00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "libts.h"
00030
00031 #include "Error.h"
00032 #include "LogUtils.h"
00033 #include "LogFilter.h"
00034 #include "LogField.h"
00035 #include "LogFormat.h"
00036 #include "LogFile.h"
00037 #include "LogBuffer.h"
00038 #include "LogHost.h"
00039 #include "LogObject.h"
00040 #include "LogConfig.h"
00041 #include "Log.h"
00042
00043 #include "SimpleTokenizer.h"
00044
00045 const char *LogFilter::OPERATOR_NAME[] = { "MATCH", "CASE_INSENSITIVE_MATCH","CONTAIN", "CASE_INSENSITIVE_CONTAIN" };
00046 const char *LogFilter::ACTION_NAME[] = { "REJECT", "ACCEPT", "WIPE_FIELD_VALUE" };
00047
00048
00049
00050
00051
00052
00053
00054
00055 LogFilter::LogFilter(const char *name, LogField * field, LogFilter::Action action, LogFilter::Operator oper)
00056 : m_name(ats_strdup(name)), m_field(NULL) , m_action(action), m_operator(oper), m_type(INT_FILTER), m_num_values(0)
00057 {
00058 m_field = new LogField(*field);
00059 ink_assert(m_field);
00060 }
00061
00062
00063
00064
00065 LogFilter::~LogFilter()
00066 {
00067 ats_free(m_name);
00068 delete m_field;
00069 }
00070
00071
00072
00073
00074
00075 void
00076 LogFilterString::_setValues(size_t n, char **value)
00077 {
00078 m_type = STRING_FILTER;
00079 m_num_values = n;
00080 if (n) {
00081 m_value = new char *[n];
00082 m_value_uppercase = new char *[n];
00083 m_length = new size_t[n];
00084 ink_assert(m_value && m_value_uppercase && m_length);
00085 for (size_t i = 0; i < n; ++i) {
00086 m_value[i] = ats_strdup(value[i]);
00087 m_length[i] = strlen(value[i]);
00088 m_value_uppercase[i] = (char *)ats_malloc((unsigned int) m_length[i] + 1);
00089 size_t j;
00090 for (j = 0; j < m_length[i]; ++j) {
00091 m_value_uppercase[i][j] = ParseRules::ink_toupper(m_value[i][j]);
00092 }
00093 m_value_uppercase[i][j] = 0;
00094 }
00095 }
00096 }
00097
00098
00099 LogFilterString::LogFilterString(const char *name, LogField * field,
00100 LogFilter::Action action, LogFilter::Operator oper, char *values)
00101 : LogFilter(name, field, action, oper)
00102 {
00103
00104
00105 char **val_array = 0;
00106 size_t i = 0;
00107 SimpleTokenizer tok(values, ',');
00108 size_t n = tok.getNumTokensRemaining();
00109 if (n) {
00110 val_array = new char *[n];
00111 char *t;
00112 while (t = tok.getNext(), t != NULL) {
00113 val_array[i++] = t;
00114 }
00115 if (i < n) {
00116 Warning("There were invalid values in the definition of filter %s"
00117 "only %zu out of %zu values will be used", name, i, n);
00118 }
00119 }
00120 _setValues(i, val_array);
00121 delete[]val_array;
00122 }
00123
00124 LogFilterString::LogFilterString(const char *name, LogField * field,
00125 LogFilter::Action action, LogFilter::Operator oper, size_t num_values, char **value)
00126 : LogFilter(name, field, action, oper)
00127 {
00128 _setValues(num_values, value);
00129 }
00130
00131 LogFilterString::LogFilterString(const LogFilterString & rhs)
00132 : LogFilter(rhs.m_name, rhs.m_field, rhs.m_action, rhs.m_operator)
00133 {
00134 _setValues(rhs.m_num_values, rhs.m_value);
00135 }
00136
00137
00138
00139
00140
00141 LogFilterString::~LogFilterString()
00142 {
00143 if (m_num_values > 0) {
00144 for (size_t i = 0; i < m_num_values; ++i) {
00145 ats_free(m_value[i]);
00146 ats_free(m_value_uppercase[i]);
00147 }
00148 delete[]m_value;
00149 delete[]m_value_uppercase;
00150 delete[]m_length;
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 bool
00165 LogFilterString::operator==(LogFilterString & rhs)
00166 {
00167 if (m_type == rhs.m_type &&
00168 *m_field == *rhs.m_field &&
00169 m_action == rhs.m_action &&
00170 m_operator == rhs.m_operator &&
00171 m_num_values == rhs.m_num_values) {
00172 for (size_t i = 0; i < m_num_values; i++) {
00173 if (m_length[i] != rhs.m_length[i] ||
00174 strncmp(m_value[i], rhs.m_value[i], m_length[i])) {
00175 return false;
00176 }
00177 }
00178 return true;
00179 }
00180 return false;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 bool
00196 LogFilterString::wipe_this_entry(LogAccess * lad)
00197 {
00198 if (m_num_values == 0 || m_field == NULL || lad == NULL || m_action != WIPE_FIELD_VALUE) {
00199 return false;
00200 }
00201
00202 static const unsigned BUFSIZE = 1024;
00203 char small_buf[BUFSIZE];
00204 char *big_buf = NULL;
00205 char *buf = small_buf;
00206 size_t marsh_len = m_field->marshal_len(lad);
00207
00208 if (marsh_len > BUFSIZE) {
00209 big_buf = (char *)ats_malloc(marsh_len);
00210 ink_assert(big_buf != NULL);
00211 buf = big_buf;
00212 }
00213
00214 ink_assert(buf != NULL);
00215 m_field->marshal(lad, buf);
00216
00217 ink_assert(buf != NULL);
00218
00219 bool cond_satisfied = false;
00220 switch (m_operator) {
00221 case MATCH:
00222
00223
00224
00225
00226
00227
00228
00229
00230 cond_satisfied = _checkConditionAndWipe(&strcmp, &buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00231 break;
00232 case CASE_INSENSITIVE_MATCH:
00233 cond_satisfied = _checkConditionAndWipe(&strcasecmp, &buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00234 break;
00235 case CONTAIN:
00236 cond_satisfied = _checkConditionAndWipe(&_isSubstring, &buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00237 break;
00238 case CASE_INSENSITIVE_CONTAIN:
00239 for (size_t i = 0; i < marsh_len; i++) {
00240 buf[i] = ParseRules::ink_toupper(buf[i]);
00241 }
00242 cond_satisfied = _checkConditionAndWipe(&_isSubstring, &buf, marsh_len, m_value_uppercase, DATA_LENGTH_LARGER);
00243 break;
00244 default:
00245 ink_assert(!"INVALID FILTER OPERATOR");
00246 }
00247
00248 m_field->updateField(lad, buf, strlen(buf));
00249
00250 ats_free(big_buf);
00251 return cond_satisfied;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 bool LogFilterString::toss_this_entry(LogAccess * lad)
00268 {
00269 if (m_num_values == 0 || m_field == NULL || lad == NULL) {
00270 return false;
00271 }
00272
00273 static const unsigned BUFSIZE = 1024;
00274 char small_buf[BUFSIZE];
00275 char small_buf_upper[BUFSIZE];
00276 char *big_buf = NULL;
00277 char *big_buf_upper = NULL;
00278 char *buf = small_buf;
00279 char *buf_upper = small_buf_upper;
00280 size_t marsh_len = m_field->marshal_len(lad);
00281
00282 if (marsh_len > BUFSIZE) {
00283 big_buf = (char *)ats_malloc((unsigned int) marsh_len);
00284 ink_assert(big_buf != NULL);
00285 buf = big_buf;
00286 }
00287
00288 m_field->marshal(lad, buf);
00289
00290 bool
00291 cond_satisfied = false;
00292 switch (m_operator) {
00293 case MATCH:
00294
00295
00296
00297
00298
00299
00300
00301
00302 cond_satisfied = _checkCondition(&strcmp, buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00303 break;
00304 case CASE_INSENSITIVE_MATCH:
00305 cond_satisfied = _checkCondition(&strcasecmp, buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00306 break;
00307 case CONTAIN:
00308 cond_satisfied = _checkCondition(&_isSubstring, buf, marsh_len, m_value, DATA_LENGTH_LARGER);
00309 break;
00310 case CASE_INSENSITIVE_CONTAIN:
00311 {
00312 if (big_buf) {
00313 big_buf_upper = (char *)ats_malloc((unsigned int) marsh_len);
00314 buf_upper = big_buf_upper;
00315 } else {
00316 buf = small_buf;
00317 }
00318 for (size_t i = 0; i < marsh_len; i++) {
00319 buf_upper[i] = ParseRules::ink_toupper(buf[i]);
00320 }
00321 cond_satisfied = _checkCondition(&_isSubstring, buf_upper, marsh_len, m_value_uppercase, DATA_LENGTH_LARGER);
00322 break;
00323 }
00324 default:
00325 ink_assert(!"INVALID FILTER OPERATOR");
00326 }
00327
00328 ats_free(big_buf);
00329 ats_free(big_buf_upper);
00330
00331 return ((m_action == REJECT && cond_satisfied) || (m_action == ACCEPT && !cond_satisfied));
00332 }
00333
00334
00335
00336
00337
00338 void
00339 LogFilterString::display(FILE * fd)
00340 {
00341 ink_assert(fd != NULL);
00342 if (m_num_values == 0) {
00343 fprintf(fd, "Filter \"%s\" is inactive, no values specified\n", m_name);
00344 } else {
00345 fprintf(fd, "Filter \"%s\" %sS records if %s %s ", m_name,
00346 ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00347 fprintf(fd, "%s", m_value[0]);
00348 for (size_t i = 1; i < m_num_values; ++i) {
00349 fprintf(fd, ", %s", m_value[i]);
00350 }
00351 fprintf(fd, "\n");
00352 }
00353 }
00354
00355 void
00356 LogFilterString::display_as_XML(FILE * fd)
00357 {
00358 ink_assert(fd != NULL);
00359 fprintf(fd,
00360 "<LogFilter>\n"
00361 " <Name = \"%s\"/>\n"
00362 " <Action = \"%s\"/>\n"
00363 " <Condition = \"%s %s ", m_name, ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00364
00365 if (m_num_values == 0) {
00366 fprintf(fd, "<no values>\"\n");
00367 } else {
00368 fprintf(fd, "%s", m_value[0]);
00369 for (size_t i = 1; i < m_num_values; ++i) {
00370 fprintf(fd, ", %s", m_value[i]);
00371 }
00372 fprintf(fd, "\"/>\n");
00373 }
00374 fprintf(fd, "</LogFilter>\n");
00375 }
00376
00377
00378
00379
00380
00381 void
00382 LogFilterInt::_setValues(size_t n, int64_t *value)
00383 {
00384 m_type = INT_FILTER;
00385 m_num_values = n;
00386 if (n) {
00387 m_value = new int64_t[n];
00388 memcpy(m_value, value, n * sizeof(int64_t));
00389 }
00390 }
00391
00392
00393 int
00394 LogFilterInt::_convertStringToInt(char *value, int64_t *ival, LogFieldAliasMap * map)
00395 {
00396 size_t i, l = strlen(value);
00397 for (i = 0; i < l && ParseRules::is_digit(value[i]); i++);
00398
00399 if (i < l) {
00400
00401
00402
00403
00404 if (map == NULL || map->asInt(value, ival) != LogFieldAliasMap::ALL_OK) {
00405 return -1;
00406 };
00407 } else {
00408
00409
00410
00411 *ival = ink_atoui(value);
00412 }
00413 return 0;
00414 }
00415
00416 LogFilterInt::LogFilterInt(const char *name, LogField * field,
00417 LogFilter::Action action, LogFilter::Operator oper, int64_t value)
00418 : LogFilter(name, field, action, oper)
00419 {
00420 int64_t v[1];
00421 v[0] = value;
00422 _setValues(1, v);
00423 }
00424
00425 LogFilterInt::LogFilterInt(const char *name, LogField * field,
00426 LogFilter::Action action, LogFilter::Operator oper, size_t num_values, int64_t *value)
00427 : LogFilter(name, field, action, oper)
00428 {
00429 _setValues(num_values, value);
00430 }
00431
00432 LogFilterInt::LogFilterInt(const char *name, LogField * field,
00433 LogFilter::Action action, LogFilter::Operator oper, char *values)
00434 : LogFilter(name, field, action, oper)
00435 {
00436
00437
00438 int64_t *val_array = 0;
00439 size_t i = 0;
00440 SimpleTokenizer tok(values, ',');
00441 size_t n = tok.getNumTokensRemaining();
00442
00443 if (n) {
00444 val_array = new int64_t[n];
00445 char *t;
00446 while (t = tok.getNext(), t != NULL) {
00447 int64_t ival;
00448 if (!_convertStringToInt(t, &ival, field->map())) {
00449
00450
00451 val_array[i++] = ival;
00452 }
00453 }
00454 if (i < n) {
00455 Warning("There were invalid values in the definition of filter %s"
00456 " only %zu out of %zu values will be used.", name, i, n);
00457 }
00458 } else {
00459 Warning("No values in the definition of filter %s.", name);
00460 }
00461
00462 _setValues(i, val_array);
00463
00464 if (n) {
00465 delete[]val_array;
00466 }
00467 }
00468
00469 LogFilterInt::LogFilterInt(const LogFilterInt & rhs)
00470 :
00471 LogFilter(rhs.m_name, rhs.m_field, rhs.m_action, rhs.m_operator)
00472 {
00473 _setValues(rhs.m_num_values, rhs.m_value);
00474 }
00475
00476
00477
00478
00479
00480 LogFilterInt::~LogFilterInt()
00481 {
00482 if (m_num_values > 0) {
00483 delete[]m_value;
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 bool LogFilterInt::operator==(LogFilterInt & rhs)
00498 {
00499 if (m_type == rhs.m_type &&
00500 * m_field == * rhs.m_field &&
00501 m_action == rhs.m_action &&
00502 m_operator == rhs.m_operator &&
00503 m_num_values == rhs.m_num_values) {
00504 for (size_t i = 0; i < m_num_values; i++) {
00505 if (m_value[i] != rhs.m_value[i]) {
00506 return false;
00507 }
00508 }
00509 return true;
00510 }
00511 return false;
00512 }
00513
00514
00515
00516
00517
00518 bool
00519 LogFilterInt::wipe_this_entry(LogAccess * lad)
00520 {
00521 if (m_num_values == 0 || m_field == NULL || lad == NULL || m_action != WIPE_FIELD_VALUE) {
00522 return false;
00523 }
00524
00525 bool cond_satisfied = false;
00526 int64_t value;
00527
00528 m_field->marshal(lad, (char *) &value);
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 if (m_num_values == 1) {
00539 cond_satisfied = (value == *m_value);
00540 } else {
00541 for (size_t i = 0; i < m_num_values; ++i) {
00542 if (value == m_value[i]) {
00543 cond_satisfied = true;
00544 break;
00545 }
00546 }
00547 }
00548
00549 return cond_satisfied;
00550 }
00551
00552
00553
00554
00555
00556 bool LogFilterInt::toss_this_entry(LogAccess * lad)
00557 {
00558 if (m_num_values == 0 || m_field == NULL || lad == NULL) {
00559 return false;
00560 }
00561
00562 bool cond_satisfied = false;
00563 int64_t value;
00564
00565 m_field->marshal(lad, (char *) &value);
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 if (m_num_values == 1) {
00576 cond_satisfied = (value == *m_value);
00577 } else {
00578 for (size_t i = 0; i < m_num_values; ++i) {
00579 if (value == m_value[i]) {
00580 cond_satisfied = true;
00581 break;
00582 }
00583 }
00584 }
00585
00586 return (m_action == REJECT && cond_satisfied) || (m_action == ACCEPT && !cond_satisfied);
00587 }
00588
00589
00590
00591
00592
00593 void
00594 LogFilterInt::display(FILE * fd)
00595 {
00596 ink_assert(fd != NULL);
00597 if (m_num_values == 0) {
00598 fprintf(fd, "Filter \"%s\" is inactive, no values specified\n", m_name);
00599 } else {
00600 fprintf(fd, "Filter \"%s\" %sS records if %s %s ", m_name,
00601 ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00602 fprintf(fd, "%" PRId64 "", m_value[0]);
00603 for (size_t i = 1; i < m_num_values; ++i) {
00604 fprintf(fd, ", %" PRId64 "", m_value[i]);
00605 }
00606 fprintf(fd, "\n");
00607 }
00608 }
00609
00610 void
00611 LogFilterInt::display_as_XML(FILE * fd)
00612 {
00613 ink_assert(fd != NULL);
00614 fprintf(fd,
00615 "<LogFilter>\n"
00616 " <Name = \"%s\"/>\n"
00617 " <Action = \"%s\"/>\n"
00618 " <Condition = \"%s %s ", m_name, ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00619
00620 if (m_num_values == 0) {
00621 fprintf(fd, "<no values>\"\n");
00622 } else {
00623 fprintf(fd, "%" PRId64 "", m_value[0]);
00624 for (size_t i = 1; i < m_num_values; ++i) {
00625 fprintf(fd, ", %" PRId64 "", m_value[i]);
00626 }
00627 fprintf(fd, "\"/>\n");
00628 }
00629 fprintf(fd, "</LogFilter>\n");
00630 }
00631
00632
00633
00634
00635 LogFilterIP::LogFilterIP(const char *name, LogField * field,
00636 LogFilter::Action action, LogFilter::Operator oper, IpAddr value)
00637 : LogFilter(name, field, action, oper)
00638 {
00639 m_map.mark(value,value);
00640 this->init();
00641 }
00642
00643 LogFilterIP::LogFilterIP(const char *name, LogField * field,
00644 LogFilter::Action action, LogFilter::Operator oper, size_t num_values, IpAddr* value)
00645 : LogFilter(name, field, action, oper)
00646 {
00647 for ( IpAddr* limit = value + num_values ; value != limit ; ++value )
00648 m_map.mark(*value,*value);
00649 this->init();
00650 }
00651
00652 LogFilterIP::LogFilterIP(const char *name, LogField * field,
00653 LogFilter::Action action, LogFilter::Operator oper, char *values)
00654 : LogFilter(name, field, action, oper)
00655 {
00656
00657
00658 size_t i = 0;
00659 SimpleTokenizer tok(values, ',');
00660 size_t n = tok.getNumTokensRemaining();
00661 char* t;
00662
00663 if (n) {
00664 while (t = tok.getNext(), t != NULL) {
00665 IpAddr min, max;
00666 char* x = strchr(t, '-');
00667 if (x) *x++ = 0;
00668 if (0 == min.load(t)) {
00669 if (x) {
00670 if (0 != max.load(x)) {
00671 Warning("LogFilterIP Configuration: '%s-%s' looks like a range but the second address was ill formed", t,x);
00672 continue;
00673 }
00674 } else {
00675 max = min;
00676 }
00677 m_map.mark(min,max);
00678 ++i;
00679 } else {
00680 Warning("LogFilterIP Configuration: '%s' is ill formed", t);
00681 }
00682 }
00683 if (i < n) {
00684 Warning("There were invalid IP values in the definition of filter %s"
00685 " only %zu out of %zu values will be used.", name, i, n);
00686 }
00687 } else {
00688 Warning("No values in the definition of filter %s.", name);
00689 }
00690 this->init();
00691 }
00692
00693 LogFilterIP::LogFilterIP(const LogFilterIP & rhs)
00694 : LogFilter(rhs.m_name, rhs.m_field, rhs.m_action, rhs.m_operator)
00695 {
00696 for ( IpMap::iterator spot(rhs.m_map.begin()), limit(rhs.m_map.end()) ; spot != limit ; ++spot ) {
00697 m_map.mark(spot->min(), spot->max(), spot->data());
00698 }
00699 this->init();
00700 }
00701
00702 void
00703 LogFilterIP::init()
00704 {
00705 m_type = IP_FILTER;
00706 m_num_values = m_map.getCount();
00707 }
00708
00709
00710
00711
00712
00713 LogFilterIP::~LogFilterIP()
00714 {
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 bool
00728 LogFilterIP::operator==(LogFilterIP & rhs)
00729 {
00730 if (m_type == rhs.m_type &&
00731 *m_field == *rhs.m_field &&
00732 m_action == rhs.m_action &&
00733 m_operator == rhs.m_operator &&
00734 m_num_values == rhs.m_num_values) {
00735
00736 IpMap::iterator left_spot(m_map.begin());
00737 IpMap::iterator left_limit(m_map.end());
00738 IpMap::iterator right_spot(rhs.m_map.begin());
00739 IpMap::iterator right_limit(rhs.m_map.end());
00740
00741 while (left_spot != left_limit && right_spot != right_limit) {
00742 if (!ats_ip_addr_eq(left_spot->min(), right_spot->min()) ||
00743 !ats_ip_addr_eq(left_spot->max(), right_spot->max()))
00744 break;
00745 ++left_spot;
00746 ++right_spot;
00747 }
00748
00749 return left_spot == left_limit && right_spot == right_limit;
00750 }
00751 return false;
00752 }
00753
00754
00755
00756
00757
00758 bool
00759 LogFilterIP::is_match(LogAccess* lad)
00760 {
00761 bool zret = false;
00762
00763 if (m_field && lad) {
00764 LogFieldIpStorage value;
00765 m_field->marshal(lad, reinterpret_cast<char *>(&value));
00766
00767
00768 zret = m_map.contains(reinterpret_cast<IpAddr&>(value));
00769 }
00770
00771 return zret;
00772 }
00773
00774 bool
00775 LogFilterIP::toss_this_entry(LogAccess* lad)
00776 {
00777 bool cond_satisfied = this->is_match(lad);
00778 return (m_action == REJECT && cond_satisfied) || (m_action == ACCEPT && !cond_satisfied);
00779 }
00780
00781 bool
00782 LogFilterIP::wipe_this_entry(LogAccess*)
00783 {
00784 # if 0
00785 bool zret = WIPE_FIELD_VALUE == m_action && this->is_match(lad);
00786 if (zret) {
00787
00788 }
00789 return zret;
00790 # else
00791 return false;
00792 # endif
00793 }
00794
00795
00796
00797
00798
00799 void
00800 LogFilterIP::displayRange(FILE* fd, IpMap::iterator const& iter)
00801 {
00802 ip_text_buffer ipb;
00803
00804 fprintf(fd, "%s", ats_ip_ntop(iter->min(), ipb, sizeof(ipb)));
00805
00806 if (!ats_ip_addr_eq(iter->min(), iter->max()))
00807 fprintf(fd, "-%s", ats_ip_ntop(iter->max(), ipb, sizeof(ipb)));
00808 }
00809
00810 void
00811 LogFilterIP::displayRanges(FILE * fd)
00812 {
00813 IpMap::iterator spot(m_map.begin()), limit(m_map.end());
00814 ink_assert(spot != limit);
00815
00816 this->displayRange(fd, spot);
00817 for ( ++spot ; spot != limit ; ++spot ) {
00818 for (size_t i = 1; i < m_num_values; ++i) {
00819 fprintf(fd, ",");
00820 this->displayRange(fd, spot);
00821 }
00822 }
00823 }
00824
00825 void
00826 LogFilterIP::display(FILE* fd)
00827 {
00828 ink_assert(fd != NULL);
00829
00830 if (0 == m_map.getCount()) {
00831 fprintf(fd, "Filter \"%s\" is inactive, no values specified\n", m_name);
00832 } else {
00833 fprintf(fd, "Filter \"%s\" %sS records if %s %s ", m_name, ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00834 this->displayRanges(fd);
00835 fprintf(fd, "\n");
00836 }
00837 }
00838
00839
00840 void
00841 LogFilterIP::display_as_XML(FILE * fd)
00842 {
00843 ink_assert(fd != NULL);
00844 fprintf(fd,
00845 "<LogFilter>\n"
00846 " <Name = \"%s\"/>\n"
00847 " <Action = \"%s\"/>\n"
00848 " <Condition = \"%s %s ", m_name, ACTION_NAME[m_action], m_field->symbol(), OPERATOR_NAME[m_operator]);
00849
00850 if (m_map.getCount() == 0) {
00851 fprintf(fd, "<no values>");
00852 } else {
00853 this->displayRanges(fd);
00854 }
00855 fprintf(fd, "\"/>\n");
00856 fprintf(fd, "</LogFilter>\n");
00857 }
00858
00859 bool
00860 filters_are_equal(LogFilter * filt1, LogFilter * filt2)
00861 {
00862 bool ret = false;
00863
00864
00865 if (filt1->type() == filt2->type()) {
00866 if (filt1->type() == LogFilter::INT_FILTER) {
00867 Debug("log-filter-compare", "int compare");
00868 ret = (*((LogFilterInt *) filt1) == *((LogFilterInt *) filt2));
00869 } else if (filt1->type() == LogFilter::IP_FILTER) {
00870 ret = (*((LogFilterIP *) filt1) == *((LogFilterIP *) filt2));
00871 } else if (filt1->type() == LogFilter::STRING_FILTER) {
00872 ret = (*((LogFilterString *) filt1) == *((LogFilterString *) filt2));
00873 } else {
00874 ink_assert(!"invalid filter type");
00875 }
00876 } else {
00877 Debug("log-filter-compare", "type diff");
00878 }
00879 return ret;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 LogFilterList::LogFilterList():m_does_conjunction(true)
00892 {
00893 }
00894
00895
00896
00897
00898 LogFilterList::~LogFilterList()
00899 {
00900 clear();
00901 }
00902
00903
00904
00905
00906 bool LogFilterList::operator==(LogFilterList & rhs)
00907 {
00908 if (m_does_conjunction == rhs.does_conjunction()) {
00909 LogFilter *f = first();
00910 LogFilter *rhsf = rhs.first();
00911
00912 while (true) {
00913 if (!(f || rhsf)) {
00914 return true;
00915 } else if (!f || !rhsf) {
00916 return false;
00917 } else if (!filters_are_equal(f, rhsf)) {
00918 return false;
00919 } else {
00920 f = next(f);
00921 rhsf = rhs.next(rhsf);
00922 }
00923 }
00924 } else {
00925 return false;
00926 }
00927 }
00928
00929
00930
00931
00932 void
00933 LogFilterList::clear()
00934 {
00935 LogFilter *f;
00936 while ((f = m_filter_list.dequeue())) {
00937 delete f;
00938 }
00939 }
00940
00941
00942
00943
00944 void
00945 LogFilterList::add(LogFilter * filter, bool copy)
00946 {
00947 ink_assert(filter != NULL);
00948 if (copy) {
00949 if (filter->type() == LogFilter::INT_FILTER) {
00950 LogFilterInt *f = new LogFilterInt(*((LogFilterInt *) filter));
00951 m_filter_list.enqueue(f);
00952 } else if (filter->type() == LogFilter::IP_FILTER) {
00953 LogFilterIP *f = new LogFilterIP(*((LogFilterIP *) filter));
00954 m_filter_list.enqueue(f);
00955 } else {
00956 LogFilterString *f = new LogFilterString(*((LogFilterString *) filter));
00957 m_filter_list.enqueue(f);
00958 }
00959 } else {
00960 m_filter_list.enqueue(filter);
00961 }
00962 }
00963
00964
00965
00966
00967 bool
00968 LogFilterList::wipe_this_entry(LogAccess * lad)
00969 {
00970 bool wipeFlag = false;
00971 for (LogFilter * f = first(); f; f = next(f)) {
00972 if (f->wipe_this_entry(lad)) {
00973 wipeFlag = true;
00974 }
00975 }
00976 return wipeFlag;
00977 }
00978
00979
00980
00981
00982
00983 bool LogFilterList::toss_this_entry(LogAccess * lad)
00984 {
00985 if (m_does_conjunction) {
00986
00987
00988 for (LogFilter * f = first(); f; f = next(f)) {
00989 if (f->toss_this_entry(lad)) {
00990 return true;
00991 }
00992 }
00993 return false;
00994 } else {
00995
00996
00997 for (LogFilter * f = first(); f; f = next(f)) {
00998 if (!f->toss_this_entry(lad)) {
00999 return false;
01000 }
01001 }
01002 return true;
01003 }
01004 }
01005
01006
01007
01008
01009 LogFilter *
01010 LogFilterList::find_by_name(char *name)
01011 {
01012 for (LogFilter * f = first(); f; f = next(f)) {
01013 if (strcmp(f->name(), name) == 0) {
01014 return f;
01015 }
01016 }
01017 return NULL;
01018 }
01019
01020
01021
01022
01023
01024 unsigned
01025 LogFilterList::count()
01026 {
01027 unsigned cnt = 0;
01028
01029 for (LogFilter * f = first(); f; f = next(f)) {
01030 cnt++;
01031 }
01032 return cnt;
01033 }
01034
01035 void
01036 LogFilterList::display(FILE * fd)
01037 {
01038 for (LogFilter * f = first(); f; f = next(f)) {
01039 f->display(fd);
01040 }
01041 }
01042
01043 void
01044 LogFilterList::display_as_XML(FILE * fd)
01045 {
01046 for (LogFilter * f = first(); f; f = next(f)) {
01047 f->display_as_XML(fd);
01048 }
01049 }