void teardown(void) { control_server_connection_closed(control_server, control_connection); control_server_free(control_server); msg_deinit(); reset_control_command_list(); }
static void control_connection_io_output(gpointer s) { ControlConnection *self = (ControlConnection *) s; gint rc; rc = self->write(self, self->output_buffer->str + self->pos, self->output_buffer->len - self->pos); if (rc < 0) { if (errno != EAGAIN) { msg_error("Error writing control channel", evt_tag_error("error")); control_server_connection_closed(self->server, self); return; } } else { self->pos += rc; } control_connection_update_watches(self); }
static void control_connection_io_input(void *s) { ControlConnection *self = (ControlConnection *) s; GString *command = NULL; gchar *nl; gint rc; gint orig_len; GList *iter; if (self->input_buffer->len > MAX_CONTROL_LINE_LENGTH) { /* too much data in input, drop the connection */ msg_error("Too much data in the control socket input buffer"); control_server_connection_closed(self->server, self); return; } orig_len = self->input_buffer->len; /* NOTE: plus one for the terminating NUL */ g_string_set_size(self->input_buffer, self->input_buffer->len + 128 + 1); rc = self->read(self, self->input_buffer->str + orig_len, 128); if (rc < 0) { if (errno != EAGAIN) { msg_error("Error reading command on control channel, closing control channel", evt_tag_error("error")); goto destroy_connection; } /* EAGAIN, should try again when data comes */ control_connection_update_watches(self); return; } else if (rc == 0) { msg_debug("EOF on control channel, closing connection"); goto destroy_connection; } else { self->input_buffer->len = orig_len + rc; self->input_buffer->str[self->input_buffer->len] = 0; } /* here we have finished reading the input, check if there's a newline somewhere */ nl = strchr(self->input_buffer->str, '\n'); if (nl) { command = g_string_sized_new(128); /* command doesn't contain NL */ g_string_assign_len(command, self->input_buffer->str, nl - self->input_buffer->str); secret_storage_wipe(self->input_buffer->str, nl - self->input_buffer->str); /* strip NL */ /*g_string_erase(self->input_buffer, 0, command->len + 1);*/ g_string_truncate(self->input_buffer, 0); } else { /* no EOL in the input buffer, wait for more data */ control_connection_update_watches(self); return; } iter = g_list_find_custom(get_control_command_list(), command->str, (GCompareFunc)control_command_start_with_command); if (iter == NULL) { msg_error("Unknown command read on control channel, closing control channel", evt_tag_str("command", command->str)); g_string_free(command, TRUE); goto destroy_connection; } ControlCommand *cmd_desc = (ControlCommand *) iter->data; cmd_desc->func(self, command, cmd_desc->user_data); control_connection_wait_for_output(self); secret_storage_wipe(command->str, command->len); g_string_free(command, TRUE); return; destroy_connection: control_server_connection_closed(self->server, self); }