|
|
BSD 4.3
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sgtty.h>
#ifdef LOG_IPC
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif LOG_IPC
static char SccsId[] = "%W% %Y% %G%";
/*
** 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, it prints the module name in front of lines,
** and has some other formatting types (or will sometime).
** Also, it adds a newline on the end of messages.
**
** The output of this routine is intended to be read by
** /etc/syslog, which will add timestamps.
**
** Parameters:
** pri -- the message priority.
** fmt -- the format string.
** p0 -- the first of many parameters.
**
** Returns:
** none
**
** Side Effects:
** output to log.
*/
#define MAXLINE 1000 /* maximum line length */
#define BUFSLOP 20 /* space to allow for "extra stuff" */
#define NULL 0 /* manifest */
static int SyslogFile = -1; /* fd for log */
static int SyslogStat = 0; /* status bits; see below */
static char *SyslogTag = NULL; /* tag for each entry */
static int SyslogMask = LOG_DEBUG; /* lowest priority logged */
#ifdef LOG_IPC
static struct sockaddr_in SyslogAddr; /* address of syslog daemon */
static char *SyslogHost = LOG_HOST; /* name of this host */
#endif LOG_IPC
syslog(pri, fmt, p0, p1, p2, p3, p4)
int pri;
char *fmt;
{
char buf[MAXLINE+BUFSLOP];
register char *b;
char *f;
int prec;
int len;
register char c;
register char *p;
int i;
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
extern char *logcvt();
char outline[MAXLINE + 1];
/* if we have no log, open it */
if (SyslogFile < 0)
openlog(0, 0);
/* see if we should just throw out this message */
if (pri > SyslogMask)
return;
f = fmt;
while (*f != '\0')
{
/* beginning of line */
b = buf;
/* insert priority code */
if (pri > 0 && (SyslogStat & LOG_COOLIT) == 0)
{
*b++ = '<';
*b++ = pri + '0';
*b++ = '>';
}
/* output current process ID */
if ((SyslogStat & LOG_PID) != 0)
{
sprintf(b, "%d ", getpid());
b += strlen(b);
}
/* and module name */
if (SyslogTag != 0)
{
for (p = SyslogTag; *p != '\0'; )
*b++ = *p++;
*b++ = ':';
*b++ = ' ';
}
while ((c = *f++) != '\0' && c != '\n')
{
/* output character directly if not interpolated */
if (c != '%')
{
*b++ = c;
continue;
}
c = *f++;
switch (c)
{
case 'm': /* output error code */
if (errno < 0 || errno > sys_nerr)
sprintf(b, "error %d", errno);
else
sprintf(b, "%s", sys_errlist[errno]);
break;
default:
*b++ = '%';
*b++ = c;
*b = '\0';
break;
}
b += strlen(b);
if (b >= &buf[MAXLINE])
break;
}
if (c == '\0')
f--;
/* add trailing newline */
*b++ = '\n';
*b = '\0';
/* output string */
sprintf(outline, buf, p0, p1, p2, p3, p4);
#ifdef LOG_IPC
if (SyslogStat & LOG_DGRAM)
{
register int r;
r = sendto(SyslogFile, outline, strlen(outline), 0,
&SyslogAddr, sizeof SyslogAddr);
#ifdef DEBUG
if (r < 0)
perror("syslog: send");
#endif DEBUG
}
else
#endif LOG_IPC
write(SyslogFile, outline, strlen(outline));
}
}
/*
** OPENLOG -- open system log
**
** This happens automatically with reasonable defaults if you
** do nothing.
**
** Parameters:
** ident -- the name to be printed as a header for
** all messages.
** logstat -- a status word, interpreted as follows:
** LOG_PID -- log the pid with each message.
**
** Returns:
** 0 -- success.
** -1 -- failure; logging on /dev/console instead.
**
** Side Effects:
** Several global variables get set.
*/
openlog(ident, logstat)
char *ident;
int logstat;
{
register int i;
register int fd;
struct stat st;
#ifdef LOG_IPC
struct servent *sp;
struct hostent *hp;
#endif LOG_IPC
SyslogTag = ident;
SyslogStat = logstat;
if (SyslogFile >= 0)
return;
#ifdef LOG_IPC
sp = getservbyname("syslog", "udp");
hp = gethostbyname(SyslogHost);
if (sp != NULL && hp != NULL)
{
bzero(&SyslogAddr, sizeof SyslogAddr);
SyslogAddr.sin_family = AF_INET;
SyslogFile = socket(AF_INET, SOCK_DGRAM, 0, 0);
if (SyslogFile >= 0 && bind(SyslogFile, &SyslogAddr, sizeof SyslogAddr, 0) < 0)
{
close(SyslogFile);
SyslogFile = -1;
}
#ifdef DEBUG
if (SyslogFile < 0)
perror("syslog: socket");
#endif DEBUG
SyslogAddr.sin_port = sp->s_port;
bcopy(hp->h_addr, (char *) &SyslogAddr.sin_addr, hp->h_length);
SyslogStat |= LOG_DGRAM;
}
#else LOG_IPC
SyslogFile = open("/dev/log", 1);
#endif LOG_IPC
if (SyslogFile < 0)
{
nolog:
SyslogStat |= LOG_COOLIT;
SyslogStat &= ~LOG_DGRAM;
SyslogMask = LOG_CRIT;
SyslogFile = open("/dev/console", 1);
if (SyslogFile < 0)
{
perror("syslog: cannot open /dev/console");
SyslogFile = 2;
}
}
#ifndef LOG_IPC
if (fstat(SyslogFile, &st) < 0)
goto nolog;
switch (st.st_mode & S_IFMT)
{
case S_IFREG:
case S_IFDIR:
(void) close(SyslogFile);
goto nolog;
}
#ifdef FIOCLEX
/* have it close automatically on exec */
ioctl(SyslogFile, FIOCLEX, NULL);
#endif FIOCLEX
#endif LOG_IPC
}
/*
** CLOSELOG -- close the system log
**
** Parameters:
** none.
**
** Returns:
** none.
**
** Side Effects:
** The system log is closed.
*/
closelog()
{
(void) close(SyslogFile);
SyslogFile = -1;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.