void control_connection_wait_for_output(ControlConnection *self) { if (self->output_buffer->len == 0) self->waiting_for_output = TRUE; control_connection_update_watches(self); }
static void control_connection_io_output(gpointer s) { ControlConnection *self = (ControlConnection *) s; gint rc; rc = write(self->control_io.fd, 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_errno("error", errno), NULL); control_connection_stop_watches(self); control_connection_free(self); return; } } else { self->pos += rc; } control_connection_update_watches(self); }
static void control_connection_start_watches(ControlConnection *self, gint sock) { IV_FD_INIT(&self->control_io); self->control_io.cookie = self; self->control_io.fd = sock; iv_fd_register_try(&self->control_io); control_connection_update_watches(self); }
void control_connection_start_watches(ControlConnection *s) { ControlConnectionUnix *self = (ControlConnectionUnix *)s; IV_FD_INIT(&self->control_io); self->control_io.cookie = self; self->control_io.fd = self->fd; iv_fd_register(&self->control_io); control_connection_update_watches(s); }
static void control_connection_send_reply(ControlConnection *self, gchar *reply, gboolean free_reply) { g_string_assign(self->output_buffer, reply); if (free_reply) g_free(reply); self->pos = 0; if (self->output_buffer->str[self->output_buffer->len - 1] != '\n') g_string_append_c(self->output_buffer, '\n'); g_string_append(self->output_buffer, ".\n"); control_connection_update_watches(self); }
void control_connection_send_reply(ControlConnection *self, GString *reply) { g_string_assign(self->output_buffer, reply->str); g_string_free(reply, TRUE); self->pos = 0; self->waiting_for_output = FALSE; if (self->output_buffer->str[self->output_buffer->len - 1] != '\n') { g_string_append_c(self->output_buffer, '\n'); } g_string_append(self->output_buffer, ".\n"); control_connection_update_watches(self); }
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); }
/* * NOTE: the channel is not in nonblocking mode, thus the control channel * may block syslog-ng completely. */ static void control_connection_io_input(void *s) { ControlConnection *self = (ControlConnection *) s; GString *command = NULL; gchar *nl; gint rc; gint cmd; gint orig_len; 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", NULL); control_connection_stop_watches(self); control_connection_free(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 = read(self->control_io.fd, 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_errno("error", errno), NULL); goto destroy_connection; } /* EAGAIN, should try again when data comes */ control_connection_update_watches(self); return; } else if (rc == 0) { msg_error("EOF on control channel, closing connection", NULL); 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); /* strip NL */ g_string_erase(self->input_buffer, 0, command->len + 1); } else { /* no EOL in the input buffer, wait for more data */ control_connection_update_watches(self); return; } for (cmd = 0; commands[cmd].func; cmd++) { if (strncmp(commands[cmd].command, command->str, strlen(commands[cmd].command)) == 0) { commands[cmd].func(self, command); break; } } if (!commands[cmd].func) { msg_error("Unknown command read on control channel, closing control channel", evt_tag_str("command", command->str), NULL); goto destroy_connection; } control_connection_update_watches(self); g_string_free(command, TRUE); return; destroy_connection: control_connection_stop_watches(self); control_connection_free(self); }