From 916f95cb58604038695347ee41a430d8ca1f0556 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 14 Nov 2013 13:41:13 +0100 Subject: debloat and reorganize code split app into procd and init binaries remove log support, this is an external service now Signed-off-by: John Crispin --- validate.c | 1002 ------------------------------------------------------------ 1 file changed, 1002 deletions(-) delete mode 100644 validate.c (limited to 'validate.c') diff --git a/validate.c b/validate.c deleted file mode 100644 index f94a071..0000000 --- a/validate.c +++ /dev/null @@ -1,1002 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "libvalidate.h" - -enum dt_optype { - OP_UNKNOWN, - OP_BOOL, - OP_NUMBER, - OP_STRING, - OP_FUNCTION -}; - -struct dt_fun; - -struct dt_op { - enum dt_optype type; - const char *next; - int length; - int nextop; - union { - bool boolean; - double number; - const char *string; - struct dt_fun *function; - } value; -}; - -struct dt_state { - int pos; - int depth; - const char *value; - struct dt_op stack[32]; -}; - -struct dt_fun { - const char *name; - bool (*call)(struct dt_state *s, int nargs); -}; - -static bool -dt_test_number(double number, const char *value) -{ - char *e; - double n; - - n = strtod(value, &e); - - return (e > value && *e == 0 && n == number); -} - -static bool -dt_test_string(const char *s, const char *end, const char *value) -{ - bool esc = false; - - while (*value) - { - if (s > end) - return false; - - if (!esc && *s == '\\') - { - s++; - - if (s >= end) - break; - - esc = true; - continue; - } - - if (*s != *value) - return false; - - esc = false; - value++; - s++; - } - - return (*s == *value || (s > end && *value == 0)); -} - -static bool -dt_step(struct dt_state *s); - -static bool -dt_call(struct dt_state *s); - -static bool -dt_type_or(struct dt_state *s, int nargs) -{ - while (nargs--) - if (dt_step(s)) - return true; - - return false; -} - -static bool -dt_type_and(struct dt_state *s, int nargs) -{ - while (nargs--) - if (!dt_step(s)) - return false; - - return true; -} - -static bool -dt_type_not(struct dt_state *s, int nargs) -{ - if (!nargs) - return false; - - return !dt_step(s); -} - -static bool -dt_type_neg(struct dt_state *s, int nargs) -{ - bool rv; - const char *value = s->value; - - if (!nargs) - return false; - - if (*s->value == '!') - while (isspace(*++s->value)); - - rv = dt_step(s); - s->value = value; - - return rv; -} - -static bool -dt_type_list(struct dt_state *s, int nargs) -{ - bool rv = true; - int pos = s->pos; - char *p, *str = strdup(s->value); - const char *value = s->value; - - if (!str || !nargs) - return false; - - for (p = strtok(str, " \t"); p; p = strtok(NULL, " \t")) - { - s->value = p; - - if (!dt_step(s)) - { - rv = false; - break; - } - - s->pos = pos; - } - - s->value = value; - free(str); - - return rv; -} - -static bool -dt_type_min(struct dt_state *s, int nargs) -{ - int n; - char *e; - - if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER) - { - n = strtol(s->value, &e, 0); - - return (e > s->value && *e == 0 && - n >= s->stack[s->pos].value.number); - } - - return false; -} - -static bool -dt_type_max(struct dt_state *s, int nargs) -{ - int n; - char *e; - - if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER) - { - n = strtol(s->value, &e, 0); - - return (e > s->value && *e == 0 && - n <= s->stack[s->pos].value.number); - } - - return false; -} - -static bool -dt_type_range(struct dt_state *s, int nargs) -{ - int n; - char *e; - - if (nargs >= 2 && - s->stack[s->pos].type == OP_NUMBER && - s->stack[s->pos + 1].type == OP_NUMBER) - { - n = strtol(s->value, &e, 0); - - return (e > s->value && *e == 0 && - n >= s->stack[s->pos].value.number && - n <= s->stack[s->pos + 1].value.number); - } - - return false; -} - -static bool -dt_type_minlen(struct dt_state *s, int nargs) -{ - if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER) - return (strlen(s->value) >= s->stack[s->pos].value.number); - - return false; -} - -static bool -dt_type_maxlen(struct dt_state *s, int nargs) -{ - if (nargs >= 1 && s->stack[s->pos].type == OP_NUMBER) - return (strlen(s->value) <= s->stack[s->pos].value.number); - - return false; -} - -static bool -dt_type_rangelen(struct dt_state *s, int nargs) -{ - if (nargs >= 2 && - s->stack[s->pos].type == OP_NUMBER && - s->stack[s->pos + 1].type == OP_NUMBER) - return (strlen(s->value) >= s->stack[s->pos].value.number && - strlen(s->value) <= s->stack[s->pos + 1].value.number); - - return false; -} - -static bool -dt_type_int(struct dt_state *s, int nargs) -{ - char *e; - - strtol(s->value, &e, 0); - - return (e > s->value && *e == 0); -} - -static bool -dt_type_uint(struct dt_state *s, int nargs) -{ - int n; - char *e; - - n = strtol(s->value, &e, 0); - - return (e > s->value && *e == 0 && n >= 0); -} - -static bool -dt_type_float(struct dt_state *s, int nargs) -{ - char *e; - - strtod(s->value, &e); - - return (e > s->value && *e == 0); -} - -static bool -dt_type_ufloat(struct dt_state *s, int nargs) -{ - int n; - char *e; - - n = strtod(s->value, &e); - - return (e > s->value && *e == 0 && n >= 0.0); -} - -static bool -dt_type_bool(struct dt_state *s, int nargs) -{ - int i; - const char *values[] = { - "0", "off", "false", "no", - "1", "on", "true", "yes" - }; - - for (i = 0; i < sizeof(values) / sizeof(values[0]); i++) - if (!strcasecmp(values[i], s->value)) - return true; - - return false; -} - -static bool -dt_type_string(struct dt_state *s, int nargs) -{ - return true; -} - -static bool -dt_type_ip4addr(struct dt_state *s, int nargs) -{ - struct in6_addr a; - return inet_pton(AF_INET, s->value, &a); -} - -static bool -dt_type_ip6addr(struct dt_state *s, int nargs) -{ - struct in6_addr a; - return inet_pton(AF_INET6, s->value, &a); -} - -static bool -dt_type_ipaddr(struct dt_state *s, int nargs) -{ - return (dt_type_ip4addr(s, 0) || dt_type_ip6addr(s, 0)); -} - -static bool -dt_type_netmask4(struct dt_state *s, int nargs) -{ - int i; - struct in_addr a; - - if (!inet_pton(AF_INET, s->value, &a)) - return false; - - if (a.s_addr == 0) - return true; - - a.s_addr = ntohl(a.s_addr); - - for (i = 0; (i < 32) && !(a.s_addr & (1 << i)); i++); - - return ((uint32_t)(~((1 << i) - 1)) == a.s_addr); -} - -static bool -dt_type_netmask6(struct dt_state *s, int nargs) -{ - int i; - struct in6_addr a; - - if (!inet_pton(AF_INET6, s->value, &a)) - return false; - - for (i = 0; (i < 16) && (a.s6_addr[i] == 0xFF); i++); - - if (i == 16) - return true; - - if ((a.s6_addr[i] != 255) && (a.s6_addr[i] != 254) && - (a.s6_addr[i] != 252) && (a.s6_addr[i] != 248) && - (a.s6_addr[i] != 240) && (a.s6_addr[i] != 224) && - (a.s6_addr[i] != 192) && (a.s6_addr[i] != 128) && - (a.s6_addr[i] != 0)) - return false; - - for (; (i < 16) && (a.s6_addr[i] == 0); i++); - - return (i == 16); -} - -static bool -dt_type_cidr4(struct dt_state *s, int nargs) -{ - int n; - struct in_addr a; - char *p, buf[sizeof("255.255.255.255/32\0")]; - - if (strlen(s->value) >= sizeof(buf)) - return false; - - strcpy(buf, s->value); - p = strchr(buf, '/'); - - if (p) - { - *p++ = 0; - - n = strtoul(p, &p, 10); - - if ((*p != 0) || (n > 32)) - return false; - } - - return inet_pton(AF_INET, buf, &a); -} - -static bool -dt_type_cidr6(struct dt_state *s, int nargs) -{ - int n; - struct in6_addr a; - char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/128\0")]; - - if (strlen(s->value) >= sizeof(buf)) - return false; - - strcpy(buf, s->value); - p = strchr(buf, '/'); - - if (p) - { - *p++ = 0; - - n = strtoul(p, &p, 10); - - if ((*p != 0) || (n > 128)) - return false; - } - - return inet_pton(AF_INET6, buf, &a); -} - -static bool -dt_type_cidr(struct dt_state *s, int nargs) -{ - return (dt_type_cidr4(s, 0) || dt_type_cidr6(s, 0)); -} - -static bool -dt_type_ipmask4(struct dt_state *s, int nargs) -{ - bool rv; - struct in_addr a; - const char *value; - char *p, buf[sizeof("255.255.255.255/255.255.255.255\0")]; - - if (strlen(s->value) >= sizeof(buf)) - return false; - - strcpy(buf, s->value); - p = strchr(buf, '/'); - - if (p) - { - *p++ = 0; - - value = s->value; - s->value = p; - rv = dt_type_netmask4(s, 0); - s->value = value; - - if (!rv) - return false; - } - - return inet_pton(AF_INET, buf, &a); -} - -static bool -dt_type_ipmask6(struct dt_state *s, int nargs) -{ - bool rv; - struct in6_addr a; - const char *value; - char *p, buf[sizeof("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255/" - "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:255.255.255.255\0")]; - - if (strlen(s->value) >= sizeof(buf)) - return false; - - strcpy(buf, s->value); - p = strchr(buf, '/'); - - if (p) - { - *p++ = 0; - - value = s->value; - s->value = p; - rv = dt_type_netmask6(s, 0); - s->value = value; - - if (!rv) - return false; - } - - return inet_pton(AF_INET6, buf, &a); -} - -static bool -dt_type_ipmask(struct dt_state *s, int nargs) -{ - return (dt_type_ipmask4(s, 0) || dt_type_ipmask6(s, 0)); -} - -static bool -dt_type_port(struct dt_state *s, int nargs) -{ - int n; - char *e; - - n = strtoul(s->value, &e, 10); - - return (e > s->value && *e == 0 && n <= 65535); -} - -static bool -dt_type_portrange(struct dt_state *s, int nargs) -{ - int n, m; - char *e; - - n = strtoul(s->value, &e, 10); - - if (e == s->value || *e != '-') - return false; - - m = strtoul(e + 1, &e, 10); - - return (*e == 0 && n <= 65535 && m <= 65535 && n <= m); -} - -static bool -dt_type_macaddr(struct dt_state *s, int nargs) -{ - return !!ether_aton(s->value); -} - -static bool -dt_type_uciname(struct dt_state *s, int nargs) -{ - const char *p; - - for (p = s->value; - *p && ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || - (*p >= '0' && *p <= '9') || (*p == '_')); - p++); - - return (*p == 0); -} - -static bool -dt_type_wpakey(struct dt_state *s, int nargs) -{ - int len = strlen(s->value); - const char *p = s->value; - - if (len == 64) - { - while (isxdigit(*p)) - p++; - - return (*p == 0); - } - - return (len >= 8 && len <= 63); -} - -static bool -dt_type_wepkey(struct dt_state *s, int nargs) -{ - int len = strlen(s->value); - const char *p = s->value; - - if (!strncmp(p, "s:", 2)) - { - len -= 2; - p += 2; - } - - if (len == 10 || len == 26) - { - while (isxdigit(*p)) - p++; - - return (*p == 0); - } - - return (len == 5 || len == 13); -} - -static bool -dt_type_hostname(struct dt_state *s, int nargs) -{ - const char *p, *last; - - for (p = last = s->value; *p; p++) - { - if (*p == '.') - { - if ((p - last) == 0 || (p - last) > 63) - return false; - - last = p + 1; - continue; - } - else if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || - (*p >= '0' && *p <= '9') || (*p == '_') || (*p == '-')) - { - continue; - } - - return false; - } - - return ((p - last) > 0 && (p - last) <= 255); -} - -static bool -dt_type_host(struct dt_state *s, int nargs) -{ - return (dt_type_hostname(s, 0) || dt_type_ipaddr(s, 0)); -} - -static bool -dt_type_network(struct dt_state *s, int nargs) -{ - return (dt_type_uciname(s, 0) || dt_type_host(s, 0)); -} - -static bool -dt_type_phonedigit(struct dt_state *s, int nargs) -{ - const char *p; - - for (p = s->value; - *p && ((*p >= '0' && *p <= '9') || (*p == '*') || (*p == '#') || - (*p == '!') || (*p == '.')); - p++); - - return (*p == 0); -} - -static bool -dt_type_directory(struct dt_state *s, int nargs) -{ - struct stat st; - return (!stat(s->value, &st) && S_ISDIR(st.st_mode)); -} - - -static bool -dt_type_device(struct dt_state *s, int nargs) -{ - struct stat st; - return (!stat(s->value, &st) && - (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))); -} - -static bool -dt_type_file(struct dt_state *s, int nargs) -{ - struct stat st; - return (!stat(s->value, &st) && S_ISREG(st.st_mode)); -} - - -static struct dt_fun dt_types[] = { - { "or", dt_type_or }, - { "and", dt_type_and }, - { "not", dt_type_not }, - { "neg", dt_type_neg }, - { "list", dt_type_list }, - { "min", dt_type_min }, - { "max", dt_type_max }, - { "range", dt_type_range }, - { "minlength", dt_type_minlen }, - { "maxlength", dt_type_maxlen }, - { "rangelength", dt_type_rangelen }, - { "integer", dt_type_int }, - { "uinteger", dt_type_uint }, - { "float", dt_type_float }, - { "ufloat", dt_type_ufloat }, - { "bool", dt_type_bool }, - { "string", dt_type_string }, - { "ip4addr", dt_type_ip4addr }, - { "ip6addr", dt_type_ip6addr }, - { "ipaddr", dt_type_ipaddr }, - { "cidr4", dt_type_cidr4 }, - { "cidr6", dt_type_cidr6 }, - { "cidr", dt_type_cidr }, - { "netmask4", dt_type_netmask4 }, - { "netmask6", dt_type_netmask6 }, - { "ipmask4", dt_type_ipmask4 }, - { "ipmask6", dt_type_ipmask6 }, - { "ipmask", dt_type_ipmask }, - { "port", dt_type_port }, - { "portrange", dt_type_portrange }, - { "macaddr", dt_type_macaddr }, - { "uciname", dt_type_uciname }, - { "wpakey", dt_type_wpakey }, - { "wepkey", dt_type_wepkey }, - { "hostname", dt_type_hostname }, - { "host", dt_type_host }, - { "network", dt_type_network }, - { "phonedigit", dt_type_phonedigit }, - { "directory", dt_type_directory }, - { "device", dt_type_device }, - { "file", dt_type_file }, - - { } -}; - -static struct dt_fun * -dt_lookup_function(const char *s, const char *e) -{ - struct dt_fun *fun = dt_types; - - while (fun->name) - { - if (!strncmp(fun->name, s, e - s) && *(fun->name + (e - s)) == '\0') - return fun; - - fun++; - } - - return NULL; -} - -static bool -dt_parse_atom(struct dt_state *s, const char *label, const char *end) -{ - char q, *e; - const char *p; - bool esc; - double dval; - struct dt_fun *func; - struct dt_op *op = &s->stack[s->depth]; - - if ((s->depth + 1) >= (sizeof(s->stack) / sizeof(s->stack[0]))) - { - printf("Syntax error, expression too long\n"); - return false; - } - - while (isspace(*label)) - label++; - - /* test whether label is a float */ - dval = strtod(label, &e); - - if (e > label) - { - op->next = e; - op->type = OP_NUMBER; - op->value.number = dval; - op->nextop = ++s->depth; - - return true; - } - else if ((*label == '"') || (*label == '\'')) - { - for (p = label + 1, q = *label, esc = false; p <= end; p++) - { - if (esc) - { - esc = false; - continue; - } - else if (*p == '\\') - { - esc = true; - continue; - } - else if (*p == q) - { - op->next = p + 1; - op->type = OP_STRING; - op->length = (p - label) - 2; - op->value.string = label + 1; - op->nextop = ++s->depth; - - return true; - } - } - - printf("Syntax error, unterminated string\n"); - return false; - } - else if (*label) - { - for (p = label; - p <= end && ((*p >= 'A' && *p <= 'Z') || - (*p >= 'a' && *p <= 'z') || - (*p >= '0' && *p <= '9') || - (*p == '_')); - p++); - - func = dt_lookup_function(label, p); - - if (!func) - { - printf("Syntax error, unrecognized function\n"); - return false; - } - - op->next = p; - op->type = OP_FUNCTION; - op->value.function = func; - op->nextop = ++s->depth; - - return true; - } - - printf("Syntax error, unexpected EOF\n"); - return false; -} - -static bool -dt_parse_list(struct dt_state *s, const char *code, const char *end); - -static bool -dt_parse_expr(const char *code, const char *end, struct dt_state *s) -{ - struct dt_op *tok; - - if (!dt_parse_atom(s, code, end)) - return false; - - tok = &s->stack[s->depth - 1]; - - while (isspace(*tok->next)) - tok->next++; - - if (tok->type == OP_FUNCTION) - { - if (*tok->next == '(') - { - end--; - - while (isspace(*end) && end > tok->next + 1) - end--; - - return dt_parse_list(s, tok->next + 1, end); - } - else if (tok->next == end) - { - return dt_parse_list(s, tok->next, tok->next); - } - - printf("Syntax error, expected '(' or EOF after function label\n"); - return false; - } - else if (tok->next == end) - { - return true; - } - - printf("Syntax error, expected ',' after literal\n"); - return false; -} - -static bool -dt_parse_list(struct dt_state *s, const char *code, const char *end) -{ - char c; - bool esc; - int nest; - const char *p, *last; - struct dt_op *fptr; - - if (!code) - return false; - - fptr = &s->stack[s->depth - 1]; - - for (nest = 0, p = last = code, esc = false, c = *p; - p <= end; - p++, c = (p < end) ? *p : '\0') - { - if (esc) - { - esc = false; - continue; - } - - switch (c) - { - case '\\': - esc = true; - break; - - case '(': - nest++; - break; - - case ')': - nest--; - break; - - case ',': - case '\0': - if (nest <= 0) - { - if (p > last) - { - if (!dt_parse_expr(last, p, s)) - return false; - - fptr->length++; - } - - last = p + 1; - } - - break; - } - } - - fptr->nextop = s->depth; - return true; -} - -static bool -dt_step(struct dt_state *s) -{ - bool rv; - struct dt_op *op = &s->stack[s->pos]; - - switch (op->type) - { - case OP_BOOL: - rv = op->value.boolean; - break; - - case OP_NUMBER: - rv = dt_test_number(op->value.number, s->value); - break; - - case OP_STRING: - rv = dt_test_string(op->value.string, op->value.string + op->length, s->value); - break; - - case OP_FUNCTION: - rv = dt_call(s); - break; - - default: - rv = false; - break; - } - - s->pos = op->nextop; - return rv; -} - -static bool -dt_call(struct dt_state *s) -{ - bool rv; - struct dt_op *fptr = &s->stack[s->pos]; - struct dt_fun *func = fptr->value.function; - - s->pos++; - - rv = func->call(s, fptr->length); - - s->pos = fptr->nextop; - - return rv; -} - -bool -dt_parse(const char *code, const char *value) -{ - struct dt_state s = { - .depth = 1, - .stack = { - { - .type = OP_FUNCTION, - .value.function = &dt_types[0], - .next = code - } - } - }; - - if (!value || !*value) - return false; - - if (!dt_parse_list(&s, code, code + strlen(code))) - return false; - - s.value = value; - - return dt_call(&s); -} -- cgit v1.2.3