Beispiel #1
0
void
noit_log_init() {
  noit_hash_init(&noit_loggers);
  noit_hash_init(&noit_logops);
  noit_register_logops("file", &posix_logio_ops);
  noit_register_logops("jlog", &jlog_logio_ops);
  noit_stderr = noit_log_stream_new_on_fd("stderr", 2, NULL);
  noit_stderr->timestamps = 1;
  noit_error = noit_log_stream_new("error", NULL, NULL, NULL, NULL);
  noit_debug = noit_log_stream_new("debug", NULL, NULL, NULL, NULL);
}
Beispiel #2
0
void
noit_log_init(int debug_on) {
  noit_hash_init(&noit_loggers);
  noit_hash_init(&noit_logops);
  noit_register_logops("file", &posix_logio_ops);
  noit_register_logops("jlog", &jlog_logio_ops);
  noit_register_logops("memory", &membuf_logio_ops);
  noit_stderr = noit_log_stream_new_on_fd("stderr", 2, NULL);
  noit_stderr->flags |= NOIT_LOG_STREAM_TIMESTAMPS;
  noit_stderr->flags |= NOIT_LOG_STREAM_FACILITY;
  noit_error = noit_log_stream_new("error", NULL, NULL, NULL, NULL);
  noit_debug = noit_log_stream_new("debug", NULL, NULL, NULL, NULL);
  noit_notice = noit_log_stream_new("notice", NULL, NULL, NULL, NULL);
  noit_debug->flags = (noit_debug->flags & ~NOIT_LOG_STREAM_DEBUG) |
                      (debug_on ? NOIT_LOG_STREAM_DEBUG : 0);
  if(debug_on) noit_debug->flags |= NOIT_LOG_STREAM_ENABLED;
  else noit_debug->flags &= ~NOIT_LOG_STREAM_ENABLED;
}
Beispiel #3
0
noit_log_stream_t
noit_log_stream_new_on_file(const char *path, noit_hash_table *config) {
  return noit_log_stream_new(path, "file", path, NULL, config);
}
Beispiel #4
0
int
noit_console_handler(eventer_t e, int mask, void *closure,
                     struct timeval *now) {
  int newmask = EVENTER_READ | EVENTER_EXCEPTION;
  int keep_going;
  acceptor_closure_t *ac = closure;
  noit_console_closure_t ncct = ac->service_ctx;

  if(mask & EVENTER_EXCEPTION || (ncct && ncct->wants_shutdown)) {
socket_error:
    /* Exceptions cause us to simply snip the connection */

    /* This removes the log feed which is important to do before calling close */
    eventer_remove_fd(e->fd);
    if(ncct) noit_console_closure_free(ncct);
    if(ac) acceptor_closure_free(ac);
    e->opset->close(e->fd, &newmask, e);
    return 0;
  }

  if(!ac->service_ctx) {
    ncct = ac->service_ctx = noit_console_closure_alloc();
  }
  if(!ncct->initialized) {
    ncct->e = e;
    if(allocate_pty(&ncct->pty_master, &ncct->pty_slave)) {
      nc_printf(ncct, "Failed to open pty: %s\n", strerror(errno));
      ncct->wants_shutdown = 1;
      goto socket_error;
    }
    else {
      int i;
      const char *line_protocol;
      HistEvent ev;

      ncct->hist = history_init();
      history(ncct->hist, &ev, H_SETSIZE, 500);
      ncct->el = el_init("noitd", ncct->pty_master, NULL,
                         e->fd, e, e->fd, e);
      if(!ncct->el) goto socket_error;
      if(el_set(ncct->el, EL_USERDATA, ncct)) {
        noitL(noit_error, "Cannot set userdata on noitedit session\n");
        goto socket_error;
      }
      if(el_set(ncct->el, EL_EDITOR, "emacs")) 
        noitL(noit_error, "Cannot set emacs mode on console\n");
      if(el_set(ncct->el, EL_HIST, history, ncct->hist))
        noitL(noit_error, "Cannot set history on console\n");
      el_set(ncct->el, EL_ADDFN, "noit_complete",
             "auto completion functions for noit", noit_edit_complete);
      el_set(ncct->el, EL_BIND, "^I", "noit_complete", NULL);
      for(i=EL_NUM_FCNS; i < ncct->el->el_map.nfunc; i++) {
        if(ncct->el->el_map.func[i] == noit_edit_complete) {
          ncct->noit_edit_complete_cmdnum = i;
          break;
        }
      }

      if(!noit_hash_retr_str(ac->config,
                             "line_protocol", strlen("line_protocol"),
                             &line_protocol)) {
        line_protocol = NULL;
      }
      if(line_protocol && !strcasecmp(line_protocol, "telnet")) {
        ncct->telnet = noit_console_telnet_alloc(ncct);
        ncct->output_cooker = nc_telnet_cooker;
      }
      noit_console_state_init(ncct);
    }
    snprintf(ncct->feed_path, sizeof(ncct->feed_path), "console/%d", e->fd);
    noit_log_stream_new(ncct->feed_path, "noit_console", ncct->feed_path,
                        ncct, NULL);
    noit_console_motd(e, ac, ncct);
    ncct->initialized = 1;
  }

  /* If we still have data to send back to the client, this will take
   * care of that
   */
  if(noit_console_continue_sending(ncct, &newmask) < 0) {
    if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error;
    return newmask | EVENTER_EXCEPTION;
  }

  for(keep_going=1 ; keep_going ; ) {
    int len, plen;
    char sbuf[4096];
    const char *buffer;

    keep_going = 0;

    buffer = el_gets(ncct->el, &plen);
    if(!el_eagain(ncct->el)) {
      if(!buffer) {
        buffer = "exit";
        plen = 4;
        nc_write(ncct, "\n", 1);
      }
      keep_going++;
    }

    len = e->opset->read(e->fd, sbuf, sizeof(sbuf)-1, &newmask, e);
    if(len == 0 || (len < 0 && errno != EAGAIN)) {
      eventer_remove_fd(e->fd);
      if(ncct) noit_console_closure_free(ncct);
      if(ac) acceptor_closure_free(ac);
      e->opset->close(e->fd, &newmask, e);
      return 0;
    }
    if(len > 0) {
      keep_going++;
      sbuf[len] = '\0';
      if(ncct->telnet) {
        noit_console_telnet_telrcv(ncct, sbuf, len);
        ptyflush(ncct);
      }
      else {
        int written;
        written = write(ncct->pty_slave, sbuf, len);
        if(written <= 0) goto socket_error;
        assert(written == len);
      }
    }
    if(buffer) {
      char *cmd_buffer;
      cmd_buffer = malloc(plen+1);
      memcpy(cmd_buffer, buffer, plen);
      /* chomp */
      cmd_buffer[plen] = '\0';
      if(cmd_buffer[plen-1] == '\n') cmd_buffer[plen-1] = '\0';
      noitL(noit_debug, "IN[%d]: '%s'\n", plen, cmd_buffer);
      noit_console_dispatch(e, cmd_buffer, ncct);
      free(cmd_buffer);
    }
    if(noit_console_continue_sending(ncct, &newmask) == -1) {
      if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error;
      return newmask | EVENTER_EXCEPTION;
    }
    if(ncct->wants_shutdown) goto socket_error;
  }
  return newmask | EVENTER_EXCEPTION;
}
int
noit_livestream_handler(eventer_t e, int mask, void *closure,
                        struct timeval *now) {
  eventer_t newe;
  pthread_t tid;
  int newmask = EVENTER_READ | EVENTER_EXCEPTION;
  acceptor_closure_t *ac = closure;
  noit_livestream_closure_t *jcl = ac->service_ctx;

  if(mask & EVENTER_EXCEPTION || (jcl && jcl->wants_shutdown)) {
socket_error:
    /* Exceptions cause us to simply snip the connection */
    eventer_remove_fd(e->fd);
    e->opset->close(e->fd, &newmask, e);
    if(jcl) noit_livestream_closure_free(jcl);
    if(ac) acceptor_closure_free(ac);
    return 0;
  }

  if(!ac->service_ctx || !jcl->feed) {
    int len;
    jcl = ac->service_ctx = noit_livestream_closure_alloc();
    /* Setup logger to this channel */
    if(!jcl->period) {
      u_int32_t nperiod;
      len = e->opset->read(e->fd, &nperiod, sizeof(nperiod), &mask, e);
      if(len == -1 && errno == EAGAIN) return mask | EVENTER_EXCEPTION;
      if(len != sizeof(nperiod)) goto socket_error;
      jcl->period = ntohl(nperiod);
      if(!jcl->period) {
        noitL(noit_error, "period of 0 specified in livestream.  not allowed.\n");
        goto socket_error;
      }
    }
    while(jcl->uuid_read < 36) {
      len = e->opset->read(e->fd, jcl->uuid_str + jcl->uuid_read, 36 - jcl->uuid_read, &mask, e);
      if(len == -1 && errno == EAGAIN) return mask | EVENTER_EXCEPTION;
      if(len == 0) goto socket_error;
      jcl->uuid_read += len;
    }
    jcl->uuid_str[36] = '\0';
    if(uuid_parse(jcl->uuid_str, jcl->uuid)) {
      noitL(noit_error, "bad uuid received in livestream handler '%s'\n", jcl->uuid_str);
      goto socket_error;
    }

    jcl->feed = malloc(32);
    snprintf(jcl->feed, 32, "livestream/%d", noit_atomic_inc32(&ls_counter));
    noit_log_stream_new(jcl->feed, "noit_livestream", jcl->feed,
                        jcl, NULL);


    jcl->check = noit_check_watch(jcl->uuid, jcl->period);
    if(!jcl->check) {
      e->opset->close(e->fd, &newmask, e);
      return 0;
    }
    /* This check must be watched from the livestream */
    noit_check_transient_add_feed(jcl->check, jcl->feed);
    /* Note the check */
    noit_check_log_check(jcl->check);
    /* kick it off, if it isn't running already */
    if(!NOIT_CHECK_LIVE(jcl->check)) noit_check_activate(jcl->check);
  }

  eventer_remove_fd(e->fd);
  newe = eventer_alloc();
  memcpy(newe, e, sizeof(*e));
  if(pthread_create(&tid, NULL, noit_livestream_thread_main, newe) == 0) {
    return 0;
  }

  noit_check_transient_remove_feed(jcl->check, jcl->feed);
  noit_livestream_closure_free(jcl);
  /* Undo our dup */
  eventer_free(newe);
  /* Creating the thread failed, close it down and deschedule. */
  e->opset->close(e->fd, &newmask, e);
  return 0;
}