static LogProtoStatus log_proto_framed_server_fetch_data(LogProtoFramedServer *self, gboolean *may_read) { gint rc; if (self->buffer_pos == self->buffer_end) self->buffer_pos = self->buffer_end = 0; if (self->buffer_size == self->buffer_end) { /* no more space in the buffer, we can't fetch further data. Move the * things we already have to the beginning of the buffer to make * space. */ memmove(self->buffer, &self->buffer[self->buffer_pos], self->buffer_end - self->buffer_pos); self->buffer_end = self->buffer_end - self->buffer_pos; self->buffer_pos = 0; } if (!(*may_read)) return LPS_SUCCESS; rc = log_transport_read(self->super.transport, &self->buffer[self->buffer_end], self->buffer_size - self->buffer_end, NULL); if (rc < 0) { if (errno != EAGAIN) { msg_error("Error reading RFC5428 style framed data", evt_tag_int("fd", self->super.transport->fd), evt_tag_errno("error", errno), NULL); return LPS_ERROR; } else { /* we need more data to parse this message but the data is not available yet */ self->half_message_in_buffer = TRUE; } } else if (rc == 0) { msg_verbose("EOF occurred while reading", evt_tag_int(EVT_TAG_FD, self->super.transport->fd), NULL); return LPS_EOF; } else { self->buffer_end += rc; } return LPS_SUCCESS; }
static gint log_proto_record_server_read_data(LogProtoBufferedServer *s, guchar *buf, gsize len, LogTransportAuxData *aux) { LogProtoRecordServer *self = (LogProtoRecordServer *) s; gint rc; /* assert that we have enough space in the buffer to read record_size bytes */ g_assert(len >= self->record_size); len = self->record_size; rc = log_transport_read(self->super.super.transport, buf, len, aux); if (rc > 0 && rc != self->record_size) { msg_error("Record size was set, and couldn't read enough bytes", evt_tag_int(EVT_TAG_FD, self->super.super.transport->fd), evt_tag_int("record_size", self->record_size), evt_tag_int("read", rc)); errno = EIO; return -1; } return rc; }
static gint log_proto_buffered_server_read_data_method(LogProtoBufferedServer *self, guchar *buf, gsize len, LogTransportAuxData *aux) { return log_transport_read(self->super.transport, buf, len, aux); }
static void log_proto_buffered_server_apply_state(LogProtoBufferedServer *self, PersistEntryHandle handle, const gchar *persist_name) { struct stat st; gint64 ofs = 0; LogProtoBufferedServerState *state; gint fd; fd = self->super.transport->fd; self->persist_handle = handle; if (fstat(fd, &st) < 0) return; state = log_proto_buffered_server_get_state(self); if (!self->buffer) { self->buffer = g_malloc(state->buffer_size); } state->pending_buffer_end = 0; if (state->file_inode && state->file_inode == st.st_ino && state->file_size <= st.st_size && state->raw_stream_pos <= st.st_size) { ofs = state->raw_stream_pos; lseek(fd, ofs, SEEK_SET); } else { if (state->file_inode) { /* the stored state does not match the current file */ msg_notice("The current log file has a mismatching size/inode information, restarting from the beginning", evt_tag_str("state", persist_name), evt_tag_int("stored_inode", state->file_inode), evt_tag_int("cur_file_inode", st.st_ino), evt_tag_int("stored_size", state->file_size), evt_tag_int("cur_file_size", st.st_size), evt_tag_int("raw_stream_pos", state->raw_stream_pos)); } goto error; } if (state->raw_buffer_size) { gssize rc; guchar *raw_buffer; if (!self->super.options->encoding) { /* no conversion, we read directly into our buffer */ if (state->raw_buffer_size > state->buffer_size) { msg_notice("Invalid LogProtoBufferedServerState.raw_buffer_size, larger than buffer_size and no encoding is set, restarting from the beginning", evt_tag_str("state", persist_name), evt_tag_int("raw_buffer_size", state->raw_buffer_size), evt_tag_int("buffer_size", state->buffer_size), evt_tag_int("init_buffer_size", self->super.options->init_buffer_size)); goto error; } raw_buffer = self->buffer; } else { if (state->raw_buffer_size > self->super.options->max_buffer_size) { msg_notice("Invalid LogProtoBufferedServerState.raw_buffer_size, larger than max_buffer_size, restarting from the beginning", evt_tag_str("state", persist_name), evt_tag_int("raw_buffer_size", state->raw_buffer_size), evt_tag_int("init_buffer_size", self->super.options->init_buffer_size), evt_tag_int("max_buffer_size", self->super.options->max_buffer_size)); goto error; } raw_buffer = g_alloca(state->raw_buffer_size); } rc = log_transport_read(self->super.transport, raw_buffer, state->raw_buffer_size, NULL); if (rc != state->raw_buffer_size) { msg_notice("Error re-reading buffer contents of the file to be continued, restarting from the beginning", evt_tag_str("state", persist_name)); goto error; } state->pending_buffer_end = 0; if (self->super.options->encoding) { if (!log_proto_buffered_server_convert_from_raw(self, raw_buffer, rc)) { msg_notice("Error re-converting buffer contents of the file to be continued, restarting from the beginning", evt_tag_str("state", persist_name)); goto error; } } else { state->pending_buffer_end += rc; } if (state->buffer_pos > state->pending_buffer_end) { msg_notice("Converted buffer contents is smaller than the current buffer position, starting from the beginning of the buffer, some lines may be duplicated", evt_tag_str("state", persist_name)); state->buffer_pos = state->pending_buffer_pos = 0; } } else { /* although we do have buffer position information, but the * complete contents of the buffer is already processed, instead * of reading and then dropping it, position the file after the * indicated block */ state->raw_stream_pos += state->raw_buffer_size; ofs = state->raw_stream_pos; state->raw_buffer_size = 0; state->buffer_pos = state->pending_buffer_end = 0; lseek(fd, state->raw_stream_pos, SEEK_SET); } goto exit; error: ofs = 0; state->buffer_pos = 0; state->pending_buffer_end = 0; state->__deprecated_buffer_cached_eol = 0; state->raw_stream_pos = 0; state->raw_buffer_size = 0; state->raw_buffer_leftover_size = 0; lseek(fd, 0, SEEK_SET); exit: state->file_inode = st.st_ino; state->file_size = st.st_size; state->raw_stream_pos = ofs; state->pending_buffer_pos = state->buffer_pos; state->pending_raw_stream_pos = state->raw_stream_pos; state->pending_raw_buffer_size = state->raw_buffer_size; state->__deprecated_buffer_cached_eol = 0; state = NULL; log_proto_buffered_server_put_state(self); }
static gint log_proto_buffered_server_read_data_method(LogProtoBufferedServer *self, guchar *buf, gsize len, GSockAddr **sa) { return log_transport_read(self->super.transport, buf, len, sa); }