glibc/misc/syslog.c
Ulrich Drepper 5290baf06c update from main archive 970118
Sun Jan 19 04:38:20 1997  Ulrich Drepper  <drepper@cygnus.com>

	* config.make.in (have-ksh, KSH): New variables.  Will be filled
	in by configure.
	* configure.in: Add test for ksh like shell (prefer bash).
	* time/Makefile (tests): Depend on install-test-data.
	(distribute): Add simplebackw.
	(generated-dirs): New variable.
	[$(have-ksh)==yes] (install-others): Add iso3166.tab and zone.tab.
	(install-bin): Add tzselect.
	(install-test-data): Install the zoneinfo files which are needed
	for the test case in the build directory.
	(test-tz-ENV): New variable.  Call test-tz program using data in
	build directory.
	* time/simpleback: New file.
	* time/test-tz.c: Pretty print.
	* time/tzfile.c: Use value of environment variable TZDIR as directory
	to look for zone info files.
	don't let search for DST data destroy already found values.
	* time/tzselect.ksh: Use @KSH@ and @TZDIR@ to be substituted when
	installing.
	* time/tzset.c (__tzset_internal): Avoid freeing string twice.
	Set DST zone name to normal zone name if no information is provided.

	* time/mktime.c (mktime): Call __tzset_internal to use current
	value of TZ.

	* Makerules (common-clean): Remove $(generated-dirs) inclusing content.

	* glibcbug.in: Fix several bugs.  Reported by several people.

	* elf/Makefile: Correct dependecies for $(objpfx)ldd.

	* inet/netinet/ip.h: Define IPTOS_LOWCOST and IPTOS_MINCOST.

	* locale/C-time.c: Update copyright.
	* locale/localeinfo.h: Likewise.
	* sysdeps/unix/bsd/bsd4.4/direntry.h: Likewise.

	* locale/programs/ld-time.c (time_finish): Correct message string.
	* locale/programs/linereader.c (lr_token): Use correctly `number'
	not `digit' in message string.

	* stdlib/strtol.c [UNSIGNED]: Don't punt immediately when `-' is
	seen.  Instead return ULONG_MAX and set ERANGE.
	* stdlib/tst-strtol.c: Correct test to reflect above change.

Sun Jan 19 03:22:30 1997  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/sys/mtio.h: Don't use <linux/mtio.h>.
	We must not use <linux/posix_types.h>.

	* sysdeps/unix/sysv/linux/sys/ipc_buf.h: Don't use __kernel_* types
	since we must not use <linux/posix_types.h>.
	* sysdeps/unix/sysv/linux/sys/procfs.h: Likewise.
	* sysdeps/unix/sysv/linux/alpha/sys/ipc_buf.h: New file.  Similar
	to sysdeps/unix/sysv/linux/sys/ipc_buf.h, but use alpha relavent
	types.
	* sysdeps/unix/sysv/linux/alpha/sys/procfs.h: New file.  Similar
	to sysdeps/unix/sysv/linux/sys/procfs.h, but use alpha relavent
	types.

Sun Jan 19 01:48:20 1997  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/libm-i387/e_exp.S: Correct computation of fractional
	part.
	* sysdeps/libm-i387/e_expf.S: Likewise.
	* sysdeps/libm-i387/e_expl.S: Likewise.
	* sysdeps/libm-i387/s_expm1.S: Correct computation of fractional
	part.  Take care of additional value left on stack by fscale.
	* sysdeps/libm-i387/s_expm1f.S: Likewise.
	* sysdeps/libm-i387/s_expm1l.S: Likewise.

Fri Jan 17 17:45:32 1997  Ulrich Drepper  <drepper@cygnus.com>

	* posix/getopt.c: Change all direct usages of `gettext' to `_'.

	* sysdeps/generic/sysd-stdio.c (__stdio_reopen): Add missing
	parameter.
	Reported by Harmanjit Singh <harman@netearth.iitd.ernet.in>.

Thu Jan 16 23:39:25 1997  Ulrich Drepper  <drepper@cygnus.com>

	* stdio-common/Makefile (tests): Add scanf11.
	* stdio-common/scanf11.c: New file.
	* stdio-common/vfscanf.c (__vfscanf): Increment `done' when %n
	was processed and value is not suppressed.
	* stdio-common/bug10.c: Correct test to expect %n increment the
	return value of scanf.
	* stdio-common/scanf1.c: Likewise.
	* stdio-common/scanf3.c: Likewise.
	* stdio-common/scanf10.c: Likewise.
	* stdio-common/tstdiomisc.c: Likewise.

	* time/strptime.c: Add lots of conditional compiling to enable use
	outside glibc.  When used in glibc, make sure C locale format
	strings will always be recognized.

Sat Jan 11 18:53:47 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/sys/sysmacros.h (major, minor, makedev):
	Fix definitions so that they work with __kernel_dev_t.

Sat Jan 11 14:24:10 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/kernel_sigaction.h,
	sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h,
	sysdeps/unix/sysv/linux/sigaction.c: New files.
	* sysdeps/unix/sysv/linux/syscalls.list: Add s_sigaction.

Sun Jan 12 15:22:33 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* libc-symbols.h (link_warning): Make sure that the .gnu.warning
	section is not allocated.
	Update and reformat copyright.

Sun Jan 12 12:19:28 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* elf/Makefile ($(objpfx)ldd): Fix depedency list.

Sat Jan 11 15:11:26 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/Makefile ($(common-objpfx)sysd-syscalls): Fix
	command so that it works in subdirectories.

Wed Jan  8 22:07:58 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/i386/syscalls.list: Add s_getgroups and
	s_setgroups.
	* sysdeps/unix/sysv/linux/m68k/syscalls.list: Likewise.
	* sysdeps/unix/sysv/linux/i386/getgroups.c,
	sysdeps/unix/sysv/linux/i386/setgroups.c,
	sysdeps/unix/sysv/linux/m68k/getgroups.c,
	sysdeps/unix/sysv/linux/m68k/setgroups.c: New files.

Wed Jan  8 19:42:59 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makefile (config.status): Delete bogus rule.
	($(objpfx)glibcbug): Renamed from plain `glibcbug', depend on
	config.status in build directory, fix command to change to build
	directory.
	* Makeconfig ($(common-objpfx)config.status): Depend on version.h.

Thu Jan  9 08:47:54 1997  Andreas Jaeger  <aj@arthur.pfalz.de>

	* glibcbug.in (while): We test for four and not five conditions,
	set MAIL_AGENT instead of RMAIL, filter spaces and tabs.

Thu Jan 16 22:00:27 1997  Ulrich Drepper  <drepper@cygnus.com>

	* misc/syslog.c: Don't define cancel_handler if _LIBC_REENTRANT
	is not defined.  Reported by Andreas Jaeger.

Thu Jan  9 08:47:54 1997  Andreas Jaeger  <aj@arthur.pfalz.de>

	* new-malloc/malloc.c (__MALLOC_P): define call to pthread
	initializer only if NO_THREADS is not defined.

Wed Jan  8 21:28:58 1997  Andreas Jaeger  <aj@arthur.pfalz.de>

	* resolv/nss_dns/dns-host.c: Clean-up: delete unnecessary includes
	and variables.

Thu Jan 16 21:50:27 1997  Ulrich Drepper  <drepper@cygnus.com>

	* inet/arpa/inet.h: Include <netinet/in.h> to get struct in_addr
	defined.

Tue Jan  7 17:29:59 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makerules (LDLIBS-c.so): New variable.

Tue Jan  7 19:22:00 1997  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makefile ($(includedir)/gnu/lib-names.h): Define the library
	names as strings, not as sequence of tokens that may fall apart.

Fri Jan 10 14:08:41 1997  Roland McGrath  <roland@fmh.frob.com>

	* time/tzfile.c (__tzfile_read): Check for bogus type and zone name
	indices in data file and punt, so a bogus file can't crash us.

Thu Jan 16 20:29:15 1997  Ulrich Drepper  <drepper@cygnus.com>

	* values.h [__USE_MISC]: Define BITSPERBYTE.

Fri Jan 17 14:16:28 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* stdio/vdprintf.c: Moved file to ...
	* sysdeps/posix/vdprintf.c: Here.  De-ansideclificate.
	* sysdeps/stub/vdprintf.c: New file.
	* sysdeps/mach/hurd/vdprintf.c: New file.

Thu Jan  9 15:59:35 1997  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/posix_opt.h: New file.

	* sysdeps/mach/hurd/sigwait.c (sigwait): Don't affect signal mask.

	* sysdeps/unix/bsd/tcsendbrk.c (tcsendbreak): Finish
	deansideclification.

	* sysdeps/mach/libc-lock.h: Add kludges to pretend to implement
	recursive locks.

Tue Jan  7 09:48:15 1997  Andreas Jaeger  <aj@arthur.pfalz.de>

	* signal/sigempty.c (sigemptyset): Correct typo: Empty set should
	have all bits zero.
1997-01-19 04:54:28 +00:00

342 lines
8.9 KiB
C

/*
* Copyright (c) 1983, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/uio.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <libc-lock.h>
#include <signal.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
static int LogType = SOCK_DGRAM; /* type of socket connection */
static int LogFile = -1; /* fd for log */
static int connected; /* have done connect */
static int LogStat = 0; /* status bits, set by openlog() */
static const char *LogTag = NULL; /* string to tag the entry with */
static int LogFacility = LOG_USER; /* default facility code */
static int LogMask = 0xff; /* mask of priorities to be logged */
extern char *__progname; /* Program name, from crt0. */
/* Define the lock. */
__libc_lock_define_initialized (static, syslog_lock)
static void openlog_internal(const char *, int, int);
static void closelog_internal(void);
static void sigpipe_handler (int);
#ifdef _LIBC_REENTRANT
static void cancel_handler (void *);
#endif
/*
* syslog, vsyslog --
* print message on log file; output is intended for syslogd(8).
*/
void
#if __STDC__
syslog(int pri, const char *fmt, ...)
#else
syslog(pri, fmt, va_alist)
int pri;
char *fmt;
va_dcl
#endif
{
va_list ap;
#if __STDC__
va_start(ap, fmt);
#else
va_start(ap);
#endif
vsyslog(pri, fmt, ap);
va_end(ap);
}
void
vsyslog(pri, fmt, ap)
int pri;
register const char *fmt;
va_list ap;
{
struct tm now_tm;
time_t now;
int fd;
FILE *f;
char *buf = 0;
size_t bufsize = 0;
size_t prioff, msgoff;
struct sigaction action, oldaction;
struct sigaction *oldaction_ptr = NULL;
int sigpipe;
#define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
/* Check for invalid bits. */
if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
syslog(INTERNALLOG,
"syslog: unknown facility/priority: %x", pri);
pri &= LOG_PRIMASK|LOG_FACMASK;
}
/* Check priority against setlogmask values. */
if (!LOG_MASK(LOG_PRI(pri)) & LogMask)
return;
/* Set default facility if none specified. */
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
/* Build the message in a memory-buffer stream. */
f = open_memstream (&buf, &bufsize);
prioff = fprintf (f, "<%d>", pri);
(void) time (&now);
#ifdef USE_IN_LIBIO
f->_IO_write_ptr += strftime (f->_IO_write_ptr,
f->_IO_write_end - f->_IO_write_ptr,
"%h %e %T ",
__localtime_r (&now, &now_tm));
#else
f->__bufp += strftime (f->__bufp, f->__put_limit - f->__bufp,
"%h %e %T ", __localtime_r (&now, &now_tm));
#endif
msgoff = ftell (f);
if (LogTag == NULL)
LogTag = __progname;
if (LogTag != NULL)
fputs (LogTag, f);
if (LogStat & LOG_PID)
fprintf (f, "[%d]", getpid ());
if (LogTag != NULL)
putc (':', f), putc (' ', f);
/* We have the header. Print the user's format into the buffer. */
vfprintf (f, fmt, ap);
/* Close the memory stream; this will finalize the data
into a malloc'd buffer in BUF. */
fclose (f);
/* Output to stderr if requested. */
if (LogStat & LOG_PERROR) {
struct iovec iov[2];
register struct iovec *v = iov;
v->iov_base = buf + msgoff;
v->iov_len = bufsize - msgoff;
++v;
v->iov_base = (char *) "\n";
v->iov_len = 1;
(void)writev(STDERR_FILENO, iov, 2);
}
/* Prepare for multiple users. We have to take care: open and
write are cancellation points. */
__libc_cleanup_region_start ((void (*) (void *)) cancel_handler,
&oldaction_ptr);
__libc_lock_lock (syslog_lock);
/* Prepare for a broken connection. */
memset (&action, 0, sizeof (action));
action.sa_handler = sigpipe_handler;
sigemptyset (&action.sa_mask);
sigpipe = sigaction (SIGPIPE, &action, &oldaction);
if (sigpipe == 0)
oldaction_ptr = &oldaction;
/* Get connected, output the message to the local logger. */
if (!connected)
openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
/* If we have a SOCK_STREAM connection, also send ASCII NUL as
a record terminator. */
if (LogType == SOCK_STREAM)
++bufsize;
if (__send(LogFile, buf, bufsize, 0) < 0)
{
closelog_internal (); /* attempt re-open next time */
/*
* Output the message to the console; don't worry about blocking,
* if console blocks everything will. Make sure the error reported
* is the one from the syslogd failure.
*/
if (LogStat & LOG_CONS &&
(fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0)
{
dprintf (fd, "%s\r\n", buf + msgoff);
(void)close(fd);
}
}
if (sigpipe == 0)
sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
/* End of critical section. */
__libc_cleanup_region_end (0);
__libc_lock_unlock (syslog_lock);
free (buf);
}
static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
static void
openlog_internal(const char *ident, int logstat, int logfac)
{
if (ident != NULL)
LogTag = ident;
LogStat = logstat;
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
LogFacility = logfac;
while (1) {
if (LogFile == -1) {
SyslogAddr.sa_family = AF_UNIX;
(void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
sizeof(SyslogAddr.sa_data));
if (LogStat & LOG_NDELAY) {
if ((LogFile = socket(AF_UNIX, LogType, 0))
== -1)
return;
(void)fcntl(LogFile, F_SETFD, 1);
}
}
if (LogFile != -1 && !connected)
if (__connect(LogFile, &SyslogAddr, sizeof(SyslogAddr))
== -1)
{
int saved_errno = errno;
(void)close(LogFile);
LogFile = -1;
if (LogType == SOCK_DGRAM
&& saved_errno == EPROTOTYPE)
{
/* retry with next SOCK_STREAM: */
LogType = SOCK_STREAM;
continue;
}
} else
connected = 1;
break;
}
}
void
openlog (const char *ident, int logstat, int logfac)
{
/* Protect against multiple users. */
__libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock,
&syslog_lock);
__libc_lock_lock (syslog_lock);
openlog_internal (ident, logstat, logfac);
/* Free the lock. */
__libc_cleanup_region_end (1);
}
static void
sigpipe_handler (int signo)
{
closelog_internal();
}
static void
closelog_internal()
{
(void)close(LogFile);
LogFile = -1;
connected = 0;
}
void
closelog ()
{
/* Protect against multiple users. */
__libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock,
&syslog_lock);
__libc_lock_lock (syslog_lock);
closelog_internal ();
/* Free the lock. */
__libc_cleanup_region_end (1);
}
#ifdef _LIBC_REENTRANT
static void
cancel_handler (void *ptr)
{
/* Restore the old signal handler. */
struct sigaction *oldaction = *((struct sigaction **) ptr);
if (oldaction != (struct sigaction *) NULL)
sigaction (SIGPIPE, oldaction, (struct sigaction *) NULL);
/* Free the lock. */
__libc_lock_unlock (syslog_lock);
}
#endif
/* setlogmask -- set the log mask level */
int
setlogmask(pmask)
int pmask;
{
int omask;
omask = LogMask;
if (pmask != 0)
LogMask = pmask;
return (omask);
}