2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
7 * Copyright (c) 1983 Regents of the University of California.
8 * All rights reserved. The Berkeley software License Agreement
9 * specifies the terms and conditions for redistribution.
12 #pragma ident "%Z%%M% %I% %E% SMI"
15 * SYSLOG -- print message on log file
17 * This routine looks a lot like printf, except that it
18 * outputs to the log file instead of the standard output.
21 * prints the module name in front of the message,
22 * has some other formatting types (or will sometime),
23 * adds a newline on the end of the message.
25 * The output of this routine is intended to be read by /etc/syslogd.
28 * Modified to use UNIX domain IPC by Ralph Campbell
31 #include <sys/types.h>
32 #include <sys/socket.h>
34 #include <sys/signal.h>
35 #include <sys/syslog.h>
37 #include <sys/unistd.h>
47 #define MAXLINE 1024 /* max message size */
49 #define PRIMASK(p) (1 << ((p) & LOG_PRIMASK))
50 #define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
51 #define IMPORTANT LOG_ERR
53 static char *logname
= "/dev/log";
54 static char *ctty
= "/dev/console";
55 static char *sysmsg
= "/dev/sysmsg";
57 static struct _syslog
{
62 struct sockaddr _SyslogAddr
;
66 #define LogFile (_syslog->_LogFile)
67 #define LogStat (_syslog->_LogStat)
68 #define LogTag (_syslog->_LogTag)
69 #define LogMask (_syslog->_LogMask)
70 #define SyslogAddr (_syslog->_SyslogAddr)
71 #define SyslogHost (_syslog->_SyslogHost)
72 #define LogFacility (_syslog->_LogFacility)
75 extern char *strerror(int);
78 void vsyslog(int, char *, va_list);
79 void openlog(char *, int, int);
80 static int snprintf(char *, size_t, char *, ...);
81 static int vsnprintf(char *, size_t, char *, va_list ap
);
86 _syslog
= (struct _syslog
*)calloc(1, sizeof (struct _syslog
));
88 return (0); /* can't do it */
89 LogFile
= -1; /* fd for log */
90 LogStat
= 0; /* status bits, set by openlog() */
91 LogTag
= "syslog"; /* string to tag the entry with */
92 LogMask
= 0xff; /* mask of priorities to be logged */
93 LogFacility
= LOG_USER
; /* default facility code */
98 syslog(int pri
, char *fmt
, ...)
103 vsyslog(pri
, fmt
, ap
);
108 vsyslog(int pri
, char *fmt
, va_list ap
)
110 char buf
[MAXLINE
+ 1], outline
[MAXLINE
+ 1];
114 int pid
, olderrno
= errno
;
115 int retsiz
, outsiz
= MAXLINE
+ 1;
118 * Maximum tag length is 256 (the pad in outline) minus the size of the
119 * other things that can go in the pad.
124 if (_syslog
== 0 && !allocstatic())
127 /* see if we should just throw out this message */
128 if (pri
<= 0 || PRIFAC(pri
) >= LOG_NFACILITIES
||
129 (PRIMASK(pri
) & LogMask
) == 0)
132 openlog(LogTag
, LogStat
| LOG_NDELAY
, 0);
134 /* set default facility if none specified */
135 if ((pri
& LOG_FACMASK
) == 0)
138 /* build the message */
141 (void) sprintf(o
, "<%d>%.15s ", pri
, ctime(&now
) + 4);
145 taglen
= strlen(LogTag
) < MAX_TAG
? strlen(LogTag
) : MAX_TAG
;
146 strncpy(o
, LogTag
, taglen
);
150 if (LogStat
& LOG_PID
) {
151 (void) sprintf(o
, "[%d]", getpid());
155 (void) strcpy(o
, ": ");
161 while ((c
= *f
++) != '\0' && c
!= '\n' && b
< &buf
[MAXLINE
]) {
168 if ((c
= *f
++) != 'm') {
173 if ((errstr
= strerror(olderrno
)) == NULL
)
174 (void) snprintf(b
, &buf
[MAXLINE
] - b
, "error %d",
177 while (*errstr
!= '\0' && b
< &buf
[MAXLINE
]) {
178 if (*errstr
== '%') {
190 if (b
> buf
&& *(b
-1) != '\n') /* ensure at least one newline */
193 (void) vsnprintf(o
, &outline
[sizeof (outline
)] - o
, buf
, ap
);
194 c
= strlen(outline
) + 1; /* add one for NULL byte */
197 outline
[MAXLINE
-1] = '\0';
200 /* output the message to the local logger */
201 if (sendto(LogFile
, outline
, c
, 0, &SyslogAddr
,
202 sizeof (SyslogAddr
)) >= 0)
204 if (!(LogStat
& LOG_CONS
))
207 /* output the message to the console */
214 (void) signal(SIGALRM
, SIG_DFL
);
215 (void) sigsetmask(sigblock(0) & ~sigmask(SIGALRM
));
217 if (((fd
= open(sysmsg
, O_WRONLY
)) >= 0) ||
218 (fd
= open(ctty
, O_WRONLY
)) >= 0) {
220 if (outsiz
> 2) { /* Just in case */
221 (void) strcat(o
, "\r\n");
224 o
= index(outline
, '>') + 1;
225 (void) write(fd
, o
, c
- (o
- outline
));
231 if (!(LogStat
& LOG_NOWAIT
))
232 while ((c
= wait((int *)0)) > 0 && c
!= pid
)
237 * OPENLOG -- open system log
240 openlog(char *ident
, int logstat
, int logfac
)
242 if (_syslog
== 0 && !allocstatic())
248 LogFacility
= logfac
& LOG_FACMASK
;
251 SyslogAddr
.sa_family
= AF_UNIX
;
252 (void) strncpy(SyslogAddr
.sa_data
, logname
,
253 sizeof (SyslogAddr
.sa_data
));
254 if (LogStat
& LOG_NDELAY
) {
255 LogFile
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
256 (void) fcntl(LogFile
, F_SETFD
, 1);
261 * CLOSELOG -- close the system log
269 (void) close(LogFile
);
274 * SETLOGMASK -- set the log mask level
277 setlogmask(int pmask
)
281 if (_syslog
== 0 && !allocstatic())
290 * snprintf/vsnprintf -- These routines are here
291 * temporarily to solve bugid 1220257. Perhaps
292 * they could become a public interface at some
293 * point but not for now.
296 extern int _doprnt();
299 snprintf(char *string
, size_t n
, char *format
, ...)
308 siop
._base
= siop
._ptr
= (unsigned char *)string
;
309 siop
._flag
= _IOWRT
+_IOSTRG
;
310 va_start(ap
, format
);
311 count
= _doprnt(format
, ap
, &siop
);
313 *siop
._ptr
= '\0'; /* plant terminating null character */
318 vsnprintf(char *string
, size_t n
, char *format
, va_list ap
)
326 siop
._base
= siop
._ptr
= (unsigned char *)string
;
327 siop
._flag
= _IOWRT
+_IOSTRG
;
328 count
= _doprnt(format
, ap
, &siop
);
329 *siop
._ptr
= '\0'; /* plant terminating null character */