diff --git a/lib/icinga/Makefile.am b/lib/icinga/Makefile.am index 3da4dcdef..86b7d4336 100644 --- a/lib/icinga/Makefile.am +++ b/lib/icinga/Makefile.am @@ -28,6 +28,8 @@ libicinga_la_SOURCES = \ icinga-type.cpp \ icingaapplication.cpp \ icingaapplication.h \ + legacytimeperiod.cpp \ + legacytimeperiod.h \ macroprocessor.cpp \ macroprocessor.h \ macroresolver.cpp \ diff --git a/lib/icinga/icinga.vcxproj b/lib/icinga/icinga.vcxproj index 08137ebb2..ec069a002 100644 --- a/lib/icinga/icinga.vcxproj +++ b/lib/icinga/icinga.vcxproj @@ -32,6 +32,7 @@ NotUsing + @@ -58,6 +59,7 @@ + diff --git a/lib/icinga/legacytimeperiod.cpp b/lib/icinga/legacytimeperiod.cpp new file mode 100644 index 000000000..a990487fc --- /dev/null +++ b/lib/icinga/legacytimeperiod.cpp @@ -0,0 +1,160 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * 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. * + * * + * This program 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, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "icinga/legacytimeperiod.h" +#include "base/scriptfunction.h" +#include "base/convert.h" +#include "base/exception.h" +#include "base/logger_fwd.h" +#include +#include +#include +#include +#include + +using namespace icinga; + +REGISTER_SCRIPTFUNCTION(LegacyTimePeriod, &LegacyTimePeriod::ScriptFunc); + +bool LegacyTimePeriod::IsInDayDefinition(const String& daydef, tm *reference) +{ + if (daydef == "sunday" || daydef == "monday" || daydef == "tuesday" || + daydef == "wednesday" || daydef == "thursday" || daydef == "friday" || + daydef == "saturday") { + int wday; + + if (daydef == "sunday") + wday = 0; + else if (daydef == "monday") + wday = 1; + else if (daydef == "tuesday") + wday = 2; + else if (daydef == "wednesday") + wday = 3; + else if (daydef == "thursday") + wday = 4; + else if (daydef == "friday") + wday = 5; + else if (daydef == "saturday") + wday = 6; + + return reference->tm_wday == wday; + } + + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid day definition: " + daydef)); +} + +Dictionary::Ptr LegacyTimePeriod::ProcessTimeRange(const String& timerange, tm *reference) +{ + std::vector times; + + boost::algorithm::split(times, timerange, boost::is_any_of("-")); + + if (times.size() != 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid timerange: " + timerange)); + + std::vector hd1, hd2; + boost::algorithm::split(hd1, times[0], boost::is_any_of(":")); + + if (hd1.size() != 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid time specification: " + times[0])); + + boost::algorithm::split(hd2, times[1], boost::is_any_of(":")); + + if (hd2.size() != 2) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid time specification: " + times[1])); + + tm begin, end; + + begin = *reference; + begin.tm_sec = 0; + begin.tm_min = Convert::ToLong(hd1[1]); + begin.tm_hour = Convert::ToLong(hd1[0]); + + end = *reference; + end.tm_sec = 0; + end.tm_min = Convert::ToLong(hd2[1]); + end.tm_hour = Convert::ToLong(hd2[0]); + + Dictionary::Ptr segment = boost::make_shared(); + segment->Set("begin", mktime(&begin)); + segment->Set("end", mktime(&end)); + + return segment; +} + +void LegacyTimePeriod::ProcessTimeRanges(const String& timeranges, tm *reference, const Array::Ptr& result) +{ + std::vector ranges; + + boost::algorithm::split(ranges, timeranges, boost::is_any_of(",")); + + BOOST_FOREACH(const String& range, ranges) { + Dictionary::Ptr segment = ProcessTimeRange(range, reference); + result->Add(segment); + } +} + +Array::Ptr LegacyTimePeriod::ScriptFunc(const TimePeriod::Ptr& tp, double begin, double end) +{ + Array::Ptr segments = boost::make_shared(); + + Dictionary::Ptr ranges = tp->Get("ranges"); + + time_t tempts = begin; + tm reference; + +#ifdef _MSC_VER + tm *temp = localtime(&tempts); + + if (temp == NULL) { + BOOST_THROW_EXCEPTION(posix_error() + << boost::errinfo_api_function("localtime") + << boost::errinfo_errno(errno)); + } + + reference = *temp; +#else /* _MSC_VER */ + if (localtime_r(&tempts, &reference) == NULL) { + BOOST_THROW_EXCEPTION(posix_error() + << boost::errinfo_api_function("localtime_r") + << boost::errinfo_errno(errno)); + } +#endif /* _MSC_VER */ + + if (ranges) { + for (int i = 0; i <= (end - begin) / (24 * 60 * 60); i++) { + String key; + Value value; + BOOST_FOREACH(boost::tie(key, value), ranges) { + if (!IsInDayDefinition(key, &reference)) + continue; + + ProcessTimeRanges(value, &reference, segments); + } + + reference.tm_wday++; + } + } + + Log(LogDebug, "icinga", "Legacy timeperiod update returned " + Convert::ToString(segments->GetLength()) + " segments."); + + return segments; +} + diff --git a/lib/icinga/legacytimeperiod.h b/lib/icinga/legacytimeperiod.h new file mode 100644 index 000000000..818f45020 --- /dev/null +++ b/lib/icinga/legacytimeperiod.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * 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. * + * * + * This program 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, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef LEGACYTIMEPERIOD_H +#define LEGACYTIMEPERIOD_H + +#include "icinga/i2-icinga.h" +#include "icinga/service.h" +#include "base/dictionary.h" + +namespace icinga +{ + +/** + * Implements Icinga 1.x time periods. + * + * @ingroup icinga + */ +class I2_ICINGA_API LegacyTimePeriod +{ +public: + static Array::Ptr ScriptFunc(const TimePeriod::Ptr& tp, double start, double end); + + static bool IsInDayDefinition(const String& daydef, tm *reference); + static Dictionary::Ptr ProcessTimeRange(const String& timerange, tm *reference); + static void ProcessTimeRanges(const String& timeranges, tm *reference, const Array::Ptr& result); + +private: + LegacyTimePeriod(void); +}; + +} + +#endif /* LEGACYTIMEPERIOD_H */