1/* 2 * Copyright (C) 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 3 * 4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; 8 * version 2.1 of the License (not later!) 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this program; if not, see <http://www.gnu.org/licenses> 17 * 18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19 */ 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include <stdarg.h> 24#include <errno.h> 25#include <sys/types.h> 26 27#include "event-parse.h" 28#include "event-utils.h" 29 30#define COMM "COMM" 31 32static struct format_field comm = { 33 .name = "COMM", 34}; 35 36struct event_list { 37 struct event_list *next; 38 struct event_format *event; 39}; 40 41static void show_error(char *error_buf, const char *fmt, ...) 42{ 43 unsigned long long index; 44 const char *input; 45 va_list ap; 46 int len; 47 int i; 48 49 input = pevent_get_input_buf(); 50 index = pevent_get_input_buf_ptr(); 51 len = input ? strlen(input) : 0; 52 53 if (len) { 54 strcpy(error_buf, input); 55 error_buf[len] = '\n'; 56 for (i = 1; i < len && i < index; i++) 57 error_buf[len+i] = ' '; 58 error_buf[len + i] = '^'; 59 error_buf[len + i + 1] = '\n'; 60 len += i+2; 61 } 62 63 va_start(ap, fmt); 64 vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap); 65 va_end(ap); 66} 67 68static void free_token(char *token) 69{ 70 pevent_free_token(token); 71} 72 73static enum event_type read_token(char **tok) 74{ 75 enum event_type type; 76 char *token = NULL; 77 78 do { 79 free_token(token); 80 type = pevent_read_token(&token); 81 } while (type == EVENT_NEWLINE || type == EVENT_SPACE); 82 83 /* If token is = or ! check to see if the next char is ~ */ 84 if (token && 85 (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && 86 pevent_peek_char() == '~') { 87 /* append it */ 88 *tok = malloc(3); 89 if (*tok == NULL) { 90 free_token(token); 91 return EVENT_ERROR; 92 } 93 sprintf(*tok, "%c%c", *token, '~'); 94 free_token(token); 95 /* Now remove the '~' from the buffer */ 96 pevent_read_token(&token); 97 free_token(token); 98 } else 99 *tok = token; 100 101 return type; 102} 103 104static int filter_cmp(const void *a, const void *b) 105{ 106 const struct filter_type *ea = a; 107 const struct filter_type *eb = b; 108 109 if (ea->event_id < eb->event_id) 110 return -1; 111 112 if (ea->event_id > eb->event_id) 113 return 1; 114 115 return 0; 116} 117 118static struct filter_type * 119find_filter_type(struct event_filter *filter, int id) 120{ 121 struct filter_type *filter_type; 122 struct filter_type key; 123 124 key.event_id = id; 125 126 filter_type = bsearch(&key, filter->event_filters, 127 filter->filters, 128 sizeof(*filter->event_filters), 129 filter_cmp); 130 131 return filter_type; 132} 133 134static struct filter_type * 135add_filter_type(struct event_filter *filter, int id) 136{ 137 struct filter_type *filter_type; 138 int i; 139 140 filter_type = find_filter_type(filter, id); 141 if (filter_type) 142 return filter_type; 143 144 filter_type = realloc(filter->event_filters, 145 sizeof(*filter->event_filters) * 146 (filter->filters + 1)); 147 if (!filter_type) 148 return NULL; 149 150 filter->event_filters = filter_type; 151 152 for (i = 0; i < filter->filters; i++) { 153 if (filter->event_filters[i].event_id > id) 154 break; 155 } 156 157 if (i < filter->filters) 158 memmove(&filter->event_filters[i+1], 159 &filter->event_filters[i], 160 sizeof(*filter->event_filters) * 161 (filter->filters - i)); 162 163 filter_type = &filter->event_filters[i]; 164 filter_type->event_id = id; 165 filter_type->event = pevent_find_event(filter->pevent, id); 166 filter_type->filter = NULL; 167 168 filter->filters++; 169 170 return filter_type; 171} 172 173/** 174 * pevent_filter_alloc - create a new event filter 175 * @pevent: The pevent that this filter is associated with 176 */ 177struct event_filter *pevent_filter_alloc(struct pevent *pevent) 178{ 179 struct event_filter *filter; 180 181 filter = malloc(sizeof(*filter)); 182 if (filter == NULL) 183 return NULL; 184 185 memset(filter, 0, sizeof(*filter)); 186 filter->pevent = pevent; 187 pevent_ref(pevent); 188 189 return filter; 190} 191 192static struct filter_arg *allocate_arg(void) 193{ 194 return calloc(1, sizeof(struct filter_arg)); 195} 196 197static void free_arg(struct filter_arg *arg) 198{ 199 if (!arg) 200 return; 201 202 switch (arg->type) { 203 case FILTER_ARG_NONE: 204 case FILTER_ARG_BOOLEAN: 205 break; 206 207 case FILTER_ARG_NUM: 208 free_arg(arg->num.left); 209 free_arg(arg->num.right); 210 break; 211 212 case FILTER_ARG_EXP: 213 free_arg(arg->exp.left); 214 free_arg(arg->exp.right); 215 break; 216 217 case FILTER_ARG_STR: 218 free(arg->str.val); 219 regfree(&arg->str.reg); 220 free(arg->str.buffer); 221 break; 222 223 case FILTER_ARG_VALUE: 224 if (arg->value.type == FILTER_STRING || 225 arg->value.type == FILTER_CHAR) 226 free(arg->value.str); 227 break; 228 229 case FILTER_ARG_OP: 230 free_arg(arg->op.left); 231 free_arg(arg->op.right); 232 default: 233 break; 234 } 235 236 free(arg); 237} 238 239static int add_event(struct event_list **events, 240 struct event_format *event) 241{ 242 struct event_list *list; 243 244 list = malloc(sizeof(*list)); 245 if (list == NULL) 246 return -1; 247 248 list->next = *events; 249 *events = list; 250 list->event = event; 251 return 0; 252} 253 254static int event_match(struct event_format *event, 255 regex_t *sreg, regex_t *ereg) 256{ 257 if (sreg) { 258 return !regexec(sreg, event->system, 0, NULL, 0) && 259 !regexec(ereg, event->name, 0, NULL, 0); 260 } 261 262 return !regexec(ereg, event->system, 0, NULL, 0) || 263 !regexec(ereg, event->name, 0, NULL, 0); 264} 265 266static enum pevent_errno 267find_event(struct pevent *pevent, struct event_list **events, 268 char *sys_name, char *event_name) 269{ 270 struct event_format *event; 271 regex_t ereg; 272 regex_t sreg; 273 int match = 0; 274 int fail = 0; 275 char *reg; 276 int ret; 277 int i; 278 279 if (!event_name) { 280 /* if no name is given, then swap sys and name */ 281 event_name = sys_name; 282 sys_name = NULL; 283 } 284 285 reg = malloc(strlen(event_name) + 3); 286 if (reg == NULL) 287 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 288 289 sprintf(reg, "^%s$", event_name); 290 291 ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); 292 free(reg); 293 294 if (ret) 295 return PEVENT_ERRNO__INVALID_EVENT_NAME; 296 297 if (sys_name) { 298 reg = malloc(strlen(sys_name) + 3); 299 if (reg == NULL) { 300 regfree(&ereg); 301 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 302 } 303 304 sprintf(reg, "^%s$", sys_name); 305 ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); 306 free(reg); 307 if (ret) { 308 regfree(&ereg); 309 return PEVENT_ERRNO__INVALID_EVENT_NAME; 310 } 311 } 312 313 for (i = 0; i < pevent->nr_events; i++) { 314 event = pevent->events[i]; 315 if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { 316 match = 1; 317 if (add_event(events, event) < 0) { 318 fail = 1; 319 break; 320 } 321 } 322 } 323 324 regfree(&ereg); 325 if (sys_name) 326 regfree(&sreg); 327 328 if (!match) 329 return PEVENT_ERRNO__EVENT_NOT_FOUND; 330 if (fail) 331 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 332 333 return 0; 334} 335 336static void free_events(struct event_list *events) 337{ 338 struct event_list *event; 339 340 while (events) { 341 event = events; 342 events = events->next; 343 free(event); 344 } 345} 346 347static enum pevent_errno 348create_arg_item(struct event_format *event, const char *token, 349 enum event_type type, struct filter_arg **parg, char *error_str) 350{ 351 struct format_field *field; 352 struct filter_arg *arg; 353 354 arg = allocate_arg(); 355 if (arg == NULL) { 356 show_error(error_str, "failed to allocate filter arg"); 357 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 358 } 359 360 switch (type) { 361 362 case EVENT_SQUOTE: 363 case EVENT_DQUOTE: 364 arg->type = FILTER_ARG_VALUE; 365 arg->value.type = 366 type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR; 367 arg->value.str = strdup(token); 368 if (!arg->value.str) { 369 free_arg(arg); 370 show_error(error_str, "failed to allocate string filter arg"); 371 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 372 } 373 break; 374 case EVENT_ITEM: 375 /* if it is a number, then convert it */ 376 if (isdigit(token[0])) { 377 arg->type = FILTER_ARG_VALUE; 378 arg->value.type = FILTER_NUMBER; 379 arg->value.val = strtoull(token, NULL, 0); 380 break; 381 } 382 /* Consider this a field */ 383 field = pevent_find_any_field(event, token); 384 if (!field) { 385 if (strcmp(token, COMM) != 0) { 386 /* not a field, Make it false */ 387 arg->type = FILTER_ARG_BOOLEAN; 388 arg->boolean.value = FILTER_FALSE; 389 break; 390 } 391 /* If token is 'COMM' then it is special */ 392 field = &comm; 393 } 394 arg->type = FILTER_ARG_FIELD; 395 arg->field.field = field; 396 break; 397 default: 398 free_arg(arg); 399 show_error(error_str, "expected a value but found %s", token); 400 return PEVENT_ERRNO__UNEXPECTED_TYPE; 401 } 402 *parg = arg; 403 return 0; 404} 405 406static struct filter_arg * 407create_arg_op(enum filter_op_type btype) 408{ 409 struct filter_arg *arg; 410 411 arg = allocate_arg(); 412 if (!arg) 413 return NULL; 414 415 arg->type = FILTER_ARG_OP; 416 arg->op.type = btype; 417 418 return arg; 419} 420 421static struct filter_arg * 422create_arg_exp(enum filter_exp_type etype) 423{ 424 struct filter_arg *arg; 425 426 arg = allocate_arg(); 427 if (!arg) 428 return NULL; 429 430 arg->type = FILTER_ARG_EXP; 431 arg->op.type = etype; 432 433 return arg; 434} 435 436static struct filter_arg * 437create_arg_cmp(enum filter_exp_type etype) 438{ 439 struct filter_arg *arg; 440 441 arg = allocate_arg(); 442 if (!arg) 443 return NULL; 444 445 /* Use NUM and change if necessary */ 446 arg->type = FILTER_ARG_NUM; 447 arg->op.type = etype; 448 449 return arg; 450} 451 452static enum pevent_errno 453add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str) 454{ 455 struct filter_arg *left; 456 char *str; 457 int op_type; 458 int ret; 459 460 switch (op->type) { 461 case FILTER_ARG_EXP: 462 if (op->exp.right) 463 goto out_fail; 464 op->exp.right = arg; 465 break; 466 467 case FILTER_ARG_OP: 468 if (op->op.right) 469 goto out_fail; 470 op->op.right = arg; 471 break; 472 473 case FILTER_ARG_NUM: 474 if (op->op.right) 475 goto out_fail; 476 /* 477 * The arg must be num, str, or field 478 */ 479 switch (arg->type) { 480 case FILTER_ARG_VALUE: 481 case FILTER_ARG_FIELD: 482 break; 483 default: 484 show_error(error_str, "Illegal rvalue"); 485 return PEVENT_ERRNO__ILLEGAL_RVALUE; 486 } 487 488 /* 489 * Depending on the type, we may need to 490 * convert this to a string or regex. 491 */ 492 switch (arg->value.type) { 493 case FILTER_CHAR: 494 /* 495 * A char should be converted to number if 496 * the string is 1 byte, and the compare 497 * is not a REGEX. 498 */ 499 if (strlen(arg->value.str) == 1 && 500 op->num.type != FILTER_CMP_REGEX && 501 op->num.type != FILTER_CMP_NOT_REGEX) { 502 arg->value.type = FILTER_NUMBER; 503 goto do_int; 504 } 505 /* fall through */ 506 case FILTER_STRING: 507 508 /* convert op to a string arg */ 509 op_type = op->num.type; 510 left = op->num.left; 511 str = arg->value.str; 512 513 /* reset the op for the new field */ 514 memset(op, 0, sizeof(*op)); 515 516 /* 517 * If left arg was a field not found then 518 * NULL the entire op. 519 */ 520 if (left->type == FILTER_ARG_BOOLEAN) { 521 free_arg(left); 522 free_arg(arg); 523 op->type = FILTER_ARG_BOOLEAN; 524 op->boolean.value = FILTER_FALSE; 525 break; 526 } 527 528 /* Left arg must be a field */ 529 if (left->type != FILTER_ARG_FIELD) { 530 show_error(error_str, 531 "Illegal lvalue for string comparison"); 532 return PEVENT_ERRNO__ILLEGAL_LVALUE; 533 } 534 535 /* Make sure this is a valid string compare */ 536 switch (op_type) { 537 case FILTER_CMP_EQ: 538 op_type = FILTER_CMP_MATCH; 539 break; 540 case FILTER_CMP_NE: 541 op_type = FILTER_CMP_NOT_MATCH; 542 break; 543 544 case FILTER_CMP_REGEX: 545 case FILTER_CMP_NOT_REGEX: 546 ret = regcomp(&op->str.reg, str, REG_ICASE|REG_NOSUB); 547 if (ret) { 548 show_error(error_str, 549 "RegEx '%s' did not compute", 550 str); 551 return PEVENT_ERRNO__INVALID_REGEX; 552 } 553 break; 554 default: 555 show_error(error_str, 556 "Illegal comparison for string"); 557 return PEVENT_ERRNO__ILLEGAL_STRING_CMP; 558 } 559 560 op->type = FILTER_ARG_STR; 561 op->str.type = op_type; 562 op->str.field = left->field.field; 563 op->str.val = strdup(str); 564 if (!op->str.val) { 565 show_error(error_str, "Failed to allocate string filter"); 566 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 567 } 568 /* 569 * Need a buffer to copy data for tests 570 */ 571 op->str.buffer = malloc(op->str.field->size + 1); 572 if (!op->str.buffer) { 573 show_error(error_str, "Failed to allocate string filter"); 574 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 575 } 576 /* Null terminate this buffer */ 577 op->str.buffer[op->str.field->size] = 0; 578 579 /* We no longer have left or right args */ 580 free_arg(arg); 581 free_arg(left); 582 583 break; 584 585 case FILTER_NUMBER: 586 587 do_int: 588 switch (op->num.type) { 589 case FILTER_CMP_REGEX: 590 case FILTER_CMP_NOT_REGEX: 591 show_error(error_str, 592 "Op not allowed with integers"); 593 return PEVENT_ERRNO__ILLEGAL_INTEGER_CMP; 594 595 default: 596 break; 597 } 598 599 /* numeric compare */ 600 op->num.right = arg; 601 break; 602 default: 603 goto out_fail; 604 } 605 break; 606 default: 607 goto out_fail; 608 } 609 610 return 0; 611 612 out_fail: 613 show_error(error_str, "Syntax error"); 614 return PEVENT_ERRNO__SYNTAX_ERROR; 615} 616 617static struct filter_arg * 618rotate_op_right(struct filter_arg *a, struct filter_arg *b) 619{ 620 struct filter_arg *arg; 621 622 arg = a->op.right; 623 a->op.right = b; 624 return arg; 625} 626 627static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg) 628{ 629 switch (op->type) { 630 case FILTER_ARG_EXP: 631 if (arg->type == FILTER_ARG_OP) 632 arg = rotate_op_right(arg, op); 633 op->exp.left = arg; 634 break; 635 636 case FILTER_ARG_OP: 637 op->op.left = arg; 638 break; 639 case FILTER_ARG_NUM: 640 if (arg->type == FILTER_ARG_OP) 641 arg = rotate_op_right(arg, op); 642 643 /* left arg of compares must be a field */ 644 if (arg->type != FILTER_ARG_FIELD && 645 arg->type != FILTER_ARG_BOOLEAN) 646 return PEVENT_ERRNO__INVALID_ARG_TYPE; 647 op->num.left = arg; 648 break; 649 default: 650 return PEVENT_ERRNO__INVALID_ARG_TYPE; 651 } 652 return 0; 653} 654 655enum op_type { 656 OP_NONE, 657 OP_BOOL, 658 OP_NOT, 659 OP_EXP, 660 OP_CMP, 661}; 662 663static enum op_type process_op(const char *token, 664 enum filter_op_type *btype, 665 enum filter_cmp_type *ctype, 666 enum filter_exp_type *etype) 667{ 668 *btype = FILTER_OP_NOT; 669 *etype = FILTER_EXP_NONE; 670 *ctype = FILTER_CMP_NONE; 671 672 if (strcmp(token, "&&") == 0) 673 *btype = FILTER_OP_AND; 674 else if (strcmp(token, "||") == 0) 675 *btype = FILTER_OP_OR; 676 else if (strcmp(token, "!") == 0) 677 return OP_NOT; 678 679 if (*btype != FILTER_OP_NOT) 680 return OP_BOOL; 681 682 /* Check for value expressions */ 683 if (strcmp(token, "+") == 0) { 684 *etype = FILTER_EXP_ADD; 685 } else if (strcmp(token, "-") == 0) { 686 *etype = FILTER_EXP_SUB; 687 } else if (strcmp(token, "*") == 0) { 688 *etype = FILTER_EXP_MUL; 689 } else if (strcmp(token, "/") == 0) { 690 *etype = FILTER_EXP_DIV; 691 } else if (strcmp(token, "%") == 0) { 692 *etype = FILTER_EXP_MOD; 693 } else if (strcmp(token, ">>") == 0) { 694 *etype = FILTER_EXP_RSHIFT; 695 } else if (strcmp(token, "<<") == 0) { 696 *etype = FILTER_EXP_LSHIFT; 697 } else if (strcmp(token, "&") == 0) { 698 *etype = FILTER_EXP_AND; 699 } else if (strcmp(token, "|") == 0) { 700 *etype = FILTER_EXP_OR; 701 } else if (strcmp(token, "^") == 0) { 702 *etype = FILTER_EXP_XOR; 703 } else if (strcmp(token, "~") == 0) 704 *etype = FILTER_EXP_NOT; 705 706 if (*etype != FILTER_EXP_NONE) 707 return OP_EXP; 708 709 /* Check for compares */ 710 if (strcmp(token, "==") == 0) 711 *ctype = FILTER_CMP_EQ; 712 else if (strcmp(token, "!=") == 0) 713 *ctype = FILTER_CMP_NE; 714 else if (strcmp(token, "<") == 0) 715 *ctype = FILTER_CMP_LT; 716 else if (strcmp(token, ">") == 0) 717 *ctype = FILTER_CMP_GT; 718 else if (strcmp(token, "<=") == 0) 719 *ctype = FILTER_CMP_LE; 720 else if (strcmp(token, ">=") == 0) 721 *ctype = FILTER_CMP_GE; 722 else if (strcmp(token, "=~") == 0) 723 *ctype = FILTER_CMP_REGEX; 724 else if (strcmp(token, "!~") == 0) 725 *ctype = FILTER_CMP_NOT_REGEX; 726 else 727 return OP_NONE; 728 729 return OP_CMP; 730} 731 732static int check_op_done(struct filter_arg *arg) 733{ 734 switch (arg->type) { 735 case FILTER_ARG_EXP: 736 return arg->exp.right != NULL; 737 738 case FILTER_ARG_OP: 739 return arg->op.right != NULL; 740 741 case FILTER_ARG_NUM: 742 return arg->num.right != NULL; 743 744 case FILTER_ARG_STR: 745 /* A string conversion is always done */ 746 return 1; 747 748 case FILTER_ARG_BOOLEAN: 749 /* field not found, is ok */ 750 return 1; 751 752 default: 753 return 0; 754 } 755} 756 757enum filter_vals { 758 FILTER_VAL_NORM, 759 FILTER_VAL_FALSE, 760 FILTER_VAL_TRUE, 761}; 762 763static enum pevent_errno 764reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, 765 struct filter_arg *arg, char *error_str) 766{ 767 struct filter_arg *other_child; 768 struct filter_arg **ptr; 769 770 if (parent->type != FILTER_ARG_OP && 771 arg->type != FILTER_ARG_OP) { 772 show_error(error_str, "can not reparent other than OP"); 773 return PEVENT_ERRNO__REPARENT_NOT_OP; 774 } 775 776 /* Get the sibling */ 777 if (old_child->op.right == arg) { 778 ptr = &old_child->op.right; 779 other_child = old_child->op.left; 780 } else if (old_child->op.left == arg) { 781 ptr = &old_child->op.left; 782 other_child = old_child->op.right; 783 } else { 784 show_error(error_str, "Error in reparent op, find other child"); 785 return PEVENT_ERRNO__REPARENT_FAILED; 786 } 787 788 /* Detach arg from old_child */ 789 *ptr = NULL; 790 791 /* Check for root */ 792 if (parent == old_child) { 793 free_arg(other_child); 794 *parent = *arg; 795 /* Free arg without recussion */ 796 free(arg); 797 return 0; 798 } 799 800 if (parent->op.right == old_child) 801 ptr = &parent->op.right; 802 else if (parent->op.left == old_child) 803 ptr = &parent->op.left; 804 else { 805 show_error(error_str, "Error in reparent op"); 806 return PEVENT_ERRNO__REPARENT_FAILED; 807 } 808 809 *ptr = arg; 810 811 free_arg(old_child); 812 return 0; 813} 814 815/* Returns either filter_vals (success) or pevent_errno (failfure) */ 816static int test_arg(struct filter_arg *parent, struct filter_arg *arg, 817 char *error_str) 818{ 819 int lval, rval; 820 821 switch (arg->type) { 822 823 /* bad case */ 824 case FILTER_ARG_BOOLEAN: 825 return FILTER_VAL_FALSE + arg->boolean.value; 826 827 /* good cases: */ 828 case FILTER_ARG_STR: 829 case FILTER_ARG_VALUE: 830 case FILTER_ARG_FIELD: 831 return FILTER_VAL_NORM; 832 833 case FILTER_ARG_EXP: 834 lval = test_arg(arg, arg->exp.left, error_str); 835 if (lval != FILTER_VAL_NORM) 836 return lval; 837 rval = test_arg(arg, arg->exp.right, error_str); 838 if (rval != FILTER_VAL_NORM) 839 return rval; 840 return FILTER_VAL_NORM; 841 842 case FILTER_ARG_NUM: 843 lval = test_arg(arg, arg->num.left, error_str); 844 if (lval != FILTER_VAL_NORM) 845 return lval; 846 rval = test_arg(arg, arg->num.right, error_str); 847 if (rval != FILTER_VAL_NORM) 848 return rval; 849 return FILTER_VAL_NORM; 850 851 case FILTER_ARG_OP: 852 if (arg->op.type != FILTER_OP_NOT) { 853 lval = test_arg(arg, arg->op.left, error_str); 854 switch (lval) { 855 case FILTER_VAL_NORM: 856 break; 857 case FILTER_VAL_TRUE: 858 if (arg->op.type == FILTER_OP_OR) 859 return FILTER_VAL_TRUE; 860 rval = test_arg(arg, arg->op.right, error_str); 861 if (rval != FILTER_VAL_NORM) 862 return rval; 863 864 return reparent_op_arg(parent, arg, arg->op.right, 865 error_str); 866 867 case FILTER_VAL_FALSE: 868 if (arg->op.type == FILTER_OP_AND) 869 return FILTER_VAL_FALSE; 870 rval = test_arg(arg, arg->op.right, error_str); 871 if (rval != FILTER_VAL_NORM) 872 return rval; 873 874 return reparent_op_arg(parent, arg, arg->op.right, 875 error_str); 876 877 default: 878 return lval; 879 } 880 } 881 882 rval = test_arg(arg, arg->op.right, error_str); 883 switch (rval) { 884 case FILTER_VAL_NORM: 885 default: 886 break; 887 888 case FILTER_VAL_TRUE: 889 if (arg->op.type == FILTER_OP_OR) 890 return FILTER_VAL_TRUE; 891 if (arg->op.type == FILTER_OP_NOT) 892 return FILTER_VAL_FALSE; 893 894 return reparent_op_arg(parent, arg, arg->op.left, 895 error_str); 896 897 case FILTER_VAL_FALSE: 898 if (arg->op.type == FILTER_OP_AND) 899 return FILTER_VAL_FALSE; 900 if (arg->op.type == FILTER_OP_NOT) 901 return FILTER_VAL_TRUE; 902 903 return reparent_op_arg(parent, arg, arg->op.left, 904 error_str); 905 } 906 907 return rval; 908 default: 909 show_error(error_str, "bad arg in filter tree"); 910 return PEVENT_ERRNO__BAD_FILTER_ARG; 911 } 912 return FILTER_VAL_NORM; 913} 914 915/* Remove any unknown event fields */ 916static int collapse_tree(struct filter_arg *arg, 917 struct filter_arg **arg_collapsed, char *error_str) 918{ 919 int ret; 920 921 ret = test_arg(arg, arg, error_str); 922 switch (ret) { 923 case FILTER_VAL_NORM: 924 break; 925 926 case FILTER_VAL_TRUE: 927 case FILTER_VAL_FALSE: 928 free_arg(arg); 929 arg = allocate_arg(); 930 if (arg) { 931 arg->type = FILTER_ARG_BOOLEAN; 932 arg->boolean.value = ret == FILTER_VAL_TRUE; 933 } else { 934 show_error(error_str, "Failed to allocate filter arg"); 935 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; 936 } 937 break; 938 939 default: 940 /* test_arg() already set the error_str */ 941 free_arg(arg); 942 arg = NULL; 943 break; 944 } 945 946 *arg_collapsed = arg; 947 return ret; 948} 949 950static enum pevent_errno 951process_filter(struct event_format *event, struct filter_arg **parg, 952 char *error_str, int not) 953{ 954 enum event_type type; 955 char *token = NULL; 956 struct filter_arg *current_op = NULL; 957 struct filter_arg *current_exp = NULL; 958 struct filter_arg *left_item = NULL; 959 struct filter_arg *arg = NULL; 960 enum op_type op_type; 961 enum filter_op_type btype; 962 enum filter_exp_type etype; 963 enum filter_cmp_type ctype; 964 enum pevent_errno ret; 965 966 *parg = NULL; 967 968 do { 969 free(token); 970 type = read_token(&token); 971 switch (type) { 972 case EVENT_SQUOTE: 973 case EVENT_DQUOTE: 974 case EVENT_ITEM: 975 ret = create_arg_item(event, token, type, &arg, error_str); 976 if (ret < 0) 977 goto fail; 978 if (!left_item) 979 left_item = arg; 980 else if (current_exp) { 981 ret = add_right(current_exp, arg, error_str); 982 if (ret < 0) 983 goto fail; 984 left_item = NULL; 985 /* Not's only one one expression */ 986 if (not) { 987 arg = NULL; 988 if (current_op) 989 goto fail_syntax; 990 free(token); 991 *parg = current_exp; 992 return 0; 993 } 994 } else 995 goto fail_syntax; 996 arg = NULL; 997 break; 998 999 case EVENT_DELIM: 1000 if (*token == ',') { 1001 show_error(error_str, "Illegal token ','"); 1002 ret = PEVENT_ERRNO__ILLEGAL_TOKEN; 1003 goto fail; 1004 } 1005 1006 if (*token == '(') { 1007 if (left_item) { 1008 show_error(error_str, 1009 "Open paren can not come after item"); 1010 ret = PEVENT_ERRNO__INVALID_PAREN; 1011 goto fail; 1012 } 1013 if (current_exp) { 1014 show_error(error_str, 1015 "Open paren can not come after expression"); 1016 ret = PEVENT_ERRNO__INVALID_PAREN; 1017 goto fail; 1018 } 1019 1020 ret = process_filter(event, &arg, error_str, 0); 1021 if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) { 1022 if (ret == 0) { 1023 show_error(error_str, 1024 "Unbalanced number of '('"); 1025 ret = PEVENT_ERRNO__UNBALANCED_PAREN; 1026 } 1027 goto fail; 1028 } 1029 ret = 0; 1030 1031 /* A not wants just one expression */ 1032 if (not) { 1033 if (current_op) 1034 goto fail_syntax; 1035 *parg = arg; 1036 return 0; 1037 } 1038 1039 if (current_op) 1040 ret = add_right(current_op, arg, error_str); 1041 else 1042 current_exp = arg; 1043 1044 if (ret < 0) 1045 goto fail; 1046 1047 } else { /* ')' */ 1048 if (!current_op && !current_exp) 1049 goto fail_syntax; 1050 1051 /* Make sure everything is finished at this level */ 1052 if (current_exp && !check_op_done(current_exp)) 1053 goto fail_syntax; 1054 if (current_op && !check_op_done(current_op)) 1055 goto fail_syntax; 1056 1057 if (current_op) 1058 *parg = current_op; 1059 else 1060 *parg = current_exp; 1061 free(token); 1062 return PEVENT_ERRNO__UNBALANCED_PAREN; 1063 } 1064 break; 1065 1066 case EVENT_OP: 1067 op_type = process_op(token, &btype, &ctype, &etype); 1068 1069 /* All expect a left arg except for NOT */ 1070 switch (op_type) { 1071 case OP_BOOL: 1072 /* Logic ops need a left expression */ 1073 if (!current_exp && !current_op) 1074 goto fail_syntax; 1075 /* fall through */ 1076 case OP_NOT: 1077 /* logic only processes ops and exp */ 1078 if (left_item) 1079 goto fail_syntax; 1080 break; 1081 case OP_EXP: 1082 case OP_CMP: 1083 if (!left_item) 1084 goto fail_syntax; 1085 break; 1086 case OP_NONE: 1087 show_error(error_str, 1088 "Unknown op token %s", token); 1089 ret = PEVENT_ERRNO__UNKNOWN_TOKEN; 1090 goto fail; 1091 } 1092 1093 ret = 0; 1094 switch (op_type) { 1095 case OP_BOOL: 1096 arg = create_arg_op(btype); 1097 if (arg == NULL) 1098 goto fail_alloc; 1099 if (current_op) 1100 ret = add_left(arg, current_op); 1101 else 1102 ret = add_left(arg, current_exp); 1103 current_op = arg; 1104 current_exp = NULL; 1105 break; 1106 1107 case OP_NOT: 1108 arg = create_arg_op(btype); 1109 if (arg == NULL) 1110 goto fail_alloc; 1111 if (current_op) 1112 ret = add_right(current_op, arg, error_str); 1113 if (ret < 0) 1114 goto fail; 1115 current_exp = arg; 1116 ret = process_filter(event, &arg, error_str, 1); 1117 if (ret < 0) 1118 goto fail; 1119 ret = add_right(current_exp, arg, error_str); 1120 if (ret < 0) 1121 goto fail; 1122 break; 1123 1124 case OP_EXP: 1125 case OP_CMP: 1126 if (op_type == OP_EXP) 1127 arg = create_arg_exp(etype); 1128 else 1129 arg = create_arg_cmp(ctype); 1130 if (arg == NULL) 1131 goto fail_alloc; 1132 1133 if (current_op) 1134 ret = add_right(current_op, arg, error_str); 1135 if (ret < 0) 1136 goto fail; 1137 ret = add_left(arg, left_item); 1138 if (ret < 0) { 1139 arg = NULL; 1140 goto fail_syntax; 1141 } 1142 current_exp = arg; 1143 break; 1144 default: 1145 break; 1146 } 1147 arg = NULL; 1148 if (ret < 0) 1149 goto fail_syntax; 1150 break; 1151 case EVENT_NONE: 1152 break; 1153 case EVENT_ERROR: 1154 goto fail_alloc; 1155 default: 1156 goto fail_syntax; 1157 } 1158 } while (type != EVENT_NONE); 1159 1160 if (!current_op && !current_exp) 1161 goto fail_syntax; 1162 1163 if (!current_op) 1164 current_op = current_exp; 1165 1166 ret = collapse_tree(current_op, parg, error_str); 1167 /* collapse_tree() may free current_op, and updates parg accordingly */ 1168 current_op = NULL; 1169 if (ret < 0) 1170 goto fail; 1171 1172 free(token); 1173 return 0; 1174 1175 fail_alloc: 1176 show_error(error_str, "failed to allocate filter arg"); 1177 ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; 1178 goto fail; 1179 fail_syntax: 1180 show_error(error_str, "Syntax error"); 1181 ret = PEVENT_ERRNO__SYNTAX_ERROR; 1182 fail: 1183 free_arg(current_op); 1184 free_arg(current_exp); 1185 free_arg(arg); 1186 free(token); 1187 return ret; 1188} 1189 1190static enum pevent_errno 1191process_event(struct event_format *event, const char *filter_str, 1192 struct filter_arg **parg, char *error_str) 1193{ 1194 int ret; 1195 1196 pevent_buffer_init(filter_str, strlen(filter_str)); 1197 1198 ret = process_filter(event, parg, error_str, 0); 1199 if (ret < 0) 1200 return ret; 1201 1202 /* If parg is NULL, then make it into FALSE */ 1203 if (!*parg) { 1204 *parg = allocate_arg(); 1205 if (*parg == NULL) 1206 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 1207 1208 (*parg)->type = FILTER_ARG_BOOLEAN; 1209 (*parg)->boolean.value = FILTER_FALSE; 1210 } 1211 1212 return 0; 1213} 1214 1215static enum pevent_errno 1216filter_event(struct event_filter *filter, struct event_format *event, 1217 const char *filter_str, char *error_str) 1218{ 1219 struct filter_type *filter_type; 1220 struct filter_arg *arg; 1221 enum pevent_errno ret; 1222 1223 if (filter_str) { 1224 ret = process_event(event, filter_str, &arg, error_str); 1225 if (ret < 0) 1226 return ret; 1227 1228 } else { 1229 /* just add a TRUE arg */ 1230 arg = allocate_arg(); 1231 if (arg == NULL) 1232 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 1233 1234 arg->type = FILTER_ARG_BOOLEAN; 1235 arg->boolean.value = FILTER_TRUE; 1236 } 1237 1238 filter_type = add_filter_type(filter, event->id); 1239 if (filter_type == NULL) 1240 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 1241 1242 if (filter_type->filter) 1243 free_arg(filter_type->filter); 1244 filter_type->filter = arg; 1245 1246 return 0; 1247} 1248 1249static void filter_init_error_buf(struct event_filter *filter) 1250{ 1251 /* clear buffer to reset show error */ 1252 pevent_buffer_init("", 0); 1253 filter->error_buffer[0] = '\0'; 1254} 1255 1256/** 1257 * pevent_filter_add_filter_str - add a new filter 1258 * @filter: the event filter to add to 1259 * @filter_str: the filter string that contains the filter 1260 * 1261 * Returns 0 if the filter was successfully added or a 1262 * negative error code. Use pevent_filter_strerror() to see 1263 * actual error message in case of error. 1264 */ 1265enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, 1266 const char *filter_str) 1267{ 1268 struct pevent *pevent = filter->pevent; 1269 struct event_list *event; 1270 struct event_list *events = NULL; 1271 const char *filter_start; 1272 const char *next_event; 1273 char *this_event; 1274 char *event_name = NULL; 1275 char *sys_name = NULL; 1276 char *sp; 1277 enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ 1278 int len; 1279 int ret; 1280 1281 filter_init_error_buf(filter); 1282 1283 filter_start = strchr(filter_str, ':'); 1284 if (filter_start) 1285 len = filter_start - filter_str; 1286 else 1287 len = strlen(filter_str); 1288 1289 do { 1290 next_event = strchr(filter_str, ','); 1291 if (next_event && 1292 (!filter_start || next_event < filter_start)) 1293 len = next_event - filter_str; 1294 else if (filter_start) 1295 len = filter_start - filter_str; 1296 else 1297 len = strlen(filter_str); 1298 1299 this_event = malloc(len + 1); 1300 if (this_event == NULL) { 1301 /* This can only happen when events is NULL, but still */ 1302 free_events(events); 1303 return PEVENT_ERRNO__MEM_ALLOC_FAILED; 1304 } 1305 memcpy(this_event, filter_str, len); 1306 this_event[len] = 0; 1307 1308 if (next_event) 1309 next_event++; 1310 1311 filter_str = next_event; 1312 1313 sys_name = strtok_r(this_event, "/", &sp); 1314 event_name = strtok_r(NULL, "/", &sp); 1315 1316 if (!sys_name) { 1317 /* This can only happen when events is NULL, but still */ 1318 free_events(events); 1319 free(this_event); 1320 return PEVENT_ERRNO__FILTER_NOT_FOUND; 1321 } 1322 1323 /* Find this event */ 1324 ret = find_event(pevent, &events, strim(sys_name), strim(event_name)); 1325 if (ret < 0) { 1326 free_events(events); 1327 free(this_event); 1328 return ret; 1329 } 1330 free(this_event); 1331 } while (filter_str); 1332 1333 /* Skip the ':' */ 1334 if (filter_start) 1335 filter_start++; 1336 1337 /* filter starts here */ 1338 for (event = events; event; event = event->next) { 1339 ret = filter_event(filter, event->event, filter_start, 1340 filter->error_buffer); 1341 /* Failures are returned if a parse error happened */ 1342 if (ret < 0) 1343 rtn = ret; 1344 1345 if (ret >= 0 && pevent->test_filters) { 1346 char *test; 1347 test = pevent_filter_make_string(filter, event->event->id); 1348 if (test) { 1349 printf(" '%s: %s'\n", event->event->name, test); 1350 free(test); 1351 } 1352 } 1353 } 1354 1355 free_events(events); 1356 1357 if (rtn >= 0 && pevent->test_filters) 1358 exit(0); 1359 1360 return rtn; 1361} 1362 1363static void free_filter_type(struct filter_type *filter_type) 1364{ 1365 free_arg(filter_type->filter); 1366} 1367 1368/** 1369 * pevent_filter_strerror - fill error message in a buffer 1370 * @filter: the event filter contains error 1371 * @err: the error code 1372 * @buf: the buffer to be filled in 1373 * @buflen: the size of the buffer 1374 * 1375 * Returns 0 if message was filled successfully, -1 if error 1376 */ 1377int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, 1378 char *buf, size_t buflen) 1379{ 1380 if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END) 1381 return -1; 1382 1383 if (strlen(filter->error_buffer) > 0) { 1384 size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); 1385 1386 if (len > buflen) 1387 return -1; 1388 return 0; 1389 } 1390 1391 return pevent_strerror(filter->pevent, err, buf, buflen); 1392} 1393 1394/** 1395 * pevent_filter_remove_event - remove a filter for an event 1396 * @filter: the event filter to remove from 1397 * @event_id: the event to remove a filter for 1398 * 1399 * Removes the filter saved for an event defined by @event_id 1400 * from the @filter. 1401 * 1402 * Returns 1: if an event was removed 1403 * 0: if the event was not found 1404 */ 1405int pevent_filter_remove_event(struct event_filter *filter, 1406 int event_id) 1407{ 1408 struct filter_type *filter_type; 1409 unsigned long len; 1410 1411 if (!filter->filters) 1412 return 0; 1413 1414 filter_type = find_filter_type(filter, event_id); 1415 1416 if (!filter_type) 1417 return 0; 1418 1419 free_filter_type(filter_type); 1420 1421 /* The filter_type points into the event_filters array */ 1422 len = (unsigned long)(filter->event_filters + filter->filters) - 1423 (unsigned long)(filter_type + 1); 1424 1425 memmove(filter_type, filter_type + 1, len); 1426 filter->filters--; 1427 1428 memset(&filter->event_filters[filter->filters], 0, 1429 sizeof(*filter_type)); 1430 1431 return 1; 1432} 1433 1434/** 1435 * pevent_filter_reset - clear all filters in a filter 1436 * @filter: the event filter to reset 1437 * 1438 * Removes all filters from a filter and resets it. 1439 */ 1440void pevent_filter_reset(struct event_filter *filter) 1441{ 1442 int i; 1443 1444 for (i = 0; i < filter->filters; i++) 1445 free_filter_type(&filter->event_filters[i]); 1446 1447 free(filter->event_filters); 1448 filter->filters = 0; 1449 filter->event_filters = NULL; 1450} 1451 1452void pevent_filter_free(struct event_filter *filter) 1453{ 1454 pevent_unref(filter->pevent); 1455 1456 pevent_filter_reset(filter); 1457 1458 free(filter); 1459} 1460 1461static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg); 1462 1463static int copy_filter_type(struct event_filter *filter, 1464 struct event_filter *source, 1465 struct filter_type *filter_type) 1466{ 1467 struct filter_arg *arg; 1468 struct event_format *event; 1469 const char *sys; 1470 const char *name; 1471 char *str; 1472 1473 /* Can't assume that the pevent's are the same */ 1474 sys = filter_type->event->system; 1475 name = filter_type->event->name; 1476 event = pevent_find_event_by_name(filter->pevent, sys, name); 1477 if (!event) 1478 return -1; 1479 1480 str = arg_to_str(source, filter_type->filter); 1481 if (!str) 1482 return -1; 1483 1484 if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { 1485 /* Add trivial event */ 1486 arg = allocate_arg(); 1487 if (arg == NULL) 1488 return -1; 1489 1490 arg->type = FILTER_ARG_BOOLEAN; 1491 if (strcmp(str, "TRUE") == 0) 1492 arg->boolean.value = 1; 1493 else 1494 arg->boolean.value = 0; 1495 1496 filter_type = add_filter_type(filter, event->id); 1497 if (filter_type == NULL) 1498 return -1; 1499 1500 filter_type->filter = arg; 1501 1502 free(str); 1503 return 0; 1504 } 1505 1506 filter_event(filter, event, str, NULL); 1507 free(str); 1508 1509 return 0; 1510} 1511 1512/** 1513 * pevent_filter_copy - copy a filter using another filter 1514 * @dest - the filter to copy to 1515 * @source - the filter to copy from 1516 * 1517 * Returns 0 on success and -1 if not all filters were copied 1518 */ 1519int pevent_filter_copy(struct event_filter *dest, struct event_filter *source) 1520{ 1521 int ret = 0; 1522 int i; 1523 1524 pevent_filter_reset(dest); 1525 1526 for (i = 0; i < source->filters; i++) { 1527 if (copy_filter_type(dest, source, &source->event_filters[i])) 1528 ret = -1; 1529 } 1530 return ret; 1531} 1532 1533 1534/** 1535 * pevent_update_trivial - update the trivial filters with the given filter 1536 * @dest - the filter to update 1537 * @source - the filter as the source of the update 1538 * @type - the type of trivial filter to update. 1539 * 1540 * Scan dest for trivial events matching @type to replace with the source. 1541 * 1542 * Returns 0 on success and -1 if there was a problem updating, but 1543 * events may have still been updated on error. 1544 */ 1545int pevent_update_trivial(struct event_filter *dest, struct event_filter *source, 1546 enum filter_trivial_type type) 1547{ 1548 struct pevent *src_pevent; 1549 struct pevent *dest_pevent; 1550 struct event_format *event; 1551 struct filter_type *filter_type; 1552 struct filter_arg *arg; 1553 char *str; 1554 int i; 1555 1556 src_pevent = source->pevent; 1557 dest_pevent = dest->pevent; 1558 1559 /* Do nothing if either of the filters has nothing to filter */ 1560 if (!dest->filters || !source->filters) 1561 return 0; 1562 1563 for (i = 0; i < dest->filters; i++) { 1564 filter_type = &dest->event_filters[i]; 1565 arg = filter_type->filter; 1566 if (arg->type != FILTER_ARG_BOOLEAN) 1567 continue; 1568 if ((arg->boolean.value && type == FILTER_TRIVIAL_FALSE) || 1569 (!arg->boolean.value && type == FILTER_TRIVIAL_TRUE)) 1570 continue; 1571 1572 event = filter_type->event; 1573 1574 if (src_pevent != dest_pevent) { 1575 /* do a look up */ 1576 event = pevent_find_event_by_name(src_pevent, 1577 event->system, 1578 event->name); 1579 if (!event) 1580 return -1; 1581 } 1582 1583 str = pevent_filter_make_string(source, event->id); 1584 if (!str) 1585 continue; 1586 1587 /* Don't bother if the filter is trivial too */ 1588 if (strcmp(str, "TRUE") != 0 && strcmp(str, "FALSE") != 0) 1589 filter_event(dest, event, str, NULL); 1590 free(str); 1591 } 1592 return 0; 1593} 1594 1595/** 1596 * pevent_filter_clear_trivial - clear TRUE and FALSE filters 1597 * @filter: the filter to remove trivial filters from 1598 * @type: remove only true, false, or both 1599 * 1600 * Removes filters that only contain a TRUE or FALES boolean arg. 1601 * 1602 * Returns 0 on success and -1 if there was a problem. 1603 */ 1604int pevent_filter_clear_trivial(struct event_filter *filter, 1605 enum filter_trivial_type type) 1606{ 1607 struct filter_type *filter_type; 1608 int count = 0; 1609 int *ids = NULL; 1610 int i; 1611 1612 if (!filter->filters) 1613 return 0; 1614 1615 /* 1616 * Two steps, first get all ids with trivial filters. 1617 * then remove those ids. 1618 */ 1619 for (i = 0; i < filter->filters; i++) { 1620 int *new_ids; 1621 1622 filter_type = &filter->event_filters[i]; 1623 if (filter_type->filter->type != FILTER_ARG_BOOLEAN) 1624 continue; 1625 switch (type) { 1626 case FILTER_TRIVIAL_FALSE: 1627 if (filter_type->filter->boolean.value) 1628 continue; 1629 case FILTER_TRIVIAL_TRUE: 1630 if (!filter_type->filter->boolean.value) 1631 continue; 1632 default: 1633 break; 1634 } 1635 1636 new_ids = realloc(ids, sizeof(*ids) * (count + 1)); 1637 if (!new_ids) { 1638 free(ids); 1639 return -1; 1640 } 1641 1642 ids = new_ids; 1643 ids[count++] = filter_type->event_id; 1644 } 1645 1646 if (!count) 1647 return 0; 1648 1649 for (i = 0; i < count; i++) 1650 pevent_filter_remove_event(filter, ids[i]); 1651 1652 free(ids); 1653 return 0; 1654} 1655 1656/** 1657 * pevent_filter_event_has_trivial - return true event contains trivial filter 1658 * @filter: the filter with the information 1659 * @event_id: the id of the event to test 1660 * @type: trivial type to test for (TRUE, FALSE, EITHER) 1661 * 1662 * Returns 1 if the event contains a matching trivial type 1663 * otherwise 0. 1664 */ 1665int pevent_filter_event_has_trivial(struct event_filter *filter, 1666 int event_id, 1667 enum filter_trivial_type type) 1668{ 1669 struct filter_type *filter_type; 1670 1671 if (!filter->filters) 1672 return 0; 1673 1674 filter_type = find_filter_type(filter, event_id); 1675 1676 if (!filter_type) 1677 return 0; 1678 1679 if (filter_type->filter->type != FILTER_ARG_BOOLEAN) 1680 return 0; 1681 1682 switch (type) { 1683 case FILTER_TRIVIAL_FALSE: 1684 return !filter_type->filter->boolean.value; 1685 1686 case FILTER_TRIVIAL_TRUE: 1687 return filter_type->filter->boolean.value; 1688 default: 1689 return 1; 1690 } 1691} 1692 1693static int test_filter(struct event_format *event, struct filter_arg *arg, 1694 struct pevent_record *record, enum pevent_errno *err); 1695 1696static const char * 1697get_comm(struct event_format *event, struct pevent_record *record) 1698{ 1699 const char *comm; 1700 int pid; 1701 1702 pid = pevent_data_pid(event->pevent, record); 1703 comm = pevent_data_comm_from_pid(event->pevent, pid); 1704 return comm; 1705} 1706 1707static unsigned long long 1708get_value(struct event_format *event, 1709 struct format_field *field, struct pevent_record *record) 1710{ 1711 unsigned long long val; 1712 1713 /* Handle our dummy "comm" field */ 1714 if (field == &comm) { 1715 const char *name; 1716 1717 name = get_comm(event, record); 1718 return (unsigned long)name; 1719 } 1720 1721 pevent_read_number_field(field, record->data, &val); 1722 1723 if (!(field->flags & FIELD_IS_SIGNED)) 1724 return val; 1725 1726 switch (field->size) { 1727 case 1: 1728 return (char)val; 1729 case 2: 1730 return (short)val; 1731 case 4: 1732 return (int)val; 1733 case 8: 1734 return (long long)val; 1735 } 1736 return val; 1737} 1738 1739static unsigned long long 1740get_arg_value(struct event_format *event, struct filter_arg *arg, 1741 struct pevent_record *record, enum pevent_errno *err); 1742 1743static unsigned long long 1744get_exp_value(struct event_format *event, struct filter_arg *arg, 1745 struct pevent_record *record, enum pevent_errno *err) 1746{ 1747 unsigned long long lval, rval; 1748 1749 lval = get_arg_value(event, arg->exp.left, record, err); 1750 rval = get_arg_value(event, arg->exp.right, record, err); 1751 1752 if (*err) { 1753 /* 1754 * There was an error, no need to process anymore. 1755 */ 1756 return 0; 1757 } 1758 1759 switch (arg->exp.type) { 1760 case FILTER_EXP_ADD: 1761 return lval + rval; 1762 1763 case FILTER_EXP_SUB: 1764 return lval - rval; 1765 1766 case FILTER_EXP_MUL: 1767 return lval * rval; 1768 1769 case FILTER_EXP_DIV: 1770 return lval / rval; 1771 1772 case FILTER_EXP_MOD: 1773 return lval % rval; 1774 1775 case FILTER_EXP_RSHIFT: 1776 return lval >> rval; 1777 1778 case FILTER_EXP_LSHIFT: 1779 return lval << rval; 1780 1781 case FILTER_EXP_AND: 1782 return lval & rval; 1783 1784 case FILTER_EXP_OR: 1785 return lval | rval; 1786 1787 case FILTER_EXP_XOR: 1788 return lval ^ rval; 1789 1790 case FILTER_EXP_NOT: 1791 default: 1792 if (!*err) 1793 *err = PEVENT_ERRNO__INVALID_EXP_TYPE; 1794 } 1795 return 0; 1796} 1797 1798static unsigned long long 1799get_arg_value(struct event_format *event, struct filter_arg *arg, 1800 struct pevent_record *record, enum pevent_errno *err) 1801{ 1802 switch (arg->type) { 1803 case FILTER_ARG_FIELD: 1804 return get_value(event, arg->field.field, record); 1805 1806 case FILTER_ARG_VALUE: 1807 if (arg->value.type != FILTER_NUMBER) { 1808 if (!*err) 1809 *err = PEVENT_ERRNO__NOT_A_NUMBER; 1810 } 1811 return arg->value.val; 1812 1813 case FILTER_ARG_EXP: 1814 return get_exp_value(event, arg, record, err); 1815 1816 default: 1817 if (!*err) 1818 *err = PEVENT_ERRNO__INVALID_ARG_TYPE; 1819 } 1820 return 0; 1821} 1822 1823static int test_num(struct event_format *event, struct filter_arg *arg, 1824 struct pevent_record *record, enum pevent_errno *err) 1825{ 1826 unsigned long long lval, rval; 1827 1828 lval = get_arg_value(event, arg->num.left, record, err); 1829 rval = get_arg_value(event, arg->num.right, record, err); 1830 1831 if (*err) { 1832 /* 1833 * There was an error, no need to process anymore. 1834 */ 1835 return 0; 1836 } 1837 1838 switch (arg->num.type) { 1839 case FILTER_CMP_EQ: 1840 return lval == rval; 1841 1842 case FILTER_CMP_NE: 1843 return lval != rval; 1844 1845 case FILTER_CMP_GT: 1846 return lval > rval; 1847 1848 case FILTER_CMP_LT: 1849 return lval < rval; 1850 1851 case FILTER_CMP_GE: 1852 return lval >= rval; 1853 1854 case FILTER_CMP_LE: 1855 return lval <= rval; 1856 1857 default: 1858 if (!*err) 1859 *err = PEVENT_ERRNO__ILLEGAL_INTEGER_CMP; 1860 return 0; 1861 } 1862} 1863 1864static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) 1865{ 1866 struct event_format *event; 1867 struct pevent *pevent; 1868 unsigned long long addr; 1869 const char *val = NULL; 1870 char hex[64]; 1871 1872 /* If the field is not a string convert it */ 1873 if (arg->str.field->flags & FIELD_IS_STRING) { 1874 val = record->data + arg->str.field->offset; 1875 1876 /* 1877 * We need to copy the data since we can't be sure the field 1878 * is null terminated. 1879 */ 1880 if (*(val + arg->str.field->size - 1)) { 1881 /* copy it */ 1882 memcpy(arg->str.buffer, val, arg->str.field->size); 1883 /* the buffer is already NULL terminated */ 1884 val = arg->str.buffer; 1885 } 1886 1887 } else { 1888 event = arg->str.field->event; 1889 pevent = event->pevent; 1890 addr = get_value(event, arg->str.field, record); 1891 1892 if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG)) 1893 /* convert to a kernel symbol */ 1894 val = pevent_find_function(pevent, addr); 1895 1896 if (val == NULL) { 1897 /* just use the hex of the string name */ 1898 snprintf(hex, 64, "0x%llx", addr); 1899 val = hex; 1900 } 1901 } 1902 1903 return val; 1904} 1905 1906static int test_str(struct event_format *event, struct filter_arg *arg, 1907 struct pevent_record *record, enum pevent_errno *err) 1908{ 1909 const char *val; 1910 1911 if (arg->str.field == &comm) 1912 val = get_comm(event, record); 1913 else 1914 val = get_field_str(arg, record); 1915 1916 switch (arg->str.type) { 1917 case FILTER_CMP_MATCH: 1918 return strcmp(val, arg->str.val) == 0; 1919 1920 case FILTER_CMP_NOT_MATCH: 1921 return strcmp(val, arg->str.val) != 0; 1922 1923 case FILTER_CMP_REGEX: 1924 /* Returns zero on match */ 1925 return !regexec(&arg->str.reg, val, 0, NULL, 0); 1926 1927 case FILTER_CMP_NOT_REGEX: 1928 return regexec(&arg->str.reg, val, 0, NULL, 0); 1929 1930 default: 1931 if (!*err) 1932 *err = PEVENT_ERRNO__ILLEGAL_STRING_CMP; 1933 return 0; 1934 } 1935} 1936 1937static int test_op(struct event_format *event, struct filter_arg *arg, 1938 struct pevent_record *record, enum pevent_errno *err) 1939{ 1940 switch (arg->op.type) { 1941 case FILTER_OP_AND: 1942 return test_filter(event, arg->op.left, record, err) && 1943 test_filter(event, arg->op.right, record, err); 1944 1945 case FILTER_OP_OR: 1946 return test_filter(event, arg->op.left, record, err) || 1947 test_filter(event, arg->op.right, record, err); 1948 1949 case FILTER_OP_NOT: 1950 return !test_filter(event, arg->op.right, record, err); 1951 1952 default: 1953 if (!*err) 1954 *err = PEVENT_ERRNO__INVALID_OP_TYPE; 1955 return 0; 1956 } 1957} 1958 1959static int test_filter(struct event_format *event, struct filter_arg *arg, 1960 struct pevent_record *record, enum pevent_errno *err) 1961{ 1962 if (*err) { 1963 /* 1964 * There was an error, no need to process anymore. 1965 */ 1966 return 0; 1967 } 1968 1969 switch (arg->type) { 1970 case FILTER_ARG_BOOLEAN: 1971 /* easy case */ 1972 return arg->boolean.value; 1973 1974 case FILTER_ARG_OP: 1975 return test_op(event, arg, record, err); 1976 1977 case FILTER_ARG_NUM: 1978 return test_num(event, arg, record, err); 1979 1980 case FILTER_ARG_STR: 1981 return test_str(event, arg, record, err); 1982 1983 case FILTER_ARG_EXP: 1984 case FILTER_ARG_VALUE: 1985 case FILTER_ARG_FIELD: 1986 /* 1987 * Expressions, fields and values evaluate 1988 * to true if they return non zero 1989 */ 1990 return !!get_arg_value(event, arg, record, err); 1991 1992 default: 1993 if (!*err) 1994 *err = PEVENT_ERRNO__INVALID_ARG_TYPE; 1995 return 0; 1996 } 1997} 1998 1999/** 2000 * pevent_event_filtered - return true if event has filter 2001 * @filter: filter struct with filter information 2002 * @event_id: event id to test if filter exists 2003 * 2004 * Returns 1 if filter found for @event_id 2005 * otherwise 0; 2006 */ 2007int pevent_event_filtered(struct event_filter *filter, int event_id) 2008{ 2009 struct filter_type *filter_type; 2010 2011 if (!filter->filters) 2012 return 0; 2013 2014 filter_type = find_filter_type(filter, event_id); 2015 2016 return filter_type ? 1 : 0; 2017} 2018 2019/** 2020 * pevent_filter_match - test if a record matches a filter 2021 * @filter: filter struct with filter information 2022 * @record: the record to test against the filter 2023 * 2024 * Returns: match result or error code (prefixed with PEVENT_ERRNO__) 2025 * FILTER_MATCH - filter found for event and @record matches 2026 * FILTER_MISS - filter found for event and @record does not match 2027 * FILTER_NOT_FOUND - no filter found for @record's event 2028 * NO_FILTER - if no filters exist 2029 * otherwise - error occurred during test 2030 */ 2031enum pevent_errno pevent_filter_match(struct event_filter *filter, 2032 struct pevent_record *record) 2033{ 2034 struct pevent *pevent = filter->pevent; 2035 struct filter_type *filter_type; 2036 int event_id; 2037 int ret; 2038 enum pevent_errno err = 0; 2039 2040 filter_init_error_buf(filter); 2041 2042 if (!filter->filters) 2043 return PEVENT_ERRNO__NO_FILTER; 2044 2045 event_id = pevent_data_type(pevent, record); 2046 2047 filter_type = find_filter_type(filter, event_id); 2048 if (!filter_type) 2049 return PEVENT_ERRNO__FILTER_NOT_FOUND; 2050 2051 ret = test_filter(filter_type->event, filter_type->filter, record, &err); 2052 if (err) 2053 return err; 2054 2055 return ret ? PEVENT_ERRNO__FILTER_MATCH : PEVENT_ERRNO__FILTER_MISS; 2056} 2057 2058static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) 2059{ 2060 char *str = NULL; 2061 char *left = NULL; 2062 char *right = NULL; 2063 char *op = NULL; 2064 int left_val = -1; 2065 int right_val = -1; 2066 int val; 2067 2068 switch (arg->op.type) { 2069 case FILTER_OP_AND: 2070 op = "&&"; 2071 /* fall through */ 2072 case FILTER_OP_OR: 2073 if (!op) 2074 op = "||"; 2075 2076 left = arg_to_str(filter, arg->op.left); 2077 right = arg_to_str(filter, arg->op.right); 2078 if (!left || !right) 2079 break; 2080 2081 /* Try to consolidate boolean values */ 2082 if (strcmp(left, "TRUE") == 0) 2083 left_val = 1; 2084 else if (strcmp(left, "FALSE") == 0) 2085 left_val = 0; 2086 2087 if (strcmp(right, "TRUE") == 0) 2088 right_val = 1; 2089 else if (strcmp(right, "FALSE") == 0) 2090 right_val = 0; 2091 2092 if (left_val >= 0) { 2093 if ((arg->op.type == FILTER_OP_AND && !left_val) || 2094 (arg->op.type == FILTER_OP_OR && left_val)) { 2095 /* Just return left value */ 2096 str = left; 2097 left = NULL; 2098 break; 2099 } 2100 if (right_val >= 0) { 2101 /* just evaluate this. */ 2102 val = 0; 2103 switch (arg->op.type) { 2104 case FILTER_OP_AND: 2105 val = left_val && right_val; 2106 break; 2107 case FILTER_OP_OR: 2108 val = left_val || right_val; 2109 break; 2110 default: 2111 break; 2112 } 2113 asprintf(&str, val ? "TRUE" : "FALSE"); 2114 break; 2115 } 2116 } 2117 if (right_val >= 0) { 2118 if ((arg->op.type == FILTER_OP_AND && !right_val) || 2119 (arg->op.type == FILTER_OP_OR && right_val)) { 2120 /* Just return right value */ 2121 str = right; 2122 right = NULL; 2123 break; 2124 } 2125 /* The right value is meaningless */ 2126 str = left; 2127 left = NULL; 2128 break; 2129 } 2130 2131 asprintf(&str, "(%s) %s (%s)", left, op, right); 2132 break; 2133 2134 case FILTER_OP_NOT: 2135 op = "!"; 2136 right = arg_to_str(filter, arg->op.right); 2137 if (!right) 2138 break; 2139 2140 /* See if we can consolidate */ 2141 if (strcmp(right, "TRUE") == 0) 2142 right_val = 1; 2143 else if (strcmp(right, "FALSE") == 0) 2144 right_val = 0; 2145 if (right_val >= 0) { 2146 /* just return the opposite */ 2147 asprintf(&str, right_val ? "FALSE" : "TRUE"); 2148 break; 2149 } 2150 asprintf(&str, "%s(%s)", op, right); 2151 break; 2152 2153 default: 2154 /* ?? */ 2155 break; 2156 } 2157 free(left); 2158 free(right); 2159 return str; 2160} 2161 2162static char *val_to_str(struct event_filter *filter, struct filter_arg *arg) 2163{ 2164 char *str = NULL; 2165 2166 asprintf(&str, "%lld", arg->value.val); 2167 2168 return str; 2169} 2170 2171static char *field_to_str(struct event_filter *filter, struct filter_arg *arg) 2172{ 2173 return strdup(arg->field.field->name); 2174} 2175 2176static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) 2177{ 2178 char *lstr; 2179 char *rstr; 2180 char *op; 2181 char *str = NULL; 2182 2183 lstr = arg_to_str(filter, arg->exp.left); 2184 rstr = arg_to_str(filter, arg->exp.right); 2185 if (!lstr || !rstr) 2186 goto out; 2187 2188 switch (arg->exp.type) { 2189 case FILTER_EXP_ADD: 2190 op = "+"; 2191 break; 2192 case FILTER_EXP_SUB: 2193 op = "-"; 2194 break; 2195 case FILTER_EXP_MUL: 2196 op = "*"; 2197 break; 2198 case FILTER_EXP_DIV: 2199 op = "/"; 2200 break; 2201 case FILTER_EXP_MOD: 2202 op = "%"; 2203 break; 2204 case FILTER_EXP_RSHIFT: 2205 op = ">>"; 2206 break; 2207 case FILTER_EXP_LSHIFT: 2208 op = "<<"; 2209 break; 2210 case FILTER_EXP_AND: 2211 op = "&"; 2212 break; 2213 case FILTER_EXP_OR: 2214 op = "|"; 2215 break; 2216 case FILTER_EXP_XOR: 2217 op = "^"; 2218 break; 2219 default: 2220 op = "[ERROR IN EXPRESSION TYPE]"; 2221 break; 2222 } 2223 2224 asprintf(&str, "%s %s %s", lstr, op, rstr); 2225out: 2226 free(lstr); 2227 free(rstr); 2228 2229 return str; 2230} 2231 2232static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) 2233{ 2234 char *lstr; 2235 char *rstr; 2236 char *str = NULL; 2237 char *op = NULL; 2238 2239 lstr = arg_to_str(filter, arg->num.left); 2240 rstr = arg_to_str(filter, arg->num.right); 2241 if (!lstr || !rstr) 2242 goto out; 2243 2244 switch (arg->num.type) { 2245 case FILTER_CMP_EQ: 2246 op = "=="; 2247 /* fall through */ 2248 case FILTER_CMP_NE: 2249 if (!op) 2250 op = "!="; 2251 /* fall through */ 2252 case FILTER_CMP_GT: 2253 if (!op) 2254 op = ">"; 2255 /* fall through */ 2256 case FILTER_CMP_LT: 2257 if (!op) 2258 op = "<"; 2259 /* fall through */ 2260 case FILTER_CMP_GE: 2261 if (!op) 2262 op = ">="; 2263 /* fall through */ 2264 case FILTER_CMP_LE: 2265 if (!op) 2266 op = "<="; 2267 2268 asprintf(&str, "%s %s %s", lstr, op, rstr); 2269 break; 2270 2271 default: 2272 /* ?? */ 2273 break; 2274 } 2275 2276out: 2277 free(lstr); 2278 free(rstr); 2279 return str; 2280} 2281 2282static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) 2283{ 2284 char *str = NULL; 2285 char *op = NULL; 2286 2287 switch (arg->str.type) { 2288 case FILTER_CMP_MATCH: 2289 op = "=="; 2290 /* fall through */ 2291 case FILTER_CMP_NOT_MATCH: 2292 if (!op) 2293 op = "!="; 2294 /* fall through */ 2295 case FILTER_CMP_REGEX: 2296 if (!op) 2297 op = "=~"; 2298 /* fall through */ 2299 case FILTER_CMP_NOT_REGEX: 2300 if (!op) 2301 op = "!~"; 2302 2303 asprintf(&str, "%s %s \"%s\"", 2304 arg->str.field->name, op, arg->str.val); 2305 break; 2306 2307 default: 2308 /* ?? */ 2309 break; 2310 } 2311 return str; 2312} 2313 2314static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) 2315{ 2316 char *str = NULL; 2317 2318 switch (arg->type) { 2319 case FILTER_ARG_BOOLEAN: 2320 asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE"); 2321 return str; 2322 2323 case FILTER_ARG_OP: 2324 return op_to_str(filter, arg); 2325 2326 case FILTER_ARG_NUM: 2327 return num_to_str(filter, arg); 2328 2329 case FILTER_ARG_STR: 2330 return str_to_str(filter, arg); 2331 2332 case FILTER_ARG_VALUE: 2333 return val_to_str(filter, arg); 2334 2335 case FILTER_ARG_FIELD: 2336 return field_to_str(filter, arg); 2337 2338 case FILTER_ARG_EXP: 2339 return exp_to_str(filter, arg); 2340 2341 default: 2342 /* ?? */ 2343 return NULL; 2344 } 2345 2346} 2347 2348/** 2349 * pevent_filter_make_string - return a string showing the filter 2350 * @filter: filter struct with filter information 2351 * @event_id: the event id to return the filter string with 2352 * 2353 * Returns a string that displays the filter contents. 2354 * This string must be freed with free(str). 2355 * NULL is returned if no filter is found or allocation failed. 2356 */ 2357char * 2358pevent_filter_make_string(struct event_filter *filter, int event_id) 2359{ 2360 struct filter_type *filter_type; 2361 2362 if (!filter->filters) 2363 return NULL; 2364 2365 filter_type = find_filter_type(filter, event_id); 2366 2367 if (!filter_type) 2368 return NULL; 2369 2370 return arg_to_str(filter, filter_type->filter); 2371} 2372 2373/** 2374 * pevent_filter_compare - compare two filters and return if they are the same 2375 * @filter1: Filter to compare with @filter2 2376 * @filter2: Filter to compare with @filter1 2377 * 2378 * Returns: 2379 * 1 if the two filters hold the same content. 2380 * 0 if they do not. 2381 */ 2382int pevent_filter_compare(struct event_filter *filter1, struct event_filter *filter2) 2383{ 2384 struct filter_type *filter_type1; 2385 struct filter_type *filter_type2; 2386 char *str1, *str2; 2387 int result; 2388 int i; 2389 2390 /* Do the easy checks first */ 2391 if (filter1->filters != filter2->filters) 2392 return 0; 2393 if (!filter1->filters && !filter2->filters) 2394 return 1; 2395 2396 /* 2397 * Now take a look at each of the events to see if they have the same 2398 * filters to them. 2399 */ 2400 for (i = 0; i < filter1->filters; i++) { 2401 filter_type1 = &filter1->event_filters[i]; 2402 filter_type2 = find_filter_type(filter2, filter_type1->event_id); 2403 if (!filter_type2) 2404 break; 2405 if (filter_type1->filter->type != filter_type2->filter->type) 2406 break; 2407 switch (filter_type1->filter->type) { 2408 case FILTER_TRIVIAL_FALSE: 2409 case FILTER_TRIVIAL_TRUE: 2410 /* trivial types just need the type compared */ 2411 continue; 2412 default: 2413 break; 2414 } 2415 /* The best way to compare complex filters is with strings */ 2416 str1 = arg_to_str(filter1, filter_type1->filter); 2417 str2 = arg_to_str(filter2, filter_type2->filter); 2418 if (str1 && str2) 2419 result = strcmp(str1, str2) != 0; 2420 else 2421 /* bail out if allocation fails */ 2422 result = 1; 2423 2424 free(str1); 2425 free(str2); 2426 if (result) 2427 break; 2428 } 2429 2430 if (i < filter1->filters) 2431 return 0; 2432 return 1; 2433} 2434 2435