1 /*
2 * Copyright (c) 2017 Balabit
3 * Copyright (c) 2017 Balázs Scheidler
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * As an additional exemption you are allowed to compile & link against the
19 * OpenSSL libraries as published by the OpenSSL project. See the file
20 * COPYING for details.
21 *
22 */
23 #include "file-specializations.h"
24 #include "transport/transport-file.h"
25 #include "logproto-file-writer.h"
26 #include "messages.h"
27 #include "ack-tracker/ack_tracker_factory.h"
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <errno.h>
33
34 static gboolean
_prepare_open(FileOpener * self,const gchar * name)35 _prepare_open(FileOpener *self, const gchar *name)
36 {
37 struct stat st;
38
39 if (stat(name, &st) >= 0)
40 {
41 if (S_ISFIFO(st.st_mode))
42 {
43 msg_error("You are using the file() driver, underlying file is a FIFO, it should be used by pipe()",
44 evt_tag_str("filename", name));
45 errno = EINVAL;
46 return FALSE;
47 }
48 }
49 return TRUE;
50 }
51
52 static LogTransport *
_construct_src_transport(FileOpener * self,gint fd)53 _construct_src_transport(FileOpener *self, gint fd)
54 {
55 LogTransport *transport = log_transport_file_new(fd);
56
57 transport->read = log_transport_file_read_and_ignore_eof_method;
58 return transport;
59 }
60
61 static LogProtoServer *
_construct_src_proto(FileOpener * s,LogTransport * transport,LogProtoFileReaderOptions * proto_options)62 _construct_src_proto(FileOpener *s, LogTransport *transport, LogProtoFileReaderOptions *proto_options)
63 {
64 log_proto_server_options_set_ack_tracker_factory(&proto_options->super.super,
65 consecutive_ack_tracker_factory_new());
66 return log_proto_file_reader_new(transport, proto_options);
67 }
68
69 FileOpener *
file_opener_for_regular_source_files_new(void)70 file_opener_for_regular_source_files_new(void)
71 {
72 FileOpener *self = file_opener_new();
73
74 self->prepare_open = _prepare_open;
75 self->construct_transport = _construct_src_transport;
76 self->construct_src_proto = _construct_src_proto;
77 return self;
78 }
79
80 typedef struct _FileOpenerRegularDestFiles
81 {
82 FileOpener super;
83 const LogWriterOptions *writer_options;
84 gboolean *use_fsync;
85 } FileOpenerRegularDestFiles;
86
87 static LogProtoClient *
_construct_dst_proto(FileOpener * s,LogTransport * transport,LogProtoClientOptions * proto_options)88 _construct_dst_proto(FileOpener *s, LogTransport *transport, LogProtoClientOptions *proto_options)
89 {
90 FileOpenerRegularDestFiles *self = (FileOpenerRegularDestFiles *) s;
91
92 return log_proto_file_writer_new(transport, proto_options,
93 self->writer_options->flush_lines,
94 *self->use_fsync);
95 }
96
97 static LogTransport *
_construct_transport(FileOpener * s,gint fd)98 _construct_transport(FileOpener *s, gint fd)
99 {
100 return log_transport_file_new(fd);
101 }
102
103 FileOpener *
file_opener_for_regular_dest_files_new(const LogWriterOptions * writer_options,gboolean * use_fsync)104 file_opener_for_regular_dest_files_new(const LogWriterOptions *writer_options, gboolean *use_fsync)
105 {
106 FileOpenerRegularDestFiles *self = g_new0(FileOpenerRegularDestFiles, 1);
107
108 file_opener_init_instance(&self->super);
109 self->super.construct_transport = _construct_transport;
110 self->super.construct_dst_proto = _construct_dst_proto;
111 self->writer_options = writer_options;
112 self->use_fsync = use_fsync;
113 return &self->super;
114 }
115