diff options
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/ctl.c | 318 | ||||
-rw-r--r-- | src/piesctl.c | 244 |
3 files changed, 385 insertions, 177 deletions
diff --git a/grecs b/grecs | |||
Subproject 3b73967c62da68d865f32ca91c8407e65b8ddc0 | Subproject 384b8c088c290f06f70835402f903627c67de6f | ||
@@ -888,8 +888,10 @@ method_decode (char const *method) | |||
888 | 888 | ||
889 | static void res_instance (struct ctlio *, enum http_method, char const *, | 889 | static void res_instance (struct ctlio *, enum http_method, char const *, |
890 | struct json_value *); | 890 | struct json_value *); |
891 | static void res_programs (struct ctlio *, enum http_method, char const *, | 891 | static void res_programs_select (struct ctlio *, enum http_method, char const *, |
892 | struct json_value *); | 892 | struct json_value *); |
893 | static void res_programs_component (struct ctlio *, enum http_method, | ||
894 | char const *, struct json_value *); | ||
893 | 895 | ||
894 | struct ctlio_resource | 896 | struct ctlio_resource |
895 | { | 897 | { |
@@ -903,7 +905,10 @@ struct ctlio_resource | |||
903 | static struct ctlio_resource restab[] = { | 905 | static struct ctlio_resource restab[] = { |
904 | #define S(s) #s, (sizeof (#s)-1) | 906 | #define S(s) #s, (sizeof (#s)-1) |
905 | { S(/instance), CTL_ADMIN_STATE, res_instance }, | 907 | { S(/instance), CTL_ADMIN_STATE, res_instance }, |
906 | { S(/programs), CTL_ADMIN_STATE|CTL_USER_STATE, res_programs }, | 908 | { S(/programs/select), CTL_ADMIN_STATE|CTL_USER_STATE, |
909 | res_programs_select }, | ||
910 | { S(/programs/component), CTL_ADMIN_STATE|CTL_USER_STATE, | ||
911 | res_programs_component }, | ||
907 | { NULL } | 912 | { NULL } |
908 | #undef S | 913 | #undef S |
909 | }; | 914 | }; |
@@ -931,7 +936,10 @@ static char * | |||
931 | json_extract (char *uri) | 936 | json_extract (char *uri) |
932 | { | 937 | { |
933 | char *p = strrchr (uri, '/'); | 938 | char *p = strrchr (uri, '/'); |
934 | if (p && strchr ("\"{[", p[1])) | 939 | if (p && (strchr ("\"{[", p[1]) |
940 | || strcmp ("true", p + 1) == 0 | ||
941 | || strcmp ("false", p + 1) == 0 | ||
942 | || strcmp ("null", p + 1) == 0)) | ||
935 | { | 943 | { |
936 | *p++ = 0; | 944 | *p++ = 0; |
937 | return p; | 945 | return p; |
@@ -1313,8 +1321,13 @@ res_instance (struct ctlio *io, enum http_method meth, | |||
1313 | struct eval_env | 1321 | struct eval_env |
1314 | { | 1322 | { |
1315 | struct ctlio *io; | 1323 | struct ctlio *io; |
1324 | int allowed_state; | ||
1316 | struct pcond_node *cond; | 1325 | struct pcond_node *cond; |
1326 | int (*fun) (struct json_value *, struct prog *); | ||
1317 | struct json_value *result; | 1327 | struct json_value *result; |
1328 | size_t total_count; | ||
1329 | size_t success_count; | ||
1330 | size_t noperm_count; | ||
1318 | }; | 1331 | }; |
1319 | 1332 | ||
1320 | static int | 1333 | static int |
@@ -1390,6 +1403,7 @@ format_idx (struct json_value *obj, const char *name, unsigned i, | |||
1390 | 1403 | ||
1391 | enum pcond_type | 1404 | enum pcond_type |
1392 | { | 1405 | { |
1406 | pcond_false, | ||
1393 | pcond_true, | 1407 | pcond_true, |
1394 | pcond_component, | 1408 | pcond_component, |
1395 | pcond_type, | 1409 | pcond_type, |
@@ -1409,8 +1423,11 @@ struct pcond_node | |||
1409 | enum pies_comp_mode mode; | 1423 | enum pies_comp_mode mode; |
1410 | enum prog_status status; | 1424 | enum prog_status status; |
1411 | enum prog_type type; | 1425 | enum prog_type type; |
1412 | struct pcond_node *unary; | 1426 | struct |
1413 | struct pcond_node *binary[2]; | 1427 | { |
1428 | size_t c; | ||
1429 | struct pcond_node **v; | ||
1430 | } arg; | ||
1414 | } v; | 1431 | } v; |
1415 | }; | 1432 | }; |
1416 | 1433 | ||
@@ -1432,13 +1449,15 @@ pcond_node_free (struct pcond_node *node) | |||
1432 | switch (node->type) | 1449 | switch (node->type) |
1433 | { | 1450 | { |
1434 | case pcond_not: | 1451 | case pcond_not: |
1435 | pcond_node_free (node->v.unary); | ||
1436 | break; | ||
1437 | |||
1438 | case pcond_and: | 1452 | case pcond_and: |
1439 | case pcond_or: | 1453 | case pcond_or: |
1440 | pcond_node_free (node->v.binary[0]); | 1454 | { |
1441 | pcond_node_free (node->v.binary[1]); | 1455 | size_t i; |
1456 | |||
1457 | for (i = 0; i < node->v.arg.c; i++) | ||
1458 | pcond_node_free (node->v.arg.v[i]); | ||
1459 | } | ||
1460 | grecs_free (node->v.arg.v); | ||
1442 | break; | 1461 | break; |
1443 | 1462 | ||
1444 | default: | 1463 | default: |
@@ -1450,12 +1469,17 @@ pcond_node_free (struct pcond_node *node) | |||
1450 | static int | 1469 | static int |
1451 | pcond_eval (struct pcond_node *node, struct prog *p) | 1470 | pcond_eval (struct pcond_node *node, struct prog *p) |
1452 | { | 1471 | { |
1472 | size_t i; | ||
1473 | |||
1453 | if (!node) | 1474 | if (!node) |
1454 | return 0; | 1475 | return 0; |
1455 | switch (node->type) | 1476 | switch (node->type) |
1456 | { | 1477 | { |
1457 | case pcond_true: | 1478 | case pcond_true: |
1458 | return 1; | 1479 | return 1; |
1480 | |||
1481 | case pcond_false: | ||
1482 | return 0; | ||
1459 | 1483 | ||
1460 | case pcond_component: | 1484 | case pcond_component: |
1461 | return strcmp (p->tag, node->v.tag) == 0; | 1485 | return strcmp (p->tag, node->v.tag) == 0; |
@@ -1470,17 +1494,19 @@ pcond_eval (struct pcond_node *node, struct prog *p) | |||
1470 | return IS_COMPONENT (p) && p->v.p.status == node->v.status; | 1494 | return IS_COMPONENT (p) && p->v.p.status == node->v.status; |
1471 | 1495 | ||
1472 | case pcond_not: | 1496 | case pcond_not: |
1473 | return !pcond_eval (node->v.unary, p); | 1497 | return !pcond_eval (node->v.arg.v[0], p); |
1474 | 1498 | ||
1475 | case pcond_and: | 1499 | case pcond_and: |
1476 | if (!pcond_eval (node->v.binary[0], p)) | 1500 | for (i = 0; i < node->v.arg.c; i++) |
1477 | return 0; | 1501 | if (!pcond_eval (node->v.arg.v[i], p)) |
1478 | return pcond_eval (node->v.binary[1], p); | 1502 | return 0; |
1503 | return 1; | ||
1479 | 1504 | ||
1480 | case pcond_or: | 1505 | case pcond_or: |
1481 | if (pcond_eval (node->v.binary[0], p)) | 1506 | for (i = 0; i < node->v.arg.c; i++) |
1482 | return 1; | 1507 | if (pcond_eval (node->v.arg.v[i], p)) |
1483 | return pcond_eval (node->v.binary[1], p); | 1508 | return 1; |
1509 | return 0; | ||
1484 | 1510 | ||
1485 | default: | 1511 | default: |
1486 | abort (); | 1512 | abort (); |
@@ -1560,26 +1586,36 @@ static int | |||
1560 | pcond_conv_not (struct pcond_node *node, struct json_value *arg, | 1586 | pcond_conv_not (struct pcond_node *node, struct json_value *arg, |
1561 | struct ctlio *io) | 1587 | struct ctlio *io) |
1562 | { | 1588 | { |
1563 | return json_to_pcond (io, arg, &node->v.unary); | 1589 | node->v.arg.v = grecs_calloc (1, sizeof (node->v.arg.v[0])); |
1590 | node->v.arg.c = 1; | ||
1591 | return json_to_pcond (io, arg, &node->v.arg.v[0]); | ||
1564 | } | 1592 | } |
1565 | 1593 | ||
1566 | static int | 1594 | static int |
1567 | pcond_conv_binary (struct pcond_node *node, struct json_value *arg, | 1595 | pcond_conv_binary (struct pcond_node *node, struct json_value *arg, |
1568 | struct ctlio *io) | 1596 | struct ctlio *io) |
1569 | { | 1597 | { |
1570 | struct json_value *v; | 1598 | size_t i, n; |
1571 | 1599 | ||
1572 | if (arg->type != json_arr) | 1600 | if (arg->type != json_arr) |
1573 | { | 1601 | { |
1574 | ctlio_reply (io, 400, "arguments to binary opcode must be array"); | 1602 | ctlio_reply (io, 400, "arguments to binary opcode must be array"); |
1575 | return -1; | 1603 | return -1; |
1576 | } | 1604 | } |
1577 | json_array_get (arg, 0, &v); | 1605 | |
1578 | if (json_to_pcond (io, v, &node->v.binary[0])) | 1606 | n = json_array_size (arg); |
1579 | return -1; | 1607 | node->v.arg.v = grecs_calloc (n, sizeof (node->v.arg.v[0])); |
1580 | json_array_get (arg, 1, &v); | 1608 | node->v.arg.c = n; |
1581 | if (json_to_pcond (io, v, &node->v.binary[1])) | 1609 | |
1582 | return -1; | 1610 | for (i = 0; i < n; i++) |
1611 | { | ||
1612 | struct json_value *v; | ||
1613 | if (json_array_get (arg, i, &v) == 0) | ||
1614 | { | ||
1615 | if (json_to_pcond (io, v, &node->v.arg.v[i])) | ||
1616 | return -1; | ||
1617 | } | ||
1618 | } | ||
1583 | return 0; | 1619 | return 0; |
1584 | } | 1620 | } |
1585 | 1621 | ||
@@ -1590,6 +1626,7 @@ struct pcond_conv { | |||
1590 | 1626 | ||
1591 | static struct pcond_conv pcond_conv[] = { | 1627 | static struct pcond_conv pcond_conv[] = { |
1592 | [pcond_true] = { "true", NULL }, | 1628 | [pcond_true] = { "true", NULL }, |
1629 | [pcond_false] = { "false", NULL }, | ||
1593 | [pcond_component] = { "component", pcond_conv_component }, | 1630 | [pcond_component] = { "component", pcond_conv_component }, |
1594 | [pcond_type] = { "type", pcond_conv_type }, | 1631 | [pcond_type] = { "type", pcond_conv_type }, |
1595 | [pcond_mode] = { "mode", pcond_conv_mode }, | 1632 | [pcond_mode] = { "mode", pcond_conv_mode }, |
@@ -1669,10 +1706,7 @@ json_to_pcond (struct ctlio *io, struct json_value *val, | |||
1669 | break; | 1706 | break; |
1670 | 1707 | ||
1671 | case json_bool: | 1708 | case json_bool: |
1672 | if (val->v.b) | 1709 | *pnode = pcond_node_alloc (val->v.b ? pcond_true : pcond_false); |
1673 | *pnode = pcond_node_alloc (pcond_true); | ||
1674 | else | ||
1675 | *pnode = NULL; | ||
1676 | break; | 1710 | break; |
1677 | 1711 | ||
1678 | case json_number: | 1712 | case json_number: |
@@ -1687,26 +1721,34 @@ json_to_pcond (struct ctlio *io, struct json_value *val, | |||
1687 | return 0; | 1721 | return 0; |
1688 | } | 1722 | } |
1689 | 1723 | ||
1690 | static struct json_value *prog_serialize (struct prog *prog); | ||
1691 | |||
1692 | static int | 1724 | static int |
1693 | selector (struct prog *prog, void *data) | 1725 | selector (struct prog *prog, void *data) |
1694 | { | 1726 | { |
1695 | struct eval_env *env = data; | 1727 | struct eval_env *env = data; |