#include <sys/limits.h>
#include <stdint.h>
+#include <time.h>
char *ctrlvalue(const char *listdir, const char *ctrlstr);
char *ctrlcontent(const char *listdir, const char *ctrlstr);
{
return (ctrluim(listdir, ctrlstr, 0, USHRT_MAX, fallback));
}
+time_t ctrltimet(const char *listdir, const char *ctrlstr, time_t fallback);
#endif /* CTRLVALUE_H */
/*
- * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (C) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
#pragma once
+#include <time.h>
+
char *lowercase(const char *);
intmax_t strtoim(const char *np, intmax_t minval, intmax_t maxval,
const char **errpp);
uintmax_t strtouim(const char *, uintmax_t, uintmax_t, const char **);
void exec_or_die(const char *arg, ...);
int exec_and_wait(const char *arg, ...);
+time_t strtotimet(const char *np, const char **errpp);
free(val);
return (ret);
}
+
+time_t
+ctrltimet(const char *listdir, const char *ctrlstr, time_t fallback)
+{
+ const char *errstr;
+ char *val = ctrlvalue(listdir, ctrlstr);
+ time_t ret;
+
+ if (val == NULL)
+ return (fallback);
+
+ ret = strtotimet(val, &errstr);
+ if (errstr != NULL) {
+ log_error(LOG_ARGS, "Invalid value for '%s': %s", ctrlstr,
+ errstr);
+ return (fallback);
+ }
+ free(val);
+ return (ret);
+}
int clean_moderation(const char *listdir)
{
- time_t modreqlife = 0;
- char *modreqlifestr;
+ time_t modreqlife;
char *moddirname;
int ret;
- modreqlifestr = ctrlvalue(listdir, "modreqlife");
- if(modreqlifestr) {
- modreqlife = atol(modreqlifestr);
- free(modreqlifestr);
- }
- if(modreqlife == 0)
- modreqlife = MODREQLIFE;
-
+ modreqlife = ctrltimet(listdir, "modreqlife", MODREQLIFE);
moddirname = concatstr(2, listdir, "/moderation");
ret = delolder(moddirname, modreqlife);
struct dirent *dp;
char *mailname, *fromname, *toname, *reptoname, *from, *to, *repto;
char *ch, *dirname = concatstr(2, listdir, "/queue/");
- char *bouncelifestr;
struct stat st;
int fromfd, tofd, fd, err = 0;
- time_t t, bouncelife = 0;
+ time_t t, bouncelife;
if(chdir(dirname) < 0) {
log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
}
/* before we try again, check and see if it's old */
- bouncelifestr = ctrlvalue(listdir, "bouncelife");
- if(bouncelifestr) {
- bouncelife = atol(bouncelifestr);
- free(bouncelifestr);
- }
- if(bouncelife == 0)
- bouncelife = BOUNCELIFE;
-
+ bouncelife = ctrltimet(listdir, "bouncelife", BOUNCELIFE);
t = time(NULL);
if(t - st.st_mtime > bouncelife) {
unlink(mailname);
DIR *bouncedir;
char *dirname = concatstr(2, listdir, "/bounce/");
char *probefile, *address, *a, *firstbounce, *bouncedata;
- char *bouncelifestr;
struct dirent *dp;
struct stat st;
int fd;
- time_t bouncetime, t, bouncelife = 0;
+ time_t bouncetime, t, bouncelife;
if(chdir(dirname) < 0) {
log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
free(dirname);
- bouncelifestr = ctrlvalue(listdir, "bouncelife");
- if(bouncelifestr) {
- bouncelife = atol(bouncelifestr);
- free(bouncelifestr);
- }
-
- if(bouncelife == 0)
- bouncelife = BOUNCELIFE;
+ bouncelife = ctrltimet(listdir, "bouncelife", BOUNCELIFE);
while((dp = readdir(bouncedir)) != NULL) {
if((strcmp(dp->d_name, "..") == 0) ||
*/
#include <sys/wait.h>
+#include <sys/param.h>
#include <ctype.h>
#include <err.h>
return (ret);
}
+time_t
+strtotimet(const char *np, const char **errpp)
+{
+ if (sizeof(time_t) == 4)
+ return ((time_t)strtoim(np, INT_MIN, INT_MAX, errpp));
+ return ((time_t)strtoim(np, LLONG_MIN, LLONG_MAX, errpp));
+}
+
uintmax_t
strtouim(const char *np, uintmax_t minval, uintmax_t maxval, const char **errpp)
{
ATF_TC_WITHOUT_HEAD(write_rcpt_to);
ATF_TC_WITHOUT_HEAD(write_mail_from);
ATF_TC_WITHOUT_HEAD(write_mailbody_from_map);
+ATF_TC_WITHOUT_HEAD(strtotimet);
#ifndef NELEM
#define NELEM(array) (sizeof(array) / sizeof((array)[0]))
close(fd1);
}
+ATF_TC_BODY(strtotimet, tc)
+{
+ const char *errp;
+ char *str;
+ ATF_REQUIRE_EQ(strtotimet("10", &errp), 10);
+ ATF_CHECK(errp == NULL);
+ asprintf(&str, "1%"PRIdMAX, INTMAX_MAX);
+ ATF_REQUIRE_EQ(strtotimet(str, &errp), 0);
+ free(str);
+ ATF_REQUIRE(errp != NULL);
+ ATF_REQUIRE_STREQ(errp, "too large");
+}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, write_rcpt_to);
ATF_TP_ADD_TC(tp, write_mail_from);
ATF_TP_ADD_TC(tp, write_mailbody_from_map);
+ ATF_TP_ADD_TC(tp, strtotimet);
return (atf_no_error());
}