summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-04-11 15:59:44 +0100
committerPatrick McHardy <kaber@trash.net>2015-04-12 19:59:27 +0100
commit0974fa84f162aecf16b4c252dcb438f7149856ab (patch)
treeaea0d6ec01b07259e2b1de11cd78131d2a6860cf
parent262b97bd112cbaed098c7941bd452c7b16a89646 (diff)
datatype: seperate time parsing/printing from time_type
Seperate relative time parsing and printing from the time_type to make it usable for set and set element time related parameters. Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/datatype.h4
-rw-r--r--src/datatype.c66
2 files changed, 45 insertions, 25 deletions
diff --git a/include/datatype.h b/include/datatype.h
index 3c3f42f3..2a6a4fca 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -231,4 +231,8 @@ concat_subtype_lookup(uint32_t type, unsigned int n)
return datatype_lookup(concat_subtype_id(type, n));
}
+extern void time_print(uint64_t seconds);
+extern struct error_record *time_parse(const struct location *loc,
+ const char *c, uint64_t *res);
+
#endif /* NFTABLES_DATATYPE_H */
diff --git a/src/datatype.c b/src/datatype.c
index 1c837152..f93337b1 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -760,11 +760,9 @@ const struct datatype icmpx_code_type = {
.sym_tbl = &icmpx_code_tbl,
};
-static void time_type_print(const struct expr *expr)
+void time_print(uint64_t seconds)
{
- uint64_t days, hours, minutes, seconds;
-
- seconds = mpz_get_uint64(expr->value);
+ uint64_t days, hours, minutes;
days = seconds / 86400;
seconds %= 86400;
@@ -801,8 +799,8 @@ static uint32_t str2int(char *tmp, const char *c, int k)
return atoi(tmp);
}
-static struct error_record *time_type_parse(const struct expr *sym,
- struct expr **res)
+struct error_record *time_parse(const struct location *loc, const char *str,
+ uint64_t *res)
{
int i, len;
unsigned int k = 0;
@@ -811,64 +809,82 @@ static struct error_record *time_type_parse(const struct expr *sym,
uint64_t d = 0, h = 0, m = 0, s = 0;
uint32_t mask = 0;
- c = sym->identifier;
+ c = str;
len = strlen(c);
for (i = 0; i < len; i++, c++) {
switch (*c) {
case 'd':
- if (mask & DAY) {
- return error(&sym->location,
+ if (mask & DAY)
+ return error(loc,
"Day has been specified twice");
- }
+
d = str2int(tmp, c, k);
k = 0;
mask |= DAY;
break;
case 'h':
- if (mask & HOUR) {
- return error(&sym->location,
+ if (mask & HOUR)
+ return error(loc,
"Hour has been specified twice");
- }
+
h = str2int(tmp, c, k);
k = 0;
mask |= HOUR;
break;
case 'm':
- if (mask & MIN) {
- return error(&sym->location,
+ if (mask & MIN)
+ return error(loc,
"Minute has been specified twice");
- }
+
m = str2int(tmp, c, k);
k = 0;
mask |= MIN;
break;
case 's':
- if (mask & SECS) {
- return error(&sym->location,
+ if (mask & SECS)
+ return error(loc,
"Second has been specified twice");
- }
+
s = str2int(tmp, c, k);
k = 0;
mask |= SECS;
break;
default:
if (!isdigit(*c))
- return error(&sym->location, "wrong format");
+ return error(loc, "wrong time format");
- if (k++ >= array_size(tmp)) {
- return error(&sym->location,
- "value too large");
- }
+ if (k++ >= array_size(tmp))
+ return error(loc, "value too large");
break;
}
}
/* default to seconds if no unit was specified */
if (!mask)
- s = atoi(sym->identifier);
+ s = atoi(str);
else
s = 24*60*60*d+60*60*h+60*m+s;
+ *res = s;
+ return NULL;
+}
+
+
+static void time_type_print(const struct expr *expr)
+{
+ time_print(mpz_get_uint64(expr->value));
+}
+
+static struct error_record *time_type_parse(const struct expr *sym,
+ struct expr **res)
+{
+ struct error_record *erec;
+ uint64_t s;
+
+ erec = time_parse(&sym->location, sym->identifier, &s);
+ if (erec != NULL)
+ return erec;
+
if (s > UINT32_MAX)
return error(&sym->location, "value too large");