#include <isc/string.h>
#include <isc/util.h>
+#include <dns/ttl.h>
+
#include <isccfg/duration.h>
/*
duration->iso8601 = true;
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+isccfg_parse_duration(isc_textregion_t *source, isccfg_duration_t *duration) {
+ isc_result_t result;
+
+ REQUIRE(duration != NULL);
+
+ duration->unlimited = false;
+ result = isccfg_duration_fromtext(source, duration);
+ if (result == ISC_R_BADNUMBER) {
+ /* Fallback to dns_ttl_fromtext. */
+ uint32_t ttl;
+ result = dns_ttl_fromtext(source, &ttl);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * With dns_ttl_fromtext() the information on optional
+ * units is lost, and is treated as seconds from now on.
+ */
+ duration->iso8601 = false;
+ duration->parts[6] = ttl;
+ }
+ }
+
+ return (result);
+}
+
+uint32_t
+isccfg_duration_toseconds(const isccfg_duration_t *duration) {
+ uint32_t seconds = 0;
+
+ REQUIRE(duration != NULL);
+
+ seconds += duration->parts[6]; /* Seconds */
+ seconds += duration->parts[5] * 60; /* Minutes */
+ seconds += duration->parts[4] * 3600; /* Hours */
+ seconds += duration->parts[3] * 86400; /* Days */
+ seconds += duration->parts[2] * 86400 * 7; /* Weeks */
+ /*
+ * The below additions are not entirely correct
+ * because days may very per month and per year.
+ */
+ seconds += duration->parts[1] * 86400 * 31; /* Months */
+ seconds += duration->parts[0] * 86400 * 365; /* Years */
+ return (seconds);
+}
*\li DNS_R_BADNUMBER
*/
+isc_result_t
+isccfg_parse_duration(isc_textregion_t *source, isccfg_duration_t *duration);
+/*%<
+ * Converts a duration string to a ISO 8601 duration.
+ * If the string does not start with a P (or p), fall back to TTL-style value.
+ * In that case the duration will be treated in seconds only.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li DNS_R_BADNUMBER
+ *\li DNS_R_BADTTL
+ */
+
+uint32_t
+isccfg_duration_toseconds(const isccfg_duration_t *duration);
+/*%<
+ * Converts an ISO 8601 duration to seconds.
+ * The conversion is approximate:
+ * - Months will be treated as 31 days.
+ * - Years will be treated as 365 days.
+ *
+ * Returns:
+ *\li The duration in seconds.
+ */
+
ISC_LANG_ENDDECLS
DE_CONST(str, tr.base);
tr.length = strlen(tr.base);
- result = isccfg_duration_fromtext(&tr, &duration);
- if (result == ISC_R_BADNUMBER) {
- /* Fallback to dns_ttl_fromtext. */
- (void)dns_ttl_fromtext(&tr, &time);
- return (time);
- }
+ result = isccfg_parse_duration(&tr, &duration);
if (result == ISC_R_SUCCESS) {
- time += duration.parts[6]; /* Seconds */
- time += duration.parts[5] * 60; /* Minutes */
- time += duration.parts[4] * 3600; /* Hours */
- time += duration.parts[3] * 86400; /* Days */
- time += duration.parts[2] * 86400 * 7; /* Weaks */
- time += duration.parts[1] * 86400 * 31; /* Months */
- time += duration.parts[0] * 86400 * 365; /* Years */
+ time = isccfg_duration_toseconds(&duration);
}
return (time);
}
uint32_t
cfg_obj_asduration(const cfg_obj_t *obj) {
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_duration);
- uint32_t duration = 0;
- duration += obj->value.duration.parts[6]; /* Seconds */
- duration += obj->value.duration.parts[5] * 60; /* Minutes */
- duration += obj->value.duration.parts[4] * 3600; /* Hours */
- duration += obj->value.duration.parts[3] * 86400; /* Days */
- duration += obj->value.duration.parts[2] * 86400 * 7; /* Weaks */
- /*
- * The below additions are not entirely correct
- * because days may very per month and per year.
- */
- duration += obj->value.duration.parts[1] * 86400 * 31; /* Months */
- duration += obj->value.duration.parts[0] * 86400 * 365; /* Years */
- return (duration);
+ return isccfg_duration_toseconds(&(obj->value.duration));
}
static isc_result_t
cfg_obj_t *obj = NULL;
isccfg_duration_t duration;
- duration.unlimited = false;
-
- result = isccfg_duration_fromtext(&pctx->token.value.as_textregion,
+ result = isccfg_parse_duration(&pctx->token.value.as_textregion,
&duration);
- if (result == ISC_R_BADNUMBER) {
- /* Fallback to dns_ttl_fromtext. */
- uint32_t ttl;
- result = dns_ttl_fromtext(&pctx->token.value.as_textregion,
- &ttl);
- if (result == ISC_R_SUCCESS) {
- /*
- * With dns_ttl_fromtext() the information on optional
- * units is lost, and is treated as seconds from now on.
- */
- duration.iso8601 = false;
- duration.parts[6] = ttl;
- }
- }
+
if (result == ISC_R_RANGE) {
cfg_parser_error(pctx, CFG_LOG_NEAR,
"duration or TTL out of range");