Changeset 30700011fc4916bef71870a2bae7739745a7a2bc

Show
Ignore:
Timestamp:
02/07/08 23:17:43 (7 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
  • src/Makefile.in

    r3efe34a r3070001  
    2525SUBS=utils jlog eventer modules noitedit 
    2626 
    27 OBJS=noitd.o noit_listener.o noit_console.o noit_check.o \ 
     27OBJS=noitd.o noit_listener.o noit_console.o noit_console_telnet.o \ 
     28        noit_check.o \ 
    2829        noit_module.o noit_conf.o noit_tokenizer.o 
    2930 
     
    4445                -Lutils -lnoit_utils \ 
    4546                -Ljlog -ljlog \ 
     47                -Lnoitedit -lnoitedit \ 
    4648                $(LIBS) 
    4749 
  • src/noit_console.c

    r37cf7d8 r3070001  
    99#include <unistd.h> 
    1010#include <errno.h> 
     11#include <sys/ioctl.h> 
     12#include <util.h> 
     13#include <arpa/telnet.h> 
    1114 
    1215#include "eventer/eventer.h" 
     
    1518#include "noit_console.h" 
    1619#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 }; 
    2420 
    2521int 
     
    7773  return -1; 
    7874} 
     75int 
     76nc_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 
    7993void 
    8094noit_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); 
    8198  if(ncct->outbuf) free(ncct->outbuf); 
     99  if(ncct->telnet) noit_console_telnet_free(ncct->telnet); 
    82100  free(ncct); 
    83101} 
     
    87105  noit_console_closure_t new_ncct; 
    88106  new_ncct = calloc(1, sizeof(*new_ncct)); 
     107  new_ncct->pty_master = -1; 
     108  new_ncct->pty_slave = -1; 
    89109  return new_ncct; 
    90110} 
    91111 
    92112int 
    93 noit_console_continue_sending(eventer_t e, noit_console_closure_t ncct, 
     113noit_console_continue_sending(noit_console_closure_t ncct, 
    94114                              int *mask) { 
    95115  int len; 
     116  eventer_t e = ncct->e; 
    96117  if(!ncct->outbuf_len) return 0; 
    97118  while(ncct->outbuf_len > ncct->outbuf_completed) { 
     
    116137void 
    117138noit_console_init() { 
     139  el_multi_init(); 
     140  signal(SIGTTOU, SIG_IGN); 
    118141  eventer_name_callback("noit_console", noit_console_handler); 
    119142} 
     
    137160noit_console_handler(eventer_t e, int mask, void *closure, 
    138161                     struct timeval *now) { 
    139   int newmask = EVENTER_READ; 
     162  int newmask = EVENTER_READ | EVENTER_EXCEPTION; 
     163  int keep_going; 
    140164  noit_console_closure_t ncct = closure; 
    141165 
    142   if(mask & EVENTER_EXCEPTION) { 
     166  if(mask & EVENTER_EXCEPTION || (ncct && ncct->wants_shutdown)) { 
     167socket_error: 
    143168    /* Exceptions cause us to simply snip the connection */ 
    144169    eventer_remove_fd(e->fd); 
     
    148173  } 
    149174 
    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  } 
    151190 
    152191  /* If we still have data to send back to the client, this will take 
    153192   * care of that 
    154193   */ 
    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)) { 
    163211      eventer_remove_fd(e->fd); 
    164212      close(e->fd); 
    165213      return 0; 
    166214    } 
    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    } 
    172234  } 
    173235  return newmask | EVENTER_EXCEPTION; 
  • src/noit_console.h

    r37cf7d8 r3070001  
    99#include "noit_defines.h" 
    1010#include "eventer/eventer.h" 
     11#include "noitedit/histedit.h" 
     12#include "noit_console_telnet.h" 
    1113 
     14typedef 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 */ 
    1218 
    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;; 
    1534 
    1635API_EXPORT(void) noit_console_init(); 
     
    2746  nc_vprintf(noit_console_closure_t ncct, const char *fmt, va_list arg); 
    2847 
     48API_EXPORT(int) 
     49  nc_write(noit_console_closure_t ncct, void *buf, int len); 
    2950 
     51API_EXPORT(int) 
     52  noit_console_continue_sending(noit_console_closure_t ncct, 
     53                                int *mask); 
    3054#endif