#pragma weak _syslog = syslog
#include "lint.h"
#include <sys/types.h>
#include <sys/types32.h>
#include <sys/mman.h>
#include <sys/stropts.h>
#include <sys/strlog.h>
#include <sys/log.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 <sys/door.h>
#include <sys/stat.h>
#include <stropts.h>
#include <sys/fork.h>
#include <sys/wait.h>
#include "libc.h"
#define MAXLINE 1024
#define PRIMASK(p) (1 << ((p) & LOG_PRIMASK))
#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
#define IMPORTANT LOG_ERR
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define logname "/dev/conslog"
#define ctty "/dev/syscon"
#define sysmsg "/dev/sysmsg"
#define DOORFILE "/var/run/syslog_door"
static struct __syslog {
int _LogFile;
int _LogStat;
const char *_LogTag;
int _LogMask;
char *_SyslogHost;
int _LogFacility;
int _LogFileInvalid;
int _OpenLogCalled;
dev_t _LogDev;
char _ProcName[PRFNSZ + 1];
} __syslog = {
-1,
0,
"syslog",
0xff,
NULL,
LOG_USER,
FALSE,
0,
};
#define LogFile (__syslog._LogFile)
#define LogStat (__syslog._LogStat)
#define LogTag (__syslog._LogTag)
#define LogMask (__syslog._LogMask)
#define SyslogHost (__syslog._SyslogHost)
#define LogFacility (__syslog._LogFacility)
#define LogFileInvalid (__syslog._LogFileInvalid)
#define OpenLogCalled (__syslog._OpenLogCalled)
#define LogDev (__syslog._LogDev)
#define ProcName (__syslog._ProcName)
static int syslogd_ok(void);
void
syslog(int pri, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsyslog(pri, fmt, ap);
va_end(ap);
}
void
vsyslog(int pri, const char *fmt, va_list ap)
{
char *b, *f, *o;
char c;
int clen;
char buf[MAXLINE + 2];
char outline[MAXLINE + 256];
time_t now;
pid_t pid;
struct log_ctl hdr;
struct strbuf dat;
struct strbuf ctl;
char timestr[26];
size_t taglen;
int olderrno = errno;
struct stat statbuff;
int procfd;
char procfile[32];
psinfo_t p;
int showpid;
uint32_t msgid;
char *msgid_start, *msgid_end;
int nowait;
int ret;
#define MAX_TAG 230
if (pri < 0 || PRIFAC(pri) >= LOG_NFACILITIES ||
(PRIMASK(pri) & LogMask) == 0)
return;
if (LogFileInvalid)
return;
showpid = 0;
if (OpenLogCalled == 0) {
(void) sprintf(procfile, "/proc/%d/psinfo", (int)getpid());
if ((procfd = open(procfile, O_RDONLY)) >= 0) {
if (read(procfd, &p, sizeof (psinfo_t)) >= 0) {
(void) strncpy(ProcName, p.pr_fname, PRFNSZ);
LogTag = (const char *) &ProcName;
showpid = LOG_PID;
}
(void) close(procfd);
}
}
if (LogFile < 0)
openlog(LogTag, LogStat|LOG_NDELAY|showpid, 0);
if ((fstat(LogFile, &statbuff) != 0) ||
(!S_ISCHR(statbuff.st_mode)) || (statbuff.st_rdev != LogDev)) {
LogFileInvalid = TRUE;
return;
}
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
hdr.pri = pri;
hdr.flags = SL_CONSOLE;
hdr.level = 0;
o = outline;
(void) time(&now);
(void) sprintf(o, "%.15s ", ctime_r(&now, timestr, 26) + 4);
o += strlen(o);
if (LogTag) {
taglen = strlen(LogTag) < MAX_TAG ? strlen(LogTag) : MAX_TAG;
(void) strncpy(o, LogTag, taglen);
o[taglen] = '\0';
o += strlen(o);
}
if (LogStat & LOG_PID) {
(void) sprintf(o, "[%d]", (int)getpid());
o += strlen(o);
}
if (LogTag) {
(void) strcpy(o, ": ");
o += 2;
}
STRLOG_MAKE_MSGID(fmt, msgid);
(void) sprintf(o, "[ID %u FACILITY_AND_PRIORITY] ", msgid);
o += strlen(o);
b = buf;
f = (char *)fmt;
while ((c = *f++) != '\0' && b < &buf[MAXLINE]) {
char *errmsg;
if (c != '%') {
*b++ = c;
continue;
}
if ((c = *f++) != 'm') {
*b++ = '%';
*b++ = c;
continue;
}
if ((errmsg = strerror(olderrno)) == NULL)
(void) snprintf(b, &buf[MAXLINE] - b, "error %d",
olderrno);
else {
while (*errmsg != '\0' && b < &buf[MAXLINE]) {
if (*errmsg == '%') {
(void) strcpy(b, "%%");
b += 2;
}
else
*b++ = *errmsg;
errmsg++;
}
*b = '\0';
}
b += strlen(b);
}
if (b > buf && *(b-1) != '\n')
*b++ = '\n';
*b = '\0';
(void) vsnprintf(o, &outline[sizeof (outline)] - o, buf, ap);
clen = (int)strlen(outline) + 1;
if (clen > MAXLINE) {
clen = MAXLINE;
outline[MAXLINE-1] = '\0';
}
if (clen > LOG_MAXPS) {
clen = LOG_MAXPS;
outline[LOG_MAXPS-1] = '\0';
}
ctl.maxlen = sizeof (struct log_ctl);
ctl.len = sizeof (struct log_ctl);
ctl.buf = (caddr_t)&hdr;
dat.maxlen = sizeof (outline);
dat.len = clen;
dat.buf = outline;
ret = putmsg(LogFile, &ctl, &dat, 0);
if (!(LogStat & LOG_CONS))
return;
if ((ret >= 0) && syslogd_ok())
return;
if ((msgid_start = strstr(outline, "[ID ")) != NULL &&
(msgid_end = strstr(msgid_start, "] ")) != NULL)
(void) strcpy(msgid_start, msgid_end + 2);
clen = strlen(outline) + 1;
nowait = (LogStat & LOG_NOWAIT);
pid = forkx(nowait? 0 : (FORK_NOSIGCHLD | FORK_WAITPID));
if (pid == -1)
return;
if (pid == 0) {
sigset_t sigs;
int fd;
(void) sigset(SIGALRM, SIG_DFL);
(void) sigemptyset(&sigs);
(void) sigaddset(&sigs, SIGALRM);
(void) sigprocmask(SIG_UNBLOCK, &sigs, NULL);
(void) alarm(5);
if (((fd = open(sysmsg, O_WRONLY)) >= 0) ||
(fd = open(ctty, O_WRONLY)) >= 0) {
(void) alarm(0);
outline[clen - 1] = '\r';
(void) write(fd, outline, clen);
(void) close(fd);
}
_exit(0);
}
if (!nowait)
while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
continue;
}
static int
syslogd_ok(void)
{
int d;
int s;
door_arg_t darg;
door_info_t info;
if ((d = open(DOORFILE, O_RDONLY)) < 0)
return (0);
info.di_target = 0;
if (__door_info(d, &info) < 0 || info.di_target == getpid()) {
(void) close(d);
return (0);
}
darg.data_ptr = NULL;
darg.data_size = 0;
darg.desc_ptr = NULL;
darg.desc_num = 0;
darg.rbuf = NULL;
darg.rsize = 0;
s = __door_call(d, &darg);
(void) close(d);
if (s < 0)
return (0);
else
return (1);
}
void
openlog(const char *ident, int logstat, int logfac)
{
struct stat statbuff;
OpenLogCalled = 1;
if (ident != NULL)
LogTag = ident;
LogStat = logstat;
if (logfac != 0)
LogFacility = logfac & LOG_FACMASK;
if ((fstat(LogFile, &statbuff) == 0) &&
(S_ISCHR(statbuff.st_mode)) && (statbuff.st_rdev == LogDev))
return;
if (LogStat & LOG_NDELAY) {
LogFile = open(logname, O_WRONLY);
(void) fcntl(LogFile, F_SETFD, 1);
(void) fstat(LogFile, &statbuff);
LogDev = statbuff.st_rdev;
}
}
void
closelog(void)
{
struct stat statbuff;
OpenLogCalled = 0;
if (LogFileInvalid)
return;
if ((fstat(LogFile, &statbuff) == 0) && (statbuff.st_rdev == LogDev)) {
(void) close(LogFile);
LogFile = -1;
LogStat = 0;
}
}
int
setlogmask(int pmask)
{
int omask = 0;
omask = LogMask;
if (pmask != 0)
LogMask = pmask;
return (omask);
}