diff options
-rw-r--r-- | Changes | 1 | ||||
-rw-r--r-- | include/extern.h | 4 | ||||
-rw-r--r-- | include/services.h | 4 | ||||
-rw-r--r-- | lang/de.l | 6 | ||||
-rw-r--r-- | lang/en_us.l | 6 | ||||
-rw-r--r-- | lang/nl.l | 6 | ||||
-rw-r--r-- | lang/pl.l | 6 | ||||
-rw-r--r-- | src/core/os_ignore.c | 88 | ||||
-rw-r--r-- | src/modules/ns_noop_convert.c | 1 | ||||
-rw-r--r-- | src/process.c | 276 | ||||
-rw-r--r-- | version.log | 7 |
11 files changed, 235 insertions, 170 deletions
@@ -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; @@ -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 @@ -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 @@ -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 |