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 /mfd | |
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.
Diffstat (limited to 'mfd')
-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 |
6 files changed, 207 insertions, 5 deletions
diff --git a/mfd/Makefile.am b/mfd/Makefile.am index 03c2fca3..a22c20f4 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 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,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 @@ -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) { @@ -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 f6cf59ef..6db5fe5e 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 */ |