Changeset a7f575acc420cc6e5ca474d23cf07149299a3bbd
- Timestamp:
- 02/09/08 06:05:17
(5 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1202537117 +0000
- git-parent:
[1d69a01311e58ce6ddb007d690b4e9aa4ac08c8c]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1202537117 +0000
- Message:
start the framework for a console state machine
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r3070001 |
ra7f575a |
|
| 25 | 25 | SUBS=utils jlog eventer modules noitedit |
|---|
| 26 | 26 | |
|---|
| 27 | | OBJS=noitd.o noit_listener.o noit_console.o noit_console_telnet.o \ |
|---|
| | 27 | OBJS=noitd.o noit_listener.o \ |
|---|
| | 28 | noit_console.o noit_console_state.o noit_console_telnet.o \ |
|---|
| 28 | 29 | noit_check.o \ |
|---|
| 29 | 30 | noit_module.o noit_conf.o noit_tokenizer.o |
|---|
| r1d69a01 |
ra7f575a |
|
| 24 | 24 | #include "noit_tokenizer.h" |
|---|
| 25 | 25 | |
|---|
| | 26 | static void |
|---|
| | 27 | nc_telnet_cooker(noit_console_closure_t ncct) { |
|---|
| | 28 | char *tmpbuf, *p, *n; |
|---|
| | 29 | int r; |
|---|
| | 30 | |
|---|
| | 31 | tmpbuf = ncct->outbuf; |
|---|
| | 32 | if(ncct->outbuf_len == 0) return; |
|---|
| | 33 | |
|---|
| | 34 | p = ncct->outbuf + ncct->outbuf_completed; |
|---|
| | 35 | r = ncct->outbuf_len - ncct->outbuf_completed; |
|---|
| | 36 | n = memchr(p, '\n', r); |
|---|
| | 37 | /* No '\n'? Nothin' to do */ |
|---|
| | 38 | if(!n) { |
|---|
| | 39 | ncct->outbuf_cooked = ncct->outbuf_len; |
|---|
| | 40 | return; |
|---|
| | 41 | } |
|---|
| | 42 | |
|---|
| | 43 | /* Forget the outbuf -- it is now tmpbuf */ |
|---|
| | 44 | ncct->outbuf = NULL; |
|---|
| | 45 | ncct->outbuf_allocd = 0; |
|---|
| | 46 | ncct->outbuf_len = 0; |
|---|
| | 47 | ncct->outbuf_completed = 0; |
|---|
| | 48 | ncct->outbuf_cooked = 0; |
|---|
| | 49 | do { |
|---|
| | 50 | if(n == tmpbuf || *(n-1) != '\r') { |
|---|
| | 51 | nc_write(ncct, p, n-p); r -= n-p; |
|---|
| | 52 | nc_write(ncct, "\r", 1); |
|---|
| | 53 | p = n; |
|---|
| | 54 | } |
|---|
| | 55 | n = memchr(p+1, '\n', r-1); |
|---|
| | 56 | } while(n); |
|---|
| | 57 | nc_write(ncct, p, r); |
|---|
| | 58 | ncct->outbuf_cooked = ncct->outbuf_len; |
|---|
| | 59 | free(tmpbuf); |
|---|
| | 60 | } |
|---|
| 26 | 61 | int |
|---|
| 27 | 62 | nc_printf(noit_console_closure_t ncct, const char *fmt, ...) { |
|---|
| … | … | |
| 104 | 139 | if(ncct->outbuf) free(ncct->outbuf); |
|---|
| 105 | 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); |
|---|
| | 146 | } |
|---|
| 106 | 147 | free(ncct); |
|---|
| 107 | 148 | } |
|---|
| … | … | |
| 122 | 163 | eventer_t e = ncct->e; |
|---|
| 123 | 164 | if(!ncct->outbuf_len) return 0; |
|---|
| | 165 | if(ncct->output_cooker) ncct->output_cooker(ncct); |
|---|
| 124 | 166 | while(ncct->outbuf_len > ncct->outbuf_completed) { |
|---|
| 125 | 167 | len = e->opset->write(e->fd, ncct->outbuf + ncct->outbuf_completed, |
|---|
| … | … | |
| 136 | 178 | free(ncct->outbuf); |
|---|
| 137 | 179 | ncct->outbuf = NULL; |
|---|
| 138 | | ncct->outbuf_allocd = 0; |
|---|
| 139 | | ncct->outbuf_len = ncct->outbuf_completed = 0; |
|---|
| | 180 | ncct->outbuf_allocd = ncct->outbuf_len = |
|---|
| | 181 | ncct->outbuf_completed = ncct->outbuf_cooked = 0; |
|---|
| 140 | 182 | return len; |
|---|
| 141 | 183 | } |
|---|
| … | … | |
| 151 | 193 | noit_console_dispatch(eventer_t e, const char *buffer, |
|---|
| 152 | 194 | noit_console_closure_t ncct) { |
|---|
| 153 | | char *cmds[32]; |
|---|
| | 195 | char **cmds; |
|---|
| 154 | 196 | int i, cnt = 32; |
|---|
| 155 | | nc_printf(ncct, "You said: %s\r\n", buffer); |
|---|
| | 197 | cmds = alloca(32 * sizeof(*cmds)); |
|---|
| | 198 | nc_printf(ncct, "You said: %s\n", buffer); |
|---|
| 156 | 199 | i = noit_tokenize(buffer, cmds, &cnt); |
|---|
| 157 | 200 | if(i>cnt) nc_printf(ncct, "Command length too long.\n"); |
|---|
| 158 | | if(i<0) nc_printf(ncct, "Error at offset: %d\n", 0-i); |
|---|
| | 201 | else if(i<0) nc_printf(ncct, "Error at offset: %d\n", 0-i); |
|---|
| | 202 | else noit_console_state_do(ncct, cnt, cmds); |
|---|
| 159 | 203 | for(i=0;i<cnt;i++) { |
|---|
| 160 | | nc_printf(ncct, "[%d] '%s'\r\n", i, cmds[i]); |
|---|
| | 204 | nc_printf(ncct, "[%d] '%s'\n", i, cmds[i]); |
|---|
| 161 | 205 | free(cmds[i]); |
|---|
| 162 | 206 | } |
|---|
| … | … | |
| 196 | 240 | el_set(ncct->el, EL_HIST, history, ncct->hist); |
|---|
| 197 | 241 | ncct->telnet = noit_console_telnet_alloc(ncct); |
|---|
| | 242 | ncct->output_cooker = nc_telnet_cooker; |
|---|
| | 243 | ncct->state = noit_console_state_initial(); |
|---|
| | 244 | noit_console_state_init(ncct); |
|---|
| 198 | 245 | } |
|---|
| 199 | 246 | } |
|---|
| … | … | |
| 202 | 249 | * care of that |
|---|
| 203 | 250 | */ |
|---|
| 204 | | if(noit_console_continue_sending(ncct, &newmask) == -1) { |
|---|
| 205 | | if(errno != EAGAIN) goto socket_error; |
|---|
| | 251 | if(noit_console_continue_sending(ncct, &newmask) < 0) { |
|---|
| | 252 | if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error; |
|---|
| 206 | 253 | return newmask | EVENTER_EXCEPTION; |
|---|
| 207 | 254 | } |
|---|
| … | … | |
| 218 | 265 | |
|---|
| 219 | 266 | len = e->opset->read(e->fd, sbuf, sizeof(sbuf)-1, &newmask, e); |
|---|
| 220 | | noitL(noit_stderr, "opset->read => %d bytes\n", len); |
|---|
| 221 | 267 | if(len == 0 || (len < 0 && errno != EAGAIN)) { |
|---|
| 222 | 268 | eventer_remove_fd(e->fd); |
|---|
| … | … | |
| 247 | 293 | noit_console_dispatch(e, cmd_buffer, ncct); |
|---|
| 248 | 294 | free(cmd_buffer); |
|---|
| 249 | | if(noit_console_continue_sending(ncct, &newmask) == -1) { |
|---|
| 250 | | if(errno != EAGAIN) goto socket_error; |
|---|
| 251 | | return newmask | EVENTER_EXCEPTION; |
|---|
| 252 | | } |
|---|
| 253 | | } |
|---|
| | 295 | } |
|---|
| | 296 | if(noit_console_continue_sending(ncct, &newmask) == -1) { |
|---|
| | 297 | if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error; |
|---|
| | 298 | return newmask | EVENTER_EXCEPTION; |
|---|
| | 299 | } |
|---|
| | 300 | if(ncct->wants_shutdown) goto socket_error; |
|---|
| 254 | 301 | } |
|---|
| 255 | 302 | return newmask | EVENTER_EXCEPTION; |
|---|
| r1d69a01 |
ra7f575a |
|
| 11 | 11 | #include "noitedit/histedit.h" |
|---|
| 12 | 12 | #include "noit_console_telnet.h" |
|---|
| | 13 | #include "utils/noit_hash.h" |
|---|
| 13 | 14 | #include <stdarg.h> |
|---|
| | 15 | |
|---|
| | 16 | struct _console_state; |
|---|
| | 17 | struct __noit_console_closure; |
|---|
| | 18 | |
|---|
| | 19 | typedef int (*console_cmd_func_t)(struct __noit_console_closure *, |
|---|
| | 20 | int, char **); |
|---|
| | 21 | typedef char *(*console_prompt_func_t)(EditLine *); |
|---|
| | 22 | typedef void (*state_free_func_t)(struct _console_state *); |
|---|
| | 23 | |
|---|
| | 24 | typedef struct cmd_info { |
|---|
| | 25 | const char *name; |
|---|
| | 26 | console_cmd_func_t func; |
|---|
| | 27 | } cmd_info_t; |
|---|
| | 28 | |
|---|
| | 29 | typedef struct _console_state { |
|---|
| | 30 | console_prompt_func_t console_prompt_function; |
|---|
| | 31 | noit_hash_table cmds; |
|---|
| | 32 | struct _console_state *stacked; |
|---|
| | 33 | state_free_func_t statefree; |
|---|
| | 34 | } noit_console_state_t; |
|---|
| 14 | 35 | |
|---|
| 15 | 36 | typedef struct __noit_console_closure { |
|---|
| … | … | |
| 22 | 43 | History *hist; |
|---|
| 23 | 44 | |
|---|
| | 45 | noit_console_state_t *state; |
|---|
| | 46 | |
|---|
| 24 | 47 | int pty_master; |
|---|
| 25 | 48 | int pty_slave; |
|---|
| … | … | |
| 29 | 52 | int outbuf_allocd; |
|---|
| 30 | 53 | int outbuf_len; |
|---|
| | 54 | int outbuf_cooked; |
|---|
| 31 | 55 | int outbuf_completed; |
|---|
| 32 | 56 | |
|---|
| 33 | 57 | /* This tracks telnet protocol state (if we're doing telnet) */ |
|---|
| 34 | 58 | noit_console_telnet_closure_t telnet; |
|---|
| 35 | | |
|---|
| 36 | | } * noit_console_closure_t;; |
|---|
| | 59 | void (*output_cooker)(struct __noit_console_closure *); |
|---|
| | 60 | } * noit_console_closure_t; |
|---|
| 37 | 61 | |
|---|
| 38 | 62 | API_EXPORT(void) noit_console_init(); |
|---|
| … | … | |
| 55 | 79 | noit_console_continue_sending(noit_console_closure_t ncct, |
|---|
| 56 | 80 | int *mask); |
|---|
| | 81 | |
|---|
| | 82 | API_EXPORT(int) |
|---|
| | 83 | noit_console_state_init(noit_console_closure_t ncct); |
|---|
| | 84 | |
|---|
| | 85 | API_EXPORT(char *) |
|---|
| | 86 | noit_console_state_prompt(EditLine *el); |
|---|
| | 87 | |
|---|
| | 88 | API_EXPORT(int) |
|---|
| | 89 | noit_console_state_pop(noit_console_closure_t ncct, int argc, char **argv); |
|---|
| | 90 | |
|---|
| | 91 | API_EXPORT(noit_console_state_t *) |
|---|
| | 92 | noit_console_state_initial(); |
|---|
| | 93 | |
|---|
| | 94 | API_EXPORT(void) |
|---|
| | 95 | noit_console_state_free(noit_console_state_t *st); |
|---|
| | 96 | |
|---|
| | 97 | API_EXPORT(int) |
|---|
| | 98 | noit_console_state_do(noit_console_closure_t ncct, int argc, char **argv); |
|---|
| | 99 | |
|---|
| 57 | 100 | #endif |
|---|