aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-05-31 20:11:19 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-05-31 20:11:45 +0300
commitfa0978a70e893bbc73d4c4816699cf241eefd3c5 (patch)
treed4c6b100c75d50f21cfdbfcb5e21da02874fcb4f
parentb7fb81d841a26476da18349200dccce86c2de337 (diff)
downloadmailfromd-fa0978a70e893bbc73d4c4816699cf241eefd3c5.tar.gz
mailfromd-fa0978a70e893bbc73d4c4816699cf241eefd3c5.tar.bz2
Implement `localdomain' function + several improvements.
* NEWS: Update. * etc/mailfromd.rc: Use localdomain to determine the domain name. Remove the `#error' statement. Hopefully, this file can be used as is. * mfd/bi_gethostname.m4 (gethostname): Add an optional argument. * mfd/gram.y: Handle function declarations with only optional arguments, e.g.: func foo(; string bar) (mailfromd_test): Add missing env_init calls. * mfd/lex.l: Remove trailing newline before displaying the `#error' diagnostics. * mflib/localdomain.mf: New file. * mflib/Makefile.am (inc_DATA): Add localdomain.mf. * mflib/safedb.mf4 (safedb_verbose): New variable. (safedbmap, safedbdel): New function. (safedbget, safedbput): Verbosely print exceptions caught if safedb_verbose is set.
-rw-r--r--NEWS33
-rw-r--r--doc/mailfromd.texi119
-rw-r--r--etc/mailfromd.rc17
-rw-r--r--mfd/bi_gethostname.m417
-rw-r--r--mfd/gram.y27
-rw-r--r--mfd/lex.l5
-rw-r--r--mflib/Makefile.am1
-rw-r--r--mflib/localdomain.mf31
-rw-r--r--mflib/safedb.mf448
9 files changed, 244 insertions, 54 deletions
diff --git a/NEWS b/NEWS
index 2309eb87..18c168e3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
-Mailfromd NEWS -- history of user-visible changes. 2009-05-23
+Mailfromd NEWS -- history of user-visible changes. 2009-05-31
Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff
@@ -39,2 +39,33 @@ m4_ifdef(`WITH_GEOIP',`
+* The gethostname function
+
+The gethostname function takes an optional argument:
+
+ string gethostname ([bool FQN])
+
+If FQN is specified and is `true', the function attempts to determine
+a fully qualified host name.
+
+* The localdomain function
+
+New function is defined in the library module `localdomain':
+
+ string localdomain()
+
+It returns the domain name of the box mailfromd is executed on.
+It is more reliable than getdomainname, because it uses DNS to
+determine the fully qualified domain name.
+
+* `Safedb' functions.
+
+Two new `safedb' interfaces are implemented:
+
+ string safedbmap (string db, string key [, string defval, number null])
+ void safedbdel (string db, string key [, number null])
+
+A new global variable is added, which controls the verbosity of all
+safedb functions. If the variable safedb_verbose is set to 1, these
+functions log the detailed diagnostics about intercepted exceptions
+before returning to the caller.
+
* Debugging
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 4bbbea9b..62b41a06 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -5251,2 +5251,7 @@ Spam keywords for the message, set by @code{sa} function (@pxref{sa}).
+@deftypevr {Predefined Variable} number safedb_verbose
+This variable controls the verbosity of the exception-safe database
+functions. @xref{safedb_verbose}.
+@end deftypevr
+
@node Back references
@@ -7558,20 +7563,2 @@ specified, or empty string otherwise.
-@deftypefn {Library Function} string safedbget (string @var{db}, @
- string @var{key} [, string @var{default}, number @var{null}])
-
- This is an exception-safe interface to @code{dbget}. If some
-database error occurs while attempting to retrieve the record,
-@code{safedbget} returns empty string.
-
-@flindex safedb.mf
- To use this function, request the @file{safedb.mf} module:
-
-@smallexample
-#require safedb
-@end smallexample
-
-@noindent
-@xref{Modules}, for a description of @acronym{MFL} module system.
-@end deftypefn
-
@deftypefn {Built-in Function} void dbput (string @var{db}, @
@@ -7588,21 +7575,2 @@ to explicitly specify the file mode for this database. See also
-@deftypefn {Library Function} void safedbput (string @var{db}, @
- string @var{key}, string @var{value} [, number @var{null}])
- This is an exception-safe interface to @code{dbput}. If a
-database error occurs while attempting to retrieve the record,
-the function returns without reporting an error.
-
-@flindex safedb.mf
- To use this function, request the @file{safedb.mf} module:
-
-@smallexample
-#require safedb
-@end smallexample
-
-@noindent
-@xref{Modules}, for a description of @acronym{MFL} module system.
-@FIXME{safedbput should probably take an optional mode argument, as
-dbput does.}
-@end deftypefn
-
@deftypefn {Built-in Function} void dbdel (string @var{db}, @
@@ -7619,2 +7587,56 @@ this database. See also @code{#pragma dbprop}, described above.
+@flindex safedb.mf
+The functions above have also the corresponding exception-safe
+interfaces, which return cleanly if the @samp{e_dbfailure} exception
+occurs. To use these interfaces, request the @file{safedb.mf} module:
+
+@smallexample
+#require safedb
+@end smallexample
+
+The exception-safe interfaces are:
+
+@deftypefn {Library Function} string safedbmap (string @var{db}, @
+ string @var{key} [, string @var{default}, number @var{null}])
+
+ This is an exception-safe interface to @code{dbmap}. If a
+database error occurs while attempting to retrieve the record,
+@code{safedbmap} returns @var{default} or @samp{0}, if it is
+not defined.
+@end deftypefn
+
+@deftypefn {Library Function} string safedbget (string @var{db}, @
+ string @var{key} [, string @var{default}, number @var{null}])
+
+ This is an exception-safe interface to @code{dbget}. If a
+database error occurs while attempting to retrieve the record,
+@code{safedbget} returns @var{default} or empty string, if it is
+not defined.
+@end deftypefn
+
+@deftypefn {Library Function} void safedbput (string @var{db}, @
+ string @var{key}, string @var{value} [, number @var{null}])
+
+ This is an exception-safe interface to @code{dbput}. If a
+database error occurs while attempting to retrieve the record,
+the function returns without raising exception.
+@end deftypefn
+
+@deftypefn {Library Function} void safedbdel (string @var{db}, @
+ string @var{key} [, number @var{null}])
+
+ This is an exception-safe interface to @code{dbdel}. If a
+database error occurs while attempting to delete the record,
+the function returns without raising exception.
+@end deftypefn
+
+@anchor{safedb_verbose}
+@vrindex safedb_verbose
+The verbosity of @samp{safedb} interfaces in case of database error is
+controlled by the value of @code{safedb_verbose} variable. If it is
+@samp{0}, these functions return silently. This is the default
+behavior. Otherwise, if @code{safedb_verbose} is not @samp{0}, these
+functions log the detailed diagnostics about the database error and
+return.
+
@anchor{dbm-seq}
@@ -7822,4 +7844,8 @@ The function @code{revip} is defined in @ref{revip}.
-@deftypefn {Built-in Function} string gethostname ()
+@deftypefn {Built-in Function} string gethostname ([bool @var{fqn}])
Return the host name of this machine.
+
+If the optional @var{fqn} is given and is @samp{true}, the function
+will attempt to return fully-qualified host name, by attempting to
+resolve it using @acronym{DNS}.
@end deftypefn
@@ -7832,4 +7858,17 @@ Depending on the underlying @samp{libc} implementation, this call may
return empty string or the string @samp{(none)}. Do not rely on it to
-get the real hostname of the box @command{mailfromd} runs on, use
-@acronym{DNS} functions instead.
+get the real domain name of the box @command{mailfromd} runs on, use
+@code{localdomain} (see below) instead.
+@end deftypefn
+
+@flindex localdomain.mf
+@deftypefn {Library Function} string localdomain ()
+Return the local domain name of this machine.
+
+This function first uses @code{getdomainname} to make a first guess.
+If it does not return a meaningful value, @code{localdomain} calls
+@code{gethostname(1)} to determine the fully qualified host name of
+the machine, and returns its domain part.
+
+To use this function, require @file{localdomain.mf} module
+(@pxref{Modules}), e.g.: @code{#require localdomain}.
@end deftypefn
diff --git a/etc/mailfromd.rc b/etc/mailfromd.rc
index e19cac49..141e2632 100644
--- a/etc/mailfromd.rc
+++ b/etc/mailfromd.rc
@@ -17,4 +17,2 @@
-#error "Do not use this file 'AS IS'! Tailor it to suit your site!"
-
#pragma option relay "/etc/mail/sendmail.cw"
@@ -26,2 +24,3 @@
#require dns
+#require localdomain
#require rateok
@@ -29,7 +28,19 @@
set mailfrom_address "<>"
-set ehlo_domain "your.domain"
+# If mailfromd does not determine local domain correctly, uncomment this
+# and replace DOMAIN with your local domain:
+#set ehlo_domain "DOMAIN"
number gltime interval("1 hour")
+
number need_greylist 0
+/* Begin block is executed at the beginning of each SMTP transaction.
+ */
+begin
+do
+ if %ehlo_domain == ""
+ set ehlo_domain localdomain()
+ fi
+done
+
func cachestr() returns string
diff --git a/mfd/bi_gethostname.m4 b/mfd/bi_gethostname.m4
index 315a2d1b..fc7af790 100644
--- a/mfd/bi_gethostname.m4
+++ b/mfd/bi_gethostname.m4
@@ -32,3 +32,3 @@
*/
-MF_DEFUN(gethostname, STRING)
+MF_DEFUN(gethostname, STRING, OPTIONAL, NUMBER dns)
{
@@ -74,2 +74,17 @@ MF_DEFUN(gethostname, STRING)
}
+
+ if (MF_OPTVAL(dns)) {
+ struct hostent *hp;
+ char *ptr = MF_OBSTACK_BASE;
+
+ hp = gethostbyname(ptr);
+ if (hp) {
+ size_t nlen = strlen(hp->h_name);
+ if (nlen >= size)
+ MF_OBSTACK_GROW(NULL,
+ nlen - size + 1);
+ strcpy(ptr, hp->h_name);
+ }
+ }
+
MF_RETURN_OBSTACK();
diff --git a/mfd/gram.y b/mfd/gram.y
index 15ee9602..812eae39 100644
--- a/mfd/gram.y
+++ b/mfd/gram.y
@@ -403,3 +403,3 @@ _create_alias(void *item, void *data)
%type <type> retdecl
-%type <parmlist> params parmlist fparmlist parmdecl
+%type <parmlist> params opt_parmlist parmlist fparmlist parmdecl
%type <parm> parm
@@ -671,3 +671,3 @@ params : fparmlist
}
- | parmlist ';' fparmlist
+ | opt_parmlist ';' fparmlist
{
@@ -676,3 +676,6 @@ params : fparmlist
$1.varargs = $3.varargs;
- $1.tail->next = $3.head;
+ if ($1.tail)
+ $1.tail->next = $3.head;
+ else
+ $1.head = $3.head;
$1.tail = $3.tail;
@@ -682,2 +685,11 @@ params : fparmlist
+opt_parmlist: /* empty */
+ {
+ $$.count = 0;
+ $$.varargs = 0;
+ $$.head = $$.tail = NULL;
+ }
+ | parmlist
+ ;
+
parmlist : parm
@@ -3182,4 +3194,5 @@ mailfromd_test(int argc, char **argv)
dict);
+ env_init(env);
xeval(env, smtp_state_begin);
-
+
env_init(env);
@@ -3222,5 +3235,7 @@ mailfromd_test(int argc, char **argv)
- xeval(env, smtp_state_end);
-
status = environment_get_status(env);
+
+ env_init(env);
+ xeval(env, smtp_state_end);
+
printf("State %s: ", state_to_string(test_state));
diff --git a/mfd/lex.l b/mfd/lex.l
index c1f9c3e8..da9dd1db 100644
--- a/mfd/lex.l
+++ b/mfd/lex.l
@@ -223,3 +223,6 @@ ICONST {LOCUS}|{VCONST}|{STATEDIR}|{PREPROC}
^[ \t]*#[ \t]*pragma[ \t].*/\n parse_pragma(yytext);
-^[ \t]*#[ \t]*error[ \t].*\n { parse_error("%s", yytext); advance_line(); }
+^[ \t]*#[ \t]*error[ \t].*\n {
+ yytext[yyleng-1] = 0; /* Kill trailing newline */
+ parse_error("%s", yytext);
+ advance_line(); }
/* End-of-line comments */
diff --git a/mflib/Makefile.am b/mflib/Makefile.am
index 8afe000f..60c08a7f 100644
--- a/mflib/Makefile.am
+++ b/mflib/Makefile.am
@@ -22,2 +22,3 @@ inc_DATA =\
is_ip.mf\
+ localdomain.mf\
match_cidr.mf\
diff --git a/mflib/localdomain.mf b/mflib/localdomain.mf
new file mode 100644
index 00000000..77f153e5
--- /dev/null
+++ b/mflib/localdomain.mf
@@ -0,0 +1,31 @@
+/* Local domain functions -*- mfl -*-
+ Copyright (C) 2009 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 <http://www.gnu.org/licenses/>. */
+
+func localdomain()
+ returns string
+do
+ string s getdomainname()
+ if %s == "" or %s == "(none)"
+ string h gethostname(1)
+ number i index(%h, ".")
+ if %h >= 0
+ set s substr(%h, %i + 1)
+ fi
+ fi
+ return %s
+done
+
+
diff --git a/mflib/safedb.mf4 b/mflib/safedb.mf4
index aaf10d51..d51e00ca 100644
--- a/mflib/safedb.mf4
+++ b/mflib/safedb.mf4
@@ -1,3 +1,3 @@
/* Safe DB I/O -*- mfl -*-
- Copyright (C) 2007, 2008 Sergey Poznyakoff
+ Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
@@ -18,2 +18,4 @@
+number safedb_verbose
+
func safedbget(string name, string key ; string defval, number null)
@@ -23,3 +25,6 @@ do
do
- return ""
+ if %safedb_verbose
+ echo "safedbget: exception $1: $2"
+ fi
+ return %defval
done
@@ -38,2 +43,5 @@ do
do
+ if %safedb_verbose
+ echo "safedbput: exception $1: $2"
+ fi
return
@@ -46 +54,37 @@ done
+
+func safedbmap(string name, string key; number defval, number null)
+ returns number
+do
+ catch e_dbfailure
+ do
+ if %safedb_verbose
+ echo "safedbmap: exception $1: $2"
+ fi
+ return %defval
+ done
+ if not defined(defval)
+ set defval 0
+ fi
+ if not defined(null)
+ set null 0
+ fi
+ return dbmap(%name, %key, %null)
+done
+
+func safedbdel(string name, string key; number null)
+do
+ catch e_dbfailure
+ do
+ if %safedb_verbose
+ echo "safedbdel: exception $1: $2"
+ fi
+ return
+ done
+ if not defined(null)
+ set null 0
+ fi
+ return dbdel(%name, %key, %null)
+done
+
+

Return to:

Send suggestions and report system problems to the System administrator.