+int bad_line(char *line, char *comment)
+{
+ int length, nb_art_chars, longest_word, nb_caps, nb_letters, nb_ctrl;
+ int l, bad;
+ unsigned char *s;
+ char *t;
+
+ nb_ctrl = 0;
+ nb_art_chars = 0;
+ nb_caps = 0;
+ nb_letters = 0;
+ length = 0;
+ l = 0;
+ longest_word = 0;
+
+ for(s=(unsigned char *)line; *s != '\0'; s++)
+ {
+ if((*s >= 'A') && (*s <= 'Z')) nb_caps++;
+ if(((*s >= 'A') && (*s <= 'Z')) ||
+ ((*s >= 'a') && (*s <= 'z'))) nb_letters++;
+ if((*s > 2) && (*s < 31)) nb_ctrl++;
+ if((*s != ' ') && (*s != '?') && (*s != '!') &&
+ (((*s >= 32) && (*s <= 47)) ||
+ ((*s >= 58) && (*s <= 63)) ||
+ ((*s >= 91) && (*s <= 96)) ||
+ (*s >= 123))) nb_art_chars++;
+
+ if(s > (unsigned char *) line)
+ {
+ if(*s == *(s-1)) l++;
+ else
+ {
+ if(l > longest_word) longest_word = l;
+ l = 0;
+ }
+ }
+
+ length++;
+ }
+ if(l > longest_word) longest_word = l;
+
+ t = comment;
+
+ bad = 0;
+ if(longest_word > 60)
+ {
+ bad = 1;
+ concat(t, "repeated chars");
+ }
+
+ if(nb_ctrl > 0)
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "control chars");
+ bad = 1;
+ }
+
+ if((nb_art_chars > nb_letters) && (nb_art_chars >= 20))
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "art chars");
+ bad = 1;
+ }
+
+ if((nb_caps*4 > nb_letters*3) && (nb_caps >= 10))
+ {
+ if(bad) concat(t, " + ");
+ concat(t, "caps");
+ bad = 1;
+ }
+
+ *t = '\0';
+
+ return bad;
+}
+
+void test_kick(char *prefix)
+{
+ int nb_kicks;
+ int last_kick_time;
+ NodeList<FloodLine *> *node, *next, *pred;
+ char *pattern, *banid, *loginathost;
+
+ loginathost = reach_loginathost(prefix);
+
+ nb_kicks = 0;
+ last_kick_time = current_time + COP_DELAY_BEETWEEN_KICKS + 1;
+ pred = NULL;
+ node = kick_list.first;
+ while(node != NULL)
+ {
+ next = node->next;
+ if(current_time <= node->body->time + COP_DELAY)
+ {
+ if(strcmp(loginathost, reach_loginathost(node->body->prefix)) == 0)
+ {
+ if(node->body->time < last_kick_time - COP_DELAY_BEETWEEN_KICKS)
+ {
+ nb_kicks += node->body->weigth;
+ last_kick_time = node->body->time;
+ }
+ }
+ pred = node;
+ }
+ else
+ {
+ if(pred == NULL) kick_list.first = next;
+ else pred->next = next;
+ delete node->body;
+ delete node;
+ }
+ node = next;
+ }
+
+ if(nb_kicks >= COP_NB_KICKS)
+ {
+ pattern = pattern_from_prefix(prefix, 0);
+ banid = clean_banid(pattern);
+
+ smart_shit(NULL, NULL,
+ pattern, "cop : too many kicks", COP_DURATION + deban_delay);
+ smart_ban(current_channel, pattern);
+ send_mode(current_channel);
+ filter_kick(current_channel, pattern, "cop : too many kicks");
+
+ delete[] banid;
+ delete[] pattern;
+ }
+}
+
+inline void add_kick(char *prefix)
+{
+ if(level_person(prefix, NULL) >= LEVEL_FRIEND) return;
+ kick_list.Insert(new FloodLine(prefix, FL_KICK, 1));
+ test_kick(prefix);
+}
+