1
0
Fork 0
mirror of https://github.com/pygos/init.git synced 2024-11-22 19:19:47 +01:00

[usyslogd] split off syslog parsing

- Add proto.{h,c} for parsing of syslog message
 - Also parse time stamp in addition to priority

Signed-off-by: David Oberhollenzer <david.oberhollenzer@tele2.at>
This commit is contained in:
David Oberhollenzer 2018-06-11 16:35:45 +02:00
parent d9f883f215
commit f1cc12f55e
4 changed files with 229 additions and 19 deletions

View file

@ -1,5 +1,6 @@
usyslogd_SOURCES = syslogd/main.c usyslogd_SOURCES = syslogd/main.c
usyslogd_SOURCES += syslogd/logfile.c syslogd/logfile.h usyslogd_SOURCES += syslogd/logfile.c syslogd/logfile.h
usyslogd_SOURCES += syslogd/proto.c syslogd/proto.h
usyslogd_CPPFLAGS = $(AM_CPPFLAGS) usyslogd_CPPFLAGS = $(AM_CPPFLAGS)
usyslogd_CFLAGS = $(AM_CFLAGS) usyslogd_CFLAGS = $(AM_CFLAGS)
usyslogd_LDFLAGS = $(AM_LDFLAGS) usyslogd_LDFLAGS = $(AM_LDFLAGS)

View file

@ -24,9 +24,9 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h>
#include "logfile.h" #include "logfile.h"
#include "proto.h"
#include "util.h" #include "util.h"
@ -118,16 +118,18 @@ static void signal_setup(void)
sigaction(SIGTERM, &act, NULL); sigaction(SIGTERM, &act, NULL);
} }
static int print_to_log(int facility, int level, const char *data) static int print_to_log(const syslog_msg_t *msg)
{ {
const char *fac_name, *lvl_str; const char *fac_name, *lvl_str;
char timebuf[32];
logfile_t *log; logfile_t *log;
struct tm tm;
fac_name = enum_to_name(facilities, facility); fac_name = enum_to_name(facilities, msg->facility);
if (fac_name == NULL) if (fac_name == NULL)
return -1; return -1;
lvl_str = enum_to_name(levels, level); lvl_str = enum_to_name(levels, msg->level);
if (lvl_str == NULL) if (lvl_str == NULL)
return -1; return -1;
@ -144,14 +146,19 @@ static int print_to_log(int facility, int level, const char *data)
logfiles = log; logfiles = log;
} }
logfile_write(log, "[%s] %s", lvl_str, data); gmtime_r(&msg->timestamp, &tm);
strftime(timebuf, sizeof(timebuf), "%FT%T", &tm);
logfile_write(log, "[%s][%s][%s][%u] %s", timebuf, lvl_str,
msg->ident ? msg->ident : "", msg->pid,
msg->message);
return 0; return 0;
} }
static int handle_data(int fd) static int handle_data(int fd)
{ {
char buffer[2048], *ptr; char buffer[2048];
int i = 0, priority; syslog_msg_t msg;
ssize_t ret; ssize_t ret;
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@ -160,20 +167,10 @@ static int handle_data(int fd)
if (ret <= 0) if (ret <= 0)
return -1; return -1;
for (ptr = buffer; isspace(*ptr); ++ptr) if (syslog_msg_parse(&msg, buffer))
;
if (*(ptr++) != '<')
return -1; return -1;
if (!isdigit(*ptr))
return -1;
for (priority = 0; isdigit(*ptr); ++ptr)
priority = priority * 10 + (*ptr) - '0';
if (*(ptr++) != '>')
return -1;
while (isspace(*ptr))
++ptr;
return print_to_log(priority >> 3, priority & 0x07, ptr); return print_to_log(&msg);
} }
int main(void) int main(void)

177
syslogd/proto.c Normal file
View file

@ -0,0 +1,177 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/*
* Copyright (C) 2018 - David Oberhollenzer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "proto.h"
static const char *months[] = {
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
};
static const int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static int isleap(int year)
{
return ((year % 4 == 0) && (year % 100 != 0)) || ((year % 400) == 0);
}
static int mdays(int year, int month)
{
return (isleap(year) && month == 2) ? 29 : days[month - 1];
}
static char *read_num(char *str, int *out, int maxval)
{
if (str == NULL || !isdigit(*str))
return NULL;
for (*out = 0; isdigit(*str); ++str) {
(*out) = (*out) * 10 + (*str) - '0';
if ((*out) > maxval)
return NULL;
}
return str;
}
static char *skip_space(char *str)
{
if (str == NULL || !isspace(*str))
return NULL;
while (isspace(*str))
++str;
return str;
}
static char *read_date_bsd(char *str, struct tm *tm)
{
int year, month, day, hour, minute, second;
time_t t;
/* decode date */
for (month = 0; month < 12; ++month) {
if (strncmp(str, months[month], 3) == 0) {
str = skip_space(str + 3);
break;
}
}
str = read_num(str, &day, 31);
str = skip_space(str);
t = time(NULL);
if (localtime_r(&t, tm) == NULL)
return NULL;
year = tm->tm_year;
/* sanity check */
if (str == NULL || month >= 12 || day < 1)
return NULL;
if (month == 11 && tm->tm_mon == 0)
--year;
if (day > mdays(year + 1900, month + 1))
return NULL;
/* decode time */
str = read_num(str, &hour, 23);
if (str == NULL || *(str++) != ':')
return NULL;
str = read_num(str, &minute, 59);
if (str == NULL || *(str++) != ':')
return NULL;
str = read_num(str, &second, 59);
str = skip_space(str);
/* store result */
memset(tm, 0, sizeof(*tm));
tm->tm_sec = second;
tm->tm_min = minute;
tm->tm_hour = hour;
tm->tm_mday = day;
tm->tm_mon = month;
tm->tm_year = year;
return str;
}
static char *decode_priority(char *str, int *priority)
{
while (isspace(*str))
++str;
if (*(str++) != '<')
return NULL;
str = read_num(str, priority, 23 * 8 + 7);
if (str == NULL || *(str++) != '>')
return NULL;
while (isspace(*str))
++str;
return str;
}
int syslog_msg_parse(syslog_msg_t *msg, char *str)
{
char *ident, *ptr;
struct tm tstamp;
pid_t pid = 0;
int priority;
memset(msg, 0, sizeof(*msg));
str = decode_priority(str, &priority);
if (str == NULL)
return -1;
msg->facility = priority >> 3;
msg->level = priority & 0x07;
str = read_date_bsd(str, &tstamp);
if (str == NULL)
return -1;
ident = str;
while (*str != '\0' && *str != ':')
++str;
if (*str == ':') {
*(str++) = '\0';
while (isspace(*str))
++str;
ptr = ident;
while (*ptr != '[' && *ptr != '\0')
++ptr;
if (*ptr == '[') {
*(ptr++) = '\0';
while (isdigit(*ptr))
pid = pid * 10 + *(ptr++) - '0';
}
} else {
ident = NULL;
}
msg->timestamp = mktime(&tstamp);
msg->pid = pid;
msg->ident = ident;
msg->message = str;
return 0;
}

35
syslogd/proto.h Normal file
View file

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-3.0-or-later */
/*
* Copyright (C) 2018 - David Oberhollenzer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PROTO_H
#define PROTO_H
#include <sys/types.h>
#include <time.h>
typedef struct {
int facility;
int level;
time_t timestamp;
pid_t pid;
const char *ident;
const char *message;
} syslog_msg_t;
int syslog_msg_parse(syslog_msg_t *msg, char *str);
#endif /* PROTO_H */