static int FilePruneFile(File *file) { SCEnter(); SCLogDebug("file %p, file->chunks_cnt %"PRIu64, file, file->chunks_cnt); if (!(file->flags & FILE_NOMAGIC)) { /* need magic but haven't set it yet, bail out */ if (file->magic == NULL) SCReturnInt(0); else SCLogDebug("file->magic %s", file->magic); } else { SCLogDebug("file->flags & FILE_NOMAGIC == true"); } /* okay, we now know we can prune */ FileData *fd = file->chunks_head; while (fd != NULL) { SCLogDebug("fd %p", fd); if (file->flags & FILE_NOSTORE || fd->stored == 1) { file->chunks_head = fd->next; if (file->chunks_tail == fd) file->chunks_tail = fd->next; FileDataFree(fd); fd = file->chunks_head; #ifdef DEBUG file->chunks_cnt--; SCLogDebug("file->chunks_cnt %"PRIu64, file->chunks_cnt); #endif } else if (fd->stored == 0) { fd = NULL; SCReturnInt(0); break; } } /* file is done when state is closed+, logging/storing is done (if any) */ if (file->state >= FILE_STATE_CLOSED && (!RunModeOutputFileEnabled() || (file->flags & FILE_LOGGED)) && (!RunModeOutputFiledataEnabled() || (file->flags & FILE_STORED))) { SCReturnInt(1); } else { SCReturnInt(0); } }
static int FilePruneFile(File *file) { SCEnter(); SCLogDebug("file %p, file->chunks_cnt %"PRIu64, file, file->chunks_cnt); if (!(file->flags & FILE_NOMAGIC)) { /* need magic but haven't set it yet, bail out */ if (file->magic == NULL) SCReturnInt(0); else SCLogDebug("file->magic %s", file->magic); } else { SCLogDebug("file->flags & FILE_NOMAGIC == true"); } /* okay, we now know we can prune */ FileData *fd = file->chunks_head; while (fd != NULL) { SCLogDebug("fd %p", fd); if (file->flags & FILE_NOSTORE || fd->stored == 1) { /* keep chunks in memory as long as we still need to * inspect them or parts of them */ if (file->flags & FILE_USE_DETECT) { uint64_t right_edge = fd->stream_offset + fd->len; if (file->content_inspected < right_edge) break; } file->chunks_head = fd->next; if (file->chunks_tail == fd) file->chunks_tail = fd->next; FileDataFree(fd); fd = file->chunks_head; #ifdef DEBUG file->chunks_cnt--; SCLogDebug("file->chunks_cnt %"PRIu64, file->chunks_cnt); #endif } else if (fd->stored == 0) { fd = NULL; SCReturnInt(0); break; } } SCLogDebug("file->state %d. Is >= FILE_STATE_CLOSED: %s", file->state, (file->state >= FILE_STATE_CLOSED) ? "yes" : "no"); /* file is done when state is closed+, logging/storing is done (if any) */ if (file->state >= FILE_STATE_CLOSED && (!RunModeOutputFileEnabled() || (file->flags & FILE_LOGGED)) && (!RunModeOutputFiledataEnabled() || (file->flags & FILE_STORED))) { SCReturnInt(1); } else { SCReturnInt(0); } }
/** \brief Create a new http log LogFilestoreCtx. * \param conf Pointer to ConfNode containing this loggers configuration. * \return NULL if failure, LogFilestoreCtx* to the file_ctx if succesful * */ static OutputInitResult LogFilestoreLogInitCtx(ConfNode *conf) { OutputInitResult result = { NULL, false }; intmax_t version = 0; if (ConfGetChildValueInt(conf, "version", &version)) { if (version > 1) { result.ok = true; return result; } } if (RunModeOutputFiledataEnabled()) { SCLogWarning(SC_ERR_NOT_SUPPORTED, "A file data logger is already enabled. Filestore (v1) " "will not be enabled."); return result; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) return result; output_ctx->data = NULL; output_ctx->DeInit = LogFilestoreLogDeInitCtx; const char *s_default_log_dir = NULL; s_default_log_dir = ConfigGetLogDirectory(); const char *s_base_dir = NULL; s_base_dir = ConfNodeLookupChildValue(conf, "log-dir"); if (s_base_dir == NULL || strlen(s_base_dir) == 0) { strlcpy(g_logfile_base_dir, s_default_log_dir, sizeof(g_logfile_base_dir)); } else { if (PathIsAbsolute(s_base_dir)) { strlcpy(g_logfile_base_dir, s_base_dir, sizeof(g_logfile_base_dir)); } else { snprintf(g_logfile_base_dir, sizeof(g_logfile_base_dir), "%s/%s", s_default_log_dir, s_base_dir); } } const char *force_filestore = ConfNodeLookupChildValue(conf, "force-filestore"); if (force_filestore != NULL && ConfValIsTrue(force_filestore)) { FileForceFilestoreEnable(); SCLogInfo("forcing filestore of all files"); } const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic"); if (force_magic != NULL && ConfValIsTrue(force_magic)) { FileForceMagicEnable(); SCLogInfo("forcing magic lookup for stored files"); } const char *write_meta = ConfNodeLookupChildValue(conf, "write-meta"); if (write_meta != NULL && !ConfValIsTrue(write_meta)) { FileWriteMetaDisable(); SCLogInfo("File-store output will not write meta files"); } FileForceHashParseCfg(conf); SCLogInfo("storing files in %s", g_logfile_base_dir); const char *stream_depth_str = ConfNodeLookupChildValue(conf, "stream-depth"); if (stream_depth_str != NULL && strcmp(stream_depth_str, "no")) { uint32_t stream_depth = 0; if (ParseSizeStringU32(stream_depth_str, &stream_depth) < 0) { SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " "file-store.stream-depth " "from conf file - %s. Killing engine", stream_depth_str); exit(EXIT_FAILURE); } else { FileReassemblyDepthEnable(stream_depth); } } const char *file_count_str = ConfNodeLookupChildValue(conf, "max-open-files"); if (file_count_str != NULL) { uint32_t file_count = 0; if (ParseSizeStringU32(file_count_str, &file_count) < 0) { SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " "file-store.max-open-files " "from conf file - %s. Killing engine", stream_depth_str); exit(EXIT_FAILURE); } else { if (file_count != 0) { FileSetMaxOpenFiles(file_count); SCLogInfo("file-store will keep a max of %d simultaneously" " open files", file_count); } } } const char *include_pid = ConfNodeLookupChildValue(conf, "include-pid"); if (include_pid != NULL && ConfValIsTrue(include_pid)) { FileIncludePidEnable(); SCLogInfo("enabling pid as a part of all file names"); } StatsRegisterGlobalCounter("file_store.open_files", LogFilestoreOpenFilesCounter); result.ctx = output_ctx; result.ok = true; SCReturnCT(result, "OutputInitResult"); }