noit_log_stream_t noit_log_stream_new(const char *name, const char *type, const char *path, void *ctx, noit_hash_table *config) { noit_log_stream_t ls, saved; struct _noit_log_stream tmpbuf; void *vops = NULL; ls = calloc(1, sizeof(*ls)); ls->name = strdup(name); ls->path = path ? strdup(path) : NULL; ls->type = type ? strdup(type) : NULL; ls->enabled = 1; ls->config = config; if(!type) ls->ops = NULL; else if(noit_hash_retrieve(&noit_logops, type, strlen(type), &vops)) ls->ops = vops; else goto freebail; if(ls->ops && ls->ops->openop(ls)) goto freebail; saved = noit_log_stream_find(name); if(saved) { pthread_rwlock_t *lock = saved->lock; memcpy(&tmpbuf, saved, sizeof(*saved)); memcpy(saved, ls, sizeof(*saved)); memcpy(ls, &tmpbuf, sizeof(*saved)); saved->lock = lock; ls->lock = NULL; noit_log_stream_free(ls); ls = saved; } else { /* We strdup the name *again*. We'going to kansas city shuffle the * ls later (see memcpy above). However, if don't strdup, then the * noit_log_stream_free up there will sweep our key right our from * under us. */ if(noit_hash_store(&noit_loggers, strdup(ls->name), strlen(ls->name), ls) == 0) goto freebail; ls->lock = calloc(1, sizeof(*ls->lock)); noit_log_init_rwlock(ls); } /* This is for things that don't open on paths */ if(ctx) ls->op_ctx = ctx; return ls; freebail: fprintf(stderr, "Failed to instantiate logger(%s,%s,%s)\n", name, type ? type : "[null]", path ? path : "[null]"); free(ls->name); if(ls->path) free(ls->path); if(ls->type) free(ls->type); free(ls); return NULL; }
void noit_console_closure_free(void *vncct) { noit_console_closure_t ncct = (noit_console_closure_t) vncct; noit_log_stream_t lf; noitL(noit_debug, "ncct free(%p)\n", (void *)ncct); if(ncct->el) el_end(ncct->el); if(ncct->hist) { history_end(ncct->hist); noitL(noit_debug, "ncct free->hist(%p)\n", (void *)ncct->hist); free(ncct->hist); } if(ncct->pty_master >= 0) close(ncct->pty_master); if(ncct->pty_slave >= 0) close(ncct->pty_slave); if(ncct->outbuf) free(ncct->outbuf); if(ncct->telnet) noit_console_telnet_free(ncct->telnet); noit_hash_destroy(&ncct->userdata, NULL, noit_console_userdata_free); while(ncct->state_stack) { noit_console_state_stack_t *tmp; tmp = ncct->state_stack; ncct->state_stack = tmp->last; if(tmp->name) free(tmp->name); free(tmp); } lf = noit_log_stream_find(ncct->feed_path); noit_log_stream_remove(ncct->feed_path); if(lf) { noit_log_stream_free(lf); } free(ncct); }