suricata
output-filestore.c
Go to the documentation of this file.
1 /* Copyright (C) 2018-2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 #include "suricata-common.h"
19 #include "output-filestore.h"
20 
21 #include "stream-tcp.h"
22 
23 #include "feature.h"
24 
25 #include "output.h"
26 #include "output-json-file.h"
27 
28 #include "util-conf.h"
29 #include "util-misc.h"
30 #include "util-path.h"
31 #include "util-print.h"
32 
33 #define MODULE_NAME "OutputFilestore"
34 
35 /* Create a filestore specific PATH_MAX that is less than the system
36  * PATH_MAX to prevent newer gcc truncation warnings with snprint. */
37 #define SHA256_STRING_LEN (SC_SHA256_LEN * 2)
38 #define LEAF_DIR_MAX_LEN 4
39 #define FILESTORE_PREFIX_MAX (PATH_MAX - SHA256_STRING_LEN - LEAF_DIR_MAX_LEN)
40 
41 /* The default log directory, relative to the default log
42  * directory. */
43 static const char *default_log_dir = "filestore";
44 
45 /* Atomic counter of simultaneously open files. */
46 static SC_ATOMIC_DECLARE(uint32_t, filestore_open_file_cnt);
47 
48 typedef struct OutputFilestoreCtx_ {
51  bool fileinfo;
54 
55 typedef struct OutputFilestoreLogThread_ {
57  uint16_t counter_max_hits;
58  uint16_t fs_error_counter;
60 
67 
69 };
70 
71 /* For WARN_ONCE, a record of warnings that have already been
72  * issued. */
73 static thread_local bool once_errs[WOT_MAX];
74 
75 #define WARN_ONCE(wot_type, ...) \
76  do { \
77  if (!once_errs[wot_type]) { \
78  once_errs[wot_type] = true; \
79  SCLogWarning(__VA_ARGS__); \
80  } \
81  } while (0)
82 
83 static uint64_t OutputFilestoreOpenFilesCounter(void)
84 {
85  return SC_ATOMIC_GET(filestore_open_file_cnt);
86 }
87 
88 static uint32_t g_file_store_max_open_files = 0;
89 
90 static void FileSetMaxOpenFiles(uint32_t count)
91 {
92  g_file_store_max_open_files = count;
93 }
94 
95 static uint32_t FileGetMaxOpenFiles(void)
96 {
97  return g_file_store_max_open_files;
98 }
99 
100 /**
101  * \brief Update the timestamps on a file to match those of another
102  * file.
103  *
104  * \param src_filename Filename to use as timestamp source.
105  * \param filename Filename to apply timestamps to.
106  */
107 static void OutputFilestoreUpdateFileTime(const char *src_filename, const char *filename)
108 {
109  struct stat sb;
110  if (stat(src_filename, &sb) != 0) {
111  SCLogDebug("Failed to stat %s: %s", filename, strerror(errno));
112  return;
113  }
114  struct utimbuf utimbuf = {
115  .actime = sb.st_atime,
116  .modtime = sb.st_mtime,
117  };
118  if (utime(filename, &utimbuf) != 0) {
119  SCLogDebug("Failed to update file timestamps: %s: %s", filename, strerror(errno));
120  }
121 }
122 
123 static void OutputFilestoreFinalizeFiles(ThreadVars *tv, const OutputFilestoreLogThread *oft,
124  const OutputFilestoreCtx *ctx, const Packet *p, File *ff, void *tx, const uint64_t tx_id,
125  uint8_t dir)
126 {
127  /* Stringify the SHA256 which will be used in the final
128  * filename. */
129  char sha256string[(SC_SHA256_LEN * 2) + 1];
130  PrintHexString(sha256string, sizeof(sha256string), ff->sha256, sizeof(ff->sha256));
131 
132  /* construct tmp file path */
133  char tmp_filename[PATH_MAX] = "";
134  char tmp_filepath[PATH_MAX] = "";
135  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
136  if (PathMerge(tmp_filepath, sizeof(tmp_filepath), ctx->tmpdir, tmp_filename) < 0)
137  return;
138 
139  /* construct final path */
140  char final_sha_short[3];
141  snprintf(final_sha_short, sizeof(final_sha_short), "%c%c", sha256string[0], sha256string[1]);
142  char final_sha_portion[PATH_MAX];
143  if (PathMerge(final_sha_portion, sizeof(final_sha_portion), final_sha_short, sha256string) < 0)
144  return;
145  char final_filename[PATH_MAX] = "";
146  if (PathMerge(final_filename, sizeof(final_filename), ctx->prefix, final_sha_portion) < 0)
147  return;
148 
149  if (SCPathExists(final_filename)) {
150  OutputFilestoreUpdateFileTime(tmp_filepath, final_filename);
151  if (unlink(tmp_filepath) != 0) {
153  WARN_ONCE(WOT_UNLINK, "Failed to remove temporary file %s: %s", tmp_filepath,
154  strerror(errno));
155  }
156  } else if (rename(tmp_filepath, final_filename) != 0) {
158  WARN_ONCE(WOT_RENAME, "Failed to rename %s to %s: %s", tmp_filepath, final_filename,
159  strerror(errno));
160  if (unlink(tmp_filepath) != 0) {
161  /* Just increment, don't log as has_fs_errors would
162  * already be set above. */
164  }
165  return;
166  }
167 
168  if (ctx->fileinfo) {
169  char js_metadata_filename_suffix[PATH_MAX];
170  if (snprintf(js_metadata_filename_suffix, sizeof(js_metadata_filename_suffix),
171  ".%" PRIuMAX ".%u.json", (uintmax_t)SCTIME_SECS(p->ts),
172  ff->file_store_id) == (int)sizeof(js_metadata_filename_suffix)) {
173  WARN_ONCE(WOT_SNPRINTF, "Failed to write file info record. Output filename truncated.");
174  return;
175  }
176  char js_metadata_filename[PATH_MAX];
177  strlcpy(js_metadata_filename, final_filename, sizeof(js_metadata_filename));
178  strlcat(js_metadata_filename, js_metadata_filename_suffix, sizeof(js_metadata_filename));
179 
180  SCJsonBuilder *js_fileinfo =
181  JsonBuildFileInfoRecord(p, ff, tx, tx_id, true, dir, ctx->xff_cfg, NULL);
182  if (likely(js_fileinfo != NULL)) {
183  SCJbClose(js_fileinfo);
184  FILE *out = fopen(js_metadata_filename, "w");
185  if (out != NULL) {
186  size_t js_len = SCJbLen(js_fileinfo);
187  fwrite(SCJbPtr(js_fileinfo), js_len, 1, out);
188  fclose(out);
189  }
190  SCJbFree(js_fileinfo);
191  }
192  }
193 }
194 
195 static int OutputFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, File *ff,
196  void *tx, const uint64_t tx_id, const uint8_t *data, uint32_t data_len, uint8_t flags,
197  uint8_t dir)
198 {
199  SCEnter();
201  OutputFilestoreCtx *ctx = aft->ctx;
202  char filename[PATH_MAX] = "";
203  int file_fd = -1;
204 
205  SCLogDebug("ff %p, data %p, data_len %u", ff, data, data_len);
206 
208  /* construct tmp file path */
209  char tmp_filename[PATH_MAX] = "";
210  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
211  if (PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename) < 0)
212  return -1;
213 
214  file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644);
215  if (file_fd == -1) {
217  SCLogWarning("Filestore (v2) failed to create %s: %s", filename, strerror(errno));
218  return -1;
219  }
220 
221  if (SC_ATOMIC_GET(filestore_open_file_cnt) < FileGetMaxOpenFiles()) {
222  SC_ATOMIC_ADD(filestore_open_file_cnt, 1);
223  ff->fd = file_fd;
224  } else {
225  if (FileGetMaxOpenFiles() > 0) {
227  }
228  ff->fd = -1;
229  }
230  /* we can get called with NULL data when we need to close */
231  } else if (data != NULL) {
232  if (ff->fd == -1) {
233  /* construct tmp file path */
234  char tmp_filename[PATH_MAX] = "";
235  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
236  if (PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename) < 0)
237  return -1;
238  file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY);
239  if (file_fd == -1) {
241  WARN_ONCE(WOT_OPEN, "Filestore (v2) failed to open file %s: %s", filename,
242  strerror(errno));
243  return -1;
244  }
245  } else {
246  file_fd = ff->fd;
247  }
248  }
249 
250  if (file_fd != -1) {
251  ssize_t r = write(file_fd, (const void *)data, (size_t)data_len);
252  if (r == -1) {
253  /* construct tmp file path */
254  char tmp_filename[PATH_MAX] = "";
255  snprintf(tmp_filename, sizeof(tmp_filename), "file.%u", ff->file_store_id);
256  (void)PathMerge(filename, sizeof(filename), ctx->tmpdir, tmp_filename);
258  WARN_ONCE(WOT_WRITE, "Filestore (v2) failed to write to %s: %s", filename,
259  strerror(errno));
260  if (ff->fd != -1) {
261  SC_ATOMIC_SUB(filestore_open_file_cnt, 1);
262  }
263  ff->fd = -1;
264  }
265  if (ff->fd == -1) {
266  close(file_fd);
267  }
268  }
269 
271  if (ff->fd != -1) {
272  close(ff->fd);
273  ff->fd = -1;
274  SC_ATOMIC_SUB(filestore_open_file_cnt, 1);
275  }
276  OutputFilestoreFinalizeFiles(tv, aft, ctx, p, ff, tx, tx_id, dir);
277  }
278 
279  return 0;
280 }
281 
282 static TmEcode OutputFilestoreLogThreadInit(ThreadVars *t, const void *initdata, void **data)
283 {
285  if (unlikely(aft == NULL))
286  return TM_ECODE_FAILED;
287 
288  if (initdata == NULL) {
289  SCLogDebug("Error getting context for LogFileStore. \"initdata\" argument NULL");
290  SCFree(aft);
291  return TM_ECODE_FAILED;
292  }
293 
294  OutputFilestoreCtx *ctx = ((OutputCtx *)initdata)->data;
295  aft->ctx = ctx;
296 
297  aft->counter_max_hits = StatsRegisterCounter("file_store.open_files_max_hit", t);
298 
299  /* File system type errors (open, write, rename) will only be
300  * logged once. But this stat will be incremented for every
301  * occurrence. */
302  aft->fs_error_counter = StatsRegisterCounter("file_store.fs_errors", t);
303 
304  *data = (void *)aft;
305  return TM_ECODE_OK;
306 }
307 
308 static TmEcode OutputFilestoreLogThreadDeinit(ThreadVars *t, void *data)
309 {
311  if (aft == NULL) {
312  return TM_ECODE_OK;
313  }
314 
315  /* clear memory */
316  memset(aft, 0, sizeof(OutputFilestoreLogThread));
317 
318  SCFree(aft);
319  return TM_ECODE_OK;
320 }
321 
322 static void OutputFilestoreLogDeInitCtx(OutputCtx *output_ctx)
323 {
324  OutputFilestoreCtx *ctx = (OutputFilestoreCtx *)output_ctx->data;
325  if (ctx->xff_cfg != NULL) {
326  SCFree(ctx->xff_cfg);
327  }
328  SCFree(ctx);
329  SCFree(output_ctx);
330 }
331 
332 static int GetLogDirectory(const SCConfNode *conf, char *out, size_t out_size)
333 {
334  const char *log_base_dir = SCConfNodeLookupChildValue(conf, "dir");
335  if (log_base_dir == NULL) {
336  SCLogConfig("Filestore (v2) default log directory %s", default_log_dir);
337  log_base_dir = default_log_dir;
338  }
339  if (PathIsAbsolute(log_base_dir)) {
340  size_t r = strlcpy(out, log_base_dir, out_size);
341  if (r >= out_size)
342  return -1;
343  } else {
344  const char *default_log_prefix = SCConfigGetLogDirectory();
345  if (PathMerge(out, out_size, default_log_prefix, log_base_dir) < 0)
346  return -1;
347  }
348  return 0;
349 }
350 
351 static bool InitFilestoreDirectory(const char *dir)
352 {
353  const uint8_t dir_count = 0xff;
354 
355  if (!SCPathExists(dir)) {
356  SCLogInfo("Filestore (v2) creating directory %s", dir);
357  if (SCCreateDirectoryTree(dir, true) != 0) {
358  SCLogError("Filestore (v2) failed to create directory %s: %s", dir, strerror(errno));
359  return false;
360  }
361  }
362 
363  for (int i = 0; i <= dir_count; i++) {
364  char hex[3];
365  snprintf(hex, sizeof(hex), "%02x", i);
366  char leaf[PATH_MAX];
367  if (PathMerge(leaf, sizeof(leaf), dir, hex) < 0) {
368  SCLogError("Filestore (v2) failed to create leaf directory: "
369  "path too long");
370  return false;
371  }
372  if (!SCPathExists(leaf)) {
373  SCLogInfo("Filestore (v2) creating directory %s", leaf);
374  if (SCDefaultMkDir(leaf) != 0) {
375  SCLogError(
376  "Filestore (v2) failed to create directory %s: %s", leaf, strerror(errno));
377  return false;
378  }
379  }
380  }
381 
382  /* Make sure the tmp directory exists. */
383  char tmpdir[PATH_MAX];
384  if (PathMerge(tmpdir, sizeof(tmpdir), dir, "tmp") < 0) {
385  SCLogError("Filestore (v2) failed to create tmp directory: path too long");
386  return false;
387  }
388  if (!SCPathExists(tmpdir)) {
389  SCLogInfo("Filestore (v2) creating directory %s", tmpdir);
390  if (SCDefaultMkDir(tmpdir) != 0) {
391  SCLogError("Filestore (v2) failed to create directory %s: %s", tmpdir, strerror(errno));
392  return false;
393  }
394  }
395 
396  return true;
397 }
398 
399 /** \brief Create a new http log OutputFilestoreCtx.
400  * \param conf Pointer to ConfNode containing this loggers configuration.
401  * \return NULL if failure, OutputFilestoreCtx* to the file_ctx if succesful
402  * */
403 static OutputInitResult OutputFilestoreLogInitCtx(SCConfNode *conf)
404 {
405  OutputInitResult result = { NULL, false };
406 
407  intmax_t version = 0;
408  if (!SCConfGetChildValueInt(conf, "version", &version) || version < 2) {
409  SCLogWarning("File-store v1 has been removed. Please update to file-store v2.");
410  return result;
411  }
412 
414  SCLogWarning("A file data logger is already enabled. Filestore (v2) "
415  "will not be enabled.");
416  return result;
417  }
418 
419  char log_directory[PATH_MAX] = "";
420  if (GetLogDirectory(conf, log_directory, sizeof(log_directory)) < 0) {
421  SCLogError("File-store output path too long.");
422  return result;
423  }
424  if (!InitFilestoreDirectory(log_directory)) {
425  return result;
426  }
427 
428  OutputFilestoreCtx *ctx = SCCalloc(1, sizeof(*ctx));
429  if (unlikely(ctx == NULL)) {
430  return result;
431  }
432 
433  strlcpy(ctx->prefix, log_directory, sizeof(ctx->prefix));
434 
435  if (PathMerge(ctx->tmpdir, sizeof(ctx->tmpdir), log_directory, "tmp") < 0) {
436  SCLogError("File-store output directory overflow.");
437  SCFree(ctx);
438  return result;
439  }
440 
441  ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
442  if (ctx->xff_cfg != NULL) {
443  HttpXFFGetCfg(conf, ctx->xff_cfg);
444  }
445 
446  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
447  if (unlikely(output_ctx == NULL)) {
448  SCFree(ctx->xff_cfg);
449  SCFree(ctx);
450  return result;
451  }
452 
453  output_ctx->data = ctx;
454  output_ctx->DeInit = OutputFilestoreLogDeInitCtx;
455 
456  const char *write_fileinfo = SCConfNodeLookupChildValue(conf, "write-fileinfo");
457  if (write_fileinfo != NULL && SCConfValIsTrue(write_fileinfo)) {
458  SCLogConfig("Filestore (v2) will output fileinfo records.");
459  ctx->fileinfo = true;
460  }
461 
462  const char *force_filestore = SCConfNodeLookupChildValue(conf, "force-filestore");
463  if (force_filestore != NULL && SCConfValIsTrue(force_filestore)) {
465  SCLogInfo("forcing filestore of all files");
466  }
467 
468  const char *force_magic = SCConfNodeLookupChildValue(conf, "force-magic");
469  if (force_magic != NULL && SCConfValIsTrue(force_magic)) {
471  SCLogConfig("Filestore (v2) forcing magic lookup for stored files");
472  }
473 
474  FileForceHashParseCfg(conf);
475 
476  /* The new filestore requires SHA256. */
478 
480 
481  const char *stream_depth_str = SCConfNodeLookupChildValue(conf, "stream-depth");
482  if (stream_depth_str != NULL && strcmp(stream_depth_str, "no")) {
483  uint32_t stream_depth = 0;
484  if (ParseSizeStringU32(stream_depth_str, &stream_depth) < 0) {
485  SCLogError("Error parsing "
486  "file-store.stream-depth "
487  "from conf file - %s. Killing engine",
488  stream_depth_str);
489  exit(EXIT_FAILURE);
490  }
491  if (stream_depth) {
492  if (stream_depth <= stream_config.reassembly_depth) {
493  SCLogWarning("file-store.stream-depth value %" PRIu32 " has "
494  "no effect since it's less than stream.reassembly.depth "
495  "value.",
496  stream_depth);
497  } else {
498  FileReassemblyDepthEnable(stream_depth);
499  }
500  }
501  }
502 
503  const char *file_count_str = SCConfNodeLookupChildValue(conf, "max-open-files");
504  if (file_count_str != NULL) {
505  uint32_t file_count = 0;
506  if (ParseSizeStringU32(file_count_str, &file_count) < 0) {
507  SCLogError("Error parsing "
508  "file-store.max-open-files "
509  "from conf file - %s. Killing engine",
510  file_count_str);
511  exit(EXIT_FAILURE);
512  } else {
513  if (file_count != 0) {
514  FileSetMaxOpenFiles(file_count);
515  SCLogConfig("Filestore (v2) will keep a max of %d "
516  "simultaneously open files",
517  file_count);
518  }
519  }
520  }
521 
522  result.ctx = output_ctx;
523  result.ok = true;
524  SCReturnCT(result, "OutputInitResult");
525 }
526 
528 {
530  OutputFilestoreLogInitCtx, OutputFilestoreLogger, OutputFilestoreLogThreadInit,
531  OutputFilestoreLogThreadDeinit);
532 
533  SC_ATOMIC_INIT(filestore_open_file_cnt);
534  SC_ATOMIC_SET(filestore_open_file_cnt, 0);
535 }
536 
538 {
539  StatsRegisterGlobalCounter("file_store.open_files", OutputFilestoreOpenFilesCounter);
540 }
SCConfValIsTrue
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:551
OutputFilestoreCtx_::prefix
char prefix[FILESTORE_PREFIX_MAX]
Definition: output-filestore.c:49
O_NOFOLLOW
#define O_NOFOLLOW
Definition: win32-misc.h:30
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
FileForceHashParseCfg
void FileForceHashParseCfg(SCConfNode *conf)
Function to parse forced file hashing configuration.
Definition: util-file.c:169
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
FileReassemblyDepthEnable
void FileReassemblyDepthEnable(uint32_t size)
Definition: util-file.c:127
JsonBuildFileInfoRecord
SCJsonBuilder * JsonBuildFileInfoRecord(const Packet *p, const File *ff, void *tx, const uint64_t tx_id, const bool stored, uint8_t dir, HttpXFFCfg *xff_cfg, OutputJsonCtx *eve_ctx)
Definition: output-json-file.c:82
stream-tcp.h
HttpXFFGetCfg
void HttpXFFGetCfg(SCConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
Definition: app-layer-htp-xff.c:202
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
PathMerge
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
Definition: util-path.c:74
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
OutputFilestoreCtx_::tmpdir
char tmpdir[FILESTORE_PREFIX_MAX]
Definition: output-filestore.c:50
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1010
WOT_MAX
@ WOT_MAX
Definition: output-filestore.c:68
SC_SHA256_LEN
#define SC_SHA256_LEN
Definition: util-file.h:65
OutputFilestoreCtx_::fileinfo
bool fileinfo
Definition: output-filestore.c:51
OutputFilestoreLogThread_::fs_error_counter
uint16_t fs_error_counter
Definition: output-filestore.c:58
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:75
ctx
struct Thresholds ctx
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
File_::file_store_id
uint32_t file_store_id
Definition: util-file.h:113
PrintHexString
void PrintHexString(char *str, size_t size, uint8_t *buf, size_t buf_len)
Definition: util-print.c:255
FileForceMagicEnable
void FileForceMagicEnable(void)
Definition: util-file.c:98
OutputRegisterFiledataModule
void OutputRegisterFiledataModule(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, SCFiledataLogger FiledataLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Register a file data output module.
Definition: output.c:459
SCConfNodeLookupChildValue
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:824
OutputFilestoreCtx_::xff_cfg
HttpXFFCfg * xff_cfg
Definition: output-filestore.c:52
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
WOT_OPEN
@ WOT_OPEN
Definition: output-filestore.c:62
OutputFilestoreCtx_
Definition: output-filestore.c:48
OUTPUT_FILEDATA_FLAG_CLOSE
#define OUTPUT_FILEDATA_FLAG_CLOSE
Definition: output-filedata.h:30
OutputCtx_::data
void * data
Definition: tm-modules.h:91
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
SCDefaultMkDir
int SCDefaultMkDir(const char *path)
Wrapper around SCMkDir with default mode arguments.
Definition: util-path.c:123
OutputCtx_
Definition: tm-modules.h:88
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
OutputFilestoreLogThread_
Definition: output-filestore.c:55
feature.h
WARN_ONCE
#define WARN_ONCE(wot_type,...)
Definition: output-filestore.c:75
OutputFilestoreCtx
struct OutputFilestoreCtx_ OutputFilestoreCtx
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
Packet_::ts
SCTime_t ts
Definition: decode.h:555
File_::fd
int fd
Definition: util-file.h:114
output-json-file.h
WOT_WRITE
@ WOT_WRITE
Definition: output-filestore.c:63
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:281
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
OutputInitResult_::ok
bool ok
Definition: output.h:48
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:259
OutputFilestoreRegister
void OutputFilestoreRegister(void)
Definition: output-filestore.c:527
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
SC_ATOMIC_DECLARE
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
Definition: util-atomic.h:280
Packet_
Definition: decode.h:501
SCConfGetChildValueInt
int SCConfGetChildValueInt(const SCConfNode *base, const char *name, intmax_t *val)
Definition: conf.c:449
SCConfigGetLogDirectory
const char * SCConfigGetLogDirectory(void)
Definition: util-conf.c:38
TmEcode
TmEcode
Definition: tm-threads-common.h:80
HttpXFFCfg_
Definition: app-layer-htp-xff.h:41
OutputFilestoreLogThread_::counter_max_hits
uint16_t counter_max_hits
Definition: output-filestore.c:57
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:229
FILESTORE_PREFIX_MAX
#define FILESTORE_PREFIX_MAX
Definition: output-filestore.c:39
SCPathExists
bool SCPathExists(const char *path)
Check if a path exists.
Definition: util-path.c:183
WOT_SNPRINTF
@ WOT_SNPRINTF
Definition: output-filestore.c:66
File_
Definition: util-file.h:107
OutputInitResult_
Definition: output.h:46
util-conf.h
FEATURE_OUTPUT_FILESTORE
#define FEATURE_OUTPUT_FILESTORE
Definition: feature.h:28
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
FileForceFilestoreEnable
void FileForceFilestoreEnable(void)
Definition: util-file.c:92
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:94
util-path.h
WOT_RENAME
@ WOT_RENAME
Definition: output-filestore.c:65
OUTPUT_FILEDATA_FLAG_OPEN
#define OUTPUT_FILEDATA_FLAG_OPEN
Definition: output-filedata.h:29
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
version
uint8_t version
Definition: decode-gre.h:1
output-filestore.h
WarnOnceTypes
WarnOnceTypes
Definition: output-filestore.c:61
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
File_::sha256
uint8_t sha256[SC_SHA256_LEN]
Definition: util-file.h:126
ParseSizeStringU32
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition: util-misc.c:174
SCLogConfig
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
MODULE_NAME
#define MODULE_NAME
Definition: output-filestore.c:33
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:271
SCFree
#define SCFree(p)
Definition: util-mem.h:61
OutputFilestoreLogThread
struct OutputFilestoreLogThread_ OutputFilestoreLogThread
LOGGER_FILE_STORE
@ LOGGER_FILE_STORE
Definition: suricata-common.h:500
WOT_UNLINK
@ WOT_UNLINK
Definition: output-filestore.c:64
ProvidesFeature
void ProvidesFeature(const char *feature_name)
Definition: feature.c:111
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:295
OutputFilestoreLogThread_::ctx
OutputFilestoreCtx * ctx
Definition: output-filestore.c:56
likely
#define likely(expr)
Definition: util-optimize.h:32
RunModeOutputFiledataEnabled
int RunModeOutputFiledataEnabled(void)
Definition: runmodes.c:543
OutputFilestoreRegisterGlobalCounters
void OutputFilestoreRegisterGlobalCounters(void)
Definition: output-filestore.c:537
FileForceSha256Enable
void FileForceSha256Enable(void)
Definition: util-file.c:116
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
util-misc.h
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:952
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCConfNode_
Definition: conf.h:37
output.h
SCCreateDirectoryTree
int SCCreateDirectoryTree(const char *path, const bool final)
Recursively create a directory.
Definition: util-path.c:137