aboutsummaryrefslogtreecommitdiff
path: root/mfd
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-05-11 00:10:42 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-05-11 00:10:42 +0300
commitffd2cf189d926abe00de0a79f292f1ea69d02aac (patch)
treeac5047e0bf1a0f2b579bf0d40299d59b2b26cc84 /mfd
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 (limited to 'mfd')
-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
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
diff --git a/mfd/prog.c b/mfd/prog.c
index 3c92a9a7..90a426eb 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 c0d4ffbc..4a4fd193 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 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
*/

Return to:

Send suggestions and report system problems to the System administrator.