From: Karel Zak Date: Tue, 6 Oct 2015 07:16:33 +0000 (+0200) Subject: logger: fix messages separation on UNIX socket X-Git-Tag: v2.28-rc1~327 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc20393cdb5ed960fa4d6822c2fbf15fc191a6a0;p=thirdparty%2Futil-linux.git logger: fix messages separation on UNIX socket The function write_output() add additional \n after each message on TYPE_TPC. This is required by syslog daemons, otherwise you will see multiple log messages merged together in your log file, for example: Oct 6 09:01:40 ws kzak: AAA<14>Oct 6 09:01:40 kzak: BBB for printf "AAA\nBBB\n" | logger -p info -u Unfortunately, the connection initialization functions keep the default ALL_TYPES as connection type and nowhere in the control struct is info about the final real connection type. The problem is invisible when you specify --tpc or --udp on logger command line. Addresses: https://github.com/karelzak/util-linux/issues/225 Signed-off-by: Karel Zak --- diff --git a/misc-utils/logger.c b/misc-utils/logger.c index c8ec8fa2dd..6a96554286 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -229,9 +229,9 @@ static int pencode(char *s) return ((level & LOG_PRIMASK) | (facility & LOG_FACMASK)); } -static int unix_socket(struct logger_ctl *ctl, const char *path, const int socket_type) +static int unix_socket(struct logger_ctl *ctl, const char *path, int *socket_type) { - int fd, i; + int fd, i, type = -1; static struct sockaddr_un s_addr; /* AF_UNIX address of local logger */ if (strlen(path) >= sizeof(s_addr.sun_path)) @@ -243,10 +243,14 @@ static int unix_socket(struct logger_ctl *ctl, const char *path, const int socke for (i = 2; i; i--) { int st = -1; - if (i == 2 && socket_type & TYPE_UDP) + if (i == 2 && *socket_type & TYPE_UDP) { st = SOCK_DGRAM; - if (i == 1 && socket_type & TYPE_TCP) + type = TYPE_UDP; + } + if (i == 1 && *socket_type & TYPE_TCP) { st = SOCK_STREAM; + type = TYPE_TCP; + } if (st == -1 || (fd = socket(AF_UNIX, st, 0)) == -1) continue; if (connect(fd, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1) { @@ -265,25 +269,30 @@ static int unix_socket(struct logger_ctl *ctl, const char *path, const int socke ctl->noact = 1; return -1; } + + /* replace ALL_TYPES with the real TYPE_* */ + if (type > 0 && type != *socket_type) + *socket_type = type; return fd; } -static int inet_socket(const char *servername, const char *port, - const int socket_type) +static int inet_socket(const char *servername, const char *port, int *socket_type) { - int fd, errcode, i; + int fd, errcode, i, type = -1; struct addrinfo hints, *res; const char *p = port; for (i = 2; i; i--) { memset(&hints, 0, sizeof(hints)); - if (i == 2 && socket_type & TYPE_UDP) { + if (i == 2 && *socket_type & TYPE_UDP) { hints.ai_socktype = SOCK_DGRAM; + type = TYPE_UDP; if (port == NULL) p = "syslog"; } - if (i == 1 && socket_type & TYPE_TCP) { + if (i == 1 && *socket_type & TYPE_TCP) { hints.ai_socktype = SOCK_STREAM; + type = TYPE_TCP; if (port == NULL) p = "syslog-conn"; } @@ -311,6 +320,9 @@ static int inet_socket(const char *servername, const char *port, if (i == 0) errx(EXIT_FAILURE, _("failed to connect to %s port %s"), servername, p); + /* replace ALL_TYPES with the real TYPE_* */ + if (type > 0 && type != *socket_type) + *socket_type = type; return fd; } @@ -781,14 +793,14 @@ static void generate_syslog_header(struct logger_ctl *const ctl) static void logger_open(struct logger_ctl *ctl) { if (ctl->server) { - ctl->fd = inet_socket(ctl->server, ctl->port, ctl->socket_type); + ctl->fd = inet_socket(ctl->server, ctl->port, &ctl->socket_type); if (!ctl->syslogfp) ctl->syslogfp = syslog_rfc5424_header; } else { if (!ctl->unix_socket) ctl->unix_socket = _PATH_DEVLOG; - ctl->fd = unix_socket(ctl, ctl->unix_socket, ctl->socket_type); + ctl->fd = unix_socket(ctl, ctl->unix_socket, &ctl->socket_type); if (!ctl->syslogfp) ctl->syslogfp = syslog_local_header; }