summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2009-05-10 21:10:42 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2009-05-10 21:10:42 (GMT)
commitffd2cf189d926abe00de0a79f292f1ea69d02aac (patch) (side-by-side diff)
treeac5047e0bf1a0f2b579bf0d40299d59b2b26cc84
parent998eaf2cdb444ee77ff67068ce3586de1eea8e4e (diff)
downloadmailfromd-ffd2cf189d926abe00de0a79f292f1ea69d02aac.tar.gz
mailfromd-ffd2cf189d926abe00de0a79f292f1ea69d02aac.tar.bz2
Implement some system information functions.
* mfd/bi_gethostname.m4: New file. * NEWS, doc/mailfromd.texi: Update. * mfd/Makefile.am (M4_FILES): Add bi_gethostname.m4. * mfd/bi_system.m4 (uname): New function. * mfd/prog.c (heap_obstack_cancel, heap_obstack_base): New function. * mfd/prog.h: Likewise. * mfd/snarf.m4 (MF_OBSTACK_BASE, MF_OBSTACK_CANCEL): New defuns. * mtasim/mtasim.c (stop_mailfromd): Reset signal handler before doing kill, so that waitpid works on hosts with BSD signal semantics.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS16
-rw-r--r--doc/mailfromd.texi51
-rw-r--r--mfd/Makefile.am1
-rw-r--r--mfd/bi_gethostname.m4123
-rw-r--r--mfd/bi_system.m459
-rw-r--r--mfd/prog.c14
-rw-r--r--mfd/prog.h2
-rw-r--r--mfd/snarf.m413
-rw-r--r--mtasim/mtasim.c8
9 files changed, 279 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index c79dfa7..b50d87a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
-Mailfromd NEWS -- history of user-visible changes. 2009-05-09
+Mailfromd NEWS -- history of user-visible changes. 2009-05-10
Copyright (C) 2005, 2006, 2007, 2008, 2009 Sergey Poznyakoff
@@ -62,2 +62,16 @@ requested header is not found.
+New system information functions are added:
+
+- string gethostname ()
+
+Return the host name of this machine.
+
+- string getdomainname ()
+
+Return the domain name of this machine.
+
+- string uname (string format)
+
+Return system information formatted according to the format specification.
+
* New pragma `dbprop'
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 0d171ab..3d2e43c 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -7730,2 +7730,16 @@ The function @code{revip} is defined in @ref{revip}.
+@deftypefn {Built-in Function} string gethostname ()
+Return the host name of this machine.
+@end deftypefn
+
+@deftypefn {Built-in Function} string getdomainname ()
+Return the domain name of this machine. Note, that it does not
+necessarily coincide with the actual machine name in @acronym{DNS}.
+
+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.
+@end deftypefn
+
@deftypefn {Built-in Function} number time ()
@@ -7765,2 +7779,39 @@ strftime('%Y-%m-%d %H:%M:%S %Z', 1164477564, 1)
+@deftypefn {Built-in Function} uname (string @var{format})
+This function returns system information formatted according to
+the format specification @var{format}. Ordinary characters placed
+in the format string are copied to the output without conversion.
+Conversion specifiers are introduced by a @samp{%} character.
+The following conversions are defined:
+
+@table @asis
+@item %s
+Name of this system.
+
+@item %n
+Name of this node within the communications network to which this node
+is attached. Note, that it does not necessarily coincide with the
+actual machine name in @acronym{DNS}.
+
+@item %r
+Kernel release.
+
+@item %v
+Kernel version.
+
+@item %m
+Name of the hardware type on which the system is running.
+@end table
+
+For example:
+
+@smallexample
+ uname('%n runs %s, release %r on %m')
+ @result{} "Trurl runs Linux, release 2.6.26 on i686"
+@end smallexample
+
+Notice the use of single quotes.
+
+@end deftypefn
+
@deftypefn {Built-in Function} number system (string @var{str})
diff --git a/mfd/Makefile.am b/mfd/Makefile.am
index 03c2fca..a22c20f 100644
--- a/mfd/Makefile.am
+++ b/mfd/Makefile.am
@@ -27,2 +27,3 @@ M4_FILES=\
bi_dns.m4\
+ bi_gethostname.m4\
bi_getopt.m4\
diff --git a/mfd/bi_gethostname.m4 b/mfd/bi_gethostname.m4
new file mode 100644
index 0000000..315a2d1
--- a/dev/null
+++ b/mfd/bi_gethostname.m4
@@ -0,0 +1,123 @@
+/* This file is part of Mailfromd. -*- c -*-
+ 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/>. */
+
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG 0
+#endif
+
+#ifndef INITIAL_HOSTNAME_LENGTH
+# define INITIAL_HOSTNAME_LENGTH 34
+#endif
+
+#ifndef INITIAL_DOMAINNAME_LENGTH
+# define INITIAL_DOMAINNAME_LENGTH 34
+#endif
+
+/* string gethostname()
+
+ This implementation is based on xgethostname by Jim Meyering
+*/
+MF_DEFUN(gethostname, STRING)
+{
+ size_t size = INITIAL_HOSTNAME_LENGTH;
+
+ MF_OBSTACK_BEGIN();
+ while (1) {
+ size_t nsize;
+ size_t size_1;
+ char *hostname;
+
+ MF_OBSTACK_GROW(NULL, size);
+ hostname = MF_OBSTACK_BASE();
+
+ /* Use SIZE_1 here rather than SIZE to work around the bug in
+ SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME
+ even when the name is as long as the supplied buffer. */
+ size_1 = size - 1;
+ hostname[size_1 - 1] = '\0';
+ errno = 0;
+
+ if (gethostname(hostname, size_1) == 0) {
+ if (!hostname[size_1 - 1])
+ break;
+ } else if (errno != 0
+ && errno != ENAMETOOLONG && errno != EINVAL
+ /* OSX/Darwin does this when the buffer is not
+ large enough */
+ && errno != ENOMEM) {
+ int saved_errno = errno;
+ MF_OBSTACK_CANCEL();
+ MF_THROW(mfe_failure,
+ "%s", mu_strerror(saved_errno));
+ }
+
+ nsize = size * 2;
+ if (nsize <= size) {
+ MF_OBSTACK_CANCEL();
+ MF_THROW(mfe_failure,
+ "%s", mu_strerror(ENOMEM));
+ }
+ size = nsize;
+ }
+ MF_RETURN_OBSTACK();
+}
+END
+
+/* string getdomainname()
+
+ This implementation is based on xgetdomainname by Jim Meyering
+*/
+MF_DEFUN(getdomainname, STRING)
+{
+ size_t size = INITIAL_DOMAINNAME_LENGTH;
+
+ MF_OBSTACK_BEGIN();
+ while (1) {
+ size_t nsize;
+ size_t size_1;
+ char *domainname;
+ int rc;
+
+ MF_OBSTACK_GROW(NULL, size);
+ domainname = MF_OBSTACK_BASE();
+
+ size_1 = size - 1;
+ domainname[size_1 - 1] = '\0';
+ errno = 0;
+
+ rc = getdomainname(domainname, size);
+ if (rc >= 0 && domainname[size_1] == '\0')
+ break;
+ else if (rc < 0 && errno != EINVAL) {
+ int saved_errno = errno;
+ MF_OBSTACK_CANCEL();
+ MF_THROW(mfe_failure,
+ "%s", mu_strerror(saved_errno));
+ }
+
+ nsize = size * 2;
+ if (nsize <= size) {
+ MF_OBSTACK_CANCEL();
+ MF_THROW(mfe_failure,
+ "%s", mu_strerror(ENOMEM));
+ }
+ size = nsize;
+ }
+ MF_RETURN_OBSTACK();
+}
+END
+
+MF_INIT
diff --git a/mfd/bi_system.m4 b/mfd/bi_system.m4
index e7eb844..55bc9a3 100644
--- a/mfd/bi_system.m4
+++ b/mfd/bi_system.m4
@@ -1,3 +1,3 @@
/* This file is part of Mailfromd. -*- c -*-
- Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff
+ Copyright (C) 2006, 2007, 2008, 2009 Sergey Poznyakoff
@@ -16,2 +16,3 @@
+#include <sys/utsname.h>
#include "strftime.h"
@@ -56,2 +57,58 @@ END
+/* Interface to the system uname call.
+
+ Format sequences are:
+ %s sysname
+ %n nodename
+ %r release
+ %v version
+ %m machine
+*/
+MF_DEFUN(uname, STRING, STRING fmt)
+{
+ struct utsname ubuf;
+
+ uname(&ubuf);
+ MF_OBSTACK_BEGIN();
+ while (*fmt) {
+ if (*fmt == '%') {
+ switch (*++fmt) {
+ case 's':
+ MF_OBSTACK_GROW(ubuf.sysname,
+ strlen(ubuf.sysname));
+ break;
+ case 'n':
+ MF_OBSTACK_GROW(ubuf.nodename,
+ strlen(ubuf.nodename));
+ break;
+ case 'r':
+ MF_OBSTACK_GROW(ubuf.release,
+ strlen(ubuf.release));
+ break;
+ case 'v':
+ MF_OBSTACK_GROW(ubuf.version,
+ strlen(ubuf.version));
+ break;
+ case 'm':
+ MF_OBSTACK_GROW(ubuf.machine,
+ strlen(ubuf.machine));
+ break;
+ case '%':
+ MF_OBSTACK_1GROW('%');
+ break;
+ default:
+ MF_OBSTACK_1GROW('%');
+ MF_OBSTACK_1GROW(*fmt);
+ }
+ fmt++;
+ } else {
+ MF_OBSTACK_1GROW(*fmt);
+ fmt++;
+ }
+ }
+ MF_OBSTACK_1GROW(0);
+ MF_RETURN_OBSTACK();
+}
+END
+
MF_INIT
diff --git a/mfd/prog.c b/mfd/prog.c
index 3c92a9a..90a426e 100644
--- a/mfd/prog.c
+++ b/mfd/prog.c
@@ -656,2 +656,10 @@ heap_obstack_begin(eval_environ_t env)
+void
+heap_obstack_cancel(eval_environ_t env)
+{
+ env->toh = env->temp_start;
+ env->temp_start = 0;
+ env->temp_size = 0;
+}
+
STKVAL
@@ -682,2 +690,8 @@ heap_obstack_grow(eval_environ_t env, void *ptr, size_t size)
+void *
+heap_obstack_base(eval_environ_t env)
+{
+ return (void*) env_data_ref(env, env->temp_start);
+}
+
STKVAL *
diff --git a/mfd/prog.h b/mfd/prog.h
index c0d4ffb..4a4fd19 100644
--- a/mfd/prog.h
+++ b/mfd/prog.h
@@ -44,3 +44,5 @@ void heap_obstack_begin(eval_environ_t env);
STKVAL heap_obstack_finish(eval_environ_t env);
+void heap_obstack_cancel(eval_environ_t env);
void *heap_obstack_grow(eval_environ_t env, void *ptr, size_t size);
+void *heap_obstack_base(eval_environ_t env);
void pushs(eval_environ_t env, const char *s);
diff --git a/mfd/snarf.m4 b/mfd/snarf.m4
index f6cf59e..6db5fe5 100644
--- a/mfd/snarf.m4
+++ b/mfd/snarf.m4
@@ -428,6 +428,11 @@ do { int __c = $1; heap_obstack_grow(env, &__c, 1); } while(0)>])
-m4_dnl /* MF_OBSTACK_CANCEL - Cancel temporary heap allocation initiated by
-m4_dnl * MF_OBSTACK_BEGIN
-m4_fnl */
-m4_dnl m4_define([<MF_OBSTACK_CANCEL>],[<heap_obstack_cancel(env)>])
+/* MF_OBSTACK_CANCEL - Cancel temporary heap allocation initiated by
+ * MF_OBSTACK_BEGIN
+ */
+m4_define([<MF_OBSTACK_CANCEL>],[<heap_obstack_cancel(env)>])
+
+/* MF_OBSTACK_BASE - Return a C pointer to the beginning of the currently
+ * allocated obstack space.
+ */
+m4_define([<MF_OBSTACK_BASE>],[<heap_obstack_base(env)>])
diff --git a/mtasim/mtasim.c b/mtasim/mtasim.c
index f9a85f5..ac751d1 100644
--- a/mtasim/mtasim.c
+++ b/mtasim/mtasim.c
@@ -662,6 +662,10 @@ stop_mailfromd (void)
int status;
+ pid_t pid;
+ signal (SIGCHLD, SIG_DFL);
kill (child_pid, SIGTERM);
- waitpid (child_pid, &status, 0);
- if (WIFEXITED (status))
+ pid = waitpid (child_pid, &status, 0);
+ if (pid == (pid_t) -1)
+ mu_error ("waitpid: %s", mu_strerror (errno));
+ else if (WIFEXITED (status))
{

Return to:

Send suggestions and report system problems to the System administrator.