Changeset 8ad126b7390d75e24ecc859efb01570b01bbcdc1
- Timestamp:
- 10/02/09 00:20:36 (4 years ago)
- git-parent:
- Files:
-
- src/noit_conf.c (modified) (3 diffs)
- src/noit_conf.h (modified) (1 diff)
- src/noit_conf_checks.c (modified) (9 diffs)
- src/noit_conf_checks.h (modified) (1 diff)
- src/noitd.c (modified) (2 diffs)
- src/stratcon_iep.h (modified) (2 diffs)
- src/stratcon_jlog_streamer.c (modified) (8 diffs)
- src/stratcond.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/noit_conf.c
r25fec2c r8ad126b 53 53 static noit_hash_table _tmp_config = NOIT_HASH_EMPTY; 54 54 static xmlDocPtr master_config = NULL; 55 static char *root_node_name = NULL; 55 56 static char master_config_file[PATH_MAX] = ""; 56 57 static xmlXPathContextPtr xpath_ctxt = NULL; … … 174 175 int noit_conf_load(const char *path) { 175 176 xmlDocPtr new_config; 177 xmlNodePtr root; 176 178 new_config = xmlParseFile(path); 177 179 if(new_config) { 180 root = xmlDocGetRootElement(new_config); 181 if(root_node_name) free(root_node_name); 182 root_node_name = strdup((char *)root->name); 178 183 if(master_config) xmlFreeDoc(master_config); 179 184 if(xpath_ctxt) xmlXPathFreeContext(xpath_ctxt); … … 784 789 if(log_configs) free(log_configs); 785 790 } 791 792 static void 793 conf_t_userdata_free(void *data) { 794 noit_conf_t_userdata_t *info = data; 795 if(info) { 796 if(info->path) free(info->path); 797 free(info); 798 } 799 } 800 801 static int 802 noit_console_state_conf_terminal(noit_console_closure_t ncct, 803 int argc, char **argv, 804 noit_console_state_t *state, void *closure) { 805 noit_conf_t_userdata_t *info; 806 if(argc) { 807 nc_printf(ncct, "extra arguments not expected.\n"); 808 return -1; 809 } 810 info = calloc(1, sizeof(*info)); 811 info->path = strdup("/"); 812 noit_console_userdata_set(ncct, NOIT_CONF_T_USERDATA, info, 813 conf_t_userdata_free); 814 noit_console_state_push_state(ncct, state); 815 noit_console_state_init(ncct); 816 return 0; 817 } 818 static int 819 noit_console_config_section(noit_console_closure_t ncct, 820 int argc, char **argv, 821 noit_console_state_t *state, void *closure) { 822 const char *err = "internal error"; 823 char *path, xpath[1024]; 824 noit_conf_t_userdata_t *info; 825 xmlXPathObjectPtr pobj = NULL; 826 xmlXPathContextPtr xpath_ctxt = NULL; 827 xmlNodePtr node = NULL, newnode; 828 vpsized_int delete = (vpsized_int)closure; 829 830 noit_conf_xml_xpath(NULL, &xpath_ctxt); 831 if(argc != 1) { 832 nc_printf(ncct, "requires one argument\n"); 833 return -1; 834 } 835 if(strchr(argv[0], '/')) { 836 nc_printf(ncct, "invalid section name\n"); 837 return -1; 838 } 839 if(!strcmp(argv[0], "check") || 840 !strcmp(argv[0], "noit") || 841 !strcmp(argv[0], "filterset") || 842 !strcmp(argv[0], "config")) { 843 nc_printf(ncct, "%s is reserved.\n", argv[0]); 844 return -1; 845 } 846 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 847 if(!strcmp(info->path, "/")) { 848 nc_printf(ncct, "manipulation of toplevel section disallowed\n"); 849 return -1; 850 } 851 852 if(delete) { 853 /* We cannot delete if we have checks */ 854 snprintf(xpath, sizeof(xpath), "/%s%s/%s//check", root_node_name, 855 info->path, argv[0]); 856 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 857 if(!pobj || pobj->type != XPATH_NODESET || 858 !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 859 err = "cannot delete section, has checks"; 860 goto bad; 861 } 862 if(pobj) xmlXPathFreeObject(pobj); 863 } 864 865 snprintf(xpath, sizeof(xpath), "/%s%s/%s", root_node_name, 866 info->path, argv[0]); 867 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 868 if(!pobj || pobj->type != XPATH_NODESET) { 869 err = "internal error: cannot detect section"; 870 goto bad; 871 } 872 if(!delete && !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 873 if(xmlXPathNodeSetGetLength(pobj->nodesetval) == 1) { 874 node = xmlXPathNodeSetItem(pobj->nodesetval, 0); 875 if(info->path) free(info->path); 876 info->path = strdup((char *)xmlGetNodePath(node) + 877 1 + strlen(root_node_name)); 878 goto cdout; 879 } 880 err = "cannot create section"; 881 goto bad; 882 } 883 if(delete && xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 884 err = "no such section"; 885 goto bad; 886 } 887 if(delete) { 888 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 889 xmlUnlinkNode(node); 890 noit_conf_mark_changed(); 891 return 0; 892 } 893 if(pobj) xmlXPathFreeObject(pobj); 894 895 path = strcmp(info->path, "/") ? info->path : ""; 896 snprintf(xpath, sizeof(xpath), "/%s%s", root_node_name, path); 897 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 898 if(!pobj || pobj->type != XPATH_NODESET || 899 xmlXPathNodeSetGetLength(pobj->nodesetval) != 1) { 900 err = "path invalid?"; 901 goto bad; 902 } 903 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 904 if((newnode = xmlNewChild(node, NULL, (xmlChar *)argv[0], NULL)) != NULL) { 905 noit_conf_mark_changed(); 906 if(info->path) free(info->path); 907 info->path = strdup((char *)xmlGetNodePath(newnode) + 1 + 908 strlen(root_node_name)); 909 } 910 else { 911 err = "failed to create section"; 912 goto bad; 913 } 914 cdout: 915 if(pobj) xmlXPathFreeObject(pobj); 916 return 0; 917 bad: 918 if(pobj) xmlXPathFreeObject(pobj); 919 nc_printf(ncct, "%s\n", err); 920 return -1; 921 } 922 923 int 924 noit_console_generic_show(noit_console_closure_t ncct, 925 int argc, char **argv, 926 noit_console_state_t *state, void *closure) { 927 int i, cnt, titled = 0, cliplen = 0; 928 const char *path = "", *basepath = NULL; 929 char xpath[1024]; 930 noit_conf_t_userdata_t *info = NULL; 931 xmlXPathObjectPtr pobj = NULL; 932 xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt; 933 xmlDocPtr master_config = NULL; 934 xmlNodePtr node = NULL; 935 936 noit_conf_xml_xpath(&master_config, &xpath_ctxt); 937 if(argc > 1) { 938 nc_printf(ncct, "too many arguments\n"); 939 return -1; 940 } 941 942 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 943 if(info) path = basepath = info->path; 944 if(!info && argc == 0) { 945 nc_printf(ncct, "argument required when not in configuration mode\n"); 946 return -1; 947 } 948 949 if(argc == 1) path = argv[0]; 950 if(!basepath) basepath = path; 951 952 /* { / } is a special case */ 953 if(!strcmp(basepath, "/")) basepath = ""; 954 if(!strcmp(path, "/")) path = ""; 955 956 if(!master_config) { 957 nc_printf(ncct, "no config\n"); 958 return -1; 959 } 960 961 /* { / } is the only path that will end with a / 962 * in XPath { / / * } means something _entirely different than { / * } 963 * Ever notice how it is hard to describe xpath in C comments? 964 */ 965 /* We don't want to show the root node */ 966 cliplen = strlen(root_node_name) + 2; /* /name/ */ 967 968 /* If we are in configuration mode 969 * and we are without an argument or the argument is absolute, 970 * clip the current path off */ 971 if(info && (argc == 0 || path[0] != '/')) cliplen += strlen(basepath); 972 if(!path[0] || path[0] == '/') /* base only, or absolute path requested */ 973 snprintf(xpath, sizeof(xpath), "/%s%s/@*", root_node_name, path); 974 else 975 snprintf(xpath, sizeof(xpath), "/%s%s/%s/@*", root_node_name, 976 basepath, path); 977 978 current_ctxt = xpath_ctxt; 979 pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); 980 if(!pobj || pobj->type != XPATH_NODESET) { 981 nc_printf(ncct, "no such object\n"); 982 goto bad; 983 } 984 cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); 985 titled = 0; 986 for(i=0; i<cnt; i++) { 987 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); 988 if(node->children && node->children == xmlGetLastChild(node) && 989 xmlNodeIsText(node->children)) { 990 if(!titled++) nc_printf(ncct, "== Section Settings ==\n"); 991 nc_printf(ncct, "%s: %s\n", xmlGetNodePath(node) + cliplen, 992 xmlXPathCastNodeToString(node->children)); 993 } 994 } 995 xmlXPathFreeObject(pobj); 996 997 /* _shorten string_ turning last { / @ * } to { / * } */ 998 if(!path[0] || path[0] == '/') /* base only, or absolute path requested */ 999 snprintf(xpath, sizeof(xpath), "/%s%s/*", root_node_name, path); 1000 else 1001 snprintf(xpath, sizeof(xpath), "/%s%s/%s/*", 1002 root_node_name, basepath, path); 1003 pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); 1004 if(!pobj || pobj->type != XPATH_NODESET) { 1005 nc_printf(ncct, "no such object\n"); 1006 goto bad; 1007 } 1008 cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); 1009 titled = 0; 1010 for(i=0; i<cnt; i++) { 1011 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); 1012 if(!(node->children && node->children == xmlGetLastChild(node) && 1013 xmlNodeIsText(node->children))) { 1014 if(!titled++) nc_printf(ncct, "== Subsections ==\n"); 1015 nc_printf(ncct, "%s\n", xmlGetNodePath(node) + cliplen); 1016 } 1017 } 1018 xmlXPathFreeObject(pobj); 1019 return 0; 1020 bad: 1021 if(pobj) xmlXPathFreeObject(pobj); 1022 return -1; 1023 } 1024 int 1025 noit_console_config_cd(noit_console_closure_t ncct, 1026 int argc, char **argv, 1027 noit_console_state_t *state, void *closure) { 1028 const char *err = "internal error"; 1029 char *path, xpath[1024]; 1030 noit_conf_t_userdata_t *info; 1031 xmlXPathObjectPtr pobj = NULL; 1032 xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt; 1033 xmlNodePtr node = NULL; 1034 char *dest; 1035 1036 noit_conf_xml_xpath(NULL, &xpath_ctxt); 1037 if(argc != 1 && !closure) { 1038 nc_printf(ncct, "requires one argument\n"); 1039 return -1; 1040 } 1041 dest = argc ? argv[0] : (char *)closure; 1042 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 1043 if(dest[0] == '/') 1044 snprintf(xpath, sizeof(xpath), "/%s%s", root_node_name, dest); 1045 else { 1046 snprintf(xpath, sizeof(xpath), "/%s%s/%s", root_node_name, 1047 info->path, dest); 1048 } 1049 if(xpath[strlen(xpath)-1] == '/') xpath[strlen(xpath)-1] = '\0'; 1050 1051 current_ctxt = xpath_ctxt; 1052 pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); 1053 if(!pobj || pobj->type != XPATH_NODESET || 1054 xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 1055 err = "no such section"; 1056 goto bad; 1057 } 1058 if(xmlXPathNodeSetGetLength(pobj->nodesetval) > 1) { 1059 err = "ambiguous section"; 1060 goto bad; 1061 } 1062 1063 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 1064 if(!strcmp((char *)node->name, "check") || 1065 !strcmp((char *)node->name, "noit") || 1066 !strcmp((char *)node->name, "filterset") || 1067 !strcmp((char *)node->name, "config")) { 1068 err = "reserved word"; 1069 goto bad; 1070 } 1071 path = (char *)xmlGetNodePath(node); 1072 if(strlen(path) < strlen(root_node_name) + 1 || 1073 strncmp(path + 1, root_node_name, strlen(root_node_name)) || 1074 (path[strlen(root_node_name) + 1] != '/' && 1075 path[strlen(root_node_name) + 1] != '\0')) { 1076 err = "new path outside out tree"; 1077 goto bad; 1078 } 1079 free(info->path); 1080 if(!strcmp(path + 1, root_node_name)) 1081 info->path = strdup("/"); 1082 else 1083 info->path = strdup((char *)xmlGetNodePath(node) + 1 + 1084 strlen(root_node_name)); 1085 if(pobj) xmlXPathFreeObject(pobj); 1086 if(closure) noit_console_state_pop(ncct, argc, argv, NULL, NULL); 1087 return 0; 1088 bad: 1089 if(pobj) xmlXPathFreeObject(pobj); 1090 nc_printf(ncct, "%s [%s]\n", err, xpath); 1091 return -1; 1092 } 1093 1094 char * 1095 conf_t_prompt(EditLine *el) { 1096 noit_console_closure_t ncct; 1097 noit_conf_t_userdata_t *info; 1098 static char *tl = "noit(conf)# "; 1099 static char *pfmt = "noit(conf:%s%s)# "; 1100 int path_len, max_len; 1101 1102 el_get(el, EL_USERDATA, (void *)&ncct); 1103 if(!ncct) return tl; 1104 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 1105 if(!info) return tl; 1106 1107 path_len = strlen(info->path); 1108 max_len = sizeof(info->prompt) - (strlen(pfmt) - 4 /* %s%s */) - 1 /* \0 */; 1109 if(path_len > max_len) 1110 snprintf(info->prompt, sizeof(info->prompt), 1111 pfmt, "...", info->path + path_len - max_len + 3 /* ... */); 1112 else 1113 snprintf(info->prompt, sizeof(info->prompt), pfmt, "", info->path); 1114 return info->prompt; 1115 } 1116 1117 #define NEW_STATE(a) (a) = noit_console_state_alloc() 1118 #define ADD_CMD(a,cmd,func,ac,ss,c) \ 1119 noit_console_state_add_cmd((a), \ 1120 NCSCMD(cmd, func, ac, ss, c)) 1121 #define DELEGATE_CMD(a,cmd,ac,ss) \ 1122 noit_console_state_add_cmd((a), \ 1123 NCSCMD(cmd, noit_console_state_delegate, ac, ss, NULL)) 1124 1125 void noit_console_conf_init() { 1126 noit_console_state_t *tl, *_conf_state, *_conf_t_state, 1127 *_write_state, *_unset_state; 1128 1129 tl = noit_console_state_initial(); 1130 1131 /* write <terimal|memory|file> */ 1132 NEW_STATE(_write_state); 1133 ADD_CMD(_write_state, "terminal", noit_conf_write_terminal, NULL, NULL, NULL); 1134 ADD_CMD(_write_state, "file", noit_conf_write_file_console, NULL, NULL, NULL); 1135 /* write memory? It's to a file, but I like router syntax */ 1136 ADD_CMD(_write_state, "memory", noit_conf_write_file_console, NULL, NULL, NULL); 1137 1138 NEW_STATE(_unset_state); 1139 ADD_CMD(_unset_state, "section", 1140 noit_console_config_section, NULL, NULL, (void *)1); 1141 1142 NEW_STATE(_conf_t_state); 1143 _conf_t_state->console_prompt_function = conf_t_prompt; 1144 noit_console_state_add_cmd(_conf_t_state, &console_command_exit); 1145 1146 ADD_CMD(_conf_t_state, "ls", noit_console_generic_show, NULL, NULL, NULL); 1147 ADD_CMD(_conf_t_state, "cd", noit_console_config_cd, NULL, NULL, NULL); 1148 ADD_CMD(_conf_t_state, "section", 1149 noit_console_config_section, NULL, NULL, (void *)0); 1150 1151 DELEGATE_CMD(_conf_t_state, "write", 1152 noit_console_opt_delegate, _write_state); 1153 DELEGATE_CMD(_conf_t_state, "no", noit_console_opt_delegate, _unset_state); 1154 1155 NEW_STATE(_conf_state); 1156 ADD_CMD(_conf_state, "terminal", 1157 noit_console_state_conf_terminal, NULL, _conf_t_state, NULL); 1158 1159 ADD_CMD(tl, "configure", 1160 noit_console_state_delegate, noit_console_opt_delegate, 1161 _conf_state, NULL); 1162 ADD_CMD(tl, "write", 1163 noit_console_state_delegate, noit_console_opt_delegate, 1164 _write_state, NULL); 1165 } 1166 src/noit_conf.h
r37daa37 r8ad126b 66 66 API_EXPORT(int) noit_conf_save(const char *path); 67 67 API_EXPORT(char *) noit_conf_config_filename(); 68 69 API_EXPORT(void) noit_console_conf_init(); 68 70 69 71 API_EXPORT(noit_conf_section_t) src/noit_conf_checks.c
r37daa37 r8ad126b 52 52 #include "utils/noit_log.h" 53 53 54 static void register_console_config_c ommands();54 static void register_console_config_check_commands(); 55 55 56 56 static struct _valid_attr_t { … … 90 90 static noit_hash_table check_attrs = NOIT_HASH_EMPTY; 91 91 92 void noit_con f_checks_init(const char *toplevel) {92 void noit_console_conf_checks_init() { 93 93 int i; 94 94 for(i=0;i<sizeof(valid_attrs)/sizeof(*valid_attrs);i++) { … … 97 97 &valid_attrs[i]); 98 98 } 99 register_console_config_commands(); 100 } 101 102 static void 103 conf_t_userdata_free(void *data) { 104 noit_conf_t_userdata_t *info = data; 105 if(info) { 106 if(info->path) free(info->path); 107 free(info); 108 } 99 register_console_config_check_commands(); 109 100 } 110 101 … … 585 576 } 586 577 static int 587 noit_console_state_conf_terminal(noit_console_closure_t ncct,588 int argc, char **argv,589 noit_console_state_t *state, void *closure) {590 noit_conf_t_userdata_t *info;591 if(argc) {592 nc_printf(ncct, "extra arguments not expected.\n");593 return -1;594 }595 info = calloc(1, sizeof(*info));596 info->path = strdup("/");597 noit_console_userdata_set(ncct, NOIT_CONF_T_USERDATA, info,598 conf_t_userdata_free);599 noit_console_state_push_state(ncct, state);600 noit_console_state_init(ncct);601 return 0;602 }603 static int604 noit_console_config_section(noit_console_closure_t ncct,605 int argc, char **argv,606 noit_console_state_t *state, void *closure) {607 const char *err = "internal error";608 char *path, xpath[1024];609 noit_conf_t_userdata_t *info;610 xmlXPathObjectPtr pobj = NULL;611 xmlXPathContextPtr xpath_ctxt = NULL;612 xmlNodePtr node = NULL, newnode;613 vpsized_int delete = (vpsized_int)closure;614 615 noit_conf_xml_xpath(NULL, &xpath_ctxt);616 if(argc != 1) {617 nc_printf(ncct, "requires one argument\n");618 return -1;619 }620 if(strchr(argv[0], '/')) {621 nc_printf(ncct, "invalid section name\n");622 return -1;623 }624 if(!strcmp(argv[0], "check")) {625 nc_printf(ncct, "use 'check' to create checks\n");626 return -1;627 }628 if(!strcmp(argv[0], "filterset")) {629 nc_printf(ncct, "use 'filterset' to create checks\n");630 return -1;631 }632 if(!strcmp(argv[0], "config")) {633 nc_printf(ncct, "use 'config' to set check config options\n");634 return -1;635 }636 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);637 if(!strcmp(info->path, "/")) {638 nc_printf(ncct, "manipulation of toplevel section disallowed\n");639 return -1;640 }641 642 if(delete) {643 /* We cannot delete if we have checks */644 snprintf(xpath, sizeof(xpath), "/noit%s/%s//check", info->path, argv[0]);645 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);646 if(!pobj || pobj->type != XPATH_NODESET ||647 !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {648 err = "cannot delete section, has checks";649 goto bad;650 }651 if(pobj) xmlXPathFreeObject(pobj);652 }653 654 snprintf(xpath, sizeof(xpath), "/noit%s/%s", info->path, argv[0]);655 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);656 if(!pobj || pobj->type != XPATH_NODESET) {657 err = "internal error: cannot detect section";658 goto bad;659 }660 if(!delete && !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {661 if(xmlXPathNodeSetGetLength(pobj->nodesetval) == 1) {662 node = xmlXPathNodeSetItem(pobj->nodesetval, 0);663 if(info->path) free(info->path);664 info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit"));665 goto cdout;666 }667 err = "cannot create section";668 goto bad;669 }670 if(delete && xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {671 err = "no such section";672 goto bad;673 }674 if(delete) {675 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);676 xmlUnlinkNode(node);677 noit_conf_mark_changed();678 return 0;679 }680 if(pobj) xmlXPathFreeObject(pobj);681 682 path = strcmp(info->path, "/") ? info->path : "";683 snprintf(xpath, sizeof(xpath), "/noit%s", path);684 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);685 if(!pobj || pobj->type != XPATH_NODESET ||686 xmlXPathNodeSetGetLength(pobj->nodesetval) != 1) {687 err = "path invalid?";688 goto bad;689 }690 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);691 if((newnode = xmlNewChild(node, NULL, (xmlChar *)argv[0], NULL)) != NULL) {692 noit_conf_mark_changed();693 if(info->path) free(info->path);694 info->path = strdup((char *)xmlGetNodePath(newnode) + strlen("/noit"));695 }696 else {697 err = "failed to create section";698 goto bad;699 }700 cdout:701 if(pobj) xmlXPathFreeObject(pobj);702 return 0;703 bad:704 if(pobj) xmlXPathFreeObject(pobj);705 nc_printf(ncct, "%s\n", err);706 return -1;707 }708 709 int710 noit_console_config_cd(noit_console_closure_t ncct,711 int argc, char **argv,712 noit_console_state_t *state, void *closure) {713 const char *err = "internal error";714 char *path, xpath[1024];715 noit_conf_t_userdata_t *info;716 xmlXPathObjectPtr pobj = NULL;717 xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt;718 xmlNodePtr node = NULL;719 char *dest;720 721 noit_conf_xml_xpath(NULL, &xpath_ctxt);722 if(argc != 1 && !closure) {723 nc_printf(ncct, "requires one argument\n");724 return -1;725 }726 dest = argc ? argv[0] : (char *)closure;727 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);728 if(dest[0] == '/')729 snprintf(xpath, sizeof(xpath), "/noit%s", dest);730 else {731 snprintf(xpath, sizeof(xpath), "/noit%s/%s", info->path, dest);732 }733 if(xpath[strlen(xpath)-1] == '/') xpath[strlen(xpath)-1] = '\0';734 735 current_ctxt = xpath_ctxt;736 pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt);737 if(!pobj || pobj->type != XPATH_NODESET ||738 xmlXPathNodeSetIsEmpty(pobj->nodesetval)) {739 err = "no such section";740 goto bad;741 }742 if(xmlXPathNodeSetGetLength(pobj->nodesetval) > 1) {743 err = "ambiguous section";744 goto bad;745 }746 747 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);748 if(!strcmp((char *)node->name, "check")) {749 err = "can't cd into a check, use 'check' instead";750 goto bad;751 }752 path = (char *)xmlGetNodePath(node);753 if(strncmp(path, "/noit/", strlen("/noit/")) && strcmp(path, "/noit")) {754 err = "new path outside out tree";755 goto bad;756 }757 free(info->path);758 if(!strcmp(path, "/noit"))759 info->path = strdup("/");760 else761 info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit"));762 if(pobj) xmlXPathFreeObject(pobj);763 if(closure) noit_console_state_pop(ncct, argc, argv, NULL, NULL);764 return 0;765 bad:766 if(pobj) xmlXPathFreeObject(pobj);767 nc_printf(ncct, "%s [%s]\n", err, xpath);768 return -1;769 }770 static int771 578 noit_console_config_show(noit_console_closure_t ncct, 772 579 int argc, char **argv, … … 969 776 snprintf(info->prompt, sizeof(info->prompt), pfmt, "[", uuid_str, "]"); 970 777 } 971 return info->prompt;972 }973 static char *974 conf_t_prompt(EditLine *el) {975 noit_console_closure_t ncct;976 noit_conf_t_userdata_t *info;977 static char *tl = "noit(conf)# ";978 static char *pfmt = "noit(conf:%s%s)# ";979 int path_len, max_len;980 981 el_get(el, EL_USERDATA, (void *)&ncct);982 if(!ncct) return tl;983 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA);984 if(!info) return tl;985 986 path_len = strlen(info->path);987 max_len = sizeof(info->prompt) - (strlen(pfmt) - 4 /* %s%s */) - 1 /* \0 */;988 if(path_len > max_len)989 snprintf(info->prompt, sizeof(info->prompt),990 pfmt, "...", info->path + path_len - max_len + 3 /* ... */);991 else992 snprintf(info->prompt, sizeof(info->prompt), pfmt, "", info->path);993 778 return info->prompt; 994 779 } … … 1325 1110 1326 1111 static 1327 void register_console_config_commands() { 1328 cmd_info_t *showcmd, *nocmd; 1329 noit_console_state_t *tl, *_conf_state, *_conf_t_state, 1330 *_conf_t_check_state, 1331 *_write_state, *_attr_state, 1332 *_unset_state, *_uattr_state; 1112 void register_console_config_check_commands() { 1113 cmd_info_t *showcmd, *nocmd, *confcmd, *conftcmd, *conftnocmd, *lscmd; 1114 noit_console_state_t *tl, *_conf_t_check_state, *_unset_state, 1115 *_attr_state, *_uattr_state; 1333 1116 1334 1117 tl = noit_console_state_initial(); 1335 1336 /* write <terimal|memory|file> */ 1337 NEW_STATE(_write_state); 1338 ADD_CMD(_write_state, "terminal", noit_conf_write_terminal, NULL, NULL, NULL); 1339 ADD_CMD(_write_state, "file", noit_conf_write_file_console, NULL, NULL, NULL); 1340 /* write memory? It's to a file, but I like router syntax */ 1341 ADD_CMD(_write_state, "memory", noit_conf_write_file_console, NULL, NULL, NULL); 1342 1118 showcmd = noit_console_state_get_cmd(tl, "show"); 1119 nocmd = noit_console_state_get_cmd(tl, "no"); 1120 confcmd = noit_console_state_get_cmd(tl, "configure"); 1121 conftcmd = noit_console_state_get_cmd(confcmd->dstate, "terminal"); 1122 conftnocmd = noit_console_state_get_cmd(conftcmd->dstate, "no"); 1123 lscmd = noit_console_state_get_cmd(conftcmd->dstate, "ls"); 1124 lscmd->func = noit_console_config_show; 1343 1125 /* attribute <attrname> <value> */ 1344 1126 NEW_STATE(_attr_state); … … 1350 1132 noit_console_state_add_check_attrs(_uattr_state, noit_conf_check_unset_attr, 1351 1133 "/checks"); 1352 1353 1134 NEW_STATE(_unset_state); 1354 1135 DELEGATE_CMD(_unset_state, "attribute", 1355 1136 noit_console_opt_delegate, _uattr_state); 1356 ADD_CMD(_unset_state, "section",1357 noit_console_config_section, NULL, NULL, (void *)1);1358 1137 ADD_CMD(_unset_state, "config", 1359 1138 noit_console_config_unsetconfig, NULL, NULL, NULL); 1360 ADD_CMD(_unset_state, "check", 1139 1140 DELEGATE_CMD(conftnocmd->dstate, "attribute", 1141 noit_console_opt_delegate, _uattr_state); 1142 ADD_CMD(conftnocmd->dstate, "config", 1143 noit_console_config_unsetconfig, NULL, NULL, NULL); 1144 ADD_CMD(conftnocmd->dstate, "check", 1361 1145 noit_console_config_nocheck, NULL, NULL, NULL); 1362 1146 … … 1377 1161 _conf_t_check_state, ".."); 1378 1162 1379 NEW_STATE(_conf_t_state); 1380 _conf_t_state->console_prompt_function = conf_t_prompt; 1381 noit_console_state_add_cmd(_conf_t_state, &console_command_exit); 1382 ADD_CMD(_conf_t_state, "ls", noit_console_config_show, NULL, NULL, NULL); 1383 ADD_CMD(_conf_t_state, "cd", noit_console_config_cd, NULL, NULL, NULL); 1384 ADD_CMD(_conf_t_state, "config", 1163 ADD_CMD(conftcmd->dstate, "config", 1385 1164 noit_console_config_setconfig, NULL, NULL, NULL); 1386 ADD_CMD(_conf_t_state, "section", 1387 noit_console_config_section, NULL, NULL, (void *)0); 1388 ADD_CMD(_conf_t_state, "check", 1165 ADD_CMD(conftcmd->dstate, "check", 1389 1166 noit_console_check, noit_console_conf_check_opts, 1390 1167 _conf_t_check_state, NULL); 1391 1168 1392 showcmd = noit_console_state_get_cmd(tl, "show");1393 1169 ADD_CMD(showcmd->dstate, "check", 1394 1170 noit_console_show_check, noit_console_check_opts, NULL, NULL); … … 1397 1173 noit_console_watch_check, noit_console_check_opts, NULL, (void *)1); 1398 1174 1399 nocmd = noit_console_state_get_cmd(tl, "no");1400 1175 ADD_CMD(nocmd->dstate, "watch", 1401 1176 noit_console_watch_check, noit_console_check_opts, NULL, (void *)0); 1402 1177 1403 DELEGATE_CMD(_conf_t_state, "write", 1404 noit_console_opt_delegate, _write_state); 1405 DELEGATE_CMD(_conf_t_state, "attribute", 1178 DELEGATE_CMD(conftcmd->dstate, "attribute", 1406 1179 noit_console_opt_delegate, _attr_state); 1407 DELEGATE_CMD(_conf_t_state, "no", noit_console_opt_delegate, _unset_state); 1408 1409 NEW_STATE(_conf_state); 1410 ADD_CMD(_conf_state, "terminal", 1411 noit_console_state_conf_terminal, NULL, _conf_t_state, NULL); 1412 1413 ADD_CMD(tl, "configure", 1414 noit_console_state_delegate, noit_console_opt_delegate, 1415 _conf_state, NULL); 1416 ADD_CMD(tl, "write", 1417 noit_console_state_delegate, noit_console_opt_delegate, 1418 _write_state, NULL); 1180 1419 1181 ADD_CMD(tl, "reload", noit_conf_checks_reload, NULL, NULL, NULL); 1420 1182 } src/noit_conf_checks.h
r37daa37 r8ad126b 38 38 #include "noit_console.h" 39 39 40 API_EXPORT(void) noit_con f_checks_init(const char *toplevel);40 API_EXPORT(void) noit_console_conf_checks_init(); 41 41 API_EXPORT(int) 42 42 noit_console_config_cd(noit_console_closure_t ncct, src/noitd.c
r75ee62d r8ad126b 181 181 /* Initialize all of our listeners */ 182 182 noit_console_init(APPNAME); 183 noit_console_conf_init(); 184 noit_console_conf_checks_init(); 183 185 noit_capabilities_listener_init(); 184 186 noit_jlog_listener_init(); … … 226 228 /* Next load the configs */ 227 229 noit_conf_init(APPNAME); 228 noit_conf_checks_init(APPNAME);229 230 if(noit_conf_load(config_file) == -1) { 230 231 fprintf(stderr, "Cannot load config: '%s'\n", config_file); src/stratcon_iep.h
r88a7178 r8ad126b 38 38 #include "utils/noit_hash.h" 39 39 #include "stratcon_datastore.h" 40 #include "stratcon_jlog_streamer.h" 40 41 41 42 #include <sys/types.h> … … 49 50 struct sockaddr *remote, void *operand); 50 51 52 API_EXPORT(jlog_streamer_ctx_t *) 53 stratcon_jlog_streamer_iep_ctx_alloc(void); 54 51 55 #endif src/stratcon_jlog_streamer.c
r4dd8a48 r8ad126b 40 40 #include "stratcon_datastore.h" 41 41 #include "stratcon_jlog_streamer.h" 42 #include "stratcon_iep.h" 42 43 43 44 #include <unistd.h> … … 73 74 nc_print_noit_conn_brief(noit_console_closure_t ncct, 74 75 noit_connection_ctx_t *ctx) { 76 jlog_streamer_ctx_t *jctx = ctx->consumer_ctx; 75 77 struct timeval now, diff, session_duration; 76 gettimeofday(&now, NULL);78 const char *feedtype = "unknown"; 77 79 const char *lasttime = "never"; 78 80 if(ctx->last_connect.tv_sec != 0) { … … 85 87 } 86 88 nc_printf(ncct, "%s [%s]:\n\tLast connect: %s\n", ctx->remote_str, 87 ctx->timeout_event ? "disconnected" : "connected", lasttime); 89 ctx->remote_cn ? "connected" : 90 (ctx->timeout_event ? "disconnected" : 91 "connecting"), lasttime); 92 switch(ntohl(jctx->jlog_feed_cmd)) { 93 case NOIT_JLOG_DATA_FEED: feedtype = "durable/storage"; break; 94 case NOIT_JLOG_DATA_TEMP_FEED: feedtype = "transient/iep"; break; 95 } 96 nc_printf(ncct, "\tJLog event streamer [%s]\n", feedtype); 97 gettimeofday(&now, NULL); 88 98 if(ctx->timeout_event) { 89 sub_timeval(now, ctx->timeout_event->whence, &diff); 90 nc_printf(ncct, "\tNext attempet in %llu.%06us\n", diff.tv_sec, diff.tv_usec); 91 } 92 else { 99 sub_timeval(ctx->timeout_event->whence, now, &diff); 100 nc_printf(ncct, "\tNext attempt in %llu.%06us\n", 101 (unsigned long long)diff.tv_sec, (unsigned int) diff.tv_usec); 102 } 103 else if(ctx->remote_cn) { 93 104 nc_printf(ncct, "\tRemote CN: '%s'\n", 94 105 ctx->remote_cn ? ctx->remote_cn : "???"); 95 106 if(ctx->consumer_callback == stratcon_jlog_recv_handler) { 96 jlog_streamer_ctx_t *jctx = ctx->consumer_ctx;97 107 struct timeval last; 98 108 double session_duration_seconds; 99 const char *feedtype = "unknown";100 109 const char *state = "unknown"; 101 110 102 switch(ntohl(jctx->jlog_feed_cmd)) {103 case NOIT_JLOG_DATA_FEED: feedtype = "durable/storage"; break;104 case NOIT_JLOG_DATA_TEMP_FEED: feedtype = "transient/iep"; break;105 }106 111 switch(jctx->state) { 107 112 case JLOG_STREAMER_WANT_INITIATE: state = "initiate"; break; … … 118 123 session_duration_seconds = session_duration.tv_sec + 119 124 (double)session_duration.tv_usec/1000000.0; 120 nc_printf(ncct, "\t JLog event streamer [%s]\n\tState: %s\n"125 nc_printf(ncct, "\tState: %s\n" 121 126 "\tNext checkpoint: [%08x:%08x]\n" 122 127 "\tLast event: %llu.%06us ago\n" 123 128 "\tEvents this session: %llu (%0.2f/s)\n" 124 129 "\tOctets this session: %llu (%0.2f/s)\n", 125 feedtype,state,130 state, 126 131 jctx->header.chkpt.log, jctx->header.chkpt.marker, 127 diff.tv_sec,diff.tv_usec,132 (unsigned long long)diff.tv_sec, (unsigned int)diff.tv_usec, 128 133 jctx->total_events, 129 134 (double)jctx->total_events/session_duration_seconds, … … 743 748 } 744 749 745 static void746 register_console_streamer_commands() {747 noit_console_state_t *tl;748 cmd_info_t *showcmd;749 750 tl = noit_console_state_initial();751 showcmd = noit_console_state_get_cmd(tl, "show");752 assert(showcmd && showcmd->dstate);753 754 noit_console_state_add_cmd(showcmd->dstate,755 NCSCMD("noits", stratcon_console_show_noits, NULL, NULL, NULL));756 }757 758 750 static int 759 751 rest_show_noits(noit_http_rest_closure_t *restc, … … 794 786 (int)ctx->last_connect.tv_usec); 795 787 xmlSetProp(node, (xmlChar *)"last_connect", (xmlChar *)buff); 796 xmlSetProp(node, (xmlChar *)"state", ctx->timeout_event ? 797 (xmlChar *)"disconnected" : (xmlChar *)"connected"); 788 xmlSetProp(node, (xmlChar *)"state", ctx->remote_cn ? 789 (xmlChar *)"connected" : 790 (ctx->timeout_event ? (xmlChar *)"disconnected" : 791 (xmlChar *)"connecting")); 792 xmlSetProp(node, (xmlChar *)"remote", (xmlChar *)ctx->remote_str); 793 switch(ntohl(jctx->jlog_feed_cmd)) { 794 case NOIT_JLOG_DATA_FEED: feedtype = "durable/storage"; break; 795 case NOIT_JLOG_DATA_TEMP_FEED: feedtype = "transient/iep"; break; 796 } 797 xmlSetProp(node, (xmlChar *)"type", (xmlChar *)feedtype); 798 798 if(ctx->timeout_event) { 799 sub_timeval( now, ctx->timeout_event->whence, &diff);799 sub_timeval(ctx->timeout_event->whence, now, &diff); 800 800 snprintf(buff, sizeof(buff), "%llu.%06d", 801 801 (long long unsigned)diff.tv_sec, (int)diff.tv_usec); 802 802 xmlSetProp(node, (xmlChar *)"next_attempt", (xmlChar *)buff); 803 803 } 804 xmlSetProp(node, (xmlChar *)"remote", (xmlChar *)ctx->remote_str); 805 if(ctx->remote_cn) 806 xmlSetProp(node, (xmlChar *)"remote_cn", (xmlChar *)ctx->remote_cn); 807 808 switch(ntohl(jctx->jlog_feed_cmd)) { 809 case NOIT_JLOG_DATA_FEED: feedtype = "durable/storage"; break; 810 case NOIT_JLOG_DATA_TEMP_FEED: feedtype = "transient/iep"; break; 811 } 812 xmlSetProp(node, (xmlChar *)"type", (xmlChar *)feedtype); 813 switch(jctx->state) { 814 case JLOG_STREAMER_WANT_INITIATE: state = "initiate"; break; 815 case JLOG_STREAMER_WANT_COUNT: state = "waiting for next batch"; break; 816 case JLOG_STREAMER_WANT_HEADER: state = "reading header"; break; 817 case JLOG_STREAMER_WANT_BODY: state = "reading body"; break; 818 case JLOG_STREAMER_IS_ASYNC: state = "asynchronously processing"; break; 819 case JLOG_STREAMER_WANT_CHKPT: state = "checkpointing"; break; 820 } 821 xmlSetProp(node, (xmlChar *)"state", (xmlChar *)state); 822 snprintf(buff, sizeof(buff), "%08x:%08x", 823 jctx->header.chkpt.log, jctx->header.chkpt.marker); 824 xmlSetProp(node, (xmlChar *)"checkpoint", (xmlChar *)buff); 825 snprintf(buff, sizeof(buff), "%llu", 826 (long long unsigned)jctx->total_events); 827 xmlSetProp(node, (xmlChar *)"session_events", (xmlChar *)buff); 828 snprintf(buff, sizeof(buff), "%llu", 829 (long long unsigned)jctx->total_bytes_read); 830 xmlSetProp(node, (xmlChar *)"session_bytes", (xmlChar *)buff); 831 832 sub_timeval(now, ctx->last_connect, &diff); 833 snprintf(buff, sizeof(buff), "%llu.%06d", 834 (long long unsigned)diff.tv_sec, (int)diff.tv_usec); 835 xmlSetProp(node, (xmlChar *)"session_duration", (xmlChar *)buff); 836 837 if(jctx->header.tv_sec) { 838 last.tv_sec = jctx->header.tv_sec; 839 last.tv_usec = jctx->header.tv_usec; 804 else if(ctx->remote_cn) { 805 if(ctx->remote_cn) 806 xmlSetProp(node, (xmlChar *)"remote_cn", (xmlChar *)ctx->remote_cn); 807 808 switch(jctx->state) { 809 case JLOG_STREAMER_WANT_INITIATE: state = "initiate"; break; 810 case JLOG_STREAMER_WANT_COUNT: state = "waiting for next batch"; break; 811 case JLOG_STREAMER_WANT_HEADER: state = "reading header"; break; 812 case JLOG_STREAMER_WANT_BODY: state = "reading body"; break; 813 case JLOG_STREAMER_IS_ASYNC: state = "asynchronously processing"; break; 814 case JLOG_STREAMER_WANT_CHKPT: state = "checkpointing"; break; 815 } 816 xmlSetProp(node, (xmlChar *)"state", (xmlChar *)state); 817 snprintf(buff, sizeof(buff), "%08x:%08x", 818 jctx->header.chkpt.log, jctx->header.chkpt.marker); 819 xmlSetProp(node, (xmlChar *)"checkpoint", (xmlChar *)buff); 820 snprintf(buff, sizeof(buff), "%llu", 821 (unsigned long long)jctx->total_events); 822 xmlSetProp(node, (xmlChar *)"session_events", (xmlChar *)buff); 823 snprintf(buff, sizeof(buff), "%llu", 824 (unsigned long long)jctx->total_bytes_read); 825 xmlSetProp(node, (xmlChar *)"session_bytes", (xmlChar *)buff); 826 827 sub_timeval(now, ctx->last_connect, &diff); 840 828 snprintf(buff, sizeof(buff), "%llu.%06d", 841 (long long unsigned)last.tv_sec, (int)last.tv_usec); 842 xmlSetProp(node, (xmlChar *)"last_event", (xmlChar *)buff); 843 sub_timeval(now, last, &diff); 844 snprintf(buff, sizeof(buff), "%llu.%06d", 845 (long long unsigned)diff.tv_sec, (int)diff.tv_usec); 846 xmlSetProp(node, (xmlChar *)"last_event_age", (xmlChar *)buff); 829 (unsigned long long)diff.tv_sec, (int)diff.tv_usec); 830 xmlSetProp(node, (xmlChar *)"session_duration", (xmlChar *)buff); 831 832 if(jctx->header.tv_sec) { 833 last.tv_sec = jctx->header.tv_sec; 834 last.tv_usec = jctx->header.tv_usec; 835 snprintf(buff, sizeof(buff), "%llu.%06d", 836 (unsigned long long)last.tv_sec, (int)last.tv_usec); 837 xmlSetProp(node, (xmlChar *)"last_event", (xmlChar *)buff); 838 sub_timeval(now, last, &diff); 839 snprintf(buff, sizeof(buff), "%llu.%06d", 840 (unsigned long long)diff.tv_sec, (int)diff.tv_usec); 841 xmlSetProp(node, (xmlChar *)"last_event_age", (xmlChar *)buff); 842 } 847 843 } 848 844 … … 858 854 return 0; 859 855 } 856 static int 857 stratcon_add_noit(const char *target, unsigned short port) { 858 int cnt; 859 char path[256]; 860 char port_str[6]; 861 noit_conf_section_t *noit_configs, parent; 862 xmlNodePtr newnoit; 863 864 snprintf(path, sizeof(path), 865 "//noits//noit[@address=\"%s\" and @port=\"%d\"]", target, port); 866 noit_configs = noit_conf_get_sections(NULL, path, &cnt); 867 free(noit_configs); 868 if(cnt != 0) return 0; 869 870 parent = noit_conf_get_section(NULL, "//noits"); 871 if(!parent) return 0; 872 snprintf(port_str, sizeof(port_str), "%d", port); 873 newnoit = xmlNewNode(NULL, (xmlChar *)"noit"); 874 xmlSetProp(newnoit, (xmlChar *)"address", (xmlChar *)target); 875 xmlSetProp(newnoit, (xmlChar *)"port", (xmlChar *)port_str); 876 xmlAddChild(parent, newnoit); 877 noit_conf_mark_changed(); 878 stratcon_streamer_connection(NULL, target, 879 stratcon_jlog_recv_handler, 880 (void *(*)())stratcon_jlog_streamer_datastore_ctx_alloc, 881 NULL, 882 jlog_streamer_ctx_free); 883 stratcon_streamer_connection(NULL, target, 884 stratcon_jlog_recv_handler, 885 (void *(*)())stratcon_jlog_streamer_iep_ctx_alloc, 886 NULL, 887 jlog_streamer_ctx_free); 888 return 1; 889 } 890 static int 891 stratcon_remove_noit(const char *target, unsigned short port) { 892 noit_hash_iter iter = NOIT_HASH_ITER_ZERO; 893 uuid_t key_id; 894 int klen, n = 0, i, cnt = 0; 895 void *vconn; 896 noit_connection_ctx_t **ctx; 897 noit_conf_section_t *noit_configs; 898 char path[256]; 899 char remote_str[256]; 900 901 snprintf(remote_str, sizeof(remote_str), "%s:%d", target, port); 902 903 snprintf(path, sizeof(path), 904 "//noits//noit[@address=\"%s\" and @port=\"%d\"]", target, port); 905 noit_configs = noit_conf_get_sections(NULL, path, &cnt); 906 for(i=0; i<cnt; i++) { 907 xmlUnlinkNode(noit_configs[i]); 908 xmlFreeNode(noit_configs[i]); 909 } 910 free(noit_configs); 911 noit_conf_mark_changed(); 912 913 pthread_mutex_lock(&noits_lock); 914 ctx = malloc(sizeof(*ctx) * noits.size); 915 while(noit_hash_next(&noits, &iter, (const char **)key_id, &klen, 916 &vconn)) { 917 if(!strcmp(((noit_connection_ctx_t *)vconn)->remote_str, remote_str)) { 918 ctx[n] = (noit_connection_ctx_t *)vconn; 919 noit_atomic_inc32(&ctx[n]->refcnt); 920 n++; 921 } 922 } 923 pthread_mutex_unlock(&noits_lock); 924 for(i=0; i<n; i++) { 925 noit_connection_ctx_dealloc(ctx[i]); /* once for the record */ 926 noit_connection_ctx_deref(ctx[i]); /* once for the aboce inc32 */ 927 } 928 free(ctx); 929 return n; 930 } 931 static int 932 stratcon_console_conf_noits(noit_console_closure_t ncct, 933 int argc, char **argv, 934 noit_console_state_t *dstate, 935 void *closure) { 936 char *cp, target[128]; 937 unsigned short port = 43191; 938 int adding = (int)closure; 939 if(argc != 1) 940 return -1; 941 942 cp = strchr(argv[0], ':'); 943 if(cp) { 944 strlcpy(target, argv[0], MIN(sizeof(target), cp-argv[0]+1)); 945 port = atoi(cp+1); 946 } 947 else strlcpy(target, argv[0], sizeof(target)); 948 if(adding) { 949 if(stratcon_add_noit(target, port)) { 950 nc_printf(ncct, "Added noit at %s:%d\n", target, port); 951 } 952 else { 953 nc_printf(ncct, "Failed to add noit at %s:%d\n", target, port); 954 } 955 } 956 else { 957 if(stratcon_remove_noit(target, port)) { 958 nc_printf(ncct, "Removed noit at %s:%d\n", target, port); 959 } 960 else { 961 nc_printf(ncct, "Failed to remove noit at %s:%d\n", target, port); 962 } 963 } 964 return 0; 965 } 966 967 static void 968 register_console_streamer_commands() { 969 noit_console_state_t *tl; 970 cmd_info_t *showcmd, *confcmd, *conftcmd, *conftnocmd; 971 972 tl = noit_console_state_initial(); 973 showcmd = noit_console_state_get_cmd(tl, "show"); 974 assert(showcmd && showcmd->dstate); 975 confcmd = noit_console_state_get_cmd(tl, "configure"); 976 conftcmd = noit_console_state_get_cmd(confcmd->dstate, "terminal"); 977 conftnocmd = noit_console_state_get_cmd(conftcmd->dstate, "no"); 978 979 noit_console_state_add_cmd(conftcmd->dstate, 980 NCSCMD("noit", stratcon_console_conf_noits, NULL, NULL, (void *)1)); 981 noit_console_state_add_cmd(conftnocmd->dstate, 982 NCSCMD("noit", stratcon_console_conf_noits, NULL, NULL, (void *)0)); 983 984 noit_console_state_add_cmd(showcmd->dstate, 985 NCSCMD("noits", stratcon_console_show_noits, NULL, NULL, NULL)); 986 } 987 988 860 989 void 861 990 stratcon_jlog_streamer_init(const char *toplevel) { … … 875 1004 ) == 0); 876 1005 } 1006 src/stratcond.c
r8504a3b r8ad126b 172 172 173 173 noit_console_init(APPNAME); 174 noit_console_conf_init(); 174 175 noit_http_rest_init(); 175 176 stratcon_realtime_http_init(APPNAME);
