# the library search path.
lib_LTLIBRARIES = libi2ncommon.la
-include_HEADERS = containerfunc.hpp daemonfunc.hpp filefunc.hxx \
+include_HEADERS = containerfunc.hpp cron.hpp daemonfunc.hpp filefunc.hxx \
i2n_configdata.hpp i2n_configfile.hpp insocketstream.hxx ip_type.hxx ipfunc.hxx \
log_macros.hpp logfunc.hpp logread.hxx oftmpstream.hxx pidfile.hpp pipestream.hxx \
pointer_func.hpp signalfunc.hpp source_track_basics.hpp stringfunc.hxx timefunc.hxx \
tracefunc.hpp userfunc.hpp
-libi2ncommon_la_SOURCES = containerfunc.cpp daemonfunc.cpp filefunc.cpp \
- i2n_configfile.cpp ipfunc.cpp logfunc.cpp logread.cpp oftmpstream.cpp pidfile.cpp \
- pointer_func.cpp signalfunc.cpp source_track_basics.cpp stringfunc.cpp timefunc.cpp \
- tracefunc.cpp userfunc.cpp
+libi2ncommon_la_SOURCES = containerfunc.cpp cron.cpp daemonfunc.cpp \
+ filefunc.cpp i2n_configfile.cpp ipfunc.cpp logfunc.cpp logread.cpp oftmpstream.cpp \
+ pidfile.cpp pointer_func.cpp signalfunc.cpp source_track_basics.cpp stringfunc.cpp \
+ timefunc.cpp tracefunc.cpp userfunc.cpp
# Note: If you specify a:b:c as the version in the next line,
# the library that is made has version (a-c).c.b. In this
--- /dev/null
+
+/** @file
+ * @brief repeating time-points and intervals
+ *
+ * @copyright Copyright © 2009 by Intra2net AG
+ * @license commercial
+ * @contact info@intra2net.com
+ *
+ */
+#include <time.h>
+
+#include <stdexcept>
+
+#include <cron.hpp>
+
+bool WeekCron::is_sane()
+{
+ if (begin < 0 || begin > 86399)
+ return false;
+
+ if (every != -1)
+ {
+ if (end < 0 || end > 86399 ||
+ every < 0 || every > 86399 ||
+ begin > end)
+ return false;
+ }
+
+ return true;
+}
+
+time_t WeekCron::get_next_run(time_t calc_from)
+{
+ if (!calc_from)
+ calc_from=time(NULL);
+
+ if (!is_sane())
+ throw std::runtime_error("illegal cron value");
+
+ if (calc_from <= 86400)
+ throw std::runtime_error("WeekCron doesn't work for times near 0");
+
+ if (week.none_set())
+ return 0;
+
+ if (every == -1)
+ {
+ // point in time
+ return get_next_point(calc_from);
+ }
+ else
+ {
+ // interval
+
+ // TODO
+ }
+}
+
+time_t WeekCron::get_next_point(time_t calc_from)
+{
+ struct tm ft;
+ localtime_r(&calc_from,&ft);
+
+ // take care of the weekday
+ ft.tm_mday+=week.days_till_set(static_cast<WEEK::WEEKDAY>(ft.tm_wday));
+
+ ft.tm_hour=0;
+ ft.tm_min=0;
+ ft.tm_sec=begin;
+
+ time_t target=mktime(&ft);
+
+ // todays schedule could already been through
+ if (target < calc_from)
+ {
+ ft.tm_mday++;
+ target=mktime(&ft);
+ }
+
+ return target;
+}
+
+
--- /dev/null
+/** @file
+ * @brief repeating time-points and intervals
+ *
+ * @copyright Copyright © 2009 by Intra2net AG
+ * @license commercial
+ * @contact info@intra2net.com
+ *
+ */
+
+#ifndef __CRON_HPP
+#define __CRON_HPP
+
+#include <time.h>
+
+#include <timefunc.hxx>
+
+/**
+ @brief time-points and intervals repeating each week
+ @note begin and end are given in seconds since start of the day
+*/
+class WeekCron
+{
+ private:
+
+ int begin;
+ int end;
+ int every;
+ WEEK week;
+
+ time_t get_next_point(time_t calc_from=0);
+
+ public:
+
+ WeekCron(void)
+ : begin(0), end(0), every(-1), week()
+ { }
+
+ WeekCron(const std::string& daystring, int _begin)
+ : begin(_begin), end(0), every(-1), week(daystring)
+ { }
+
+ WeekCron(const std::string& daystring, int _begin, int _end, int _every)
+ : begin(_begin), end(_end), every(_every), week(daystring)
+ { }
+
+ bool is_sane();
+
+ time_t get_next_run(time_t calc_from=0);
+
+};
+
+#endif
}
}
+/**
+ @brief returns the number of days till the next weekday which is set
+ @param start weekday to start checking
+ @note returns 0 if the start-day is set
+*/
+int WEEK::days_till_set(WEEKDAY start)
+{
+ if (none_set())
+ return -1;
+
+ for (unsigned int days=0; days < 8; days++)
+ {
+ unsigned int check=start+days;
+ if (check > 6)
+ check-=7;
+ if (is_set(static_cast<WEEKDAY>(check)))
+ return days;
+ }
+
+ throw logic_error("can't find next weekday");
+
+ // fake
+ return -1;
+}
+
std::string WEEK::get_daystring() const
{
ostringstream out;
bool none_set() const
{ return days.none(); }
+ int days_till_set(WEEKDAY day);
+
std::string get_daystring() const;
std::string get_displaystring() const;
std::string get_netfilterstring() const;
METASOURCES = AUTO
check_PROGRAMS = test
test_SOURCES = ip_range.cpp stringfunc.cpp test.cpp test_containerfunc.cpp \
- test_filefunc.cpp test_global_config.cpp test_logging.cpp test_pidfile.cpp \
- test_timefunc.cpp
+ test_cron.cpp test_filefunc.cpp test_global_config.cpp test_logging.cpp \
+ test_pidfile.cpp test_timefunc.cpp
test_LDADD = $(top_builddir)/src/libi2ncommon.la \
$(top_builddir)/configlib/libi2ncommon_config.la @CPPUNIT_LIBS@
--- /dev/null
+/** @file
+ * @brief unit test for cron functions.
+ *
+ * @copyright Copyright © 2009 by Intra2net AG
+ * @license commercial
+ * @contact info@intra2net.com
+ *
+ */
+
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <time.h>
+#include <stdlib.h>
+
+#include <cron.hpp>
+
+using namespace std;
+using namespace CppUnit;
+
+class TestCronFunc : public TestFixture
+{
+ CPPUNIT_TEST_SUITE(TestCronFunc);
+
+ CPPUNIT_TEST(NotYetToday);
+ CPPUNIT_TEST(LaterToday);
+ CPPUNIT_TEST(Tomorrow);
+ CPPUNIT_TEST(NextWeek);
+
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void setUp()
+ {
+ // our check-values are set for Germany
+ setenv("TZ",":Europe/Berlin",1);
+ }
+
+ void tearDown()
+ { }
+
+ void NotYetToday()
+ {
+ WeekCron cron("2345",3600);
+ CPPUNIT_ASSERT_EQUAL( 1233100800, static_cast<int>(cron.get_next_run(1233099657)));
+ }
+
+ void LaterToday()
+ {
+ WeekCron cron("2345",3600);
+ CPPUNIT_ASSERT_EQUAL( 1233187200, static_cast<int>(cron.get_next_run(1233100801)));
+ }
+
+ void Tomorrow()
+ {
+ WeekCron cron("45",3600);
+ CPPUNIT_ASSERT_EQUAL( 1233187200, static_cast<int>(cron.get_next_run(1233099657)));
+ }
+
+ void NextWeek()
+ {
+ WeekCron cron("1",3600);
+ CPPUNIT_ASSERT_EQUAL( 1233532800, static_cast<int>(cron.get_next_run(1233099657)));
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TestCronFunc);