Changeset 30700011fc4916bef71870a2bae7739745a7a2bc
- Timestamp:
- 02/07/08 23:17:43
(5 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1202426263 +0000
- git-parent:
[31ecb27a3a88da161238c56128d25ddc8e264595]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1202426263 +0000
- Message:
integrate a full-on telnet server... hey, why not?
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r3efe34a |
r3070001 |
|
| 25 | 25 | SUBS=utils jlog eventer modules noitedit |
|---|
| 26 | 26 | |
|---|
| 27 | | OBJS=noitd.o noit_listener.o noit_console.o noit_check.o \ |
|---|
| | 27 | OBJS=noitd.o noit_listener.o noit_console.o noit_console_telnet.o \ |
|---|
| | 28 | noit_check.o \ |
|---|
| 28 | 29 | noit_module.o noit_conf.o noit_tokenizer.o |
|---|
| 29 | 30 | |
|---|
| … | … | |
| 44 | 45 | -Lutils -lnoit_utils \ |
|---|
| 45 | 46 | -Ljlog -ljlog \ |
|---|
| | 47 | -Lnoitedit -lnoitedit \ |
|---|
| 46 | 48 | $(LIBS) |
|---|
| 47 | 49 | |
|---|
| r37cf7d8 |
r3070001 |
|
| 9 | 9 | #include <unistd.h> |
|---|
| 10 | 10 | #include <errno.h> |
|---|
| | 11 | #include <sys/ioctl.h> |
|---|
| | 12 | #include <util.h> |
|---|
| | 13 | #include <arpa/telnet.h> |
|---|
| 11 | 14 | |
|---|
| 12 | 15 | #include "eventer/eventer.h" |
|---|
| … | … | |
| 15 | 18 | #include "noit_console.h" |
|---|
| 16 | 19 | #include "noit_tokenizer.h" |
|---|
| 17 | | |
|---|
| 18 | | struct __noit_console_closure { |
|---|
| 19 | | char *outbuf; |
|---|
| 20 | | int outbuf_allocd; |
|---|
| 21 | | int outbuf_len; |
|---|
| 22 | | int outbuf_completed; |
|---|
| 23 | | }; |
|---|
| 24 | 20 | |
|---|
| 25 | 21 | int |
|---|
| … | … | |
| 77 | 73 | return -1; |
|---|
| 78 | 74 | } |
|---|
| | 75 | int |
|---|
| | 76 | nc_write(noit_console_closure_t ncct, void *buf, int len) { |
|---|
| | 77 | if(!ncct->outbuf_allocd) { |
|---|
| | 78 | ncct->outbuf = malloc(len); |
|---|
| | 79 | if(!ncct->outbuf) return 0; |
|---|
| | 80 | ncct->outbuf_allocd = len; |
|---|
| | 81 | } |
|---|
| | 82 | else if(ncct->outbuf_allocd < ncct->outbuf_len + len) { |
|---|
| | 83 | char *newbuf; |
|---|
| | 84 | newbuf = realloc(ncct->outbuf, ncct->outbuf_len + len); |
|---|
| | 85 | if(!newbuf) return 0; |
|---|
| | 86 | ncct->outbuf = newbuf; |
|---|
| | 87 | } |
|---|
| | 88 | memcpy(ncct->outbuf + ncct->outbuf_len, buf, len); |
|---|
| | 89 | ncct->outbuf_len += len; |
|---|
| | 90 | return len; |
|---|
| | 91 | } |
|---|
| | 92 | |
|---|
| 79 | 93 | void |
|---|
| 80 | 94 | noit_console_closure_free(noit_console_closure_t ncct) { |
|---|
| | 95 | if(ncct->el) el_end(ncct->el); |
|---|
| | 96 | if(ncct->pty_master >= 0) close(ncct->pty_master); |
|---|
| | 97 | if(ncct->pty_slave >= 0) close(ncct->pty_slave); |
|---|
| 81 | 98 | if(ncct->outbuf) free(ncct->outbuf); |
|---|
| | 99 | if(ncct->telnet) noit_console_telnet_free(ncct->telnet); |
|---|
| 82 | 100 | free(ncct); |
|---|
| 83 | 101 | } |
|---|
| … | … | |
| 87 | 105 | noit_console_closure_t new_ncct; |
|---|
| 88 | 106 | new_ncct = calloc(1, sizeof(*new_ncct)); |
|---|
| | 107 | new_ncct->pty_master = -1; |
|---|
| | 108 | new_ncct->pty_slave = -1; |
|---|
| 89 | 109 | return new_ncct; |
|---|
| 90 | 110 | } |
|---|
| 91 | 111 | |
|---|
| 92 | 112 | int |
|---|
| 93 | | noit_console_continue_sending(eventer_t e, noit_console_closure_t ncct, |
|---|
| | 113 | noit_console_continue_sending(noit_console_closure_t ncct, |
|---|
| 94 | 114 | int *mask) { |
|---|
| 95 | 115 | int len; |
|---|
| | 116 | eventer_t e = ncct->e; |
|---|
| 96 | 117 | if(!ncct->outbuf_len) return 0; |
|---|
| 97 | 118 | while(ncct->outbuf_len > ncct->outbuf_completed) { |
|---|
| … | … | |
| 116 | 137 | void |
|---|
| 117 | 138 | noit_console_init() { |
|---|
| | 139 | el_multi_init(); |
|---|
| | 140 | signal(SIGTTOU, SIG_IGN); |
|---|
| 118 | 141 | eventer_name_callback("noit_console", noit_console_handler); |
|---|
| 119 | 142 | } |
|---|
| … | … | |
| 137 | 160 | noit_console_handler(eventer_t e, int mask, void *closure, |
|---|
| 138 | 161 | struct timeval *now) { |
|---|
| 139 | | int newmask = EVENTER_READ; |
|---|
| | 162 | int newmask = EVENTER_READ | EVENTER_EXCEPTION; |
|---|
| | 163 | int keep_going; |
|---|
| 140 | 164 | noit_console_closure_t ncct = closure; |
|---|
| 141 | 165 | |
|---|
| 142 | | if(mask & EVENTER_EXCEPTION) { |
|---|
| | 166 | if(mask & EVENTER_EXCEPTION || (ncct && ncct->wants_shutdown)) { |
|---|
| | 167 | socket_error: |
|---|
| 143 | 168 | /* Exceptions cause us to simply snip the connection */ |
|---|
| 144 | 169 | eventer_remove_fd(e->fd); |
|---|
| … | … | |
| 148 | 173 | } |
|---|
| 149 | 174 | |
|---|
| 150 | | if(!ncct) ncct = closure = e->closure = noit_console_closure_alloc(); |
|---|
| | 175 | if(!ncct) { |
|---|
| | 176 | int on = 1; |
|---|
| | 177 | ncct = closure = e->closure = noit_console_closure_alloc(); |
|---|
| | 178 | ncct->e = e; |
|---|
| | 179 | if(openpty(&ncct->pty_master, &ncct->pty_slave, NULL, NULL, NULL) || |
|---|
| | 180 | ioctl(ncct->pty_master, FIONBIO, &on)) { |
|---|
| | 181 | nc_printf(ncct, "Failed to open pty: %s\n", strerror(errno)); |
|---|
| | 182 | ncct->wants_shutdown = 1; |
|---|
| | 183 | } |
|---|
| | 184 | else { |
|---|
| | 185 | ncct->el = el_init("noitd", ncct->pty_master, e->fd, e->fd); |
|---|
| | 186 | el_set(ncct->el, EL_EDITOR, "emacs"); |
|---|
| | 187 | ncct->telnet = noit_console_telnet_alloc(ncct); |
|---|
| | 188 | } |
|---|
| | 189 | } |
|---|
| 151 | 190 | |
|---|
| 152 | 191 | /* If we still have data to send back to the client, this will take |
|---|
| 153 | 192 | * care of that |
|---|
| 154 | 193 | */ |
|---|
| 155 | | if(noit_console_continue_sending(e, ncct, &newmask) == -1) |
|---|
| 156 | | return newmask; |
|---|
| 157 | | |
|---|
| 158 | | if(mask & EVENTER_READ) { |
|---|
| 159 | | int len; |
|---|
| 160 | | char buffer[4096]; |
|---|
| 161 | | len = e->opset->read(e->fd, buffer, sizeof(buffer)-1, &newmask, e); |
|---|
| 162 | | if(len <= 0) { |
|---|
| | 194 | if(noit_console_continue_sending(ncct, &newmask) == -1) { |
|---|
| | 195 | if(errno != EAGAIN) goto socket_error; |
|---|
| | 196 | return newmask | EVENTER_EXCEPTION; |
|---|
| | 197 | } |
|---|
| | 198 | |
|---|
| | 199 | for(keep_going=1 ; keep_going ; ) { |
|---|
| | 200 | int len, plen; |
|---|
| | 201 | char sbuf[4096]; |
|---|
| | 202 | const char *buffer; |
|---|
| | 203 | |
|---|
| | 204 | keep_going = 0; |
|---|
| | 205 | |
|---|
| | 206 | buffer = el_gets(ncct->el, &plen); |
|---|
| | 207 | if(!el_eagain(ncct->el)) keep_going++; |
|---|
| | 208 | |
|---|
| | 209 | len = e->opset->read(e->fd, sbuf, sizeof(sbuf)-1, &newmask, e); |
|---|
| | 210 | if(len == 0 || (len < 0 && errno != EAGAIN)) { |
|---|
| 163 | 211 | eventer_remove_fd(e->fd); |
|---|
| 164 | 212 | close(e->fd); |
|---|
| 165 | 213 | return 0; |
|---|
| 166 | 214 | } |
|---|
| 167 | | buffer[len] = '\0'; |
|---|
| 168 | | printf("IN: %s", buffer); |
|---|
| 169 | | noit_console_dispatch(e, buffer, ncct); |
|---|
| 170 | | if(noit_console_continue_sending(e, ncct, &newmask) == -1) |
|---|
| 171 | | return newmask; |
|---|
| | 215 | if(len > 0) { |
|---|
| | 216 | keep_going++; |
|---|
| | 217 | sbuf[len] = '\0'; |
|---|
| | 218 | if(ncct->telnet) { |
|---|
| | 219 | noit_console_telnet_telrcv(ncct, sbuf, len); |
|---|
| | 220 | ptyflush(ncct); |
|---|
| | 221 | } |
|---|
| | 222 | else { |
|---|
| | 223 | write(ncct->pty_slave, sbuf, len); |
|---|
| | 224 | } |
|---|
| | 225 | } |
|---|
| | 226 | if(buffer) { |
|---|
| | 227 | printf("IN: %s", buffer); |
|---|
| | 228 | noit_console_dispatch(e, buffer, ncct); |
|---|
| | 229 | if(noit_console_continue_sending(ncct, &newmask) == -1) { |
|---|
| | 230 | if(errno != EAGAIN) goto socket_error; |
|---|
| | 231 | return newmask | EVENTER_EXCEPTION; |
|---|
| | 232 | } |
|---|
| | 233 | } |
|---|
| 172 | 234 | } |
|---|
| 173 | 235 | return newmask | EVENTER_EXCEPTION; |
|---|
| r37cf7d8 |
r3070001 |
|
| 9 | 9 | #include "noit_defines.h" |
|---|
| 10 | 10 | #include "eventer/eventer.h" |
|---|
| | 11 | #include "noitedit/histedit.h" |
|---|
| | 12 | #include "noit_console_telnet.h" |
|---|
| 11 | 13 | |
|---|
| | 14 | typedef struct __noit_console_closure { |
|---|
| | 15 | eventer_t e; /* The event it is attached to. This |
|---|
| | 16 | * is needed so it can write itself out */ |
|---|
| | 17 | int wants_shutdown; /* Set this to 1 to have it die */ |
|---|
| 12 | 18 | |
|---|
| 13 | | struct __noit_console_closure; |
|---|
| 14 | | typedef struct __noit_console_closure * noit_console_closure_t; |
|---|
| | 19 | /* nice console support */ |
|---|
| | 20 | EditLine *el; |
|---|
| | 21 | int pty_master; |
|---|
| | 22 | int pty_slave; |
|---|
| | 23 | |
|---|
| | 24 | /* Output buffer for non-blocking sends */ |
|---|
| | 25 | char *outbuf; |
|---|
| | 26 | int outbuf_allocd; |
|---|
| | 27 | int outbuf_len; |
|---|
| | 28 | int outbuf_completed; |
|---|
| | 29 | |
|---|
| | 30 | /* This tracks telnet protocol state (if we're doing telnet) */ |
|---|
| | 31 | noit_console_telnet_closure_t telnet; |
|---|
| | 32 | |
|---|
| | 33 | } * noit_console_closure_t;; |
|---|
| 15 | 34 | |
|---|
| 16 | 35 | API_EXPORT(void) noit_console_init(); |
|---|
| … | … | |
| 27 | 46 | nc_vprintf(noit_console_closure_t ncct, const char *fmt, va_list arg); |
|---|
| 28 | 47 | |
|---|
| | 48 | API_EXPORT(int) |
|---|
| | 49 | nc_write(noit_console_closure_t ncct, void *buf, int len); |
|---|
| 29 | 50 | |
|---|
| | 51 | API_EXPORT(int) |
|---|
| | 52 | noit_console_continue_sending(noit_console_closure_t ncct, |
|---|
| | 53 | int *mask); |
|---|
| 30 | 54 | #endif |
|---|