pending list fixed;
This commit is contained in:
parent
891010dd13
commit
8f2ec43dca
31
include/ilib/misc.h
Normal file
31
include/ilib/misc.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* this 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.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2007, 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* misc.h: misc definitions and functions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __MISC_H__
|
||||||
|
#define __MISC_H__
|
||||||
|
|
||||||
|
/* Some various constants used across the project */
|
||||||
|
#define PATHLEN_MAX 2048
|
||||||
|
|
||||||
|
/* Build time constants */
|
||||||
|
#define PENDING_ID_LEN 16
|
||||||
|
#define DEFAULT_PENDING_TTL 86400 /* default TTL for confirmation email */
|
||||||
|
|
||||||
|
#endif /* __MISC_H__ */
|
||||||
@ -1,23 +1,41 @@
|
|||||||
/* pending.h - Pending subscription state tracker using splay tree */
|
/*
|
||||||
|
* this 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.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2007, 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* pending.h: maintain a pending list of emails
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef __PENDING_H__
|
#ifndef __PENDING_H__
|
||||||
#define __PENDING_H__
|
#define __PENDING_H__
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ilib/splay.h>
|
#include <ilib/splay.h>
|
||||||
|
#include <ilib/misc.h>
|
||||||
#define PENDING_ID_LEN 16
|
|
||||||
|
|
||||||
typedef struct pending_entry {
|
typedef struct pending_entry {
|
||||||
splay_node_t node;
|
splay_node_t node;
|
||||||
char token[PENDING_ID_LEN + 1]; /* Unique hex string token */
|
char token[PENDING_ID_LEN + 1];
|
||||||
char *email; /* Applicant email address */
|
char *email;
|
||||||
time_t created_at; /* Unix timestamp for TTL check */
|
time_t created_at; /* ttl to compare */
|
||||||
} pending_entry_t;
|
} pending_entry_t;
|
||||||
|
|
||||||
typedef struct pending_pool {
|
typedef struct pending_pool {
|
||||||
splay_t tree;
|
splay_t tree;
|
||||||
char *filepath;
|
char *filepath;
|
||||||
long ttl_seconds; /* Default TTL: e.g., 86400 (24h) */
|
long ttl_seconds; /* TTL defined for the pending list */
|
||||||
} pending_pool_t;
|
} pending_pool_t;
|
||||||
|
|
||||||
int pending_pool_init(pending_pool_t *pool, const char *filepath, long ttl_seconds);
|
int pending_pool_init(pending_pool_t *pool, const char *filepath, long ttl_seconds);
|
||||||
|
|||||||
@ -8,7 +8,8 @@ noinst_HEADERS = \
|
|||||||
$(top_srcdir)/include/ilib/pending.h \
|
$(top_srcdir)/include/ilib/pending.h \
|
||||||
$(top_srcdir)/include/ilib/splay.h \
|
$(top_srcdir)/include/ilib/splay.h \
|
||||||
$(top_srcdir)/include/ilib/subscribers.h \
|
$(top_srcdir)/include/ilib/subscribers.h \
|
||||||
$(top_srcdir)/include/ilib/template.h
|
$(top_srcdir)/include/ilib/template.h \
|
||||||
|
$(top_srcdir)/include/ilib/misc.h
|
||||||
|
|
||||||
# daemon sources
|
# daemon sources
|
||||||
subrelayd_SOURCES = \
|
subrelayd_SOURCES = \
|
||||||
|
|||||||
@ -1,4 +1,25 @@
|
|||||||
/* pending.c - Pending subscription tracker implementation */
|
/*
|
||||||
|
* this 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.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2007, 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* pending.c: maintain a pending list of emails
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -7,6 +28,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <ilib/misc.h>
|
||||||
#include <ilib/pending.h>
|
#include <ilib/pending.h>
|
||||||
|
|
||||||
/* Case-sensitive token comparator for splay tree */
|
/* Case-sensitive token comparator for splay tree */
|
||||||
@ -29,7 +51,7 @@ static char *trim_whitespace(char *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates a secure random 16-character hex token via /dev/urandom */
|
/* Generates a secure random hex token via /dev/urandom */
|
||||||
static void generate_token(char *buf, size_t len)
|
static void generate_token(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
static const char hex[] = "0123456789abcdef";
|
static const char hex[] = "0123456789abcdef";
|
||||||
@ -38,7 +60,7 @@ static void generate_token(char *buf, size_t len)
|
|||||||
int fd = open("/dev/urandom", O_RDONLY);
|
int fd = open("/dev/urandom", O_RDONLY);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
if (read(fd, bytes, sizeof(bytes)) != sizeof(bytes)) {
|
if (read(fd, bytes, sizeof(bytes)) != sizeof(bytes)) {
|
||||||
/* Fallback pseudo-random seeding if read fails */
|
/* fallback pseudo-random (rand()) seeding if read fails */
|
||||||
for (size_t i = 0; i < sizeof(bytes); i++) bytes[i] = (unsigned char)rand();
|
for (size_t i = 0; i < sizeof(bytes); i++) bytes[i] = (unsigned char)rand();
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -61,7 +83,8 @@ int pending_pool_init(pending_pool_t *pool, const char *filepath, long ttl_secon
|
|||||||
pool->filepath = strdup(filepath);
|
pool->filepath = strdup(filepath);
|
||||||
if (!pool->filepath) return -ENOMEM;
|
if (!pool->filepath) return -ENOMEM;
|
||||||
|
|
||||||
pool->ttl_seconds = (ttl_seconds > 0) ? ttl_seconds : 86400; /* Default 24h */
|
/* Default is 24h, let's use config for this in the future */
|
||||||
|
pool->ttl_seconds = (ttl_seconds > 0) ? ttl_seconds : DEFAULT_PENDING_TTL;
|
||||||
|
|
||||||
return splay_init(&pool->tree, pending_cmp);
|
return splay_init(&pool->tree, pending_cmp);
|
||||||
}
|
}
|
||||||
@ -184,6 +207,10 @@ int pending_load_file(pending_pool_t *pool)
|
|||||||
|
|
||||||
snprintf(entry->token, sizeof(entry->token), "%s", token);
|
snprintf(entry->token, sizeof(entry->token), "%s", token);
|
||||||
entry->email = strdup(email);
|
entry->email = strdup(email);
|
||||||
|
if(!entry->email) {
|
||||||
|
free(entry);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
entry->created_at = created_at;
|
entry->created_at = created_at;
|
||||||
|
|
||||||
if (splay_insert(&pool->tree, &entry->node, entry->token) != 0) {
|
if (splay_insert(&pool->tree, &entry->node, entry->token) != 0) {
|
||||||
@ -203,13 +230,13 @@ int pending_save_file(pending_pool_t *pool)
|
|||||||
|
|
||||||
pending_purge_expired(pool);
|
pending_purge_expired(pool);
|
||||||
|
|
||||||
char tmp_path[1024];
|
char tmp_path[PATHLEN_MAX];
|
||||||
snprintf(tmp_path, sizeof(tmp_path), "%s.tmp.%d", pool->filepath, getpid());
|
snprintf(tmp_path, sizeof(tmp_path), "%s.tmp.%d", pool->filepath, getpid());
|
||||||
|
|
||||||
FILE *fp = fopen(tmp_path, "w");
|
FILE *fp = fopen(tmp_path, "w");
|
||||||
if (!fp) return -errno;
|
if (!fp) return -errno;
|
||||||
|
|
||||||
fprintf(fp, "# Subrelay Pending Subscriptions State\n");
|
fprintf(fp, "# Subrelay list of pending subscriptions emails\n");
|
||||||
fprintf(fp, "# TOKEN TIMESTAMP EMAIL\n\n");
|
fprintf(fp, "# TOKEN TIMESTAMP EMAIL\n\n");
|
||||||
|
|
||||||
splay_node_t *curr = splay_first(&pool->tree);
|
splay_node_t *curr = splay_first(&pool->tree);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user