]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/lists.c
List and class handling: add optional "reason" text
[ngircd.git] / src / ngircd / lists.c
index 4f9a8855e043510df2c10a939ca115ef6743e6da..9a10ac7dab9f50995b3107b0f1b136cae92f9c44 100644 (file)
@@ -1,27 +1,26 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2011 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
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
- *
- * Management of IRC lists: ban, invite, ...
  */
 
-
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: lists.c,v 1.20 2006/12/07 17:57:20 fw Exp $";
+/**
+ * @file
+ * Management of IRC lists: ban, invite, etc.
+ */
 
 #include "imp.h"
 #include <assert.h>
 
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "log.h"
 #include "match.h"
@@ -40,7 +39,8 @@ static char UNUSED id[] = "$Id: lists.c,v 1.20 2006/12/07 17:57:20 fw Exp $";
 struct list_elem {
        struct list_elem *next;
        char mask[MASK_LEN];
-       bool onlyonce;
+       char *reason;
+       time_t valid_until;     /** 0: unlimited; 1: once; t(>1): until t */
 };
 
 
@@ -50,6 +50,19 @@ Lists_GetMask(const struct list_elem *e)
        return e->mask;
 }
 
+GLOBAL const char *
+Lists_GetReason(const struct list_elem *e)
+{
+       assert(e != NULL);
+       return e->reason;
+}
+
+GLOBAL time_t
+Lists_GetValidity(const struct list_elem *e)
+{
+       assert(e != NULL);
+       return e->valid_until;
+}
 
 GLOBAL struct list_elem*
 Lists_GetFirst(const struct list_head *h)
@@ -64,9 +77,18 @@ Lists_GetNext(const struct list_elem *e)
        return e->next;
 }
 
-
+/**
+ * Add a new mask to a list.
+ *
+ * @param header List head.
+ * @param Mask The IRC mask to add to the list.
+ * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
+ * @param Reason Reason string or NULL, if no reason should be saved.
+ * @return true on success, false otherwise.
+ */
 bool
-Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
+Lists_Add(struct list_head *header, const char *Mask, time_t ValidUntil,
+         const char *Reason)
 {
        struct list_elem *e, *newelem;
 
@@ -80,15 +102,24 @@ Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
        newelem = malloc(sizeof(struct list_elem));
        if( ! newelem ) {
                Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
-               return NULL;
+               return false;
        }
 
-       strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
-       newelem->onlyonce = OnlyOnce;
+       strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
+       if (Reason) {
+               newelem->reason = malloc(strlen(Reason) + 1);
+               if (newelem->reason)
+                       strlcpy(newelem->reason, Reason, strlen(Reason) + 1);
+               else
+                       Log(LOG_EMERG,
+                           "Can't allocate memory for new list reason text!");
+       }
+       else
+               newelem->reason = NULL;
+       newelem->valid_until = ValidUntil;
        newelem->next = e;
        header->first = newelem;
 
-       LogDebug("Added \"%s\" to invite list", Mask);
        return true;
 }
 
@@ -102,6 +133,8 @@ Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *vi
        if (p) p->next = victim->next;
        else header->first = victim->next;
 
+       if (victim->reason)
+               free(victim->reason);
        free(victim);
 }
 
@@ -143,7 +176,9 @@ Lists_Free(struct list_head *head)
                LogDebug("Deleted \"%s\" from invite list" , e->mask);
                victim = e;
                e = e->next;
-               free( victim );
+               if (victim->reason)
+                       free(victim->reason);
+               free(victim);
        }
 }
 
@@ -162,8 +197,8 @@ Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
 }
 
 
-GLOBAL char *
-Lists_MakeMask( char *Pattern )
+GLOBAL const char *
+Lists_MakeMask(const char *Pattern)
 {
        /* This function generats a valid IRC mask of "any" string. This
         * mask is only valid until the next call to Lists_MakeMask(),
@@ -212,27 +247,37 @@ Lists_MakeMask( char *Pattern )
 } /* Lists_MakeMask */
 
 
-
 bool
 Lists_Check( struct list_head *header, CLIENT *Client)
 {
-       struct list_elem *e, *last;
+       struct list_elem *e, *last, *next;
 
        assert( header != NULL );
 
        e = header->first;
        last = NULL;
 
-       while( e ) {
-               if( Match( e->mask, Client_Mask( Client ))) {
-                       if( e->onlyonce ) { /* delete entry */
-                               LogDebug("Deleted \"%s\" from list", e->mask);
+       while (e) {
+               next = e->next;
+               if (e->valid_until > 1 && e->valid_until < time(NULL)) {
+                       /* Entry is expired, delete it */
+                       LogDebug("Deleted \"%s\" from list (expired).",
+                                e->mask);
+                       Lists_Unlink(header, last, e);
+                       e = next;
+                       continue;
+               }
+               if (Match(e->mask, Client_Mask(Client))) {
+                       if (e->valid_until == 1 ) {
+                               /* Entry is valid only once, delete it */
+                               LogDebug("Deleted \"%s\" from list (used).",
+                                        e->mask);
                                Lists_Unlink(header, last, e);
                        }
                        return true;
                }
                last = e;
-               e = e->next;
+               e = next;
        }
 
        return false;