summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--include/extern.h4
-rw-r--r--include/services.h4
-rw-r--r--lang/de.l6
-rw-r--r--lang/en_us.l6
-rw-r--r--lang/nl.l6
-rw-r--r--lang/pl.l6
-rw-r--r--src/core/os_ignore.c88
-rw-r--r--src/modules/ns_noop_convert.c1
-rw-r--r--src/process.c276
-rw-r--r--version.log7
11 files changed, 235 insertions, 170 deletions
diff --git a/Changes b/Changes
index ccdcd2c4f..0f978d839 100644
--- a/Changes
+++ b/Changes
@@ -57,6 +57,7 @@ Anope Version S V N
09/01 F Fixed crashbug in cs_access. [#932]
09/02 F Fixed bug in enc_none in combination with truncated pass. [#934]
09/03 F Fixed variables not correctly shown in help. [#873]
+09/04 F Rewrote the ignore system to fix several issues. [#930]
Provided by Robin Burchell <w00t@inspircd.org> - 2008
08/08 F Strict warnings in send.c from comparing address of non-ptr [ #00]
diff --git a/include/extern.h b/include/extern.h
index 4284b09de..a9a68a250 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -1007,10 +1007,12 @@ E int defconParseModeString(const char *str);
/**** process.c ****/
E int allow_ignore;
-E IgnoreData *ignore[];
+E IgnoreData *ignore;
E void add_ignore(const char *nick, time_t delta);
E IgnoreData *get_ignore(const char *nick);
+E int delete_ignore(const char *nick);
+E int clear_ignores();
E int split_buf(char *buf, char ***argv, int colon_special);
E void process(void);
diff --git a/include/services.h b/include/services.h
index 3d8ee2be1..e1376f1bb 100644
--- a/include/services.h
+++ b/include/services.h
@@ -1036,8 +1036,8 @@ struct c_elist_entry {
/* Ignorance list data. */
typedef struct ignore_data {
- struct ignore_data *next;
- char who[NICKMAX];
+ struct ignore_data *prev, *next;
+ char *mask;
time_t time; /* When do we stop ignoring them? */
} IgnoreData;
diff --git a/lang/de.l b/lang/de.l
index d5182d4d7..1b60b950d 100644
--- a/lang/de.l
+++ b/lang/de.l
@@ -2935,11 +2935,11 @@ OPER_IGNORE_SYNTAX
OPER_IGNORE_VALID_TIME
Du musst eine zulässige Zahl als Zeit eingeben.
OPER_IGNORE_TIME_DONE
- Der Nickname %s wird jetzt für %s ignoriert.
+ %s wird jetzt für %s ignoriert.
OPER_IGNORE_PERM_DONE
- Der Nickname %s will wird jetzt permanent ignoriert.
+ %s will wird jetzt permanent ignoriert.
OPER_IGNORE_DEL_DONE
- Der Nickname %s wird nicht länger ignoriert.
+ %s wird nicht länger ignoriert.
OPER_IGNORE_LIST
Services Ignore-Liste:
OPER_IGNORE_LIST_NOMATCH
diff --git a/lang/en_us.l b/lang/en_us.l
index 1c5b2cb41..3ba2a13c3 100644
--- a/lang/en_us.l
+++ b/lang/en_us.l
@@ -2880,11 +2880,11 @@ OPER_IGNORE_SYNTAX
OPER_IGNORE_VALID_TIME
You have to enter a valid number as time.
OPER_IGNORE_TIME_DONE
- Nick %s will now be ignored for %s.
+ %s will now be ignored for %s.
OPER_IGNORE_PERM_DONE
- Nick %s will now permanently be ignored.
+ %s will now permanently be ignored.
OPER_IGNORE_DEL_DONE
- Nick %s will no longer be ignored.
+ %s will no longer be ignored.
OPER_IGNORE_LIST
Services ignore list:
OPER_IGNORE_LIST_NOMATCH
diff --git a/lang/nl.l b/lang/nl.l
index f2ee74b45..0d4f80d27 100644
--- a/lang/nl.l
+++ b/lang/nl.l
@@ -2942,11 +2942,11 @@ OPER_IGNORE_SYNTAX
OPER_IGNORE_VALID_TIME
Je moet een geldig nummer als tijd invoeren.
OPER_IGNORE_TIME_DONE
- Nick %s zal nu genegeerd worden voor %s.
+ %s zal nu genegeerd worden voor %s.
OPER_IGNORE_PERM_DONE
- Nick %s zal nu permanent genegeerd worden.
+ %s zal nu permanent genegeerd worden.
OPER_IGNORE_DEL_DONE
- Nick %s zal niet meer genegeerd worden.
+ %s zal niet meer genegeerd worden.
OPER_IGNORE_LIST
Services negeer-lijst:
OPER_IGNORE_LIST_NOMATCH
diff --git a/lang/pl.l b/lang/pl.l
index 728dc2790..1ffa318e8 100644
--- a/lang/pl.l
+++ b/lang/pl.l
@@ -3141,11 +3141,11 @@ OPER_IGNORE_SYNTAX
OPER_IGNORE_VALID_TIME
Musisz podać prawidłową liczbę dla czasu.
OPER_IGNORE_TIME_DONE
- Nick %s będzie od teraz igorowany na %s.
+ %s będzie od teraz igorowany na %s.
OPER_IGNORE_PERM_DONE
- Nick %s będzie od teraz igorowany cały czas.
+ %s będzie od teraz igorowany cały czas.
OPER_IGNORE_DEL_DONE
- Nick %s nie będzie już dłużej ignorowany.
+ %s nie będzie już dłużej ignorowany.
OPER_IGNORE_LIST
Lista ignore serwisów:
OPER_IGNORE_LIST_NOMATCH
diff --git a/src/core/os_ignore.c b/src/core/os_ignore.c
index 7b65a938d..6ae5ad16f 100644
--- a/src/core/os_ignore.c
+++ b/src/core/os_ignore.c
@@ -18,8 +18,6 @@
int do_ignorelist(User * u);
void myOperServHelp(User * u);
int do_ignoreuser(User * u);
-int do_clearignore(User * u);
-void delete_ignore(const char *nick);
/**
* Create the command, and tell anope about it.
@@ -79,7 +77,6 @@ int do_ignoreuser(User * u)
}
if (!stricmp(cmd, "ADD")) {
-
char *time = strtok(NULL, " ");
char *nick = strtok(NULL, " ");
char *rest = strtok(NULL, "");
@@ -103,101 +100,48 @@ int do_ignoreuser(User * u)
notice_lang(s_OperServ, u, OPER_IGNORE_PERM_DONE, nick);
} else {
add_ignore(nick, t);
- notice_lang(s_OperServ, u, OPER_IGNORE_TIME_DONE, nick,
- time);
+ notice_lang(s_OperServ, u, OPER_IGNORE_TIME_DONE, nick, time);
}
}
} else if (!stricmp(cmd, "LIST")) {
do_ignorelist(u);
- }
- else if (!stricmp(cmd, "DEL")) {
+ } else if (!stricmp(cmd, "DEL")) {
char *nick = strtok(NULL, " ");
if (!nick) {
notice_lang(s_OperServ, u, OPER_IGNORE_SYNTAX);
} else {
- if (get_ignore(nick) == 0) {
- notice_lang(s_OperServ, u, OPER_IGNORE_LIST_NOMATCH, nick);
- return MOD_CONT;
- } else {
- delete_ignore(nick);
+ if (delete_ignore(nick)) {
notice_lang(s_OperServ, u, OPER_IGNORE_DEL_DONE, nick);
+ return MOD_CONT;
}
+ notice_lang(s_OperServ, u, OPER_IGNORE_LIST_NOMATCH, nick);
}
} else if (!stricmp(cmd, "CLEAR")) {
- do_clearignore(u);
-
+ clear_ignores();
+ notice_lang(s_OperServ, u, OPER_IGNORE_LIST_CLEARED);
+ return MOD_CONT;
} else
notice_lang(s_OperServ, u, OPER_IGNORE_SYNTAX);
+
return MOD_CONT;
}
/* shows the Services ignore list */
-
int do_ignorelist(User * u)
{
- int sent_header = 0;
IgnoreData *id;
- int i;
- for (i = 0; i < 256; i++) {
- for (id = ignore[i]; id; id = id->next) {
- if (!sent_header) {
- notice_lang(s_OperServ, u, OPER_IGNORE_LIST);
- sent_header = 1;
- }
- notice_user(s_OperServ, u, "%s", id->who);
- }
- }
- if (!sent_header)
+ if (!ignore) {
notice_lang(s_OperServ, u, OPER_IGNORE_LIST_EMPTY);
- return MOD_CONT;
-}
-
-/* deletes a nick from the ignore list */
-
-void delete_ignore(const char *nick)
-{
- IgnoreData *ign, *prev;
- IgnoreData **whichlist;
-
- if (!nick || !*nick) {
- return;
- }
-
- whichlist = &ignore[tolower(nick[0])];
-
- for (ign = *whichlist, prev = NULL; ign; prev = ign, ign = ign->next) {
- if (stricmp(ign->who, nick) == 0)
- break;
+ return MOD_CONT;
}
- /* If the ignore was not found, bail out -GD */
- if (!ign)
- return;
- if (prev)
- prev->next = ign->next;
- else
- *whichlist = ign->next;
- free(ign);
- ign = NULL;
-}
-/**************************************************************************/
-/* Cleares the Services ignore list */
+ notice_lang(s_OperServ, u, OPER_IGNORE_LIST);
+ for (id = ignore; id; id = id->next)
+ notice_user(s_OperServ, u, "%s", id->mask);
-int do_clearignore(User * u)
-{
- IgnoreData *id = NULL, *next = NULL;
- int i;
- for (i = 0; i < 256; i++) {
- for (id = ignore[i]; id; id = next) {
- next = id->next;
- free(id);
- if (!next) {
- ignore[i] = NULL;
- }
- }
- }
- notice_lang(s_OperServ, u, OPER_IGNORE_LIST_CLEARED);
return MOD_CONT;
}
+
+/* EOF */
diff --git a/src/modules/ns_noop_convert.c b/src/modules/ns_noop_convert.c
index a5a859100..2858bef1e 100644
--- a/src/modules/ns_noop_convert.c
+++ b/src/modules/ns_noop_convert.c
@@ -56,7 +56,6 @@ int mSaveData(int argc, char **argv);
int mLoadConfig(int argc, char **argv);
void m_AddLanguages(void);
-void delete_ignore(const char *nick);
/*************************************************************************/
diff --git a/src/process.c b/src/process.c
index 58adc3bf7..a8efaec94 100644
--- a/src/process.c
+++ b/src/process.c
@@ -21,119 +21,233 @@
/* Use ignore code? */
int allow_ignore = 1;
-/* People to ignore (hashed by first character of nick). */
-IgnoreData *ignore[256];
+/* Masks to ignore. */
+IgnoreData *ignore;
/*************************************************************************/
-/* add_ignore: Add someone to the ignorance list for the next `delta'
- * seconds.
+/**
+ * Add a mask/nick to the ignorelits for delta seconds.
+ * @param nick Nick or (nick!)user@host to add to the ignorelist.
+ * @param delta Seconds untill new entry is set to expire.
*/
-
void add_ignore(const char *nick, time_t delta)
{
IgnoreData *ign;
- char who[NICKMAX];
+ char tmp[BUFSIZE];
+ char *mask, *user, *host;
time_t now = time(NULL);
- IgnoreData **whichlist = &ignore[tolower(nick[0])];
-
- strscpy(who, nick, NICKMAX);
- for (ign = *whichlist; ign; ign = ign->next) {
- if (stricmp(ign->who, who) == 0)
+
+ if (!nick)
+ return;
+
+ /* Determine whether we get a nick or a mask. */
+ if ((host = strchr(nick, '@'))) {
+ /* Check whether we have a nick too.. */
+ if ((user = strchr(nick, '!'))) {
+ /* this should never happen */
+ if (user > host)
+ return;
+ mask = sstrdup(nick);
+ } else {
+ /* We have user@host. Add nick wildcard. */
+ snprintf(tmp, sizeof(tmp), "*!%s", nick);
+ mask = sstrdup(tmp);
+ }
+ } else {
+ /* We only got a nick.. */
+ snprintf(tmp, sizeof(tmp), "%s!*@*", nick);
+ mask = sstrdup(tmp);
+ }
+
+ /* Check if we already got an identical entry. */
+ for (ign = ignore; ign; ign = ign->next)
+ if (stricmp(ign->mask, mask) == 0)
break;
- }
+
+ /* Found one.. */
if (ign) {
- if (ign->time > now)
- ign->time += delta;
- else
- ign->time = now + delta;
+ if (ign->time < now + delta)
+ ign->time = now + delta;
+ /* Create new entry.. */
} else {
ign = scalloc(sizeof(*ign), 1);
- strscpy(ign->who, who, sizeof(ign->who));
+ ign->mask = mask;
ign->time = now + delta;
- ign->next = *whichlist;
- *whichlist = ign;
+ ign->prev = NULL;
+ ign->next = ignore;
+ if (ignore)
+ ignore->prev = ign;
+ ignore = ign;
+
+ if (debug)
+ alog("debug: Added new ignore entry for %s", mask);
}
}
/*************************************************************************/
-/* get_ignore: Retrieve an ignorance record for a nick. If the nick isn't
- * being ignored, return NULL and flush the record from the
- * in-core list if it exists (i.e. ignore timed out).
+/**
+ * Retrieve an ignorance record for a nick or mask.
+ * If the nick isn't being ignored, we return NULL and if necesary
+ * flush the record from the in-core list (i.e. ignore timed out).
+ * @param nick Nick or (nick!)user@host to look for on the ignorelist.
+ * @return Pointer to the ignore record, NULL if none was found.
*/
-
IgnoreData *get_ignore(const char *nick)
{
- IgnoreData *ign, *prev;
+ IgnoreData *ign;
+ char tmp[BUFSIZE];
+ char *user, *host;
time_t now = time(NULL);
- IgnoreData **whichlist = &ignore[tolower(nick[0])];
User *u = finduser(nick);
- IgnoreData **whichlist2 = NULL;
- /* Bleah, this doesn't work. I need a way to get the first char of u->username.
- /if (u) whichlist2 = &ignore[tolower(u->username[0])]; */
- IgnoreData **whichlistast = &ignore[42]; /* * */
- IgnoreData **whichlistqst = &ignore[63]; /* ? */
- int finished = 0;
-
+
+ if (!nick)
+ return NULL;
/* User has disabled the IGNORE system */
- if (!allow_ignore) {
+ if (!allow_ignore)
return NULL;
- }
-
- /* if an oper gets on the ignore list we let them privmsg, this will allow
- them in places we call get_ignore to get by */
- if (u && is_oper(u)) {
- return NULL;
- }
-
- for (ign = *whichlist, prev = NULL; ign; prev = ign, ign = ign->next) {
- if (stricmp(ign->who, nick) == 0) {
- finished = 1;
- break;
- }
- }
- /* We can only do the next checks if we have an actual user -GD */
- if (u) {
- if (!finished && whichlist2) {
- for (ign = *whichlist2, prev = NULL; ign;
- prev = ign, ign = ign->next) {
- if (match_usermask(ign->who, u)) {
- finished = 1;
- break;
- }
- }
- }
- if (!finished) {
- for (ign = *whichlistast, prev = NULL; ign;
- prev = ign, ign = ign->next) {
- if (match_usermask(ign->who, u)) {
- finished = 1;
- break;
- }
- }
- }
- if (!finished) {
- for (ign = *whichlistqst, prev = NULL; ign;
- prev = ign, ign = ign->next) {
- if (match_usermask(ign->who, u)) {
- finished = 1;
- break;
- }
- }
- }
- }
+
+ /* If we found a real user, match his mask against the ignorelist. */
+ if (u) {
+ /* Opers are not ignored, even if a matching entry may be present. */
+ if (is_oper(u))
+ return NULL;
+
+ for (ign = ignore; ign; ign = ign->next)
+ if (match_usermask(ign->mask, u))
+ break;
+ } else {
+ /* We didn't get a user.. generate a valid mask. */
+ if ((host = strchr(nick, '@'))) {
+ if ((user = strchr(nick, '!'))) {
+ /* this should never happen */
+ if (user > host)
+ return NULL;
+ snprintf(tmp, sizeof(tmp), "%s", nick);
+ } else {
+ /* We have user@host. Add nick wildcard. */
+ snprintf(tmp, sizeof(tmp), "*!%s", nick);
+ }
+ } else {
+ /* We only got a nick.. */
+ snprintf(tmp, sizeof(tmp), "%s!*@*", nick);
+ }
+
+ for (ign = ignore; ign; ign = ign->next)
+ if (match_wild_nocase(ign->mask, tmp))
+ break;
+ }
+
+ /* Check whether the entry has timed out */
if (ign && ign->time <= now) {
- if (prev)
- prev->next = ign->next;
- else
- *whichlist = ign->next;
+ if (debug)
+ alog("debug: Expiring ignore entry %s", ign->mask);
+
+ if (ign->prev)
+ ign->prev->next = ign->next;
+ else if (ignore == ign)
+ ignore = ign->next;
+ if (ign->next)
+ ign->next->prev = ign->prev;
+
+ free(ign->mask);
free(ign);
ign = NULL;
}
+
+ if (ign && debug)
+ alog("debug: Found ignore entry (%s) for %s", ign->mask, nick);
+
return ign;
}
+
+/*************************************************************************/
+
+/**
+ * Deletes a given nick/mask from the ignorelist.
+ * @param nick Nick or (nick!)user@host to delete from the ignorelist.
+ * @return Returns 1 on success, 0 if no entry is found.
+ */
+int delete_ignore(const char *nick)
+{
+ IgnoreData *ign;
+ char tmp[BUFSIZE];
+ char *user, *host;
+
+ if (!nick)
+ return 0;
+
+ /* Determine whether we get a nick or a mask. */
+ if ((host = strchr(nick, '@'))) {
+ /* Check whether we have a nick too.. */
+ if ((user = strchr(nick, '!'))) {
+ /* this should never happen */
+ if (user > host)
+ return 0;
+ snprintf(tmp, sizeof(tmp), "%s", nick);
+ } else {
+ /* We have user@host. Add nick wildcard. */
+ snprintf(tmp, sizeof(tmp), "*!%s", nick);
+ }
+ } else {
+ /* We only got a nick.. */
+ snprintf(tmp, sizeof(tmp), "%s!*@*", nick);
+ }
+
+ for (ign = ignore; ign; ign = ign->next)
+ if (stricmp(ign->mask, tmp) == 0)
+ break;
+
+ /* No matching ignore found. */
+ if (!ign)
+ return 0;
+
+ if (debug)
+ alog("Deleting ignore entry %s", ign->mask);
+
+ /* Delete the entry and all references to it. */
+ if (ign->prev)
+ ign->prev->next = ign->next;
+ else if (ignore == ign)
+ ignore = ign->next;
+ if (ign->next)
+ ign->next->prev = ign->prev;
+ free(ign->mask);
+ free(ign);
+ ign = NULL;
+ return 1;
+}
+
+/*************************************************************************/
+
+/**
+ * Clear the ignorelist.
+ * @return The number of entries deleted.
+ */
+int clear_ignores()
+{
+ IgnoreData *ign, *next;
+ int i = 0;
+
+ if (!ignore)
+ return 0;
+
+ for (ign = ignore; ign; ign = next) {
+ next = ign->next;
+
+ if (debug)
+ alog("Deleting ignore entry %s", ign->mask);
+
+ free(ign->mask);
+ free(ign);
+ i++;
+ }
+ ignore = NULL;
+
+ return i;
+}
/*************************************************************************/
diff --git a/version.log b/version.log
index 627da2d5a..9d7285da9 100644
--- a/version.log
+++ b/version.log
@@ -9,10 +9,15 @@ VERSION_MAJOR="1"
VERSION_MINOR="7"
VERSION_PATCH="21"
VERSION_EXTRA="-svn"
-VERSION_BUILD="1427"
+VERSION_BUILD="1428"
# $Log$
#
+# BUILD : 1.7.21 (1428)
+# BUGS : 930
+# NOTES : Rewrote the ignore system to handle both nicks and masks
+# properly.
+#
# BUILD : 1.7.21 (1427)
# BUGS : 931
# NOTES : Added anope build scripts for windows to /src/tools