/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
/*
* SYSLOG -- print message on log file
*
* This routine looks a lot like printf, except that it
* outputs to the log file instead of the standard output.
* Also:
* adds a timestamp,
* prints the module name in front of the message,
* has some other formatting types (or will sometime),
* adds a newline on the end of the message.
*
*/
#include "lint.h"
#include <stdlib.h>
#include <procfs.h>
#include <syslog.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <wait.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <thread.h>
#include <synch.h>
#include <stropts.h>
#include <paths.h>
#include "libc.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#endif
static struct __syslog {
int _LogFile;
int _LogStat;
const char *_LogTag;
int _LogMask;
char *_SyslogHost;
int _LogFacility;
int _LogFileInvalid;
int _OpenLogCalled;
} __syslog = {
-1, /* fd for log */
0, /* status bits, set by openlog() */
"syslog", /* string to tag the entry with */
0xff, /* mask of priorities to be logged */
NULL,
LOG_USER, /* default facility code */
FALSE, /* check for validity of fd for log */
0, /* openlog has not yet been called */
};
static int syslogd_ok(void);
/*
* Regrettably, there are several instances inside libc where
* syslog() is called from the bottom of a deep call stack
* and a critical lock was acquired near the top of the stack.
*
* Because syslog() uses stdio (and it is called from within stdio)
* it runs the danger of deadlocking, perhaps with an interposed
* malloc() when fork() is occurring concurrently, perhaps with
* some other lock within libc.
*
* The only fix for this problem is to restructure libc not to do
* this thing and always to call syslog() with no locks held.
* This restructuring will require a substantial effort.
*
* Meanwhile, we just hope that on the rare occasion that syslog()
* is called from within libc (such occurrences should "never happen")
* that we don't get caught in a race condition deadlock.
*/
void
{
}
void
{
char *b, *f, *o;
char c;
int clen;
int procfd;
psinfo_t p;
int showpid;
int nowait;
/*
* Maximum tag length is 256 (the pad in outline) minus the size of the
* other things that can go in the pad.
*/
/* see if we should just throw out this message */
return;
if (LogFileInvalid)
return;
/*
* if openlog() has not been called by the application,
* try to get the name of the application and set it
* as the ident string for messages. If unable to get
* it for any reason, fall back to using the default
* of syslog. If we succeed in getting the name, also
* turn on LOG_PID, to provide greater detail.
*/
showpid = 0;
if (OpenLogCalled == 0) {
}
}
}
if (LogFile < 0)
return;
}
/* set default facility if none specified */
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
/* build the header */
/* build the message */
/*
* To avoid potential security problems, bounds checking is done
* on outline and buf.
* The following code presumes that the header information will
* fit in 250-odd bytes, as was accounted for in the buffer size
* allocation. This is dependent on the assumption that the LogTag
* and the string returned by sprintf() for getpid() will return
* be less than 230-odd characters combined.
*/
o = outline;
o += strlen(o);
if (LogTag) {
o[taglen] = '\0';
o += strlen(o);
}
o += strlen(o);
}
if (LogTag) {
(void) strcpy(o, ": ");
o += 2;
}
o += strlen(o);
b = buf;
f = (char *)fmt;
char *errmsg;
if (c != '%') {
*b++ = c;
continue;
}
if ((c = *f++) != 'm') {
*b++ = '%';
*b++ = c;
continue;
}
olderrno);
else {
if (*errmsg == '%') {
(void) strcpy(b, "%%");
b += 2;
}
else
*b++ = *errmsg;
errmsg++;
}
*b = '\0';
}
b += strlen(b);
}
*b++ = '\n';
*b = '\0';
/* LINTED variable format specifier */
}
/*
* 1136432 points out that the underlying log driver actually
* refuses to accept (ERANGE) messages longer than LOG_MAXPS
* bytes. So it really doesn't make much sense to putmsg a
* longer message..
*/
}
/* set up the strbufs */
/* output the message to the local logger */
return;
return;
/*
* Output the message to the console directly. To reduce visual
* clutter, we strip out the message ID.
*/
if (pid == -1)
return;
if (pid == 0) {
int fd;
(void) sigemptyset(&sigs);
(void) alarm(5);
(void) alarm(0);
}
_exit(0);
}
if (!nowait)
continue;
}
/*
* Use a door call to syslogd to see if it's alive.
*/
static int
syslogd_ok(void)
{
int d;
int s;
return (0);
/*
* see if our pid matches the pid of the door server.
* If so, syslogd has called syslog(), probably as
* a result of some name service library error, and
* we don't want to let syslog continue and possibly
* fork here.
*/
(void) close(d);
return (0);
}
s = __door_call(d, &darg);
(void) close(d);
if (s < 0)
return (0); /* failure - syslogd dead */
else
return (1);
}
/*
* OPENLOG -- open system log
*/
void
{
OpenLogCalled = 1;
if (ident != NULL)
LogTag = ident;
if (logfac != 0)
/*
* if the fstat(2) fails or the st_rdev has changed
* then we must open the file
*/
return;
if (LogStat & LOG_NDELAY) {
}
}
/*
* CLOSELOG -- close the system log
*/
void
closelog(void)
{
OpenLogCalled = 0;
/* if the LogFile is invalid it can not be closed */
if (LogFileInvalid)
return;
/*
* if the fstat(2) fails or the st_rdev has changed
* then we can not close the file
*/
LogFile = -1;
LogStat = 0;
}
}
/*
* SETLOGMASK -- set the log mask level
*/
int
{
int omask = 0;
if (pmask != 0)
return (omask);
}