From 4396936f383cfc8098e43cece8e4b2af8f0a6fa4 Mon Sep 17 00:00:00 2001
From: LucentW <LucentW@users.noreply.github.com>
Date: Mon, 11 May 2015 21:50:48 +0200
Subject: [PATCH] Implement timestamp tracking of invites

Now lists nodes also have the "onlyonce" field, since the valid_until is
used to keep the timestamp of placing. Found no references to onlyonce
or about valid_until being == 1, though, so it might be unused, but
still available for other enhancements.
---
 src/ngircd/channel.c |  2 +-
 src/ngircd/lists.c   | 23 +++++++++++++++++++----
 src/ngircd/lists.h   |  3 ++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c
index a7c97d51..d8ee7b70 100644
--- a/src/ngircd/channel.c
+++ b/src/ngircd/channel.c
@@ -1120,7 +1120,7 @@ Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce, const char *who )
 {
 	struct list_head *h = Channel_GetListInvites(c);
 	LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
-	return Lists_Add(h, mask, onlyonce, who);
+	return Lists_Add(h, mask, time(NULL), who, onlyonce);
 }
 
 
diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c
index 247344e5..2ca67e9d 100644
--- a/src/ngircd/lists.c
+++ b/src/ngircd/lists.c
@@ -32,7 +32,8 @@ 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;
 };
 
 /**
@@ -65,7 +66,7 @@ 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.
+ * @return Validity: 0=unlimited, >0 until this time stamp.
  */
 GLOBAL time_t
 Lists_GetValidity(const struct list_elem *e)
@@ -74,6 +75,19 @@ Lists_GetValidity(const struct list_elem *e)
 	return e->valid_until;
 }
 
+/**
+ * Get "onlyonce" value stored in list element.
+ *
+ * @param list_elem 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.
  *
@@ -111,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 = false)
 {
 	struct list_elem *e, *newelem;
 
@@ -148,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;
 
@@ -363,7 +378,7 @@ 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,
diff --git a/src/ngircd/lists.h b/src/ngircd/lists.h
index db0f11a9..4206151e 100644
--- a/src/ngircd/lists.h
+++ b/src/ngircd/lists.h
@@ -36,7 +36,7 @@ GLOBAL struct list_elem *Lists_CheckDupeMask PARAMS((const struct list_head *hea
 					const char *mask));
 
 GLOBAL bool Lists_Add PARAMS((struct list_head *h, const char *Mask,
-			      time_t ValidUntil, const char *Reason));
+			      time_t ValidUntil, const char *Reason, bool OnlyOnce));
 GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask));
 GLOBAL unsigned long Lists_Count PARAMS((struct list_head *h));
 
@@ -46,6 +46,7 @@ GLOBAL void Lists_MakeMask PARAMS((const char *Pattern, char *mask, size_t len))
 GLOBAL const char *Lists_GetMask PARAMS((const struct list_elem *e));
 GLOBAL const char *Lists_GetReason PARAMS((const struct list_elem *e));
 GLOBAL time_t Lists_GetValidity PARAMS((const struct list_elem *e));
+GLOBAL bool Lists_GetOnlyOnce PARAMS((const struct list_elem *e));
 
 GLOBAL void Lists_Expire PARAMS((struct list_head *h, const char *ListName));