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