diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 00:10:42 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 00:10:42 +0300 |
commit | ffd2cf189d926abe00de0a79f292f1ea69d02aac (patch) | |
tree | ac5047e0bf1a0f2b579bf0d40299d59b2b26cc84 | |
parent | 998eaf2cdb444ee77ff67068ce3586de1eea8e4e (diff) | |
download | mailfromd-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.
-rw-r--r-- | NEWS | 16 | ||||
-rw-r--r-- | doc/mailfromd.texi | 51 | ||||
-rw-r--r-- | mfd/Makefile.am | 1 | ||||
-rw-r--r-- | mfd/bi_gethostname.m4 | 123 | ||||
-rw-r--r-- | mfd/bi_system.m4 | 59 | ||||
-rw-r--r-- | mfd/prog.c | 14 | ||||
-rw-r--r-- | mfd/prog.h | 2 | ||||
-rw-r--r-- | mfd/snarf.m4 | 13 | ||||
-rw-r--r-- | mtasim/mtasim.c | 8 |
9 files changed, 279 insertions, 8 deletions
@@ -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 0d171ab0..3d2e43c5 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 03c2fca3..a22c20f4 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 00000000..315a2d1b --- /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 e7eb8449..55bc9a36 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 @@ -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 * @@ -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 f6cf59ef..6db5fe5e 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 f9a85f53..ac751d12 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)) { |