/*
* Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License (not later!)
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include "event-parse.h"
#include "event-utils.h"
#define COMM "COMM"
static struct format_field comm = {
.name = "COMM",
};
struct event_list {
struct event_list *next;
struct event_format *event;
};
#define MAX_ERR_STR_SIZE 256
static void show_error(char **error_str, const char *fmt, ...)
{
unsigned long long index;
const char *input;
char *error;
va_list ap;
int len;
int i;
if (!error_str)
return;
input = pevent_get_input_buf();
index = pevent_get_input_buf_ptr();
len = input ? strlen(input) : 0;
error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3);
if (len) {
strcpy(error, input);
error[len] = '\n';
for (i = 1; i < len && i < index; i++)
error[len+i] = ' ';
error[len + i] = '^';
error[len + i + 1] = '\n';
len += i+2;
}
va_start(ap, fmt);
vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap);
va_end(ap);
*error_str = error;
}
static void free_token(char *token)
{
pevent_free_token(token);
}
static enum event_type read_token(char **tok)
{
enum event_type type;
char *token = NULL;
do {
free_token(token);
type = pevent_read_token(&token);
} while (type == EVENT_NEWLINE || type == EVENT_SPACE);
/* If token is = or ! check to see if the next char is ~ */
if (token &&
(strcmp(token, "=") == 0 || strcmp(token, "!") == 0) &&
pevent_peek_char() == '~') {
/* append it */
*tok = malloc_or_die(3);
sprintf(*tok, "%c%c", *token, '~');
free_token(token);
/* Now remove the '~' from the buffer */
pevent_read_token(&token);
free_token(token);
} else
*tok = token;
return type;
}
static int filter_cmp(const void *a, const void *b)
{
const struct filter_type *ea = a;
const struct filter_type *eb = b;
if (ea->event_id < eb->event_id)
return -1;
if (ea->event_id > eb->event_id)
return 1;
return 0;
}
static struct filter_type *
find_filter_type(struct event_filter *filter, int id)
{
struct filter_type *filter_type;
struct filter_type key;
key.event_id = id;
filter_type = bsearch(&key, filter->event_filters,
filter->filters,
sizeof(*filter->event_filters),
filter_cmp);
return filter_type;
}
static struct filter_type *
add_filter_type(struct event_filter *filter, int id)
{
struct filter_type *filter_type;
int i;
filter_type = find_filter_type(filter, id);
if (filter_type)
return filter_type;
filter->event_filters = realloc(filter->event_filters,
sizeof(*filter->event_filters) *
(filter->filters + 1));
if (!filter->event_filters)
die("Could not allocate filter");
for (i = 0; i < filter->filters; i++) {
if (filter->event_filters[i].event_id > id)
break;
}
if (i < filter->filters)
memmove(&filter->event_filters[i+1],
&filter->event_filters[i],
sizeof(*filter->event_filters) *
(filter->filters - i));
filter_type = &filter->event_filters[i];
filter_type->event_id = id;
filter_type->event = pevent_find_event(filter->pevent, id);
filter_type->filter = NULL;
filter->filters++;
return filter_type;
}
/**
* pevent_filter_alloc - create a new event filter
* @pevent: The pevent that this filter is associated with
*/
struct event_filter *pevent_filter_alloc(struct pevent *pevent)
{
struct event_filter *filter;
filter = malloc_or_die(sizeof(*filter));
memset(filter, 0, sizeof(*filter));
filter->pevent = pevent;
pevent_ref(pevent);
return filter;
}
static struct filter_arg *allocate_arg(void)
{
struct filter_arg *arg;
arg = malloc_or_die(sizeof(*arg));
memset(arg, 0, sizeof(*arg));
return arg;
}
static void free_arg(struct filter_arg *arg)
{
if (!arg)
return;
switch (arg->type) {
case FILTER_ARG_NONE:
case FILTER_ARG_BOOLEAN:
break;
case FILTER_ARG_NUM:
free_arg(arg->num.left);
free_arg(arg->num.right);
break;
case FILTER_ARG_EXP:
free_arg(arg->exp.left);
free_arg(arg->exp.right);
break;
case FILTER_ARG_STR:
free(arg->str.val);
regfree(&arg->str.reg);
free(arg->str.buffer);
break;
case FILTER_ARG_VALUE:
if (arg->value.type == FILTER_STRING ||
arg->value.type == FILTER_CHAR)
free(arg->value.str);
break;
case FILTER_ARG_OP:
free_arg(arg->op.left);
free_arg(arg->op.right);
default:
break;
}
free(arg);
}
static void add_event(struct event_list **events,
struct event_format *event)
{
struct event_list *list;
list = malloc_or_die(sizeof(*list));
list->next = *events;
*events = list;
list->event = event;
}
static int event_match(struct event_format *event,
regex_t *sreg, regex_t *ereg)
{
if (sreg) {
return !regexec(sreg, event->system, 0, NULL, 0) &&
!regexec(ereg, event->name, 0, NULL, 0);
}
return !regexec(ereg, event->system, 0, NULL, 0) ||
!regexec(ereg, event->name, 0, NULL, 0);
}
static int
find_event(struct pevent *pevent, struct event_list **events,
char *sys_name, char *event_name)
{
struct event_format *event;
regex_t ereg;
regex_t sreg;
int match = 0;
char *reg;
int ret;
int i;
if (!event_name) {
/* if no name is given, then swap sys and name */
event_name = sys_name;
sys_name = NULL;
}
reg = malloc_or_die(strlen(event_name) + 3);
sprintf(reg, "^%s$", event_name);
ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
free(reg);
if (ret)
return -1;
if (sys_name) {
reg = malloc_or_die(strlen(sys_name) + 3);
sprintf(reg, "^%s$", sys_name);
ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
free(reg);
if (ret) {
regfree(&ereg);
return -1;
}
}
for (i = 0; i < pevent->nr_events; i++) {
event = pevent->events[i];
if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
match = 1;
add_event(events, event);
}
}
regfree(&ereg);
if (sys_name)
regfree(&sreg);
if (!match)
return -1;
return 0;
}
static void free_events(struct event_list *events)
{
struct event_list *event;
while (events) {
event = events;
events = events->next;
free(event);
}
}
static struct filter_arg *
create_arg_item(struct event_format *event, const char *token,
enum event_type type, char **error_str)
{
struct format_field *field;
struct filter_arg *arg;
arg = allocate_arg();
switch (type) {
case EVENT_SQUOTE:
case EVENT_DQUOTE:
arg->type = FILTER_ARG_VALUE;
arg->value.type =
type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR;
arg->value.str = strdup(token);
if (!arg->value.str)
die("malloc string");
break;
case EVENT_ITEM:
/* if it is a number, then convert it */
if (isdigit(token[0])) {
arg->type = FILTER_ARG_VALUE;
arg->value.type = FILTER_NUMBER;
arg->value.val = strtoull(token, NULL, 0);
break;
}
/* Consider this a field */
field = pevent_find_any_field(event, token);
if (!field) {
if (strcmp(token, COMM) != 0) {
/* not a field, Make it false */
arg->type = FILTER_ARG_BOOLEAN;
arg->boolean.value = FILTER_FALSE;
break;
}
/* If token is 'COMM' then it is special */
field = &comm;
}
arg->type = FILTER_ARG_FIELD;
arg->field.field = field;
break;
default:
free_arg(arg);
show
局外狗
- 粉丝: 80
- 资源: 1万+
最新资源
- 汽车锁(世界锁)全自动检测设备机械设计结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- Docker & Docker-Compose资源获取下载.zip
- 基于HTML、Java、JavaScript、CSS的Flowermall线上花卉商城设计源码
- 基于SSM框架和微信小程序的订餐管理系统点餐功能源码
- 基于freeRTOS和STM32F103x的手机远程控制浴室温度系统设计源码
- 基于Java语言的经典设计模式源码解析与应用
- 桥墩冲刷实验水槽工程图机械结构设计图纸和其它技术资料和技术方案非常好100%好用.zip
- 基于物联网与可视化技术的ECIOT集成设计源码
- 基于Vue和微信小程序的JavaScript广告投放demo设计源码
- 基于layui框架的省市复选框组件设计源码
- 基于HTML、CSS、Python技术的学生先群网(asgnet.cn, efsdw.cn)设计源码
- 基于Vue、TypeScript、CSS、HTML的vite_project废弃Vue项目设计源码
- 基于微信小程序的童书租借系统设计源码
- 基于Python和JavaScript的车辆牌照识别系统设计源码
- 基于Spring Boot和Vue的校园健康管理系统设计源码
- 基于Python的滑动验证码设计源码下载
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈