Compare commits
70 Commits
dynamic_li
...
before_cac
Author | SHA1 | Date | |
---|---|---|---|
205c0e0adf | |||
b8a0a2a1bb | |||
928e2ca7bc | |||
b75f59fdd8 | |||
5832197bde | |||
4f3d692726 | |||
344765d725 | |||
812b35bf8c | |||
55d6e766a4 | |||
ec836e7873 | |||
d383a66530 | |||
7d82f677f5 | |||
4b6954543e | |||
aff20e6a45 | |||
b76313bfdb | |||
b07243b9c4 | |||
8576bc0cd1 | |||
ef7f203672 | |||
2e75bee478 | |||
c50deaec33 | |||
406b297b4c | |||
70c97ea841 | |||
c2ddba5117 | |||
2edd5699af | |||
4d3428cfe3 | |||
b941ada2af | |||
cd88928614 | |||
11838b31df | |||
e6666d6c7a | |||
95d3897971 | |||
06aaebadc4 | |||
326f9f7b19 | |||
589a4f2f12 | |||
00cf457a23 | |||
2b79539c82 | |||
44719d72e5 | |||
82e2f931e7 | |||
ae9fc97ea1 | |||
d01974a95e | |||
1888e7548e | |||
ce4f26b134 | |||
2d4e3ffaf6 | |||
9de6cf1de0 | |||
7e2b1365b4 | |||
cafbf37771 | |||
f24c18bb4a | |||
db9eed56a1 | |||
8bb4298c3a | |||
945dd84829 | |||
40649c7d3c | |||
d3c0f80aaf | |||
ae46b70398 | |||
ec14ad4e99 | |||
e64af682dc | |||
7e407c1fb6 | |||
1b0dd3f54c | |||
d7322c983a | |||
8a16d6e8f9 | |||
258d83ed5b | |||
ae25bb22fc | |||
9403e7c8ac | |||
d56117cbb3 | |||
ab782fdb54 | |||
9052673b36 | |||
1e2a4c461d | |||
0885316155 | |||
19223f6f37 | |||
a7512898a7 | |||
276a203119 | |||
802aad75cb |
@ -1,13 +0,0 @@
|
||||
# The "checkoutlist" file is used to support additional version controlled
|
||||
# administrative files in $CVSROOT/CVSROOT, such as template files.
|
||||
#
|
||||
# The first entry on a line is a filename which will be checked out from
|
||||
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
|
||||
# The remainder of the line is an error message to use if the file cannot
|
||||
# be checked out.
|
||||
#
|
||||
# File format:
|
||||
#
|
||||
# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
|
||||
#
|
||||
# comment lines begin with '#'
|
@ -1,15 +0,0 @@
|
||||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
# of files to check. A non-zero exit of the filter program will
|
||||
# cause the commit to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
@ -1,21 +0,0 @@
|
||||
# Set this to "no" if pserver shouldn't check system users/passwords
|
||||
#SystemAuth=no
|
||||
|
||||
# Put CVS lock files in this directory rather than directly in the repository.
|
||||
#LockDir=/var/lock/cvs
|
||||
|
||||
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
|
||||
# level of the new working directory when using the `cvs checkout'
|
||||
# command.
|
||||
#TopLevelAdmin=no
|
||||
|
||||
# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the
|
||||
# history file, or a subset as needed (ie `TMAR' logs all write operations)
|
||||
#LogHistory=TOEFWUPCGMAR
|
||||
|
||||
# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg
|
||||
# script to change the log message. Set it to `stat' to force CVS to verify# that the file has changed before reading it (this can take up to an extra
|
||||
# second per directory being committed, so it is not recommended for large
|
||||
# repositories. Set it to `never' (the previous CVS behavior) to prevent
|
||||
# verifymsg scripts from changing the log message.
|
||||
#RereadLogAfterVerify=always
|
@ -1,19 +0,0 @@
|
||||
# This file affects handling of files based on their names.
|
||||
#
|
||||
# The -m option specifies whether CVS attempts to merge files.
|
||||
#
|
||||
# The -k option specifies keyword expansion (e.g. -kb for binary).
|
||||
#
|
||||
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
|
||||
#
|
||||
# wildcard [option value][option value]...
|
||||
#
|
||||
# where option is one of
|
||||
# -f from cvs filter value: path to filter
|
||||
# -t to cvs filter value: path to filter
|
||||
# -m update methodology value: MERGE or COPY
|
||||
# -k expansion mode value: b, o, kkv, &c
|
||||
#
|
||||
# and value is a single-quote delimited value.
|
||||
# For example:
|
||||
#*.gif -k 'b'
|
@ -1,21 +0,0 @@
|
||||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
@ -1,27 +0,0 @@
|
||||
# The "loginfo" file controls where "cvs commit" log information
|
||||
# is sent. The first entry on a line is a regular expression which must match
|
||||
# the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. If a match is found, then the remainder of the line is a filter
|
||||
# program that should expect log information on its standard input.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name ALL appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or DEFAULT.
|
||||
#
|
||||
# You may specify a format string as part of the
|
||||
# filter. The string is composed of a `%' followed
|
||||
# by a single format character, or followed by a set of format
|
||||
# characters surrounded by `{' and `}' as separators. The format
|
||||
# characters are:
|
||||
#
|
||||
# s = file name
|
||||
# V = old version number (pre-checkin)
|
||||
# v = new version number (post-checkin)
|
||||
# t = tag or branch name
|
||||
#
|
||||
# For example:
|
||||
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
||||
# or
|
||||
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
|
@ -1,26 +0,0 @@
|
||||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
# key [options] directory
|
||||
# key [options] directory files...
|
||||
#
|
||||
# Where "options" are composed of:
|
||||
# -i prog Run "prog" on "cvs commit" from top-level of module.
|
||||
# -o prog Run "prog" on "cvs checkout" of module.
|
||||
# -e prog Run "prog" on "cvs export" of module.
|
||||
# -t prog Run "prog" on "cvs rtag" of module.
|
||||
# -u prog Run "prog" on "cvs update" of module.
|
||||
# -d dir Place module in directory "dir" instead of module name.
|
||||
# -l Top-level directory only -- do not recurse.
|
||||
#
|
||||
# NOTE: If you change any of the "Run" options above, you'll have to
|
||||
# release and re-checkout any working directories of these modules.
|
||||
#
|
||||
# And "directory" is a path to a directory relative to $CVSROOT.
|
||||
#
|
||||
# The "-a" option specifies an alias. An alias is interpreted as if
|
||||
# everything on the right of the "-a" had been typed on the command line.
|
||||
#
|
||||
# You can encode a module within a module by using the special '&'
|
||||
# character to interpose another module into the current module. This
|
||||
# can be useful for creating a module that consists of many directories
|
||||
# spread out over the entire source repository.
|
@ -1,12 +0,0 @@
|
||||
# The "notify" file controls where notifications from watches set by
|
||||
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
|
||||
# a regular expression which is tested against the directory that the
|
||||
# change is being made to, relative to the $CVSROOT. If it matches,
|
||||
# then the remainder of the line is a filter program that should contain
|
||||
# one occurrence of %s for the user to notify, and information on its
|
||||
# standard input.
|
||||
#
|
||||
# "ALL" or "DEFAULT" can be used in place of the regular expression.
|
||||
#
|
||||
# For example:
|
||||
#ALL mail -s "CVS notification" %s
|
@ -1,13 +0,0 @@
|
||||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being made to, relative to the
|
||||
# $CVSROOT. For the first match that is found, then the remainder of the
|
||||
# line is the name of the file that contains the template.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
@ -1,20 +0,0 @@
|
||||
# The "taginfo" file is used to control pre-tag checks.
|
||||
# The filter on the right is invoked with the following arguments:
|
||||
#
|
||||
# $1 -- tagname
|
||||
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
|
||||
# $3 -- repository
|
||||
# $4-> file revision [file revision ...]
|
||||
#
|
||||
# A non-zero exit of the filter program will cause the tag to be aborted.
|
||||
#
|
||||
# The first entry on a line is a regular expression which is tested
|
||||
# against the directory that the change is being committed to, relative
|
||||
# to the $CVSROOT. For the first match that is found, then the remainder
|
||||
# of the line is the name of the filter to run.
|
||||
#
|
||||
# If the repository name does not match any of the regular expressions in this
|
||||
# file, the "DEFAULT" line is used, if it is specified.
|
||||
#
|
||||
# If the name "ALL" appears as a regular expression it is always used
|
||||
# in addition to the first matching regex or "DEFAULT".
|
@ -1,21 +0,0 @@
|
||||
# The "verifymsg" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
# rcsinfo file) is provided for the logging procedure. Given a
|
||||
# template with locations for, a bug-id number, a list of people who
|
||||
# reviewed the code before it can be checked in, and an external
|
||||
# process to catalog the differences that were code reviewed, the
|
||||
# following test can be applied to the code:
|
||||
#
|
||||
# Making sure that the entered bug-id number is correct.
|
||||
# Validating that the code that was reviewed is indeed the code being
|
||||
# checked in (using the bug-id number or a seperate review
|
||||
# number to identify this particular code set.).
|
||||
#
|
||||
# If any of the above test failed, then the commit would be aborted.
|
||||
#
|
||||
# Actions such as mailing a copy of the report to each reviewer are
|
||||
# better handled by an entry in the loginfo file.
|
||||
#
|
||||
# One thing that should be noted is the the ALL keyword is not
|
||||
# supported. There can be only one entry that matches a given
|
||||
# repository.
|
@ -1,37 +0,0 @@
|
||||
import threading
|
||||
import time
|
||||
|
||||
from Logging import *
|
||||
|
||||
|
||||
|
||||
class Cache(object):
|
||||
def __init__(self, expiration):
|
||||
self.lock = threading.Lock()
|
||||
self.expiration = expiration
|
||||
self.cache = {}
|
||||
|
||||
def put(self, key, value):
|
||||
self.lock.acquire()
|
||||
self.cache[key] = (time.time(), value)
|
||||
debug("cache.put(%s, %s)" % (str(key), str(value)))
|
||||
self.lock.release()
|
||||
|
||||
def get(self, key):
|
||||
try:
|
||||
self.lock.acquire()
|
||||
debug("cache.get(%s)" % str(key))
|
||||
try:
|
||||
timestamp, value = self.cache[key]
|
||||
debug("cache.get found: %s" % value)
|
||||
if (timestamp + self.expiration) < time.time():
|
||||
debug("cache.get: expired")
|
||||
del self.cache[key]
|
||||
raise KeyError
|
||||
return value
|
||||
except KeyError:
|
||||
debug("cache.get: found nothing")
|
||||
return None
|
||||
finally:
|
||||
self.lock.release()
|
||||
|
@ -1,27 +0,0 @@
|
||||
from Logging import *
|
||||
|
||||
from SendmailSocketMapHandler import smmapBaseHandlerWorker
|
||||
from SendmailSocketMapHandler import smmapBaseHandlerContainer
|
||||
from SendmailSocketMapHandler import MyPermanentVerifierException
|
||||
from SendmailSocketMapHandler import MyTemporaryVerifierException
|
||||
|
||||
from VerifierHandler import MySMTP
|
||||
|
||||
class MyLMTP(MySMTP):
|
||||
def lhlo(self, param):
|
||||
return self.docmd("lhlo " + param)
|
||||
|
||||
class CyrusCheckerWorker(smmapBaseHandlerWorker):
|
||||
OK = "OK"
|
||||
NOK = "NOK"
|
||||
TEMPNOK = "TEMPNOK"
|
||||
|
||||
def execute(self, data):
|
||||
debug("data " + data)
|
||||
|
||||
host, address = data.split('|')
|
||||
|
||||
debug("host: (%s), address: (%s)" % (host, address))
|
||||
|
||||
return "<OK>"
|
||||
|
@ -1,14 +0,0 @@
|
||||
import syslog
|
||||
|
||||
|
||||
config = None
|
||||
|
||||
def log(data):
|
||||
syslog.syslog(syslog.LOG_INFO, data)
|
||||
|
||||
def debug(data):
|
||||
syslog.syslog(syslog.LOG_DEBUG, data)
|
||||
|
||||
def openlog(c):
|
||||
config = c
|
||||
syslog.openlog(config.get('Logging', 'ApplID'), syslog.LOG_PID, syslog.LOG_MAIL)
|
@ -1,8 +0,0 @@
|
||||
Cache.py
|
||||
Logging.py
|
||||
SendmailSocketMapHandler.py
|
||||
VerifierHandler.py
|
||||
setup.py
|
||||
smmapd
|
||||
smmapd.ini
|
||||
verifysender.m4
|
@ -1,190 +0,0 @@
|
||||
import SocketServer
|
||||
import time
|
||||
|
||||
from Logging import *
|
||||
|
||||
|
||||
class NetStringError(ValueError): pass
|
||||
|
||||
def NetStringDecode(s):
|
||||
try:
|
||||
length, data = s.split(':')
|
||||
except ValueError:
|
||||
raise NetStringError, "Separator not found"
|
||||
try:
|
||||
length = int(length)
|
||||
except ValueError:
|
||||
raise NetStringError, "Can not read length"
|
||||
if len(data) != length+1:
|
||||
raise NetStringError, "Data has unexpected length"
|
||||
if data[-1] != ',':
|
||||
raise NetStringError, "End-delimiter not found"
|
||||
return data[:-1]
|
||||
|
||||
def NetStringEncode(s):
|
||||
return str(len(s)) + ":" + s + ","
|
||||
|
||||
|
||||
class MyPermanentVerifierException(ValueError): pass
|
||||
|
||||
class MyTemporaryVerifierException(ValueError): pass
|
||||
|
||||
class MyBaseRequestHandler(SocketServer.BaseRequestHandler):
|
||||
def handle(self):
|
||||
debug("Connected from " + str(self.client_address))
|
||||
self.localSetup()
|
||||
while 1:
|
||||
receivedData = self.request.recv(8192)
|
||||
if (receivedData == None) or (len(receivedData) == 0): break
|
||||
debug("Data: (%s)" % receivedData)
|
||||
self.request.sendall(self.process(receivedData))
|
||||
self.request.close();
|
||||
self.localFinish()
|
||||
debug("Disconnected")
|
||||
|
||||
def process(self, data):
|
||||
debug("MyBaseRequestHandler.process")
|
||||
return data
|
||||
|
||||
def localSetup(self): pass
|
||||
|
||||
def localfinish(self): pass
|
||||
|
||||
|
||||
class SendmailAdaptor:
|
||||
PERM = "PERM "
|
||||
OK = "OK "
|
||||
NOTFOUND = "NOTFOUND "
|
||||
TEMP = "TEMP "
|
||||
|
||||
def preProcess(self, data):
|
||||
try:
|
||||
data = NetStringDecode(data)
|
||||
klass, data = data.split(' ')
|
||||
return klass, data
|
||||
except NetStringError, arg:
|
||||
raise MyPermanentVerifierException, arg
|
||||
except ValueError:
|
||||
raise MyPermanentVerifierException, "<class> <data> expected, only one found"
|
||||
|
||||
def postProcess(self, data):
|
||||
return NetStringEncode(data)
|
||||
|
||||
def process(self, data):
|
||||
startTime = time.time()
|
||||
try:
|
||||
klass, data2 = self.preProcess(data)
|
||||
arg = self.execute(klass, data2)
|
||||
code = SendmailAdaptor.OK
|
||||
except MyPermanentVerifierException, arg:
|
||||
code, arg = SendmailAdaptor.PERM, str(arg)
|
||||
except MyTemporaryVerifierException, arg:
|
||||
code, arg = SendmailAdaptor.TEMP, str(arg)
|
||||
endTime = time.time()
|
||||
log("Class: %s, Data: %s, Code: %s, Arg: %s, Delay: %f" % (klass, data2, code, arg, endTime-startTime))
|
||||
return self.postProcess(code + arg)
|
||||
|
||||
def execute(self, data):
|
||||
return data
|
||||
|
||||
class NullAdaptor(SendmailAdaptor):
|
||||
def preProcess(self, data):
|
||||
return re.compile(r'^(.*?)[\r\n]{1,2}$').match(data).group(1)
|
||||
|
||||
def postProcess(self, data):
|
||||
return data + "\n"
|
||||
|
||||
|
||||
class SendmailDispatcher(SendmailAdaptor, MyBaseRequestHandler):
|
||||
pluginContainerObjects = {}
|
||||
|
||||
|
||||
def registerAll(config):
|
||||
for section in config.get('Daemon', 'Plugins').split(','):
|
||||
SendmailDispatcher.register(section, config)
|
||||
|
||||
registerAll = staticmethod(registerAll)
|
||||
|
||||
|
||||
def register(section, config):
|
||||
cfg = Config(section, config)
|
||||
className = cfg.get('ContainerClass')
|
||||
moduleName = cfg.get('ContainerModule')
|
||||
if className == None:
|
||||
className = 'smmapBaseHandlerContainer'
|
||||
else:
|
||||
if moduleName == None:
|
||||
moduleName == className
|
||||
m = __import__(moduleName)
|
||||
log("Registering %s, %s" % (section, className))
|
||||
klass = eval("m.%s" % className)
|
||||
containerObject = klass(cfg)
|
||||
containerObject.setup()
|
||||
SendmailDispatcher.pluginContainerObjects[section] = containerObject
|
||||
|
||||
register = staticmethod(register)
|
||||
|
||||
|
||||
def localSetup(self):
|
||||
self.pluginWorkerObjects = {}
|
||||
|
||||
def localFinish(self):
|
||||
for o in self.pluginWorkerObjects.values():
|
||||
o.finish()
|
||||
|
||||
def execute(self, klass, data):
|
||||
if not self.pluginContainerObjects.has_key(klass):
|
||||
raise MyPermanentVerifierException, "Class %s not implemented" % klass
|
||||
elif not self.pluginWorkerObjects.has_key(klass):
|
||||
debug("Instantiate worker %s" % klass)
|
||||
self.pluginWorkerObjects[klass] = self.pluginContainerObjects[klass].getWorker()
|
||||
|
||||
return self.pluginWorkerObjects[klass].execute(data)
|
||||
|
||||
|
||||
class Config(object):
|
||||
def __init__(self, section, config):
|
||||
self.section = section
|
||||
self.config = config
|
||||
|
||||
def getSection(self):
|
||||
return self.section
|
||||
|
||||
def get(self, item):
|
||||
return self.config.get(self.section, item)
|
||||
|
||||
|
||||
class smmapBaseHandlerWorker(object):
|
||||
def __init__(self, container):
|
||||
self.container = container
|
||||
|
||||
def setup(self): pass
|
||||
|
||||
def finish(self): pass
|
||||
|
||||
def execute(self, data):
|
||||
raise NotImplementedError
|
||||
|
||||
class smmapBaseHandlerContainer(object):
|
||||
def __init__(self, cfg):
|
||||
self.config = cfg
|
||||
workerClassName = cfg.get('WorkerClass')
|
||||
workerModuleName = cfg.get('WorkerModule')
|
||||
if workerModuleName == None:
|
||||
workerModuleName = workerClassName
|
||||
m = __import__(workerModuleName)
|
||||
self.workerClass = eval("m.%s" % workerClassName)
|
||||
|
||||
def setup(self): pass
|
||||
|
||||
def finish(self): pass
|
||||
|
||||
def getWorker(self):
|
||||
worker = self.workerClass(self)
|
||||
worker.setup()
|
||||
return worker
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,240 +0,0 @@
|
||||
import threading
|
||||
import socket
|
||||
import Queue
|
||||
import re
|
||||
import time
|
||||
|
||||
#import timeoutsocket
|
||||
import DNS
|
||||
|
||||
from Logging import *
|
||||
|
||||
from Cache import Cache
|
||||
|
||||
from SendmailSocketMapHandler import smmapBaseHandlerWorker
|
||||
from SendmailSocketMapHandler import smmapBaseHandlerContainer
|
||||
from SendmailSocketMapHandler import MyPermanentVerifierException
|
||||
from SendmailSocketMapHandler import MyTemporaryVerifierException
|
||||
|
||||
|
||||
|
||||
class VerifierHandlerContainer(smmapBaseHandlerContainer):
|
||||
def setup(self):
|
||||
DNS.ParseResolvConf()
|
||||
if self.config.get('EnableCaching').lower() in ('true', 'yes', '1'):
|
||||
debug("enabling cache")
|
||||
self.cache = Cache(int(self.config.get('CacheExpiration')))
|
||||
else:
|
||||
debug("disabling cache")
|
||||
self.cache = None
|
||||
|
||||
|
||||
class VerifierHandlerWorker(smmapBaseHandlerWorker):
|
||||
OK = "OK"
|
||||
NOK = "NOK"
|
||||
TEMPNOK = "TEMPNOK"
|
||||
|
||||
def setup(self):
|
||||
self.zombies = []
|
||||
|
||||
class checker(threading.Thread):
|
||||
def __init__(self, ready, config, host, address):
|
||||
threading.Thread.__init__(self)
|
||||
self.ready = ready
|
||||
self.config = config
|
||||
self.host = host
|
||||
self.address = address
|
||||
|
||||
def checkAddressAvailability(self):
|
||||
try:
|
||||
debug("Trying " + self.host)
|
||||
s = MySMTP(self.host, float(self.config.get('SMTPTimeOut')))
|
||||
s.helo(self.config.get('SMTPHeloParam'))
|
||||
s.mail(self.config.get('SMTPCheckSender'))
|
||||
s.rcpt(self.address.getAddress())
|
||||
s.quit()
|
||||
result = VerifierHandlerWorker.OK
|
||||
except MySMTPTemporaryException:
|
||||
result = VerifierHandlerWorker.TEMPNOK
|
||||
except MySMTPPermanentException:
|
||||
result = VerifierHandlerWorker.NOK
|
||||
except socket.timeout:
|
||||
result = VerifierHandlerWorker.TEMPNOK
|
||||
except socket.error:
|
||||
result = VerifierHandlerWorker.TEMPNOK
|
||||
return result
|
||||
|
||||
def run(self):
|
||||
self.result = self.checkAddressAvailability()
|
||||
self.ready.put(self.getName())
|
||||
debug("NOTIFIED Host %s, Result %s" % (self.host, self.result))
|
||||
|
||||
def getResult(self):
|
||||
return self.result
|
||||
|
||||
def getHost(self):
|
||||
return self.host
|
||||
|
||||
def getAddress(self):
|
||||
return self.address
|
||||
|
||||
def checkAvailability(self, mxes, address):
|
||||
ready = Queue.Queue()
|
||||
checkerThreads = {}
|
||||
for m in mxes:
|
||||
checkerThread = VerifierHandlerWorker.checker(ready, self.container.config, m, address)
|
||||
checkerThread.start()
|
||||
checkerThreads[checkerThread.getName()] = checkerThread
|
||||
|
||||
result = VerifierHandlerWorker.TEMPNOK
|
||||
while 1:
|
||||
debug("%i threads left" % len(checkerThreads))
|
||||
if len(checkerThreads) == 0:
|
||||
debug("no threads left ...")
|
||||
break
|
||||
if result != VerifierHandlerWorker.TEMPNOK:
|
||||
debug("got a permanent result ...")
|
||||
break
|
||||
debug("Waiting for results ...")
|
||||
name = ready.get()
|
||||
checkerThread = checkerThreads[name]
|
||||
checkerThread.join()
|
||||
tempResult = checkerThread.getResult()
|
||||
debug("success, result is " + str(tempResult))
|
||||
if [VerifierHandlerWorker.OK, VerifierHandlerWorker.NOK].count(tempResult) != 0:
|
||||
result = tempResult
|
||||
del checkerThreads[name]
|
||||
self.zombies.extend(checkerThreads.values())
|
||||
return result
|
||||
|
||||
def finish(self):
|
||||
while 1:
|
||||
debug("finish: %i zombies left" % len(self.zombies))
|
||||
for z in self.zombies:
|
||||
if not z.isAlive():
|
||||
debug("finish: thread %s for %s, %s terminated" % (z.getName(), z.getHost(), z.getAddress().getAddress()))
|
||||
self.zombies.remove(z)
|
||||
for z in self.zombies:
|
||||
debug("finish: left over %s for %s, %s" % (z.getName(), z.getHost(), z.getAddress().getAddress()))
|
||||
if len(self.zombies) == 0:
|
||||
debug("finish: no zombie left ...")
|
||||
break
|
||||
debug("finish: WAITING")
|
||||
time.sleep(5)
|
||||
debug("finish: CONTINUE")
|
||||
debug("finish: all threads terminated")
|
||||
|
||||
|
||||
def execute(self, address):
|
||||
debug("address " + address)
|
||||
|
||||
address = EMailAddress(address)
|
||||
|
||||
bestmxes = address.getBestMX()
|
||||
if not bestmxes:
|
||||
return "<NOK> <no bestmx found>"
|
||||
|
||||
if self.container.cache == None:
|
||||
debug("no caching")
|
||||
result = self.checkAvailability(bestmxes, address)
|
||||
else:
|
||||
result = self.container.cache.get(address.getAddress())
|
||||
if result == None:
|
||||
debug("not found in cache")
|
||||
result = self.checkAvailability(bestmxes, address)
|
||||
if result != VerifierHandlerWorker.TEMPNOK:
|
||||
self.container.cache.put(address.getAddress(), result)
|
||||
else:
|
||||
debug("found in cache")
|
||||
|
||||
if result == VerifierHandlerWorker.OK:
|
||||
return "<OK>"
|
||||
elif result == VerifierHandlerWorker.NOK:
|
||||
return "<NOK> <home server sent a permanent negative answer>"
|
||||
else:
|
||||
raise MyTemporaryVerifierException, "no mx reachable"
|
||||
|
||||
|
||||
class MySMTPPermanentException(ValueError): pass
|
||||
|
||||
class MySMTPTemporaryException(ValueError): pass
|
||||
|
||||
class MySMTP(object):
|
||||
def __init__(self, host, timeout, port=25):
|
||||
self.host = host
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.settimeout(timeout)
|
||||
self.socket.connect((host, port))
|
||||
self.socket.recv(8192)
|
||||
self.resPattern = re.compile(r'[\w\W]*?^(\d{3,3}) (.*?)[\r\n]{1,2}$', re.MULTILINE)
|
||||
|
||||
def checkResult(self, r):
|
||||
code, text = r
|
||||
code = code / 100
|
||||
|
||||
if code == 2:
|
||||
return;
|
||||
elif code == 4:
|
||||
raise MySMTPTemporaryException, text
|
||||
elif code == 5:
|
||||
raise MySMTPPermanentException, text
|
||||
else:
|
||||
raise MySMTPPermanentException, "unknown code: " + str(code) + ", text: " + str(text)
|
||||
|
||||
def docmd(self, cmd):
|
||||
debug("docmd: %s, cmd: %s " % (self.host, cmd))
|
||||
self.socket.sendall(cmd + "\r\n")
|
||||
res = self.socket.recv(8192)
|
||||
debug("docmd: result: (%s)" % res)
|
||||
m = self.resPattern.match(res)
|
||||
return self.checkResult((int(m.group(1)), m.group(2)))
|
||||
|
||||
def helo(self, param):
|
||||
return self.docmd("helo " + param)
|
||||
|
||||
def mail(self, sender):
|
||||
if sender[0] != '<' and sender[-1] != '>': sender = '<' + sender + '>'
|
||||
return self.docmd("mail from:" + sender)
|
||||
|
||||
def rcpt(self, recipient):
|
||||
return self.docmd("rcpt to:<%s>" % recipient)
|
||||
|
||||
def quit(self):
|
||||
self.docmd("quit")
|
||||
self.socket.close()
|
||||
|
||||
|
||||
class EMailAddress(object):
|
||||
def __init__(self, address):
|
||||
self.address = address
|
||||
if self.address[0] == '<' and self.address[-1] == '>': self.address = self.address[1:-1]
|
||||
try:
|
||||
self.userpart, self.domain = self.address.split('@')
|
||||
except ValueError:
|
||||
raise MyPermanentVerifierException, "excepted email address, found not at-sign"
|
||||
|
||||
def getUserPart(self):
|
||||
return self.userpart
|
||||
|
||||
def getDomain(self):
|
||||
return self.domain
|
||||
|
||||
def getAddress(self):
|
||||
return self.address
|
||||
|
||||
def getBestMX(self):
|
||||
if self.domain[0] == '[' and self.domain[-1] == ']':
|
||||
bestmx2 = [self.domain[1:-1]]
|
||||
else:
|
||||
bestmx = DNS.mxlookup(self.domain)
|
||||
pref = None
|
||||
bestmx2 = []
|
||||
for mx in bestmx:
|
||||
if pref == None: pref = mx[0]
|
||||
if pref == mx[0]:
|
||||
bestmx2.append(mx[1])
|
||||
else:
|
||||
break
|
||||
debug("bestmx " + str(bestmx2))
|
||||
return bestmx2
|
||||
|
@ -1,327 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Sender Address Verifier for Sendmail</title>
|
||||
<meta name="generator" content="emacs-wiki.el">
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<link rev="made" href="mailto:woho@hottis.de">
|
||||
<link rel="stylesheet" type="text/css" href="/web/default.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Sender Address Verifier for Sendmail</h1>
|
||||
<!-- Page published by Emacs Wiki begins here -->
|
||||
<p>
|
||||
Author: Wolfgang Hottgenroth <<a href="mailto:woho@hottis.de">woho@hottis.de</a>>, 2004-05-17
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is the prototype of a sender address verifier for sendmail-8.13.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It consists of a m4 file containing a FEATURE to be included in your
|
||||
<code>sendmail.mc</code> and a verifier daemon in a bit of python code.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
By including the FEATURE in your sendmail.mc file and running the
|
||||
verifier daemon, sendmail file verify either
|
||||
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>all sender addresses (with certain exceptions) or
|
||||
</li>
|
||||
<li>only certain sender addresses
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This will be done by connecting to the best MX servers of the
|
||||
particular domain, trying to send a mail to the particular address and
|
||||
collect the replies.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Actually only the <code>HELO</code>, <code>MAIL</code> and <code>RCPT</code> commands are issued.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a positive reply was found, the mail is considered as valid.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a permanent negative reply was found, the mail is considered as
|
||||
invalid.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If no MX entry was found, the mail is considered as invalid.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a temporary negative reply was found, the mail is considered as
|
||||
temporary invalid.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If there is more than one best MX server all of these servers are
|
||||
connected in parallel and the first permanent reply (either positive
|
||||
or negative) is returned.
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Download</h3>
|
||||
|
||||
<p>
|
||||
The complete sources: <a href="./download/">download</a>
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Have a look into the sources: <a href="http://www.hottis.de/cgi-bin/cvsweb.cgi/sender_verifier/">sources</a>
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Requirements</h3>
|
||||
|
||||
<h4>sendmail</h4>
|
||||
|
||||
<p>
|
||||
sendmail-8.13 is required, since this thing uses the fresh introduced
|
||||
socket map.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Find it <a href="http://www.sendmail.org">here</a> on the sendmail homepage.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Your need to build sendmail with support for the socket map. Include
|
||||
|
||||
</p>
|
||||
|
||||
<pre class="example">
|
||||
APPENDDEF(`confMAPDEF',`-DSOCKETMAP')
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
in your <code>site.config.m4</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<h4>Python</h4>
|
||||
|
||||
<p>
|
||||
Python 2.2 or 2.3 is required. If you have Python 2.3 you must delete
|
||||
the <code>import timeoutsocket</code> line from <code>verifier.py</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Additionally the python package <code>python-dns</code> is required. Find it
|
||||
<a href="http://pydns.sourceforge.net/">http://pydns.sourceforge.net</a>.
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Configuration of sendmail</h3>
|
||||
|
||||
<p>
|
||||
Include the FEATURE in your <code>sendmail.mc</code> file. You need to give two
|
||||
parameters:
|
||||
|
||||
</p>
|
||||
|
||||
<pre class="example">
|
||||
FEATURE(`verifysender', `mode', `return')
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
For <code>mode</code> you must give either <code>white</code> or <code>black</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>white</code></dt>
|
||||
<dd>
|
||||
All sender addresses but those mentioned in the whitelist
|
||||
file are verified. Complete addresses or just domains can be listed in
|
||||
the file. The default location of the whitelist is
|
||||
<code>/etc/mail/verify-white-list</code>. If you need a different location,
|
||||
define it to <code>confVERIFIER_WHITELIST</code>.
|
||||
</dd>
|
||||
<dt><code>black</code></dt>
|
||||
<dd>
|
||||
only addresses or addresses within domains listed in the
|
||||
blacklist file are verified. It is obviously only useful to mention
|
||||
domains in the blacklist. The default location of the blacklist is
|
||||
<code>/etc/mail/verify-black-list</code>. If you need a different location,
|
||||
define it to <code>confVERIFIER_BLACKLIST</code>.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
Both the blacklist and the whitelist file are maps, they must be
|
||||
created with <code>makemap</code>. Therefore the entries need a LHS (the address
|
||||
or domain) and a RHS. The actual content of the RHS has NO meaning at
|
||||
all.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The FEATURE defines a socket map. The default target of the map is
|
||||
<code>inet:8884@127.0.0.1</code>, according to the default setting in
|
||||
<code>Config.py</code>. If you need something different, define it to
|
||||
<code>confVERIFIER_MAP</code>, but don't forget to also adjust <code>Config.py</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Configuration of the verification daemon</h3>
|
||||
|
||||
<p>
|
||||
The configuration of the daemon is done in the file <code>Config.py</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is the default of this file:
|
||||
|
||||
</p>
|
||||
|
||||
<pre class="example">
|
||||
[Daemon]
|
||||
Address: 127.0.0.1
|
||||
Port: 8884
|
||||
PidFile: smmapd.pid
|
||||
Plugins: Verifier,Verifier2
|
||||
|
||||
[Logging]
|
||||
ApplId: smmapd
|
||||
|
||||
[Verifier]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: 1
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: local
|
||||
SMTPCheckSender: <>
|
||||
|
||||
[Verifier2]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: 1
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: hottis.de
|
||||
SMTPCheckSender: <postmaster@hottis.de></pre>
|
||||
|
||||
<p>
|
||||
<code>Port</code> and <code>Address</code> are specifying the socket the daemon should
|
||||
listen to for communication with sendmail. These settings must be
|
||||
reflected in the <code>confVERIFIER_MAP</code> if you change it.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>SMTPTimeOut</code> is the timeout for the communication with the MX servers
|
||||
when verifying addresses.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>SMTPHeloParam</code> is the parameter the verifier will use with the <code>HELO</code>
|
||||
command when verifying.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>SMTPCheckSender</code> is the sender address used during
|
||||
verifications. You should not change it unless you know what you do to
|
||||
avoid verification loops.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Since the verification is a time and resource consuming process,
|
||||
results can be cached, which is enabled by default. Set
|
||||
<code>EnableCaching</code> to 0 to disable it.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>CacheExpiration</code> is the time in seconds an entry in the cache is
|
||||
considered as valid. It should be much higher.
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Operation</h3>
|
||||
|
||||
<p>
|
||||
Configure sendmail and the daemon according to your needs. Start the
|
||||
daemon:
|
||||
|
||||
</p>
|
||||
|
||||
<pre class="example">
|
||||
./verifier.py
|
||||
</pre>
|
||||
|
||||
<h3>Changes</h3>
|
||||
|
||||
<ul>
|
||||
<li>According to a comment in comp.mail.sendmail I've introduced a class
|
||||
<code>verifier_fix_white</code> in the FEATURE file, currently containing only
|
||||
the string <code>postmaster</code>. Addresses with userpart in this class will
|
||||
never ever be verified to avoid infinite verifying loops.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>2004-05-17</h4>
|
||||
|
||||
<ul>
|
||||
<li>support plugins
|
||||
</li>
|
||||
<li>separate container and worker object, thereby enable multiple
|
||||
instances of the same plugins
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Page published by Emacs Wiki ends here -->
|
||||
<div class="navfoot">
|
||||
<hr>
|
||||
<table width="100%" border="0" summary="Footer navigation">
|
||||
<tr>
|
||||
<td width="33%" align="left">
|
||||
<span class="footdate">UPDATED: 2004-05-17</span>
|
||||
</td>
|
||||
<td width="34%" align="center">
|
||||
<span class="foothome">
|
||||
|
||||
</span>
|
||||
</td>
|
||||
<td width="33%" align="right">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,195 +0,0 @@
|
||||
#title Sender Address Verifier for Sendmail
|
||||
#style /web/default.css
|
||||
|
||||
|
||||
Author: Wolfgang Hottgenroth <woho@hottis.de>, 2004-05-17
|
||||
|
||||
|
||||
|
||||
|
||||
This is the prototype of a sender address verifier for sendmail-8.13.
|
||||
|
||||
It consists of a m4 file containing a FEATURE to be included in your
|
||||
=sendmail.mc= and a verifier daemon in a bit of python code.
|
||||
|
||||
|
||||
By including the FEATURE in your sendmail.mc file and running the
|
||||
verifier daemon, sendmail file verify either
|
||||
|
||||
- all sender addresses (with certain exceptions) or
|
||||
- only certain sender addresses
|
||||
|
||||
This will be done by connecting to the best MX servers of the
|
||||
particular domain, trying to send a mail to the particular address and
|
||||
collect the replies.
|
||||
|
||||
Actually only the =HELO=, =MAIL= and =RCPT= commands are issued.
|
||||
|
||||
If a positive reply was found, the mail is considered as valid.
|
||||
|
||||
If a permanent negative reply was found, the mail is considered as
|
||||
invalid.
|
||||
|
||||
If no MX entry was found, the mail is considered as invalid.
|
||||
|
||||
If a temporary negative reply was found, the mail is considered as
|
||||
temporary invalid.
|
||||
|
||||
If there is more than one best MX server all of these servers are
|
||||
connected in parallel and the first permanent reply (either positive
|
||||
or negative) is returned.
|
||||
|
||||
|
||||
** Download
|
||||
|
||||
The complete sources: [[./download/][download]]
|
||||
|
||||
Have a look into the sources: [[http://www.hottis.de/cgi-bin/cvsweb.cgi/sender_verifier/][sources]]
|
||||
|
||||
|
||||
|
||||
|
||||
** Requirements
|
||||
|
||||
*** sendmail
|
||||
|
||||
sendmail-8.13 is required, since this thing uses the fresh introduced
|
||||
socket map.
|
||||
|
||||
Find it [[http://www.sendmail.org][here]] on the sendmail homepage.
|
||||
|
||||
Your need to build sendmail with support for the socket map. Include
|
||||
|
||||
<example>
|
||||
APPENDDEF(`confMAPDEF',`-DSOCKETMAP')
|
||||
</example>
|
||||
|
||||
in your =site.config.m4=.
|
||||
|
||||
|
||||
*** Python
|
||||
|
||||
Python 2.2 or 2.3 is required. If you have Python 2.3 you must delete
|
||||
the =import timeoutsocket= line from =verifier.py=.
|
||||
|
||||
Additionally the python package =python-dns= is required. Find it
|
||||
[[http://pydns.sourceforge.net/][http://pydns.sourceforge.net]].
|
||||
|
||||
|
||||
|
||||
** Configuration of sendmail
|
||||
|
||||
Include the FEATURE in your =sendmail.mc= file. You need to give two
|
||||
parameters:
|
||||
|
||||
<example>
|
||||
FEATURE(`verifysender', `mode', `return')
|
||||
</example>
|
||||
|
||||
For =mode= you must give either =white= or =black=.
|
||||
|
||||
=white= :: All sender addresses but those mentioned in the whitelist
|
||||
file are verified. Complete addresses or just domains can be listed in
|
||||
the file. The default location of the whitelist is
|
||||
=/etc/mail/verify-white-list=. If you need a different location,
|
||||
define it to =confVERIFIER_WHITELIST=.
|
||||
|
||||
=black= :: only addresses or addresses within domains listed in the
|
||||
blacklist file are verified. It is obviously only useful to mention
|
||||
domains in the blacklist. The default location of the blacklist is
|
||||
=/etc/mail/verify-black-list=. If you need a different location,
|
||||
define it to =confVERIFIER_BLACKLIST=.
|
||||
|
||||
Both the blacklist and the whitelist file are maps, they must be
|
||||
created with =makemap=. Therefore the entries need a LHS (the address
|
||||
or domain) and a RHS. The actual content of the RHS has NO meaning at
|
||||
all.
|
||||
|
||||
The FEATURE defines a socket map. The default target of the map is
|
||||
=inet:8884@127.0.0.1=, according to the default setting in
|
||||
=Config.py=. If you need something different, define it to
|
||||
=confVERIFIER_MAP=, but don't forget to also adjust =Config.py=.
|
||||
|
||||
|
||||
** Configuration of the verification daemon
|
||||
|
||||
The configuration of the daemon is done in the file =Config.py=.
|
||||
|
||||
This is the default of this file:
|
||||
|
||||
<example>
|
||||
[Daemon]
|
||||
Address: 127.0.0.1
|
||||
Port: 8884
|
||||
PidFile: smmapd.pid
|
||||
Plugins: Verifier,Verifier2
|
||||
|
||||
[Logging]
|
||||
ApplId: smmapd
|
||||
|
||||
[Verifier]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: 1
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: local
|
||||
SMTPCheckSender: <>
|
||||
|
||||
[Verifier2]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: 1
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: hottis.de
|
||||
SMTPCheckSender: <postmaster@hottis.de></example>
|
||||
|
||||
=Port= and =Address= are specifying the socket the daemon should
|
||||
listen to for communication with sendmail. These settings must be
|
||||
reflected in the =confVERIFIER_MAP= if you change it.
|
||||
|
||||
=SMTPTimeOut= is the timeout for the communication with the MX servers
|
||||
when verifying addresses.
|
||||
|
||||
=SMTPHeloParam= is the parameter the verifier will use with the =HELO=
|
||||
command when verifying.
|
||||
|
||||
=SMTPCheckSender= is the sender address used during
|
||||
verifications. You should not change it unless you know what you do to
|
||||
avoid verification loops.
|
||||
|
||||
Since the verification is a time and resource consuming process,
|
||||
results can be cached, which is enabled by default. Set
|
||||
=EnableCaching= to 0 to disable it.
|
||||
|
||||
=CacheExpiration= is the time in seconds an entry in the cache is
|
||||
considered as valid. It should be much higher.
|
||||
|
||||
|
||||
** Operation
|
||||
|
||||
Configure sendmail and the daemon according to your needs. Start the
|
||||
daemon:
|
||||
|
||||
<example>
|
||||
./verifier.py
|
||||
</example>
|
||||
|
||||
|
||||
** Changes
|
||||
|
||||
- According to a comment in comp.mail.sendmail I've introduced a class
|
||||
=verifier_fix_white= in the FEATURE file, currently containing only
|
||||
the string =postmaster=. Addresses with userpart in this class will
|
||||
never ever be verified to avoid infinite verifying loops.
|
||||
|
||||
*** 2004-05-17
|
||||
- support plugins
|
||||
- separate container and worker object, thereby enable multiple
|
||||
instances of the same plugins
|
||||
|
@ -1,19 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name="smmapd",
|
||||
version="0.1",
|
||||
description="Framework for sendmail SocketMap handlers",
|
||||
long_description = """
|
||||
A framework to build handlers for the sendmail 8.13 SocketMap,
|
||||
together with an implementation of a sender-address verifier,
|
||||
together we a sendmail m4 feature file""",
|
||||
author="Wolfgang Hottgenroth",
|
||||
author_email="woho@hottis.de",
|
||||
url="http://www.hottis.de/web/verifier/index.html",
|
||||
py_modules = [ 'SendmailSocketMapHandler', 'Cache', 'Logging', 'VerifierHandler' ],
|
||||
scripts = [ 'smmapd' ],
|
||||
data_files = [('config', ['smmapd.ini']),
|
||||
('cf/feature', ['verifysender.m4'])]
|
||||
)
|
@ -1,65 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import SocketServer
|
||||
import socket
|
||||
import os
|
||||
import ConfigParser
|
||||
import getopt
|
||||
import sys
|
||||
|
||||
from Logging import *
|
||||
from SendmailSocketMapHandler import SendmailDispatcher
|
||||
|
||||
|
||||
def usage():
|
||||
print "Usage"
|
||||
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hC:F", ["help", "ConfigFile=", "ForeGround"])
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
configFile = '/etc/smmapd.ini'
|
||||
foreGround = None
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit()
|
||||
if o in ("-C", "--ConfigFile"):
|
||||
configFile = a
|
||||
if o in ("-F", "--ForeGround"):
|
||||
foreGround = 1
|
||||
|
||||
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read(configFile)
|
||||
|
||||
openlog(config)
|
||||
|
||||
if foreGround:
|
||||
pid = 0
|
||||
else:
|
||||
pid = os.fork()
|
||||
|
||||
if pid:
|
||||
pidFile = file(config.get('Daemon', 'PidFile'), mode='w')
|
||||
pidFile.write("%i\n" % pid)
|
||||
pidFile.close()
|
||||
print "daemon started with pid ", pid
|
||||
else:
|
||||
log("daemon started")
|
||||
|
||||
SendmailDispatcher.registerAll(config)
|
||||
|
||||
try:
|
||||
address = config.get('Daemon', 'Address')
|
||||
port = int(config.get('Daemon', 'Port'))
|
||||
srv = SocketServer.ThreadingTCPServer((address, port), SendmailDispatcher)
|
||||
srv.serve_forever()
|
||||
except socket.error, arg:
|
||||
log("got a socket error: %s" % str(arg))
|
||||
log("daemon died")
|
||||
|
@ -1,37 +0,0 @@
|
||||
[Daemon]
|
||||
Address: 127.0.0.1
|
||||
Port: 8884
|
||||
PidFile: smmapd.pid
|
||||
Plugins: verifier,verifier2,cyrusChecker
|
||||
|
||||
[Logging]
|
||||
ApplId: smmapd
|
||||
|
||||
[verifier]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: yes
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: local
|
||||
SMTPCheckSender: <>
|
||||
|
||||
[verifier2]
|
||||
ContainerModule: VerifierHandler
|
||||
ContainerClass: VerifierHandlerContainer
|
||||
WorkerModule: VerifierHandler
|
||||
WorkerClass: VerifierHandlerWorker
|
||||
EnableCaching: yes
|
||||
CacheExpiration: 20
|
||||
SMTPTimeOut: 20
|
||||
SMTPHeloParam: hottis.de
|
||||
SMTPCheckSender: <postmaster@hottis.de>
|
||||
|
||||
[cyrusChecker]
|
||||
ContainerModule: SendmailSocketMapHandler
|
||||
ContainerClass: smmapBaseHandlerContainer
|
||||
WorkerModule: CyrusChecker
|
||||
WorkerClass: CyrusCheckerWorker
|
||||
|
@ -1,424 +0,0 @@
|
||||
|
||||
####
|
||||
# Copyright 2000,2001 by Timothy O'Malley <timo@alum.mit.edu>
|
||||
#
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software
|
||||
# and its documentation for any purpose and without fee is hereby
|
||||
# granted, provided that the above copyright notice appear in all
|
||||
# copies and that both that copyright notice and this permission
|
||||
# notice appear in supporting documentation, and that the name of
|
||||
# Timothy O'Malley not be used in advertising or publicity
|
||||
# pertaining to distribution of the software without specific, written
|
||||
# prior permission.
|
||||
#
|
||||
# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
|
||||
# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
####
|
||||
|
||||
"""Timeout Socket
|
||||
|
||||
This module enables a timeout mechanism on all TCP connections. It
|
||||
does this by inserting a shim into the socket module. After this module
|
||||
has been imported, all socket creation goes through this shim. As a
|
||||
result, every TCP connection will support a timeout.
|
||||
|
||||
The beauty of this method is that it immediately and transparently
|
||||
enables the entire python library to support timeouts on TCP sockets.
|
||||
As an example, if you wanted to SMTP connections to have a 20 second
|
||||
timeout:
|
||||
|
||||
import timeoutsocket
|
||||
import smtplib
|
||||
timeoutsocket.setDefaultSocketTimeout(20)
|
||||
|
||||
|
||||
The timeout applies to the socket functions that normally block on
|
||||
execution: read, write, connect, and accept. If any of these
|
||||
operations exceeds the specified timeout, the exception Timeout
|
||||
will be raised.
|
||||
|
||||
The default timeout value is set to None. As a result, importing
|
||||
this module does not change the default behavior of a socket. The
|
||||
timeout mechanism only activates when the timeout has been set to
|
||||
a numeric value. (This behavior mimics the behavior of the
|
||||
select.select() function.)
|
||||
|
||||
This module implements two classes: TimeoutSocket and TimeoutFile.
|
||||
|
||||
The TimeoutSocket class defines a socket-like object that attempts to
|
||||
avoid the condition where a socket may block indefinitely. The
|
||||
TimeoutSocket class raises a Timeout exception whenever the
|
||||
current operation delays too long.
|
||||
|
||||
The TimeoutFile class defines a file-like object that uses the TimeoutSocket
|
||||
class. When the makefile() method of TimeoutSocket is called, it returns
|
||||
an instance of a TimeoutFile.
|
||||
|
||||
Each of these objects adds two methods to manage the timeout value:
|
||||
|
||||
get_timeout() --> returns the timeout of the socket or file
|
||||
set_timeout() --> sets the timeout of the socket or file
|
||||
|
||||
|
||||
As an example, one might use the timeout feature to create httplib
|
||||
connections that will timeout after 30 seconds:
|
||||
|
||||
import timeoutsocket
|
||||
import httplib
|
||||
H = httplib.HTTP("www.python.org")
|
||||
H.sock.set_timeout(30)
|
||||
|
||||
Note: When used in this manner, the connect() routine may still
|
||||
block because it happens before the timeout is set. To avoid
|
||||
this, use the 'timeoutsocket.setDefaultSocketTimeout()' function.
|
||||
|
||||
Good Luck!
|
||||
|
||||
"""
|
||||
|
||||
__version__ = "$Revision$"
|
||||
__author__ = "Timothy O'Malley <timo@alum.mit.edu>"
|
||||
|
||||
#
|
||||
# Imports
|
||||
#
|
||||
import select, string
|
||||
import socket
|
||||
if not hasattr(socket, "_no_timeoutsocket"):
|
||||
_socket = socket.socket
|
||||
else:
|
||||
_socket = socket._no_timeoutsocket
|
||||
|
||||
|
||||
#
|
||||
# Set up constants to test for Connected and Blocking operations.
|
||||
# We delete 'os' and 'errno' to keep our namespace clean(er).
|
||||
# Thanks to Alex Martelli and G. Li for the Windows error codes.
|
||||
#
|
||||
import os
|
||||
if os.name == "nt":
|
||||
_IsConnected = ( 10022, 10056 )
|
||||
_ConnectBusy = ( 10035, )
|
||||
_AcceptBusy = ( 10035, )
|
||||
else:
|
||||
import errno
|
||||
_IsConnected = ( errno.EISCONN, )
|
||||
_ConnectBusy = ( errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK )
|
||||
_AcceptBusy = ( errno.EAGAIN, errno.EWOULDBLOCK )
|
||||
del errno
|
||||
del os
|
||||
|
||||
|
||||
#
|
||||
# Default timeout value for ALL TimeoutSockets
|
||||
#
|
||||
_DefaultTimeout = None
|
||||
def setDefaultSocketTimeout(timeout):
|
||||
global _DefaultTimeout
|
||||
_DefaultTimeout = timeout
|
||||
def getDefaultSocketTimeout():
|
||||
return _DefaultTimeout
|
||||
|
||||
#
|
||||
# Exceptions for socket errors and timeouts
|
||||
#
|
||||
Error = socket.error
|
||||
class Timeout(Exception):
|
||||
pass
|
||||
|
||||
|
||||
#
|
||||
# Factory function
|
||||
#
|
||||
from socket import AF_INET, SOCK_STREAM
|
||||
def timeoutsocket(family=AF_INET, type=SOCK_STREAM, proto=None):
|
||||
if family != AF_INET or type != SOCK_STREAM:
|
||||
if proto:
|
||||
return _socket(family, type, proto)
|
||||
else:
|
||||
return _socket(family, type)
|
||||
return TimeoutSocket( _socket(family, type), _DefaultTimeout )
|
||||
# end timeoutsocket
|
||||
|
||||
#
|
||||
# The TimeoutSocket class definition
|
||||
#
|
||||
class TimeoutSocket:
|
||||
"""TimeoutSocket object
|
||||
Implements a socket-like object that raises Timeout whenever
|
||||
an operation takes too long.
|
||||
The definition of 'too long' can be changed using the
|
||||
set_timeout() method.
|
||||
"""
|
||||
|
||||
_copies = 0
|
||||
_blocking = 1
|
||||
|
||||
def __init__(self, sock, timeout):
|
||||
self._sock = sock
|
||||
self._timeout = timeout
|
||||
# end __init__
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self._sock, key)
|
||||
# end __getattr__
|
||||
|
||||
def get_timeout(self):
|
||||
return self._timeout
|
||||
# end set_timeout
|
||||
|
||||
def set_timeout(self, timeout=None):
|
||||
self._timeout = timeout
|
||||
# end set_timeout
|
||||
|
||||
def setblocking(self, blocking):
|
||||
self._blocking = blocking
|
||||
return self._sock.setblocking(blocking)
|
||||
# end set_timeout
|
||||
|
||||
def connect_ex(self, addr):
|
||||
errcode = 0
|
||||
try:
|
||||
self.connect(addr)
|
||||
except Error, why:
|
||||
errcode = why[0]
|
||||
return errcode
|
||||
# end connect_ex
|
||||
|
||||
def connect(self, addr, port=None, dumbhack=None):
|
||||
# In case we were called as connect(host, port)
|
||||
if port != None: addr = (addr, port)
|
||||
|
||||
# Shortcuts
|
||||
sock = self._sock
|
||||
timeout = self._timeout
|
||||
blocking = self._blocking
|
||||
|
||||
# First, make a non-blocking call to connect
|
||||
try:
|
||||
sock.setblocking(0)
|
||||
sock.connect(addr)
|
||||
sock.setblocking(blocking)
|
||||
return
|
||||
except Error, why:
|
||||
# Set the socket's blocking mode back
|
||||
sock.setblocking(blocking)
|
||||
|
||||
# If we are not blocking, re-raise
|
||||
if not blocking:
|
||||
raise
|
||||
|
||||
# If we are already connected, then return success.
|
||||
# If we got a genuine error, re-raise it.
|
||||
errcode = why[0]
|
||||
if dumbhack and errcode in _IsConnected:
|
||||
return
|
||||
elif errcode not in _ConnectBusy:
|
||||
raise
|
||||
|
||||
# Now, wait for the connect to happen
|
||||
# ONLY if dumbhack indicates this is pass number one.
|
||||
# If select raises an error, we pass it on.
|
||||
# Is this the right behavior?
|
||||
if not dumbhack:
|
||||
r,w,e = select.select([], [sock], [], timeout)
|
||||
if w:
|
||||
return self.connect(addr, dumbhack=1)
|
||||
|
||||
# If we get here, then we should raise Timeout
|
||||
raise Timeout("Attempted connect to %s timed out." % str(addr) )
|
||||
# end connect
|
||||
|
||||
def accept(self, dumbhack=None):
|
||||
# Shortcuts
|
||||
sock = self._sock
|
||||
timeout = self._timeout
|
||||
blocking = self._blocking
|
||||
|
||||
# First, make a non-blocking call to accept
|
||||
# If we get a valid result, then convert the
|
||||
# accept'ed socket into a TimeoutSocket.
|
||||
# Be carefult about the blocking mode of ourselves.
|
||||
try:
|
||||
sock.setblocking(0)
|
||||
newsock, addr = sock.accept()
|
||||
sock.setblocking(blocking)
|
||||
timeoutnewsock = self.__class__(newsock, timeout)
|
||||
timeoutnewsock.setblocking(blocking)
|
||||
return (timeoutnewsock, addr)
|
||||
except Error, why:
|
||||
# Set the socket's blocking mode back
|
||||
sock.setblocking(blocking)
|
||||
|
||||
# If we are not supposed to block, then re-raise
|
||||
if not blocking:
|
||||
raise
|
||||
|
||||
# If we got a genuine error, re-raise it.
|
||||
errcode = why[0]
|
||||
if errcode not in _AcceptBusy:
|
||||
raise
|
||||
|
||||
# Now, wait for the accept to happen
|
||||
# ONLY if dumbhack indicates this is pass number one.
|
||||
# If select raises an error, we pass it on.
|
||||
# Is this the right behavior?
|
||||
if not dumbhack:
|
||||
r,w,e = select.select([sock], [], [], timeout)
|
||||
if r:
|
||||
return self.accept(dumbhack=1)
|
||||
|
||||
# If we get here, then we should raise Timeout
|
||||
raise Timeout("Attempted accept timed out.")
|
||||
# end accept
|
||||
|
||||
def send(self, data, flags=0):
|
||||
sock = self._sock
|
||||
if self._blocking:
|
||||
r,w,e = select.select([],[sock],[], self._timeout)
|
||||
if not w:
|
||||
raise Timeout("Send timed out")
|
||||
return sock.send(data, flags)
|
||||
# end send
|
||||
|
||||
def recv(self, bufsize, flags=0):
|
||||
sock = self._sock
|
||||
if self._blocking:
|
||||
r,w,e = select.select([sock], [], [], self._timeout)
|
||||
if not r:
|
||||
raise Timeout("Recv timed out")
|
||||
return sock.recv(bufsize, flags)
|
||||
# end recv
|
||||
|
||||
def makefile(self, flags="r", bufsize=-1):
|
||||
self._copies = self._copies +1
|
||||
return TimeoutFile(self, flags, bufsize)
|
||||
# end makefile
|
||||
|
||||
def close(self):
|
||||
if self._copies <= 0:
|
||||
self._sock.close()
|
||||
else:
|
||||
self._copies = self._copies -1
|
||||
# end close
|
||||
|
||||
# end TimeoutSocket
|
||||
|
||||
|
||||
class TimeoutFile:
|
||||
"""TimeoutFile object
|
||||
Implements a file-like object on top of TimeoutSocket.
|
||||
"""
|
||||
|
||||
def __init__(self, sock, mode="r", bufsize=4096):
|
||||
self._sock = sock
|
||||
self._bufsize = 4096
|
||||
if bufsize > 0: self._bufsize = bufsize
|
||||
if not hasattr(sock, "_inqueue"): self._sock._inqueue = ""
|
||||
|
||||
# end __init__
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self._sock, key)
|
||||
# end __getattr__
|
||||
|
||||
def close(self):
|
||||
self._sock.close()
|
||||
self._sock = None
|
||||
# end close
|
||||
|
||||
def write(self, data):
|
||||
self.send(data)
|
||||
# end write
|
||||
|
||||
def read(self, size=-1):
|
||||
_sock = self._sock
|
||||
_bufsize = self._bufsize
|
||||
while 1:
|
||||
datalen = len(_sock._inqueue)
|
||||
if datalen >= size >= 0:
|
||||
break
|
||||
bufsize = _bufsize
|
||||
if size > 0:
|
||||
bufsize = min(bufsize, size - datalen )
|
||||
buf = self.recv(bufsize)
|
||||
if not buf:
|
||||
break
|
||||
_sock._inqueue = _sock._inqueue + buf
|
||||
data = _sock._inqueue
|
||||
_sock._inqueue = ""
|
||||
if size > 0 and datalen > size:
|
||||
_sock._inqueue = data[size:]
|
||||
data = data[:size]
|
||||
return data
|
||||
# end read
|
||||
|
||||
def readline(self, size=-1):
|
||||
_sock = self._sock
|
||||
_bufsize = self._bufsize
|
||||
while 1:
|
||||
idx = string.find(_sock._inqueue, "\n")
|
||||
if idx >= 0:
|
||||
break
|
||||
datalen = len(_sock._inqueue)
|
||||
if datalen >= size >= 0:
|
||||
break
|
||||
bufsize = _bufsize
|
||||
if size > 0:
|
||||
bufsize = min(bufsize, size - datalen )
|
||||
buf = self.recv(bufsize)
|
||||
if not buf:
|
||||
break
|
||||
_sock._inqueue = _sock._inqueue + buf
|
||||
|
||||
data = _sock._inqueue
|
||||
_sock._inqueue = ""
|
||||
if idx >= 0:
|
||||
idx = idx + 1
|
||||
_sock._inqueue = data[idx:]
|
||||
data = data[:idx]
|
||||
elif size > 0 and datalen > size:
|
||||
_sock._inqueue = data[size:]
|
||||
data = data[:size]
|
||||
return data
|
||||
# end readline
|
||||
|
||||
def readlines(self, sizehint=-1):
|
||||
result = []
|
||||
data = self.read()
|
||||
while data:
|
||||
idx = string.find(data, "\n")
|
||||
if idx >= 0:
|
||||
idx = idx + 1
|
||||
result.append( data[:idx] )
|
||||
data = data[idx:]
|
||||
else:
|
||||
result.append( data )
|
||||
data = ""
|
||||
return result
|
||||
# end readlines
|
||||
|
||||
def flush(self): pass
|
||||
|
||||
# end TimeoutFile
|
||||
|
||||
|
||||
#
|
||||
# Silently replace the socket() builtin function with
|
||||
# our timeoutsocket() definition.
|
||||
#
|
||||
if not hasattr(socket, "_no_timeoutsocket"):
|
||||
socket._no_timeoutsocket = socket.socket
|
||||
socket.socket = timeoutsocket
|
||||
del socket
|
||||
socket = timeoutsocket
|
||||
# Finis
|
@ -1,110 +0,0 @@
|
||||
VERSIONID(`$Id$')
|
||||
|
||||
|
||||
|
||||
divert(-1)
|
||||
|
||||
define(`_USAGE_', `dnl
|
||||
errprint(`*** ERROR: missing argument for FEATURE(verifysender):
|
||||
Usage: FEATURE(`verifysender', `_mode_', `_return_')
|
||||
_mode_: black or white
|
||||
_return_: temp or perm
|
||||
found: $1
|
||||
')')
|
||||
|
||||
ifelse(_ARG_, `black', `', `
|
||||
ifelse(_ARG_, `white', `', `
|
||||
_USAGE_(`_mode_: ('_ARG_`)
|
||||
')
|
||||
')')
|
||||
|
||||
ifelse(_ARG2_, `temp', `', `
|
||||
ifelse(_ARG2_, `perm', `', `
|
||||
_USAGE_(`_return_: ('_ARG2_`)
|
||||
')
|
||||
')')
|
||||
|
||||
define(`_mode_', _ARG_)
|
||||
define(`_return_', _ARG2_)
|
||||
|
||||
errprint(`*** _mode_: '_mode_`
|
||||
')
|
||||
errprint(`*** _return_: '_return_`
|
||||
')
|
||||
|
||||
|
||||
define(`_T_DSN_', `4.1.0')
|
||||
define(`_T_REPLY', `451')
|
||||
ifelse(_return_, `temp', `
|
||||
define(`_DSN_', _T_DSN_)
|
||||
define(`_REPLY_', _T_REPLY)', `dnl
|
||||
define(`_DSN_', `5.1.0')
|
||||
define(`_REPLY_', `550')')
|
||||
|
||||
ifelse(defn(`confVERIFIER_MAP'), `', `
|
||||
define(`_VERIFIER_MAP_', `inet:8884@127.0.0.1')', `
|
||||
define(`_VERIFIER_MAP_', confVERIFIER_MAP)')
|
||||
|
||||
ifelse(defn(`confVERIFIER_BLACKLIST'), `', `
|
||||
define(`_VERIFIER_BLACKLIST_', `/etc/mail/verifier-black-list')', `
|
||||
define(`_VERIFIER_BLACKLIST_', confVERIFIER_BLACKLIST)')
|
||||
|
||||
ifelse(defn(`confVERIFIER_WHITELIST'), `', `
|
||||
define(`_VERIFIER_WHITELIST_', `/etc/mail/verifier-white-list')', `
|
||||
define(`_VERIFIER_WHITELIST_', confVERIFIER_WHITELIST)')
|
||||
|
||||
divert(0)
|
||||
|
||||
LOCAL_CONFIG
|
||||
# Adjust the port
|
||||
Kverifier socket -T<temp> _VERIFIER_MAP_
|
||||
ifelse(_mode_, `white', `dnl
|
||||
Kverifier_helper hash -o _VERIFIER_WHITELIST_', `dnl
|
||||
Kverifier_helper hash _VERIFIER_BLACKLIST_')
|
||||
C{verifier_fix_white} postmaster
|
||||
|
||||
LOCAL_RULESETS
|
||||
# This ruleset can be used to test the verifier in -bt mode
|
||||
Svt
|
||||
R$+ $: < $(verifier $1 $:none $) >
|
||||
|
||||
Sverifier0
|
||||
R< $={verifier_fix_white} @ $+ > $@ < ok >
|
||||
R< $+ @ $+ > $: < $2 > < $(verifier_helper $1 @ $2 $: $) >
|
||||
R< $+ > < > $: < $(verifier_helper $1 $: $) >
|
||||
ifelse(_mode_, `white', `dnl
|
||||
dnl if we found nothing in the whitelist, we continue with checking
|
||||
R< > $@ < cont >
|
||||
dnl if we found something in the whitelist, we skip further verifications
|
||||
R< $+ > $@ < ok >', `dnl
|
||||
dnl if we found nothing in the blacklist, we skip further verifications
|
||||
R< > $@ < ok >
|
||||
dnl if we found something in the blacklist, we continue with checking
|
||||
R< $+ > $@ < cont >')
|
||||
|
||||
Sverifier1
|
||||
R< $+ > $: < $(verifier $1 $:none $) >
|
||||
R< $* < temp > > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (1)"
|
||||
R< none > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (2)"
|
||||
R< <OK> $* > $@ < ok >
|
||||
R< <NOK> < $* > > $#error $@ _DSN_ $: "_REPLY_ Sender Address was verified as bad: " $1
|
||||
R< <TNOK> < $* > > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (3): " $1
|
||||
dnl if we get here, some is wrong with our code
|
||||
R$* $#error $@ 4.7.1 $: "451 Local configuration error <sv1>"
|
||||
|
||||
|
||||
SLocal_check_mail
|
||||
dnl MAILER-DAEMON address must not be verified
|
||||
R<> $@ <>
|
||||
dnl try to focus
|
||||
R$+ $: <> $>3 $1
|
||||
R<> $+ < @ $+ . > $: < $1 @ $2 >
|
||||
R<> $+ < @ $+ > $: < $1 @ $2 >
|
||||
dnl if unable to focus, rest of check_mail should take care (may be we should reject)
|
||||
R<> $* $@ OK
|
||||
R< $+ @ $+ > $: < $1 @ $2 > $>verifier0 < $1 @ $2 >
|
||||
R< $+ @ $+ > < cont > $: < $1 @ $2 > $>verifier1 < $1 @ $2 >
|
||||
R< $+ @ $+ > $# $* $# $3
|
||||
R< $+ @ $+ > < ok > $@ OK
|
||||
dnl if we get here, some is wrong with our code
|
||||
R$* $#error $@ 4.7.1 $: "451 Local configuration error <sv2>"
|
@ -1 +1 @@
|
||||
#AUTHOR# <#EMAIL#>
|
||||
Wolfgang Hottgenroth <woho@hottis.de>
|
||||
|
@ -0,0 +1 @@
|
||||
2004-11-09: 0.94: first public release
|
||||
|
@ -0,0 +1 @@
|
||||
See doc/smmapdfw.info please.
|
||||
|
@ -1,2 +1,3 @@
|
||||
SUBDIRS = libsmmapdfw smmapd verify_worker test_worker cyrus_worker
|
||||
SUBDIRS = libsmmapdfw smmapd verify_worker test_worker cyrus_worker doc m4 mib
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
SUBDIRS = libsmmapdfw smmapd verify_worker test_worker cyrus_worker
|
||||
SUBDIRS = libsmmapdfw smmapd verify_worker test_worker cyrus_worker doc m4 mib
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
|
@ -0,0 +1 @@
|
||||
See doc/smmapd.info please.
|
||||
|
@ -1,7 +1,13 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* enable verify cache */
|
||||
#undef ENABLE_VERIFY_CACHE
|
||||
/* enable cache */
|
||||
#undef ENABLE_CACHE
|
||||
|
||||
/* enable Net-SNMP */
|
||||
#undef ENABLE_NETSNMP
|
||||
|
||||
/* enable stats */
|
||||
#undef ENABLE_STATS
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
@ -33,6 +39,9 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `djbdns' library (-ldjbdns). */
|
||||
#undef HAVE_LIBDJBDNS
|
||||
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
|
309
smmapdfw/configure
vendored
309
smmapdfw/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.59 for smmapdfw 0.9.
|
||||
# Generated by GNU Autoconf 2.59 for smmapdfw 0.96.
|
||||
#
|
||||
# Report bugs to <woho@hottis.de>.
|
||||
#
|
||||
@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='smmapdfw'
|
||||
PACKAGE_TARNAME='smmapdfw'
|
||||
PACKAGE_VERSION='0.9'
|
||||
PACKAGE_STRING='smmapdfw 0.9'
|
||||
PACKAGE_VERSION='0.96'
|
||||
PACKAGE_STRING='smmapdfw 0.96'
|
||||
PACKAGE_BUGREPORT='woho@hottis.de'
|
||||
|
||||
# Factoring default headers for most tests.
|
||||
@ -953,7 +953,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures smmapdfw 0.9 to adapt to many kinds of systems.
|
||||
\`configure' configures smmapdfw 0.96 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1019,7 +1019,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of smmapdfw 0.9:";;
|
||||
short | recursive ) echo "Configuration of smmapdfw 0.96:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1028,6 +1028,7 @@ Optional Features:
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
--enable-maintainer-mode enable make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer
|
||||
--enable-stats Enables statistics collection. (default=no)
|
||||
--enable-shared[=PKGS]
|
||||
build shared libraries [default=yes]
|
||||
--enable-static[=PKGS]
|
||||
@ -1041,6 +1042,13 @@ Optional Packages:
|
||||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||
--with-bdb-lib-dir Directory for Berkeley DB library files
|
||||
--with-bdb-inc-dir Directory for Berkeley include files
|
||||
--with-djbdns-lib-dir Directory for Bernstein's djbdns library files
|
||||
--with-djbdns-inc-dir Directory for Bernstein's djbdns include files
|
||||
--with-netsnmp With Net-SNMP
|
||||
--with-netsnmp-lib-dir Directory for Net-SNMP library files
|
||||
--with-netsnmp-inc-dir Directory for Net-SNMP include files
|
||||
--with-netsnmp-bin-dir Directory for Net-SNMP bin files, specifically
|
||||
net-snmp-config
|
||||
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
||||
--with-pic try to use only PIC/non-PIC objects [default=use
|
||||
both]
|
||||
@ -1160,7 +1168,7 @@ fi
|
||||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
smmapdfw configure 0.9
|
||||
smmapdfw configure 0.96
|
||||
generated by GNU Autoconf 2.59
|
||||
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
@ -1174,7 +1182,7 @@ cat >&5 <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by smmapdfw $as_me 0.9, which was
|
||||
It was created by smmapdfw $as_me 0.96, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -1705,7 +1713,7 @@ fi
|
||||
|
||||
PACKAGE=smmapdfw
|
||||
|
||||
VERSION=0.9
|
||||
VERSION=0.96
|
||||
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||
{ { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
|
||||
@ -1844,7 +1852,7 @@ if test "${with_bdb_lib_dir+set}" = set; then
|
||||
withval="$with_bdb_lib_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
{ { echo "$as_me:$LINENO: error: Need bdb-lib-dir" >&5
|
||||
echo "$as_me: error: Need bdb-lib-dir" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
@ -1865,7 +1873,7 @@ if test "${with_bdb_inc_dir+set}" = set; then
|
||||
withval="$with_bdb_inc_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
{ { echo "$as_me:$LINENO: error: Need bdb-inc-dir" >&5
|
||||
echo "$as_me: error: Need bdb-inc-dir" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
@ -1880,14 +1888,125 @@ echo "$as_me: error: Need bdb-inc-dir" >&2;}
|
||||
|
||||
fi;
|
||||
|
||||
WITHOUT_DJBDNS=0
|
||||
|
||||
ENABLE_VERIFY_CACHE=1
|
||||
# Check whether --with-djbdns-lib-dir or --without-djbdns-lib-dir was given.
|
||||
if test "${with_djbdns_lib_dir+set}" = set; then
|
||||
withval="$with_djbdns_lib_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
WITHOUT_DJBDNS=1
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
LDFLAGS="$LDFLAGS -L$withval -R$withval"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
# Check whether --with-djbdns-inc-dir or --without-djbdns-inc-dir was given.
|
||||
if test "${with_djbdns_inc_dir+set}" = set; then
|
||||
withval="$with_djbdns_inc_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
WITHOUT_DJBDNS=1
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
|
||||
WITHOUT_NETSNMP=1
|
||||
|
||||
# Check whether --with-netsnmp or --without-netsnmp was given.
|
||||
if test "${with_netsnmp+set}" = set; then
|
||||
withval="$with_netsnmp"
|
||||
case "$withval" in
|
||||
no)
|
||||
WITHOUT_NETSNMP=1
|
||||
;;
|
||||
*)
|
||||
WITHOUT_NETSNMP=0
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
|
||||
# Check whether --with-netsnmp-lib-dir or --without-netsnmp-lib-dir was given.
|
||||
if test "${with_netsnmp_lib_dir+set}" = set; then
|
||||
withval="$with_netsnmp_lib_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
LDFLAGS="$LDFLAGS -L$withval -R$withval"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
# Check whether --with-netsnmp-inc-dir or --without-netsnmp-inc-dir was given.
|
||||
if test "${with_netsnmp_inc_dir+set}" = set; then
|
||||
withval="$with_netsnmp_inc_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
NETSNMP_BINDIR=""
|
||||
|
||||
# Check whether --with-netsnmp-bin-dir or --without-netsnmp-bin-dir was given.
|
||||
if test "${with_netsnmp_bin_dir+set}" = set; then
|
||||
withval="$with_netsnmp_bin_dir"
|
||||
case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
NETSNMP_BINDIR="$withval/"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi;
|
||||
|
||||
|
||||
ENABLE_CACHE=1
|
||||
|
||||
|
||||
|
||||
|
||||
ENABLE_STATS=0
|
||||
# Check whether --enable-stats or --disable-stats was given.
|
||||
if test "${enable_stats+set}" = set; then
|
||||
enableval="$enable_stats"
|
||||
if test "x$enableval" = xyes; then ENABLE_STATS=1; fi
|
||||
if test "x$enableval" = xno; then ENABLE_STATS=0; fi
|
||||
|
||||
|
||||
fi;
|
||||
|
||||
# Checks for programs.
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
@ -3412,7 +3531,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 3415 "configure"' > conftest.$ac_ext
|
||||
echo '#line 3534 "configure"' > conftest.$ac_ext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@ -4867,7 +4986,7 @@ fi
|
||||
|
||||
|
||||
# Provide some information about the compiler.
|
||||
echo "$as_me:4870:" \
|
||||
echo "$as_me:4989:" \
|
||||
"checking for Fortran 77 compiler version" >&5
|
||||
ac_compiler=`set X $ac_compile; echo $2`
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
|
||||
@ -5899,11 +6018,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:5902: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6021: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:5906: \$? = $ac_status" >&5
|
||||
echo "$as_me:6025: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -6132,11 +6251,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6135: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6254: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6139: \$? = $ac_status" >&5
|
||||
echo "$as_me:6258: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -6192,11 +6311,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6195: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6314: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:6199: \$? = $ac_status" >&5
|
||||
echo "$as_me:6318: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -8380,7 +8499,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8383 "configure"
|
||||
#line 8502 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -8478,7 +8597,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 8481 "configure"
|
||||
#line 8600 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -10655,11 +10774,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:10658: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:10777: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:10662: \$? = $ac_status" >&5
|
||||
echo "$as_me:10781: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -10715,11 +10834,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:10718: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:10837: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:10722: \$? = $ac_status" >&5
|
||||
echo "$as_me:10841: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -12084,7 +12203,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12087 "configure"
|
||||
#line 12206 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12182,7 +12301,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 12185 "configure"
|
||||
#line 12304 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -13009,11 +13128,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13012: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13131: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:13016: \$? = $ac_status" >&5
|
||||
echo "$as_me:13135: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -13069,11 +13188,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:13072: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:13191: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:13076: \$? = $ac_status" >&5
|
||||
echo "$as_me:13195: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -15114,11 +15233,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15117: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15236: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15121: \$? = $ac_status" >&5
|
||||
echo "$as_me:15240: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -15347,11 +15466,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15350: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15469: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:15354: \$? = $ac_status" >&5
|
||||
echo "$as_me:15473: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings
|
||||
@ -15407,11 +15526,11 @@ else
|
||||
-e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:15410: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:15529: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:15414: \$? = $ac_status" >&5
|
||||
echo "$as_me:15533: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@ -17595,7 +17714,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17598 "configure"
|
||||
#line 17717 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17693,7 +17812,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 17696 "configure"
|
||||
#line 17815 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -19102,7 +19221,6 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5
|
||||
echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then
|
||||
@ -19249,6 +19367,92 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
if test "x$WITHOUT_DJBDNS" = "x0"; then
|
||||
|
||||
echo "$as_me:$LINENO: checking for dns_transmit_start in -ldjbdns" >&5
|
||||
echo $ECHO_N "checking for dns_transmit_start in -ldjbdns... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_djbdns_dns_transmit_start+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-ldjbdns $LIBS"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any gcc2 internal prototype to avoid an error. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
/* We use char because int might match the return type of a gcc2
|
||||
builtin and then its argument prototype would still apply. */
|
||||
char dns_transmit_start ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
dns_transmit_start ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
|
||||
(eval $ac_link) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
ac_cv_lib_djbdns_dns_transmit_start=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_lib_djbdns_dns_transmit_start=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $ac_cv_lib_djbdns_dns_transmit_start" >&5
|
||||
echo "${ECHO_T}$ac_cv_lib_djbdns_dns_transmit_start" >&6
|
||||
if test $ac_cv_lib_djbdns_dns_transmit_start = yes; then
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBDJBDNS 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-ldjbdns $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
ENABLE_NETSNMP=0
|
||||
if test "x$WITHOUT_NETSNMP" = "x0"; then
|
||||
NET_SNMP_CONFIG=$NETSNMP_BINDIR"net-snmp-config"
|
||||
NETSNMP_LIBS_1=`$NET_SNMP_CONFIG --agent-libs`
|
||||
NETSNMP_LIBS_2=`$NET_SNMP_CONFIG --libs`
|
||||
LIBS="$LIBS $NETSNMP_LIBS_1 $NETSNMP_LIBS_2"
|
||||
ENABLE_NETSNMP=1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
|
||||
@ -20939,7 +21143,7 @@ done
|
||||
|
||||
|
||||
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
echo "$as_me:$LINENO: checking for __db_ndbm_open in -ldb" >&5
|
||||
echo $ECHO_N "checking for __db_ndbm_open in -ldb... $ECHO_C" >&6
|
||||
if test "${ac_cv_lib_db___db_ndbm_open+set}" = set; then
|
||||
@ -21223,12 +21427,22 @@ fi
|
||||
|
||||
if test "x$BDB_NOT_FOUND" = "x1"; then
|
||||
echo "*** no db/dbm found, disabling verify cache"
|
||||
ENABLE_VERIFY_CACHE=0
|
||||
ENABLE_CACHE=0
|
||||
fi
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ENABLE_VERIFY_CACHE ${ENABLE_VERIFY_CACHE}
|
||||
#define ENABLE_CACHE ${ENABLE_CACHE}
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ENABLE_STATS ${ENABLE_STATS}
|
||||
_ACEOF
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define ENABLE_NETSNMP ${ENABLE_NETSNMP}
|
||||
_ACEOF
|
||||
|
||||
|
||||
@ -21237,7 +21451,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile libsmmapdfw/Makefile smmapd/Makefile test_worker/Makefile verify_worker/Makefile cyrus_worker/Makefile"
|
||||
ac_config_files="$ac_config_files Makefile libsmmapdfw/Makefile smmapd/Makefile test_worker/Makefile verify_worker/Makefile cyrus_worker/Makefile doc/Makefile m4/Makefile mib/Makefile"
|
||||
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
@ -21602,7 +21816,7 @@ _ASBOX
|
||||
} >&5
|
||||
cat >&5 <<_CSEOF
|
||||
|
||||
This file was extended by smmapdfw $as_me 0.9, which was
|
||||
This file was extended by smmapdfw $as_me 0.96, which was
|
||||
generated by GNU Autoconf 2.59. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -21665,7 +21879,7 @@ _ACEOF
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
smmapdfw config.status 0.9
|
||||
smmapdfw config.status 0.96
|
||||
configured by $0, generated by GNU Autoconf 2.59,
|
||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||
|
||||
@ -21781,6 +21995,9 @@ do
|
||||
"test_worker/Makefile" ) CONFIG_FILES="$CONFIG_FILES test_worker/Makefile" ;;
|
||||
"verify_worker/Makefile" ) CONFIG_FILES="$CONFIG_FILES verify_worker/Makefile" ;;
|
||||
"cyrus_worker/Makefile" ) CONFIG_FILES="$CONFIG_FILES cyrus_worker/Makefile" ;;
|
||||
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
|
||||
"m4/Makefile" ) CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;;
|
||||
"mib/Makefile" ) CONFIG_FILES="$CONFIG_FILES mib/Makefile" ;;
|
||||
"default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
|
||||
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
||||
|
@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
|
||||
AC_INIT(smmapdfw, 0.9, woho@hottis.de)
|
||||
AM_INIT_AUTOMAKE(smmapdfw, 0.9)
|
||||
AC_INIT(smmapdfw, 0.96, woho@hottis.de)
|
||||
AM_INIT_AUTOMAKE(smmapdfw, 0.96)
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
@ -15,7 +15,7 @@ AC_ARG_WITH(bdb-lib-dir,
|
||||
Directory for Berkeley DB library files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
AC_MSG_ERROR(Need bdb-lib-dir)
|
||||
fi
|
||||
;;
|
||||
@ -32,7 +32,7 @@ AC_ARG_WITH(bdb-inc-dir,
|
||||
Directory for Berkeley include files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
AC_MSG_ERROR(Need bdb-inc-dir)
|
||||
fi
|
||||
;;
|
||||
@ -44,8 +44,99 @@ AC_ARG_WITH(bdb-inc-dir,
|
||||
esac ]
|
||||
)
|
||||
|
||||
WITHOUT_DJBDNS=0
|
||||
AC_ARG_WITH(djbdns-lib-dir,
|
||||
[AC_HELP_STRING(--with-djbdns-lib-dir, [
|
||||
Directory for Bernstein's djbdns library files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
WITHOUT_DJBDNS=1
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
LDFLAGS="$LDFLAGS -L$withval -R$withval"
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
ENABLE_VERIFY_CACHE=1
|
||||
AC_ARG_WITH(djbdns-inc-dir,
|
||||
[AC_HELP_STRING(--with-djbdns-inc-dir, [
|
||||
Directory for Bernstein's djbdns include files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
WITHOUT_DJBDNS=1
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
|
||||
|
||||
WITHOUT_NETSNMP=1
|
||||
AC_ARG_WITH(netsnmp,
|
||||
[AC_HELP_STRING(--with-netsnmp, [
|
||||
With Net-SNMP])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
WITHOUT_NETSNMP=1
|
||||
;;
|
||||
*)
|
||||
WITHOUT_NETSNMP=0
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
|
||||
AC_ARG_WITH(netsnmp-lib-dir,
|
||||
[AC_HELP_STRING(--with-netsnmp-lib-dir, [
|
||||
Directory for Net-SNMP library files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
LDFLAGS="$LDFLAGS -L$withval -R$withval"
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(netsnmp-inc-dir,
|
||||
[AC_HELP_STRING(--with-netsnmp-inc-dir, [
|
||||
Directory for Net-SNMP include files])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
CPPFLAGS="$CPPFLAGS -I$withval"
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
NETSNMP_BINDIR=""
|
||||
AC_ARG_WITH(netsnmp-bin-dir,
|
||||
[AC_HELP_STRING(--with-netsnmp-bin-dir, [
|
||||
Directory for Net-SNMP bin files, specifically net-snmp-config])],
|
||||
[ case "$withval" in
|
||||
no)
|
||||
;;
|
||||
yes)
|
||||
;;
|
||||
*)
|
||||
NETSNMP_BINDIR="$withval/"
|
||||
;;
|
||||
esac ]
|
||||
)
|
||||
|
||||
|
||||
ENABLE_CACHE=1
|
||||
dnl AC_ARG_ENABLE(verify-cache,
|
||||
dnl [AC_HELP_STRING(--enable-verify-cache, [
|
||||
dnl Enables the cache in the verify worker.
|
||||
@ -79,7 +170,15 @@ dnl (default=no)])],
|
||||
dnl cyrus_BUILD=libcyrus_worker.la
|
||||
dnl )
|
||||
|
||||
ENABLE_STATS=0
|
||||
AC_ARG_ENABLE(stats,
|
||||
[AC_HELP_STRING(--enable-stats, [
|
||||
Enables statistics collection.
|
||||
(default=no)])],
|
||||
if test "x$enableval" = xyes; then ENABLE_STATS=1; fi
|
||||
if test "x$enableval" = xno; then ENABLE_STATS=0; fi
|
||||
|
||||
)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
@ -100,10 +199,23 @@ AC_CHECK_LIB(pthread, pthread_create,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
AC_CHECK_LIB([resolv], [inet_aton])
|
||||
AC_CHECK_LIB([socket], [connect])
|
||||
|
||||
if test "x$WITHOUT_DJBDNS" = "x0"; then
|
||||
AC_CHECK_LIB([djbdns], [dns_transmit_start])
|
||||
fi
|
||||
|
||||
ENABLE_NETSNMP=0
|
||||
if test "x$WITHOUT_NETSNMP" = "x0"; then
|
||||
NET_SNMP_CONFIG=$NETSNMP_BINDIR"net-snmp-config"
|
||||
NETSNMP_LIBS_1=`$NET_SNMP_CONFIG --agent-libs`
|
||||
NETSNMP_LIBS_2=`$NET_SNMP_CONFIG --libs`
|
||||
LIBS="$LIBS $NETSNMP_LIBS_1 $NETSNMP_LIBS_2"
|
||||
ENABLE_NETSNMP=1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
@ -130,7 +242,7 @@ AC_CHECK_FUNCS([inet_ntoa memset select socket strchr strdup strerror strrchr st
|
||||
|
||||
|
||||
|
||||
if test "x$ENABLE_VERIFY_CACHE" = "x1"; then
|
||||
if test "x$ENABLE_CACHE" = "x1"; then
|
||||
AC_CHECK_LIB([db], [__db_ndbm_open],
|
||||
[ BDB_LIBS="-ldb" ],
|
||||
AC_CHECK_LIB([db], [__db_ndbm_open_4002],
|
||||
@ -150,10 +262,12 @@ AC_SUBST(BDB_LIBS)
|
||||
|
||||
if test "x$BDB_NOT_FOUND" = "x1"; then
|
||||
echo "*** no db/dbm found, disabling verify cache"
|
||||
ENABLE_VERIFY_CACHE=0
|
||||
ENABLE_CACHE=0
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(ENABLE_VERIFY_CACHE, ${ENABLE_VERIFY_CACHE}, [enable verify cache])
|
||||
AC_DEFINE_UNQUOTED(ENABLE_CACHE, ${ENABLE_CACHE}, [enable cache])
|
||||
AC_DEFINE_UNQUOTED(ENABLE_STATS, ${ENABLE_STATS}, [enable stats])
|
||||
AC_DEFINE_UNQUOTED(ENABLE_NETSNMP, ${ENABLE_NETSNMP}, [enable Net-SNMP])
|
||||
|
||||
|
||||
|
||||
@ -163,6 +277,6 @@ dnl AC_SUBST(test_BUILD)
|
||||
dnl AC_SUBST(cyrus_BUILD)
|
||||
|
||||
|
||||
AC_CONFIG_FILES([Makefile libsmmapdfw/Makefile smmapd/Makefile test_worker/Makefile verify_worker/Makefile cyrus_worker/Makefile])
|
||||
AC_CONFIG_FILES([Makefile libsmmapdfw/Makefile smmapd/Makefile test_worker/Makefile verify_worker/Makefile cyrus_worker/Makefile doc/Makefile m4/Makefile mib/Makefile])
|
||||
|
||||
AC_OUTPUT
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
@ -6,7 +26,9 @@
|
||||
#include "smmapd.h"
|
||||
|
||||
#include "smtp.h"
|
||||
#include "dns.h"
|
||||
#include "htdns.h"
|
||||
#include "htmalloc.h"
|
||||
#include "stats.h"
|
||||
|
||||
#define SMM_LOCAL_PERM_NOK 101
|
||||
#define SMM_LOCAL_TEMP_NOK 102
|
||||
@ -25,6 +47,7 @@ struct cyrus_container_handle_s {
|
||||
typedef struct cyrus_container_handle_s cyrus_container_handle_t;
|
||||
|
||||
|
||||
|
||||
struct cyrus_work_handle_s {
|
||||
int id;
|
||||
cyrus_container_handle_t *cch;
|
||||
@ -36,25 +59,25 @@ typedef struct cyrus_work_handle_s cyrus_work_handle_t;
|
||||
|
||||
int cyrus_init(cfgl_t *cfg, void **handle);
|
||||
int cyrus_destroy(void *handle);
|
||||
/* int cyrus_work_setup(void *handle, void **work_handle); */
|
||||
/* int cyrus_work_setup(void *handle, void **work_handle); */
|
||||
int cyrus_work(void *handle, void *work_handle, char *input, char *output);
|
||||
/* int cyrus_work_destroy(void *handle, void *work_handle); */
|
||||
/* int cyrus_work_destroy(void *handle, void *work_handle); */
|
||||
|
||||
|
||||
class_descriptor_t cyruscheck = {
|
||||
"cyruscheck",
|
||||
&cyrus_init,
|
||||
&cyrus_destroy,
|
||||
NULL, /* &verify_work_setup, */
|
||||
NULL, /* &cyrus_work_setup, */
|
||||
&cyrus_work,
|
||||
NULL /* &cyrus_work_destroy */
|
||||
NULL /* &cyrus_work_destroy */
|
||||
};
|
||||
|
||||
|
||||
int cyrus_init(cfgl_t *cfg, void **handle) {
|
||||
cyrus_container_handle_t *cch;
|
||||
|
||||
cch = (cyrus_container_handle_t*) malloc(sizeof(cyrus_container_handle_t));
|
||||
cch = (cyrus_container_handle_t*) htmalloc(sizeof(cyrus_container_handle_t));
|
||||
cch->cfg = cfg;
|
||||
|
||||
cch->timeout = atoi(findcfglx(cch->cfg, "timeout", "5"));
|
||||
@ -74,6 +97,8 @@ int cyrus_destroy(void *handle) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
static const char *DEFAULT_ANSWER = "default answer";
|
||||
static const char *ILLEGAL_INPUT = "illegal input (must be 'depot_uid depot_host')";
|
||||
@ -82,6 +107,8 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
static const char *GO_AHEAD = "go ahead";
|
||||
static const char *DEPOT_DNS_ERROR = "depot could not be found in dns";
|
||||
|
||||
static int log_id = 0;
|
||||
|
||||
cyrus_container_handle_t *cch = (cyrus_container_handle_t*) handle;
|
||||
int result = SMM_TEMP_NOK;
|
||||
char *depot_uid, *depot_host, *response_text, *tmp_arg;
|
||||
@ -95,12 +122,16 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
} state = CONNECT;
|
||||
|
||||
|
||||
log_id++;
|
||||
|
||||
syslog(LOG_DEBUG, "cyrus_work: going to check %s", input);
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) going to check %s", log_id, input);
|
||||
|
||||
incStatCounter(STAT_CNT_CYRUS_WORKER);
|
||||
|
||||
depot_uid = input;
|
||||
if (NULL == (depot_host = strchr(depot_uid, ' '))) {
|
||||
snprintf(output, ANSWER_BUFSIZE, ILLEGAL_INPUT);
|
||||
incStatCounter(STAT_CNT_CYRUS_ILLEGAL_INPUT);
|
||||
return SMM_PERM_NOK;
|
||||
}
|
||||
|
||||
@ -110,9 +141,10 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
|
||||
a_rdata = get_a_rrs(depot_host);
|
||||
if (NULL == a_rdata) {
|
||||
syslog(LOG_DEBUG, "cyrus_work: depot_host %s could not be found in dns",
|
||||
depot_host);
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) depot_host %s could not be found in dns",
|
||||
log_id, depot_host);
|
||||
snprintf(output, ANSWER_BUFSIZE, DEPOT_DNS_ERROR);
|
||||
incStatCounter(STAT_CNT_CYRUS_DEPOT_DNS_FAILURE);
|
||||
return SMM_TEMP_NOK;
|
||||
}
|
||||
|
||||
@ -120,13 +152,14 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
free_rrs((void**)a_rdata);
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "cyrus_work: depot_uid %s, depot_host %s", depot_uid, depot_host);
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) depot_uid %s, depot_host %s", log_id,
|
||||
depot_uid, depot_host);
|
||||
|
||||
|
||||
lmtp = smtp_init(ip_address, cch->lmtp_port, cch->timeout);
|
||||
|
||||
while ((END != state) && (0 == done)) {
|
||||
syslog(LOG_DEBUG, "cyrus_work, lmtp dialog state %d", state);
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) lmtp dialog state %d", log_id, state);
|
||||
switch(state) {
|
||||
case CONNECT:
|
||||
err = smtp_connect(lmtp);
|
||||
@ -138,7 +171,7 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
err = smtp_mailfrom(lmtp, cch->sender_address);
|
||||
break;
|
||||
case RCPTTO:
|
||||
tmp_arg = (char*) malloc(sizeof(char) * (strlen(depot_uid)+5));
|
||||
tmp_arg = (char*) htmalloc(sizeof(char) * (strlen(depot_uid)+5));
|
||||
*tmp_arg = '\0';
|
||||
strcat(tmp_arg, "<");
|
||||
strcat(tmp_arg, depot_uid);
|
||||
@ -158,7 +191,7 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
|
||||
switch(err) {
|
||||
case SMTP_TIMEOUT:
|
||||
syslog(LOG_DEBUG, "cyrus_work, timeout in lmtp dialog");
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) timeout in lmtp dialog", log_id);
|
||||
result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)TIMEOUT_ERROR;
|
||||
done = 1;
|
||||
@ -167,13 +200,14 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
/* evaluate smtp_response, return or continue */
|
||||
err = smtp_response(lmtp, &response_text);
|
||||
if (-1 == err) {
|
||||
syslog(LOG_DEBUG, "cyrus_work, response could not be parsed");
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) response could not be parsed", log_id);
|
||||
result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)UNEXPECTED_ERROR;
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
syslog(LOG_DEBUG, "cyrus_work, response: %d, %s", err, response_text);
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) response: %d, %s", log_id,
|
||||
err, response_text);
|
||||
switch(err/100) {
|
||||
case 4:
|
||||
result = SMM_LOCAL_TEMP_NOK;
|
||||
@ -193,7 +227,7 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_DEBUG, "cyrus_work, unexpected error in lmtp dialog");
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) unexpected error in lmtp dialog", log_id);
|
||||
result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)UNEXPECTED_ERROR;
|
||||
done = 1;
|
||||
@ -208,14 +242,17 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
case SMM_LOCAL_TEMP_NOK:
|
||||
snprintf(output, ANSWER_BUFSIZE, "<TNOK><%s>", response_text);
|
||||
result = SMM_OK;
|
||||
incStatCounter(STAT_CNT_CYRUS_RETURNED_TNOK);
|
||||
break;
|
||||
case SMM_LOCAL_PERM_NOK:
|
||||
snprintf(output, ANSWER_BUFSIZE, "<NOK><%s>", response_text);
|
||||
result = SMM_OK;
|
||||
incStatCounter(STAT_CNT_CYRUS_RETURNED_NOK);
|
||||
break;
|
||||
case SMM_LOCAL_OK:
|
||||
snprintf(output, ANSWER_BUFSIZE, "<OK><%s>", response_text);
|
||||
result = SMM_OK;
|
||||
incStatCounter(STAT_CNT_CYRUS_RETURNED_OK);
|
||||
break;
|
||||
default:
|
||||
snprintf(output, ANSWER_BUFSIZE, response_text);
|
||||
@ -224,6 +261,8 @@ int cyrus_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
|
||||
smtp_destroy(lmtp);
|
||||
|
||||
syslog(LOG_DEBUG, "cyrus_work: (%04x) result %d, %s", log_id,
|
||||
result, output);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
1
smmapdfw/doc/Makefile.am
Normal file
1
smmapdfw/doc/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
info_TEXINFOS = smmapdfw.texi
|
325
smmapdfw/doc/Makefile.in
Normal file
325
smmapdfw/doc/Makefile.in
Normal file
@ -0,0 +1,325 @@
|
||||
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
BDB_LIBS = @BDB_LIBS@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
GCJ = @GCJ@
|
||||
GCJFLAGS = @GCJFLAGS@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
LIB = @LIB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
info_TEXINFOS = smmapdfw.texi
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
TEXI2DVI = texi2dvi
|
||||
INFO_DEPS = smmapdfw.info
|
||||
DVIS = smmapdfw.dvi
|
||||
TEXINFOS = smmapdfw.texi
|
||||
DIST_COMMON = README Makefile.am Makefile.in texinfo.tex
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .dvi .info .ps .texi .texinfo .txi
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
smmapdfw.info: smmapdfw.texi
|
||||
smmapdfw.dvi: smmapdfw.texi
|
||||
|
||||
|
||||
DVIPS = dvips
|
||||
|
||||
.texi.info:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
|
||||
.texi.dvi:
|
||||
TEXINPUTS=.:$$TEXINPUTS \
|
||||
MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
||||
|
||||
.texi:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
|
||||
.texinfo.info:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
|
||||
.texinfo:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
|
||||
.texinfo.dvi:
|
||||
TEXINPUTS=.:$$TEXINPUTS \
|
||||
MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
||||
|
||||
.txi.info:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
|
||||
.txi.dvi:
|
||||
TEXINPUTS=.:$$TEXINPUTS \
|
||||
MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
||||
|
||||
.txi:
|
||||
@cd $(srcdir) && rm -f $@ $@-[0-9] $@-[0-9][0-9]
|
||||
cd $(srcdir) \
|
||||
&& $(MAKEINFO) `echo $< | sed 's,.*/,,'`
|
||||
.dvi.ps:
|
||||
$(DVIPS) $< -o $@
|
||||
|
||||
install-info-am: $(INFO_DEPS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(infodir)
|
||||
@list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
d=$(srcdir); \
|
||||
for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
|
||||
if test -f $$d/$$ifile; then \
|
||||
echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; \
|
||||
$(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; \
|
||||
else : ; fi; \
|
||||
done; \
|
||||
done
|
||||
@$(POST_INSTALL)
|
||||
@if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file";\
|
||||
install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :;\
|
||||
done; \
|
||||
else : ; fi
|
||||
|
||||
uninstall-info:
|
||||
$(PRE_UNINSTALL)
|
||||
@if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
|
||||
ii=yes; \
|
||||
else ii=; fi; \
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
test -z "$$ii" \
|
||||
|| install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; \
|
||||
done
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(INFO_DEPS)'; \
|
||||
for file in $$list; do \
|
||||
(cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
|
||||
done
|
||||
|
||||
dist-info: $(INFO_DEPS)
|
||||
list='$(INFO_DEPS)'; \
|
||||
for base in $$list; do \
|
||||
d=$(srcdir); \
|
||||
for file in `cd $$d && eval echo $$base*`; do \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file; \
|
||||
done; \
|
||||
done
|
||||
|
||||
mostlyclean-aminfo:
|
||||
-rm -f smmapdfw.aux smmapdfw.cp smmapdfw.cps smmapdfw.dvi smmapdfw.fn \
|
||||
smmapdfw.fns smmapdfw.ky smmapdfw.kys smmapdfw.ps \
|
||||
smmapdfw.log smmapdfw.pg smmapdfw.toc smmapdfw.tp \
|
||||
smmapdfw.tps smmapdfw.vr smmapdfw.vrs smmapdfw.op smmapdfw.tr \
|
||||
smmapdfw.cv smmapdfw.cn
|
||||
|
||||
clean-aminfo:
|
||||
|
||||
distclean-aminfo:
|
||||
|
||||
maintainer-clean-aminfo:
|
||||
cd $(srcdir) && for i in $(INFO_DEPS); do \
|
||||
rm -f $$i; \
|
||||
if test "`echo $$i-[0-9]*`" != "$$i-[0-9]*"; then \
|
||||
rm -f $$i-[0-9]*; \
|
||||
fi; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = doc
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
here=`cd $(top_builddir) && pwd`; \
|
||||
top_distdir=`cd $(top_distdir) && pwd`; \
|
||||
distdir=`cd $(distdir) && pwd`; \
|
||||
cd $(top_srcdir) \
|
||||
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu doc/Makefile
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info
|
||||
info-am: $(INFO_DEPS)
|
||||
info: info-am
|
||||
dvi-am: $(DVIS)
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am:
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am: install-info-am
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am: uninstall-info
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile $(INFO_DEPS)
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(infodir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-aminfo clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-aminfo distclean-generic clean-am
|
||||
-rm -f libtool
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-aminfo maintainer-clean-generic \
|
||||
distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: install-info-am uninstall-info mostlyclean-aminfo \
|
||||
distclean-aminfo clean-aminfo maintainer-clean-aminfo tags distdir \
|
||||
info-am info dvi-am dvi check check-am installcheck-am installcheck \
|
||||
install-exec-am install-exec install-data-am install-data install-am \
|
||||
install uninstall-am uninstall all-redirect all-am all installdirs \
|
||||
mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -13,6 +13,7 @@ Copyright @copyright{} 2004 Wolfgang Hottgenroth
|
||||
@titlepage
|
||||
@title smmapdfw
|
||||
@subtitle A framework for workers for the sendmail socketmap
|
||||
@subtitle --- featuring a sender-address verifier and a Cyrus mailbox checker ---
|
||||
@author Wolfgang Hottgenroth
|
||||
|
||||
@page
|
||||
@ -32,6 +33,8 @@ Copyright @copyright{} 2004 Wolfgang Hottgenroth
|
||||
@menu
|
||||
* Motivation::
|
||||
* Overview::
|
||||
* Building smmapd from the sources::
|
||||
* Command line options::
|
||||
* Using from sendmail::
|
||||
* Configuration::
|
||||
* API::
|
||||
@ -39,29 +42,375 @@ Copyright @copyright{} 2004 Wolfgang Hottgenroth
|
||||
@detailmenu
|
||||
--- The Detailed Node Listing ---
|
||||
|
||||
Overview
|
||||
|
||||
* Sender-address verification plugin::
|
||||
* Cyrus mailbox check plugin::
|
||||
|
||||
Using from sendmail
|
||||
|
||||
* sender address verification::
|
||||
* Cyrus IMAP server mailbox checks::
|
||||
|
||||
Configuration
|
||||
|
||||
* Global::
|
||||
* Plugin::
|
||||
|
||||
Plugin
|
||||
|
||||
* Sender-address verifier::
|
||||
* Cyrus mailbox checker::
|
||||
|
||||
API
|
||||
|
||||
* Plugin interface::
|
||||
* Obtaining configuration data::
|
||||
* More or less useful stuff::
|
||||
|
||||
Plugin interface
|
||||
|
||||
* name::
|
||||
* Container setup function::
|
||||
* Container destroy function::
|
||||
* Worker setup function::
|
||||
* Worker destroy function::
|
||||
* Worker function::
|
||||
|
||||
Obtaining configuration data
|
||||
|
||||
* Without default value::
|
||||
* With default value::
|
||||
|
||||
More or less useful stuff
|
||||
|
||||
* count.h::
|
||||
* queue.h::
|
||||
* htdns.h::
|
||||
* htmalloc.h::
|
||||
* smtp.h::
|
||||
* safe_write.h::
|
||||
|
||||
@end detailmenu
|
||||
@end menu
|
||||
|
||||
@node Motivation, Overview, Top, Top
|
||||
@chapter Motivation
|
||||
Why smmapdfw
|
||||
With release 8.13 sendmail introduces the socket map type. A map can
|
||||
be defined where a query is sent over an socket to an external daemon,
|
||||
doing some computations on the query to send back the result over the
|
||||
socket.
|
||||
|
||||
@node Overview, Using from sendmail, Motivation, Top
|
||||
This opens another door to query data from external processes when
|
||||
performing mail routing. Thereby the already rich feature set of
|
||||
sendmail can be improved even more.
|
||||
|
||||
This framework provides all required stuff like a threaded tcp-server,
|
||||
the netstring codec, map name dispatching, configuration file
|
||||
processing and more, so someone who likes to design and implement a
|
||||
particular socket map and concentrate completely on the particular
|
||||
task the socket map has to perform.
|
||||
|
||||
The particular socket map processor appears as a shared object which
|
||||
is dynamically loaded by the daemon depending on the configuration.
|
||||
|
||||
@node Overview, Building smmapd from the sources, Motivation, Top
|
||||
@chapter Overview
|
||||
Overview over smmapdfw
|
||||
smmapdfw consists of the actual server -- smmapd --, a library --
|
||||
libsmmapdfw -- providing the API and three plugins, one useless
|
||||
example and two more useful ones: a sender-address verifier and a
|
||||
Cyrus mailbox checker.
|
||||
|
||||
@node Using from sendmail, Configuration, Overview, Top
|
||||
The server reads the configuration file, loads all configured plugins
|
||||
(socket map processors) and opens the configured tcp socket. It
|
||||
accepts requests on this tcp socket from sendmail in netstring
|
||||
encoding. For each connections it starts a thread. In this thread it
|
||||
dispatches the requests (the map name is part of the request) -- after
|
||||
decoding it from netstring and stripping the map name -- to the
|
||||
particular socket map processors. Afterwards it returns the result of
|
||||
the socket map processor -- after encoding it into netstring -- to
|
||||
sendmail.
|
||||
|
||||
The library provides all functions and types defined by the API. For
|
||||
details go ahead to the API section.
|
||||
|
||||
The socket map processors are implemented as plugins which are
|
||||
registered and loaded at run-time. They have to implement a worker
|
||||
function and may implement container and worker setup and destroy
|
||||
functions.
|
||||
|
||||
For each plugin two handles may be created: the container handle can
|
||||
be created at server start up time and lasts the whole lifetime of the
|
||||
server, the worker handle is created when a request is dispatched to a
|
||||
plugin and lasts for all requests coming in during the
|
||||
connection.
|
||||
|
||||
The container setup function, which a plugin can implement, is called
|
||||
at start up time, and returns the container handle.
|
||||
|
||||
The worker setup function, which a plugin can implement, is called
|
||||
when the first request of a connection is dispatched to the plugin,
|
||||
and returns the worker handle.
|
||||
|
||||
Both container and worker handle are provided to the worker function.
|
||||
|
||||
The framework stores both container and worker handle as void pointer,
|
||||
so each plugin has to define its own handle data structure.
|
||||
|
||||
|
||||
@menu
|
||||
* Sender-address verification plugin::
|
||||
* Cyrus mailbox check plugin::
|
||||
@end menu
|
||||
|
||||
@node Sender-address verification plugin, Cyrus mailbox check plugin, Overview, Overview
|
||||
@section Sender-address verification plugin
|
||||
This plugin performs verifications of sender-addresses.
|
||||
|
||||
An m4 file -- @file{verifysender.m4} -- providing a sendmail feature is
|
||||
part of the smmapdfw distribution.
|
||||
|
||||
To verify a sender-address, the plugin looks up the primary MX record
|
||||
of the domain of the sender-address and all IP addresses belonging to
|
||||
the found MX names.
|
||||
|
||||
For each IP address it starts a checker thread. Each checker thread
|
||||
starts an smtp dialog to the mail-server listening on the IP. It stops
|
||||
the dialog after an failure or latest after the @code{rcpt} command.
|
||||
It uses a configurable address as sender and the address under test as
|
||||
recipient. It collects the result given after the @code{rcpt} and
|
||||
returns depending on the code OK, temporary or permanent failure.
|
||||
|
||||
The first checker thread returning a permanent result (OK or permanent
|
||||
failure) wins and its result is stored in the cache (if enabled) and
|
||||
returned to sendmail.
|
||||
|
||||
If no checker thread delivers a permanent result within the result
|
||||
timeout, a temporary failure is returned. However, no checker thread
|
||||
is aborted and the result of the first one is then just stored in the
|
||||
cache.
|
||||
|
||||
|
||||
@node Cyrus mailbox check plugin, , Sender-address verification plugin, Overview
|
||||
@section Cyrus mailbox checker
|
||||
When sendmail performs final delivery via lmtp to a Cyrus IMAP server
|
||||
and the IMAP server returns a overquota failure, sendmail is in a
|
||||
somewhat unlucky position since it already has accepted the mail and
|
||||
nevertheless can not deliver it. It has to keep it in the queue. (So,
|
||||
the quota of a mailbox is unlimitly extended into sendmail's queue.)
|
||||
|
||||
Unlucky enough, but usually after five days of repeated unsuccessful
|
||||
delivery attempt the message is returned to its sender.
|
||||
|
||||
But it comes even more bad: the sender-address might be invalid, and
|
||||
now the message can not be returned.
|
||||
|
||||
So, it would be good to reject the message directly in the smtp dialog
|
||||
if the recipients mailbox is overquota.
|
||||
|
||||
Again, an m4 file -- @file{cyruscheck.m4} -- providing a sendmail
|
||||
feature is part of this distribution.
|
||||
|
||||
It hooks into the local parse ruleset and checks through the map
|
||||
utilizing this plugin the Cyrus IMAP server to see whether the
|
||||
particular mailbox can store more mail.
|
||||
|
||||
@node Building smmapd from the sources, Command line options, Overview, Top
|
||||
@chapter Building smmapd from the sources
|
||||
smmapd comes with a autoconf @file{configure} script.
|
||||
|
||||
To get some help for the parameters it supports, say
|
||||
|
||||
@verbatim
|
||||
./configure --help
|
||||
@end verbatim
|
||||
|
||||
Important options are these:
|
||||
|
||||
@verbatim
|
||||
--enable-stats Enables statistics collection. (default=no)
|
||||
--with-bdb-lib-dir Directory for Berkeley DB library files
|
||||
--with-bdb-inc-dir Directory for Berkeley include files
|
||||
--with-djbdns-lib-dir Directory for Bernstein's djbdns library files
|
||||
--with-djbdns-inc-dir Directory for Bernstein's djbdns include files
|
||||
--with-netsnmp With Net-SNMP
|
||||
--with-netsnmp-lib-dir Directory for Net-SNMP library files
|
||||
--with-netsnmp-inc-dir Directory for Net-SNMP include files
|
||||
--with-netsnmp-bin-dir Directory for Net-SNMP bin files, specifically
|
||||
net-snmp-config
|
||||
@end verbatim
|
||||
|
||||
The Berkeley DB (tested with version 4.1.25) is required for the cache
|
||||
of the verifier plugin.
|
||||
|
||||
DJB's resolver library (djbdns) is required on systems where the
|
||||
default resolver library is not thread-safe. (In my test-bed this was
|
||||
true for Solaris 8.)
|
||||
|
||||
To gather statistic data, use @code{--enable-stats}, to be able to
|
||||
retrieve statistic data through snmp use @code{--with-netsnmp}. snmp
|
||||
requires @code{--enable-stats}. If there are no direct paths to the
|
||||
Net-SNMP stuff (tested with Net-SNMP 5.1.2), use
|
||||
@code{--with-netsnmp-lib-dir}, @code{--with-netsnmp-inc-dir} and
|
||||
@code{--with-netsnmp-bin-dir}.
|
||||
|
||||
|
||||
@node Command line options, Using from sendmail, Building smmapd from the sources, Top
|
||||
@chapter Command line options
|
||||
|
||||
@table @code
|
||||
@item -F
|
||||
Run smmapd in foreground instead of daemonizing. Overwrites the
|
||||
@code{do_fork} configuration option.
|
||||
|
||||
@item -f <config-file>
|
||||
Use the given configuration file instead of the default one.
|
||||
|
||||
@item -p <pid-file>
|
||||
Write the pid when daemonizing to the given pid file instead of the
|
||||
one mentioned in the configuration file.
|
||||
|
||||
@item -v
|
||||
Display version information.
|
||||
|
||||
@item -h
|
||||
Display usage information.
|
||||
@end table
|
||||
|
||||
|
||||
@node Using from sendmail, Configuration, Command line options, Top
|
||||
@chapter Using from sendmail
|
||||
How to use smmapdfw from sendmail
|
||||
|
||||
To use a socket map in sendmail, it must be defined in the cf:
|
||||
|
||||
@verbatim
|
||||
Kverifier socket -T<temp> inet:8884@127.0.0.1
|
||||
@end verbatim
|
||||
|
||||
Then, the socket map can be used in rules as any other map too:
|
||||
|
||||
@verbatim
|
||||
R< $+ > $: < $1 > < $(verifier $1 $:none $) >
|
||||
@end verbatim
|
||||
|
||||
|
||||
Many socket maps can use the same socket:
|
||||
|
||||
@verbatim
|
||||
Kverifier socket -T<temp> inet:8884@127.0.0.1
|
||||
Kcyruscheck socket -T<temp> inet:8884@127.0.0.1
|
||||
Kdontknow socket -T<temp> inet:8884@127.0.0.1
|
||||
@end verbatim
|
||||
|
||||
(Here, the dispatcher of smmapdfw jumps in.)
|
||||
|
||||
@menu
|
||||
* sender address verification::
|
||||
* Cyrus IMAP server mailbox checks::
|
||||
@end menu
|
||||
|
||||
@node sender address verification, Cyrus IMAP server mailbox checks, Using from sendmail, Using from sendmail
|
||||
@section sender address verification
|
||||
|
||||
A sendmail feature file is delivered with smmapd to link the sender
|
||||
address verification into the ruleset @code{check_mail} hook
|
||||
@code{Local_check_mail}.
|
||||
|
||||
It takes three parameters and can be used in the @code{sendmail.mc}
|
||||
like this:
|
||||
|
||||
@verbatim
|
||||
FEATURE(`verifysender', `_mode_', `_return_', `_dummy_')
|
||||
@end verbatim
|
||||
|
||||
@code{_mode_} must be replaced by either @code{black} or
|
||||
@code{white}.
|
||||
|
||||
For @code{black} a blacklist in
|
||||
@code{/etc/mail/verifier-black-list} is considered and only sender
|
||||
addresses in there mentioned domains are verified.
|
||||
|
||||
The location of the blacklist can be configured using
|
||||
|
||||
@verbatim
|
||||
define(`confVERIFIER_BLACKLIST', `hash -o /prod/sendmail/etc/verifier-black-list')
|
||||
@end verbatim
|
||||
|
||||
|
||||
For @code{white} a whitelist in
|
||||
@code{/etc/mail/verifier-white-list} is considered and sender
|
||||
addresses in the whitelist or in domains mentioned in the whitelist
|
||||
are not verified.
|
||||
|
||||
The location of the whitelist can be configured using
|
||||
|
||||
@verbatim
|
||||
define(`confVERIFIER_WHITELIST', `hash -o /prod/sendmail/etc/verifier-white-list')
|
||||
@end verbatim
|
||||
|
||||
@code{confVERIFIER_BLACKLIST} and @code{confVERIFIER_WHITELIST} must
|
||||
appear in the @code{sendmail.mc} before the feature is called.
|
||||
|
||||
@code{_return_} must be replaced by either @code{temp} or
|
||||
@code{perm}.
|
||||
|
||||
If the sender address verification ends up in a permanent negative
|
||||
response from the home-server of the address, for @code{temp} a
|
||||
temporary failure (4xx), for @code{perm} a permanent
|
||||
failure (5xx) is returned.
|
||||
|
||||
@code{_dummy_} must be replaced by either @code{active} or
|
||||
@code{dummy}. If @code{dummy} is set here, the verifier is called but
|
||||
its result is just logged and not further considered for the routing.
|
||||
|
||||
The connection to the smmapd is configured using
|
||||
@code{define(`confVERIFIER_MAP')}.
|
||||
The default is
|
||||
|
||||
@verbatim
|
||||
define(`confVERIFIER_MAP', `inet:8884@127.0.0.1')
|
||||
@end verbatim
|
||||
|
||||
@node Cyrus IMAP server mailbox checks, , sender address verification, Using from sendmail
|
||||
@section Cyrus IMAP server mailbox checks
|
||||
|
||||
|
||||
A sendmail feature file @code{cyruscheck.m4} is delivered with
|
||||
smmapd. It provides a ruleset @code{cyruscheck}, which can by used in
|
||||
ruleset @code{ParseLocal}.
|
||||
|
||||
It can be used in the @code{sendmail.mc} like this:
|
||||
|
||||
@verbatim
|
||||
FEATURE(`cyruscheck', `_dummy_')
|
||||
@end verbatim
|
||||
|
||||
@code{_dummy_} must be replaced by either @code{active} or
|
||||
@code{dummy}. If @code{dummy} is set here, the verifier is called but
|
||||
its result is just logged and not further considered for the routing.
|
||||
|
||||
However, remember that only the ruleset @code{cyruscheck} is
|
||||
provided. You need to call it in your @code{LocalParse} ruleset on
|
||||
your own.
|
||||
|
||||
The ruleset takes two parameters: The mailbox name on the Cyrus IMAP
|
||||
server and the hostname of the Cyrus IMAP server, both in angle brackets.
|
||||
|
||||
The connection to the smmapd is configured using
|
||||
@code{define(`confCYRUSCHECK_MAP')}.
|
||||
The default is
|
||||
|
||||
@verbatim
|
||||
define(`confCYRUSCHECK_MAP', `inet:8884@127.0.0.1')
|
||||
@end verbatim
|
||||
|
||||
|
||||
|
||||
@node Configuration, API, Using from sendmail, Top
|
||||
@chapter Configuration
|
||||
How to configure smmapdfw
|
||||
The configuration file of smmapdfw has one global section, for the
|
||||
server itself and one section for each plugin.
|
||||
|
||||
|
||||
@menu
|
||||
* Global::
|
||||
@ -70,11 +419,202 @@ How to configure smmapdfw
|
||||
|
||||
@node Global, Plugin, Configuration, Configuration
|
||||
@section Global
|
||||
Global configuration items
|
||||
|
||||
@verbatim
|
||||
[global]
|
||||
do_fork = 0
|
||||
pid_file = smmapd.pid
|
||||
address = 127.0.0.1
|
||||
port = 8887
|
||||
; plugin_dir = /home/who/Sources/sf/smmapdfw
|
||||
; plugins = test_worker1 test_worker2 verifier cyruscheck lua_worker
|
||||
plugins = verifier
|
||||
enable_stats = 1
|
||||
enable_snmp = 1
|
||||
|
||||
|
||||
|
||||
@end verbatim
|
||||
|
||||
@table @samp
|
||||
@item do_fork
|
||||
Should the server fork into background. 0 or 1. May be overwritten by
|
||||
@code{-F} commandline switch.
|
||||
|
||||
@item pid_file
|
||||
Path and filename of the pidfile. May be overwritten by @code{-p}
|
||||
commandline switch.
|
||||
|
||||
@item address
|
||||
Address to bind socket on. Leave it out to bind on @code{IN_ANYADDR}.
|
||||
|
||||
@item port
|
||||
Port to bind socket on.
|
||||
|
||||
@item plugin_dir
|
||||
Directory where plugins can be found. Usually this parameter is not
|
||||
required, when plugins are installed in the lib path configured when
|
||||
building smmapdfw. Only one path can be given.
|
||||
|
||||
@item plugins
|
||||
Lists all plugins separated by spaces which should be loaded. The plugin name refers to
|
||||
the section name of the particular configuration section.
|
||||
|
||||
@item enable_stats
|
||||
This enables the statistics output thread. It is only available when
|
||||
smmapd was built with @code{--enable-stats}. Further configuration in
|
||||
section @code{stats} is required.
|
||||
|
||||
@item enable_snmp
|
||||
This enables the snmp AgentX subagent to retrieve statistic data. It
|
||||
is only available when smmapd was built with @code{--enable-stats} and
|
||||
@code{--with-netsnmp}. Further configuration in section @code{snmp} is required.
|
||||
@end table
|
||||
|
||||
|
||||
|
||||
@section stats
|
||||
|
||||
@verbatim
|
||||
[stats]
|
||||
stdout_nice = 2
|
||||
syslog_nice =1
|
||||
period = 1
|
||||
@end verbatim
|
||||
|
||||
The statistics output thread can write to stdout and/or syslog in two
|
||||
different format, one more human-readable, the other one more
|
||||
machine-readable.
|
||||
|
||||
The number after @code{stdout_nice} and @code{syslog_nice} specifies
|
||||
the format. 0 means no output on this channel, 1 means
|
||||
machine-readable output and 2 means human-readable output.
|
||||
|
||||
@code{period} specifies the time in seconds behind to statistic
|
||||
outputs.
|
||||
|
||||
@section snmp
|
||||
|
||||
@verbatim
|
||||
[snmp]
|
||||
agentx_socket = /var/agentx/master
|
||||
@end verbatim
|
||||
|
||||
The socket on which the snmpd is listening for AgentX subagents is
|
||||
specified here.
|
||||
|
||||
|
||||
@node Plugin, , Global, Configuration
|
||||
@section Plugin
|
||||
General plugin configuration items
|
||||
The section name of a plugin configuration section must be used in the
|
||||
@code{plugins} parameter of the @code{global} section.
|
||||
|
||||
Each plugin section must have at least the name of the shared object
|
||||
file from which the plugin should be loaded in the parameter @code{obj}.
|
||||
|
||||
All other parameters a completely under the control of the plugin
|
||||
designer/implementor.
|
||||
|
||||
@menu
|
||||
* Sender-address verifier::
|
||||
* Cyrus mailbox checker::
|
||||
@end menu
|
||||
|
||||
@node Sender-address verifier, Cyrus mailbox checker, Plugin, Plugin
|
||||
@subsection Sender-address verifier
|
||||
|
||||
@verbatim
|
||||
[verifier]
|
||||
obj = libverify_worker.so
|
||||
timeout_result = 5
|
||||
timeout_dialog = 20
|
||||
cache_enabled = 1
|
||||
cache_expiry = 86400
|
||||
cache_file = /var/lib/smmapdfw/verifier.cache
|
||||
sender_address = <>
|
||||
ehlo_arg = local
|
||||
smtp_port = 25
|
||||
max_checker_threads = 100
|
||||
|
||||
@end verbatim
|
||||
|
||||
|
||||
@table @samp
|
||||
@item obj
|
||||
The plugin should be loaded from the file @code{libverify_worker.so}.
|
||||
|
||||
@item timeout_result
|
||||
The plugin will return a result latest after this timeout. If there is
|
||||
no result at this time, a temporary failure will be returned. However,
|
||||
running verifications will not be aborted, so their results can go
|
||||
into the cache.
|
||||
|
||||
@item timeout_dialog
|
||||
Timeout for the smtp dialog to home servers of sender-addresses.
|
||||
|
||||
@item cache_enable
|
||||
Cache permenant results of verifications.
|
||||
|
||||
@item cache_expiry
|
||||
Expiry time of entries in the cache.
|
||||
|
||||
@item cache_file
|
||||
Path and filename of the cache.
|
||||
|
||||
@item sender_address
|
||||
This address will be used as sender-address in the verification
|
||||
dialog. Use some special to avoid verification loops. The address must
|
||||
be given in exactly that notation it should be used in the dialog.
|
||||
|
||||
@item ehlo_arg
|
||||
Argument to the @code{ehlo} command in the verification dialog. Note
|
||||
that certain MTA's require a full qualified domain name.
|
||||
|
||||
@item smtp_port
|
||||
Port to be used for smtp verification dialog.
|
||||
|
||||
@item max_checker_threads
|
||||
The verifier plugin looks up the primary MX for a sender-address and
|
||||
resolves all IP addresses for the found MX records. For each IP
|
||||
address it starts one checker thread. (The first one returning a
|
||||
permenant result wins.) This parameter limits the number of checker
|
||||
threads.
|
||||
@end table
|
||||
|
||||
@node Cyrus mailbox checker, , Sender-address verifier, Plugin
|
||||
@subsection Cyrus mailbox checker
|
||||
|
||||
@verbatim
|
||||
[cyruscheck]
|
||||
obj = libcyrus_worker.so
|
||||
timeout = 10
|
||||
sender_address = <testsender>
|
||||
lhlo_arg = local
|
||||
lmtp_port = 24
|
||||
|
||||
@end verbatim
|
||||
|
||||
|
||||
@table @samp
|
||||
@item obj
|
||||
The cyrus mailbox checker should be loaded from the file
|
||||
@code{libcyrus_worker.so}.
|
||||
|
||||
@item timeout
|
||||
Timeout for the lmtp dialog.
|
||||
|
||||
@item sender_address
|
||||
Address to be used as sender in the lmtp dialog.
|
||||
|
||||
@item lhlo_arg
|
||||
Argument for @code{lhlo} in the lmtp dialog.
|
||||
|
||||
@item lmtp_port
|
||||
Port to be used for the lmtp dialog.
|
||||
@end table
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -82,5 +622,315 @@ General plugin configuration items
|
||||
@chapter API
|
||||
API documentation for plugin programmers
|
||||
|
||||
@menu
|
||||
* Plugin interface::
|
||||
* Obtaining configuration data::
|
||||
* More or less useful stuff::
|
||||
@end menu
|
||||
|
||||
@node Plugin interface, Obtaining configuration data, API, API
|
||||
@section Plugin interface
|
||||
|
||||
Each plugin has to defined a class descriptor of the type
|
||||
@code{class_descriptor_t}.
|
||||
|
||||
@verbatim
|
||||
struct class_descriptor_s {
|
||||
char *name;
|
||||
int (*init_function)(cfgl_t *cfg, void **handle);
|
||||
int (*destroy_function)(void *handle);
|
||||
int (*work_setup_function)(void *handle, void **work_handle);
|
||||
int (*work_function)(void *handle, void *work_handle, char *input,
|
||||
char *output);
|
||||
int (*work_destroy_function)(void *handle, void *work_handle);
|
||||
};
|
||||
|
||||
typedef struct class_descriptor_s class_descriptor_t;
|
||||
|
||||
@end verbatim
|
||||
|
||||
The variable name of the class descriptor must be the same as the
|
||||
configuration section name from the configuration file. As an example:
|
||||
here is the descriptor of the verifier plugin:
|
||||
|
||||
@verbatim
|
||||
class_descriptor_t verifier = {
|
||||
"verifier",
|
||||
&verify_init,
|
||||
&verify_destroy,
|
||||
&verify_work_setup,
|
||||
&verify_work,
|
||||
&verify_work_destroy
|
||||
};
|
||||
|
||||
@end verbatim
|
||||
|
||||
@menu
|
||||
* name::
|
||||
* Container setup function::
|
||||
* Container destroy function::
|
||||
* Worker setup function::
|
||||
* Worker destroy function::
|
||||
* Worker function::
|
||||
@end menu
|
||||
|
||||
@node name, Container setup function, Plugin interface, Plugin interface
|
||||
@subsection @code{name}
|
||||
|
||||
This is the name of the plugin. It must match to the name of the
|
||||
plugin descriptor and the name of the plugin's configuration section.
|
||||
|
||||
@node Container setup function, Container destroy function, name, Plugin interface
|
||||
@subsection Container setup function: @code{init_function}
|
||||
|
||||
@code{int (*init_function)(cfgl_t *cfg, void **handle);}
|
||||
|
||||
The Container setup function is called at start up time. A handle to
|
||||
access the configuration is handed over and the container handle is
|
||||
expected back.
|
||||
|
||||
Each plugin defines its own structure for the container
|
||||
handle. Certainly it will store the configuration handle within.
|
||||
|
||||
|
||||
@node Container destroy function, Worker setup function, Container setup function, Plugin interface
|
||||
@subsection Container destroy function: @code{destroy_function}
|
||||
|
||||
@code{int (*destroy_function)(void *handle);}
|
||||
|
||||
The Container destroy function is called when the plugin is
|
||||
unloaded. Is happens currently never.
|
||||
|
||||
However, free any resources allocated for the container within this
|
||||
function.
|
||||
|
||||
|
||||
@node Worker setup function, Worker destroy function, Container destroy function, Plugin interface
|
||||
@subsection Worker setup function: @code{work_setup_function}
|
||||
|
||||
@code{int (*work_setup_function)(void *handle, void **work_handle);}
|
||||
|
||||
The worker setup function is called when the first request of one
|
||||
connection is dispatched to the plugin. The container handle is
|
||||
provided, the worker handle is expected back.
|
||||
|
||||
Each plugin defines its own structure for the worker handle.
|
||||
|
||||
|
||||
@node Worker destroy function, Worker function, Worker setup function, Plugin interface
|
||||
@subsection Worker destroy function: @code{work_destroy_function}
|
||||
|
||||
@code{int (*work_destroy_function)(void *handle, void *work_handle);}
|
||||
|
||||
The worker destroy function is called when the connection associated
|
||||
with the worker is closed.
|
||||
|
||||
Free any resources allocated for this worker. Do not free resources
|
||||
associated with the container.
|
||||
|
||||
@node Worker function, , Worker destroy function, Plugin interface
|
||||
@subsection Worker function: @code{work_function}
|
||||
|
||||
@code{int (*work_function)(void *handle, void *work_handle, char *input, char *output);}
|
||||
|
||||
The worker function is called for each request dispatched to this
|
||||
plugin. The container handle, the worker handle and of course the
|
||||
input is provided.
|
||||
|
||||
The return value must be one of
|
||||
|
||||
@verbatim
|
||||
#define SMM_OK 1
|
||||
#define SMM_TEMP_NOK 2
|
||||
#define SMM_PERM_NOK 3
|
||||
#define SMM_NOT_FOUND_NOK 4
|
||||
|
||||
@end verbatim
|
||||
|
||||
which matches to the codes sendmail expects in the response from a
|
||||
socket map.
|
||||
|
||||
@code{output} is the text returned with the code to
|
||||
sendmail. Especially for @code{SMM_OK} this is the return value of the
|
||||
map.
|
||||
|
||||
|
||||
@node Obtaining configuration data, More or less useful stuff, Plugin interface, API
|
||||
@section Obtaining configuration data
|
||||
|
||||
Each plugin can easily obtain data from its own configuration section.
|
||||
|
||||
|
||||
@menu
|
||||
* Without default value::
|
||||
* With default value::
|
||||
@end menu
|
||||
|
||||
@node Without default value, With default value, Obtaining configuration data, Obtaining configuration data
|
||||
@subsection Without default value
|
||||
|
||||
@code{char *findcfgl(config_item_t *cfg, char *name);}
|
||||
|
||||
@table @samp
|
||||
@item cfg
|
||||
Configuration handle, handed over to the plugin through the container
|
||||
setup function.
|
||||
|
||||
@item name
|
||||
Name of the configuration parameter.
|
||||
@end table
|
||||
|
||||
The value of the request configuration parameter is returned. If it
|
||||
does not exist, @code{NULL} is returned.
|
||||
|
||||
@node With default value, , Without default value, Obtaining configuration data
|
||||
@subsection With default value
|
||||
|
||||
@code{char *findcfglx(config_item_t *cfg, char *name, char *default_value);}
|
||||
|
||||
@table @samp
|
||||
@item cfg
|
||||
Configuration handle, handed over to the plugin through the container
|
||||
setup function.
|
||||
|
||||
@item name
|
||||
Name of the configuration parameter.
|
||||
|
||||
@item default_value
|
||||
Default value to be returned instead of @code{NULL} if the parameter
|
||||
is not mentioned in the configuration file.
|
||||
@end table
|
||||
|
||||
|
||||
|
||||
@node More or less useful stuff, , Obtaining configuration data, API
|
||||
@section More or less useful stuff
|
||||
|
||||
The functions of the library are discussed here for each of the header files.
|
||||
|
||||
@menu
|
||||
* count.h::
|
||||
* queue.h::
|
||||
* htdns.h::
|
||||
* htmalloc.h::
|
||||
* smtp.h::
|
||||
* safe_write.h::
|
||||
@end menu
|
||||
|
||||
@node count.h, queue.h, More or less useful stuff, More or less useful stuff
|
||||
@subsection @code{count.h}
|
||||
|
||||
This is a threadsafe counter, wrapped around an @code{int}.
|
||||
|
||||
Define or allocate a handle of type @code{count_t} to use it.
|
||||
|
||||
It defines the following functions of hopefully obvious meaning:
|
||||
|
||||
@verbatim
|
||||
void count_init(count_t *c);
|
||||
void count_destroy(count_t *c);
|
||||
int count_inc(count_t *c);
|
||||
int count_dec(count_t *c);
|
||||
int count_get(count_t *c);
|
||||
@end verbatim
|
||||
|
||||
|
||||
@node queue.h, htdns.h, count.h, More or less useful stuff
|
||||
@subsection @code{queue.h}
|
||||
|
||||
This is a threadsafe queue. Pointers to anything (@code{void}) can be
|
||||
stored in it.
|
||||
|
||||
Define or allocate a handle of type @code{ht_queue_t} to use it.
|
||||
|
||||
It defines the following functions of hopefully obvious meaning:
|
||||
|
||||
@verbatim
|
||||
void queue_init(ht_queue_t *q);
|
||||
void queue_destroy(ht_queue_t *q);
|
||||
int queue_put(ht_queue_t *q, void *d);
|
||||
void *queue_get_wait(ht_queue_t *q);
|
||||
@end verbatim
|
||||
|
||||
|
||||
@node htdns.h, htmalloc.h, queue.h, More or less useful stuff
|
||||
@subsection @code{htdns.h}
|
||||
|
||||
This is a wrapper around the resolver library selected at build time
|
||||
(currently traditional @code{libresolv} or djbdns).
|
||||
|
||||
It defines the following functions:
|
||||
|
||||
@verbatim
|
||||
void free_rrs(void **resp);
|
||||
mx_rdata_t** get_mx_rrs(char *domain);
|
||||
mx_rdata_t** get_best_mx_rrs(char *domain);
|
||||
a_rdata_t** get_a_rrs(char *domain);
|
||||
cname_rdata_t** get_cname_rrs(char *domain);
|
||||
@end verbatim
|
||||
|
||||
For details on the data types look into the header file.
|
||||
|
||||
Don't forget to free anything you got using @code{free_rrs}.
|
||||
|
||||
@node htmalloc.h, smtp.h, htdns.h, More or less useful stuff
|
||||
@subsection @code{htmalloc.h}
|
||||
|
||||
This provides variants of @code{malloc}, @code{realloc} and
|
||||
@code{strdup} which either returns or in case of out-of-memory sends
|
||||
the whole process into nirwana.
|
||||
|
||||
@verbatim
|
||||
void *htmalloc(size_t size);
|
||||
void *htrealloc(void *ptr, size_t size);
|
||||
char *htstrdup(const char *s);
|
||||
@end verbatim
|
||||
|
||||
|
||||
@node smtp.h, safe_write.h, htmalloc.h, More or less useful stuff
|
||||
@subsection @code{smtp.h}
|
||||
|
||||
This is a simple smtp library, also useable for lmtp.
|
||||
|
||||
Define or allocate a handle of type @code{smtp_t} to use it.
|
||||
|
||||
@verbatim
|
||||
smtp_t *smtp_init2(char *host_address, int port, int timeout);
|
||||
smtp_t *smtp_init(unsigned int address, int port, int timeout);
|
||||
void smtp_destroy(smtp_t *handle);
|
||||
|
||||
int smtp_response(smtp_t *handle, char **response);
|
||||
int smtp_command(smtp_t *handle, char *command, char *arg);
|
||||
|
||||
int smtp_connect(smtp_t *handle);
|
||||
int smtp_close(smtp_t *handle);
|
||||
|
||||
int smtp_helo(smtp_t *handle, char *arg);
|
||||
int smtp_ehlo(smtp_t *handle, char *arg);
|
||||
int smtp_lhlo(smtp_t *handle, char *arg);
|
||||
int smtp_mailfrom(smtp_t *handle, char *arg);
|
||||
int smtp_rcptto(smtp_t *handle, char *arg);
|
||||
int smtp_data(smtp_t *handle);
|
||||
int smtp_datasend(smtp_t *handle, char *data);
|
||||
int smtp_dataend(smtp_t *handle);
|
||||
int smtp_rset(smtp_t *handle);
|
||||
int smtp_quit(smtp_t *handle);
|
||||
@end verbatim
|
||||
|
||||
Note: @code{host_address} in @code{smtp_init2} is a quad-dotted IP
|
||||
address, no hostname.
|
||||
|
||||
@node safe_write.h, , smtp.h, More or less useful stuff
|
||||
@subsection @code{safe_write.h}
|
||||
|
||||
@verbatim
|
||||
ssize_t safe_write(int fd, const void *buf, size_t count);
|
||||
@end verbatim
|
||||
|
||||
This is a @code{SIGPIPE} death avoiding write function. However, no
|
||||
input should be expected when trying to write with this function,
|
||||
since at least one input character is eaten up.
|
||||
|
||||
|
||||
|
||||
@bye
|
||||
|
6341
smmapdfw/doc/texinfo.tex
Normal file
6341
smmapdfw/doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
include_HEADERS=containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h dns.h smmapd.h
|
||||
include_HEADERS=containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h
|
||||
lib_LTLIBRARIES = libsmmapdfw.la
|
||||
libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c dns.c smtp.c
|
||||
|
||||
libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c
|
||||
libsmmapdfw_la_LIBADD = @BDB_LIBS@
|
||||
|
||||
|
@ -87,9 +87,10 @@ RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
include_HEADERS = containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h dns.h smmapd.h
|
||||
include_HEADERS = containers_public.h queue.h smtp.h cfg.h count.h safe_write.h sunos_comp.h htdns.h smmapd.h htmalloc.h stats.h htcache.h
|
||||
lib_LTLIBRARIES = libsmmapdfw.la
|
||||
libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c dns.c smtp.c
|
||||
libsmmapdfw_la_SOURCES = cfg.c queue.c count.c safe_write.c config_public.c htdns.c smtp.c htmalloc.c stats.c htcache.c
|
||||
libsmmapdfw_la_LIBADD = @BDB_LIBS@
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
@ -101,9 +102,9 @@ CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libsmmapdfw_la_LDFLAGS =
|
||||
libsmmapdfw_la_LIBADD =
|
||||
libsmmapdfw_la_DEPENDENCIES =
|
||||
libsmmapdfw_la_OBJECTS = cfg.lo queue.lo count.lo safe_write.lo \
|
||||
config_public.lo dns.lo smtp.lo
|
||||
config_public.lo htdns.lo smtp.lo htmalloc.lo stats.lo htcache.lo
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
@ -118,8 +119,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DEP_FILES = .deps/cfg.P .deps/config_public.P .deps/count.P .deps/dns.P \
|
||||
.deps/queue.P .deps/safe_write.P .deps/smtp.P
|
||||
DEP_FILES = .deps/cfg.P .deps/config_public.P .deps/count.P \
|
||||
.deps/htcache.P .deps/htdns.P .deps/htmalloc.P .deps/queue.P \
|
||||
.deps/safe_write.P .deps/smtp.P .deps/stats.P
|
||||
SOURCES = $(libsmmapdfw_la_SOURCES)
|
||||
OBJECTS = $(libsmmapdfw_la_OBJECTS)
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
@ -15,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#include "cfg.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
#include "sunos_comp.h"
|
||||
|
||||
@ -81,9 +104,9 @@ config_section_t *readcfg(char *cfgfile) {
|
||||
state = STATE_START;
|
||||
i = 0;
|
||||
|
||||
cs = (config_section_t*) malloc(sizeof(config_section_t));
|
||||
cs = (config_section_t*) htmalloc(sizeof(config_section_t));
|
||||
cs->next = NULL;
|
||||
cs->name = (char*) malloc(strlen(buffer)+1);
|
||||
cs->name = (char*) htmalloc(strlen(buffer)+1);
|
||||
strcpy(cs->name, buffer);
|
||||
cs->item = NULL;
|
||||
|
||||
@ -113,9 +136,9 @@ config_section_t *readcfg(char *cfgfile) {
|
||||
state = STATE_EQUAL;
|
||||
i = 0;
|
||||
|
||||
ci = (config_item_t*) malloc(sizeof(config_item_t));
|
||||
ci = (config_item_t*) htmalloc(sizeof(config_item_t));
|
||||
ci->next = NULL;
|
||||
ci->name = (char*) malloc(strlen(buffer)+1);
|
||||
ci->name = (char*) htmalloc(strlen(buffer)+1);
|
||||
strcpy(ci->name, buffer);
|
||||
ci->value = NULL;
|
||||
|
||||
@ -172,7 +195,7 @@ config_section_t *readcfg(char *cfgfile) {
|
||||
state = STATE_START;
|
||||
i = 0;
|
||||
|
||||
ci->value = (char*) malloc(strlen(buffer)+1);
|
||||
ci->value = (char*) htmalloc(strlen(buffer)+1);
|
||||
strcpy(ci->value, buffer);
|
||||
|
||||
break;
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CONTAINERS_PUBLIC_H_
|
||||
#define _CONTAINERS_PUBLIC_H_
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "count.h"
|
||||
|
||||
void count_init(count_t *c) {
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _COUNT_H_
|
||||
#define _COUNT_H_
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
#ifndef _DNS_H_
|
||||
#define _DNS_H_
|
||||
|
||||
struct mx_rdata_s {
|
||||
int type;
|
||||
int preference;
|
||||
char *exchange;
|
||||
};
|
||||
|
||||
typedef struct mx_rdata_s mx_rdata_t;
|
||||
|
||||
struct a_rdata_s {
|
||||
int type;
|
||||
unsigned int address;
|
||||
};
|
||||
|
||||
typedef struct a_rdata_s a_rdata_t;
|
||||
|
||||
struct rdata_s {
|
||||
int type;
|
||||
union {
|
||||
mx_rdata_t mx;
|
||||
a_rdata_t a;
|
||||
} data;
|
||||
};
|
||||
|
||||
typedef struct rdata_s rdata_t;
|
||||
|
||||
|
||||
void free_rrs(void **resp);
|
||||
mx_rdata_t** get_mx_rrs(char *domain);
|
||||
mx_rdata_t** get_best_mx_rrs(char *domain);
|
||||
a_rdata_t** get_a_rrs(char *domain);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _DNS_H_ */
|
||||
|
||||
|
174
smmapdfw/libsmmapdfw/htcache.c
Normal file
174
smmapdfw/libsmmapdfw/htcache.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if ENABLE_CACHE == 1
|
||||
#define DB_DBM_HSEARCH 1
|
||||
#include <db.h>
|
||||
#endif
|
||||
|
||||
#include "htcache.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
struct mydata_s {
|
||||
time_t timestamp;
|
||||
int value_size;
|
||||
char value[1];
|
||||
};
|
||||
|
||||
typedef struct mydata_s mydata_t;
|
||||
|
||||
|
||||
|
||||
htcache_t *cache_init(const char *file, int expiry) {
|
||||
#if ENABLE_CACHE == 1
|
||||
htcache_t *handle = (htcache_t*) htmalloc(sizeof(htcache_t));
|
||||
handle->mutex = (pthread_mutex_t*) htmalloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(handle->mutex, NULL);
|
||||
pthread_mutex_unlock(handle->mutex);
|
||||
handle->file = file;
|
||||
handle->expiry = expiry;
|
||||
|
||||
return handle;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cache_destroy(htcache_t *handle) {
|
||||
#if ENABLE_CACHE == 1
|
||||
pthread_mutex_destroy(handle->mutex);
|
||||
free(handle->mutex);
|
||||
free(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void cache_insert(htcache_t *handle, const char *key, const void *value, int value_size) {
|
||||
#if ENABLE_CACHE == 1
|
||||
DBM *cache;
|
||||
datum data, dkey;
|
||||
int ret;
|
||||
mydata_t *mydata;
|
||||
|
||||
syslog(LOG_DEBUG, "cache_insert: inserting %s -> %s (size %d)", key, (char*) value, value_size);
|
||||
dkey.dsize = strlen(key) + 1; /* one more for the terminating \0 */
|
||||
dkey.dptr = (char*) key;
|
||||
data.dsize = (sizeof(mydata_t) + value_size + 1);
|
||||
mydata = (mydata_t *) htmalloc(data.dsize);
|
||||
mydata->timestamp = time(NULL);
|
||||
mydata->value_size = value_size;
|
||||
memcpy(mydata->value, value, value_size);
|
||||
data.dptr = (char*) mydata;
|
||||
|
||||
pthread_mutex_lock(handle->mutex);
|
||||
if (NULL != (cache = dbm_open(handle->file, O_RDWR | O_CREAT, 0644))) {
|
||||
ret = dbm_store(cache, dkey, data, DBM_INSERT);
|
||||
if (ret != 0) {
|
||||
syslog(LOG_DEBUG, "cache_insert: couldn't insert record");
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "cache_insert: record inserted");
|
||||
}
|
||||
dbm_close(cache);
|
||||
}
|
||||
pthread_mutex_unlock(handle->mutex);
|
||||
|
||||
free(mydata);
|
||||
#else
|
||||
syslog(LOG_DEBUG, "cache_insert: cache disabled");
|
||||
#endif /* ENABLE_CACHE */
|
||||
}
|
||||
|
||||
|
||||
void *cache_lookup(htcache_t *handle, const char* key) {
|
||||
#if ENABLE_CACHE == 1
|
||||
DBM *cache;
|
||||
datum data, dkey;
|
||||
char *output;
|
||||
mydata_t *mydata;
|
||||
int value_size, ret, res = -1;
|
||||
|
||||
syslog(LOG_DEBUG, "cache_lookup: looking up %s, expiry %d",
|
||||
key, handle->expiry);
|
||||
|
||||
if (NULL != (cache = dbm_open(handle->file, O_RDONLY, 0644))) {
|
||||
dkey.dsize = strlen(key) + 1; /* one more for the terminating \0 */
|
||||
dkey.dptr = (char*) key;
|
||||
data = dbm_fetch(cache, dkey);
|
||||
if (NULL == data.dptr) {
|
||||
syslog(LOG_DEBUG, "cache_lookup: nothing found");
|
||||
dbm_close(cache);
|
||||
} else {
|
||||
mydata = (mydata_t *) data.dptr;
|
||||
syslog(LOG_DEBUG, "cache_lookup: found: %s -> %s (size %d)",
|
||||
key, data.dptr, data.dsize);
|
||||
if ((mydata->timestamp + handle->expiry) > time(NULL)) {
|
||||
syslog(LOG_DEBUG, "cache_lookup: not yet expired");
|
||||
value_size = mydata->value_size;
|
||||
output = (char*) htmalloc(value_size+5);
|
||||
memcpy(output, mydata->value, value_size);
|
||||
|
||||
/* Berkeley DB frees on its own! */
|
||||
/* free(data.dptr); */
|
||||
dbm_close(cache);
|
||||
res = 0;
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "cache_lookup: expired, will be deleted from cache");
|
||||
/* free(data.dptr); --- Berkeley DB frees on its own */
|
||||
dbm_close(cache);
|
||||
|
||||
pthread_mutex_lock(handle->mutex);
|
||||
if (NULL != (cache = dbm_open(handle->file, O_RDWR, 0644))) {
|
||||
ret = dbm_delete(cache, dkey);
|
||||
if (ret != 0) {
|
||||
syslog(LOG_DEBUG, "cache_insert: couldn't delete record");
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "cache_insert: record deleted");
|
||||
}
|
||||
dbm_close(cache);
|
||||
}
|
||||
pthread_mutex_unlock(handle->mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
#else
|
||||
return -1;
|
||||
#endif /* ENABLE_CACHE */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
43
smmapdfw/libsmmapdfw/htcache.h
Normal file
43
smmapdfw/libsmmapdfw/htcache.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _HTCACHE_H_
|
||||
#define _HTCACHE_H_
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
typedef struct htcache_s {
|
||||
const char *file;
|
||||
int expiry;
|
||||
pthread_mutex_t *mutex;
|
||||
} htcache_t;
|
||||
|
||||
htcache_t *cache_init(const char *file, int expiry);
|
||||
void cache_destroy(htcache_t *handle);
|
||||
void cache_insert(htcache_t *handle, const char *key, const void *value, int value_size);
|
||||
void *cache_lookup(htcache_t *handle, const char *key);
|
||||
|
||||
|
||||
#endif /* _HTCACHE_H_ */
|
||||
|
||||
|
@ -1,18 +1,52 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dns.h"
|
||||
#if HAVE_LIBDJBDNS
|
||||
#include <dns.h>
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
|
||||
#include "htdns.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
#if ! HAVE_LIBDJBDNS
|
||||
extern int h_errno;
|
||||
/* extern struct state _res; */
|
||||
#endif
|
||||
|
||||
union answer_u {
|
||||
HEADER hdr;
|
||||
@ -28,19 +62,27 @@ typedef union answer_u answer_t;
|
||||
#define get16(b, o) ((b[o] << 8) + b[o+1])
|
||||
|
||||
|
||||
#if HAVE_LIBDJBDNS
|
||||
pthread_mutex_t dns_transmit_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static int get_domain_name(answer_t *answer, int offset, char **name) {
|
||||
int start, len, i, offset2;
|
||||
char *name_buf, *name_buf2;
|
||||
char *name_buf, *name_buf2, *remember_name_buf;
|
||||
name_buf = NULL;
|
||||
|
||||
|
||||
|
||||
while (0 != (len = answer->buf[offset++])) {
|
||||
if (0xC0 == (len & 0xC0)) {
|
||||
if (NULL != name) { /* if we don't need the result, we don't need to recurse, since a ... */
|
||||
offset2 = ((len & ~0xC0) << 8) + answer->buf[offset++];
|
||||
get_domain_name(answer, offset2, &name_buf2);
|
||||
name_buf = (char*) realloc(name_buf, ((NULL != name_buf) ? strlen(name_buf) : 0) + strlen(name_buf2) + 1);
|
||||
remember_name_buf = name_buf;
|
||||
name_buf = (char*) htrealloc(name_buf, ((NULL != name_buf) ? strlen(name_buf) : 0) + strlen(name_buf2) + 1);
|
||||
if (NULL == remember_name_buf) {
|
||||
name_buf[0] = '\0';
|
||||
}
|
||||
strcat(name_buf, name_buf2);
|
||||
free(name_buf2);
|
||||
*name = name_buf;
|
||||
@ -53,7 +95,7 @@ static int get_domain_name(answer_t *answer, int offset, char **name) {
|
||||
offset += len;
|
||||
if (NULL != name) {
|
||||
i = (NULL != name_buf) ? strlen(name_buf) : 0;
|
||||
name_buf = (char*) realloc(name_buf, i+len+2);
|
||||
name_buf = (char*) htrealloc(name_buf, i+len+2);
|
||||
strncpy(name_buf + i, answer->buf + start, len);
|
||||
name_buf[i+len] = '\0';
|
||||
strcat(name_buf, ".");
|
||||
@ -68,7 +110,7 @@ static int get_domain_name(answer_t *answer, int offset, char **name) {
|
||||
}
|
||||
|
||||
static int get_mx_rdata(answer_t *answer, int offset, int len, mx_rdata_t **resp) {
|
||||
*resp = (mx_rdata_t*) malloc(sizeof(mx_rdata_t));
|
||||
*resp = (mx_rdata_t*) htmalloc(sizeof(mx_rdata_t));
|
||||
(*resp)->preference = get16(answer->buf, offset);
|
||||
get_domain_name(answer, offset+2, &(*resp)->exchange);
|
||||
(*resp)->type = T_MX;
|
||||
@ -84,13 +126,27 @@ static void free_mx_rdata(mx_rdata_t *resp) {
|
||||
|
||||
|
||||
static int get_a_rdata(answer_t *answer, int offset, int len, a_rdata_t **resp) {
|
||||
*resp = (a_rdata_t*) malloc(sizeof(a_rdata_t));
|
||||
*resp = (a_rdata_t*) htmalloc(sizeof(a_rdata_t));
|
||||
(*resp)->address = htonl(get32(answer->buf, offset));
|
||||
(*resp)->type = T_A;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_cname_rdata(answer_t *answer, int offset, int len, cname_rdata_t **resp) {
|
||||
*resp = (cname_rdata_t*) htmalloc(sizeof(cname_rdata_t));
|
||||
get_domain_name(answer, offset, &(*resp)->cname);
|
||||
(*resp)->type = T_CNAME;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_cname_rdata(cname_rdata_t *resp) {
|
||||
free(resp->cname);
|
||||
free(resp);
|
||||
}
|
||||
|
||||
|
||||
static void free_a_rdata(a_rdata_t *resp) {
|
||||
free(resp);
|
||||
}
|
||||
@ -103,6 +159,9 @@ static int get_rdata(answer_t *answer, int type, int offset, int len, void **res
|
||||
case T_A:
|
||||
get_a_rdata(answer, offset, len, (a_rdata_t**)resp);
|
||||
break;
|
||||
case T_CNAME:
|
||||
get_cname_rdata(answer, offset, len, (cname_rdata_t**)resp);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "type %d unsupported\n", type);
|
||||
}
|
||||
@ -118,6 +177,9 @@ static void free_rdata(void *resp) {
|
||||
case T_A:
|
||||
free_a_rdata(resp);
|
||||
break;
|
||||
case T_CNAME:
|
||||
free_cname_rdata(resp);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_ERR, "type %d unsupported\n", d->type);
|
||||
}
|
||||
@ -135,51 +197,155 @@ void free_rrs(void **resp) {
|
||||
|
||||
static void** get_rrs(char *domain, int qtype) {
|
||||
unsigned int res, i, cnt, len, offset, x, y, rdlength;
|
||||
answer_t answer;
|
||||
answer_t *answer;
|
||||
unsigned int class, type, ttl;
|
||||
char *name;
|
||||
void **rdata, **rdata2;
|
||||
|
||||
#if HAVE_LIBDJBDNS
|
||||
struct dns_transmit dt = {0};
|
||||
#endif
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "get_rrs: looking up domain %s, qtype %d", domain, qtype);
|
||||
|
||||
res = res_search(domain, C_IN, qtype, (u_char*) &answer, sizeof(answer_t));
|
||||
if (-1 == res) {
|
||||
return NULL;
|
||||
#if HAVE_LIBDJBDNS
|
||||
{
|
||||
char s[64];
|
||||
int flagrecursive = 1;
|
||||
char *q = NULL;
|
||||
char t[2];
|
||||
char localip[4] = "\0\0\0\0";
|
||||
iopause_fd x[1];
|
||||
struct taia deadline;
|
||||
struct taia stamp;
|
||||
|
||||
|
||||
t[0] = '\0';
|
||||
t[1] = qtype;
|
||||
|
||||
if (dns_resolvconfip(s) == -1) {
|
||||
syslog(LOG_ERR, "failure in dns_resolvconfip: %d, %s\n",
|
||||
errno, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dns_domain_fromdot(&q, domain, strlen(domain));
|
||||
|
||||
pthread_mutex_lock(&dns_transmit_mutex);
|
||||
res = dns_transmit_start(&dt, s, flagrecursive, q, t, localip);
|
||||
pthread_mutex_unlock(&dns_transmit_mutex);
|
||||
|
||||
if (res == -1) {
|
||||
syslog(LOG_ERR, "failure in dns_transmit_start: %d, %s\n",
|
||||
errno, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int r;
|
||||
|
||||
taia_now(&stamp);
|
||||
taia_uint(&deadline,120);
|
||||
taia_add(&deadline, &deadline, &stamp);
|
||||
pthread_mutex_lock(&dns_transmit_mutex);
|
||||
dns_transmit_io(&dt, x, &deadline);
|
||||
pthread_mutex_unlock(&dns_transmit_mutex);
|
||||
|
||||
iopause(x, 1, &deadline, &stamp);
|
||||
|
||||
pthread_mutex_lock(&dns_transmit_mutex);
|
||||
r = dns_transmit_get(&dt, x, &stamp);
|
||||
pthread_mutex_unlock(&dns_transmit_mutex);
|
||||
|
||||
if (-1 == r) {
|
||||
syslog(LOG_ERR, "failure in dns_transmit_get: %d, %s\n",
|
||||
errno, strerror(errno));
|
||||
|
||||
pthread_mutex_lock(&dns_transmit_mutex);
|
||||
dns_transmit_free(&dt);
|
||||
pthread_mutex_unlock(&dns_transmit_mutex);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (1 == r)
|
||||
break;
|
||||
}
|
||||
|
||||
answer = (answer_t*) dt.packet;
|
||||
}
|
||||
#else
|
||||
{
|
||||
answer_t lanswer;
|
||||
|
||||
syslog(LOG_DEBUG, "get_rrs: before res_search");
|
||||
res = res_search(domain, C_IN, qtype, (u_char*) &lanswer, sizeof(answer_t));
|
||||
if (-1 == res) {
|
||||
syslog(LOG_ERR, "get_rrs: error in res_search: h_errno=%d, errno=%d, (%s)",
|
||||
h_errno, errno, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
answer = &lanswer;
|
||||
}
|
||||
#endif
|
||||
|
||||
cnt = sizeof(HEADER);
|
||||
|
||||
#if 0
|
||||
syslog(LOG_DEBUG, "id: %d\n", answer->hdr.id);
|
||||
syslog(LOG_DEBUG, "qr: %d\n", answer->hdr.qr);
|
||||
syslog(LOG_DEBUG, "oc: %d\n", answer->hdr.opcode);
|
||||
syslog(LOG_DEBUG, "aa: %d\n", answer->hdr.aa);
|
||||
syslog(LOG_DEBUG, "tc: %d\n", answer->hdr.tc);
|
||||
syslog(LOG_DEBUG, "rd: %d\n", answer->hdr.rd);
|
||||
syslog(LOG_DEBUG, "ra: %d\n", answer->hdr.ra);
|
||||
syslog(LOG_DEBUG, "ad: %d\n", answer->hdr.ad);
|
||||
syslog(LOG_DEBUG, "cd: %d\n", answer->hdr.cd);
|
||||
syslog(LOG_DEBUG, "rc: %d\n", answer->hdr.rcode);
|
||||
syslog(LOG_DEBUG, "qdcount: %d\n", ntohs(answer->hdr.qdcount));
|
||||
syslog(LOG_DEBUG, "ancount: %d\n", ntohs(answer->hdr.ancount));
|
||||
syslog(LOG_DEBUG, "nscount: %d\n", ntohs(answer->hdr.nscount));
|
||||
syslog(LOG_DEBUG, "arcount: %d\n", ntohs(answer->hdr.arcount));
|
||||
#endif
|
||||
|
||||
/* query section */
|
||||
for (y = 0; y < ntohs(answer.hdr.qdcount); y++) {
|
||||
cnt = get_domain_name(&answer, cnt, NULL);
|
||||
type = get16(answer.buf, cnt);
|
||||
for (y = 0; y < ntohs(answer->hdr.qdcount); y++) {
|
||||
cnt = get_domain_name(answer, cnt, NULL);
|
||||
type = get16(answer->buf, cnt);
|
||||
cnt += 2;
|
||||
class = get16(answer.buf, cnt);
|
||||
class = get16(answer->buf, cnt);
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
/* answer section */
|
||||
rdata = (void**)malloc(sizeof(void*) * (ntohs(answer.hdr.ancount)+1));
|
||||
for (y = 0; y < ntohs(answer.hdr.ancount); y++) {
|
||||
cnt = get_domain_name(&answer, cnt, NULL);
|
||||
type = get16(answer.buf, cnt);
|
||||
assert(type==qtype);
|
||||
rdata = (void**)htmalloc(sizeof(void*) * (ntohs(answer->hdr.ancount)+1));
|
||||
for (y = 0; y < ntohs(answer->hdr.ancount); y++) {
|
||||
cnt = get_domain_name(answer, cnt, NULL);
|
||||
type = get16(answer->buf, cnt);
|
||||
syslog(LOG_DEBUG, "get_rrs: answer type %d", type);
|
||||
/* assert(type==qtype); */
|
||||
cnt += 2;
|
||||
class = get16(answer.buf, cnt);
|
||||
class = get16(answer->buf, cnt);
|
||||
cnt += 2;
|
||||
ttl = get32(answer.buf, cnt);
|
||||
ttl = get32(answer->buf, cnt);
|
||||
cnt += 4;
|
||||
rdlength = get16(answer.buf, cnt);
|
||||
rdlength = get16(answer->buf, cnt);
|
||||
cnt += 2;
|
||||
rdata2 = rdata+y;
|
||||
get_rdata(&answer, type, cnt, rdlength, rdata2);
|
||||
get_rdata(answer, type, cnt, rdlength, rdata2);
|
||||
cnt += rdlength;
|
||||
}
|
||||
|
||||
rdata2 = rdata+y;
|
||||
*((void**)rdata2) = NULL;
|
||||
|
||||
#if HAVE_LIBDJBDNS
|
||||
pthread_mutex_lock(&dns_transmit_mutex);
|
||||
dns_transmit_free(&dt);
|
||||
pthread_mutex_unlock(&dns_transmit_mutex);
|
||||
#endif
|
||||
|
||||
return rdata;
|
||||
}
|
||||
|
||||
@ -188,7 +354,21 @@ mx_rdata_t** get_mx_rrs(char *domain) {
|
||||
}
|
||||
|
||||
a_rdata_t** get_a_rrs(char *domain) {
|
||||
return (a_rdata_t**) get_rrs(domain, T_A);
|
||||
rdata_t **rdata, **rdata2;
|
||||
cname_rdata_t **cname_rdata;
|
||||
|
||||
rdata = (rdata_t**) get_rrs(domain, T_A);
|
||||
if ((NULL == rdata) || (NULL == *rdata))
|
||||
return NULL;
|
||||
|
||||
if ((*rdata)->type == T_CNAME) {
|
||||
cname_rdata = (cname_rdata_t**) rdata;
|
||||
rdata2 = (rdata_t**) get_a_rrs((*cname_rdata)->cname);
|
||||
free_rrs((void**)rdata);
|
||||
rdata = rdata2;
|
||||
}
|
||||
|
||||
return (a_rdata_t**) rdata;
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +403,7 @@ mx_rdata_t** get_best_mx_rrs(char *domain) {
|
||||
return all_mx_rrs;
|
||||
} else {
|
||||
/* space for the minimum pref rr's */
|
||||
best_mx_rrs = (mx_rdata_t**) malloc(sizeof(mx_rdata_t*) * (best_cnt+1));
|
||||
best_mx_rrs = (mx_rdata_t**) htmalloc(sizeof(mx_rdata_t*) * (best_cnt+1));
|
||||
for (mx_rdata2 = all_mx_rrs; *mx_rdata2 != NULL; mx_rdata2++) {
|
||||
if ((*mx_rdata2)->preference == min_pref) {
|
||||
/* is a minimum one, keep it */
|
||||
@ -262,6 +442,9 @@ int main(int argc, char **argv) {
|
||||
domain = argv[1];
|
||||
}
|
||||
|
||||
openlog("htdns-test", LOG_PID, LOG_LOCAL2);
|
||||
|
||||
|
||||
printf("before get_mx_rrs: %s\n", domain);
|
||||
|
||||
mx_rdata = get_mx_rrs(domain);
|
||||
@ -303,6 +486,8 @@ int main(int argc, char **argv) {
|
||||
/* free_rrs((void**)a_rdata); */
|
||||
|
||||
|
||||
|
||||
closelog();
|
||||
}
|
||||
|
||||
#endif /* _TEST_MODE_ */
|
70
smmapdfw/libsmmapdfw/htdns.h
Normal file
70
smmapdfw/libsmmapdfw/htdns.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _DNS_H_
|
||||
#define _DNS_H_
|
||||
|
||||
struct mx_rdata_s {
|
||||
int type;
|
||||
int preference;
|
||||
char *exchange;
|
||||
};
|
||||
|
||||
typedef struct mx_rdata_s mx_rdata_t;
|
||||
|
||||
struct cname_rdata_s {
|
||||
int type;
|
||||
char *cname;
|
||||
};
|
||||
|
||||
typedef struct cname_rdata_s cname_rdata_t;
|
||||
|
||||
struct a_rdata_s {
|
||||
int type;
|
||||
unsigned int address;
|
||||
};
|
||||
|
||||
typedef struct a_rdata_s a_rdata_t;
|
||||
|
||||
struct rdata_s {
|
||||
int type;
|
||||
union {
|
||||
mx_rdata_t mx;
|
||||
a_rdata_t a;
|
||||
cname_rdata_t cname;
|
||||
} data;
|
||||
};
|
||||
|
||||
typedef struct rdata_s rdata_t;
|
||||
|
||||
|
||||
void free_rrs(void **resp);
|
||||
mx_rdata_t** get_mx_rrs(char *domain);
|
||||
mx_rdata_t** get_best_mx_rrs(char *domain);
|
||||
a_rdata_t** get_a_rrs(char *domain);
|
||||
cname_rdata_t** get_cname_rrs(char *domain);
|
||||
|
||||
|
||||
|
||||
#endif /* _DNS_H_ */
|
||||
|
||||
|
56
smmapdfw/libsmmapdfw/htmalloc.c
Normal file
56
smmapdfw/libsmmapdfw/htmalloc.c
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
void *htmalloc(size_t size) {
|
||||
void *p = malloc(size);
|
||||
if (NULL == p) {
|
||||
syslog(LOG_ERR, "htmalloc: out of memory");
|
||||
exit(153);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void *htrealloc(void *ptr, size_t size) {
|
||||
void *p = realloc(ptr, size);
|
||||
if (NULL == p) {
|
||||
syslog(LOG_ERR, "htremalloc: out of memory");
|
||||
exit(153);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
char *htstrdup(const char *s) {
|
||||
char *p = htmalloc(strlen(s) + 1);
|
||||
strcpy(p, s);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
34
smmapdfw/libsmmapdfw/htmalloc.h
Normal file
34
smmapdfw/libsmmapdfw/htmalloc.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _HTMALLOC_H_
|
||||
#define _HTMALLOC_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *htmalloc(size_t size);
|
||||
void *htrealloc(void *ptr, size_t size);
|
||||
char *htstrdup(const char *s);
|
||||
|
||||
|
||||
|
||||
#endif /* _HTMALLOC_H_ */
|
||||
|
||||
|
@ -1,4 +1,27 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "queue.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
#ifdef _TEST_MODE_
|
||||
#include <stdio.h>
|
||||
@ -23,7 +46,7 @@ void queue_destroy(ht_queue_t *q) {
|
||||
int queue_put(ht_queue_t *q, void *d) {
|
||||
queue_entry_t *entry;
|
||||
|
||||
entry = (queue_entry_t *) malloc(sizeof(queue_entry_t));
|
||||
entry = (queue_entry_t *) htmalloc(sizeof(queue_entry_t));
|
||||
if (NULL == entry)
|
||||
return -1;
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _QUEUE_H_
|
||||
#define _QUEUE_H_
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SAFE_WRITE_H_
|
||||
#define _SAFE_WRITE_H_
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
@ -12,7 +34,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "smtp.h"
|
||||
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
#define BUFSIZE 1024
|
||||
@ -21,7 +43,7 @@
|
||||
|
||||
|
||||
smtp_t *smtp_init(unsigned int address, int port, int timeout) {
|
||||
smtp_t *handle = (smtp_t*) malloc(sizeof(smtp_t));
|
||||
smtp_t *handle = (smtp_t*) htmalloc(sizeof(smtp_t));
|
||||
|
||||
handle->address = address;
|
||||
handle->port = port;
|
||||
@ -30,7 +52,7 @@ smtp_t *smtp_init(unsigned int address, int port, int timeout) {
|
||||
handle->response_code = 0;
|
||||
handle->got_timeout = 0;
|
||||
|
||||
handle->buffer = (char*) malloc(BUFSIZE+5);
|
||||
handle->buffer = (char*) htmalloc(BUFSIZE+5);
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -196,9 +218,7 @@ int smtp_command(smtp_t *handle, char *command, char *arg) {
|
||||
}
|
||||
|
||||
int smtp_connect(smtp_t *handle) {
|
||||
int err;
|
||||
int c;
|
||||
int res;
|
||||
int err, c, res, optval;
|
||||
fd_set wrfs;
|
||||
struct timeval tv;
|
||||
|
||||
@ -209,6 +229,13 @@ int smtp_connect(smtp_t *handle) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
optval = 0x10; /* TOS=lowdelay*/
|
||||
err = setsockopt(handle->socket, IPPROTO_IP, IP_TOS, (void*)&optval, sizeof(optval));
|
||||
if (-1 == err) {
|
||||
syslog(LOG_DEBUG, "smtp_connect: unable to set IPTOS_LOWDELAY: %d (%s)", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = fcntl(handle->socket, F_GETFL);
|
||||
if (-1 == c) {
|
||||
syslog(LOG_DEBUG, "smtp_connect: unable to get flags, errno: %d (%s)", errno, strerror(errno));
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SMTP_H_
|
||||
#define _SMTP_H_
|
||||
|
||||
|
106
smmapdfw/libsmmapdfw/stats.c
Normal file
106
smmapdfw/libsmmapdfw/stats.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _STATS_C_
|
||||
#include "stats.h"
|
||||
|
||||
#include "count.h"
|
||||
|
||||
|
||||
#if ENABLE_STATS==1
|
||||
count_t statCounter[STAT_CNT_MAXNUM];
|
||||
#endif
|
||||
|
||||
void initStatCounter() {
|
||||
#if ENABLE_STATS==1
|
||||
int i;
|
||||
|
||||
for (i=0; i<STAT_CNT_MAXNUM; i++) {
|
||||
count_init(&statCounter[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int getStatCounter(int cnt_idx) {
|
||||
#if ENABLE_STATS==1
|
||||
assert((cnt_idx >= 0) && (cnt_idx < STAT_CNT_MAXNUM));
|
||||
return count_get(&statCounter[cnt_idx]);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void incStatCounter(int cnt_idx) {
|
||||
#if ENABLE_STATS==1
|
||||
assert((cnt_idx >= 0) && (cnt_idx < STAT_CNT_MAXNUM));
|
||||
count_inc(&statCounter[cnt_idx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void decStatCounter(int cnt_idx) {
|
||||
#if ENABLE_STATS==1
|
||||
assert((cnt_idx >= 0) && (cnt_idx < STAT_CNT_MAXNUM));
|
||||
count_dec(&statCounter[cnt_idx]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void outputStats(int stdout_nice, int syslog_nice) {
|
||||
#if ENABLE_STATS==1
|
||||
char buf[1024];
|
||||
char buf2[64];
|
||||
int i, v;
|
||||
|
||||
*buf = '\0';
|
||||
*buf2 = '\0';
|
||||
|
||||
strcat(buf, "Stats: ");
|
||||
|
||||
if (2 == stdout_nice)
|
||||
printf("---------------------------------------------------------\n");
|
||||
|
||||
for (i=1; i<STAT_CNT_MAXNUM; i++) {
|
||||
v = getStatCounter(i);
|
||||
if (2 == stdout_nice)
|
||||
printf("%44s = %5d\n", stat_cnt_names[i], v);
|
||||
if (2 == syslog_nice)
|
||||
syslog(LOG_DEBUG, "%44s = %5d\n", stat_cnt_names[i], v);
|
||||
if ((1 == stdout_nice) || (1 == syslog_nice)) {
|
||||
sprintf(buf2, "%d ", v);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
}
|
||||
|
||||
if (stdout_nice)
|
||||
printf("\n");
|
||||
|
||||
if (1 == stdout_nice)
|
||||
printf("%s\n\n", buf);
|
||||
if (1 == syslog_nice)
|
||||
syslog(LOG_DEBUG, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
103
smmapdfw/libsmmapdfw/stats.h
Normal file
103
smmapdfw/libsmmapdfw/stats.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _STATS_H_
|
||||
#define _STATS_H_
|
||||
|
||||
#include "smmapd.h"
|
||||
|
||||
#ifdef _STATS_C_
|
||||
char *stat_cnt_names[] = {
|
||||
"",
|
||||
"Server: accepted",
|
||||
"Server: failed",
|
||||
"Server: running networker threads",
|
||||
"Server: networker threads",
|
||||
"Server: failed to start, networker threads",
|
||||
|
||||
"Verifier: entries in cache",
|
||||
"Verifier: running worker threads",
|
||||
"Verifier: worker threads",
|
||||
"Verifier: failed to start, worker threads",
|
||||
"Verifier: timed out worker threads",
|
||||
"Verifier: running checker threads",
|
||||
"Verifier: checker threads",
|
||||
"Verifier: failed to start, checker threads",
|
||||
"Verifier: answered from cache",
|
||||
"Verifier: returned OK",
|
||||
"Verifier: returned NOK",
|
||||
"Verifier: returned TNOK",
|
||||
|
||||
"Cyrus: checker",
|
||||
"Cyrus: illegal input",
|
||||
"Cyrus: depot dns failure",
|
||||
"Cyrus: returned OK",
|
||||
"Cyrus: returned NOK",
|
||||
"Cyrus: returned TNOK",
|
||||
|
||||
"Server: returned OK",
|
||||
"Server: returned TEMP_NOK",
|
||||
"Server: returned PERM_NOK",
|
||||
"Server: returned NOT_FOUND_NOK",
|
||||
"Server: returned illegal input",
|
||||
"Server: returned unknown class",
|
||||
"Server: returned TIMEOUT_NOK",
|
||||
"Server: returned netstring unparsable",
|
||||
};
|
||||
#endif /* _STATS_C_ */
|
||||
|
||||
|
||||
#define STAT_CNT_ACCEPTED 1
|
||||
#define STAT_CNT_FAILED 2
|
||||
#define STAT_CNT_NETWORKER_R_THREADS 3
|
||||
#define STAT_CNT_NETWORKER_THREADS 4
|
||||
#define STAT_CNT_NETWORKER_THREADS_FAILED 5
|
||||
|
||||
#define STAT_CNT_VERIFIER_CACHE 6
|
||||
#define STAT_CNT_VERIFIER_WORKER_R_THREADS 7
|
||||
#define STAT_CNT_VERIFIER_WORKER_THREADS 8
|
||||
#define STAT_CNT_VERIFIER_WORKER_THREADS_FAILED 9
|
||||
#define STAT_CNT_VERIFIER_WORKER_THREADS_TIMEOUT 10
|
||||
#define STAT_CNT_VERIFIER_CHECKER_R_THREADS 11
|
||||
#define STAT_CNT_VERIFIER_CHECKER_THREADS 12
|
||||
#define STAT_CNT_VERIFIER_CHECKER_THREADS_FAILED 13
|
||||
#define STAT_CNT_VERIFIER_ANSWERED_FROM_CACHE 14
|
||||
#define STAT_CNT_VERIFIER_RETURNED_OK 15
|
||||
#define STAT_CNT_VERIFIER_RETURNED_NOK 16
|
||||
#define STAT_CNT_VERIFIER_RETURNED_TNOK 17
|
||||
|
||||
#define STAT_CNT_CYRUS_WORKER 18
|
||||
#define STAT_CNT_CYRUS_ILLEGAL_INPUT 19
|
||||
#define STAT_CNT_CYRUS_DEPOT_DNS_FAILURE 20
|
||||
#define STAT_CNT_CYRUS_RETURNED_OK 21
|
||||
#define STAT_CNT_CYRUS_RETURNED_NOK 22
|
||||
#define STAT_CNT_CYRUS_RETURNED_TNOK 23
|
||||
|
||||
#define STAT_CNT_OFFSET 23
|
||||
#define STAT_CNT_MAXNUM STAT_CNT_OFFSET + SMM_MAX_NUM
|
||||
|
||||
|
||||
void initStatCounter();
|
||||
unsigned int getStatCounter(int cnt_idx);
|
||||
void incStatCounter(int cnt_idx);
|
||||
void decStatCounter(int cnt_idx);
|
||||
void outputStats(int stdout_nice, int syslog_nice);
|
||||
#endif /* _STATS_H_ */
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _SUNOS_COMP_H_
|
||||
#define _SUNOS_COMP_H_
|
||||
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
@ -7,6 +27,7 @@
|
||||
|
||||
#include "containers_public.h"
|
||||
#include "smmapd.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
#define CFG_LUALIB_NAMES "load"
|
||||
@ -67,7 +88,7 @@ int lua_init(cfgl_t *cfg, void **handle) {
|
||||
const luaL_reg *lualib;
|
||||
cfgl_t *cfgl_iter;
|
||||
|
||||
lch = (lua_container_handle_t*) malloc(sizeof(lua_container_handle_t));
|
||||
lch = (lua_container_handle_t*) htmalloc(sizeof(lua_container_handle_t));
|
||||
lch->cfg = cfg;
|
||||
|
||||
lua_filename = findcfgl(lch->cfg, CFG_LUA_FILENAME);
|
||||
@ -145,7 +166,7 @@ int lua_destroy(void *handle) {
|
||||
}
|
||||
|
||||
int lua_work_setup(void *handle, void **work_handle) {
|
||||
lua_worker_handle_t *lwh = (lua_worker_handle_t*)malloc(sizeof(lua_worker_handle_t));
|
||||
lua_worker_handle_t *lwh = (lua_worker_handle_t*)htmalloc(sizeof(lua_worker_handle_t));
|
||||
lwh->lch = (lua_container_handle_t*) handle;
|
||||
|
||||
lwh->l = lua_newthread(lwh->lch->l);
|
||||
|
2
smmapdfw/m4/Makefile.am
Normal file
2
smmapdfw/m4/Makefile.am
Normal file
@ -0,0 +1,2 @@
|
||||
data_DATA = cyruscheck.m4 verifysender.m4
|
||||
EXTRA_DIST = cyruscheck.m4 verifysender.m4
|
221
smmapdfw/m4/Makefile.in
Normal file
221
smmapdfw/m4/Makefile.in
Normal file
@ -0,0 +1,221 @@
|
||||
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
BDB_LIBS = @BDB_LIBS@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
GCJ = @GCJ@
|
||||
GCJFLAGS = @GCJFLAGS@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
LIB = @LIB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
data_DATA = cyruscheck.m4 verifysender.m4
|
||||
EXTRA_DIST = cyruscheck.m4 verifysender.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DATA = $(data_DATA)
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
install-dataDATA: $(data_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(datadir)
|
||||
@list='$(data_DATA)'; for p in $$list; do \
|
||||
if test -f $(srcdir)/$$p; then \
|
||||
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(datadir)/$$p"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(datadir)/$$p; \
|
||||
else if test -f $$p; then \
|
||||
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(datadir)/$$p"; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(datadir)/$$p; \
|
||||
fi; fi; \
|
||||
done
|
||||
|
||||
uninstall-dataDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(data_DATA)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(datadir)/$$p; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = m4
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
here=`cd $(top_builddir) && pwd`; \
|
||||
top_distdir=`cd $(top_distdir) && pwd`; \
|
||||
distdir=`cd $(distdir) && pwd`; \
|
||||
cd $(top_srcdir) \
|
||||
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu m4/Makefile
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am:
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am: install-dataDATA
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am: uninstall-dataDATA
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile $(DATA)
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(datadir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-generic clean-am
|
||||
-rm -f libtool
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: uninstall-dataDATA install-dataDATA tags distdir info-am info \
|
||||
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
|
||||
install-exec install-data-am install-data install-am install \
|
||||
uninstall-am uninstall all-redirect all-am all installdirs \
|
||||
mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -1,3 +1,21 @@
|
||||
dnl Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
dnl
|
||||
dnl This file is part of smmapdfw.
|
||||
dnl
|
||||
dnl smmapdfw is free software; you can redistribute it and/or modify it
|
||||
dnl under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl smmapdfw is distributed in the hope that it will be useful, but WITHOUT
|
||||
dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
dnl License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
dnl Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
VERSIONID(`$Id$')
|
||||
|
||||
|
||||
@ -42,7 +60,10 @@ Scc
|
||||
R< $+ > < $+ > $: < $(cyruscheck $1 $2 $:none $) >
|
||||
|
||||
Scyruscheck
|
||||
R< $+ > < $+ > $: < $1 > < $2 > < $(cyruscheck $1 $2 $:none $) >
|
||||
R< $+ > < $+ > $: < $1 > < $2 > < $&f >
|
||||
dnl do not perform check when sender is not set - so only for the recipient
|
||||
R< $+ > < $+ > < > $@ < ok >
|
||||
R< $+ > < $+ > < $+ > $: < $1 > < $2 > < $(cyruscheck $1 $2 $:none $) >
|
||||
ifelse(_dummy_, `dummy', `dnl
|
||||
dnl dummy
|
||||
R< $+ > < $+ > < $+ > $@ < ok > $(cht_logger $1 -- $2 --- $3 $)', `dnl
|
||||
@ -51,4 +72,5 @@ R< $+ > < $+ > < $+ > $: < $3 >
|
||||
R< <OK> $* > $@ < ok >
|
||||
R< <NOK> $* > $#error $@ 5.0.0 $: "500 Depot returns error: " $1
|
||||
R< <TNOK> $* > $#error $@ 4.0.0 $: "400 Depot returns error: " $1
|
||||
R< $* <temp> > $#error $@ 4.0.0 $: "400 Currently not verification possible, try again later"
|
||||
R$* $#error $@ 4.7.1 $: "451 Local configuration error <cc1>"')
|
||||
|
@ -1,3 +1,21 @@
|
||||
dnl Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
dnl
|
||||
dnl This file is part of smmapdfw.
|
||||
dnl
|
||||
dnl smmapdfw is free software; you can redistribute it and/or modify it
|
||||
dnl under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl smmapdfw is distributed in the hope that it will be useful, but WITHOUT
|
||||
dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
dnl License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
dnl Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
VERSIONID(`$Id$')
|
||||
|
||||
|
||||
@ -75,6 +93,7 @@ Kverifier_helper _VERIFIER_WHITELIST_', `dnl
|
||||
Kverifier_helper _VERIFIER_BLACKLIST_')
|
||||
Kvht_logger syslog
|
||||
C{verifier_fix_white} postmaster
|
||||
Kvbestmx bestmx
|
||||
|
||||
LOCAL_RULESETS
|
||||
# This ruleset can be used to test the verifier in -bt mode
|
||||
@ -84,7 +103,9 @@ R$+ $: < $(verifier $1 $:none $) >
|
||||
Sverifier0
|
||||
R< $={verifier_fix_white} @ $+ > $@ < ok >
|
||||
R< $+ @ $+ > $: < $2 > < $(verifier_helper $1 @ $2 $: $) >
|
||||
R< $+ > < > $: < $(verifier_helper $1 $: $) >
|
||||
R< $+ > < > $: < $1 > < $(verifier_helper $1 $: $) >
|
||||
R< $+ > < > $: < $1 > < $(vbestmx $1 $) >
|
||||
R< $+ > < $+ . > $: < $(verifier_helper "mx:" $2 "" $: $) >
|
||||
ifelse(_mode_, `white', `dnl
|
||||
dnl if we found nothing in the whitelist, we continue with checking
|
||||
R< > $@ < cont >
|
||||
|
21
smmapdfw/mib/DE-HOTTIS-MIB.txt
Normal file
21
smmapdfw/mib/DE-HOTTIS-MIB.txt
Normal file
@ -0,0 +1,21 @@
|
||||
DE-HOTTIS-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
MODULE-IDENTITY, OBJECT-TYPE, Integer32, enterprises FROM SNMPv2-SMI
|
||||
;
|
||||
|
||||
deHottis MODULE-IDENTITY
|
||||
LAST-UPDATED "200411040000Z" -- 04 Nov 2004, midnight
|
||||
ORGANIZATION "hottis.de"
|
||||
CONTACT-INFO "postal: Wolfgang Hottgenroth
|
||||
Eupenstr. 20
|
||||
45259 Essen
|
||||
Germany
|
||||
|
||||
email: woho@hottis.de
|
||||
"
|
||||
DESCRIPTION "My main MIB
|
||||
"
|
||||
::= { enterprises 9676 }
|
||||
|
||||
END
|
354
smmapdfw/mib/DE-HOTTIS-SMMAPD-MIB.txt
Normal file
354
smmapdfw/mib/DE-HOTTIS-SMMAPD-MIB.txt
Normal file
@ -0,0 +1,354 @@
|
||||
DE-HOTTIS-SMMAPD-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
MODULE-IDENTITY, OBJECT-TYPE, Counter32 FROM SNMPv2-SMI
|
||||
deHottis FROM DE-HOTTIS-MIB
|
||||
;
|
||||
|
||||
deHottisSmmapdMIB MODULE-IDENTITY
|
||||
LAST-UPDATED "200411040000Z" -- 04 Nov 2004, midnight
|
||||
ORGANIZATION "hottis.de"
|
||||
CONTACT-INFO "postal: Wolfgang Hottgenroth
|
||||
Eupenstr. 20
|
||||
45259 Essen
|
||||
Germany
|
||||
|
||||
email: woho@hottis.de
|
||||
"
|
||||
DESCRIPTION "MIB for gathering statistics from smmapd
|
||||
"
|
||||
::= { deHottis 2 }
|
||||
|
||||
dhsSmmapdStats OBJECT IDENTIFIER ::= { deHottisSmmapdMIB 1 }
|
||||
|
||||
dhsNumber1 OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"number1"
|
||||
::= { dhsSmmapdStats 1 }
|
||||
|
||||
|
||||
DhsServerStat ::=
|
||||
SEQUENCE {
|
||||
dhsAccepted Counter32,
|
||||
dhsFailed Counter32,
|
||||
dhsRunningNwThreads Integer32,
|
||||
dhsNwThreads Counter32,
|
||||
dhsFailedNwThreads Counter32,
|
||||
dhsOKReturned Counter32,
|
||||
dhsTEMPReturned Counter32,
|
||||
dhsPERMReturned Counter32,
|
||||
dhsNOTFOUNDReturned Counter32,
|
||||
dhsIllegalInputFailure Counter32,
|
||||
dhsUnknownClassFailure Counter32,
|
||||
dhsTimeoutFailure Counter32,
|
||||
dhsNetStringFailure Counter32
|
||||
}
|
||||
|
||||
dhsServerStat OBJECT-TYPE
|
||||
SYNTAX DhsServerStat
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Statistics of the server"
|
||||
::= { dhsSmmapdStats 2 }
|
||||
|
||||
|
||||
dhsAccepted OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Connections accepted by the server"
|
||||
::= { dhsServerStat 1 }
|
||||
|
||||
dhsFailed OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Connections the server failed to accept"
|
||||
::= { dhsServerStat 2 }
|
||||
|
||||
dhsRunningNwThreads OBJECT-TYPE
|
||||
SYNTAX Integer32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Running networker threads"
|
||||
::= { dhsServerStat 3 }
|
||||
|
||||
dhsNwThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Networker threads"
|
||||
::= { dhsServerStat 4 }
|
||||
|
||||
dhsFailedNwThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Networker threads failed to start"
|
||||
::= { dhsServerStat 5 }
|
||||
|
||||
dhsOKReturned OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"OK returned to sendmail"
|
||||
::= { dhsServerStat 6 }
|
||||
|
||||
dhsTEMPReturned OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"TEMP failure returned to sendmail"
|
||||
::= { dhsServerStat 7 }
|
||||
|
||||
dhsPERMReturned OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"PERM failure returned to sendmail"
|
||||
::= { dhsServerStat 8 }
|
||||
|
||||
dhsNOTFOUNDReturned OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"NOTFOUND returned to sendmail"
|
||||
::= { dhsServerStat 9 }
|
||||
|
||||
dhsIllegalInputFailure OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Class not found (PERM) returned to sendmail"
|
||||
::= { dhsServerStat 10 }
|
||||
|
||||
dhsUnknownClassFailure OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Class not found (PERM) returned to sendmail"
|
||||
::= { dhsServerStat 11 }
|
||||
|
||||
dhsTimeoutFailure OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Timeout failure returned to sendmail"
|
||||
::= { dhsServerStat 12 }
|
||||
|
||||
dhsNetStringFailure OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"NetString (NOK) returned to sendmail"
|
||||
::= { dhsServerStat 13 }
|
||||
|
||||
|
||||
DhsVerifierStat ::=
|
||||
SEQUENCE {
|
||||
dhsVCacheEntries Integer32,
|
||||
dhsVRunningWorkerThreads Integer32,
|
||||
dhsVWorkerThreads Counter32,
|
||||
dhsVFailedWorkerThreads Counter32,
|
||||
dhsVTimedOutWorkerThreads Counter32,
|
||||
dhsVRunningCheckerThreads Integer32,
|
||||
dhsVCheckerThreads Counter32,
|
||||
dhsVFailedCheckerThreads Counter32,
|
||||
dhsVAnsweredFromCache Counter32,
|
||||
dhsVReturnedOK Counter32,
|
||||
dhsVReturnedNOK Counter32,
|
||||
dhsVReturnedTNOK Counter32
|
||||
}
|
||||
|
||||
dhsVerifierStat OBJECT-TYPE
|
||||
SYNTAX DhsVerifierStat
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Statistics of the verifier"
|
||||
::= { dhsSmmapdStats 3 }
|
||||
|
||||
|
||||
dhsVCacheEntries OBJECT-TYPE
|
||||
SYNTAX Integer32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Entries in verifier cache"
|
||||
::= { dhsVerifierStat 1 }
|
||||
|
||||
dhsVRunningWorkerThreads OBJECT-TYPE
|
||||
SYNTAX Integer32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Running verifier worker threads"
|
||||
::= { dhsVerifierStat 2 }
|
||||
|
||||
dhsVWorkerThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"verifier worker threads"
|
||||
::= { dhsVerifierStat 3 }
|
||||
|
||||
dhsVFailedWorkerThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"failed to start verifier worker threads"
|
||||
::= { dhsVerifierStat 4 }
|
||||
|
||||
dhsVTimedOutWorkerThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"timed out verifier worker threads"
|
||||
::= { dhsVerifierStat 5 }
|
||||
|
||||
dhsVRunningCheckerThreads OBJECT-TYPE
|
||||
SYNTAX Integer32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Running verifier checker threads"
|
||||
::= { dhsVerifierStat 6 }
|
||||
|
||||
dhsVCheckerThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"verifier checker threads"
|
||||
::= { dhsVerifierStat 7 }
|
||||
|
||||
dhsVFailedCheckerThreads OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"failed to start verifier checker threads"
|
||||
::= { dhsVerifierStat 8 }
|
||||
|
||||
dhsVAnsweredFromCache OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"answers taken directly from cache"
|
||||
::= { dhsVerifierStat 9 }
|
||||
|
||||
dhsVReturnedOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"verifier returned OK"
|
||||
::= { dhsVerifierStat 10 }
|
||||
|
||||
dhsVReturnedNOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"verifier returned NOK"
|
||||
::= { dhsVerifierStat 11 }
|
||||
|
||||
dhsVReturnedTNOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"verifier returned TNOK"
|
||||
::= { dhsVerifierStat 12 }
|
||||
|
||||
|
||||
DhsCyrusStat ::=
|
||||
SEQUENCE {
|
||||
dhsCWorker Counter32,
|
||||
dhsCIllegalInput Counter32,
|
||||
dhsCDepotDNSFailure Counter32,
|
||||
dhsCReturnedOK Counter32,
|
||||
dhsCReturnedNOK Counter32,
|
||||
dhsCReturnedTNOK Counter32
|
||||
}
|
||||
|
||||
dhsCyrusStat OBJECT-TYPE
|
||||
SYNTAX DhsCyrusStat
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Statistics of the cyrus checker"
|
||||
::= { dhsSmmapdStats 4 }
|
||||
|
||||
|
||||
dhsCWorker OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers"
|
||||
::= { dhsCyrusStat 1 }
|
||||
|
||||
dhsCIllegalInput OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers with illegal input"
|
||||
::= { dhsCyrusStat 2 }
|
||||
|
||||
dhsCDepotDNSFailure OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers with depot DNS failure"
|
||||
::= { dhsCyrusStat 3 }
|
||||
|
||||
dhsCReturnedOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers returned OK"
|
||||
::= { dhsCyrusStat 4 }
|
||||
|
||||
dhsCReturnedNOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers returned NOK"
|
||||
::= { dhsCyrusStat 5 }
|
||||
|
||||
dhsCReturnedTNOK OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"cyrus checkers returned TNOK"
|
||||
::= { dhsCyrusStat 6 }
|
||||
|
||||
|
||||
END
|
2
smmapdfw/mib/Makefile.am
Normal file
2
smmapdfw/mib/Makefile.am
Normal file
@ -0,0 +1,2 @@
|
||||
data_DATA = DE-HOTTIS-MIB.txt DE-HOTTIS-SMMAPD-MIB.txt
|
||||
EXTRA_DIST = DE-HOTTIS-MIB.txt DE-HOTTIS-SMMAPD-MIB.txt
|
221
smmapdfw/mib/Makefile.in
Normal file
221
smmapdfw/mib/Makefile.in
Normal file
@ -0,0 +1,221 @@
|
||||
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
BDB_LIBS = @BDB_LIBS@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
GCJ = @GCJ@
|
||||
GCJFLAGS = @GCJFLAGS@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
LIB = @LIB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
data_DATA = DE-HOTTIS-MIB.txt DE-HOTTIS-SMMAPD-MIB.txt
|
||||
EXTRA_DIST = DE-HOTTIS-MIB.txt DE-HOTTIS-SMMAPD-MIB.txt
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DATA = $(data_DATA)
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu mib/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
install-dataDATA: $(data_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(datadir)
|
||||
@list='$(data_DATA)'; for p in $$list; do \
|
||||
if test -f $(srcdir)/$$p; then \
|
||||
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(datadir)/$$p"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(datadir)/$$p; \
|
||||
else if test -f $$p; then \
|
||||
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(datadir)/$$p"; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(datadir)/$$p; \
|
||||
fi; fi; \
|
||||
done
|
||||
|
||||
uninstall-dataDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(data_DATA)'; for p in $$list; do \
|
||||
rm -f $(DESTDIR)$(datadir)/$$p; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = mib
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
here=`cd $(top_builddir) && pwd`; \
|
||||
top_distdir=`cd $(top_distdir) && pwd`; \
|
||||
distdir=`cd $(distdir) && pwd`; \
|
||||
cd $(top_srcdir) \
|
||||
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu mib/Makefile
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
info-am:
|
||||
info: info-am
|
||||
dvi-am:
|
||||
dvi: dvi-am
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
installcheck-am:
|
||||
installcheck: installcheck-am
|
||||
install-exec-am:
|
||||
install-exec: install-exec-am
|
||||
|
||||
install-data-am: install-dataDATA
|
||||
install-data: install-data-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-am
|
||||
uninstall-am: uninstall-dataDATA
|
||||
uninstall: uninstall-am
|
||||
all-am: Makefile $(DATA)
|
||||
all-redirect: all-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(datadir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-am
|
||||
|
||||
distclean-am: distclean-generic clean-am
|
||||
-rm -f libtool
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
.PHONY: uninstall-dataDATA install-dataDATA tags distdir info-am info \
|
||||
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
|
||||
install-exec install-data-am install-data install-am install \
|
||||
uninstall-am uninstall all-redirect all-am all installdirs \
|
||||
mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -1,9 +1,10 @@
|
||||
noinst_HEADERS = containers.h
|
||||
noinst_HEADERS = containers.h snmp_subagent.h
|
||||
sysconf_DATA = smmapd.ini
|
||||
bin_PROGRAMS = smmapd
|
||||
smmapd_SOURCES = smmapd.c containers.c
|
||||
smmapd_SOURCES = smmapd.c containers.c snmp_subagent.c
|
||||
smmapd_LDADD = ../libsmmapdfw/libsmmapdfw.la
|
||||
|
||||
INCLUDES = -I../libsmmapdfw
|
||||
CPPFLAGS = -DDEFAULT_SMMAPD_INI=\"$(sysconfdir)/smmapd.ini\" @CPPFLAGS@
|
||||
|
||||
EXTRA_DIST = smmapd.ini
|
@ -87,14 +87,16 @@ RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
|
||||
noinst_HEADERS = containers.h
|
||||
noinst_HEADERS = containers.h snmp_subagent.h
|
||||
sysconf_DATA = smmapd.ini
|
||||
bin_PROGRAMS = smmapd
|
||||
smmapd_SOURCES = smmapd.c containers.c
|
||||
smmapd_SOURCES = smmapd.c containers.c snmp_subagent.c
|
||||
smmapd_LDADD = ../libsmmapdfw/libsmmapdfw.la
|
||||
|
||||
INCLUDES = -I../libsmmapdfw
|
||||
CPPFLAGS = -DDEFAULT_SMMAPD_INI=\"$(sysconfdir)/smmapd.ini\" @CPPFLAGS@
|
||||
|
||||
EXTRA_DIST = smmapd.ini
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
@ -105,7 +107,8 @@ PROGRAMS = $(bin_PROGRAMS)
|
||||
DEFS = @DEFS@ -I. -I$(srcdir) -I..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
smmapd_OBJECTS = smmapd.$(OBJEXT) containers.$(OBJEXT)
|
||||
smmapd_OBJECTS = smmapd.$(OBJEXT) containers.$(OBJEXT) \
|
||||
snmp_subagent.$(OBJEXT)
|
||||
smmapd_DEPENDENCIES = ../libsmmapdfw/libsmmapdfw.la
|
||||
smmapd_LDFLAGS =
|
||||
CFLAGS = @CFLAGS@
|
||||
@ -124,7 +127,7 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DEP_FILES = .deps/containers.P .deps/smmapd.P
|
||||
DEP_FILES = .deps/containers.P .deps/smmapd.P .deps/snmp_subagent.P
|
||||
SOURCES = $(smmapd_SOURCES)
|
||||
OBJECTS = $(smmapd_OBJECTS)
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
@ -21,6 +43,7 @@
|
||||
#include "containers.h"
|
||||
#include "cfg.h"
|
||||
#include "smmapd.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
#define CFG_SECTION_GLOBAL "global"
|
||||
@ -37,7 +60,7 @@ classes_t *classes_head = &classes_root;
|
||||
|
||||
|
||||
int containers_setup(container_handle_t **ch) {
|
||||
*ch = (container_handle_t*)malloc(sizeof(container_handle_t));
|
||||
*ch = (container_handle_t*)htmalloc(sizeof(container_handle_t));
|
||||
(*ch)->worker_handle_root.next = NULL;
|
||||
return 0;
|
||||
}
|
||||
@ -108,7 +131,7 @@ int containers_dispatcher(container_handle_t *ch, char *input, char *output) {
|
||||
|
||||
if ((NULL == wh_last->next) && (NULL == wh2)) {
|
||||
syslog(LOG_DEBUG, "dispatcher: we haven't one, we create one");
|
||||
wh2 = (worker_handle_t*)malloc(sizeof(worker_handle_t));
|
||||
wh2 = (worker_handle_t*)htmalloc(sizeof(worker_handle_t));
|
||||
wh2->id = classes->id;
|
||||
if (NULL != classes->descr->work_setup_function) {
|
||||
err = (*classes->descr->work_setup_function)(classes->handle, &(wh2->handle));
|
||||
@ -148,7 +171,7 @@ static int register_class(int id, class_descriptor_t *class_descriptor) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
w = (classes_t *) malloc(sizeof(classes_t));
|
||||
w = (classes_t *) htmalloc(sizeof(classes_t));
|
||||
if (NULL == w) {
|
||||
syslog(LOG_ERR, "register_class: unable to alloc memory");
|
||||
return -2;
|
||||
@ -232,7 +255,7 @@ int register_all() {
|
||||
return -3;
|
||||
}
|
||||
|
||||
obj_name = (char*) malloc(((cfg_plugin_dir == NULL) ? 0 : strlen(cfg_plugin_dir)) + strlen(cfg_obj) + 5);
|
||||
obj_name = (char*) htmalloc(((cfg_plugin_dir == NULL) ? 0 : strlen(cfg_plugin_dir)) + strlen(cfg_obj) + 5);
|
||||
obj_name[0] = '\0';
|
||||
if (cfg_plugin_dir != NULL) {
|
||||
strcat(obj_name, cfg_plugin_dir);
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _CONTAINERS_H_
|
||||
#define _CONTAINERS_H_
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
@ -41,10 +62,13 @@
|
||||
#include "containers.h"
|
||||
#include "cfg.h"
|
||||
#include "safe_write.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
#define _SMMAPD_C_
|
||||
#include "smmapd.h"
|
||||
|
||||
#include "stats.h"
|
||||
#include "snmp_subagent.h"
|
||||
|
||||
#include "sunos_comp.h"
|
||||
|
||||
@ -52,6 +76,7 @@
|
||||
#define CFG_SECTION_GLOBAL "global"
|
||||
#define CFG_NAME_ADDRESS "address"
|
||||
#define CFG_NAME_PORT "port"
|
||||
#define CFG_NETSTRING_DISABLED "netstring_disabled"
|
||||
|
||||
#define DEFAULT_PORT "8888"
|
||||
|
||||
@ -72,10 +97,38 @@ typedef struct networkerThread_s networkerThread_t;
|
||||
|
||||
ht_queue_t terminated_networker_queue;
|
||||
pthread_t cleanerThread;
|
||||
|
||||
#if ENABLE_STATS==1
|
||||
pthread_t statsThread;
|
||||
#endif
|
||||
|
||||
#if ENABLE_NETSNMP==1
|
||||
pthread_t snmpThread;
|
||||
#endif
|
||||
count_t thread_counter;
|
||||
|
||||
cfg_t *cfg;
|
||||
|
||||
int netstring_disabled = 0;
|
||||
|
||||
#if ENABLE_STATS==1
|
||||
void * statser(void * arg) {
|
||||
int stdout_nice = atoi(findcfgx(cfg, "stats", "stdout_nice", "0"));
|
||||
int syslog_nice = atoi(findcfgx(cfg, "stats", "syslog_nice", "0"));
|
||||
int period = atoi(findcfgx(cfg, "stats", "period", "10"));
|
||||
|
||||
while(1) {
|
||||
outputStats(stdout_nice, syslog_nice);
|
||||
sleep(period);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_NETSNMP==1
|
||||
void * snmper(void * arg) {
|
||||
snmp_subagent_main(cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
void * cleaner(void * arg) {
|
||||
networkerThread_t *t;
|
||||
@ -88,6 +141,7 @@ void * cleaner(void * arg) {
|
||||
count_get(&thread_counter));
|
||||
t = (networkerThread_t*) queue_get_wait(&terminated_networker_queue);
|
||||
count_dec(&thread_counter);
|
||||
decStatCounter(STAT_CNT_NETWORKER_R_THREADS);
|
||||
|
||||
syslog(LOG_DEBUG, "cleaner: Networker serving %d (address: %s, port: %d), result %d",
|
||||
t->clientSock, inet_ntoa(t->clientAddr.sin_addr),
|
||||
@ -122,6 +176,8 @@ void * networker(void * arg) {
|
||||
networkerThread_t * thread = (networkerThread_t *) arg;
|
||||
thread->pthread = pthread_self();
|
||||
|
||||
incStatCounter(STAT_CNT_NETWORKER_THREADS);
|
||||
|
||||
syslog(LOG_DEBUG, "networker: serving %d (address: %s, port: %d) started",
|
||||
thread->clientSock, inet_ntoa(thread->clientAddr.sin_addr),
|
||||
ntohs(thread->clientAddr.sin_port));
|
||||
@ -137,27 +193,36 @@ void * networker(void * arg) {
|
||||
else
|
||||
buffer[cnt] = '\0';
|
||||
|
||||
len = strtol(buffer, &input, 10);
|
||||
if ((0 == len) && (buffer == input)) {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no length found: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (*input++ != ':') {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no colon found: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (strlen(input)-1 != len) {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, length does not match: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (input[strlen(input)-1] != ',') {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no terminating comma: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
dispatcher_result = 0;
|
||||
if (netstring_disabled) {
|
||||
input = buffer;
|
||||
} else {
|
||||
input[strlen(input)-1] = '\0'; /* strip off the comma */
|
||||
|
||||
len = strtol(buffer, &input, 10);
|
||||
if ((0 == len) && (buffer == input)) {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no length found: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (*input++ != ':') {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no colon found: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (strlen(input)-1 != len) {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, length does not match: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else if (input[strlen(input)-1] != ',') {
|
||||
syslog(LOG_DEBUG, "networker: netstring unparsable, no terminating comma: %s", buffer);
|
||||
dispatcher_result = SMM_NETSTRING_UNPARSABLE;
|
||||
} else {
|
||||
input[strlen(input)-1] = '\0'; /* strip off the comma */
|
||||
}
|
||||
}
|
||||
|
||||
if (!dispatcher_result) {
|
||||
answer[0] = '\0';
|
||||
dispatcher_result = containers_dispatcher(container_handle, input, answer);
|
||||
syslog(LOG_DEBUG, "networker: dispatcher result: %d, answer: %s", dispatcher_result, answer);
|
||||
}
|
||||
|
||||
incStatCounter(dispatcher_result + STAT_CNT_OFFSET);
|
||||
|
||||
result_text = (dispatcher_result > SMM_MAX_NUM) ?
|
||||
T_SMM_RESULTS[0] :
|
||||
T_SMM_RESULTS[dispatcher_result];
|
||||
@ -169,11 +234,15 @@ void * networker(void * arg) {
|
||||
if (NULL == answer_ptr)
|
||||
answer_ptr = answer;
|
||||
|
||||
snprintf(output, OUTPUT_BUFSIZE, "%d:%s%s%s,",
|
||||
strlen(result_text) + strlen(answer_ptr) + ((strlen(answer_ptr) > 0) ? 1 : 0),
|
||||
result_text,
|
||||
(strlen(answer_ptr) > 0) ? " " : "",
|
||||
answer_ptr);
|
||||
if (netstring_disabled) {
|
||||
snprintf(output, OUTPUT_BUFSIZE, "%s\n", answer_ptr);
|
||||
} else {
|
||||
snprintf(output, OUTPUT_BUFSIZE, "%d:%s%s%s,",
|
||||
strlen(result_text) + strlen(answer_ptr) + ((strlen(answer_ptr) > 0) ? 1 : 0),
|
||||
result_text,
|
||||
(strlen(answer_ptr) > 0) ? " " : "",
|
||||
answer_ptr);
|
||||
}
|
||||
|
||||
safe_write(thread->clientSock, output, strlen(output));
|
||||
}
|
||||
@ -199,9 +268,14 @@ int server() {
|
||||
networkerThread_t *thread;
|
||||
pthread_t tid;
|
||||
int optval = 1;
|
||||
|
||||
int enableStats;
|
||||
int enableSnmp;
|
||||
|
||||
char *cfg_address, *cfg_port;
|
||||
|
||||
netstring_disabled = atoi(findcfgx(cfg, CFG_SECTION_GLOBAL, CFG_NETSTRING_DISABLED, "0"));
|
||||
|
||||
|
||||
serverSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (-1 == serverSock) {
|
||||
syslog(LOG_ERR, "server: failure when creating server socket");
|
||||
@ -243,6 +317,21 @@ int server() {
|
||||
queue_init(&terminated_networker_queue);
|
||||
pthread_create(&cleanerThread, NULL, &cleaner, NULL);
|
||||
|
||||
#if ENABLE_STATS==1
|
||||
enableStats = atoi(findcfgx(cfg, "global", "enable_stats", "0"));
|
||||
if (enableStats) {
|
||||
syslog(LOG_INFO, "server: starting stats thread");
|
||||
pthread_create(&statsThread, NULL, &statser, NULL);
|
||||
}
|
||||
#endif /* ENABLE_STATS */
|
||||
|
||||
#if ENABLE_NETSNMP==1
|
||||
enableSnmp = atoi(findcfgx(cfg, "global", "enable_snmp", "0"));
|
||||
if (enableSnmp) {
|
||||
syslog(LOG_INFO, "server: starting snmp subagent thread");
|
||||
pthread_create(&snmpThread, NULL, &snmper, NULL);
|
||||
}
|
||||
#endif /* ENABLE_NETSNMP */
|
||||
|
||||
while (1) {
|
||||
syslog(LOG_DEBUG, "server: Waiting for connection");
|
||||
@ -251,15 +340,18 @@ int server() {
|
||||
syslog(LOG_DEBUG, "server: Got a connection %d", clientSock);
|
||||
|
||||
if (-1 == clientSock) {
|
||||
syslog(LOG_ERR, "server: failure when accepting connection");
|
||||
return -1;
|
||||
incStatCounter(STAT_CNT_FAILED);
|
||||
syslog(LOG_ERR, "server: failure when accepting connection: %d, %s",
|
||||
errno, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
incStatCounter(STAT_CNT_ACCEPTED);
|
||||
|
||||
thread = (networkerThread_t *) malloc(sizeof(networkerThread_t)+10);
|
||||
thread = (networkerThread_t *) htmalloc(sizeof(networkerThread_t)+10);
|
||||
if (NULL == thread) {
|
||||
syslog(LOG_ERR, "server: unable to alloc memory for networker");
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -269,12 +361,15 @@ int server() {
|
||||
thread->clientAddrLen = clientAddrLen;
|
||||
|
||||
count_inc(&thread_counter);
|
||||
incStatCounter(STAT_CNT_NETWORKER_R_THREADS);
|
||||
res = pthread_create(&tid, NULL, &networker, thread);
|
||||
if (0 != res) {
|
||||
syslog(LOG_ERR, "server: unable to start networker thread");
|
||||
free(thread);
|
||||
decStatCounter(STAT_CNT_NETWORKER_R_THREADS);
|
||||
incStatCounter(STAT_CNT_NETWORKER_THREADS_FAILED);
|
||||
count_dec(&thread_counter);
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,10 +397,10 @@ int main(int argc, char **argv) {
|
||||
foreground = 1;
|
||||
break;
|
||||
case 'f':
|
||||
cfg_file = strdup(optarg);
|
||||
cfg_file = htstrdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
pid_file = strdup(optarg);
|
||||
pid_file = htstrdup(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
printf("\nsmmapd - Wolfgang Hottgenroth <woho@hottis.de>\n");
|
||||
|
@ -6,6 +6,21 @@ port = 8887
|
||||
; plugin_dir = /home/who/Sources/sf/smmapdfw
|
||||
; plugins = test_worker1 test_worker2 verifier cyruscheck lua_worker
|
||||
plugins = verifier
|
||||
enable_stats = 0
|
||||
enable_snmp = 1
|
||||
|
||||
; disables the netstring codec, only for debugging in the development
|
||||
; phase, sendmail is unable to talk to smmapd if the codec is disabled
|
||||
; netstring_disabled = 1
|
||||
|
||||
[snmp]
|
||||
agentx_socket = /var/agentx/master
|
||||
|
||||
[stats]
|
||||
stdout_nice = 2
|
||||
syslog_nice = 1
|
||||
period = 1
|
||||
|
||||
|
||||
[test_worker1]
|
||||
obj = libtest_workers.so
|
||||
@ -21,7 +36,7 @@ timeout_dialog = 20
|
||||
cache_enabled = 1
|
||||
cache_expiry = 86400
|
||||
sender_address = <>
|
||||
ehlo_arg = local
|
||||
helo_arg = local
|
||||
smtp_port = 25
|
||||
max_checker_threads = 100
|
||||
|
||||
|
222
smmapdfw/smmapd/snmp_subagent.c
Normal file
222
smmapdfw/smmapd/snmp_subagent.c
Normal file
@ -0,0 +1,222 @@
|
||||
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if ENABLE_NETSNMP==1
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include "stats.h"
|
||||
#include "smmapd.h"
|
||||
#include "cfg.h"
|
||||
|
||||
typedef struct var_cnt_map_s {
|
||||
char* var;
|
||||
int cnt;
|
||||
} var_cnt_map_t;
|
||||
|
||||
int number1 = 42;
|
||||
int counter32 = 1;
|
||||
int integer32 = 1;
|
||||
|
||||
var_cnt_map_t *var_cnt_map = NULL;
|
||||
int num_var_cnt_map = 0;
|
||||
|
||||
char *agentx_socket = NULL;
|
||||
|
||||
|
||||
int
|
||||
handle_number1(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests)
|
||||
{
|
||||
switch(reqinfo->mode) {
|
||||
|
||||
case MODE_GET:
|
||||
snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER,
|
||||
(u_char *) &number1,
|
||||
sizeof(number1));
|
||||
break;
|
||||
|
||||
default:
|
||||
return SNMP_ERR_GENERR;
|
||||
}
|
||||
|
||||
return SNMP_ERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
handle_it(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests,
|
||||
u_char type)
|
||||
{
|
||||
int i, cnt, value, res;
|
||||
for (i=0; i<num_var_cnt_map; i++)
|
||||
if (0 == strcmp(reginfo->handlerName, var_cnt_map[i].var)) {
|
||||
cnt = var_cnt_map[i].cnt;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MODE_GET == reqinfo->mode) {
|
||||
value = getStatCounter(cnt);
|
||||
snmp_set_var_typed_value(requests->requestvb, type,
|
||||
(u_char *) &value,
|
||||
sizeof(value));
|
||||
res = SNMP_ERR_NOERROR;
|
||||
} else {
|
||||
res = SNMP_ERR_GENERR;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
handle_counter32(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests)
|
||||
{
|
||||
return handle_it(handler, reginfo, reqinfo, requests, ASN_COUNTER);
|
||||
}
|
||||
|
||||
int
|
||||
handle_integer32(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests)
|
||||
{
|
||||
return handle_it(handler, reginfo, reqinfo, requests, ASN_INTEGER);
|
||||
}
|
||||
|
||||
void map_var_cnt(int cnt, char* var) {
|
||||
var_cnt_map = (var_cnt_map_t*) realloc(var_cnt_map, sizeof(var_cnt_map_t) * (num_var_cnt_map + 1));
|
||||
var_cnt_map[num_var_cnt_map].var = var;
|
||||
var_cnt_map[num_var_cnt_map].cnt = cnt;
|
||||
num_var_cnt_map++;
|
||||
}
|
||||
|
||||
#define NETSNMP_REGISTER_SCALAR(A, B, C) netsnmp_register_scalar(netsnmp_create_handler_registration(#A, B, A##_oid, OID_LENGTH(A##_oid), HANDLER_CAN_RONLY)); map_var_cnt(C, #A)
|
||||
|
||||
void
|
||||
init_dhsMIBObjects(void)
|
||||
{
|
||||
static oid dhsNumber1_oid[] = { 1,3,6,1,4,1,9676,2,1,1 };
|
||||
static oid dhsAccepted_oid[] = { 1,3,6,1,4,1,9676,2,1,2,1 };
|
||||
static oid dhsFailed_oid[] = { 1,3,6,1,4,1,9676,2,1,2,2 };
|
||||
static oid dhsRunningNwThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,2,3 };
|
||||
static oid dhsNwThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,2,4 };
|
||||
static oid dhsFailedNwThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,2,5 };
|
||||
static oid dhsOKReturned_oid[] = { 1,3,6,1,4,1,9676,2,1,2,6 };
|
||||
static oid dhsTEMPReturned_oid[] = { 1,3,6,1,4,1,9676,2,1,2,7 };
|
||||
static oid dhsPERMReturned_oid[] = { 1,3,6,1,4,1,9676,2,1,2,8 };
|
||||
static oid dhsNOTFOUNDReturned_oid[] = { 1,3,6,1,4,1,9676,2,1,2,9 };
|
||||
static oid dhsIllegalInputFailure_oid[] = { 1,3,6,1,4,1,9676,2,1,2,10 };
|
||||
static oid dhsUnknownClassFailure_oid[] = { 1,3,6,1,4,1,9676,2,1,2,11 };
|
||||
static oid dhsTimeoutFailure_oid[] = { 1,3,6,1,4,1,9676,2,1,2,12 };
|
||||
static oid dhsNetStringFailure_oid[] = { 1,3,6,1,4,1,9676,2,1,2,13 };
|
||||
|
||||
static oid dhsVCacheEntries_oid[] = { 1,3,6,1,4,1,9676,2,1,3,1 };
|
||||
static oid dhsVRunningWorkerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,2 };
|
||||
static oid dhsVWorkerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,3 };
|
||||
static oid dhsVFailedWorkerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,4 };
|
||||
static oid dhsVTimedOutWorkerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,5 };
|
||||
static oid dhsVRunningCheckerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,6 };
|
||||
static oid dhsVCheckerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,7 };
|
||||
static oid dhsVFailedCheckerThreads_oid[] = { 1,3,6,1,4,1,9676,2,1,3,8 };
|
||||
static oid dhsVAnsweredFromCache_oid[] = { 1,3,6,1,4,1,9676,2,1,3,9 };
|
||||
static oid dhsVReturnedOK_oid[] = { 1,3,6,1,4,1,9676,2,1,3,10 };
|
||||
static oid dhsVReturnedNOK_oid[] = { 1,3,6,1,4,1,9676,2,1,3,11 };
|
||||
static oid dhsVReturnedTNOK_oid[] = { 1,3,6,1,4,1,9676,2,1,3,12 };
|
||||
|
||||
static oid dhsCWorker_oid[] = { 1,3,6,1,4,1,9676,2,1,4,1 };
|
||||
static oid dhsCIllegalInput_oid[] = { 1,3,6,1,4,1,9676,2,1,4,2 };
|
||||
static oid dhsCDepotDNSFailure_oid[] = { 1,3,6,1,4,1,9676,2,1,4,3 };
|
||||
static oid dhsCReturnedOK_oid[] = { 1,3,6,1,4,1,9676,2,1,4,4 };
|
||||
static oid dhsCReturnedNOK_oid[] = { 1,3,6,1,4,1,9676,2,1,4,5 };
|
||||
static oid dhsCReturnedTNOK_oid[] = { 1,3,6,1,4,1,9676,2,1,4,6 };
|
||||
|
||||
|
||||
DEBUGMSGTL(("dhsMIBObjects", "Initializing\n"));
|
||||
|
||||
NETSNMP_REGISTER_SCALAR(dhsNumber1, handle_number1, 0);
|
||||
NETSNMP_REGISTER_SCALAR(dhsAccepted, handle_counter32, STAT_CNT_ACCEPTED);
|
||||
NETSNMP_REGISTER_SCALAR(dhsFailed, handle_counter32, STAT_CNT_FAILED);
|
||||
NETSNMP_REGISTER_SCALAR(dhsRunningNwThreads, handle_integer32, STAT_CNT_NETWORKER_R_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsNwThreads, handle_counter32, STAT_CNT_NETWORKER_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsFailedNwThreads, handle_counter32, STAT_CNT_NETWORKER_THREADS_FAILED);
|
||||
NETSNMP_REGISTER_SCALAR(dhsOKReturned, handle_counter32, SMM_OK+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsTEMPReturned, handle_counter32, SMM_TEMP_NOK+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsPERMReturned, handle_counter32, SMM_PERM_NOK+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsNOTFOUNDReturned, handle_counter32, SMM_NOT_FOUND_NOK+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsIllegalInputFailure, handle_counter32, SMM_ILLEGAL_INPUT+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsUnknownClassFailure, handle_counter32, SMM_UNKNOWN_CLASS+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsTimeoutFailure, handle_counter32, SMM_TIMEOUT_NOK+STAT_CNT_OFFSET);
|
||||
NETSNMP_REGISTER_SCALAR(dhsNetStringFailure, handle_counter32, SMM_NETSTRING_UNPARSABLE+STAT_CNT_OFFSET);
|
||||
|
||||
NETSNMP_REGISTER_SCALAR(dhsVCacheEntries, handle_integer32, STAT_CNT_VERIFIER_CACHE);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVRunningWorkerThreads, handle_integer32, STAT_CNT_VERIFIER_WORKER_R_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVWorkerThreads, handle_counter32, STAT_CNT_VERIFIER_WORKER_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVFailedWorkerThreads, handle_counter32, STAT_CNT_VERIFIER_WORKER_THREADS_FAILED);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVTimedOutWorkerThreads, handle_counter32, STAT_CNT_VERIFIER_WORKER_THREADS_TIMEOUT);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVRunningCheckerThreads, handle_integer32, STAT_CNT_VERIFIER_CHECKER_R_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVCheckerThreads, handle_counter32, STAT_CNT_VERIFIER_CHECKER_THREADS);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVFailedCheckerThreads, handle_counter32, STAT_CNT_VERIFIER_CHECKER_THREADS_FAILED);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVAnsweredFromCache, handle_counter32, STAT_CNT_VERIFIER_ANSWERED_FROM_CACHE);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVReturnedOK, handle_counter32, STAT_CNT_VERIFIER_RETURNED_OK);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVReturnedNOK, handle_counter32, STAT_CNT_VERIFIER_RETURNED_NOK);
|
||||
NETSNMP_REGISTER_SCALAR(dhsVReturnedTNOK, handle_counter32, STAT_CNT_VERIFIER_RETURNED_TNOK);
|
||||
|
||||
NETSNMP_REGISTER_SCALAR(dhsCWorker, handle_counter32, STAT_CNT_CYRUS_WORKER);
|
||||
NETSNMP_REGISTER_SCALAR(dhsCIllegalInput, handle_counter32, STAT_CNT_CYRUS_ILLEGAL_INPUT);
|
||||
NETSNMP_REGISTER_SCALAR(dhsCDepotDNSFailure, handle_counter32, STAT_CNT_CYRUS_DEPOT_DNS_FAILURE);
|
||||
NETSNMP_REGISTER_SCALAR(dhsCReturnedOK, handle_counter32, STAT_CNT_CYRUS_RETURNED_OK);
|
||||
NETSNMP_REGISTER_SCALAR(dhsCReturnedNOK, handle_counter32, STAT_CNT_CYRUS_RETURNED_NOK);
|
||||
NETSNMP_REGISTER_SCALAR(dhsCReturnedTNOK, handle_counter32, STAT_CNT_CYRUS_RETURNED_TNOK);
|
||||
|
||||
}
|
||||
|
||||
void snmp_subagent_main(cfg_t *cfg) {
|
||||
snmp_enable_syslog_ident("smmapd", LOG_LOCAL2);
|
||||
|
||||
agentx_socket = findcfgx(cfg, "snmp", "agentx_socket", "/var/agentx/master");
|
||||
netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET, agentx_socket);
|
||||
|
||||
netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
|
||||
init_agent("smmapd_subagent");
|
||||
init_dhsMIBObjects();
|
||||
init_snmp("smmapd_subagent");
|
||||
|
||||
while(1) {
|
||||
agent_check_and_process(1);
|
||||
}
|
||||
|
||||
snmp_shutdown("mysubagent");
|
||||
}
|
||||
#endif
|
35
smmapdfw/smmapd/snmp_subagent.h
Normal file
35
smmapdfw/smmapd/snmp_subagent.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _SNMP_SUBAGENT_H_
|
||||
#define _SNMP_SUBAGENT_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "cfg.h"
|
||||
|
||||
#if ENABLE_NETSNMP==1
|
||||
void snmp_subagent_main(cfg_t *cfg);
|
||||
#endif
|
||||
|
||||
#endif /* _SNMP_SUBAGENT_H_ */
|
||||
|
||||
|
75
smmapdfw/test/Connector.py
Normal file
75
smmapdfw/test/Connector.py
Normal file
@ -0,0 +1,75 @@
|
||||
import socket
|
||||
import time
|
||||
from threading import Thread, activeCount
|
||||
|
||||
|
||||
class NetStringError(ValueError): pass
|
||||
|
||||
def NetStringDecode(s):
|
||||
try:
|
||||
length, data = s.split(':', 1)
|
||||
except ValueError:
|
||||
raise NetStringError, "Separator not found"
|
||||
try:
|
||||
length = int(length)
|
||||
except ValueError:
|
||||
raise NetStringError, "Can not read length"
|
||||
if len(data) != length+1:
|
||||
raise NetStringError, "Data has unexpected length"
|
||||
if data[-1] != ',':
|
||||
raise NetStringError, "End-delimiter not found"
|
||||
return data[:-1]
|
||||
|
||||
def NetStringEncode(s):
|
||||
return str(len(s)) + ":" + s + ","
|
||||
|
||||
|
||||
class Connector (Thread):
|
||||
def __init__(self, config, details):
|
||||
Thread.__init__(self)
|
||||
self.config = config
|
||||
self.host = self.config.get('Global', 'Host')
|
||||
self.port = int(self.config.get('Global', 'Port'))
|
||||
self.klass = self.__class__.__name__
|
||||
self.details = details
|
||||
|
||||
def connect(self):
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((self.host, self.port))
|
||||
|
||||
|
||||
def query(self, request):
|
||||
nets_request = NetStringEncode(self.klass + ' ' + request)
|
||||
|
||||
print(self.getName() + " REQUEST: " + nets_request)
|
||||
self.sock.sendall(nets_request)
|
||||
|
||||
nets_response = self.sock.recv(8192)
|
||||
print(self.getName() + " NETS_RESPONSE: " + nets_response)
|
||||
response = NetStringDecode(nets_response)
|
||||
print(self.getName() + " RESPONSE: " + response)
|
||||
|
||||
return response
|
||||
|
||||
def close(self):
|
||||
self.sock.close()
|
||||
|
||||
|
||||
def execute(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def run(self):
|
||||
return self.execute()
|
||||
|
||||
|
||||
def threadedExecute(config, klass, numOfThreads, details):
|
||||
threads = []
|
||||
|
||||
while (1):
|
||||
if activeCount() < numOfThreads:
|
||||
t = klass(config, details)
|
||||
t.start()
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
|
13
smmapdfw/test/test
Executable file
13
smmapdfw/test/test
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import ConfigParser
|
||||
|
||||
import Connector
|
||||
import verifier
|
||||
import test_worker1
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.read("test.ini");
|
||||
|
||||
|
||||
Connector.threadedExecute(config, verifier.verifier, int(config.get('Global', 'Threads')), {})
|
10
smmapdfw/test/test.ini
Normal file
10
smmapdfw/test/test.ini
Normal file
@ -0,0 +1,10 @@
|
||||
[Global]
|
||||
Host: ddev8.eng.emea.uu.net
|
||||
Port: 389
|
||||
Threads: 20
|
||||
|
||||
[Verifier]
|
||||
AddressFile: addresses.lst
|
||||
QueriesPerSession: 2
|
||||
|
||||
|
6
smmapdfw/test/test_worker1.py
Normal file
6
smmapdfw/test/test_worker1.py
Normal file
@ -0,0 +1,6 @@
|
||||
from Connector import Connector
|
||||
|
||||
class test_worker1 (Connector):
|
||||
def __init__(self, config):
|
||||
Connector.__init__(self, config)
|
||||
|
29
smmapdfw/test/verifier.py
Normal file
29
smmapdfw/test/verifier.py
Normal file
@ -0,0 +1,29 @@
|
||||
import random
|
||||
from Connector import Connector
|
||||
|
||||
class verifier (Connector):
|
||||
addresses = None
|
||||
|
||||
def __init__(self, config, details):
|
||||
Connector.__init__(self, config, details)
|
||||
self.readAddressFile()
|
||||
random.seed()
|
||||
|
||||
def readAddressFile(self):
|
||||
if (verifier.addresses == None):
|
||||
addressFile = self.config.get('Verifier', 'AddressFile')
|
||||
f = open(addressFile)
|
||||
l = f.readlines()
|
||||
f.close()
|
||||
verifier.addresses = map(lambda x: x[:-1].rstrip(), l)
|
||||
|
||||
|
||||
def execute(self):
|
||||
queriesPerSession = int(self.config.get('Verifier', 'QueriesPerSession'))
|
||||
self.connect()
|
||||
for i in range(queriesPerSession):
|
||||
a = verifier.addresses[int(random.random()*len(verifier.addresses))]
|
||||
self.query(a)
|
||||
self.close()
|
||||
|
||||
|
@ -1,6 +1,28 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include "containers_public.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
int test_worker1_init(cfgl_t *cfg, void **handle);
|
||||
int test_worker1_setup(void *handle, void **work_handle);
|
||||
@ -43,7 +65,7 @@ int test_worker1_init(cfgl_t *cfg, void **handle) {
|
||||
}
|
||||
|
||||
int test_worker1_setup(void *handle, void **work_handle) {
|
||||
test_worker1_handle_t *twh = (test_worker1_handle_t*)malloc(sizeof(test_worker1_handle_t));
|
||||
test_worker1_handle_t *twh = (test_worker1_handle_t*)htmalloc(sizeof(test_worker1_handle_t));
|
||||
twh->counter = 0;
|
||||
*work_handle = twh;
|
||||
return 0;
|
||||
|
@ -1,3 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2004, Wolfgang Hottgenroth
|
||||
|
||||
This file is part of smmapdfw.
|
||||
|
||||
smmapdfw 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.
|
||||
|
||||
smmapdfw 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 smmapdfw. If not, write to the Free Software Foundation, 59
|
||||
Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
@ -15,7 +35,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if ENABLE_VERIFY_CACHE == 1
|
||||
#if ENABLE_CACHE == 1
|
||||
#define DB_DBM_HSEARCH 1
|
||||
#include <db.h>
|
||||
#endif
|
||||
@ -23,11 +43,12 @@
|
||||
#include "containers_public.h"
|
||||
#include "smmapd.h"
|
||||
|
||||
#include "dns.h"
|
||||
#include "htdns.h"
|
||||
#include "queue.h"
|
||||
#include "smtp.h"
|
||||
#include "htmalloc.h"
|
||||
|
||||
|
||||
#include "stats.h"
|
||||
|
||||
#define SMM_LOCAL_PERM_NOK 101
|
||||
#define SMM_LOCAL_TEMP_NOK 102
|
||||
@ -43,7 +64,7 @@ struct verify_container_handle_s {
|
||||
pthread_mutex_t *cache_mutex;
|
||||
char *cache_file;
|
||||
char *sender_address;
|
||||
char *ehlo_arg;
|
||||
char *helo_arg;
|
||||
int smtp_port;
|
||||
int max_checker_threads;
|
||||
};
|
||||
@ -140,13 +161,13 @@ class_descriptor_t verifier = {
|
||||
int verify_init(cfgl_t *cfg, void **handle) {
|
||||
verify_container_handle_t *vch;
|
||||
|
||||
vch = (verify_container_handle_t*) malloc(sizeof(verify_container_handle_t));
|
||||
vch = (verify_container_handle_t*) htmalloc(sizeof(verify_container_handle_t));
|
||||
vch->cfg = cfg;
|
||||
|
||||
vch->timeout_result = atoi(findcfglx(vch->cfg, "timeout_result", "5"));
|
||||
vch->timeout_dialog = atoi(findcfglx(vch->cfg, "timeout_dialog", "20"));
|
||||
vch->sender_address = findcfglx(vch->cfg, "sender_address", "<>");
|
||||
vch->ehlo_arg = findcfglx(vch->cfg, "ehlo_arg", "local");
|
||||
vch->helo_arg = findcfglx(vch->cfg, "helo_arg", "local");
|
||||
vch->smtp_port = atoi(findcfglx(vch->cfg, "smtp_port", "25"));
|
||||
vch->max_checker_threads = atoi(findcfglx(vch->cfg, "max_checker_threads", "25"));
|
||||
vch->cache_enabled = atoi(findcfglx(vch->cfg, "cache_enabled", "1"));
|
||||
@ -154,7 +175,7 @@ int verify_init(cfgl_t *cfg, void **handle) {
|
||||
vch->cache_file = findcfglx(vch->cfg, "cache_file", "verifier_cache");
|
||||
|
||||
if (1 == vch->cache_enabled) {
|
||||
vch->cache_mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
|
||||
vch->cache_mutex = (pthread_mutex_t*) htmalloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(vch->cache_mutex, NULL);
|
||||
pthread_mutex_unlock(vch->cache_mutex);
|
||||
} else {
|
||||
@ -184,15 +205,15 @@ int verify_destroy(void *handle) {
|
||||
int verify_work_setup(void *handle, void **work_handle) {
|
||||
verify_work_handle_t *vwh;
|
||||
|
||||
vwh = (verify_work_handle_t*)malloc(sizeof(verify_work_handle_t));
|
||||
vwh = (verify_work_handle_t*)htmalloc(sizeof(verify_work_handle_t));
|
||||
vwh->id = 0;
|
||||
vwh->result = (verify_result_t*) malloc(sizeof(verify_result_t));
|
||||
vwh->result_mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
|
||||
vwh->result = (verify_result_t*) htmalloc(sizeof(verify_result_t));
|
||||
vwh->result_mutex = (pthread_mutex_t*) htmalloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init(vwh->result_mutex, NULL);
|
||||
pthread_mutex_unlock(vwh->result_mutex);
|
||||
vwh->result_cond = (pthread_cond_t*) malloc(sizeof(pthread_cond_t));
|
||||
vwh->result_cond = (pthread_cond_t*) htmalloc(sizeof(pthread_cond_t));
|
||||
pthread_cond_init(vwh->result_cond, NULL);
|
||||
vwh->terminator_queue = (ht_queue_t*) malloc(sizeof(ht_queue_t));
|
||||
vwh->terminator_queue = (ht_queue_t*) htmalloc(sizeof(ht_queue_t));
|
||||
queue_init(vwh->terminator_queue);
|
||||
vwh->vch = (verify_container_handle_t*)handle;
|
||||
|
||||
@ -206,12 +227,13 @@ int verify_work_destroy(void *handle, void *work_handle) {
|
||||
checker_thread_t *ct;
|
||||
int cnt, cnt2, err;
|
||||
|
||||
syslog(LOG_DEBUG, "verify_work_destroy: was %d times used", vwh->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work_destroy: was %d times used", work_handle, vwh->id);
|
||||
|
||||
/* The terminator_queue must be drained until id_counter is zero again */
|
||||
cnt = vwh->id;
|
||||
while (cnt != 0) {
|
||||
syslog(LOG_DEBUG, "verify_work_destroy, %d thread in queue, waiting for it", cnt);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work_destroy, %d thread in queue, waiting for it",
|
||||
work_handle, cnt);
|
||||
wt = (worker_thread_t*) queue_get_wait(vwh->terminator_queue);
|
||||
|
||||
cnt2 = wt->checker_cnt;
|
||||
@ -220,7 +242,9 @@ int verify_work_destroy(void *handle, void *work_handle) {
|
||||
/* clean up the checker stuff */
|
||||
|
||||
pthread_join(ct->thread, NULL);
|
||||
syslog(LOG_DEBUG, "verify_work_destroy, checker_thread (id=%d) joined", ct->id);
|
||||
decStatCounter(STAT_CNT_VERIFIER_CHECKER_R_THREADS);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work_destroy, checker_thread (id=%d) joined",
|
||||
work_handle, ct->id);
|
||||
|
||||
free(ct->output);
|
||||
free(ct);
|
||||
@ -229,7 +253,9 @@ int verify_work_destroy(void *handle, void *work_handle) {
|
||||
}
|
||||
|
||||
err = pthread_join(wt->thread, NULL);
|
||||
syslog(LOG_DEBUG, "verify_work_destroy, worker_thread (id=%d) joined", wt->id);
|
||||
decStatCounter(STAT_CNT_VERIFIER_WORKER_R_THREADS);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work_destroy, worker_thread (id=%d) joined",
|
||||
work_handle, wt->id);
|
||||
free(wt->input);
|
||||
|
||||
/* this will always be a pointer to something const or allocated, which
|
||||
@ -261,7 +287,7 @@ int verify_work_destroy(void *handle, void *work_handle) {
|
||||
|
||||
|
||||
void cache_insert(verify_container_handle_t *vch, const char *address, int result, const char *output) {
|
||||
#if ENABLE_VERIFY_CACHE == 1
|
||||
#if ENABLE_CACHE == 1
|
||||
DBM *cache;
|
||||
datum data, key;
|
||||
int ret;
|
||||
@ -272,7 +298,7 @@ void cache_insert(verify_container_handle_t *vch, const char *address, int resul
|
||||
key.dsize = strlen(address) + 1; /* one more for the terminating \0 */
|
||||
key.dptr = (char*) address;
|
||||
data.dsize = (sizeof(mydata_t) + (sizeof(char) * (strlen(output) + 1)));
|
||||
mydata = (mydata_t *) malloc(data.dsize);
|
||||
mydata = (mydata_t *) htmalloc(data.dsize);
|
||||
mydata->result = result;
|
||||
mydata->timestamp = time(NULL);
|
||||
strcpy(mydata->output, output);
|
||||
@ -284,6 +310,7 @@ void cache_insert(verify_container_handle_t *vch, const char *address, int resul
|
||||
if (ret != 0) {
|
||||
syslog(LOG_DEBUG, "cache_insert: couldn't insert record");
|
||||
} else {
|
||||
incStatCounter(STAT_CNT_VERIFIER_CACHE);
|
||||
syslog(LOG_DEBUG, "cache_insert: record inserted");
|
||||
}
|
||||
dbm_close(cache);
|
||||
@ -294,11 +321,11 @@ void cache_insert(verify_container_handle_t *vch, const char *address, int resul
|
||||
}
|
||||
#else
|
||||
syslog(LOG_DEBUG, "cache_insert: cache disabled");
|
||||
#endif /* ENABLE_VERIFY_CACHE */
|
||||
#endif /* ENABLE_CACHE */
|
||||
}
|
||||
|
||||
int cache_lookup(verify_container_handle_t *vch, const char* address, int *result, char **output) {
|
||||
#if ENABLE_VERIFY_CACHE == 1
|
||||
#if ENABLE_CACHE == 1
|
||||
DBM *cache;
|
||||
datum data, key;
|
||||
mydata_t *mydata;
|
||||
@ -322,14 +349,16 @@ int cache_lookup(verify_container_handle_t *vch, const char* address, int *resul
|
||||
if ((mydata->timestamp + vch->cache_expiry) > time(NULL)) {
|
||||
syslog(LOG_DEBUG, "cache_lookup: not yet expired");
|
||||
*result = mydata->result;
|
||||
*output = (char*) malloc(sizeof(char) * (strlen(mydata->output) + 1));
|
||||
*output = (char*) htmalloc(sizeof(char) * (strlen(mydata->output) + 1));
|
||||
strcpy(*output, mydata->output);
|
||||
free(data.dptr);
|
||||
|
||||
/* Berkeley DB frees on its own! */
|
||||
/* free(data.dptr); */
|
||||
dbm_close(cache);
|
||||
res = 0;
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "cache_lookup: expired, will be deleted from cache");
|
||||
free(data.dptr);
|
||||
/* free(data.dptr); --- Berkeley DB frees on its own */
|
||||
dbm_close(cache);
|
||||
|
||||
pthread_mutex_lock(vch->cache_mutex);
|
||||
@ -338,6 +367,7 @@ int cache_lookup(verify_container_handle_t *vch, const char* address, int *resul
|
||||
if (ret != 0) {
|
||||
syslog(LOG_DEBUG, "cache_insert: couldn't delete record");
|
||||
} else {
|
||||
decStatCounter(STAT_CNT_VERIFIER_CACHE);
|
||||
syslog(LOG_DEBUG, "cache_insert: record deleted");
|
||||
}
|
||||
dbm_close(cache);
|
||||
@ -351,7 +381,7 @@ int cache_lookup(verify_container_handle_t *vch, const char* address, int *resul
|
||||
return res;
|
||||
#else
|
||||
return -1;
|
||||
#endif /* ENABLE_VERIFY_CACHE */
|
||||
#endif /* ENABLE_CACHE */
|
||||
}
|
||||
|
||||
|
||||
@ -381,11 +411,11 @@ int cache_lookup(verify_container_handle_t *vch, const char* address, int *resul
|
||||
*/
|
||||
|
||||
#define PERM_NOK_RETURN(msg) \
|
||||
syslog(LOG_ERR, "verify_work: %s", msg); \
|
||||
syslog(LOG_ERR, "verify (%p) verify_work: %s", vwh, msg); \
|
||||
snprintf(output, ANSWER_BUFSIZE, "verify_work: %s", msg); \
|
||||
return SMM_PERM_NOK;
|
||||
#define TEMP_NOK_RETURN(msg) \
|
||||
syslog(LOG_ERR, "verify_work: %s", msg); \
|
||||
syslog(LOG_ERR, "verify (%p) verify_work: %s", vwh, msg); \
|
||||
snprintf(output, ANSWER_BUFSIZE, "verify_work: %s", msg); \
|
||||
return SMM_TEMP_NOK;
|
||||
|
||||
@ -398,41 +428,44 @@ int verify_work(void *handle, void *work_handle, char *input, char *output) {
|
||||
struct timespec ts;
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "verify_work: going to verify %s\n", input);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work: going to verify %s\n", vwh, input);
|
||||
|
||||
vwh->id += 1;
|
||||
|
||||
vwh->result->id = vwh->id;
|
||||
|
||||
wt = (worker_thread_t*) malloc(sizeof(worker_thread_t));
|
||||
wt = (worker_thread_t*) htmalloc(sizeof(worker_thread_t));
|
||||
wt->id = vwh->id;
|
||||
wt->terminator_queue = vwh->terminator_queue;
|
||||
wt->input = (char*) malloc(sizeof(char) * (strlen(input)+1));
|
||||
wt->input = (char*) htmalloc(sizeof(char) * (strlen(input)+1));
|
||||
strcpy(wt->input, input);
|
||||
wt->output = NULL;
|
||||
wt->mutex = vwh->result_mutex;
|
||||
wt->cond = vwh->result_cond;
|
||||
wt->result = vwh->result;
|
||||
wt->checker_terminator_queue = (ht_queue_t*) malloc(sizeof(ht_queue_t));
|
||||
wt->checker_terminator_queue = (ht_queue_t*) htmalloc(sizeof(ht_queue_t));
|
||||
queue_init(wt->checker_terminator_queue);
|
||||
wt->checker_cnt = 0;
|
||||
wt->vwh = work_handle;
|
||||
|
||||
syslog(LOG_DEBUG, "verify_work: going to start worker thread, id=%d", vwh->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work: going to start worker thread, id=%d",
|
||||
vwh, vwh->id);
|
||||
pthread_mutex_lock(vwh->result_mutex);
|
||||
err = pthread_create(&tid, NULL, &worker_thread, wt);
|
||||
if (-1 == err) {
|
||||
incStatCounter(STAT_CNT_VERIFIER_WORKER_THREADS_FAILED);
|
||||
free(wt->input);
|
||||
free(wt);
|
||||
PERM_NOK_RETURN("unable to create worker thread");
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "verify_work: waiting for result");
|
||||
pthread_mutex_lock(vwh->result_mutex);
|
||||
syslog(LOG_DEBUG, "verify (%p) verify_work: waiting for result", vwh);
|
||||
ts.tv_sec = time(0) + vch->timeout_result;
|
||||
ts.tv_nsec = 0;
|
||||
err = pthread_cond_timedwait(vwh->result_cond, vwh->result_mutex, &ts);
|
||||
pthread_mutex_unlock(vwh->result_mutex);
|
||||
if (ETIMEDOUT == err) {
|
||||
incStatCounter(STAT_CNT_VERIFIER_WORKER_THREADS_TIMEOUT);
|
||||
TEMP_NOK_RETURN("worker thread timed out");
|
||||
}
|
||||
|
||||
@ -460,7 +493,7 @@ static unsigned int *get_mx_ip_addresses(char *domain) {
|
||||
a_rdata = get_a_rrs((*mx_rdata2)->exchange);
|
||||
if (NULL != a_rdata) {
|
||||
for (a_rdata2 = a_rdata; *a_rdata2 != NULL; a_rdata2++) {
|
||||
addresses = (unsigned int*)realloc(addresses, sizeof(unsigned int)*(i+2)); /* 2 since first i==0 and
|
||||
addresses = (unsigned int*)htrealloc(addresses, sizeof(unsigned int)*(i+2)); /* 2 since first i==0 and
|
||||
we always need one more
|
||||
for the termination */
|
||||
*(addresses+i) = (*a_rdata2)->address;
|
||||
@ -488,7 +521,7 @@ static void *checker_thread(void *arg) {
|
||||
|
||||
int timeout = ct->vwh->vch->timeout_dialog;
|
||||
char *sender_address = ct->vwh->vch->sender_address;
|
||||
char *ehlo_arg = ct->vwh->vch->ehlo_arg;
|
||||
char *helo_arg = ct->vwh->vch->helo_arg;
|
||||
int port = ct->vwh->vch->smtp_port;
|
||||
|
||||
smtp_t *smtp;
|
||||
@ -502,10 +535,14 @@ static void *checker_thread(void *arg) {
|
||||
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d) started, %08x %s", ct->id, ct->ip_address, ct->email_address);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d) started, %08x %s",
|
||||
ct->vwh, ct->id, ct->ip_address, ct->email_address);
|
||||
|
||||
ct->thread = pthread_self();
|
||||
|
||||
incStatCounter(STAT_CNT_VERIFIER_CHECKER_THREADS);
|
||||
incStatCounter(STAT_CNT_VERIFIER_CHECKER_R_THREADS);
|
||||
|
||||
/*
|
||||
Connect to ct->ip_address using ct->email_address,
|
||||
put the result text in ct->output, TBD: by copy or pointer,
|
||||
@ -515,19 +552,20 @@ static void *checker_thread(void *arg) {
|
||||
|
||||
|
||||
while ((END != state) && (0 == done)) {
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d), smtp dialog state %d", ct->id, state);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d), smtp dialog state %d",
|
||||
ct->vwh, ct->id, state);
|
||||
switch(state) {
|
||||
case CONNECT:
|
||||
err = smtp_connect(smtp);
|
||||
break;
|
||||
case EHLO:
|
||||
err = smtp_ehlo(smtp, ehlo_arg);
|
||||
err = smtp_helo(smtp, helo_arg);
|
||||
break;
|
||||
case MAILFROM:
|
||||
err = smtp_mailfrom(smtp, sender_address);
|
||||
break;
|
||||
case RCPTTO:
|
||||
tmp_arg = (char*) malloc(sizeof(char) * (strlen(ct->email_address)+5));
|
||||
tmp_arg = (char*) htmalloc(sizeof(char) * (strlen(ct->email_address)+5));
|
||||
*tmp_arg = '\0';
|
||||
strcat(tmp_arg, "<");
|
||||
strcat(tmp_arg, ct->email_address);
|
||||
@ -547,7 +585,8 @@ static void *checker_thread(void *arg) {
|
||||
|
||||
switch(err) {
|
||||
case SMTP_TIMEOUT:
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d), timeout in smtp dialog", ct->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d), timeout in smtp dialog",
|
||||
ct->vwh, ct->id);
|
||||
ct->result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)TIMEOUT_ERROR;
|
||||
done = 1;
|
||||
@ -556,13 +595,15 @@ static void *checker_thread(void *arg) {
|
||||
/* evaluate smtp_response, return or continue */
|
||||
err = smtp_response(smtp, &response_text);
|
||||
if (-1 == err) {
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d), response could not be parsed", ct->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d), response could not be parsed",
|
||||
ct->vwh, ct->id);
|
||||
ct->result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)UNEXPECTED_ERROR;
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d), response: %d, %s (%d)", ct->id, err, response_text, strlen(response_text));
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d), response: %d, %s (%d)",
|
||||
ct->vwh, ct->id, err, response_text, strlen(response_text));
|
||||
switch(err/100) {
|
||||
case 4:
|
||||
ct->result = SMM_LOCAL_TEMP_NOK;
|
||||
@ -582,7 +623,8 @@ static void *checker_thread(void *arg) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d), unexpected error in smtp dialog", ct->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d), unexpected error in smtp dialog",
|
||||
ct->vwh, ct->id);
|
||||
ct->result = SMM_LOCAL_TEMP_NOK;
|
||||
response_text = (char*)UNEXPECTED_ERROR;
|
||||
done = 1;
|
||||
@ -592,12 +634,13 @@ static void *checker_thread(void *arg) {
|
||||
|
||||
smtp_close(smtp);
|
||||
|
||||
ct->output = (char*) malloc(sizeof(char) * (strlen(response_text)+1));
|
||||
ct->output = (char*) htmalloc(sizeof(char) * (strlen(response_text)+1));
|
||||
strcpy(ct->output, response_text);
|
||||
|
||||
smtp_destroy(smtp);
|
||||
|
||||
syslog(LOG_DEBUG, "checker_thread (id=%d) goes to terminator queue", ct->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) checker_thread (id=%d) goes to terminator queue",
|
||||
ct->vwh, ct->id);
|
||||
queue_put(ct->checker_terminator_queue, ct);
|
||||
}
|
||||
|
||||
@ -618,10 +661,13 @@ static void *worker_thread(void *arg) {
|
||||
static const char *NO_MX_AVAILABLE = "no MX available";
|
||||
static const char *NO_PERM_RESULT = "no checker returned permanent result";
|
||||
|
||||
syslog(LOG_DEBUG, "worker_thread %d started, %s", wt->id, wt->input);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread %d started, %s",
|
||||
wt->vwh, wt->id, wt->input);
|
||||
|
||||
wt->thread = pthread_self();
|
||||
|
||||
incStatCounter(STAT_CNT_VERIFIER_WORKER_R_THREADS);
|
||||
incStatCounter(STAT_CNT_VERIFIER_WORKER_THREADS);
|
||||
|
||||
|
||||
|
||||
@ -632,13 +678,15 @@ static void *worker_thread(void *arg) {
|
||||
result = SMM_LOCAL_PERM_NOK;
|
||||
} else {
|
||||
if (0 == cache_lookup(wt->vwh->vch, wt->input, &result, &cached_output)) {
|
||||
syslog(LOG_DEBUG, "worker_thread: got a cached result for %s -> %d, %s",
|
||||
wt->input, result, cached_output);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: got a cached result for %s -> %d, %s",
|
||||
wt->vwh, wt->input, result, cached_output);
|
||||
incStatCounter(STAT_CNT_VERIFIER_ANSWERED_FROM_CACHE);
|
||||
wt->output = cached_output;
|
||||
} else {
|
||||
domain_part += 1;
|
||||
|
||||
syslog(LOG_DEBUG, "worker_thread: looking up %s", domain_part);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: looking up %s",
|
||||
wt->vwh, domain_part);
|
||||
|
||||
mx_ip_addresses = get_mx_ip_addresses(domain_part);
|
||||
if (NULL == mx_ip_addresses) {
|
||||
@ -647,12 +695,13 @@ static void *worker_thread(void *arg) {
|
||||
} else {
|
||||
for (i = 0; (*(mx_ip_addresses+i) != 0) && (i < wt->vwh->vch->max_checker_threads); i++) {
|
||||
unsigned int address = *(mx_ip_addresses+i);
|
||||
syslog(LOG_DEBUG, "worker_thread: starting checker thread to %d.%d.%d.%d, for email-address %s",
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: starting checker thread to %d.%d.%d.%d, for email-address %s",
|
||||
wt->vwh,
|
||||
(address&0xff000000)>>24, (address&0x00ff0000)>>16,
|
||||
(address&0x0000ff00)>>8, (address&0x000000ff),
|
||||
wt->input);
|
||||
|
||||
ct = (checker_thread_t*) malloc(sizeof(checker_thread_t));
|
||||
ct = (checker_thread_t*) htmalloc(sizeof(checker_thread_t));
|
||||
ct->id = i+1; /* id of ct should start with 1, same as id of wt */
|
||||
ct->ip_address = address;
|
||||
ct->email_address = wt->input;
|
||||
@ -663,7 +712,8 @@ static void *worker_thread(void *arg) {
|
||||
|
||||
err = pthread_create(&tid, NULL, &checker_thread, ct);
|
||||
if (-1 == err) {
|
||||
syslog(LOG_ERR, "worker_thread: unable to create checker thread");
|
||||
incStatCounter(STAT_CNT_VERIFIER_CHECKER_THREADS_FAILED);
|
||||
syslog(LOG_ERR, "verify (%p) worker_thread: unable to create checker thread", wt->vwh);
|
||||
free(ct);
|
||||
} else {
|
||||
wt->checker_cnt += 1;
|
||||
@ -675,17 +725,19 @@ static void *worker_thread(void *arg) {
|
||||
while (wt->checker_cnt > 0) {
|
||||
ct = (checker_thread_t*) queue_get_wait(wt->checker_terminator_queue);
|
||||
wt->checker_cnt -= 1;
|
||||
syslog(LOG_DEBUG, "worker_thread: got checker result for %d.%d.%d.%d: %s -> %d, %s",
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: got checker result for %d.%d.%d.%d: %s -> %d, %s",
|
||||
wt->vwh,
|
||||
((ct->ip_address)&0xff000000)>>24, ((ct->ip_address)&0x00ff0000)>>16,
|
||||
((ct->ip_address)&0x0000ff00)>>8, ((ct->ip_address)&0x000000ff),
|
||||
wt->input, ct->result, ct->output);
|
||||
|
||||
pthread_join(ct->thread, NULL);
|
||||
syslog(LOG_DEBUG, "worker_thread: checker thread joined");
|
||||
decStatCounter(STAT_CNT_VERIFIER_CHECKER_R_THREADS);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: checker thread joined", wt->vwh);
|
||||
|
||||
if ((SMM_LOCAL_TEMP_NOK != ct->result) &&
|
||||
(SMM_TEMP_NOK != ct->result)) {
|
||||
syslog(LOG_DEBUG, "worker_thread: this is a permanent result, returning");
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: this is a permanent result, returning", wt->vwh);
|
||||
wt->output = ct->output;
|
||||
result = ct->result;
|
||||
cache_insert(wt->vwh->vch, wt->input, ct->result, ct->output);
|
||||
@ -693,7 +745,8 @@ static void *worker_thread(void *arg) {
|
||||
break; /* exit from the ct-collecting while loop, leave the rest of the ct's
|
||||
for the cleanup */
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "worker_thread: this is a temporary result, continue to wait");
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread: this is a temporary result, continue to wait",
|
||||
wt->vwh);
|
||||
wt->output = (char*) NO_PERM_RESULT;
|
||||
result = SMM_LOCAL_TEMP_NOK;
|
||||
/* we've collected the ct but its output is not longer need, so free it here */
|
||||
@ -708,24 +761,28 @@ static void *worker_thread(void *arg) {
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
syslog(LOG_DEBUG, "worker_thread %d waiting for mutex", wt->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread %d waiting for mutex",
|
||||
wt->vwh, wt->id);
|
||||
pthread_mutex_lock(wt->mutex);
|
||||
if (wt->result->id == wt->id) {
|
||||
syslog(LOG_DEBUG, "worker_thread %d returned result", wt->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread %d returned result", wt->vwh, wt->id);
|
||||
/* we can write the result */
|
||||
wt->result->output = (char*) malloc(sizeof(char) * (strlen(wt->output)+15)); /* enough for the output
|
||||
wt->result->output = (char*) htmalloc(sizeof(char) * (strlen(wt->output)+15)); /* enough for the output
|
||||
plus <><> and prefix */
|
||||
switch (result) {
|
||||
case SMM_LOCAL_TEMP_NOK:
|
||||
sprintf(wt->result->output, "<TNOK><%s>", wt->output);
|
||||
incStatCounter(STAT_CNT_VERIFIER_RETURNED_TNOK);
|
||||
result = SMM_OK;
|
||||
break;
|
||||
case SMM_LOCAL_PERM_NOK:
|
||||
sprintf(wt->result->output, "<NOK><%s>", wt->output);
|
||||
incStatCounter(STAT_CNT_VERIFIER_RETURNED_NOK);
|
||||
result = SMM_OK;
|
||||
break;
|
||||
case SMM_LOCAL_OK:
|
||||
sprintf(wt->result->output, "<OK><%s>", wt->output);
|
||||
incStatCounter(STAT_CNT_VERIFIER_RETURNED_OK);
|
||||
result = SMM_OK;
|
||||
break;
|
||||
default:
|
||||
@ -736,7 +793,7 @@ static void *worker_thread(void *arg) {
|
||||
wt->result->result = result;
|
||||
pthread_cond_signal(wt->cond);
|
||||
} else {
|
||||
syslog(LOG_DEBUG, "worker_thread %d drops result", wt->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread %d drops result", wt->vwh, wt->id);
|
||||
/* result not longer interested */
|
||||
}
|
||||
pthread_mutex_unlock(wt->mutex);
|
||||
@ -755,7 +812,8 @@ static void *worker_thread(void *arg) {
|
||||
free(cached_output);
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "worker_thread %d goes to terminator queue", wt->id);
|
||||
syslog(LOG_DEBUG, "verify (%p) worker_thread %d goes to terminator queue",
|
||||
wt->vwh, wt->id);
|
||||
queue_put(wt->terminator_queue, wt);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user