コード例 #1
0
ファイル: PathUtil.cpp プロジェクト: Kalmalyzer/tundra
static void PathConcatImpl(PathBuffer* buffer, const T* other)
{
  CHECK(!PathIsAbsolute(other));

  int seg_count = buffer->m_SegCount;

  int min_seg_count = (buffer->m_Flags & PathBuffer::kFlagWindowsDevicePath) ? 1 : 0;

  // Start by throwing away .. from the other path
  for (int i = 0, count = other->m_LeadingDotDots; i < count; ++i)
  {
    if (seg_count > min_seg_count)
    {
      seg_count--;
    }
    else if (seg_count == 0)
    {
      buffer->m_LeadingDotDots++;
    }
  }

  // Can't go higher than root directory. Just clamp to there.
  if (PathIsAbsolute(buffer))
  {
    buffer->m_LeadingDotDots = 0;
  }

  // Compute how much of our data buffer we need to keep
  int keep_buffer = BufferSize(buffer, seg_count);
  // Compute size of the other buffer.
  int other_buffer = BufferSize(other, other->m_SegCount);

  CHECK(seg_count + other->m_SegCount <= kMaxPathSegments);
  CHECK(keep_buffer + other_buffer <= kMaxPathLength);

  memcpy(buffer->m_Data + keep_buffer, other->m_Data, other_buffer);
  for (int i = 0, count = other->m_SegCount; i < count; ++i)
  {
    buffer->m_SegEnds[seg_count + i] = uint16_t(other->m_SegEnds[i] + keep_buffer);
  }
  
  buffer->m_SegCount = uint16_t(seg_count + other->m_SegCount);
}
コード例 #2
0
ファイル: PathUtil.cpp プロジェクト: Kalmalyzer/tundra
void PathConcat(PathBuffer* buffer, const PathBuffer* other)
{
  if (PathIsAbsolute(other))
  {
    *buffer = *other;
  }
  else
  {
    PathConcatImpl(buffer, other);
  }
}
コード例 #3
0
ファイル: log-filestore.c プロジェクト: Zopieux/suricata
/** \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 OutputCtx *LogFilestoreLogInitCtx(ConfNode *conf)
{
    LogFileCtx *logfile_ctx = LogFileNewCtx();
    if (logfile_ctx == NULL) {
        SCLogDebug("Could not create new LogFilestoreCtx");
        return NULL;
    }

    OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
    if (unlikely(output_ctx == NULL))
        return NULL;

    output_ctx->data = NULL;
    output_ctx->DeInit = LogFilestoreLogDeInitCtx;

    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_magic = ConfNodeLookupChildValue(conf, "force-magic");
    if (force_magic != NULL && ConfValIsTrue(force_magic)) {
        FileForceMagicEnable();
        SCLogInfo("forcing magic lookup for stored files");
    }

    const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5");
    if (force_md5 != NULL && ConfValIsTrue(force_md5)) {
#ifdef HAVE_NSS
        FileForceMd5Enable();
        SCLogInfo("forcing md5 calculation for stored files");
#else
        SCLogInfo("md5 calculation requires linking against libnss");
#endif
    }
    SCLogInfo("storing files in %s", g_logfile_base_dir);

    SCReturnPtr(output_ctx, "OutputCtx");
}
コード例 #4
0
static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
{
	if (PathIsAbsolute(pSrc) || !isalnum(pSrc[0]))
		mir_tstrncpy(pOut, pSrc, (int)outSize);
	else {
		if (dbPath[0] == _T('\0')) {
			char tmp[1024];
			CallService(MS_DB_GETPROFILEPATH, _countof(tmp), (LPARAM)tmp);
			mir_sntprintf(dbPath, _T("%S\\"), tmp);
		}

		mir_sntprintf(pOut, outSize, _T("%s%s"), dbPath, pSrc);
	}
}
コード例 #5
0
static void PathToRelative(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
{
	if (!PathIsAbsolute(pSrc))
		mir_tstrncpy(pOut, pSrc, (int)outSize);
	else {
		if (dbPath[0] == _T('\0')) {
			char tmp[1024];
			CallService(MS_DB_GETPROFILEPATH, _countof(tmp), (LPARAM)tmp);
			mir_sntprintf(dbPath, _T("%S\\"), tmp);
		}

		size_t len = mir_tstrlen(dbPath);
		if (!_tcsnicmp(pSrc, dbPath, len))
			len = 0;
		mir_tstrncpy(pOut, pSrc + len, outSize);
	}
}
コード例 #6
0
ファイル: path.cpp プロジェクト: kxepal/miranda-ng
MIR_CORE_DLL(int) PathToRelative(const char *pSrc, char *pOut, const char *pBase)
{
	if (!pSrc || !pSrc[0] || strlen(pSrc) > MAX_PATH)
		return 0;

	if (!PathIsAbsolute(pSrc))
		strncpy_s(pOut, MAX_PATH, pSrc, _TRUNCATE);
	else {
		if (pBase == NULL)
			pBase = szMirandaPath;

		size_t cbBaseLen = strlen(pBase);
		if (!strnicmp(pSrc, pBase, cbBaseLen))
			strncpy_s(pOut, MAX_PATH, pSrc + cbBaseLen, _TRUNCATE);
		else
			strncpy_s(pOut, MAX_PATH, pSrc, _TRUNCATE);
	}

	return (int)strlen(pOut);
}
コード例 #7
0
ファイル: path.cpp プロジェクト: kxepal/miranda-ng
MIR_CORE_DLL(int) PathToAbsolute(const char *pSrc, char *pOut, const char *base)
{
	if (!pSrc || !pSrc[0] || strlen(pSrc) > MAX_PATH) {
		*pOut = 0;
		return 0;
	}

	char buf[MAX_PATH];
	if (pSrc[0] < ' ')
		strncpy_s(pOut, MAX_PATH, pSrc, _TRUNCATE);

	if (PathIsAbsolute(pSrc))
		return GetFullPathNameA(pSrc, MAX_PATH, pOut, NULL);

	if (base == NULL)
		base = szMirandaPath;

	if (pSrc[0] == '\\')
		pSrc++;
	mir_snprintf(buf, "%s%s", base, pSrc);
	return GetFullPathNameA(buf, _countof(buf), pOut, NULL);
}
コード例 #8
0
/** \brief open a generic output "log file", which may be a regular file or a socket
 *  \param conf ConfNode structure for the output section in question
 *  \param log_ctx Log file context allocated by caller
 *  \param default_filename Default name of file to open, if not specified in ConfNode
 *  \param rotate Register the file for rotation in HUP.
 *  \retval 0 on success
 *  \retval -1 on error
 */
int
SCConfLogOpenGeneric(ConfNode *conf,
                     LogFileCtx *log_ctx,
                     const char *default_filename,
                     int rotate)
{
    char log_path[PATH_MAX];
    char *log_dir;
    const char *filename, *filetype;

    // Arg check
    if (conf == NULL || log_ctx == NULL || default_filename == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric(conf %p, ctx %p, default %p) "
                   "missing an argument",
                   conf, log_ctx, default_filename);
        return -1;
    }
    if (log_ctx->fp != NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric: previously initialized Log CTX "
                   "encountered");
        return -1;
    }

    // Resolve the given config
    filename = ConfNodeLookupChildValue(conf, "filename");
    if (filename == NULL)
        filename = default_filename;

    log_dir = ConfigGetLogDirectory();

    if (PathIsAbsolute(filename)) {
        snprintf(log_path, PATH_MAX, "%s", filename);
    } else {
        snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
    }

    filetype = ConfNodeLookupChildValue(conf, "filetype");
    if (filetype == NULL)
        filetype = DEFAULT_LOG_FILETYPE;

    const char *append = ConfNodeLookupChildValue(conf, "append");
    if (append == NULL)
        append = DEFAULT_LOG_MODE_APPEND;

    // Now, what have we been asked to open?
    if (strcasecmp(filetype, "unix_stream") == 0) {
        /* Don't bail. May be able to connect later. */
        log_ctx->is_sock = 1;
        log_ctx->sock_type = SOCK_STREAM;
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_STREAM, 1);
    } else if (strcasecmp(filetype, "unix_dgram") == 0) {
        /* Don't bail. May be able to connect later. */
        log_ctx->is_sock = 1;
        log_ctx->sock_type = SOCK_DGRAM;
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_DGRAM, 1);
    } else if (strcasecmp(filetype, DEFAULT_LOG_FILETYPE) == 0 ||
               strcasecmp(filetype, "file") == 0) {
        log_ctx->fp = SCLogOpenFileFp(log_path, append);
        if (log_ctx->fp == NULL)
            return -1; // Error already logged by Open...Fp routine
        log_ctx->is_regular = 1;
        if (rotate) {
            OutputRegisterFileRotationFlag(&log_ctx->rotation_flag);
        }
    } else if (strcasecmp(filetype, "pcie") == 0) {
        log_ctx->pcie_fp = SCLogOpenPcieFp(log_ctx, log_path, append);
        if (log_ctx->pcie_fp == NULL)
            return -1; // Error already logged by Open...Fp routine
#ifdef HAVE_LIBHIREDIS
    } else if (strcasecmp(filetype, "redis") == 0) {
        ConfNode *redis_node = ConfNodeLookupChild(conf, "redis");
        if (SCConfLogOpenRedis(redis_node, log_ctx) < 0) {
            SCLogError(SC_ERR_REDIS, "failed to open redis output");
            return -1;
        }
        log_ctx->type = LOGFILE_TYPE_REDIS;
#endif
    } else {
        SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for "
                   "%s.filetype.  Expected \"regular\" (default), \"unix_stream\", "
                   "\"pcie\" "
                   "or \"unix_dgram\"",
                   conf->name);
    }
    log_ctx->filename = SCStrdup(log_path);
    if (unlikely(log_ctx->filename == NULL)) {
        SCLogError(SC_ERR_MEM_ALLOC,
            "Failed to allocate memory for filename");
        return -1;
    }

    SCLogInfo("%s output device (%s) initialized: %s", conf->name, filetype,
              filename);

    return 0;
}
コード例 #9
0
/** \brief open a generic output "log file", which may be a regular file or a socket
 *  \param conf ConfNode structure for the output section in question
 *  \param log_ctx Log file context allocated by caller
 *  \param default_filename Default name of file to open, if not specified in ConfNode
 *  \retval 0 on success
 *  \retval -1 on error
 */
int
SCConfLogOpenGeneric(ConfNode *conf,
                     LogFileCtx *log_ctx,
                     const char *default_filename)
{
    char log_path[PATH_MAX];
    char *log_dir;
    const char *filename, *filetype;

    // Arg check
    if (conf == NULL || log_ctx == NULL || default_filename == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric(conf %p, ctx %p, default %p) "
                   "missing an argument",
                   conf, log_ctx, default_filename);
        return -1;
    }
    if (log_ctx->fp != NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric: previously initialized Log CTX "
                   "encountered");
        return -1;
    }

    // Resolve the given config
    filename = ConfNodeLookupChildValue(conf, "filename");
    if (filename == NULL)
        filename = default_filename;

    if (ConfGet("default-log-dir", &log_dir) != 1)
        log_dir = DEFAULT_LOG_DIR;

    if (PathIsAbsolute(filename)) {
        snprintf(log_path, PATH_MAX, "%s", filename);
    } else {
        snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
    }

    filetype = ConfNodeLookupChildValue(conf, "filetype");
    if (filetype == NULL)
        filetype = DEFAULT_LOG_FILETYPE;

#ifdef __tile__
    log_ctx->filetype = regular;
#endif
    // Now, what have we been asked to open?
    if (strcasecmp(filetype, "unix_stream") == 0) {
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_STREAM);
#ifdef __tile__
        log_ctx->filetype = unix_stream;
#endif
    } else if (strcasecmp(filetype, "unix_dgram") == 0) {
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_DGRAM);
#ifdef __tile__
        log_ctx->filetype = unix_dgram;
#endif
    } else if (strcasecmp(filetype, DEFAULT_LOG_FILETYPE) == 0) {
        const char *append;

        append = ConfNodeLookupChildValue(conf, "append");
        if (append == NULL)
            append = DEFAULT_LOG_MODE_APPEND;
        log_ctx->fp = SCLogOpenFileFp(log_path, append);
#ifdef __tile__
    } else if (strcasecmp(filetype, "tile_pcie") == 0) {
        const char *append;

        append = ConfNodeLookupChildValue(conf, "append");
        if (append == NULL)
            append = DEFAULT_LOG_MODE_APPEND;
        log_ctx->pcie_ctx = SCLogOpenPcieFileFp(log_path, append);
        log_ctx->filetype = tile_pcie;
#endif
    } else {
        SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for "
                   "%s.type.  Expected \"regular\" (default), \"unix_stream\" "
                   "or \"unix_dgram\"",
                   conf->name);
    }

#ifdef __tile__
    if (log_ctx->filetype == tile_pcie) {
        if (log_ctx->pcie_ctx == NULL)
            return -1; // Error already logged by Open...Fp routine
    } else {
        if (log_ctx->fp == NULL)
            return -1; // Error already logged by Open...Fp routine
    }
#else
    if (log_ctx->fp == NULL)
        return -1; // Error already logged by Open...Fp routine
#endif

    SCLogInfo("%s output device (%s) initialized: %s", conf->name, filetype,
              filename);

    return 0;
}
コード例 #10
0
ファイル: log-filestore.c プロジェクト: glongo/suricata
/** \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");
}
コード例 #11
0
int PopulatePickerFromFile( PlaylistPicker* picker, char* fname, const char* basePath, LoopDetectionList *ldList )
{
    Assert( picker );
    Assert( fname );
    
    FILE*                       weightings = NULL;
    LoopDetectionListElement*   ldElement = NULL;
    LoopDetectionNode*          ldNode = NULL;
    int                         lineCount = 0;
    int                         pickErr = kPickerPopulateNoErr; 
    char                        path[kMaxPickerPath];
    
    
        
#if kPartialPathBeginsWithDelimiter
    if (PathIsAbsolute(fname))
    {
        if ( *basePath )
            fname++;
#else
    if ( !PathIsAbsolute(fname) )
    {
#endif
        // it's a partial path, expand it to include all
        // previously traversed paths
        ::strncpy( path, basePath, kMaxPickerPath-1 );
        ::strncat( path, fname, kMaxPickerPath-1 );
            
    }
    else
    {
        // it's an absolute reference. use the path
        // part of this for the new basePath
        ::strncpy( path, fname, kMaxPickerPath-1 );
        
    }
    
    // path is now either an absolute or working directory
    // referenced partial path to the playlist file.
    int len = strlen(path);
    char lastChar = path[len-1];
    if (lastChar == '\n' || lastChar == '\r' || lastChar == ' ')
        path[len-1] = '\0';

    // ldList is passed as NULL by the initial caller.  recursive calls
    // pass along the ldList we create hre
    if ( ldList == NULL )
        ldList = new LoopDetectionList;

    Assert( ldList );
    
    if ( !ldList )
        pickErr = kPickerPopulateNoMem;
    
    
    if ( !pickErr )
    {
        if ( ldList->ForEachUntil( CompareNameToElement, path ) )
        {
            // we're already in the include chain, this is a loop
            // print a warning (error?) and continue past the loop.
            //qtss_printf("- Playlists include loop at file: %s\n", path );
            pickErr = kPickerPopulateLoopDetected;
        }
    }
    
    
    
    if ( !pickErr )
    {
        ldElement = new LoopDetectionListElement( path );
        
        Assert( ldElement );
        
        if ( ldElement )
        {   ldNode = new LoopDetectionNode( ldElement );
            Assert( ldNode );
            if ( !ldNode )
                pickErr = kPickerPopulateNoMem;
        }
        else
            pickErr = kPickerPopulateNoMem;
    }
    
    if (::IsDir(path))
        return ::PopulatePickerFromDir(picker, path);
    
    if ( !pickErr )
    {
        weightings = ::fopen( path, "r" );

        if (!weightings) 
        {
            qtss_printf("- Playlist picker failed opening list file %s\n", path);
            pickErr = kPickerPopulateFileError;
        }
    }
    
    if ( !pickErr )
    {
        long    lineBuffSize = (kMaxPickerPath *2) - 1;
        long    wordBuffSize = kMaxPickerPath - 1;
        
        char    lineBuff[kMaxPickerPath * 2];
        char    wordBuff[kMaxPickerPath];
        char*   next;
        char*   pathEnd;
        char*   thisLine;
        
        // add ourselves to the list
        ldList->AddNode( ldNode );
        
        // trim off the file name to get just the path part
        pathEnd = ::strrchr( path, kPathDelimiterChar );
        
        if ( pathEnd )
        {   
            pathEnd++;
            *pathEnd = 0;
        }
        else
            *path = 0;
        
        thisLine = lineBuff;
        
        if ( ::fgets( lineBuff, lineBuffSize, weightings ) != NULL )
        {
            lineCount++;
            
            thisLine = ::TrimLeft( lineBuff );
            
            if ( 0 != ::strncmp(thisLine,"*PLAY-LIST*",11) )
            {   
                //qtss_printf("- Playlist file missing *PLAY-LIST* identifier as first line:\n");
                //qtss_printf("  %s%s\n", basePath, fname);
                pickErr = kPickerPopulateBadFormat;
            }
        }
        
            
        if ( !pickErr )
        {
            do 
            {   
                next = lineBuff;
                
                if ( ::fgets( lineBuff, lineBuffSize, weightings ) == NULL )
                    break;
                
//                qtss_printf("line = %s\n", lineBuff);
                lineCount++;
                
                next = ::TrimLeft( lineBuff );
                
                if ( *next == '#' )
                {
                    // it's a comment - just toss
                    
                    //if ( *next )
                    //  qtss_printf( "comment: %s" , &lineBuff[1] );
                    
                }
                else if (*next == '+') // a list
                {
                    next = ::TrimLeft( next+1 );    // skip past + include
                    
                    if ( *next == '"' ) // get the name from the next part of the buff
                        next = ::GetQuotedWord( wordBuff, next, wordBuffSize );
                    else
                        next = ::GetWord( wordBuff, next, wordBuffSize );
                        
                    
                    
                    // recusively populate from the include file.
                    pickErr = PopulatePickerFromFile( picker, wordBuff, path, ldList );
                    
                    if ( pickErr )
                    {   
                        DisplayPickerErr( pickErr, "Playlist Include failed",  fname, lineCount, lineBuff );
                        pickErr = kPickerPopulateNoErr;
                    }
                }
                else if ( *next )
                {
                    char    numBuff[32];
                    char    expandedFileName[kMaxPickerPath];
                    int     weight = 10;    // default weight is 10

                    // get the movie file name
                    if ( *next == '"' )
                        next = ::GetQuotedWord( wordBuff, next, wordBuffSize );
                    else
                        next = ::GetWord( wordBuff, next, wordBuffSize );
                
                    if (*wordBuff)
                    {
                        #if kPartialPathBeginsWithDelimiter
                        if ( PathIsAbsolute(wordBuff) )
                        {
                            char *wordStart = wordBuff;
                            if ( *path )
                                wordStart++;
                            // full or partial path to the movie
                            ::strcpy( expandedFileName, path );
                            ::strcat( expandedFileName, wordStart );
                        }
                        #else
                        if ( !PathIsAbsolute(wordBuff) )
                        {
                            // it's a partial path..
                            
                            // cat the path and fname to form the 
                            // full or partial path to the movie
                            ::strcpy( expandedFileName, path );
                            ::strcat( expandedFileName, wordBuff );
                        }
                        #endif
                        else
                        {   // it's an absolute path..
                            ::strcpy( expandedFileName, wordBuff );
                        }
                        
                        // then get the weighting ( if supplied )
                        next = ::GetWord( numBuff, next, 32 );

                        if ( *numBuff )
                            weight = ::atoi(numBuff);

 //                       qtss_printf("expanded file name = %s\n", expandedFileName);
                        if (::IsDir(expandedFileName))
                            pickErr = ::PopulatePickerFromDir(picker, expandedFileName, weight);
                        else if ( !picker->AddToList( expandedFileName, weight ) )
                            pickErr = kPickerPopulateNoMem;
                    }
                }
                
            } while ( feof( weightings ) == 0 && pickErr == kPickerPopulateNoErr );
        }
        
        // remove ourselves from the list
        ldList->RemoveNode( ldNode );
    }
    
    // only report unreported errors.
    if ( ldList && ldList->GetNumNodes() == 0 && pickErr )
        ::DisplayPickerErr( pickErr, "Playlist error", fname, lineCount, NULL );
        
    
    if ( ldNode )
        delete ldNode; // node deletes element
    else if ( ldElement )
        delete ldElement;
    

    if ( weightings )
        (void)::fclose( weightings );

    if ( ldList && ldList->GetNumNodes() == 0 )
    {
        // all done now!
        delete ldList;
        ldList = NULL;
    
    }
    
    return pickErr;
}

int PopulatePickerFromDir( PlaylistPicker* picker, char* dirPath, int weight )
{
    static char expandedFileName[kMaxPickerPath];   // static so we don't build up the stack frame on recursion
    int pickErr = 0;
    if (dirPath != NULL)
        strcpy(expandedFileName, dirPath);
    
#ifdef __Win32__
    WIN32_FIND_DATA findData;
    HANDLE findResultHandle;
    Bool16 keepSearching = true;
    int len = strlen(expandedFileName);
    if (expandedFileName[len - 1] != kPathDelimiterChar)
    {
        expandedFileName[len] = kPathDelimiterChar;
        expandedFileName[len+1] = 0;
        len++;
    }
    strcat(expandedFileName, "*");
    
    findResultHandle = ::FindFirstFile( expandedFileName, &findData);
    if ( NULL == findResultHandle || INVALID_HANDLE_VALUE == findResultHandle )
    {
        //qtss_printf( "FindFirstFile( \"%s\" ): gle = %lu\n", searchPath, GetLastError() );
        return 0;
    }

    while ( (pickErr == 0) && keepSearching )
    {
        expandedFileName[len] = 0;  // retruncate name
        if (findData.cFileName[0] != '.')       // ignore anything beginning with a "."
        {
            strcat(expandedFileName, findData.cFileName);
            if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 
                pickErr = PopulatePickerFromDir(picker, NULL, weight);
            else if ( !picker->AddToList( expandedFileName, weight ) )
                pickErr = kPickerPopulateNoMem;
        }

        keepSearching = FindNextFile( findResultHandle, &findData );
    }
        
#else
    DIR* dir;
    struct dirent* entry;
    int len = strlen(expandedFileName);
    
    if (expandedFileName[len - 1] != kPathDelimiterChar)
    {
        expandedFileName[len] = kPathDelimiterChar;
        expandedFileName[len+1] = 0;
        len++;
    }

    dir = opendir(expandedFileName);
    if (dir == NULL)
        return kPickerPopulateFileError;
        
    do {
        entry = readdir(dir);
        if (entry == NULL) break;
        
        if (entry->d_name[0] == '.')        // ignore anything beginning with a "."
            continue;

        if (len + strlen(entry->d_name) < kMaxPickerPath)
        {
            strcat(expandedFileName, entry->d_name);
            
#if __solaris__ || __sgi__ || __osf__ || __hpux__
			if (::IsDir(expandedFileName))
#else
            if ((entry->d_type & DT_DIR) != 0)
#endif
                pickErr = PopulatePickerFromDir(picker, NULL, weight);
            else if ( !picker->AddToList( expandedFileName, weight ) )
                pickErr = kPickerPopulateNoMem;
        }
        expandedFileName[len] = 0;  // retruncate name
    } while (pickErr == 0);
    
    //close the directory back up
    (void)::closedir(dir);
    
#endif  
    return pickErr;
}
コード例 #12
0
ファイル: util-logopenfile.c プロジェクト: norg/suricata
/** \brief open a generic output "log file", which may be a regular file or a socket
 *  \param conf ConfNode structure for the output section in question
 *  \param log_ctx Log file context allocated by caller
 *  \param default_filename Default name of file to open, if not specified in ConfNode
 *  \param rotate Register the file for rotation in HUP.
 *  \retval 0 on success
 *  \retval -1 on error
 */
int
SCConfLogOpenGeneric(ConfNode *conf,
                     LogFileCtx *log_ctx,
                     const char *default_filename,
                     int rotate)
{
    char log_path[PATH_MAX];
    const char *log_dir;
    const char *filename, *filetype;

    // Arg check
    if (conf == NULL || log_ctx == NULL || default_filename == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric(conf %p, ctx %p, default %p) "
                   "missing an argument",
                   conf, log_ctx, default_filename);
        return -1;
    }
    if (log_ctx->fp != NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "SCConfLogOpenGeneric: previously initialized Log CTX "
                   "encountered");
        return -1;
    }

    // Resolve the given config
    filename = ConfNodeLookupChildValue(conf, "filename");
    if (filename == NULL)
        filename = default_filename;

    log_dir = ConfigGetLogDirectory();

    if (PathIsAbsolute(filename)) {
        snprintf(log_path, PATH_MAX, "%s", filename);
    } else {
        snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
    }

    /* Rotate log file based on time */
    const char *rotate_int = ConfNodeLookupChildValue(conf, "rotate-interval");
    if (rotate_int != NULL) {
        time_t now = time(NULL);
        log_ctx->flags |= LOGFILE_ROTATE_INTERVAL;

        /* Use a specific time */
        if (strcmp(rotate_int, "minute") == 0) {
            log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
            log_ctx->rotate_interval = 60;
        } else if (strcmp(rotate_int, "hour") == 0) {
            log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
            log_ctx->rotate_interval = 3600;
        } else if (strcmp(rotate_int, "day") == 0) {
            log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
            log_ctx->rotate_interval = 86400;
        }

        /* Use a timer */
        else {
            log_ctx->rotate_interval = SCParseTimeSizeString(rotate_int);
            if (log_ctx->rotate_interval == 0) {
                SCLogError(SC_ERR_INVALID_NUMERIC_VALUE,
                           "invalid rotate-interval value");
                exit(EXIT_FAILURE);
            }
            log_ctx->rotate_time = now + log_ctx->rotate_interval;
        }
    }

    filetype = ConfNodeLookupChildValue(conf, "filetype");
    if (filetype == NULL)
        filetype = DEFAULT_LOG_FILETYPE;

    const char *filemode = ConfNodeLookupChildValue(conf, "filemode");
    uint32_t mode = 0;
    if (filemode != NULL &&
            ByteExtractStringUint32(&mode, 8, strlen(filemode),
                                    filemode) > 0) {
        log_ctx->filemode = mode;
    }

    const char *append = ConfNodeLookupChildValue(conf, "append");
    if (append == NULL)
        append = DEFAULT_LOG_MODE_APPEND;

    /* JSON flags */
#ifdef HAVE_LIBJANSSON
    log_ctx->json_flags = JSON_PRESERVE_ORDER|JSON_COMPACT|
                          JSON_ENSURE_ASCII|JSON_ESCAPE_SLASH;

    ConfNode *json_flags = ConfNodeLookupChild(conf, "json");

    if (json_flags != 0) {
        const char *preserve_order = ConfNodeLookupChildValue(json_flags,
                                                              "preserve-order");
        if (preserve_order != NULL && ConfValIsFalse(preserve_order))
            log_ctx->json_flags &= ~(JSON_PRESERVE_ORDER);

        const char *compact = ConfNodeLookupChildValue(json_flags, "compact");
        if (compact != NULL && ConfValIsFalse(compact))
            log_ctx->json_flags &= ~(JSON_COMPACT);

        const char *ensure_ascii = ConfNodeLookupChildValue(json_flags,
                                                            "ensure-ascii");
        if (ensure_ascii != NULL && ConfValIsFalse(ensure_ascii))
            log_ctx->json_flags &= ~(JSON_ENSURE_ASCII);

        const char *escape_slash = ConfNodeLookupChildValue(json_flags,
                                                            "escape-slash");
        if (escape_slash != NULL && ConfValIsFalse(escape_slash))
            log_ctx->json_flags &= ~(JSON_ESCAPE_SLASH);
    }
#endif /* HAVE_LIBJANSSON */

    // Now, what have we been asked to open?
    if (strcasecmp(filetype, "unix_stream") == 0) {
#ifdef BUILD_WITH_UNIXSOCKET
        /* Don't bail. May be able to connect later. */
        log_ctx->is_sock = 1;
        log_ctx->sock_type = SOCK_STREAM;
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_STREAM, 1);
#else
        return -1;
#endif
    } else if (strcasecmp(filetype, "unix_dgram") == 0) {
#ifdef BUILD_WITH_UNIXSOCKET
        /* Don't bail. May be able to connect later. */
        log_ctx->is_sock = 1;
        log_ctx->sock_type = SOCK_DGRAM;
        log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_DGRAM, 1);
#else
        return -1;
#endif
    } else if (strcasecmp(filetype, DEFAULT_LOG_FILETYPE) == 0 ||
               strcasecmp(filetype, "file") == 0) {
        log_ctx->fp = SCLogOpenFileFp(log_path, append, log_ctx->filemode);
        if (log_ctx->fp == NULL)
            return -1; // Error already logged by Open...Fp routine
        log_ctx->is_regular = 1;
        if (rotate) {
            OutputRegisterFileRotationFlag(&log_ctx->rotation_flag);
        }
    } else if (strcasecmp(filetype, "pcie") == 0) {
        log_ctx->pcie_fp = SCLogOpenPcieFp(log_ctx, log_path, append);
        if (log_ctx->pcie_fp == NULL)
            return -1; // Error already logged by Open...Fp routine
#ifdef HAVE_LIBHIREDIS
    } else if (strcasecmp(filetype, "redis") == 0) {
        ConfNode *redis_node = ConfNodeLookupChild(conf, "redis");
        if (SCConfLogOpenRedis(redis_node, log_ctx) < 0) {
            SCLogError(SC_ERR_REDIS, "failed to open redis output");
            return -1;
        }
        log_ctx->type = LOGFILE_TYPE_REDIS;
#endif
    } else {
        SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for "
                   "%s.filetype.  Expected \"regular\" (default), \"unix_stream\", "
                   "\"pcie\" "
                   "or \"unix_dgram\"",
                   conf->name);
    }
    log_ctx->filename = SCStrdup(log_path);
    if (unlikely(log_ctx->filename == NULL)) {
        SCLogError(SC_ERR_MEM_ALLOC,
            "Failed to allocate memory for filename");
        return -1;
    }

#ifdef BUILD_WITH_UNIXSOCKET
    /* If a socket and running live, do non-blocking writes. */
    if (log_ctx->is_sock && run_mode_offline == 0) {
        SCLogInfo("Setting logging socket of non-blocking in live mode.");
        log_ctx->send_flags |= MSG_DONTWAIT;
    }
#endif
    SCLogInfo("%s output device (%s) initialized: %s", conf->name, filetype,
              filename);

    return 0;
}