X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Flists.c;h=38b3b0e8031fc9f52480748dbf8b2de84e079d11;hp=6faf311a74f767207c0f2c622cde44e72a924280;hb=e954b59d414fb32b89291514d0d690c9ebabba49;hpb=48326e061aacd954e24f76c53ded10448cbc28eb diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c index 6faf311a..38b3b0e8 100644 --- a/src/ngircd/lists.c +++ b/src/ngircd/lists.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2018 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,37 +16,30 @@ * Management of IRC lists: ban, invite, etc. */ -#include "imp.h" #include +#include +#include +#include +#include -#include "defines.h" #include "conn.h" -#include "channel.h" #include "log.h" #include "match.h" -#include "messages.h" -#include "irc-write.h" - -#include -#include -#include -#include "exp.h" #include "lists.h" -#define MASK_LEN (2*CLIENT_HOST_LEN) - struct list_elem { struct list_elem *next; /** pointer to next list element */ char mask[MASK_LEN]; /** IRC mask */ char *reason; /** Optional "reason" text */ - time_t valid_until; /** 0: unlimited; 1: once; t(>1): until t */ + time_t valid_until; /** 0: unlimited; t(>0): until t */ + bool onlyonce; }; /** * Get IRC mask stored in list element. * - * @param list_elem List element. + * @param e List element. * @return Pointer to IRC mask */ GLOBAL const char * @@ -59,7 +52,7 @@ Lists_GetMask(const struct list_elem *e) /** * Get optional "reason" text stored in list element. * - * @param list_elem List element. + * @param e List element. * @return Pointer to "reason" text or empty string (""). */ GLOBAL const char * @@ -72,8 +65,8 @@ Lists_GetReason(const struct list_elem *e) /** * Get "validity" value stored in list element. * - * @param list_elem List element. - * @return Validity: 0=unlimited, 1=once, >1 until this time stamp. + * @param e List element. + * @return Validity: 0=unlimited, >0 until this time stamp. */ GLOBAL time_t Lists_GetValidity(const struct list_elem *e) @@ -82,6 +75,19 @@ Lists_GetValidity(const struct list_elem *e) return e->valid_until; } +/** + * Get "onlyonce" value stored in list element. + * + * @param e List element. + * @return True if the element was stored for single use, false otherwise. + */ +GLOBAL bool +Lists_GetOnlyOnce(const struct list_elem *e) +{ + assert(e != NULL); + return e->onlyonce; +} + /** * Get first list element of a list. * @@ -119,7 +125,7 @@ Lists_GetNext(const struct list_elem *e) */ bool Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil, - const char *Reason) + const char *Reason, bool OnlyOnce) { struct list_elem *e, *newelem; @@ -130,7 +136,8 @@ Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil, if (e) { e->valid_until = ValidUntil; if (Reason) { - free(e->reason); + if (e->reason) + free(e->reason); e->reason = strdup(Reason); } return true; @@ -155,6 +162,7 @@ Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil, else newelem->reason = NULL; newelem->valid_until = ValidUntil; + newelem->onlyonce = OnlyOnce; newelem->next = e; h->first = newelem; @@ -261,17 +269,13 @@ Lists_CheckDupeMask(const struct list_head *h, const char *Mask ) /** * Generate a valid IRC mask from "any" string given. * - * Attention: This mask is only valid until the next call to Lists_MakeMask(), - * because a single global buffer ist used! You have to copy the generated - * mask to some sane location yourself! - * * @param Pattern Source string to generate an IRC mask for. - * @return Pointer to global result buffer. + * @param mask Buffer to store the mask. + * @param len Size of the buffer. */ -GLOBAL const char * -Lists_MakeMask(const char *Pattern) +GLOBAL void +Lists_MakeMask(const char *Pattern, char *mask, size_t len) { - static char TheMask[MASK_LEN]; char *excl, *at; assert(Pattern != NULL); @@ -284,30 +288,23 @@ Lists_MakeMask(const char *Pattern) if (!at && !excl) { /* Neither "!" nor "@" found: use string as nickname */ - strlcpy(TheMask, Pattern, sizeof(TheMask) - 5); - strlcat(TheMask, "!*@*", sizeof(TheMask)); - return TheMask; - } - - if (!at && excl) { + strlcpy(mask, Pattern, len - 5); + strlcat(mask, "!*@*", len); + } else if (!at && excl) { /* Domain part is missing */ - strlcpy(TheMask, Pattern, sizeof(TheMask) - 3); - strlcat(TheMask, "@*", sizeof(TheMask)); - return TheMask; - } - - if (at && !excl) { + strlcpy(mask, Pattern, len - 3); + strlcat(mask, "@*", len); + } else if (at && !excl) { /* User name is missing */ *at = '\0'; at++; - strlcpy(TheMask, Pattern, sizeof(TheMask) - 5); - strlcat(TheMask, "!*@", sizeof(TheMask)); - strlcat(TheMask, at, sizeof(TheMask)); - return TheMask; + strlcpy(mask, Pattern, len - 5); + strlcat(mask, "!*@", len); + strlcat(mask, at, len); + at--; *at = '@'; + } else { + /* All parts (nick, user and domain name) are given */ + strlcpy(mask, Pattern, len); } - - /* All parts (nick, user and domain name) are given */ - strlcpy(TheMask, Pattern, sizeof(TheMask)); - return TheMask; } /* Lists_MakeMask */ /** @@ -320,18 +317,20 @@ Lists_MakeMask(const char *Pattern) bool Lists_Check(struct list_head *h, CLIENT *Client) { - return Lists_CheckReason(h, Client) != NULL; + return Lists_CheckReason(h, Client, NULL, 0); } /** - * Check if a client is listed in a list and return the "reason". + * Check if a client is listed in a list and store the reason. * - * @param h List head. + * @param h List head. * @param Client Client to check. + * @param reason Buffer to store the reason. + * @param len Size of the buffer if reason should be saved. * @return true if client is listed, false if not. */ -char * -Lists_CheckReason(struct list_head *h, CLIENT *Client) +bool +Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len) { struct list_elem *e, *last, *next; @@ -342,20 +341,22 @@ Lists_CheckReason(struct list_head *h, CLIENT *Client) while (e) { next = e->next; - if (Match(e->mask, Client_Mask(Client))) { - if (e->valid_until == 1) { + if (MatchCaseInsensitive(e->mask, Client_MaskCloaked(Client))) { + if (len && e->reason) + strlcpy(reason, e->reason, len); + if (e->onlyonce) { /* Entry is valid only once, delete it */ LogDebug("Deleted \"%s\" from list (used).", e->mask); Lists_Unlink(h, last, e); } - return e->reason ? e->reason : ""; + return true; } last = e; e = next; } - return NULL; + return false; } /** @@ -377,14 +378,14 @@ Lists_Expire(struct list_head *h, const char *ListName) while (e) { next = e->next; - if (e->valid_until > 1 && e->valid_until < now) { + if (e->valid_until > 0 && e->valid_until < now) { /* Entry is expired, delete it */ if (e->reason) - Log(LOG_INFO, + Log(LOG_NOTICE|LOG_snotice, "Deleted \"%s\" (\"%s\") from %s list (expired).", e->mask, e->reason, ListName); else - Log(LOG_INFO, + Log(LOG_NOTICE|LOG_snotice, "Deleted \"%s\" from %s list (expired).", e->mask, ListName); Lists_Unlink(h, last, e);