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 }