1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 * syslog implementation
37 #include "sysloglib.h"
42 Syslog_state_t log
= { LOG_USER
, -1, 0, ~0 };
44 static const Namval_t attempt
[] =
52 "/dev/console", LOG_CONS
,
55 const Namval_t log_facility
[] =
71 "system2", LOG_SYSTEM2
,
74 "system1", LOG_SYSTEM1
,
77 "system0", LOG_SYSTEM0
,
82 const Namval_t log_severity
[] =
88 "warning", LOG_WARNING
,
98 * open /dev/(fdp|tcp|udp)/HOST/SERVICE for read
103 #include <sys/socket.h>
106 #include <netinet/in.h>
108 #if !defined(htons) && !_lib_htons
109 # define htons(x) (x)
111 #if !defined(htonl) && !_lib_htonl
112 # define htonl(x) (x)
115 #ifndef INADDR_LOOPBACK
116 #define INADDR_LOOPBACK 0x7f000001L
120 * convert s to sockaddr_in
121 * -1 returned on error
125 str2inet(register char* s
, char* prot
, struct sockaddr_in
* addr
)
131 unsigned short p
= 0;
133 if (!memcmp(s
, "local/", 6))
139 else if (!isdigit(*s
))
142 char* e
= strchr(s
, '/');
144 if (!(e
= strchr(s
, '/')))
147 hp
= gethostbyname(s
);
149 if (!hp
|| hp
->h_addrtype
!= AF_INET
|| hp
->h_length
> sizeof(struct in_addr
))
151 a
= (unsigned long)((struct in_addr
*)hp
->h_addr
)->s_addr
;
158 while ((c
= *s
++) >= '0' && c
<= '9')
159 v
= v
* 10 + c
- '0';
161 a
= (a
<< 8) | (v
& 0xff);
170 if (!(sp
= getservbyname(s
- 1, prot
)))
178 if (c
!= '.' && c
!= '/')
181 memset((char*)addr
, 0, sizeof(*addr
));
182 addr
->sin_family
= AF_INET
;
183 addr
->sin_addr
.s_addr
= a
;
189 * call this after open fails to see if path is a socket
193 sockopen(const char* path
)
196 struct sockaddr_in addr
;
199 if (pathgetlink(path
, buf
, sizeof(buf
)) <= 0)
201 if (strlen(path
) >= sizeof(buf
))
208 struct sockaddr_un ua
;
211 if ((ul
= strlen(buf
)) < sizeof(ua
.sun_path
) && !stat(buf
, &st
) && S_ISSOCK(st
.st_mode
))
213 if ((fd
= socket(AF_UNIX
, SOCK_STREAM
, 0)) < 0)
215 ua
.sun_family
= AF_UNIX
;
216 strcpy(ua
.sun_path
, buf
);
217 ul
+= sizeof(ua
.sun_family
) + 1;
218 if (!connect(fd
, (struct sockaddr
*)&ua
, ul
))
225 if (!strmatch(buf
, "/dev/(tcp|udp)/*/*"))
228 if (str2inet(buf
+ 9, buf
+ 5, &addr
))
230 if ((fd
= socket(AF_INET
, buf
[5] == 't' ? SOCK_STREAM
: SOCK_DGRAM
, 0)) < 0)
232 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
)))
243 sockopen(const char* path
)
251 sendlog(const char* msg
)
254 register Namval_t
* p
;
257 n
= msg
? strlen(msg
) : 0;
264 if (log
.attempt
>= elementsof(attempt
))
266 p
= (Namval_t
*)&attempt
[log
.attempt
++];
267 if (p
->value
&& !(p
->value
& log
.flags
))
269 if (*(s
= p
->name
) != '/' && !(s
= pathpath(buf
, s
, "", PATH_REGULAR
|PATH_READ
)))
271 if ((log
.fd
= open(s
, O_WRONLY
|O_APPEND
|O_NOCTTY
)) < 0 && (log
.fd
= sockopen(s
)) < 0)
273 fcntl(log
.fd
, F_SETFD
, FD_CLOEXEC
);
275 if (!n
|| write(log
.fd
, msg
, n
) > 0)
280 if (n
&& (log
.flags
& LOG_PERROR
))
285 extend(Sfio_t
* sp
, void* vp
, Sffmt_t
* dp
)
289 dp
->flags
|= SFFMT_VALUE
;
292 *((char**)vp
) = fmterror(errno
);
298 vsyslog(int priority
, const char* format
, va_list ap
)
306 if (!LOG_FACILITY(priority
))
307 priority
|= log
.facility
;
308 if (!(priority
& log
.mask
))
310 if (sp
= sfstropen())
312 sfputr(sp
, fmttime("%b %d %H:%M:%S", time(NiL
)), -1);
313 if (log
.flags
& LOG_LEVEL
)
315 if ((c
= LOG_SEVERITY(priority
)) < elementsof(log_severity
))
316 s
= (char*)log_severity
[c
].name
;
318 sfsprintf(s
= buf
, sizeof(buf
), "debug%d", c
);
319 sfprintf(sp
, " %-8s ", s
);
320 if ((c
= LOG_FACILITY(priority
)) < elementsof(log_facility
))
321 s
= (char*)log_facility
[c
].name
;
323 sfsprintf(s
= buf
, sizeof(buf
), "local%d", c
);
324 sfprintf(sp
, " %-8s ", s
);
327 if (!*log
.host
&& gethostname(log
.host
, sizeof(log
.host
)-1))
328 strcpy(log
.host
, "localhost");
329 sfprintf(sp
, " %s", log
.host
);
332 sfprintf(sp
, " %s", log
.ident
);
333 if (log
.flags
& LOG_PID
)
337 sfprintf(sp
, "[%d]", getpid());
342 memset(&fmt
, 0, sizeof(fmt
));
343 fmt
.version
= SFIO_VERSION
;
344 fmt
.form
= (char*)format
;
346 va_copy(fmt
.args
, ap
);
347 sfprintf(sp
, "%!", &fmt
);
349 if ((s
= sfstrseek(sp
, 0, SEEK_CUR
)) && *(s
- 1) != '\n')
351 if (s
= sfstruse(sp
))
358 syslog(int priority
, const char* format
, ...)
362 va_start(ap
, format
);
363 vsyslog(priority
, format
, ap
);