/* This file is part of Mailfromd. Copyright (C) 2008 Sergey Poznyakoff This program 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 3, or (at your option) any later version. This program 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 this program. If not, see . */ #include "status.mfh" #pragma regex push +extended +icase string sav_database "%__statedir__/sav.db" number sav_positive_ttl interval("1 day") number sav_negative_ttl interval("1 day") func sav_get_cache(string key) returns string do catch * do echo "Exception $1 while reading from %sav_database: $2" return "" done string record dbget(%sav_database, %key, "", 0) if %record != "" if %record matches '([0-9]+) ([0-9]+)' number timediff time() - \1 number result \2 number ttl if %result = success set ttl %sav_positive_ttl else set ttl %sav_negative_ttl fi if %timediff > %ttl echo "$i: CLEARING record %record" set result "" fi return %result else echo "$i: ERROR: Malformed DB line: %record" fi fi return "" done func sav_put_cache(string key, number value) do catch * do echo "Exception $1 while writing to %sav_database: $2" return done dbput(%sav_database, %key, time() " %value", 0) done func __safe_getmx(string domain) returns string do catch e_failure do return "" done return getmx(%domain) done func __safe_pollhost(string ip, string email, string domain, string mailfrom) returns number do catch * do return $1 done return _pollhost(%ip, %email, %domain, %mailfrom) done func mf_resolved(number code) returns number do return %code == success or %code == not_found done func sav(string email, string ehlo, string mailfrom) alias stdpoll returns number do number rc sav_get_cache(%email) if mf_resolved(%rc) set last_poll_host "" set last_poll_send "" set last_poll_recv "" set cache_used 1 return %rc fi set cache_used 0 catch e_temp_failure do return $1 done string mxlist __safe_getmx(domainpart(%email)) if %mxlist == "" set rc __safe_pollhost(domainpart(%email), %email, %ehlo, %mailfrom) else loop for string mxs %mxlist " " number i index(%mxs, " "), while %i != -1, set mxs substr(%mxs, %i + 1) set i index(%mxs, " ") do string host substr(%mxs, 0, %i) set rc __safe_pollhost(%host, %email, %ehlo, %mailfrom) if mf_resolved(%rc) sav_put_cache(%email, %rc) break fi done fi return %rc done func sav_strict(string email, string ehlo, string mailfrom) alias strictpoll returns number do number rc sav_get_cache(%email) if mf_resolved(%rc) set last_poll_host "" set last_poll_send "" set last_poll_recv "" set cache_used 1 return %rc fi set cache_used 0 set rc __safe_pollhost(domainpart(%email), %email, %ehlo, %mailfrom) if mf_resolved(%rc) return %rc fi catch e_temp_failure do return $1 done string mxlist __safe_getmx(domainpart(%email)) if %mxlist == "" return %rc else # FIXME: The loop is same as in sav. Use macro. loop for string mxs %mxlist " " number i index(%mxs, " "), while %i != -1, set mxs substr(%mxs, %i + 1) set i index(%mxs, " ") do string host substr(%mxs, 0, %i) set rc __safe_pollhost(%host, %email, %ehlo, %mailfrom) if mf_resolved(%rc) sav_put_cache(%email, %rc) break fi done fi return %rc done #pragma regex pop