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,4 +1,4 @@
-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
See the end of file for copying conditions.
@@ -60,6 +60,20 @@ Index is 1-based.
All current_header functions raise the e_not_found exception if the
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'
This pragma defines user database properties. It takes two or three
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 0d171ab..3d2e43c 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -7728,6 +7728,20 @@ The function @code{revip} is defined in @ref{revip}.
@node System functions
@subsubsection System functions
+@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 ()
Return the time since the Epoch (00:00:00 UTC, January 1, 1970),
measured in seconds.
@@ -7763,6 +7777,43 @@ strftime('%Y-%m-%d %H:%M:%S %Z', 1164477564, 1)
@end smallexample
@end deftypefn
+@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})
The function @code{system} executes a command specified in @var{str}
by calling @command{/bin/sh -c string}, and returns -1 on error or
diff --git a/mfd/Makefile.am b/mfd/Makefile.am
index 03c2fca..a22c20f 100644
--- a/mfd/Makefile.am
+++ b/mfd/Makefile.am
@@ -25,6 +25,7 @@ M4_FILES=\
bi_curhdr.m4\
bi_db.m4\
bi_dns.m4\
+ bi_gethostname.m4\
bi_getopt.m4\
bi_gettext.m4\
bi_header.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,5 +1,5 @@
/* This file is part of Mailfromd. -*- c -*-
- Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff
+ Copyright (C) 2006, 2007, 2008, 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
@@ -14,6 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include <sys/utsname.h>
#include "strftime.h"
MF_DEFUN(system, NUMBER, STRING str)
@@ -54,4 +55,60 @@ MF_DEFUN(umask, NUMBER, NUMBER mask)
}
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
@@ -654,6 +654,14 @@ heap_obstack_begin(eval_environ_t env)
env->temp_size = 0;
}
+void
+heap_obstack_cancel(eval_environ_t env)
+{
+ env->toh = env->temp_start;
+ env->temp_start = 0;
+ env->temp_size = 0;
+}
+
STKVAL
heap_obstack_finish(eval_environ_t env)
{
@@ -680,6 +688,12 @@ heap_obstack_grow(eval_environ_t env, void *ptr, size_t size)
return ret;
}
+void *
+heap_obstack_base(eval_environ_t env)
+{
+ return (void*) env_data_ref(env, env->temp_start);
+}
+
STKVAL *
env_data_ref(eval_environ_t env, size_t off)
{
diff --git a/mfd/prog.h b/mfd/prog.h
index c0d4ffb..4a4fd19 100644
--- a/mfd/prog.h
+++ b/mfd/prog.h
@@ -42,7 +42,9 @@ size_t heap_reserve_words(eval_environ_t env, size_t size);
STKVAL heap_tempspace(eval_environ_t env, size_t size);
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);
void advance_pc(eval_environ_t env, long cnt);
void adjust_stack(eval_environ_t env, unsigned cnt);
diff --git a/mfd/snarf.m4 b/mfd/snarf.m4
index f6cf59e..6db5fe5 100644
--- a/mfd/snarf.m4
+++ b/mfd/snarf.m4
@@ -426,10 +426,15 @@ do {
m4_define([<MF_OBSTACK_1GROW>],[<m4_dnl
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)>])
/* MF_RETURN_OBSTACK() - Relocate and return temporary space
*/
diff --git a/mtasim/mtasim.c b/mtasim/mtasim.c
index f9a85f5..ac751d1 100644
--- a/mtasim/mtasim.c
+++ b/mtasim/mtasim.c
@@ -660,10 +660,14 @@ stop_mailfromd (void)
if (child_pid > 0)
{
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))
{
status = WEXITSTATUS (status);
if (status != 0)

Return to:

Send suggestions and report system problems to the System administrator.