summaryrefslogtreecommitdiffstats
path: root/contrib/amd/libamu/xutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/amd/libamu/xutil.c')
-rw-r--r--contrib/amd/libamu/xutil.c103
1 files changed, 87 insertions, 16 deletions
diff --git a/contrib/amd/libamu/xutil.c b/contrib/amd/libamu/xutil.c
index a8b15bf..998d0d8 100644
--- a/contrib/amd/libamu/xutil.c
+++ b/contrib/amd/libamu/xutil.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-1999 Erez Zadok
+ * Copyright (c) 1997-2001 Erez Zadok
* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990 The Regents of the University of California.
@@ -38,7 +38,7 @@
*
* %W% (Berkeley) %G%
*
- * $Id: xutil.c,v 1.8 1999/09/30 21:01:42 ezk Exp $
+ * $Id: xutil.c,v 1.11.2.6 2001/01/10 03:23:41 ezk Exp $
*
*/
@@ -80,7 +80,11 @@ static int orig_mem_bytes;
#endif /* DEBUG_MEM */
/* forward definitions */
-static void real_plog(int lvl, char *fmt, va_list vargs);
+static void real_plog(int lvl, const char *fmt, va_list vargs)
+ __attribute__((__format__(__printf__, 2, 0)));
+/* for GCC format string auditing */
+static const char *expand_error(const char *f, char *e, int maxlen)
+ __attribute__((__format_arg__(1)));
#ifdef DEBUG
/*
@@ -93,15 +97,20 @@ struct opt_tab dbg_opt[] =
{"daemon", D_DAEMON}, /* Enter daemon mode */
{"fork", D_FORK}, /* Fork server (nofork = don't fork) */
{"full", D_FULL}, /* Program trace */
+#ifdef HAVE_CLOCK_GETTIME
+ {"hrtime", D_HRTIME}, /* Print high resolution time stamps */
+#endif /* HAVE_CLOCK_GETTIME */
/* info service specific debugging (hesiod, nis, etc) */
{"info", D_INFO},
# ifdef DEBUG_MEM
{"mem", D_MEM}, /* Trace memory allocations */
# endif /* DEBUG_MEM */
{"mtab", D_MTAB}, /* Use local mtab file */
+ {"readdir", D_READDIR}, /* check on browsable_dirs progress */
{"str", D_STR}, /* Debug string munging */
{"test", D_TEST}, /* Full debug - but no daemon */
{"trace", D_TRACE}, /* Protocol trace */
+ {"xdrtrace", D_XDRTRACE}, /* Trace xdr routines */
{0, 0}
};
#endif /* DEBUG */
@@ -280,18 +289,31 @@ checkup_mem(void)
* with the current error code taken from errno. Make sure
* 'e' never gets longer than maxlen characters.
*/
-static void
-expand_error(char *f, char *e, int maxlen)
+static const char *
+expand_error(const char *f, char *e, int maxlen)
{
+#ifndef HAVE_STRERROR
+ /*
+ * XXX: we are assuming that if a system doesn't has strerror,
+ * then it has sys_nerr. If this assumption turns out to be wrong on
+ * some systems, we'll have to write a separate test to detect if
+ * a system has sys_nerr. -Erez
+ */
extern int sys_nerr;
- char *p, *q;
+#endif /* not HAVE_STRERROR */
+ const char *p;
+ char *q;
int error = errno;
int len = 0;
for (p = f, q = e; (*q = *p) && len < maxlen; len++, q++, p++) {
if (p[0] == '%' && p[1] == 'm') {
const char *errstr;
+#ifdef HAVE_STRERROR
+ if (error < 0)
+#else /* not HAVE_STRERROR */
if (error < 0 || error >= sys_nerr)
+#endif /* not HAVE_STRERROR */
errstr = NULL;
else
#ifdef HAVE_STRERROR
@@ -309,6 +331,7 @@ expand_error(char *f, char *e, int maxlen)
}
}
e[maxlen-1] = '\0'; /* null terminate, to be sure */
+ return e;
}
@@ -320,13 +343,34 @@ show_time_host_and_name(int lvl)
{
static time_t last_t = 0;
static char *last_ctime = 0;
- time_t t = clocktime();
+ time_t t;
+#ifdef HAVE_CLOCK_GETTIME
+ struct timespec ts;
+#endif /* HAVE_CLOCK_GETTIME */
+ char nsecs[11] = ""; /* '.' + 9 digits + '\0' */
char *sev;
+#ifdef HAVE_CLOCK_GETTIME
+ /*
+ * Some systems (AIX 4.3) seem to implement clock_gettime() as stub
+ * returning ENOSYS.
+ */
+ if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
+ t = ts.tv_sec;
+#ifdef DEBUG
+ amuDebug(D_HRTIME)
+ sprintf(nsecs, ".%09ld", ts.tv_nsec);
+#endif /* DEBUG */
+ }
+ else
+#endif /* HAVE_CLOCK_GETTIME */
+ t = clocktime();
+
if (t != last_t) {
last_ctime = ctime(&t);
last_t = t;
}
+
switch (lvl) {
case XLOG_FATAL:
sev = "fatal:";
@@ -356,8 +400,8 @@ show_time_host_and_name(int lvl)
sev = "hmm: ";
break;
}
- fprintf(logfp, "%15.15s %s %s[%ld]/%s ",
- last_ctime + 4, am_get_hostname(),
+ fprintf(logfp, "%15.15s%s %s %s[%ld]/%s ",
+ last_ctime + 4, nsecs, am_get_hostname(),
am_get_progname(),
(long) am_mypid,
sev);
@@ -376,7 +420,7 @@ debug_option(char *opt)
void
-dplog(char *fmt, ...)
+dplog(const char *fmt, ...)
{
va_list ap;
@@ -391,7 +435,7 @@ dplog(char *fmt, ...)
void
-plog(int lvl, char *fmt, ...)
+plog(int lvl, const char *fmt, ...)
{
va_list ap;
@@ -405,7 +449,7 @@ plog(int lvl, char *fmt, ...)
static void
-real_plog(int lvl, char *fmt, va_list vargs)
+real_plog(int lvl, const char *fmt, va_list vargs)
{
char msg[1024];
char efmt[1024];
@@ -420,17 +464,21 @@ real_plog(int lvl, char *fmt, va_list vargs)
checkup_mem();
#endif /* DEBUG_MEM */
- expand_error(fmt, efmt, 1024);
-
#ifdef HAVE_VSNPRINTF
- vsnprintf(ptr, 1024, efmt, vargs);
+ /*
+ * XXX: ptr is 1024 bytes long, but we may write to ptr[strlen(ptr) + 2]
+ * (to add an '\n', see code below) so we have to limit the string copy
+ * to 1023 (including the '\0').
+ */
+ vsnprintf(ptr, 1023, expand_error(fmt, efmt, 1024), vargs);
+ msg[1022] = '\0'; /* null terminate, to be sure */
#else /* not HAVE_VSNPRINTF */
/*
* XXX: ptr is 1024 bytes long. It is possible to write into it
* more than 1024 bytes, if efmt is already large, and vargs expand
* as well. This is not as safe as using vsnprintf().
*/
- vsprintf(ptr, efmt, vargs);
+ vsprintf(ptr, expand_error(fmt, efmt, 1023), vargs);
msg[1023] = '\0'; /* null terminate, to be sure */
#endif /* not HAVE_VSNPRINTF */
@@ -873,6 +921,7 @@ amu_release_controlling_tty(void)
#ifdef TIOCNOTTY
int fd;
#endif /* TIOCNOTTY */
+ int tempfd;
#ifdef HAVE_SETSID
/* XXX: one day maybe use vhangup(2) */
@@ -884,6 +933,28 @@ amu_release_controlling_tty(void)
}
#endif /* HAVE_SETSID */
+ /*
+ * In daemon mode, leaving open file descriptors to terminals or pipes
+ * can be a really bad idea.
+ * Case in point: the redhat startup script calls us through their 'initlog'
+ * program, which exits as soon as the original amd process exits. If, at some
+ * point, a misbehaved library function decides to print something to the screen,
+ * we get a SIGPIPE and die.
+ * More precisely: NIS libc functions will attempt to print to stderr
+ * "YPBINDPROC_DOMAIN: Domain not bound" if ypbind is running but can't find
+ * a ypserver.
+ *
+ * So we close all of our "terminal" filedescriptors, i.e. 0, 1 and 2, then
+ * reopen them as /dev/null.
+ *
+ * XXX We should also probably set the SIGPIPE handler to SIG_IGN.
+ */
+ tempfd = open("/dev/null", O_RDWR);
+ fflush(stdin); close(0); dup2(tempfd, 0);
+ fflush(stdout); close(1); dup2(tempfd, 1);
+ fflush(stderr); close(2); dup2(tempfd, 2);
+ close(tempfd);
+
#ifdef TIOCNOTTY
fd = open("/dev/tty", O_RDWR);
if (fd < 0) {
OpenPOWER on IntegriCloud