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