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:
parent
d9f883f215
commit
f1cc12f55e
4 changed files with 229 additions and 19 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
177
syslogd/proto.c
Normal 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
35
syslogd/proto.h
Normal 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 */
|
Loading…
Reference in a new issue