Merge branch 'master' into dev
This commit is contained in:
commit
f0b7b6fdf8
46
man/logger.1
46
man/logger.1
@ -33,11 +33,15 @@
|
|||||||
.Nd Send messages to system log, or a log file
|
.Nd Send messages to system log, or a log file
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl chiknsv
|
.Op Fl 46bchiknsv
|
||||||
.Op Fl d Ar SD
|
.Op Fl d Ar SD
|
||||||
.Op Fl f Ar FILE
|
.Op Fl f Ar FILE
|
||||||
|
.Op Fl h Ar HOST
|
||||||
|
.Op Fl H Ar HOSTNAME
|
||||||
|
.Op Fl I Ar PID
|
||||||
.Op Fl m Ar MSGID
|
.Op Fl m Ar MSGID
|
||||||
.Op Fl p Ar PRIO
|
.Op Fl p Ar PRIO
|
||||||
|
.Op Fl P Ar PORT
|
||||||
.Op Fl r Ar SIZE:NUM
|
.Op Fl r Ar SIZE:NUM
|
||||||
.Op Fl t Ar TAG
|
.Op Fl t Ar TAG
|
||||||
.Op Fl u Ar SOCK
|
.Op Fl u Ar SOCK
|
||||||
@ -61,6 +65,16 @@ reads input from
|
|||||||
.Sh OPTIONS
|
.Sh OPTIONS
|
||||||
This program follows the usual UNIX command line syntax:
|
This program follows the usual UNIX command line syntax:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Fl 4
|
||||||
|
Force
|
||||||
|
.Nm
|
||||||
|
to use IPv4 addresses only.
|
||||||
|
.It Fl 6
|
||||||
|
Force
|
||||||
|
.Nm
|
||||||
|
to use IPv6 addresses only.
|
||||||
|
.It Fl b
|
||||||
|
Use RFC3164 (BSD) style format, default: RFC5424.
|
||||||
.It Fl c
|
.It Fl c
|
||||||
Log to console
|
Log to console
|
||||||
.Ql ( LOG_CONS )
|
.Ql ( LOG_CONS )
|
||||||
@ -83,6 +97,25 @@ accepts
|
|||||||
.Fl f-
|
.Fl f-
|
||||||
as an alias for
|
as an alias for
|
||||||
.Ar stdout .
|
.Ar stdout .
|
||||||
|
.It Fl H Ar hostname
|
||||||
|
Set the hostname in the header of the message to specified value.
|
||||||
|
If not specified, host part of
|
||||||
|
.Xr gethostname 3
|
||||||
|
will be used.
|
||||||
|
.It Fl h Ar host
|
||||||
|
Send the message to the remote system
|
||||||
|
.Ar host
|
||||||
|
instead of logging it locally.
|
||||||
|
.It Fl I Ar PID
|
||||||
|
Like
|
||||||
|
.Fl i ,
|
||||||
|
but uses
|
||||||
|
.Ar PID .
|
||||||
|
Useful when logging from shell scripts that send multiple messages.
|
||||||
|
E.g., the following arguments might be a useful template:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
logger -t $(basename $0) -I $$
|
||||||
|
.Ed
|
||||||
.It Fl i
|
.It Fl i
|
||||||
Log the process id of the logger process with each line
|
Log the process id of the logger process with each line
|
||||||
.Ql ( LOG_PID ) .
|
.Ql ( LOG_PID ) .
|
||||||
@ -112,6 +145,17 @@ or sending remote in correctly formatted RFC5424 style.
|
|||||||
.It Fl n
|
.It Fl n
|
||||||
Open log file immediately
|
Open log file immediately
|
||||||
.Ql ( LOG_NDELAY ) .
|
.Ql ( LOG_NDELAY ) .
|
||||||
|
.It Fl P Ar port
|
||||||
|
Send the message to the specified
|
||||||
|
.Ar port
|
||||||
|
number on a remote system,
|
||||||
|
which can be specified as a service name
|
||||||
|
or as a decimal number.
|
||||||
|
The default is
|
||||||
|
.Dq Li syslog .
|
||||||
|
If an unknown service name is used,
|
||||||
|
.Nm
|
||||||
|
prints a warning and falls back to port 514.
|
||||||
.It Fl p Ar PRIO
|
.It Fl p Ar PRIO
|
||||||
Priority, numeric or
|
Priority, numeric or
|
||||||
.Ar facility.severity
|
.Ar facility.severity
|
||||||
|
100
src/logger.c
100
src/logger.c
@ -35,11 +35,14 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#define SYSLOG_NAMES
|
#define SYSLOG_NAMES
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
@ -61,8 +64,8 @@ static int create(char *path, mode_t mode, uid_t uid, gid_t gid)
|
|||||||
*/
|
*/
|
||||||
static int logrotate(char *file, int num, off_t sz)
|
static int logrotate(char *file, int num, off_t sz)
|
||||||
{
|
{
|
||||||
int cnt;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
if (stat(file, &st))
|
if (stat(file, &st))
|
||||||
return 1;
|
return 1;
|
||||||
@ -122,6 +125,39 @@ static void log_kmsg(FILE *fp, char *ident, int pri, int opts, char *buf)
|
|||||||
fprintf(fp, "<%d>%s[%d]:%s\n", pri, ident, getpid(), buf);
|
fprintf(fp, "<%d>%s[%d]:%s\n", pri, ident, getpid(), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nslookup(const char *host, const char *svcname, int family, struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
struct addrinfo hints, *ai, *result;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = !host ? AI_PASSIVE : 0;
|
||||||
|
hints.ai_family = family;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
|
error = getaddrinfo(host, svcname, &hints, &result);
|
||||||
|
if (error == EAI_SERVICE) {
|
||||||
|
warnx("%s/udp: unknown service, trying syslog port 514", svcname);
|
||||||
|
svcname = "514";
|
||||||
|
error = getaddrinfo(host, svcname, &hints, &result);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
warnx("%s (%s:%s)", gai_strerror(error), host, svcname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ai = result; ai; ai = ai->ai_next) {
|
||||||
|
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy(sa, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo(result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int checksz(FILE *fp, off_t sz)
|
static int checksz(FILE *fp, off_t sz)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -193,16 +229,23 @@ static int usage(int code)
|
|||||||
"\n"
|
"\n"
|
||||||
"Write MESSAGE (or line-by-line stdin) to syslog, or file (with logrotate).\n"
|
"Write MESSAGE (or line-by-line stdin) to syslog, or file (with logrotate).\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" -4 Prefer IPv4 address when sending remote, see -h\n"
|
||||||
|
" -6 Prefer IPv6 address when sending remote, see -h\n"
|
||||||
|
" -b Use RFC3164 (BSD) style format, default: RFC5424\n"
|
||||||
" -c Log to console (LOG_CONS) on failure\n"
|
" -c Log to console (LOG_CONS) on failure\n"
|
||||||
" -d SD Log SD as RFC5424 style 'structured data' in message\n"
|
" -d SD Log SD as RFC5424 style 'structured data' in message\n"
|
||||||
" -f FILE Log file to write messages to, instead of syslog daemon\n"
|
" -f FILE Log file to write messages to, instead of syslog daemon\n"
|
||||||
|
" -h HOST Send (UDP) message to this remote syslog server (IP or DNS name)\n"
|
||||||
|
" -H NAME Use NAME instead of system hostname in message header\n"
|
||||||
" -i Log process ID of the logger process with each line (LOG_PID)\n"
|
" -i Log process ID of the logger process with each line (LOG_PID)\n"
|
||||||
|
" -I PID Log process ID using PID, recommed using PID $$ for shell scripts\n"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
" -k Log to kernel /dev/kmsg if /dev/log doesn't exist yet\n"
|
" -k Log to kernel /dev/kmsg if /dev/log doesn't exist yet\n"
|
||||||
#endif
|
#endif
|
||||||
" -m MSGID Log message using this RFC5424 style MSGID\n"
|
" -m MSGID Log message using this RFC5424 style MSGID\n"
|
||||||
" -n Open log file immediately (LOG_NDELAY)\n"
|
" -n Open log file immediately (LOG_NDELAY)\n"
|
||||||
" -p PRIO Log message priority (numeric or facility.severity pair)\n"
|
" -p PRIO Log message priority (numeric or facility.severity pair)\n"
|
||||||
|
" -P PORT Use PORT (or named UDP service) for remote server, default: syslog\n"
|
||||||
" -r S[:R] Enable log file rotation, default: 200 kB \e[4ms\e[0mize, 5 \e[4mr\e[0motations\n"
|
" -r S[:R] Enable log file rotation, default: 200 kB \e[4ms\e[0mize, 5 \e[4mr\e[0motations\n"
|
||||||
" -s Log to stderr as well as the system log\n"
|
" -s Log to stderr as well as the system log\n"
|
||||||
" -t TAG Log using the specified tag (defaults to user name)\n"
|
" -t TAG Log using the specified tag (defaults to user name)\n"
|
||||||
@ -220,21 +263,36 @@ static int usage(int code)
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
char *ident = NULL, *logfile = NULL;
|
||||||
int c, num = 5;
|
char *host = NULL, *sockpath = NULL;
|
||||||
|
char *msgid = NULL, *sd = NULL;
|
||||||
|
char *svcname = "syslog";
|
||||||
|
off_t size = 200 * 1024;
|
||||||
int facility = LOG_USER;
|
int facility = LOG_USER;
|
||||||
int severity = LOG_INFO;
|
int severity = LOG_INFO;
|
||||||
int log_opts = 0;
|
int family = AF_UNSPEC;
|
||||||
int rotate = 0;
|
struct sockaddr sa;
|
||||||
int allow_kmsg = 0;
|
int allow_kmsg = 0;
|
||||||
off_t size = 200 * 1024;
|
|
||||||
char *ident = NULL, *logfile = NULL;
|
|
||||||
char *msgid = NULL, *sd = NULL;
|
|
||||||
char *sockpath = NULL;
|
|
||||||
char buf[512] = "";
|
char buf[512] = "";
|
||||||
|
int log_opts = 0;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
int c, num = 5;
|
||||||
|
int rotate = 0;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "?cd:f:ikm:np:r:st:u:v")) != EOF) {
|
while ((c = getopt(argc, argv, "46?bcd:f:h:H:iI:km:np:P:r:st:u:v")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case '4':
|
||||||
|
family = AF_INET;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '6':
|
||||||
|
family = AF_INET6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
log_opts |= LOG_RFC3154;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
log_opts |= LOG_CONS;
|
log_opts |= LOG_CONS;
|
||||||
break;
|
break;
|
||||||
@ -247,10 +305,23 @@ int main(int argc, char *argv[])
|
|||||||
logfile = optarg;
|
logfile = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
host = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'H':
|
||||||
|
strlcpy(log.log_hostname, optarg, sizeof(log.log_hostname));
|
||||||
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
log_opts |= LOG_PID;
|
log_opts |= LOG_PID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'I':
|
||||||
|
log_opts |= LOG_PID;
|
||||||
|
log.log_pid = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'k':
|
case 'k':
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
allow_kmsg = 1;
|
allow_kmsg = 1;
|
||||||
@ -272,6 +343,10 @@ int main(int argc, char *argv[])
|
|||||||
return usage(1);
|
return usage(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'P':
|
||||||
|
svcname = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
parse_rotation(optarg, &size, &num);
|
parse_rotation(optarg, &size, &num);
|
||||||
if (size > 0 && num > 0)
|
if (size > 0 && num > 0)
|
||||||
@ -351,6 +426,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
return fclose(fp);
|
return fclose(fp);
|
||||||
}
|
}
|
||||||
|
} else if (host) {
|
||||||
|
log.log_host = &sa;
|
||||||
|
if (nslookup(host, svcname, family, &sa))
|
||||||
|
return 1;
|
||||||
|
log_opts |= LOG_NDELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
openlog_r(ident, log_opts, facility, &log);
|
openlog_r(ident, log_opts, facility, &log);
|
||||||
|
147
src/syslog.c
147
src/syslog.c
@ -96,6 +96,20 @@ is_socket(int fd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used on systems that don't have sa->sa_len
|
||||||
|
*/
|
||||||
|
#ifndef HAVE_SA_LEN
|
||||||
|
static socklen_t sa_len(struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET6)
|
||||||
|
return sizeof(struct sockaddr_in6);
|
||||||
|
if (sa->sa_family == AF_INET)
|
||||||
|
return sizeof(struct sockaddr_in);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* syslog, vsyslog --
|
* syslog, vsyslog --
|
||||||
* print message on log file; output is intended for syslogd(8).
|
* print message on log file; output is intended for syslogd(8).
|
||||||
@ -190,6 +204,8 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
{
|
{
|
||||||
static const char BRCOSP[] = "]: ";
|
static const char BRCOSP[] = "]: ";
|
||||||
static const char CRLF[] = "\r\n";
|
static const char CRLF[] = "\r\n";
|
||||||
|
struct sockaddr *sa = NULL;
|
||||||
|
socklen_t len = 0;
|
||||||
size_t cnt, prlen, tries;
|
size_t cnt, prlen, tries;
|
||||||
char ch, *p, *t;
|
char ch, *p, *t;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@ -225,6 +241,17 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
if ((pri & LOG_FACMASK) == 0)
|
if ((pri & LOG_FACMASK) == 0)
|
||||||
pri |= data->log_fac;
|
pri |= data->log_fac;
|
||||||
|
|
||||||
|
/* Get system time, wallclock, fall back to UNIX time */
|
||||||
|
if (gettimeofday(&tv, NULL) == -1) {
|
||||||
|
tv.tv_sec = time(NULL);
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strftime() implies tzset(), localtime_r() doesn't. */
|
||||||
|
tzset();
|
||||||
|
now = (time_t) tv.tv_sec;
|
||||||
|
localtime_r(&now, &tmnow);
|
||||||
|
|
||||||
/* Build the message. */
|
/* Build the message. */
|
||||||
p = tbuf;
|
p = tbuf;
|
||||||
tbuf_left = TBUF_LEN;
|
tbuf_left = TBUF_LEN;
|
||||||
@ -237,23 +264,59 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
tbuf_left -= prlen; \
|
tbuf_left -= prlen; \
|
||||||
} while (/*CONSTCOND*/0)
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
/* Default log format is RFC5424, continues below BSD format */
|
||||||
|
if (data->log_stat & LOG_RFC3154) {
|
||||||
|
if (!(data->log_stat & LOG_NLOG)) {
|
||||||
|
prlen = snprintf(p, tbuf_left, "<%d>", pri);
|
||||||
|
DEC();
|
||||||
|
} else
|
||||||
|
prlen = 0;
|
||||||
|
|
||||||
|
prlen = strftime(dbuf, sizeof(dbuf), "%b %d %T ", &tmnow);
|
||||||
|
|
||||||
|
if (data->log_stat & (LOG_PERROR|LOG_CONS|LOG_NLOG)) {
|
||||||
|
iov[iovcnt].iov_base = dbuf;
|
||||||
|
iov[iovcnt].iov_len = strlen(dbuf);
|
||||||
|
iovcnt++;
|
||||||
|
}
|
||||||
|
if (data->log_host) {
|
||||||
|
memcpy(p, dbuf, prlen);
|
||||||
|
DEC();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->log_hostname[0] == '\0' && gethostname(data->log_hostname,
|
||||||
|
sizeof(data->log_hostname)) == -1) {
|
||||||
|
/* can this really happen? */
|
||||||
|
data->log_hostname[0] = '-';
|
||||||
|
data->log_hostname[1] = '\0';
|
||||||
|
}
|
||||||
|
prlen = snprintf(p, tbuf_left, "%s ", data->log_hostname);
|
||||||
|
DEC();
|
||||||
|
|
||||||
|
if (data->log_tag == NULL)
|
||||||
|
data->log_tag = getprogname();
|
||||||
|
prlen = snprintf(p, tbuf_left, "%s", data->log_tag);
|
||||||
|
DEC();
|
||||||
|
|
||||||
|
if (data->log_stat & LOG_PID) {
|
||||||
|
if (data->log_pid == -1)
|
||||||
|
data->log_pid = getpid();
|
||||||
|
prlen = snprintf(p, tbuf_left, "[%d]", data->log_pid);
|
||||||
|
DEC();
|
||||||
|
}
|
||||||
|
strlcat(p, ":", tbuf_left);
|
||||||
|
prlen = 1;
|
||||||
|
DEC();
|
||||||
|
goto output;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(data->log_stat & LOG_NLOG)) {
|
if (!(data->log_stat & LOG_NLOG)) {
|
||||||
prlen = snprintf(p, tbuf_left, "<%d>1 ", pri);
|
prlen = snprintf(p, tbuf_left, "<%d>1 ", pri);
|
||||||
DEC();
|
DEC();
|
||||||
} else
|
} else
|
||||||
prlen = 0;
|
prlen = 0;
|
||||||
|
|
||||||
if (gettimeofday(&tv, NULL) == -1) {
|
|
||||||
tv.tv_sec = time(NULL);
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* strftime() implies tzset(), localtime_r() doesn't. */
|
|
||||||
tzset();
|
|
||||||
now = (time_t) tv.tv_sec;
|
|
||||||
localtime_r(&now, &tmnow);
|
|
||||||
|
|
||||||
prlen = strftime(p, tbuf_left, "%FT%T", &tmnow);
|
prlen = strftime(p, tbuf_left, "%FT%T", &tmnow);
|
||||||
DEC();
|
DEC();
|
||||||
prlen = snprintf(p, tbuf_left, ".%06ld", (long)tv.tv_usec);
|
prlen = snprintf(p, tbuf_left, ".%06ld", (long)tv.tv_usec);
|
||||||
@ -307,7 +370,9 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
DEC();
|
DEC();
|
||||||
|
|
||||||
if (data->log_stat & LOG_PID) {
|
if (data->log_stat & LOG_PID) {
|
||||||
prlen = snprintf(p, tbuf_left, "%d ", getpid());
|
if (data->log_pid == -1)
|
||||||
|
data->log_pid = getpid();
|
||||||
|
prlen = snprintf(p, tbuf_left, "%d ", data->log_pid);
|
||||||
if (data->log_stat & (LOG_PERROR|LOG_CONS|LOG_NLOG)) {
|
if (data->log_stat & (LOG_PERROR|LOG_CONS|LOG_NLOG)) {
|
||||||
iov[iovcnt].iov_base = __UNCONST("[");
|
iov[iovcnt].iov_base = __UNCONST("[");
|
||||||
iov[iovcnt].iov_len = 1;
|
iov[iovcnt].iov_len = 1;
|
||||||
@ -343,6 +408,7 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
} else
|
} else
|
||||||
strlcat(fmt_cat, "-", FMT_LEN);
|
strlcat(fmt_cat, "-", FMT_LEN);
|
||||||
|
|
||||||
|
output:
|
||||||
if (data->log_stat & (LOG_PERROR|LOG_CONS|LOG_NLOG))
|
if (data->log_stat & (LOG_PERROR|LOG_CONS|LOG_NLOG))
|
||||||
msgsdlen = strlen(fmt_cat) + 1;
|
msgsdlen = strlen(fmt_cat) + 1;
|
||||||
else
|
else
|
||||||
@ -425,8 +491,17 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data->log_host) {
|
||||||
|
sa = data->log_host;
|
||||||
|
#ifdef HAVE_SA_LEN
|
||||||
|
len = sa->sa_len;
|
||||||
|
#else
|
||||||
|
len = sa_len(sa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the send() failed, there are two likely scenarios:
|
* If the send() fails, there are two likely scenarios:
|
||||||
* 1) syslogd was restarted
|
* 1) syslogd was restarted
|
||||||
* 2) /dev/log is out of socket buffer space
|
* 2) /dev/log is out of socket buffer space
|
||||||
* We attempt to reconnect to /dev/log to take care of
|
* We attempt to reconnect to /dev/log to take care of
|
||||||
@ -434,7 +509,7 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
|
|||||||
* to give syslogd a chance to empty its socket buffer.
|
* to give syslogd a chance to empty its socket buffer.
|
||||||
*/
|
*/
|
||||||
for (tries = 0; tries < MAXTRIES; tries++) {
|
for (tries = 0; tries < MAXTRIES; tries++) {
|
||||||
if (send(data->log_file, tbuf, cnt, 0) != -1)
|
if (sendto(data->log_file, tbuf, cnt, 0, sa, len) != -1)
|
||||||
break;
|
break;
|
||||||
if (errno != ENOBUFS) {
|
if (errno != ENOBUFS) {
|
||||||
disconnectlog_r(data);
|
disconnectlog_r(data);
|
||||||
@ -487,7 +562,7 @@ disconnectlog_r(struct syslog_data *data)
|
|||||||
static void
|
static void
|
||||||
connectlog_r(struct syslog_data *data)
|
connectlog_r(struct syslog_data *data)
|
||||||
{
|
{
|
||||||
/* AF_UNIX address of local logger */
|
struct sockaddr *sa = data->log_host;
|
||||||
static struct sockaddr_un sun = {
|
static struct sockaddr_un sun = {
|
||||||
.sun_family = AF_LOCAL,
|
.sun_family = AF_LOCAL,
|
||||||
#ifdef HAVE_SA_LEN
|
#ifdef HAVE_SA_LEN
|
||||||
@ -495,28 +570,48 @@ connectlog_r(struct syslog_data *data)
|
|||||||
#endif
|
#endif
|
||||||
.sun_path = _PATH_LOG,
|
.sun_path = _PATH_LOG,
|
||||||
};
|
};
|
||||||
|
socklen_t len;
|
||||||
|
int family;
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
path = getenv("SYSLOG_UNIX_PATH");
|
if (sa) {
|
||||||
if (!data->log_sockpath && path)
|
family = sa->sa_family;
|
||||||
data->log_sockpath = path;
|
#ifdef HAVE_SA_LEN
|
||||||
if (data->log_sockpath && !access(data->log_sockpath, W_OK))
|
len = sa->sa_len;
|
||||||
strlcpy(sun.sun_path, data->log_sockpath, sizeof(sun.sun_path));
|
#else
|
||||||
|
len = sa_len(sa);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
sa = (struct sockaddr *)&sun;
|
||||||
|
family = AF_UNIX;
|
||||||
|
#ifdef HAVE_SA_LEN
|
||||||
|
len = sa->sa_len;
|
||||||
|
#else
|
||||||
|
len = sizeof(sun);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
path = getenv("SYSLOG_UNIX_PATH");
|
||||||
|
if (!data->log_sockpath && path)
|
||||||
|
data->log_sockpath = path;
|
||||||
|
|
||||||
|
if (data->log_sockpath && !access(data->log_sockpath, W_OK))
|
||||||
|
strlcpy(sun.sun_path, data->log_sockpath, sizeof(sun.sun_path));
|
||||||
|
}
|
||||||
|
|
||||||
if (data->log_file == -1 || fcntl(data->log_file, F_GETFL, 0) == -1) {
|
if (data->log_file == -1 || fcntl(data->log_file, F_GETFL, 0) == -1) {
|
||||||
data->log_file = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
data->log_file = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||||
if (data->log_file == -1)
|
if (data->log_file == -1)
|
||||||
return;
|
return;
|
||||||
data->log_connected = 0;
|
data->log_connected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data->log_connected) {
|
if (!data->log_connected) {
|
||||||
if (!is_socket(data->log_file)) {
|
if (!is_socket(data->log_file)) {
|
||||||
data->log_connected = 1;
|
data->log_connected = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect(data->log_file, (const struct sockaddr *)&sun,
|
if (connect(data->log_file, sa, len) == -1) {
|
||||||
sizeof(sun)) == -1) {
|
|
||||||
(void)close(data->log_file);
|
(void)close(data->log_file);
|
||||||
data->log_file = -1;
|
data->log_file = -1;
|
||||||
} else
|
} else
|
||||||
@ -534,10 +629,12 @@ openlog_unlocked_r(const char *ident, int logstat, int logfac,
|
|||||||
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
|
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
|
||||||
data->log_fac = logfac;
|
data->log_fac = logfac;
|
||||||
|
|
||||||
if (data->log_stat & LOG_NDELAY) /* open immediately */
|
if (data->log_stat & LOG_NDELAY) { /* open immediately */
|
||||||
connectlog_r(data);
|
connectlog_r(data);
|
||||||
|
if (data->log_connected)
|
||||||
data->log_opened = 1;
|
data->log_opened = 1;
|
||||||
|
} else
|
||||||
|
data->log_opened = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -190,6 +190,7 @@ CODE facilitynames[] = {
|
|||||||
#define LOG_PTRIM 0x040 /* trim tag and pid from messages to stderr */
|
#define LOG_PTRIM 0x040 /* trim tag and pid from messages to stderr */
|
||||||
#define LOG_NLOG 0x080 /* don't write to the system log */
|
#define LOG_NLOG 0x080 /* don't write to the system log */
|
||||||
#define LOG_STDOUT 0x100 /* like nlog, for debugging syslogp() API */
|
#define LOG_STDOUT 0x100 /* like nlog, for debugging syslogp() API */
|
||||||
|
#define LOG_RFC3154 0x200 /* Log to remote/ipc socket in old BSD format */
|
||||||
|
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
|
|
||||||
@ -206,6 +207,8 @@ struct syslog_data {
|
|||||||
char log_hostname[256]; /* MAXHOSTNAMELEN */
|
char log_hostname[256]; /* MAXHOSTNAMELEN */
|
||||||
int log_fac;
|
int log_fac;
|
||||||
int log_mask;
|
int log_mask;
|
||||||
|
void *log_host; /* struct sockaddr* */
|
||||||
|
int log_pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SYSLOG_DATA_INIT { \
|
#define SYSLOG_DATA_INIT { \
|
||||||
@ -219,6 +222,8 @@ struct syslog_data {
|
|||||||
.log_hostname = { '\0' }, \
|
.log_hostname = { '\0' }, \
|
||||||
.log_fac = LOG_USER, \
|
.log_fac = LOG_USER, \
|
||||||
.log_mask = 0xff, \
|
.log_mask = 0xff, \
|
||||||
|
.log_host = NULL, \
|
||||||
|
.log_pid = -1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -30,6 +30,7 @@ MSG=$MSG$MSG$MSG$MSG$MSG$MSG$MSG$MSG$MSG$MSG
|
|||||||
logger ${MSG}
|
logger ${MSG}
|
||||||
logger 1${MSG}
|
logger 1${MSG}
|
||||||
logger 2${MSG}
|
logger 2${MSG}
|
||||||
|
sleep 1
|
||||||
|
|
||||||
if [ -f "${LOG}.0" ] &&
|
if [ -f "${LOG}.0" ] &&
|
||||||
grep 'script 1' "${NOT1STAMP}" &&
|
grep 'script 1' "${NOT1STAMP}" &&
|
||||||
|
Loading…
Reference in New Issue
Block a user