Changeset 7192210e4ed02f4546970eb41f6da3a167b4316a
- Timestamp:
- 02/09/08 18:47:00
(5 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1202582820 +0000
- git-parent:
[a7f575acc420cc6e5ca474d23cf07149299a3bbd]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1202582820 +0000
- Message:
delegate hooking into the configuration system to other modules
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r7cdd67a |
r7192210 |
|
| 13 | 13 | |
|---|
| 14 | 14 | #include "noit_conf.h" |
|---|
| | 15 | #include "noit_console.h" |
|---|
| 15 | 16 | #include "utils/noit_hash.h" |
|---|
| 16 | 17 | #include "utils/noit_log.h" |
|---|
| … | … | |
| 38 | 39 | }; |
|---|
| 39 | 40 | |
|---|
| | 41 | void register_console_config_commands(); |
|---|
| 40 | 42 | |
|---|
| 41 | 43 | void noit_conf_init() { |
|---|
| … | … | |
| 48 | 50 | xmlInitParser(); |
|---|
| 49 | 51 | xmlXPathInit(); |
|---|
| | 52 | register_console_config_commands(); |
|---|
| 50 | 53 | } |
|---|
| 51 | 54 | |
|---|
| … | … | |
| 271 | 274 | } |
|---|
| 272 | 275 | |
|---|
| | 276 | |
|---|
| | 277 | static int |
|---|
| | 278 | noit_console_state_conf_terminal(noit_console_closure_t ncct, |
|---|
| | 279 | int argc, char **argv, void *state) { |
|---|
| | 280 | if(argc) { |
|---|
| | 281 | nc_printf(ncct, "extra arguments not expected.\n"); |
|---|
| | 282 | return -1; |
|---|
| | 283 | } |
|---|
| | 284 | noit_console_state_push_state(ncct, state); |
|---|
| | 285 | noit_console_state_init(ncct); |
|---|
| | 286 | return 0; |
|---|
| | 287 | } |
|---|
| | 288 | |
|---|
| | 289 | static char * |
|---|
| | 290 | conf_t_prompt(EditLine *el) { |
|---|
| | 291 | static char *tl = "noit(conf)# "; |
|---|
| | 292 | return tl; |
|---|
| | 293 | } |
|---|
| | 294 | |
|---|
| | 295 | void register_console_config_commands() { |
|---|
| | 296 | noit_console_state_t *tl, *_conf_state, *_conf_t_state; |
|---|
| | 297 | |
|---|
| | 298 | tl = noit_console_state_initial(); |
|---|
| | 299 | |
|---|
| | 300 | _conf_t_state = calloc(1, sizeof(*_conf_t_state)); |
|---|
| | 301 | _conf_t_state->console_prompt_function = conf_t_prompt; |
|---|
| | 302 | noit_console_state_add_cmd(_conf_t_state, &console_command_exit); |
|---|
| | 303 | |
|---|
| | 304 | _conf_state = calloc(1, sizeof(*_conf_state)); |
|---|
| | 305 | noit_console_state_add_cmd(_conf_state, |
|---|
| | 306 | NCSCMD("terminal", noit_console_state_conf_terminal, _conf_t_state)); |
|---|
| | 307 | |
|---|
| | 308 | noit_console_state_add_cmd(tl, |
|---|
| | 309 | NCSCMD("configure", noit_console_state_delegate, _conf_state)); |
|---|
| | 310 | } |
|---|
| ra7f575a |
r7192210 |
|
| 139 | 139 | if(ncct->outbuf) free(ncct->outbuf); |
|---|
| 140 | 140 | if(ncct->telnet) noit_console_telnet_free(ncct->telnet); |
|---|
| 141 | | while(ncct->state) { |
|---|
| 142 | | noit_console_state_t *tmp; |
|---|
| 143 | | tmp = ncct->state; |
|---|
| 144 | | ncct->state = tmp->stacked; |
|---|
| 145 | | noit_console_state_free(tmp); |
|---|
| | 141 | while(ncct->state_stack) { |
|---|
| | 142 | noit_console_state_stack_t *tmp; |
|---|
| | 143 | tmp = ncct->state_stack; |
|---|
| | 144 | ncct->state_stack = tmp->last; |
|---|
| | 145 | free(tmp); |
|---|
| 146 | 146 | } |
|---|
| 147 | 147 | free(ncct); |
|---|
| … | … | |
| 152 | 152 | noit_console_closure_t new_ncct; |
|---|
| 153 | 153 | new_ncct = calloc(1, sizeof(*new_ncct)); |
|---|
| | 154 | noit_console_state_push_state(new_ncct, noit_console_state_initial()); |
|---|
| 154 | 155 | new_ncct->pty_master = -1; |
|---|
| 155 | 156 | new_ncct->pty_slave = -1; |
|---|
| … | … | |
| 241 | 242 | ncct->telnet = noit_console_telnet_alloc(ncct); |
|---|
| 242 | 243 | ncct->output_cooker = nc_telnet_cooker; |
|---|
| 243 | | ncct->state = noit_console_state_initial(); |
|---|
| 244 | 244 | noit_console_state_init(ncct); |
|---|
| 245 | 245 | } |
|---|
| ra7f575a |
r7192210 |
|
| 18 | 18 | |
|---|
| 19 | 19 | typedef int (*console_cmd_func_t)(struct __noit_console_closure *, |
|---|
| 20 | | int, char **); |
|---|
| | 20 | int, char **, void *); |
|---|
| 21 | 21 | typedef char *(*console_prompt_func_t)(EditLine *); |
|---|
| 22 | 22 | typedef void (*state_free_func_t)(struct _console_state *); |
|---|
| … | … | |
| 25 | 25 | const char *name; |
|---|
| 26 | 26 | console_cmd_func_t func; |
|---|
| | 27 | void *closure; |
|---|
| 27 | 28 | } cmd_info_t; |
|---|
| | 29 | |
|---|
| | 30 | /* This performs a pop (exiting if at toplevel) */ |
|---|
| | 31 | extern cmd_info_t console_command_exit; |
|---|
| 28 | 32 | |
|---|
| 29 | 33 | typedef struct _console_state { |
|---|
| 30 | 34 | console_prompt_func_t console_prompt_function; |
|---|
| 31 | 35 | noit_hash_table cmds; |
|---|
| 32 | | struct _console_state *stacked; |
|---|
| 33 | 36 | state_free_func_t statefree; |
|---|
| 34 | 37 | } noit_console_state_t; |
|---|
| | 38 | |
|---|
| | 39 | typedef struct _console_state_stack { |
|---|
| | 40 | noit_console_state_t *state; |
|---|
| | 41 | struct _console_state_stack *last; |
|---|
| | 42 | } noit_console_state_stack_t; |
|---|
| 35 | 43 | |
|---|
| 36 | 44 | typedef struct __noit_console_closure { |
|---|
| … | … | |
| 43 | 51 | History *hist; |
|---|
| 44 | 52 | |
|---|
| 45 | | noit_console_state_t *state; |
|---|
| | 53 | noit_console_state_stack_t *state_stack; |
|---|
| 46 | 54 | |
|---|
| 47 | 55 | int pty_master; |
|---|
| … | … | |
| 83 | 91 | noit_console_state_init(noit_console_closure_t ncct); |
|---|
| 84 | 92 | |
|---|
| 85 | | API_EXPORT(char *) |
|---|
| 86 | | noit_console_state_prompt(EditLine *el); |
|---|
| | 93 | API_EXPORT(int) |
|---|
| | 94 | noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv, |
|---|
| | 95 | void *); |
|---|
| 87 | 96 | |
|---|
| 88 | 97 | API_EXPORT(int) |
|---|
| 89 | | noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv); |
|---|
| | 98 | noit_console_state_add_cmd(noit_console_state_t *state, |
|---|
| | 99 | cmd_info_t *cmd); |
|---|
| | 100 | |
|---|
| | 101 | API_EXPORT(noit_console_state_t *) |
|---|
| | 102 | noit_console_state_build(console_prompt_func_t promptf, cmd_info_t **clist, |
|---|
| | 103 | state_free_func_t sfreef); |
|---|
| | 104 | |
|---|
| | 105 | API_EXPORT(void) |
|---|
| | 106 | noit_console_state_push_state(noit_console_closure_t ncct, |
|---|
| | 107 | noit_console_state_t *); |
|---|
| 90 | 108 | |
|---|
| 91 | 109 | API_EXPORT(noit_console_state_t *) |
|---|
| … | … | |
| 98 | 116 | noit_console_state_do(noit_console_closure_t ncct, int argc, char **argv); |
|---|
| 99 | 117 | |
|---|
| | 118 | API_EXPORT(int) |
|---|
| | 119 | _noit_console_state_do(noit_console_closure_t ncct, |
|---|
| | 120 | noit_console_state_stack_t *stack, |
|---|
| | 121 | int argc, char **argv); |
|---|
| | 122 | |
|---|
| | 123 | API_EXPORT(int) |
|---|
| | 124 | noit_console_state_delegate(noit_console_closure_t ncct, |
|---|
| | 125 | int argc, char **argv, void *closure); |
|---|
| | 126 | |
|---|
| | 127 | API_EXPORT(cmd_info_t *) |
|---|
| | 128 | NCSCMD(const char *name, console_cmd_func_t func, void *closure); |
|---|
| | 129 | |
|---|
| 100 | 130 | #endif |
|---|
| ra7f575a |
r7192210 |
|
| 13 | 13 | #include "noit_tokenizer.h" |
|---|
| 14 | 14 | |
|---|
| 15 | | cmd_info_t _cit_exit = { "exit", noit_console_state_pop }; |
|---|
| 16 | | cmd_info_t *_tl_cmds[] = { |
|---|
| 17 | | &_cit_exit, |
|---|
| 18 | | NULL |
|---|
| 19 | | }; |
|---|
| | 15 | cmd_info_t console_command_exit = { "exit", noit_console_state_pop, NULL }; |
|---|
| | 16 | |
|---|
| | 17 | static char * |
|---|
| | 18 | noit_console_state_prompt(EditLine *el) { |
|---|
| | 19 | static char *tl = "noit# "; |
|---|
| | 20 | return tl; |
|---|
| | 21 | } |
|---|
| 20 | 22 | |
|---|
| 21 | 23 | int |
|---|
| 22 | | noit_console_state_do(noit_console_closure_t ncct, int argc, char **argv) { |
|---|
| | 24 | noit_console_state_delegate(noit_console_closure_t ncct, |
|---|
| | 25 | int argc, char **argv, void *closure) { |
|---|
| | 26 | noit_console_state_stack_t tmps = { 0 }; |
|---|
| | 27 | |
|---|
| | 28 | if(argc == 0) { |
|---|
| | 29 | nc_printf(ncct, "arguments expected\n"); |
|---|
| | 30 | return -1; |
|---|
| | 31 | } |
|---|
| | 32 | tmps.state = closure; |
|---|
| | 33 | return _noit_console_state_do(ncct, &tmps, argc, argv); |
|---|
| | 34 | } |
|---|
| | 35 | |
|---|
| | 36 | int |
|---|
| | 37 | _noit_console_state_do(noit_console_closure_t ncct, |
|---|
| | 38 | noit_console_state_stack_t *stack, |
|---|
| | 39 | int argc, char **argv) { |
|---|
| 23 | 40 | cmd_info_t *cmd; |
|---|
| 24 | 41 | |
|---|
| 25 | | if(!argc) return -1; |
|---|
| 26 | | if(!noit_hash_retrieve(&ncct->state->cmds, |
|---|
| | 42 | if(!argc) { |
|---|
| | 43 | nc_printf(ncct, "arguments expected\n"); |
|---|
| | 44 | return -1; |
|---|
| | 45 | } |
|---|
| | 46 | if(!noit_hash_retrieve(&stack->state->cmds, |
|---|
| 27 | 47 | argv[0], strlen(argv[0]), (void **)&cmd)) { |
|---|
| 28 | 48 | nc_printf(ncct, "No such command: '%s'\n", argv[0]); |
|---|
| 29 | 49 | return -1; |
|---|
| 30 | 50 | } |
|---|
| 31 | | return cmd->func(ncct, argc-1, argv+1); |
|---|
| | 51 | return cmd->func(ncct, argc-1, argv+1, cmd->closure); |
|---|
| | 52 | } |
|---|
| | 53 | int |
|---|
| | 54 | noit_console_state_do(noit_console_closure_t ncct, int argc, char **argv) { |
|---|
| | 55 | return _noit_console_state_do(ncct, ncct->state_stack, argc, argv); |
|---|
| 32 | 56 | } |
|---|
| 33 | 57 | |
|---|
| … | … | |
| 42 | 66 | return strcasecmp(a->name, b->name); |
|---|
| 43 | 67 | } |
|---|
| | 68 | |
|---|
| | 69 | int |
|---|
| | 70 | noit_console_state_add_cmd(noit_console_state_t *state, |
|---|
| | 71 | cmd_info_t *cmd) { |
|---|
| | 72 | return noit_hash_store(&state->cmds, cmd->name, strlen(cmd->name), cmd); |
|---|
| | 73 | } |
|---|
| | 74 | |
|---|
| 44 | 75 | noit_console_state_t * |
|---|
| 45 | 76 | noit_console_state_build(console_prompt_func_t promptf, cmd_info_t **clist, |
|---|
| … | … | |
| 57 | 88 | return state; |
|---|
| 58 | 89 | } |
|---|
| 59 | | void |
|---|
| 60 | | noit_console_state_free(noit_console_state_t *st) { |
|---|
| 61 | | noit_hash_destroy(&st->cmds, NULL, NULL); |
|---|
| | 90 | |
|---|
| | 91 | cmd_info_t *NCSCMD(const char *name, console_cmd_func_t func, |
|---|
| | 92 | void *closure) { |
|---|
| | 93 | cmd_info_t *cmd; |
|---|
| | 94 | cmd = calloc(1, sizeof(*cmd)); |
|---|
| | 95 | cmd->name = strdup(name); |
|---|
| | 96 | cmd->func = func; |
|---|
| | 97 | cmd->closure = closure; |
|---|
| | 98 | return cmd; |
|---|
| 62 | 99 | } |
|---|
| | 100 | |
|---|
| 63 | 101 | noit_console_state_t * |
|---|
| 64 | 102 | noit_console_state_initial() { |
|---|
| 65 | | return noit_console_state_build(noit_console_state_prompt, _tl_cmds, |
|---|
| 66 | | noit_console_state_free); |
|---|
| | 103 | static noit_console_state_t *_top_level_state = NULL; |
|---|
| | 104 | if(!_top_level_state) { |
|---|
| | 105 | _top_level_state = calloc(1, sizeof(*_top_level_state)); |
|---|
| | 106 | noit_console_state_add_cmd(_top_level_state, &console_command_exit); |
|---|
| | 107 | } |
|---|
| | 108 | return _top_level_state; |
|---|
| 67 | 109 | } |
|---|
| 68 | 110 | |
|---|
| 69 | | char * |
|---|
| 70 | | noit_console_state_prompt(EditLine *el) { |
|---|
| 71 | | static char *tl = "noit# "; |
|---|
| 72 | | return tl; |
|---|
| | 111 | void |
|---|
| | 112 | noit_console_state_push_state(noit_console_closure_t ncct, |
|---|
| | 113 | noit_console_state_t *state) { |
|---|
| | 114 | noit_console_state_stack_t *stack; |
|---|
| | 115 | stack = calloc(1, sizeof(*stack)); |
|---|
| | 116 | stack->last = ncct->state_stack; |
|---|
| | 117 | stack->state = state; |
|---|
| | 118 | ncct->state_stack = stack; |
|---|
| 73 | 119 | } |
|---|
| 74 | 120 | |
|---|
| 75 | 121 | int |
|---|
| 76 | | noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv) { |
|---|
| 77 | | noit_console_state_t *current; |
|---|
| | 122 | noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv, |
|---|
| | 123 | void *unused) { |
|---|
| | 124 | noit_console_state_stack_t *current; |
|---|
| 78 | 125 | |
|---|
| 79 | 126 | if(argc) { |
|---|
| … | … | |
| 81 | 128 | return -1; |
|---|
| 82 | 129 | } |
|---|
| 83 | | if(!ncct->state || !ncct->state->stacked) { |
|---|
| | 130 | if(!ncct->state_stack || !ncct->state_stack->last) { |
|---|
| 84 | 131 | ncct->wants_shutdown = 1; |
|---|
| 85 | 132 | return 0; |
|---|
| 86 | 133 | } |
|---|
| 87 | 134 | |
|---|
| 88 | | current = ncct->state; |
|---|
| 89 | | ncct->state = ncct->state->stacked; |
|---|
| 90 | | current->stacked = NULL; |
|---|
| 91 | | if(current->statefree) current->statefree(current); |
|---|
| | 135 | current = ncct->state_stack; |
|---|
| | 136 | ncct->state_stack = current->last; |
|---|
| | 137 | current->last = NULL; |
|---|
| | 138 | if(current->state->statefree) current->state->statefree(current->state); |
|---|
| | 139 | free(current); |
|---|
| 92 | 140 | noit_console_state_init(ncct); |
|---|
| 93 | 141 | return 0; |
|---|
| … | … | |
| 96 | 144 | int |
|---|
| 97 | 145 | noit_console_state_init(noit_console_closure_t ncct) { |
|---|
| 98 | | if(ncct->el && ncct->state->console_prompt_function) { |
|---|
| 99 | | el_set(ncct->el, EL_PROMPT, ncct->state->console_prompt_function); |
|---|
| | 146 | if(ncct->el) { |
|---|
| | 147 | console_prompt_func_t f; |
|---|
| | 148 | f = ncct->state_stack->state->console_prompt_function; |
|---|
| | 149 | el_set(ncct->el, EL_PROMPT, f ? f : noit_console_state_prompt); |
|---|
| 100 | 150 | } |
|---|
| 101 | 151 | return 0; |
|---|