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); }
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; }
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); }
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; }