./PaxHeaders/rsyslog-8.2512.00000644000000000000000000000013215114544377012624 xustar0030 mtime=1764935935.203760587 30 atime=1764935935.208760664 30 ctime=1764935935.203760587 rsyslog-8.2512.0/0000775000175000017500000000000015114544377012210 5ustar00rgerrgerrsyslog-8.2512.0/PaxHeaders/README0000644000000000000000000000013215053526213013413 xustar0030 mtime=1756277899.484426395 30 atime=1764931121.553004492 30 ctime=1764935920.415534202 rsyslog-8.2512.0/README0000664000175000017500000000007715053526213013063 0ustar00rgerrgersee README.md -- this file here is just required for autotools rsyslog-8.2512.0/PaxHeaders/outchannel.c0000644000000000000000000000013215055605325015043 xustar0030 mtime=1756826325.634800457 30 atime=1764931000.998028136 30 ctime=1764935923.309578509 rsyslog-8.2512.0/outchannel.c0000664000175000017500000001642315055605325014515 0ustar00rgerrger/* This is the output channel processing code of rsyslog. * Output channels - in the long term - will define how * messages will be sent to whatever file or other medium. * Currently, they mainly provide a way to store some file-related * information (most importantly the maximum file size allowed). * Please see syslogd.c for license information. * begun 2005-06-21 rgerhards * * Copyright (C) 2005-2016 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include "stringbuf.h" #include "outchannel.h" #include "rsconf.h" #include "debug.h" /* Constructs a outchannel list object. Returns pointer to it * or NULL (if it fails). */ struct outchannel *ochConstruct(void) { struct outchannel *pOch; if ((pOch = calloc(1, sizeof(struct outchannel))) == NULL) return NULL; /* basic initialisaion is done via calloc() - need to * initialize only values != 0. */ if (loadConf->och.ochLast == NULL) { /* we are the first element! */ loadConf->och.ochRoot = loadConf->och.ochLast = pOch; } else { loadConf->och.ochLast->pNext = pOch; loadConf->och.ochLast = pOch; } return (pOch); } /* skips the next comma and any whitespace * in front and after it. */ static void skip_Comma(uchar **pp) { register uchar *p; assert(pp != NULL); assert(*pp != NULL); p = *pp; while (isspace(*p)) ++p; if (*p == ',') ++p; while (isspace(*p)) ++p; *pp = p; } /* helper to ochAddLine. Parses a comma-delimited field * The field is delimited by SP or comma. Leading whitespace * is "eaten" and does not become part of the field content. */ static rsRetVal get_Field(uchar **pp, uchar **pField) { DEFiRet; register uchar *p; cstr_t *pStrB = NULL; assert(pp != NULL); assert(*pp != NULL); assert(pField != NULL); skip_Comma(pp); p = *pp; CHKiRet(cstrConstruct(&pStrB)); /* copy the field */ while (*p && *p != ' ' && *p != ',') { CHKiRet(cstrAppendChar(pStrB, *p++)); } *pp = p; cstrFinalize(pStrB); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, pField, 0)); finalize_it: if (iRet != RS_RET_OK) { if (pStrB != NULL) cstrDestruct(&pStrB); } RETiRet; } /* helper to ochAddLine. Parses a off_t type from the * input line. * returns: 0 - ok, 1 - failure */ static int get_off_t(uchar **pp, off_t *pOff_t) { register uchar *p; off_t val; assert(pp != NULL); assert(*pp != NULL); assert(pOff_t != NULL); skip_Comma(pp); p = *pp; val = 0; while (*p && isdigit((int)*p)) { val = val * 10 + (*p - '0'); ++p; } *pp = p; *pOff_t = val; return 0; } /* helper to ochAddLine. Parses everything from the * current position to the end of line and returns it * to the caller. Leading white space is removed, but * not trailing. */ static rsRetVal get_restOfLine(uchar **pp, uchar **pBuf) { DEFiRet; register uchar *p; cstr_t *pStrB = NULL; assert(pp != NULL); assert(*pp != NULL); assert(pBuf != NULL); skip_Comma(pp); p = *pp; CHKiRet(cstrConstruct(&pStrB)); /* copy the field */ while (*p) { CHKiRet(cstrAppendChar(pStrB, *p++)); } *pp = p; cstrFinalize(pStrB); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, pBuf, 0)); finalize_it: if (iRet != RS_RET_OK) { if (pStrB != NULL) cstrDestruct(&pStrB); } RETiRet; } /* Add a new outchannel line * returns pointer to new object if it succeeds, NULL otherwise. * An outchannel line is primarily a set of fields delemited by commas. * There might be some whitespace between the field (but not within) * and the commas. This can be removed. */ struct outchannel *ochAddLine(char *pName, uchar **ppRestOfConfLine) { struct outchannel *pOch; uchar *p; assert(pName != NULL); assert(ppRestOfConfLine != NULL); if ((pOch = ochConstruct()) == NULL) return NULL; pOch->iLenName = strlen(pName); pOch->pszName = (char *)malloc(pOch->iLenName + 1); if (pOch->pszName == NULL) { dbgprintf("ochAddLine could not alloc memory for outchannel name!"); pOch->iLenName = 0; return NULL; /* I know - we create a memory leak here - but I deem * it acceptable as it is a) a very small leak b) very * unlikely to happen. rgerhards 2004-11-17 */ } memcpy(pOch->pszName, pName, pOch->iLenName + 1); /* now actually parse the line */ p = *ppRestOfConfLine; assert(p != NULL); /* get params */ get_Field(&p, &pOch->pszFileTemplate); if (*p) get_off_t(&p, &pOch->uSizeLimit); if (*p) get_restOfLine(&p, &pOch->cmdOnSizeLimit); *ppRestOfConfLine = p; return (pOch); } /* Find a outchannel object based on name. Search * currently is case-sensitive (should we change?). * returns pointer to outchannel object if found and * NULL otherwise. * rgerhards 2004-11-17 */ struct outchannel *ochFind(char *pName, int iLenName) { struct outchannel *pOch; assert(pName != NULL); pOch = loadConf->och.ochRoot; while (pOch != NULL && !(pOch->iLenName == iLenName && !strcmp(pOch->pszName, pName))) { pOch = pOch->pNext; } return (pOch); } /* Destroy the outchannel structure. This is for de-initialization * at program end. Everything is deleted. * rgerhards 2005-02-22 */ void ochDeleteAll(void) { struct outchannel *pOch, *pOchDel; pOch = runConf->och.ochRoot; while (pOch != NULL) { dbgprintf("Delete Outchannel: Name='%s'\n ", pOch->pszName == NULL ? "NULL" : pOch->pszName); pOchDel = pOch; pOch = pOch->pNext; if (pOchDel->pszName != NULL) free(pOchDel->pszName); if (pOchDel->pszFileTemplate != NULL) free(pOchDel->pszFileTemplate); if (pOchDel->cmdOnSizeLimit != NULL) free(pOchDel->cmdOnSizeLimit); free(pOchDel); } } /* Print the outchannel structure. This is more or less a * debug or test aid, but anyhow I think it's worth it... */ void ochPrintList(rsconf_t *cnf) { struct outchannel *pOch; pOch = cnf->och.ochRoot; while (pOch != NULL) { dbgprintf("Outchannel: Name='%s'\n", pOch->pszName == NULL ? "NULL" : pOch->pszName); dbgprintf("\tFile Template: '%s'\n", pOch->pszFileTemplate == NULL ? "NULL" : (char *)pOch->pszFileTemplate); dbgprintf("\tMax Size.....: %lu\n", (long unsigned)pOch->uSizeLimit); dbgprintf("\tOnSizeLimtCmd: '%s'\n", pOch->cmdOnSizeLimit == NULL ? "NULL" : (char *)pOch->cmdOnSizeLimit); pOch = pOch->pNext; /* done, go next */ } } /* vi:set ai: */ rsyslog-8.2512.0/PaxHeaders/m40000644000000000000000000000013015114544360012775 xustar0029 mtime=1764935920.39053382 30 atime=1764935930.037681508 29 ctime=1764935920.39053382 rsyslog-8.2512.0/m4/0000775000175000017500000000000015114544360012520 5ustar00rgerrgerrsyslog-8.2512.0/m4/PaxHeaders/lt~obsolete.m40000644000000000000000000000013115114544312015664 xustar0030 mtime=1764935882.005945967 30 atime=1764935882.026946288 29 ctime=1764935920.39053382 rsyslog-8.2512.0/m4/lt~obsolete.m40000644000175000017500000001400715114544312015331 0ustar00rgerrger# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) rsyslog-8.2512.0/m4/PaxHeaders/ltsugar.m40000644000000000000000000000013215114544311014773 xustar0030 mtime=1764935881.948945093 30 atime=1764935881.965945354 30 ctime=1764935920.385533743 rsyslog-8.2512.0/m4/ltsugar.m40000644000175000017500000001045315114544311014440 0ustar00rgerrger# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) rsyslog-8.2512.0/m4/PaxHeaders/atomic_operations_64bit.m40000644000000000000000000000013215035412264020044 xustar0030 mtime=1752569012.356063431 30 atime=1764930914.421570855 30 ctime=1764935920.378533636 rsyslog-8.2512.0/m4/atomic_operations_64bit.m40000664000175000017500000000244315035412264017513 0ustar00rgerrger# rsyslog # # atomic_operations.m4 - autoconf macro to check if compiler supports atomic # operations # # rgerhards, 2008-09-18, added based on # http://svn.apache.org/repos/asf/apr/apr/trunk/configure.in # # AC_DEFUN([RS_ATOMIC_OPERATIONS_64BIT], [AC_CACHE_CHECK([whether the compiler provides atomic builtins for 64 bit data types], [ap_cv_atomic_builtins_64], [AC_TRY_RUN([ int main() { unsigned long long val = 1010, tmp, *mem = &val; if (__sync_fetch_and_add(&val, 1010) != 1010 || val != 2020) return 1; tmp = val; if (__sync_fetch_and_sub(mem, 1010) != tmp || val != 1010) return 1; if (__sync_sub_and_fetch(&val, 1010) != 0 || val != 0) return 1; tmp = 3030; if (__sync_val_compare_and_swap(mem, 0, tmp) != 0 || val != tmp) return 1; if (__sync_lock_test_and_set(&val, 4040) != 3030) return 1; mem = &tmp; if (__sync_val_compare_and_swap(&mem, &tmp, &val) != &tmp) return 1; __sync_synchronize(); if (mem != &val) return 1; return 0; }], [ap_cv_atomic_builtins_64=yes], [ap_cv_atomic_builtins_64=no], [ap_cv_atomic_builtins_64=no])]) if test "$ap_cv_atomic_builtins_64" = "yes"; then AC_DEFINE(HAVE_ATOMIC_BUILTINS64, 1, [Define if compiler provides 64 bit atomic builtins]) fi ]) rsyslog-8.2512.0/m4/PaxHeaders/ac_check_define.m40000644000000000000000000000013215035412264016347 xustar0030 mtime=1752569012.356063431 30 atime=1764930914.422570872 30 ctime=1764935920.374533575 rsyslog-8.2512.0/m4/ac_check_define.m40000664000175000017500000000215515035412264016016 0ustar00rgerrgerAC_DEFUN([AC_CHECK_DEFINED],[ AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl AC_CACHE_CHECK([for $1 defined], ac_var, AC_TRY_COMPILE(,[ #ifdef $1 int ok; #else choke me #endif ],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no))) AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl AS_VAR_POPDEF([ac_var])dnl ]) AC_DEFUN([AX_CHECK_DEFINED],[ AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2])dnl AC_CACHE_CHECK([for $2 defined], ac_var, AC_TRY_COMPILE($1,[ #ifdef $2 int ok; #else choke me #endif ],AS_VAR_SET(ac_var, yes),AS_VAR_SET(ac_var, no))) AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl AS_VAR_POPDEF([ac_var])dnl ]) AC_DEFUN([AX_CHECK_FUNC], [AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl AC_CACHE_CHECK([for $2], ac_var, dnl AC_LANG_FUNC_LINK_TRY [AC_LINK_IFELSE([AC_LANG_PROGRAM([$1 #undef $2 char $2 ();],[ char (*f) () = $2; return f != $2; ])], [AS_VAR_SET(ac_var, yes)], [AS_VAR_SET(ac_var, no)])]) AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl AS_VAR_POPDEF([ac_var])dnl ])# AC_CHECK_FUNC rsyslog-8.2512.0/m4/PaxHeaders/atomic_operations.m40000644000000000000000000000013215055602573017042 xustar0030 mtime=1756824955.995450968 30 atime=1764930914.422570872 30 ctime=1764935920.376533606 rsyslog-8.2512.0/m4/atomic_operations.m40000664000175000017500000000356615055602573016520 0ustar00rgerrger# rsyslog # # atomic_operations.m4 - autoconf macro to check if compiler supports atomic # operations # # rgerhards, 2008-09-18, added based on # http://svn.apache.org/repos/asf/apr/apr/trunk/configure.in # # AC_DEFUN([RS_ATOMIC_OPERATIONS], [AC_CACHE_CHECK([whether the compiler provides atomic builtins], [ap_cv_atomic_builtins], [AC_TRY_RUN([ #include int main() { unsigned long val = 1010, tmp, *mem = &val; time_t tval = 1010, ttmp, *tmem = &tval; if (__sync_fetch_and_add(&val, 1010) != 1010 || val != 2020) return 1; tmp = val; if (__sync_fetch_and_sub(mem, 1010) != tmp || val != 1010) return 1; if (__sync_sub_and_fetch(&val, 1010) != 0 || val != 0) return 1; tmp = 3030; if (__sync_val_compare_and_swap(mem, 0, tmp) != 0 || val != tmp) return 1; if (__sync_lock_test_and_set(&val, 4040) != 3030) return 1; mem = &tmp; if (__sync_val_compare_and_swap(&mem, &tmp, &val) != &tmp) return 1; if (__sync_fetch_and_add(&tval, 1010) != 1010 || tval != 2020) return 1; ttmp = tval; if (__sync_fetch_and_sub(tmem, 1010) != ttmp || tval != 1010) return 1; if (__sync_sub_and_fetch(&tval, 1010) != 0 || tval != 0) return 1; ttmp = 3030; if (__sync_val_compare_and_swap(tmem, 0, ttmp) != 0 || tval != ttmp) return 1; if (__sync_lock_test_and_set(&tval, 4040) != 3030) return 1; tmem = &ttmp; if (__sync_val_compare_and_swap(&tmem, &ttmp, &tval) != &ttmp) return 1; __sync_synchronize(); if (mem != &val) return 1; if (tmem != &tval) return 1; return 0; }], [ap_cv_atomic_builtins=yes], [ap_cv_atomic_builtins=no], [ap_cv_atomic_builtins=no])]) if test "$ap_cv_atomic_builtins" = "yes"; then AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1, [Define if compiler provides atomic builtins]) fi ]) rsyslog-8.2512.0/m4/PaxHeaders/libtool.m40000644000000000000000000000013215114544311014756 xustar0030 mtime=1764935881.897944312 30 atime=1764935881.909944496 30 ctime=1764935920.381533682 rsyslog-8.2512.0/m4/libtool.m40000644000175000017500000113165215114544311014431 0ustar00rgerrger# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 59 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS _LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. _LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -z "$STRIP"; then AC_MSG_RESULT([no]) else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_FILECMD # ---------------- # Check for a file(cmd) program that can be used to detect file type and magic m4_defun([_LT_DECL_FILECMD], [AC_CHECK_TOOL([FILECMD], [file], [:]) _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ])# _LD_DECL_FILECMD # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS rsyslog-8.2512.0/m4/PaxHeaders/ltversion.m40000644000000000000000000000013215114544311015337 xustar0030 mtime=1764935881.975945507 30 atime=1764935881.995945813 30 ctime=1764935920.388533789 rsyslog-8.2512.0/m4/ltversion.m40000644000175000017500000000131215114544311014776 0ustar00rgerrger# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, # Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4245 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.7]) m4_define([LT_PACKAGE_REVISION], [2.4.7]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.7' macro_revision='2.4.7' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) rsyslog-8.2512.0/m4/PaxHeaders/ltoptions.m40000644000000000000000000000013115114544311015344 xustar0029 mtime=1764935881.92194468 30 atime=1764935881.936944909 30 ctime=1764935920.383533713 rsyslog-8.2512.0/m4/ltoptions.m40000644000175000017500000003427515114544311015022 0ustar00rgerrger# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free # Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) rsyslog-8.2512.0/PaxHeaders/threads.c0000644000000000000000000000013215055605325014335 xustar0030 mtime=1756826325.658800819 30 atime=1764930999.147997353 30 ctime=1764935923.287578173 rsyslog-8.2512.0/threads.c0000664000175000017500000002237615055605325014013 0ustar00rgerrger/* threads.c * * This file implements threading support helpers (and maybe the thread object) * for rsyslog. * * File begun on 2007-12-14 by RGerhards * * Copyright 2007-2016 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_PRCTL_H #include #endif #include "rsyslog.h" #include "dirty.h" #include "linkedlist.h" #include "threads.h" #include "srUtils.h" #include "errmsg.h" #include "glbl.h" #include "unicode-helper.h" #include "rsconf.h" /* linked list of currently-known threads */ static linkedList_t llThrds; /* methods */ /* Construct a new thread object */ static rsRetVal thrdConstruct(thrdInfo_t **ppThis) { DEFiRet; thrdInfo_t *pThis; assert(ppThis != NULL); CHKmalloc(pThis = calloc(1, sizeof(thrdInfo_t))); pthread_mutex_init(&pThis->mutThrd, NULL); pthread_cond_init(&pThis->condThrdTerm, NULL); *ppThis = pThis; finalize_it: RETiRet; } /* Destructs a thread object. The object must not be linked to the * linked list of threads. Please note that the thread should have been * stopped before. If not, we try to do it. */ static rsRetVal thrdDestruct(thrdInfo_t *pThis) { DEFiRet; assert(pThis != NULL); pthread_mutex_lock(&pThis->mutThrd); if (pThis->bIsActive == 1) { pthread_mutex_unlock(&pThis->mutThrd); thrdTerminate(pThis); } else { pthread_mutex_unlock(&pThis->mutThrd); pthread_join(pThis->thrdID, NULL); } /* call cleanup function, if any */ if (pThis->pAfterRun != NULL) pThis->pAfterRun(pThis); pthread_mutex_destroy(&pThis->mutThrd); pthread_cond_destroy(&pThis->condThrdTerm); free(pThis->name); free(pThis); RETiRet; } /* terminate a thread via the non-cancel interface * This is a separate function as it involves a bit more of code. * rgerhads, 2009-10-15 */ static rsRetVal thrdTerminateNonCancel(thrdInfo_t *pThis) { struct timespec tTimeout; int ret; int was_active; DEFiRet; assert(pThis != NULL); DBGPRINTF("request term via SIGTTIN for input thread '%s' %p\n", pThis->name, (void *)pThis->thrdID); pThis->bShallStop = RSTRUE; d_pthread_mutex_lock(&pThis->mutThrd); timeoutComp(&tTimeout, runConf->globals.inputTimeoutShutdown); was_active = pThis->bIsActive; while (was_active) { if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslogd debug: info: trying to cooperatively stop " "input %s, timeout %d ms\n", pThis->name, runConf->globals.inputTimeoutShutdown); } DBGPRINTF("thread %s: initiating termination, timeout %d ms\n", pThis->name, runConf->globals.inputTimeoutShutdown); const int r = pthread_kill(pThis->thrdID, SIGTTIN); if (r != 0) { LogError(r, RS_RET_INTERNAL_ERROR, "error terminating thread %s " "this may cause shutdown issues", pThis->name); } ret = d_pthread_cond_timedwait(&pThis->condThrdTerm, &pThis->mutThrd, &tTimeout); if (ret == ETIMEDOUT) { DBGPRINTF( "input thread term: timeout expired waiting on thread %s " "termination - canceling\n", pThis->name); if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslogd debug: input thread term: " "timeout expired waiting on thread %s " "termination - canceling\n", pThis->name); } pthread_cancel(pThis->thrdID); break; } else if (ret != 0) { char errStr[1024]; int err = ret; rs_strerror_r(err, errStr, sizeof(errStr)); DBGPRINTF("input thread term: cond_wait returned with error %d: %s\n", err, errStr); } was_active = pThis->bIsActive; } d_pthread_mutex_unlock(&pThis->mutThrd); if (was_active) { DBGPRINTF("non-cancel input thread termination FAILED for thread %s %p\n", pThis->name, (void *)pThis->thrdID); } else { DBGPRINTF("non-cancel input thread termination succeeded for thread %s %p\n", pThis->name, (void *)pThis->thrdID); } RETiRet; } /* terminate a thread gracefully. */ rsRetVal thrdTerminate(thrdInfo_t *pThis) { DEFiRet; assert(pThis != NULL); if (pThis->bNeedsCancel) { DBGPRINTF("request term via canceling for input thread %s\n", pThis->name); if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslogd debug: request term via canceling for " "input thread %s\n", pThis->name); } pthread_cancel(pThis->thrdID); } else { thrdTerminateNonCancel(pThis); } pthread_join(pThis->thrdID, NULL); /* wait for input thread to complete */ RETiRet; } /* terminate all known threads gracefully. */ rsRetVal thrdTerminateAll(void) { DEFiRet; llDestroy(&llThrds); RETiRet; } /* This is an internal wrapper around the user thread function. Its * purpose is to handle all the necessary housekeeping stuff so that the * user function needs not to be aware of the threading calls. The user * function call has just "normal", non-threading semantics. * rgerhards, 2007-12-17 */ static ATTR_NORETURN void *thrdStarter(void *const arg) { DEFiRet; thrdInfo_t *const pThis = (thrdInfo_t *)arg; #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) uchar thrdName[32] = "in:"; #endif assert(pThis != NULL); assert(pThis->pUsrThrdMain != NULL); #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) ustrncpy(thrdName + 3, pThis->name, 20); dbgOutputTID((char *)thrdName); /* set thread name - we ignore if the call fails, has no harsh consequences... */ if (prctl(PR_SET_NAME, thrdName, 0, 0, 0) != 0) { DBGPRINTF("prctl failed, not setting thread name for '%s'\n", pThis->name); } else { DBGPRINTF("set thread name to '%s'\n", thrdName); } #endif /* block all signals except SIGTTIN and SIGSEGV */ sigset_t sigSet; sigfillset(&sigSet); sigdelset(&sigSet, SIGTTIN); sigdelset(&sigSet, SIGSEGV); pthread_sigmask(SIG_BLOCK, &sigSet, NULL); /* setup complete, we are now ready to execute the user code. We will not * regain control until the user code is finished, in which case we terminate * the thread. */ iRet = pThis->pUsrThrdMain(pThis); if (iRet == RS_RET_OK) { dbgprintf("thrdStarter: usrThrdMain %s - 0x%lx returned with iRet %d, exiting now.\n", pThis->name, (unsigned long)pThis->thrdID, iRet); } else { LogError(0, iRet, "main thread of %s terminated abnormally", pThis->name); } /* signal master control that we exit (we do the mutex lock mostly to * keep the thread debugger happer, it would not really be necessary with * the logic we employ...) */ d_pthread_mutex_lock(&pThis->mutThrd); pThis->bIsActive = 0; pthread_cond_signal(&pThis->condThrdTerm); d_pthread_mutex_unlock(&pThis->mutThrd); pthread_exit(0); } /* Start a new thread and add it to the list of currently * executing threads. It is added at the end of the list. * rgerhards, 2007-12-14 */ rsRetVal thrdCreate(rsRetVal (*thrdMain)(thrdInfo_t *), rsRetVal (*afterRun)(thrdInfo_t *), sbool bNeedsCancel, uchar *name) { DEFiRet; thrdInfo_t *pThis; #if defined(_AIX) pthread_attr_t aix_attr; #endif assert(thrdMain != NULL); CHKiRet(thrdConstruct(&pThis)); pThis->bIsActive = 1; pThis->pUsrThrdMain = thrdMain; pThis->pAfterRun = afterRun; pThis->bNeedsCancel = bNeedsCancel; pThis->name = ustrdup(name); #if defined(_AIX) pthread_attr_init(&aix_attr); pthread_attr_setstacksize(&aix_attr, 4096 * 512); pthread_create(&pThis->thrdID, &aix_attr, thrdStarter, pThis); #else pthread_create(&pThis->thrdID, &default_thread_attr, thrdStarter, pThis); #endif CHKiRet(llAppend(&llThrds, NULL, pThis)); finalize_it: RETiRet; } /* initialize the thread-support subsystem * must be called once at the start of the program */ rsRetVal thrdInit(void) { DEFiRet; iRet = llInit(&llThrds, (rsRetVal(*)(void *))thrdDestruct, NULL, NULL); RETiRet; } /* de-initialize the thread subsystem * must be called once at the end of the program */ rsRetVal thrdExit(void) { DEFiRet; iRet = llDestroy(&llThrds); RETiRet; } /* vi:set ai: */ rsyslog-8.2512.0/PaxHeaders/test-driver0000644000000000000000000000013215114544320014723 xustar0030 mtime=1764935888.420044218 30 atime=1764935888.420044218 30 ctime=1764935931.896709966 rsyslog-8.2512.0/test-driver0000755000175000017500000001141715114544320014374 0ustar00rgerrger#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: rsyslog-8.2512.0/PaxHeaders/platform0000644000000000000000000000013215114544360014303 xustar0030 mtime=1764935920.436534524 30 atime=1764935930.037681508 30 ctime=1764935920.436534524 rsyslog-8.2512.0/platform/0000775000175000017500000000000015114544360014024 5ustar00rgerrgerrsyslog-8.2512.0/platform/PaxHeaders/README0000644000000000000000000000013115055602574015245 xustar0029 mtime=1756824956.00345108 30 atime=1764931121.622005608 30 ctime=1764935920.436534524 rsyslog-8.2512.0/platform/README0000664000175000017500000000064015055602574014712 0ustar00rgerrgerThis subdirectory contains platform-specific files. They are maintained based on a best effort basis, and are not necessarily the same like the specific platform ships them. Some files are changed in the way the rsyslog projects would recommend them; some may even be outdated. Use this with care. If in doubt, please have a look at the official distro repos. They obviously have the gold standard for each distro. rsyslog-8.2512.0/platform/PaxHeaders/freebsd0000644000000000000000000000013215114544360015715 xustar0030 mtime=1764935920.438534555 30 atime=1764935930.175683621 30 ctime=1764935920.438534555 rsyslog-8.2512.0/platform/freebsd/0000775000175000017500000000000015114544360015436 5ustar00rgerrgerrsyslog-8.2512.0/platform/freebsd/PaxHeaders/rsyslogd0000644000000000000000000000013215035412264017562 xustar0030 mtime=1752569012.365000895 30 atime=1764931121.630005738 30 ctime=1764935920.438534555 rsyslog-8.2512.0/platform/freebsd/rsyslogd0000775000175000017500000000405615035412264017236 0ustar00rgerrger#!/bin/sh # Sample startup script for rsyslogd on FreeBSD. # It worked on my machine, but this does not necessarily # mean it works on all machines - it's not thouroughly # tested. Please note that it may also work on other # BSD variants, too. # # As of this writing, there was an issue with the mysql client # library on startup. If compiled with MySQL support, rsyslogd # would not necessarily start correctly but could eventually # die with a "mysql client libary not found" (or similar) # message. I do not know its cause neither the cure. If you # have one, let me know. # # ATTENTION: you need also to change the /etc/rc.config file # and disable stock syslogd and then enable rsyslogd! # # rgerhards 2005-08-09 # # PROVIDE: rsyslogd # REQUIRE: mountcritremote cleanvar # BEFORE: SERVERS . /etc/rc.subr name="rsyslogd" rcvar=`set_rcvar` pidfile="/var/run/rsyslogd.pid" command="/usr/sbin/${name}" required_files="/etc/rsyslog.conf" start_precmd="rsyslogd_precmd" extra_commands="reload" _sockfile="/var/run/rsyslogd.sockets" evalargs="rc_flags=\"\`set_socketlist\` \$rc_flags\"" altlog_proglist="named" rsyslogd_precmd() { # Transitional symlink for old binaries # if [ ! -L /dev/log ]; then ln -sf /var/run/log /dev/log fi rm -f /var/run/log # Create default list of syslog sockets to watch # ( umask 022 ; > $_sockfile ) # If running named(8) or ntpd(8) chrooted, added appropriate # syslog socket to list of sockets to watch. # for _l in $altlog_proglist; do eval _ldir=\$${_l}_chrootdir if checkyesno `set_rcvar $_l` && [ -n "$_ldir" ]; then echo "${_ldir}/var/run/log" >> $_sockfile fi done # If other sockets have been provided, change run_rc_command()'s # internal copy of $rsyslogd_flags to force use of specific # rsyslogd sockets. # if [ -s $_sockfile ]; then echo "/var/run/log" >> $_sockfile eval $evalargs fi return 0 } set_socketlist() { _socketargs= for _s in `cat $_sockfile | tr '\n' ' '` ; do _socketargs="-l $_s $_socketargs" done echo $_socketargs } load_rc_config $name run_rc_command "$1" rsyslog-8.2512.0/platform/PaxHeaders/slackware0000644000000000000000000000013215114544360016257 xustar0030 mtime=1764935920.440534585 30 atime=1764935930.175683621 30 ctime=1764935920.440534585 rsyslog-8.2512.0/platform/slackware/0000775000175000017500000000000015114544360016000 5ustar00rgerrgerrsyslog-8.2512.0/platform/slackware/PaxHeaders/rc.rsyslogd0000644000000000000000000000013215035412264020527 xustar0030 mtime=1752569012.365000895 30 atime=1764931121.639005883 30 ctime=1764935920.440534585 rsyslog-8.2512.0/platform/slackware/rc.rsyslogd0000775000175000017500000000305215035412264020176 0ustar00rgerrger#!/bin/sh # Start/stop/restart the system logging daemons. # # Written for Slackware Linux by Patrick J. Volkerding . # Modded for rsyslogd by Chris Elvidge Sept 2005 # create_xconsole() { if [ ! -e /dev/xconsole ]; then mknod -m 640 /dev/xconsole p else chmod 0640 /dev/xconsole fi chown 0:0 /dev/xconsole } rsyslogd_start() { if [ -x /usr/sbin/rsyslogd -a -x /usr/sbin/klogd ]; then echo "Starting rsyslogd / klogd daemons: " # this one listens on the "usual" socket /dev/log echo "/usr/sbin/rsyslogd -i $pidfile1" /usr/sbin/rsyslogd -i "$pidfile1" # this one listens only to the UDP port sleep 1 echo "/usr/sbin/rsyslogd -o -r0 -f $confile2 -i $pidfile2" /usr/sbin/rsyslogd -o -r0 -f "$confile2" -i "$pidfile2" sleep 1 # prevent syslogd/klogd race condition on SMP kernels echo "/usr/sbin/klogd -c 3 -x" # '-c 3' = display level 'error' or higher messages on console # '-x' = turn off broken EIP translation /usr/sbin/klogd -c 3 -x fi } rsyslogd_stop() { killall rsyslogd 2> /dev/null killall klogd 2> /dev/null /usr/bin/rm pidfile1 2> /dev/null /usr/bin/rm pidfile2 2> /dev/null } rsyslogd_restart() { rsyslogd_stop sleep 1 rsyslogd_start } confile1=/etc/rsyslog.conf pidfile1=/var/run/rsyslogd.pid confile2=/etc/rsyslog.udp.conf pidfile2=/var/run/rsyslogd.udp.pid case "$1" in 'start') create_xconsole rsyslogd_start ;; 'stop') rsyslogd_stop ;; 'restart') rsyslogd_restart ;; *) echo "usage $0 start|stop|restart" esac rsyslog-8.2512.0/platform/PaxHeaders/redhat0000644000000000000000000000013215114544360015552 xustar0030 mtime=1764935920.442534616 30 atime=1764935930.175683621 30 ctime=1764935920.442534616 rsyslog-8.2512.0/platform/redhat/0000775000175000017500000000000015114544360015273 5ustar00rgerrgerrsyslog-8.2512.0/platform/redhat/PaxHeaders/rsyslog.conf0000644000000000000000000000013215035412264020177 xustar0030 mtime=1752569012.365000895 30 atime=1764931121.647006012 30 ctime=1764935920.443534631 rsyslog-8.2512.0/platform/redhat/rsyslog.conf0000664000175000017500000000657115035412264017654 0ustar00rgerrger# rsyslog configuration file (for Red Hat-based systems) # note that most of this config file uses old-style format, # because it is well-known AND quite suitable for simple cases # like we have with the default config. For more advanced # things, RainerScript configuration is suggested. # # For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html # or latest version online at https://www.rsyslog.com/doc/rsyslog_conf.html # If you experience problems, see https://www.rsyslog.com/doc/troubleshoot.html #### MODULES #### module(load="imuxsock") # provides support for local system logging (e.g. via logger command) module(load="imklog") # provides kernel logging support (previously done by rklogd) #module(load"immark") # provides --MARK-- message capability # Provides UDP syslog reception # for parameters see https://www.rsyslog.com/doc/imudp.html #module(load="imudp") # needs to be done just once #input(type="imudp" port="514") # Provides TCP syslog reception # for parameters see https://www.rsyslog.com/doc/imtcp.html #module(load="imtcp") # needs to be done just once #input(type="imtcp" port="514") #### GLOBAL DIRECTIVES #### # Use default timestamp format $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat # File syncing capability is disabled by default. This feature is usually not required, # not useful and an extreme performance hit #$ActionFileEnableSync on # Include all config files in /etc/rsyslog.d/ $IncludeConfig /etc/rsyslog.d/*.conf #### RULES #### # Log all kernel messages to the console. # Logging much else clutters up the screen. #kern.* /dev/console # Log anything (except mail) of level info or higher. # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none /var/log/messages # The authpriv file has restricted access. authpriv.* /var/log/secure # Log all the mail messages in one place. mail.* /var/log/maillog # Log cron stuff cron.* /var/log/cron # Everybody gets emergency messages *.emerg :omusrmsg:* # Save news errors of level crit and higher in a special file. uucp,news.crit /var/log/spooler # Save boot messages also to boot.log local7.* /var/log/boot.log # ### begin forwarding rule ### # The statement between the begin ... end define a SINGLE forwarding # rule. They belong together, do NOT split them. If you create multiple # forwarding rules, duplicate the whole block! # Remote Logging (we use TCP for reliable delivery) # # An on-disk queue is created for this action. If the remote host is # down, messages are spooled to disk and sent when it is up again. #$WorkDirectory /var/lib/rsyslog # where to place spool files #$ActionQueueFileName fwdRule1 # unique name prefix for spool files #$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible) #$ActionQueueSaveOnShutdown on # save messages to disk on shutdown #$ActionQueueType LinkedList # run asynchronously #$ActionResumeRetryCount -1 # infinite retries if host is down # remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional #*.* @@remote-host:514 # ### end of the forwarding rule ### rsyslog-8.2512.0/PaxHeaders/template.c0000644000000000000000000000013215103346332014510 xustar0030 mtime=1762512090.632175993 30 atime=1764931001.497036435 30 ctime=1764935923.314578586 rsyslog-8.2512.0/template.c0000664000175000017500000035634515103346332014174 0ustar00rgerrger/* This is the template processing code of rsyslog. * begun 2004-11-17 rgerhards * * Copyright 2004-2019 Rainer Gerhards and Adiscon * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Note: there is a tiny bit of code left where I could not get any response * from the author if this code can be placed under ASL2.0. I have guarded this * with #ifdef STRICT_GPLV3. Only if that macro is defined, the code will be * compiled. Otherwise this feature is not present. The plan is to do a * different implementation in the future to get rid of this problem. * rgerhards, 2012-08-25 */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include "stringbuf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "dirty.h" #include "obj.h" #include "errmsg.h" #include "strgen.h" #include "rsconf.h" #include "msg.h" #include "parserif.h" #include "unicode-helper.h" /* states for lazily built JSON tree used in list templates with jsonf mode */ #define TPL_JSON_TREE_NOT_BUILT 0 #define TPL_JSON_TREE_BUILT 1 #define TPL_JSON_TREE_UNSUPPORTED 2 enum tplJsonNodeType { tplJsonNodeObject = 0, tplJsonNodeValue = 1 }; struct tplJsonNode { enum tplJsonNodeType type; uchar *name; size_t nameLen; struct templateEntry *pTpe; /* only valid for value nodes */ struct tplJsonNode *parent; struct tplJsonNode *firstChild; struct tplJsonNode *lastChild; struct tplJsonNode *nextSibling; }; static struct tplJsonNode *tplJsonNodeNew(enum tplJsonNodeType type, const uchar *name, size_t nameLen); static void tplJsonNodeAddChild(struct tplJsonNode *parent, struct tplJsonNode *child); static void tplJsonNodeFree(struct tplJsonNode *node); static rsRetVal tplJsonEnsureContainer( struct tplJsonNode *parent, const uchar *name, size_t nameLen, struct tplJsonNode **ppContainer, int *pUnsupported); static rsRetVal tplJsonAddValueNode( struct tplJsonNode *parent, struct templateEntry *pTpe, const uchar *name, size_t nameLen, int *pUnsupported); static rsRetVal tplJsonBuildTree(struct template *pTpl); static rsRetVal tplJsonRender(struct template *pTpl, smsg_t *pMsg, actWrkrIParams_t *iparam, struct syslogTime *ttNow); static rsRetVal tplJsonRenderChildren( const struct tplJsonNode *parent, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppDst, int *pNeedComma); static rsRetVal tplJsonRenderNode( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput); static rsRetVal tplJsonRenderValue( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput); static rsRetVal tplJsonRenderObject( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput); static void tplWarnDuplicateJsonKeys(struct template *pTpl); /** * \brief Allocate a fresh JSON tree node for dotted jsonf rendering. * * The node optionally owns a copy of \p name so descendants can be * addressed without depending on the template entry backing storage. * * \param type Node role (object container or scalar value). * \param name Optional name for the node. * \param nameLen Length of \p name in bytes (without terminator). * \return Newly allocated node or NULL on allocation failure. */ static struct tplJsonNode *tplJsonNodeNew(enum tplJsonNodeType type, const uchar *name, size_t nameLen) { struct tplJsonNode *node = calloc(1, sizeof(struct tplJsonNode)); if (node == NULL) return NULL; node->type = type; node->pTpe = NULL; if (name != NULL && nameLen > 0) { node->name = malloc(nameLen + 1); if (node->name == NULL) { free(node); return NULL; } memcpy(node->name, name, nameLen); node->name[nameLen] = '\0'; node->nameLen = nameLen; } return node; } /** * \brief Link a child node to its parent while maintaining sibling order. * * The helper records both first and last child so breadth-first iteration * is cheap when walking the tree later during rendering. * * \param parent Parent object that will receive \p child. * \param child Node to link; ownership is transferred to \p parent. */ static void tplJsonNodeAddChild(struct tplJsonNode *parent, struct tplJsonNode *child) { if (parent == NULL || child == NULL) return; child->parent = parent; child->nextSibling = NULL; if (parent->firstChild == NULL) { parent->firstChild = parent->lastChild = child; } else { parent->lastChild->nextSibling = child; parent->lastChild = child; } } /** * \brief Recursively dispose a JSON node subtree. * * Frees all descendants, the node name buffer, and the node itself. * Safe to call with NULL. * * \param node Root of the subtree to release. */ static void tplJsonNodeFree(struct tplJsonNode *node) { if (node == NULL) return; struct tplJsonNode *child = node->firstChild; while (child != NULL) { struct tplJsonNode *next = child->nextSibling; tplJsonNodeFree(child); child = next; } free(node->name); free(node); } /** * \brief Ensure an object child exists for the given dotted segment. * * Creates an intermediate container when necessary and flags the template * as unsupported if the segment collides with an existing value node. * * \param parent Current node that should hold the container. * \param name Segment name to ensure. * \param nameLen Length of \p name. * \param ppContainer Out parameter receiving the container when found. * \param pUnsupported Set to 1 when the template cannot be expressed. * \retval RS_RET_OK Container exists or was created. * \retval RS_RET_OUT_OF_MEMORY Allocation failed. */ static rsRetVal tplJsonEnsureContainer(struct tplJsonNode *parent, const uchar *name, size_t nameLen, struct tplJsonNode **ppContainer, int *pUnsupported) { struct tplJsonNode *child; if (ppContainer != NULL) *ppContainer = NULL; if (pUnsupported != NULL) *pUnsupported = 0; if (parent == NULL) return RS_RET_ERR; for (child = parent->firstChild; child != NULL; child = child->nextSibling) { if (child->nameLen == nameLen && memcmp(child->name, name, nameLen) == 0) { if (child->type != tplJsonNodeObject) { if (pUnsupported != NULL) *pUnsupported = 1; return RS_RET_OK; } if (ppContainer != NULL) *ppContainer = child; return RS_RET_OK; } } child = tplJsonNodeNew(tplJsonNodeObject, name, nameLen); if (child == NULL) return RS_RET_OUT_OF_MEMORY; tplJsonNodeAddChild(parent, child); if (ppContainer != NULL) *ppContainer = child; return RS_RET_OK; } /** * \brief Attach a value node for a template entry at the current tree level. * * Rejects collisions where an existing object node already occupies the * desired name and propagates an unsupported flag to the caller. * * \param parent Object node receiving the value. * \param pTpe Template entry that supplies the value. * \param name Final path segment for the value. * \param nameLen Length of \p name. * \param pUnsupported Output flag marked when a collision is detected. * \retval RS_RET_OK Value node linked or collision recorded. * \retval RS_RET_OUT_OF_MEMORY Allocation failed. */ static rsRetVal tplJsonAddValueNode( struct tplJsonNode *parent, struct templateEntry *pTpe, const uchar *name, size_t nameLen, int *pUnsupported) { struct tplJsonNode *child; if (pUnsupported != NULL) *pUnsupported = 0; if (parent == NULL) return RS_RET_ERR; for (child = parent->firstChild; child != NULL; child = child->nextSibling) { if (child->nameLen == nameLen && memcmp(child->name, name, nameLen) == 0) { if (child->type == tplJsonNodeObject) { if (pUnsupported != NULL) *pUnsupported = 1; return RS_RET_OK; } child->pTpe = pTpe; return RS_RET_OK; } } child = tplJsonNodeNew(tplJsonNodeValue, name, nameLen); if (child == NULL) return RS_RET_OUT_OF_MEMORY; child->pTpe = pTpe; tplJsonNodeAddChild(parent, child); return RS_RET_OK; } /** * \brief Build the JSON tree representation for a jsonf list template. * * Walks dotted outname segments, creating containers as required and * recording which templates cannot be represented as structured JSON. * * \param pTpl Template to analyse; its tree fields are updated in place. * \retval RS_RET_OK on success or when jsonf is unsupported for the template. * \retval RS_RET_OUT_OF_MEMORY on allocation failure. */ static rsRetVal tplJsonBuildTree(struct template *pTpl) { struct tplJsonNode *root = NULL; struct templateEntry *pTpe; int unsupported = 0; DEFiRet; if (pTpl->bJsonTreeBuilt != TPL_JSON_TREE_NOT_BUILT) RETiRet; CHKmalloc(root = tplJsonNodeNew(tplJsonNodeObject, NULL, 0)); for (pTpe = pTpl->pEntryRoot; pTpe != NULL; pTpe = pTpe->pNext) { if (pTpe->fieldName == NULL || pTpe->lenFieldName == 0) { unsupported = 1; break; } if (pTpe->eEntryType == CONSTANT) { if (!pTpe->data.constant.bJSONf) { unsupported = 1; break; } } else if (pTpe->eEntryType == FIELD) { if (!pTpe->data.field.options.bJSONf && !pTpe->data.field.options.bJSONfr) { unsupported = 1; break; } } else { unsupported = 1; break; } struct tplJsonNode *parent = root; const uchar *segStart = pTpe->fieldName; const uchar *ptr = pTpe->fieldName; const uchar *end = pTpe->fieldName + pTpe->lenFieldName; while (ptr < end) { if (*ptr == '.') { if (ptr == segStart) { unsupported = 1; break; } struct tplJsonNode *container = NULL; const size_t segLen = (size_t)(ptr - segStart); CHKiRet(tplJsonEnsureContainer(parent, segStart, segLen, &container, &unsupported)); if (unsupported) break; parent = container; ++ptr; segStart = ptr; continue; } ++ptr; } if (unsupported) break; const size_t segLen = (size_t)(end - segStart); if (segLen == 0) { unsupported = 1; break; } CHKiRet(tplJsonAddValueNode(parent, pTpe, segStart, segLen, &unsupported)); if (unsupported) break; } if (unsupported) { tplJsonNodeFree(root); pTpl->pJsonRoot = NULL; pTpl->bJsonTreeBuilt = TPL_JSON_TREE_UNSUPPORTED; LogError(0, NO_ERRCODE, "template '%s' with option jsonftree has conflicting keys (e.g. 'a' and 'a.b'); " "falling back to flat JSON output.", pTpl->pszName != NULL ? pTpl->pszName : ""); } else { pTpl->pJsonRoot = root; pTpl->bJsonTreeBuilt = TPL_JSON_TREE_BUILT; } finalize_it: if (iRet != RS_RET_OK) { tplJsonNodeFree(root); } RETiRet; } /** * \brief Render a list template with jsonf option via the pre-built tree. * * Serialises the lazily cached tree into the caller-provided work buffer * producing canonical JSON with nested objects. * * \param pTpl Template to render; must already have a built tree. * \param pMsg Message supplying field data. * \param iparam Worker output buffer descriptor. * \param ttNow Timestamp context for field formatting. * \retval RS_RET_OK on success or an error code from subordinate lookups. */ static rsRetVal tplJsonRender(struct template *pTpl, smsg_t *pMsg, actWrkrIParams_t *iparam, struct syslogTime *ttNow) { es_str_t *out = NULL; char *rendered = NULL; int needComma = 0; DEFiRet; if (pTpl->pJsonRoot == NULL) RETiRet; CHKmalloc(out = es_newStr(128)); es_addChar(&out, '{'); CHKiRet(tplJsonRenderChildren(pTpl->pJsonRoot, pMsg, ttNow, &out, &needComma)); es_addBufConstcstr(&out, "}\n"); const int len = es_strlen(out); if ((size_t)len + 1 > (size_t)iparam->lenBuf) { CHKiRet(ExtendBuf(iparam, (size_t)len + 1)); } rendered = es_str2cstr(out, NULL); CHKmalloc(rendered); memcpy(iparam->param, rendered, (size_t)len); iparam->param[len] = '\0'; iparam->lenStr = len; finalize_it: if (rendered != NULL) free(rendered); if (out != NULL) es_deleteStr(out); RETiRet; } /** * \brief Render all children of a JSON node, inserting commas as needed. * * Recursively descends into the tree and appends emitted fragments to the * destination string buffer. * * \param parent Node whose children should be rendered. * \param pMsg Message that provides runtime values. * \param ttNow Timestamp context for property formatting. * \param ppDst Destination string buffer reference. * \param pNeedComma Tracks whether a comma should precede the next child. */ static rsRetVal tplJsonRenderChildren( const struct tplJsonNode *parent, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppDst, int *pNeedComma) { const struct tplJsonNode *child = parent->firstChild; es_str_t *childStr = NULL; int childHasOutput = 0; DEFiRet; while (child != NULL) { childStr = NULL; childHasOutput = 0; CHKiRet(tplJsonRenderNode(child, pMsg, ttNow, &childStr, &childHasOutput)); if (childHasOutput) { if (*pNeedComma) es_addBufConstcstr(ppDst, ", "); es_addStr(ppDst, childStr); *pNeedComma = 1; } if (childStr != NULL) { es_deleteStr(childStr); childStr = NULL; } child = child->nextSibling; } finalize_it: if (childStr != NULL) es_deleteStr(childStr); RETiRet; } /** * \brief Dispatch renderer for a node depending on its type. * * Value nodes are expanded into name/value pairs, while object nodes yield * nested JSON objects. * * \param node Node to render. * \param pMsg Message providing data. * \param ttNow Timestamp context. * \param ppOut Output string produced for this node. * \param pHasOutput Flag indicating whether a value was emitted. */ static rsRetVal tplJsonRenderNode( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput) { if (node->type == tplJsonNodeValue) { return tplJsonRenderValue(node, pMsg, ttNow, ppOut, pHasOutput); } return tplJsonRenderObject(node, pMsg, ttNow, ppOut, pHasOutput); } /** * \brief Render a scalar template entry into a JSON name/value fragment. * * Handles both constant and property-backed entries, including trimming any * legacy jsonf field prefixes and skipping empty expansions. * * \param node Value node describing the template entry. * \param pMsg Message context for property lookups. * \param ttNow Timestamp context. * \param ppOut Newly allocated string with the rendered fragment. * \param pHasOutput Set to 1 if the fragment contains data. */ static rsRetVal tplJsonRenderValue( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput) { uchar *pVal = NULL; rs_size_t lenVal = 0; unsigned short bMustBeFreed = 0; es_str_t *out = NULL; const uchar *valuePtr; size_t valueLen; const uchar *colon; DEFiRet; *ppOut = NULL; *pHasOutput = 0; if (node->pTpe == NULL || node->name == NULL || node->nameLen == 0) RETiRet; if (node->pTpe->eEntryType == CONSTANT) { pVal = node->pTpe->data.constant.pConstant; lenVal = node->pTpe->data.constant.iLenConstant; } else if (node->pTpe->eEntryType == FIELD) { pVal = MsgGetProp(pMsg, node->pTpe, &node->pTpe->data.field.msgProp, &lenVal, &bMustBeFreed, ttNow); } else { RETiRet; } if (pVal == NULL || lenVal <= 0) goto finalize_it; valuePtr = pVal; valueLen = (size_t)lenVal; colon = memchr(pVal, ':', (size_t)lenVal); if (colon != NULL) { const uchar *keyStart = pVal; const uchar *keyEnd = colon; while (keyStart < colon && isspace((int)*keyStart)) ++keyStart; while (keyEnd > keyStart && isspace((int)*(keyEnd - 1))) --keyEnd; const size_t prefixLen = (size_t)(keyEnd - keyStart); int matchesKey = 0; if (prefixLen >= 2 && keyStart[0] == '"' && keyEnd[-1] == '"' && node->pTpe->fieldName != NULL) { if ((size_t)node->pTpe->lenFieldName == prefixLen - 2 && memcmp(keyStart + 1, node->pTpe->fieldName, node->pTpe->lenFieldName) == 0) { matchesKey = 1; } } if (matchesKey) { size_t offset = (size_t)((colon + 1) - pVal); if (offset >= (size_t)lenVal) goto finalize_it; valuePtr = pVal + offset; valueLen = (size_t)lenVal - offset; } } while (valueLen > 0 && isspace((int)*valuePtr)) { ++valuePtr; --valueLen; } while (valueLen > 0 && isspace((int)valuePtr[valueLen - 1])) --valueLen; if (valueLen == 0) goto finalize_it; const size_t requiredLen = node->nameLen + valueLen + 4; if (requiredLen > (size_t)INT_MAX) { parser_errmsg("error: jsonf value to be rendered is too large"); ABORT_FINALIZE(RS_RET_ERR); } CHKmalloc(out = es_newStr((int)requiredLen)); es_addChar(&out, '"'); es_addBuf(&out, (const char *)node->name, node->nameLen); es_addBufConstcstr(&out, "\":"); es_addBuf(&out, (const char *)valuePtr, valueLen); *ppOut = out; out = NULL; *pHasOutput = 1; finalize_it: if (bMustBeFreed && pVal != NULL) free(pVal); if (out != NULL) es_deleteStr(out); RETiRet; } /** * \brief Render an object node and all nested children into JSON. * * Skips empty objects to preserve legacy behaviour while ensuring commas * and braces are placed consistently. * * \param node Object node to render. * \param pMsg Message supplying data for descendants. * \param ttNow Timestamp context. * \param ppOut Output string containing the rendered object. * \param pHasOutput Flag set when the object emitted any fields. */ static rsRetVal tplJsonRenderObject( const struct tplJsonNode *node, smsg_t *pMsg, struct syslogTime *ttNow, es_str_t **ppOut, int *pHasOutput) { es_str_t *out = NULL; es_str_t *childStr = NULL; int needComma = 0; const struct tplJsonNode *child; DEFiRet; *ppOut = NULL; *pHasOutput = 0; if (node->name == NULL || node->nameLen == 0) RETiRet; const size_t requiredLen = node->nameLen + 5; if (requiredLen > (size_t)INT_MAX) { parser_errmsg("error: jsonf object key to be rendered is too large"); ABORT_FINALIZE(RS_RET_ERR); } CHKmalloc(out = es_newStr((int)requiredLen)); es_addChar(&out, '"'); es_addBuf(&out, (const char *)node->name, node->nameLen); es_addBufConstcstr(&out, "\": {"); child = node->firstChild; while (child != NULL) { childStr = NULL; int childHasOutput = 0; CHKiRet(tplJsonRenderNode(child, pMsg, ttNow, &childStr, &childHasOutput)); if (childHasOutput) { if (needComma) es_addBufConstcstr(&out, ", "); es_addStr(&out, childStr); needComma = 1; } if (childStr != NULL) { es_deleteStr(childStr); childStr = NULL; } child = child->nextSibling; } if (!needComma) goto finalize_it; es_addChar(&out, '}'); *ppOut = out; out = NULL; *pHasOutput = 1; finalize_it: if (childStr != NULL) es_deleteStr(childStr); if (out != NULL) es_deleteStr(out); RETiRet; } static void tplWarnDuplicateJsonKeys(struct template *pTpl) { struct templateEntry *curr; if (pTpl == NULL) return; for (curr = pTpl->pEntryRoot; curr != NULL; curr = curr->pNext) { struct templateEntry *scan; int isJsonField = 0; if (curr->fieldName == NULL || curr->lenFieldName <= 0) continue; if (curr->eEntryType == CONSTANT) { isJsonField = curr->data.constant.bJSONf; } else if (curr->eEntryType == FIELD) { isJsonField = curr->data.field.options.bJSONf || curr->data.field.options.bJSONfr; } if (!isJsonField) continue; for (scan = pTpl->pEntryRoot; scan != curr; scan = scan->pNext) { int scanJsonField = 0; if (scan->fieldName == NULL || scan->lenFieldName <= 0) continue; if (scan->eEntryType == CONSTANT) { scanJsonField = scan->data.constant.bJSONf; } else if (scan->eEntryType == FIELD) { scanJsonField = scan->data.field.options.bJSONf || scan->data.field.options.bJSONfr; } if (!scanJsonField) continue; if (scan->lenFieldName == curr->lenFieldName && memcmp(scan->fieldName, curr->fieldName, curr->lenFieldName) == 0) { LogError(0, NO_ERRCODE, "template '%s': duplicate JSON key '%.*s' encountered; later definition takes precedence", pTpl->pszName != NULL ? pTpl->pszName : "", curr->lenFieldName, curr->fieldName); break; } } } } PRAGMA_IGNORE_Wswitch_enum /* static data */ DEFobjCurrIf(obj) DEFobjCurrIf(strgen) /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfparamdescr[] = {{"name", eCmdHdlrString, 1}, {"type", eCmdHdlrString, 1}, {"string", eCmdHdlrString, 0}, {"plugin", eCmdHdlrString, 0}, {"subtree", eCmdHdlrString, 0}, {"option.stdsql", eCmdHdlrBinary, 0}, {"option.sql", eCmdHdlrBinary, 0}, {"option.json", eCmdHdlrBinary, 0}, {"option.jsonf", eCmdHdlrBinary, 0}, {"option.jsonftree", eCmdHdlrBinary, 0}, {"option.casesensitive", eCmdHdlrBinary, 0}}; static struct cnfparamblk pblk = {CNFPARAMBLK_VERSION, sizeof(cnfparamdescr) / sizeof(struct cnfparamdescr), cnfparamdescr}; static struct cnfparamdescr cnfparamdescrProperty[] = {{"name", eCmdHdlrString, 1}, {"outname", eCmdHdlrString, 0}, {"dateformat", eCmdHdlrString, 0}, {"date.inutc", eCmdHdlrBinary, 0}, {"compressspace", eCmdHdlrBinary, 0}, {"caseconversion", eCmdHdlrString, 0}, {"controlcharacters", eCmdHdlrString, 0}, {"securepath", eCmdHdlrString, 0}, {"format", eCmdHdlrString, 0}, {"position.from", eCmdHdlrInt, 0}, {"position.to", eCmdHdlrInt, 0}, {"position.relativetoend", eCmdHdlrBinary, 0}, {"field.number", eCmdHdlrInt, 0}, {"field.delimiter", eCmdHdlrInt, 0}, {"regex.expression", eCmdHdlrString, 0}, {"regex.type", eCmdHdlrString, 0}, {"regex.nomatchmode", eCmdHdlrString, 0}, {"regex.match", eCmdHdlrInt, 0}, {"regex.submatch", eCmdHdlrInt, 0}, {"droplastlf", eCmdHdlrBinary, 0}, {"fixedwidth", eCmdHdlrBinary, 0}, {"datatype", eCmdHdlrString, 0}, {"onempty", eCmdHdlrString, 0}, {"mandatory", eCmdHdlrBinary, 0}, {"spifno1stsp", eCmdHdlrBinary, 0}}; static struct cnfparamblk pblkProperty = { CNFPARAMBLK_VERSION, sizeof(cnfparamdescrProperty) / sizeof(struct cnfparamdescr), cnfparamdescrProperty}; static struct cnfparamdescr cnfparamdescrConstant[] = { {"value", eCmdHdlrString, 1}, {"format", eCmdHdlrString, 0}, {"outname", eCmdHdlrString, 0}}; static struct cnfparamblk pblkConstant = { CNFPARAMBLK_VERSION, sizeof(cnfparamdescrConstant) / sizeof(struct cnfparamdescr), cnfparamdescrConstant}; #ifdef FEATURE_REGEXP DEFobjCurrIf(regexp) static int bFirstRegexpErrmsg = 1; /**< did we already do a "can't load regexp" error message? */ #endif /* helper to tplToString and strgen's, extends buffer */ #define ALLOC_INC 128 rsRetVal ExtendBuf(actWrkrIParams_t *__restrict__ const iparam, const size_t iMinSize) { uchar *pNewBuf; size_t iNewSize; DEFiRet; iNewSize = (iMinSize / ALLOC_INC + 1) * ALLOC_INC; CHKmalloc(pNewBuf = (uchar *)realloc(iparam->param, iNewSize)); iparam->param = pNewBuf; iparam->lenBuf = iNewSize; finalize_it: RETiRet; } /* This functions converts a template into a string. * * The function takes a pointer to a template and a pointer to a msg object * as well as a pointer to an output buffer and its size. Note that the output * buffer pointer may be NULL, size 0, in which case a new one is allocated. * The output buffer is grown as required. It is the caller's duty to free the * buffer when it is done. Note that it is advisable to reuse memory, as this * offers big performance improvements. * rewritten 2009-06-19 rgerhards */ rsRetVal tplToString(struct template *__restrict__ const pTpl, smsg_t *__restrict__ const pMsg, actWrkrIParams_t *__restrict__ const iparam, struct syslogTime *const ttNow) { DEFiRet; struct templateEntry *__restrict__ pTpe; size_t iBuf; unsigned short bMustBeFreed = 0; uchar *pVal; rs_size_t iLenVal = 0; int need_comma = 0; if (pTpl->pStrgen != NULL) { CHKiRet(pTpl->pStrgen(pMsg, iparam)); FINALIZE; } if (pTpl->bHaveSubtree) { /* only a single CEE subtree must be provided */ /* note: we could optimize the code below, however, this is * not worth the effort, as this passing mode is not expected * in subtree mode and so most probably only used for debug & test. */ getJSONPropVal(pMsg, &pTpl->subtree, &pVal, &iLenVal, &bMustBeFreed); if (iLenVal >= (rs_size_t)iparam->lenBuf) /* we reserve one char for the final \0! */ CHKiRet(ExtendBuf(iparam, iLenVal + 1)); memcpy(iparam->param, pVal, iLenVal + 1); iparam->lenStr = iLenVal; FINALIZE; } /* we have a "regular" template with template entries */ if (pTpl->optFormatEscape == JSONF && pTpl->bJsonTreeEnabled) { if (pTpl->bJsonTreeBuilt == TPL_JSON_TREE_NOT_BUILT) { CHKiRet(tplJsonBuildTree(pTpl)); } if (pTpl->bJsonTreeBuilt == TPL_JSON_TREE_BUILT && pTpl->pJsonRoot != NULL) { CHKiRet(tplJsonRender(pTpl, pMsg, iparam, ttNow)); FINALIZE; } } /* loop through the template. We obtain one value * and copy it over to our dynamic string buffer. Then, we * free the obtained value (if requested). We continue this * loop until we got hold of all values. */ pTpe = pTpl->pEntryRoot; iBuf = 0; const int isJsonFlat = (pTpl->optFormatEscape == JSONF && !pTpl->bJsonTreeEnabled); if (isJsonFlat) { if (iparam->lenBuf < 2) /* we reserve one char for the final \0! */ CHKiRet(ExtendBuf(iparam, 2)); iBuf = 1; *iparam->param = '{'; } while (pTpe != NULL) { if (pTpe->eEntryType == CONSTANT) { pVal = (uchar *)pTpe->data.constant.pConstant; iLenVal = pTpe->data.constant.iLenConstant; bMustBeFreed = 0; } else if (pTpe->eEntryType == FIELD) { pVal = (uchar *)MsgGetProp(pMsg, pTpe, &pTpe->data.field.msgProp, &iLenVal, &bMustBeFreed, ttNow); /* we now need to check if we should use SQL option. In this case, * we must go over the generated string and escape '\'' characters. * rgerhards, 2005-09-22: the option values below look somewhat misplaced, * but they are handled in this way because of legacy (don't break any * existing thing). */ if (pTpl->optFormatEscape == SQL_ESCAPE) doEscape(&pVal, &iLenVal, &bMustBeFreed, SQL_ESCAPE); else if (pTpl->optFormatEscape == JSON_ESCAPE) doEscape(&pVal, &iLenVal, &bMustBeFreed, JSON_ESCAPE); else if (pTpl->optFormatEscape == STDSQL_ESCAPE) doEscape(&pVal, &iLenVal, &bMustBeFreed, STDSQL_ESCAPE); } else { DBGPRINTF("TplToString: invalid entry type %d\n", pTpe->eEntryType); pVal = (uchar *)"*LOGIC ERROR*"; iLenVal = sizeof("*LOGIC ERROR*") - 1; bMustBeFreed = 0; } /* got source, now copy over */ const int isLastEntry = (pTpe->pNext == NULL); const size_t closingLen = (isJsonFlat && isLastEntry) ? 2 : 0; size_t requiredLen = closingLen; if (iLenVal > 0) { if (need_comma) requiredLen += 2; requiredLen += (size_t)iLenVal; } if (requiredLen > 0 && (iBuf + requiredLen) >= iparam->lenBuf) CHKiRet(ExtendBuf(iparam, iBuf + requiredLen + 1)); if (iLenVal > 0) { /* may be zero depending on property */ if (need_comma) { memcpy(iparam->param + iBuf, ", ", 2); iBuf += 2; } memcpy(iparam->param + iBuf, pVal, iLenVal); iBuf += iLenVal; if (isJsonFlat) { need_comma = 1; } } if (closingLen > 0) { memcpy(iparam->param + iBuf, "}\n", 2); iBuf += 2; } if (bMustBeFreed) { free(pVal); bMustBeFreed = 0; } pTpe = pTpe->pNext; } if (iBuf == iparam->lenBuf) { /* in the weired case of an *empty* template, this can happen. * it is debatable if we should really fix it here or simply * forbid that case. However, performance toll is minimal, so * I tend to permit it. -- 2010-11-05 rgerhards */ CHKiRet(ExtendBuf(iparam, iBuf + 1)); } iparam->param[iBuf] = '\0'; iparam->lenStr = iBuf; finalize_it: if (bMustBeFreed) { free(pVal); bMustBeFreed = 0; } RETiRet; } /* This functions converts a template into a json object. * For further general details, see the very similar funtion * tpltoString(). * rgerhards, 2012-08-29 */ rsRetVal tplToJSON(struct template *pTpl, smsg_t *pMsg, struct json_object **pjson, struct syslogTime *ttNow) { struct templateEntry *pTpe; rs_size_t propLen; unsigned short bMustBeFreed; uchar *pVal; struct json_object *json, *jsonf; rsRetVal localRet; DEFiRet; if (pTpl->bHaveSubtree) { if (jsonFind(pMsg, &pTpl->subtree, pjson) != RS_RET_OK) *pjson = NULL; if (*pjson == NULL) { /* we need to have a root object! */ *pjson = json_object_new_object(); } else { json_object_get(*pjson); /* inc refcount */ } FINALIZE; } json = json_object_new_object(); for (pTpe = pTpl->pEntryRoot; pTpe != NULL; pTpe = pTpe->pNext) { if (pTpe->eEntryType == CONSTANT) { if (pTpe->fieldName == NULL) continue; jsonf = json_object_new_string((char *)pTpe->data.constant.pConstant); json_object_object_add(json, (char *)pTpe->fieldName, jsonf); } else if (pTpe->eEntryType == FIELD) { if (pTpe->data.field.msgProp.id == PROP_CEE || pTpe->data.field.msgProp.id == PROP_LOCAL_VAR || pTpe->data.field.msgProp.id == PROP_GLOBAL_VAR) { localRet = msgGetJSONPropJSON(pMsg, &pTpe->data.field.msgProp, &jsonf); if (localRet == RS_RET_OK) { json_object_object_add(json, (char *)pTpe->fieldName, json_object_get(jsonf)); } else { DBGPRINTF("tplToJSON: error %d looking up property %s\n", localRet, pTpe->fieldName); if (pTpe->data.field.options.bMandatory) { json_object_object_add(json, (char *)pTpe->fieldName, NULL); } } } else { pVal = (uchar *)MsgGetProp(pMsg, pTpe, &pTpe->data.field.msgProp, &propLen, &bMustBeFreed, ttNow); if (pTpe->data.field.options.bMandatory || propLen > 0) { jsonf = json_object_new_string_len((char *)pVal, propLen + 1); json_object_object_add(json, (char *)pTpe->fieldName, jsonf); } if (bMustBeFreed) { /* json-c makes its own private copy! */ free(pVal); } } } } assert(iRet == RS_RET_OK); *pjson = json; finalize_it: RETiRet; } /* Helper to doEscape. This is called if doEscape * runs out of memory allocating the escaped string. * Then we are in trouble. We can * NOT simply return the unmodified string because this * may cause SQL injection. But we also can not simply * abort the run, this would be a DoS. I think an appropriate * measure is to remove the dangerous \' characters (SQL). We * replace them by \", which will break the message and * signatures eventually present - but this is the * best thing we can do now (or does anybody * have a better idea?). rgerhards 2004-11-23 * added support for escape mode (see doEscape for details). * if mode = SQL_ESCAPE, then backslashes are changed to slashes. * rgerhards 2005-09-22 */ static void doEmergencyEscape(register uchar *p, int mode) { while (*p) { if ((mode == SQL_ESCAPE || mode == STDSQL_ESCAPE) && *p == '\'') { *p = '"'; } else if (mode == JSON_ESCAPE) { if (*p == '"') { *p = '\''; } else if (*p == '\\') { *p = '/'; } } else if ((mode == SQL_ESCAPE) && *p == '\\') { *p = '/'; } ++p; } } /* SQL-Escape a string. Single quotes are found and * replaced by two of them. A new buffer is allocated * for the provided string and the provided buffer is * freed. The length is updated. Parameter pbMustBeFreed * is set to 1 if a new buffer is allocated. Otherwise, * it is left untouched. * -- * We just discovered a security issue. MySQL is so * "smart" to not only support the standard SQL mechanism * for escaping quotes, but to also provide its own (using * c-type syntax with backslashes). As such, it is actually * possible to do sql injection via rsyslogd. The cure is now * to escape backslashes, too. As we have found on the web, some * other databases seem to be similar "smart" (why do we have standards * at all if they are violated without any need???). Even better, MySQL's * smartness depends on config settings. So we add a new option to this * function that allows the caller to select if they want to standard or * "smart" encoding ;) * -- * Parameter "mode" is STDSQL_ESCAPE, SQL_ESCAPE "smart" SQL engines, or * JSON_ESCAPE for everyone requiring escaped JSON (e.g. ElasticSearch). * 2005-09-22 rgerhards */ rsRetVal doEscape(uchar **pp, rs_size_t *pLen, unsigned short *pbMustBeFreed, int mode) { DEFiRet; uchar *p = NULL; int iLen; cstr_t *pStrB = NULL; uchar *pszGenerated; assert(pp != NULL); assert(*pp != NULL); assert(pLen != NULL); assert(pbMustBeFreed != NULL); /* first check if we need to do anything at all... */ if (mode == STDSQL_ESCAPE) for (p = *pp; *p && *p != '\''; ++p); else if (mode == SQL_ESCAPE) for (p = *pp; *p && *p != '\'' && *p != '\\'; ++p); else if (mode == JSON_ESCAPE) for (p = *pp; *p && (*p == '"' || *p == '\\'); ++p); /* when we get out of the loop, we are either at the * string terminator or the first character to escape */ if (p && *p == '\0') FINALIZE; /* nothing to do in this case! */ p = *pp; iLen = *pLen; CHKiRet(cstrConstruct(&pStrB)); while (*p) { if ((mode == SQL_ESCAPE || mode == STDSQL_ESCAPE) && *p == '\'') { CHKiRet(cstrAppendChar(pStrB, (mode == STDSQL_ESCAPE) ? '\'' : '\\')); iLen++; /* reflect the extra character */ } else if ((mode == SQL_ESCAPE) && *p == '\\') { CHKiRet(cstrAppendChar(pStrB, '\\')); iLen++; /* reflect the extra character */ } else if ((mode == JSON_ESCAPE) && (*p == '"' || *p == '\\')) { CHKiRet(cstrAppendChar(pStrB, '\\')); iLen++; /* reflect the extra character */ } CHKiRet(cstrAppendChar(pStrB, *p)); ++p; } cstrFinalize(pStrB); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, &pszGenerated, 0)); if (*pbMustBeFreed) free(*pp); /* discard previous value */ *pp = pszGenerated; *pLen = iLen; *pbMustBeFreed = 1; finalize_it: if (iRet != RS_RET_OK) { doEmergencyEscape(*pp, mode); if (pStrB != NULL) cstrDestruct(&pStrB); } RETiRet; } /* Constructs a template entry object. Returns pointer to it * or NULL (if it fails). Pointer to associated template list entry * must be provided. */ static struct templateEntry *tpeConstruct(struct template *pTpl) { struct templateEntry *pTpe; assert(pTpl != NULL); if ((pTpe = calloc(1, sizeof(struct templateEntry))) == NULL) return NULL; /* basic initialization is done via calloc() - need to * initialize only values != 0. */ if (pTpl->pEntryLast == NULL) { /* we are the first element! */ pTpl->pEntryRoot = pTpl->pEntryLast = pTpe; } else { pTpl->pEntryLast->pNext = pTpe; pTpl->pEntryLast = pTpe; } pTpl->tpenElements++; return (pTpe); } /* Helper function to apply case-sensitivity to templates. */ static void apply_case_sensitivity(struct template *pTpl) { if (pTpl->optCaseSensitive) return; struct templateEntry *pTpe; for (pTpe = pTpl->pEntryRoot; pTpe != NULL; pTpe = pTpe->pNext) { if (pTpe->eEntryType == FIELD) { if (pTpe->data.field.msgProp.id == PROP_CEE || pTpe->data.field.msgProp.id == PROP_LOCAL_VAR || pTpe->data.field.msgProp.id == PROP_GLOBAL_VAR) { uchar *p; p = pTpe->fieldName; for (; *p; ++p) *p = tolower(*p); p = pTpe->data.field.msgProp.name; for (; *p; ++p) *p = tolower(*p); } } } } /* Constructs a template list object. Returns pointer to it * or NULL (if it fails). */ static struct template *tplConstruct(rsconf_t *conf) { struct template *pTpl; if ((pTpl = calloc(1, sizeof(struct template))) == NULL) return NULL; /* basic initialisation is done via calloc() - need to * initialize only values != 0. */ if (conf->templates.last == NULL) { /* we are the first element! */ conf->templates.root = conf->templates.last = pTpl; } else { conf->templates.last->pNext = pTpl; conf->templates.last = pTpl; } return (pTpl); } /* helper to tplAddLine. Parses a constant and generates * the necessary structure. * Parameter "bDoEscapes" is to support legacy vs. v6+ config system. In * legacy, we must do escapes ourselves, whereas v6+ passes in already * escaped strings (which we are NOT permitted to further escape, this would * cause invalid result strings!). Note: if escapes are not permitted, * quotes (") are just a regular character and do NOT terminate the constant! */ static rsRetVal do_Constant(unsigned char **pp, struct template *pTpl, int bDoEscapes) { register unsigned char *p; cstr_t *pStrB; struct templateEntry *pTpe; int i; DEFiRet; assert(pp != NULL); assert(*pp != NULL); assert(pTpl != NULL); p = *pp; CHKiRet(cstrConstruct(&pStrB)); /* process the message and expand escapes * (additional escapes can be added here if needed) */ while (*p && *p != '%' && !(bDoEscapes && *p == '\"')) { if (bDoEscapes && *p == '\\') { switch (*++p) { case '\0': /* the best we can do - it's invalid anyhow... */ cstrAppendChar(pStrB, *p); break; case 'n': cstrAppendChar(pStrB, '\n'); ++p; break; case 'r': cstrAppendChar(pStrB, '\r'); ++p; break; case '\\': cstrAppendChar(pStrB, '\\'); ++p; break; case '%': cstrAppendChar(pStrB, '%'); ++p; break; case '0': /* numerical escape sequence */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i = 0; while (*p && isdigit((int)*p)) { i = i * 10 + *p++ - '0'; } cstrAppendChar(pStrB, i); break; default: cstrAppendChar(pStrB, *p++); break; } } else cstrAppendChar(pStrB, *p++); } if ((pTpe = tpeConstruct(pTpl)) == NULL) { rsCStrDestruct(&pStrB); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pTpe->eEntryType = CONSTANT; cstrFinalize(pStrB); /* We obtain the length from the counted string object * (before we delete it). Later we might take additional * benefit from the counted string object. * 2005-09-09 rgerhards */ pTpe->data.constant.iLenConstant = rsCStrLen(pStrB); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, &pTpe->data.constant.pConstant, 0)); *pp = p; finalize_it: RETiRet; } /* Helper that checks to see if a property already has a format * type defined */ static int hasFormat(struct templateEntry *pTpe) { return (pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON || pTpe->data.field.options.bJSONf || pTpe->data.field.options.bJSONr); } /* Helper to do_Parameter(). This parses the formatting options * specified in a template variable. It returns the passed-in pointer * updated to the next processed character. */ static void doOptions(unsigned char **pp, struct templateEntry *pTpe) { register unsigned char *p; unsigned char Buf[64]; size_t i; assert(pp != NULL); assert(*pp != NULL); assert(pTpe != NULL); p = *pp; while (*p && *p != '%' && *p != ':') { /* outer loop - until end of options */ memset(Buf, 0, sizeof(Buf)); /* silence valgrind warnings */ i = 0; while ((i < sizeof(Buf) - 1) && *p && *p != '%' && *p != ':' && *p != ',') { /* inner loop - until end of ONE option */ Buf[i++] = tolower((int)*p); ++p; } Buf[i] = '\0'; /* terminate */ /* check if we need to skip oversize option */ while (*p && *p != '%' && *p != ':' && *p != ',') ++p; /* just skip */ if (*p == ',') ++p; /* eat ',' */ /* OK, we got the option, so now lets look what * it tells us... */ if (!strcmp((char *)Buf, "date-mysql")) { pTpe->data.field.eDateFormat = tplFmtMySQLDate; } else if (!strcmp((char *)Buf, "date-pgsql")) { pTpe->data.field.eDateFormat = tplFmtPgSQLDate; } else if (!strcmp((char *)Buf, "date-rfc3164")) { pTpe->data.field.eDateFormat = tplFmtRFC3164Date; } else if (!strcmp((char *)Buf, "date-rfc3164-buggyday")) { pTpe->data.field.eDateFormat = tplFmtRFC3164BuggyDate; } else if (!strcmp((char *)Buf, "date-rfc3339")) { pTpe->data.field.eDateFormat = tplFmtRFC3339Date; } else if (!strcmp((char *)Buf, "date-unixtimestamp")) { pTpe->data.field.eDateFormat = tplFmtUnixDate; } else if (!strcmp((char *)Buf, "date-subseconds")) { pTpe->data.field.eDateFormat = tplFmtSecFrac; } else if (!strcmp((char *)Buf, "date-wdayname")) { pTpe->data.field.eDateFormat = tplFmtWDayName; } else if (!strcmp((char *)Buf, "date-wday")) { pTpe->data.field.eDateFormat = tplFmtWDay; } else if (!strcmp((char *)Buf, "date-year")) { pTpe->data.field.eDateFormat = tplFmtYear; } else if (!strcmp((char *)Buf, "date-month")) { pTpe->data.field.eDateFormat = tplFmtMonth; } else if (!strcmp((char *)Buf, "date-day")) { pTpe->data.field.eDateFormat = tplFmtDay; } else if (!strcmp((char *)Buf, "date-hour")) { pTpe->data.field.eDateFormat = tplFmtHour; } else if (!strcmp((char *)Buf, "date-minute")) { pTpe->data.field.eDateFormat = tplFmtMinute; } else if (!strcmp((char *)Buf, "date-second")) { pTpe->data.field.eDateFormat = tplFmtSecond; } else if (!strcmp((char *)Buf, "date-tzoffshour")) { pTpe->data.field.eDateFormat = tplFmtTZOffsHour; } else if (!strcmp((char *)Buf, "date-tzoffsmin")) { pTpe->data.field.eDateFormat = tplFmtTZOffsMin; } else if (!strcmp((char *)Buf, "date-tzoffsdirection")) { pTpe->data.field.eDateFormat = tplFmtTZOffsDirection; } else if (!strcmp((char *)Buf, "date-ordinal")) { pTpe->data.field.eDateFormat = tplFmtOrdinal; } else if (!strcmp((char *)Buf, "date-week")) { pTpe->data.field.eDateFormat = tplFmtWeek; } else if (!strcmp((char *)Buf, "date-iso-week")) { pTpe->data.field.eDateFormat = tplFmtISOWeek; } else if (!strcmp((char *)Buf, "date-iso-week-year")) { pTpe->data.field.eDateFormat = tplFmtISOWeekYear; } else if (!strcmp((char *)Buf, "date-utc")) { pTpe->data.field.options.bDateInUTC = 1; } else if (!strcmp((char *)Buf, "lowercase")) { pTpe->data.field.eCaseConv = tplCaseConvLower; } else if (!strcmp((char *)Buf, "uppercase")) { pTpe->data.field.eCaseConv = tplCaseConvUpper; } else if (!strcmp((char *)Buf, "sp-if-no-1st-sp")) { pTpe->data.field.options.bSPIffNo1stSP = 1; } else if (!strcmp((char *)Buf, "compressspace")) { pTpe->data.field.options.bCompressSP = 1; } else if (!strcmp((char *)Buf, "escape-cc")) { pTpe->data.field.options.bEscapeCC = 1; } else if (!strcmp((char *)Buf, "drop-cc")) { pTpe->data.field.options.bDropCC = 1; } else if (!strcmp((char *)Buf, "space-cc")) { pTpe->data.field.options.bSpaceCC = 1; } else if (!strcmp((char *)Buf, "drop-last-lf")) { pTpe->data.field.options.bDropLastLF = 1; } else if (!strcmp((char *)Buf, "secpath-drop")) { pTpe->data.field.options.bSecPathDrop = 1; } else if (!strcmp((char *)Buf, "secpath-replace")) { pTpe->data.field.options.bSecPathReplace = 1; } else if (!strcmp((char *)Buf, "pos-end-relative")) { pTpe->data.field.options.bFromPosEndRelative = 1; } else if (!strcmp((char *)Buf, "fixed-width")) { pTpe->data.field.options.bFixedWidth = 1; } else if (!strcmp((char *)Buf, "csv")) { if (hasFormat(pTpe)) { LogError(0, NO_ERRCODE, "error: can only specify " "one option out of (json, jsonf, jsonr, jsonfr, csv) - csv ignored"); } else { pTpe->data.field.options.bCSV = 1; } } else if (!strcmp((char *)Buf, "json")) { if (hasFormat(pTpe)) { LogError(0, NO_ERRCODE, "error: can only specify " "one option out of (json, jsonf, jsonr, jsonfr, csv) - json ignored"); } else { pTpe->data.field.options.bJSON = 1; } } else if (!strcmp((char *)Buf, "jsonf")) { if (hasFormat(pTpe)) { LogError(0, NO_ERRCODE, "error: can only specify " "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonf ignored"); } else { pTpe->data.field.options.bJSONf = 1; } } else if (!strcmp((char *)Buf, "jsonr")) { if (hasFormat(pTpe)) { LogError(0, NO_ERRCODE, "error: can only specify " "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonr ignored"); } else { pTpe->data.field.options.bJSONr = 1; } } else if (!strcmp((char *)Buf, "jsonfr")) { if (hasFormat(pTpe)) { LogError(0, NO_ERRCODE, "error: can only specify " "one option out of (json, jsonf, jsonr, jsonfr, csv) - jsonfr ignored"); } else { pTpe->data.field.options.bJSONfr = 1; } } else if (!strcmp((char *)Buf, "mandatory-field")) { pTpe->data.field.options.bMandatory = 1; } else { LogError(0, NO_ERRCODE, "template error: invalid field option '%s' " "specified - ignored", Buf); } } *pp = p; } /* helper to tplAddLine. Parses a parameter and generates * the necessary structure. */ static rsRetVal do_Parameter(uchar **pp, struct template *pTpl) { uchar *p; cstr_t *pStrProp = NULL; cstr_t *pStrField = NULL; struct templateEntry *pTpe; int iNum; /* to compute numbers */ #ifdef FEATURE_REGEXP /* APR: variables for regex */ rsRetVal iRetLocal; int longitud; unsigned char *regex_char; unsigned char *regex_end; #endif DEFiRet; assert(pp != NULL); assert(*pp != NULL); assert(pTpl != NULL); p = (uchar *)*pp; CHKiRet(cstrConstruct(&pStrProp)); CHKmalloc(pTpe = tpeConstruct(pTpl)); pTpe->eEntryType = FIELD; while (*p && *p != '%' && *p != ':') { cstrAppendChar(pStrProp, *p); ++p; } /* got the name */ cstrFinalize(pStrProp); CHKiRet(msgPropDescrFill(&pTpe->data.field.msgProp, cstrGetSzStrNoNULL(pStrProp), cstrLen(pStrProp))); /* Check frompos, if it has an R, then topos should be a regex */ if (*p == ':') { pTpe->bComplexProcessing = 1; ++p; /* eat ':' */ #ifdef FEATURE_REGEXP if (*p == 'R') { /* APR: R found! regex alarm ! :) */ ++p; /* eat ':' */ /* first come the regex type */ if (*p == ',') { ++p; /* eat ',' */ if (p[0] == 'B' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) { pTpe->data.field.typeRegex = TPL_REGEX_BRE; p += 3; /* eat indicator sequence */ } else if (p[0] == 'E' && p[1] == 'R' && p[2] == 'E' && (p[3] == ',' || p[3] == ':')) { pTpe->data.field.typeRegex = TPL_REGEX_ERE; p += 3; /* eat indicator sequence */ } else { LogError(0, NO_ERRCODE, "error: invalid regular expression " "type, rest of line %s", (char *)p); } } /* now check for submatch ID */ pTpe->data.field.iSubMatchToUse = 0; if (*p == ',') { /* in this case a number follows, which indicates which match * shall be used. This must be a single digit. */ ++p; /* eat ',' */ if (isdigit((int)*p)) { pTpe->data.field.iSubMatchToUse = *p - '0'; ++p; /* eat digit */ } } /* now pull what to do if we do not find a match */ if (*p == ',') { ++p; /* eat ',' */ if (p[0] == 'D' && p[1] == 'F' && p[2] == 'L' && p[3] == 'T' && (p[4] == ',' || p[4] == ':')) { pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_DFLTSTR; p += 4; /* eat indicator sequence */ } else if (p[0] == 'B' && p[1] == 'L' && p[2] == 'A' && p[3] == 'N' && p[4] == 'K' && (p[5] == ',' || p[5] == ':')) { pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_BLANK; p += 5; /* eat indicator sequence */ } else if (p[0] == 'F' && p[1] == 'I' && p[2] == 'E' && p[3] == 'L' && p[4] == 'D' && (p[5] == ',' || p[5] == ':')) { pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_WHOLE_FIELD; p += 5; /* eat indicator sequence */ } else if (p[0] == 'Z' && p[1] == 'E' && p[2] == 'R' && p[3] == 'O' && (p[4] == ',' || p[4] == ':')) { pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_ZERO; p += 4; /* eat indicator sequence */ } else if (p[0] == ',') { /* empty, use default */ pTpe->data.field.nomatchAction = TPL_REGEX_NOMATCH_USE_DFLTSTR; /* do NOT eat indicator sequence, as this was already eaten - the * comma itself is already part of the next field. */ } else { LogError(0, NO_ERRCODE, "template %s error: invalid regular " "expression type, rest of line %s", pTpl->pszName, (char *)p); } } /* now check for match ID */ pTpe->data.field.iMatchToUse = 0; if (*p == ',') { /* in this case a number follows, which indicates which match * shall be used. This must be a single digit. */ ++p; /* eat ',' */ if (isdigit((int)*p)) { pTpe->data.field.iMatchToUse = *p - '0'; ++p; /* eat digit */ } } if (*p != ':') { /* There is something more than an R , this is invalid ! */ /* Complain on extra characters */ LogError(0, NO_ERRCODE, "error: invalid character in frompos " "after \"R\", property: '%%%s'", (char *)*pp); } else { pTpe->data.field.has_regex = 1; dbgprintf("we have a regexp and use match #%d, submatch #%d\n", pTpe->data.field.iMatchToUse, pTpe->data.field.iSubMatchToUse); } } else { /* now we fall through the "regular" FromPos code */ #endif /* #ifdef FEATURE_REGEXP */ if (*p == 'F') { #ifdef STRICT_GPLV3 pTpe->data.field.field_expand = 0; #endif /* we have a field counter, so indicate it in the template */ ++p; /* eat 'F' */ if (*p == ':') { /* no delimiter specified, so use the default (HT) */ pTpe->data.field.has_fields = 1; pTpe->data.field.field_delim = 9; } else if (*p == ',') { ++p; /* eat ',' */ /* configured delimiter follows, so we need to obtain * it. Important: the following number must be the * **DECIMAL** ASCII value of the delimiter character. */ pTpe->data.field.has_fields = 1; if (!isdigit((int)*p)) { /* complain and use default */ LogError(0, NO_ERRCODE, "error: invalid character in " "frompos after \"F,\", property: '%%%s' - using 9 (HT) as field delimiter", (char *)*pp); pTpe->data.field.field_delim = 9; } else { iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; if (iNum < 0 || iNum > 255) { LogError(0, NO_ERRCODE, "error: non-USASCII delimiter " "character value %d in template - using 9 (HT) as substitute", iNum); pTpe->data.field.field_delim = 9; } else { pTpe->data.field.field_delim = iNum; #ifdef STRICT_GPLV3 if (*p == '+') { pTpe->data.field.field_expand = 1; p++; } #endif if (*p == ',') { /* real fromPos? */ ++p; iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; pTpe->data.field.iFromPos = iNum; } else if (*p != ':') { parser_errmsg( "error: invalid character " "'%c' in frompos after \"F,\", property: '%s' " "be sure to use DECIMAL character " "codes!", *p, (char *)*pp); ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); } } } } else { /* invalid character after F, so we need to reject * this. */ LogError(0, NO_ERRCODE, "error: invalid character in frompos " "after \"F\", property: '%%%s'", (char *)*pp); } } else { /* we now have a simple offset in frompos (the previously "normal" case) */ iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; pTpe->data.field.iFromPos = iNum; /* skip to next known good */ while (*p && *p != '%' && *p != ':') { /* TODO: complain on extra characters */ dbgprintf("error: extra character in frompos: '%s'\n", p); ++p; } } #ifdef FEATURE_REGEXP } #endif /* #ifdef FEATURE_REGEXP */ } /* check topos (holds an regex if FromPos is "R"*/ if (*p == ':') { ++p; /* eat ':' */ #ifdef FEATURE_REGEXP if (pTpe->data.field.has_regex) { dbgprintf("debug: has regex \n"); /* APR 2005-09 I need the string that represent the regex */ /* The regex end is: "--end" */ /* TODO : this is hardcoded and cant be escaped, please change */ regex_end = (unsigned char *)strstr((char *)p, "--end"); if (regex_end == NULL) { dbgprintf("error: can not find regex end in: '%s'\n", p); pTpe->data.field.has_regex = 0; } else { /* We get here ONLY if the regex end was found */ longitud = regex_end - p; /* Malloc for the regex string */ regex_char = (unsigned char *)malloc(longitud + 1); if (regex_char == NULL) { dbgprintf("Could not allocate memory for template parameter!\n"); pTpe->data.field.has_regex = 0; ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } /* Get the regex string for compiling later */ memcpy(regex_char, p, longitud); regex_char[longitud] = '\0'; dbgprintf("debug: regex detected: '%s'\n", regex_char); /* Now i compile the regex */ /* Remember that the re is an attribute of the Template entry */ if ((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) { int iOptions; iOptions = (pTpe->data.field.typeRegex == TPL_REGEX_ERE) ? REG_EXTENDED : 0; int errcode; if ((errcode = regexp.regcomp(&(pTpe->data.field.re), (char *)regex_char, iOptions) != 0)) { char errbuff[512]; regexp.regerror(errcode, &(pTpe->data.field.re), errbuff, sizeof(errbuff)); DBGPRINTF("Template.c: Error in regular expression: %s\n", errbuff); pTpe->data.field.has_regex = 2; } } else { /* regexp object could not be loaded */ dbgprintf( "error %d trying to load regexp library - this may be desired " "and thus OK", iRetLocal); if (bFirstRegexpErrmsg) { /* prevent flood of messages, maybe even an endless loop! */ bFirstRegexpErrmsg = 0; LogError(0, NO_ERRCODE, "regexp library could not be loaded " "(error %d), regexp ignored", iRetLocal); } pTpe->data.field.has_regex = 2; } /* Finally we move the pointer to the end of the regex * so it aint parsed twice or something weird */ p = regex_end + 5 /*strlen("--end")*/; free(regex_char); } } else if (*p == '$') { /* shortcut for "end of message */ p++; /* eat '$' */ /* in this case, we do a quick, somewhat dirty but totally * legitimate trick: we simply use a topos that is higher than * potentially ever can happen. The code below checks that no copy * will occur after the end of string, so this is perfectly legal. * rgerhards, 2006-10-17 */ pTpe->data.field.iToPos = 9999999; } else { /* fallthrough to "regular" ToPos code */ #endif /* #ifdef FEATURE_REGEXP */ if (pTpe->data.field.has_fields == 1) { iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; pTpe->data.field.iFieldNr = iNum; if (*p == ',') { /* get real toPos? */ ++p; iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; pTpe->data.field.iToPos = iNum; } } else { iNum = 0; while (isdigit((int)*p)) iNum = iNum * 10 + *p++ - '0'; pTpe->data.field.iToPos = iNum; } /* skip to next known good */ while (*p && *p != '%' && *p != ':') { /* TODO: complain on extra characters */ dbgprintf("error: extra character in frompos: '%s'\n", p); ++p; } #ifdef FEATURE_REGEXP } #endif /* #ifdef FEATURE_REGEXP */ } /* check options */ if (*p == ':') { ++p; /* eat ':' */ doOptions(&p, pTpe); } if (pTpe->data.field.options.bFromPosEndRelative) { if (pTpe->data.field.iToPos > pTpe->data.field.iFromPos) { iNum = pTpe->data.field.iToPos; pTpe->data.field.iToPos = pTpe->data.field.iFromPos; pTpe->data.field.iFromPos = iNum; } } else { if (pTpe->data.field.iToPos < pTpe->data.field.iFromPos) { iNum = pTpe->data.field.iToPos; pTpe->data.field.iToPos = pTpe->data.field.iFromPos; pTpe->data.field.iFromPos = iNum; } } /* check field name */ if (*p == ':') { ++p; /* eat ':' */ CHKiRet(cstrConstruct(&pStrField)); while (*p != ':' && *p != '%' && *p != '\0') { cstrAppendChar(pStrField, *p); ++p; } cstrFinalize(pStrField); } /* save field name - if none was given, use the property name instead */ if (pStrField == NULL) { if (pTpe->data.field.msgProp.id == PROP_CEE || pTpe->data.field.msgProp.id == PROP_LOCAL_VAR) { /* in CEE case, we remove "$!"/"$." from the fieldname - it's just our indicator */ pTpe->fieldName = ustrdup(cstrGetSzStrNoNULL(pStrProp) + 2); pTpe->lenFieldName = cstrLen(pStrProp) - 2; } else { pTpe->fieldName = ustrdup(cstrGetSzStrNoNULL(pStrProp)); pTpe->lenFieldName = cstrLen(pStrProp); } } else { pTpe->fieldName = ustrdup(cstrGetSzStrNoNULL(pStrField)); pTpe->lenFieldName = ustrlen(pTpe->fieldName); cstrDestruct(&pStrField); } if (pTpe->fieldName == NULL) { DBGPRINTF("template/do_Parameter: fieldName is NULL!\n"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } if (*p) ++p; /* eat '%' */ *pp = p; finalize_it: if (pStrProp != NULL) cstrDestruct(&pStrProp); RETiRet; } /* Add a new entry for a template module. * returns pointer to new object if it succeeds, NULL otherwise. * rgerhards, 2010-05-31 */ static rsRetVal tplAddTplMod(struct template *pTpl, uchar **ppRestOfConfLine) { uchar *pSrc; uchar szMod[2048]; unsigned lenMod; strgen_t *pStrgen; DEFiRet; pSrc = *ppRestOfConfLine; lenMod = 0; while (*pSrc && !isspace(*pSrc) && lenMod < sizeof(szMod) - 1) { szMod[lenMod] = *pSrc++; lenMod++; } szMod[lenMod] = '\0'; *ppRestOfConfLine = pSrc; CHKiRet(strgen.FindStrgen(&pStrgen, szMod)); pTpl->pStrgen = pStrgen->pModule->mod.sm.strgen; DBGPRINTF("template bound to strgen '%s'\n", szMod); /* check if the name potentially contains some well-known options * Note: we have opted to let the name contain all options. This sounds * useful, because the strgen MUST actually implement a specific set * of options. Doing this via the name looks to the enduser as if the * regular syntax were used, and it make sure the strgen postively * acknowledged implementing the option. -- rgerhards, 2011-03-21 */ if (lenMod > 6 && !strcasecmp((char *)szMod + lenMod - 7, ",stdsql")) { pTpl->optFormatEscape = STDSQL_ESCAPE; DBGPRINTF("strgen supports the stdsql option\n"); } else if (lenMod > 3 && !strcasecmp((char *)szMod + lenMod - 4, ",sql")) { pTpl->optFormatEscape = SQL_ESCAPE; DBGPRINTF("strgen supports the sql option\n"); } else if (lenMod > 4 && !strcasecmp((char *)szMod + lenMod - 4, ",json")) { pTpl->optFormatEscape = JSON_ESCAPE; DBGPRINTF("strgen supports the json option\n"); } finalize_it: RETiRet; } /* Add a new template line * returns pointer to new object if it succeeds, NULL otherwise. */ struct template *tplAddLine(rsconf_t *conf, const char *pName, uchar **ppRestOfConfLine) { struct template *pTpl; unsigned char *p; int bDone; size_t i; rsRetVal localRet; assert(pName != NULL); assert(ppRestOfConfLine != NULL); if ((pTpl = tplConstruct(conf)) == NULL) return NULL; DBGPRINTF("tplAddLine processing template '%s'\n", pName); pTpl->iLenName = strlen(pName); pTpl->pszName = (char *)malloc(pTpl->iLenName + 1); if (pTpl->pszName == NULL) { dbgprintf("tplAddLine could not alloc memory for template name!"); pTpl->iLenName = 0; return NULL; /* I know - we create a memory leak here - but I deem * it acceptable as it is a) a very small leak b) very * unlikely to happen. rgerhards 2004-11-17 */ } memcpy(pTpl->pszName, pName, pTpl->iLenName + 1); /* now actually parse the line */ p = *ppRestOfConfLine; assert(p != NULL); while (isspace((int)*p)) /* skip whitespace */ ++p; switch (*p) { case '"': /* just continue */ break; case '=': *ppRestOfConfLine = p + 1; localRet = tplAddTplMod(pTpl, ppRestOfConfLine); if (localRet != RS_RET_OK) { LogError(0, localRet, "Template '%s': error %d defining template via strgen module", pTpl->pszName, localRet); /* we simply make the template defunct in this case by setting * its name to a zero-string. We do not free it, as this would * require additional code and causes only a very small memory * consumption. Memory is freed, however, in normal operation * and most importantly by HUPing syslogd. */ *pTpl->pszName = '\0'; } return NULL; default: dbgprintf("Template '%s' invalid, does not start with '\"'!\n", pTpl->pszName); /* we simply make the template defunct in this case by setting * its name to a zero-string. We do not free it, as this would * require additional code and causes only a very small memory * consumption. */ *pTpl->pszName = '\0'; return NULL; } ++p; /* we finally go to the actual template string - so let's have some fun... */ bDone = *p ? 0 : 1; while (!bDone) { switch (*p) { case '\0': bDone = 1; break; case '%': /* parameter */ ++p; /* eat '%' */ if (do_Parameter(&p, pTpl) != RS_RET_OK) { dbgprintf("tplAddLine error: parameter invalid"); return NULL; }; break; default: /* constant */ do_Constant(&p, pTpl, 1); break; } if (*p == '"') { /* end of template string? */ ++p; /* eat it! */ bDone = 1; } } /* we now have the template - let's look at the options (if any) * we process options until we reach the end of the string or * an error occurs - whichever is first. */ while (*p) { while (isspace((int)*p)) /* skip whitespace */ ++p; if (*p != ',') break; ++p; /* eat ',' */ while (isspace((int)*p)) /* skip whitespace */ ++p; /* read option word */ char optBuf[128] = {'\0'}; /* buffer for options - should be more than enough... */ i = 0; while ((i < (sizeof(optBuf) - 1)) && *p && *p != '=' && *p != ',' && *p != '\n') { optBuf[i++] = tolower((int)*p); ++p; } optBuf[i] = '\0'; if (*p == '\n') ++p; /* as of now, the no form is nonsense... but I do include * it anyhow... ;) rgerhards 2004-11-22 */ if (!strcmp(optBuf, "stdsql")) { pTpl->optFormatEscape = STDSQL_ESCAPE; } else if (!strcmp(optBuf, "json")) { pTpl->optFormatEscape = JSON_ESCAPE; } else if (!strcmp(optBuf, "sql")) { pTpl->optFormatEscape = SQL_ESCAPE; } else if (!strcmp(optBuf, "nosql")) { pTpl->optFormatEscape = NO_ESCAPE; } else if (!strcmp(optBuf, "casesensitive")) { pTpl->optCaseSensitive = 1; } else if (!strcmp(optBuf, "jsonf")) { pTpl->optFormatEscape = JSONF; pTpl->bJsonTreeEnabled = 0; } else if (!strcmp(optBuf, "jsonftree")) { pTpl->optFormatEscape = JSONF; pTpl->bJsonTreeEnabled = 1; } else { dbgprintf("Invalid option '%s' ignored.\n", optBuf); } } *ppRestOfConfLine = p; apply_case_sensitivity(pTpl); if (pTpl->optFormatEscape == JSONF) tplWarnDuplicateJsonKeys(pTpl); return (pTpl); } static rsRetVal createConstantTpe(struct template *pTpl, struct cnfobj *o) { struct templateEntry *pTpe; es_str_t *value = NULL; /* init just to keep compiler happy - mandatory parameter */ int i; int is_jsonf = 0; struct cnfparamvals *pvals = NULL; struct json_object *json = NULL; struct json_object *jval = NULL; uchar *outname = NULL; DEFiRet; /* pull params */ pvals = nvlstGetParams(o->nvlst, &pblkConstant, NULL); if (pvals == NULL) { parser_errmsg("error processing template parameters"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } cnfparamsPrint(&pblkConstant, pvals); for (i = 0; i < pblkConstant.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblkConstant.descr[i].name, "value")) { value = pvals[i].val.d.estr; } else if (!strcmp(pblkConstant.descr[i].name, "outname")) { outname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblkConstant.descr[i].name, "format")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"jsonf", sizeof("jsonf") - 1)) { is_jsonf = 1; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid format type '%s' for constant", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else { LogError(0, RS_RET_INTERNAL_ERROR, "template:constantTpe: program error, non-handled " "param '%s'\n", pblkConstant.descr[i].name); } } if (is_jsonf && outname == NULL) { parser_errmsg("constant set to format jsonf, but outname not specified - aborting"); ABORT_FINALIZE(RS_RET_ERR); } /* just double-check */ assert(value != NULL); /* apply */ CHKmalloc(pTpe = tpeConstruct(pTpl)); es_unescapeStr(value); pTpe->eEntryType = CONSTANT; pTpe->fieldName = outname; if (outname != NULL) pTpe->lenFieldName = ustrlen(outname); pTpe->data.constant.bJSONf = is_jsonf; if (is_jsonf) { json = json_object_new_object(); CHKmalloc(json); const char *sz = es_str2cstr(value, NULL); CHKmalloc(sz); jval = json_object_new_string(sz); if (jval == NULL) { free((void *)sz); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } free((void *)sz); json_object_object_add(json, (char *)outname, jval); const char *jsonStr = json_object_get_string(json); CHKmalloc(jsonStr); const size_t jsonLen = strlen(jsonStr); if (jsonLen < 2) { parser_errmsg("error: failed to serialize jsonf constant"); ABORT_FINALIZE(RS_RET_ERR); } const size_t fragmentLen = jsonLen - 2; uchar *fragment = (uchar *)strndup(jsonStr + 1, fragmentLen); CHKmalloc(fragment); size_t fragLen = ustrlen(fragment); while (fragLen > 0 && isspace((int)fragment[fragLen - 1])) { --fragLen; } fragment[fragLen] = '\0'; size_t lead = 0; while (lead < fragLen && isspace((int)fragment[lead])) ++lead; if (lead > 0) { memmove(fragment, fragment + lead, fragLen - lead + 1); fragLen -= lead; } pTpe->data.constant.pConstant = fragment; pTpe->data.constant.iLenConstant = fragLen; json_object_put(json); json = NULL; } else { pTpe->data.constant.iLenConstant = es_strlen(value); pTpe->data.constant.pConstant = (uchar *)es_str2cstr(value, NULL); } finalize_it: if (json != NULL) json_object_put(json); if (pvals != NULL) cnfparamvalsDestruct(pvals, &pblkConstant); RETiRet; } static rsRetVal createPropertyTpe(struct template *pTpl, struct cnfobj *o) { struct templateEntry *pTpe; uchar *name = NULL; uchar *outname = NULL; int i; int droplastlf = 0; int spifno1stsp = 0; int mandatory = 0; int frompos = -1; int topos = 0; int topos_set = 0; int fieldnum = -1; int fielddelim = 9; /* default is HT (USACSII 9) */ int fixedwidth = 0; int re_matchToUse = 0; int re_submatchToUse = 0; int bComplexProcessing = 0; int bPosRelativeToEnd = 0; int bDateInUTC = 0; int bCompressSP = 0; unsigned dataType = TPE_DATATYPE_STRING; unsigned onEmpty = TPE_DATAEMPTY_KEEP; char *re_expr = NULL; struct cnfparamvals *pvals = NULL; enum { F_NONE, F_CSV, F_JSON, F_JSONF, F_JSONR, F_JSONFR } formatType = F_NONE; enum { CC_NONE, CC_ESCAPE, CC_SPACE, CC_DROP } controlchr = CC_NONE; enum { SP_NONE, SP_DROP, SP_REPLACE } secpath = SP_NONE; enum tplFormatCaseConvTypes caseconv = tplCaseConvNo; enum tplFormatTypes datefmt = tplFmtDefault; enum tplRegexType re_type = TPL_REGEX_BRE; enum tlpRegexNoMatchType re_nomatchType = TPL_REGEX_NOMATCH_USE_DFLTSTR; DEFiRet; /* pull params */ pvals = nvlstGetParams(o->nvlst, &pblkProperty, NULL); if (pvals == NULL) { parser_errmsg("error processing template entry config parameters"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } cnfparamsPrint(&pblkProperty, pvals); for (i = 0; i < pblkProperty.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblkProperty.descr[i].name, "name")) { name = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblkProperty.descr[i].name, "datatype")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"string", sizeof("string") - 1)) { dataType = TPE_DATATYPE_STRING; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"number", sizeof("number") - 1)) { dataType = TPE_DATATYPE_NUMBER; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"bool", sizeof("bool") - 1)) { dataType = TPE_DATATYPE_BOOL; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"auto", sizeof("auto") - 1)) { dataType = TPE_DATATYPE_AUTO; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid dataType '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "onempty")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"keep", sizeof("keep") - 1)) { onEmpty = TPE_DATAEMPTY_KEEP; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"skip", sizeof("skip") - 1)) { onEmpty = TPE_DATAEMPTY_SKIP; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"null", sizeof("null") - 1)) { onEmpty = TPE_DATAEMPTY_NULL; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid onEmpty value '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "droplastlf")) { droplastlf = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "fixedwidth")) { fixedwidth = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "mandatory")) { mandatory = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "spifno1stsp")) { spifno1stsp = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "outname")) { outname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblkProperty.descr[i].name, "position.from")) { frompos = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "position.to")) { topos = pvals[i].val.d.n; topos_set = 1; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "position.relativetoend")) { bPosRelativeToEnd = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "field.number")) { fieldnum = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "field.delimiter")) { fielddelim = pvals[i].val.d.n; bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "regex.expression")) { re_expr = es_str2cstr(pvals[i].val.d.estr, NULL); bComplexProcessing = 1; } else if (!strcmp(pblkProperty.descr[i].name, "regex.type")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"BRE", sizeof("BRE") - 1)) { re_type = TPL_REGEX_BRE; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"ERE", sizeof("ERE") - 1)) { re_type = TPL_REGEX_ERE; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid regex.type '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "regex.nomatchmode")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"DFLT", sizeof("DFLT") - 1)) { re_nomatchType = TPL_REGEX_NOMATCH_USE_DFLTSTR; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"BLANK", sizeof("BLANK") - 1)) { re_nomatchType = TPL_REGEX_NOMATCH_USE_BLANK; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"FIELD", sizeof("FIELD") - 1)) { re_nomatchType = TPL_REGEX_NOMATCH_USE_WHOLE_FIELD; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"ZERO", sizeof("ZERO") - 1)) { re_nomatchType = TPL_REGEX_NOMATCH_USE_ZERO; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid format type '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "regex.match")) { bComplexProcessing = 1; re_matchToUse = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "regex.submatch")) { bComplexProcessing = 1; re_submatchToUse = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "format")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"csv", sizeof("csv") - 1)) { formatType = F_CSV; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"json", sizeof("json") - 1)) { formatType = F_JSON; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"jsonf", sizeof("jsonf") - 1)) { formatType = F_JSONF; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"jsonr", sizeof("jsonr") - 1)) { formatType = F_JSONR; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"jsonfr", sizeof("jsonfr") - 1)) { formatType = F_JSONFR; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid format type '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "controlcharacters")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"escape", sizeof("escape") - 1)) { controlchr = CC_ESCAPE; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"space", sizeof("space") - 1)) { controlchr = CC_SPACE; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"drop", sizeof("drop") - 1)) { controlchr = CC_DROP; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid controlcharacter mode '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "securepath")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"drop", sizeof("drop") - 1)) { secpath = SP_DROP; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"replace", sizeof("replace") - 1)) { secpath = SP_REPLACE; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid securepath mode '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "caseconversion")) { bComplexProcessing = 1; if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"lower", sizeof("lower") - 1)) { caseconv = tplCaseConvLower; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"upper", sizeof("upper") - 1)) { caseconv = tplCaseConvUpper; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid caseconversion type '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblkProperty.descr[i].name, "compressspace")) { bComplexProcessing = 1; bCompressSP = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "date.inutc")) { bDateInUTC = pvals[i].val.d.n; } else if (!strcmp(pblkProperty.descr[i].name, "dateformat")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"mysql", sizeof("mysql") - 1)) { datefmt = tplFmtMySQLDate; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"pgsql", sizeof("pgsql") - 1)) { datefmt = tplFmtPgSQLDate; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"rfc3164", sizeof("rfc3164") - 1)) { datefmt = tplFmtRFC3164Date; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"rfc3164-buggyday", sizeof("rfc3164-buggyday") - 1)) { datefmt = tplFmtRFC3164BuggyDate; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"rfc3339", sizeof("rfc3339") - 1)) { datefmt = tplFmtRFC3339Date; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"unixtimestamp", sizeof("unixtimestamp") - 1)) { datefmt = tplFmtUnixDate; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"subseconds", sizeof("subseconds") - 1)) { datefmt = tplFmtSecFrac; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"wdayname", sizeof("wdayname") - 1)) { datefmt = tplFmtWDayName; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"wday", sizeof("wday") - 1)) { datefmt = tplFmtWDay; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"year", sizeof("year") - 1)) { datefmt = tplFmtYear; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"month", sizeof("month") - 1)) { datefmt = tplFmtMonth; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"day", sizeof("day") - 1)) { datefmt = tplFmtDay; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"hour", sizeof("hour") - 1)) { datefmt = tplFmtHour; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"minute", sizeof("minute") - 1)) { datefmt = tplFmtMinute; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"second", sizeof("second") - 1)) { datefmt = tplFmtSecond; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"tzoffshour", sizeof("tzoffshour") - 1)) { datefmt = tplFmtTZOffsHour; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"tzoffsmin", sizeof("tzoffsmin") - 1)) { datefmt = tplFmtTZOffsMin; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"tzoffsdirection", sizeof("tzoffsdirection") - 1)) { datefmt = tplFmtTZOffsDirection; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"ordinal", sizeof("ordinal") - 1)) { datefmt = tplFmtOrdinal; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"week", sizeof("week") - 1)) { datefmt = tplFmtWeek; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid date format '%s' for property", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else { dbgprintf( "template:propertyTpe: program error, non-handled " "param '%s'\n", pblkProperty.descr[i].name); } } if (name == NULL) { CHKmalloc(name = (uchar *)strdup("")); } if (outname == NULL) { /* we need to drop "$!" prefix, if present */ if (ustrlen(name) >= 2 && !strncmp((char *)name, "$!", 2)) outname = ustrdup(name + 2); else outname = ustrdup(name); } /* sanity check */ if (topos_set == 0 && frompos != -1) topos = 2000000000; /* large enough ;) */ if (frompos == -1 && topos_set != 0) frompos = 0; if (bPosRelativeToEnd) { if (topos > frompos) { LogError(0, RS_RET_ERR, "position.to=%d is higher than postion.from=%d " "in 'relativeToEnd' mode\n", topos, frompos); ABORT_FINALIZE(RS_RET_ERR); } } else { if ((topos >= 0) && (topos < frompos)) { LogError(0, RS_RET_ERR, "position.to=%d is lower than postion.from=%d\n", topos, frompos); ABORT_FINALIZE(RS_RET_ERR); } } if (fieldnum != -1 && re_expr != NULL) { LogError(0, RS_RET_ERR, "both field extraction and regex extraction " "specified - this is not possible, remove one"); ABORT_FINALIZE(RS_RET_ERR); } /* apply */ CHKmalloc(pTpe = tpeConstruct(pTpl)); pTpe->eEntryType = FIELD; CHKiRet(msgPropDescrFill(&pTpe->data.field.msgProp, name, strlen((char *)name))); pTpe->data.field.options.bDropLastLF = droplastlf; pTpe->data.field.options.bSPIffNo1stSP = spifno1stsp; pTpe->data.field.options.bMandatory = mandatory; pTpe->data.field.options.bFixedWidth = fixedwidth; pTpe->data.field.options.dataType = dataType; pTpe->data.field.options.onEmpty = onEmpty; pTpe->data.field.eCaseConv = caseconv; switch (formatType) { case F_NONE: /* all set ;) */ break; case F_CSV: pTpe->data.field.options.bCSV = 1; break; case F_JSON: pTpe->data.field.options.bJSON = 1; break; case F_JSONF: pTpe->data.field.options.bJSONf = 1; break; case F_JSONR: pTpe->data.field.options.bJSONr = 1; break; case F_JSONFR: pTpe->data.field.options.bJSONfr = 1; break; default: // No action needed for other cases break; } switch (controlchr) { case CC_NONE: /* all set ;) */ break; case CC_ESCAPE: pTpe->data.field.options.bEscapeCC = 1; break; case CC_SPACE: pTpe->data.field.options.bSpaceCC = 1; break; case CC_DROP: pTpe->data.field.options.bDropCC = 1; break; default: // No action needed for other cases break; } switch (secpath) { case SP_NONE: /* all set ;) */ break; case SP_DROP: pTpe->data.field.options.bSecPathDrop = 1; break; case SP_REPLACE: pTpe->data.field.options.bSecPathReplace = 1; break; default: // No action needed for other cases break; } pTpe->fieldName = outname; if (outname != NULL) pTpe->lenFieldName = ustrlen(outname); outname = NULL; pTpe->bComplexProcessing = bComplexProcessing; pTpe->data.field.eDateFormat = datefmt; pTpe->data.field.options.bDateInUTC = bDateInUTC; pTpe->data.field.options.bCompressSP = bCompressSP; if (fieldnum != -1) { pTpe->data.field.has_fields = 1; pTpe->data.field.iFieldNr = fieldnum; pTpe->data.field.field_delim = fielddelim; } if (frompos != -1) { pTpe->data.field.iFromPos = frompos; pTpe->data.field.iToPos = topos; pTpe->data.field.options.bFromPosEndRelative = bPosRelativeToEnd; } if (re_expr != NULL) { rsRetVal iRetLocal; pTpe->data.field.typeRegex = re_type; pTpe->data.field.nomatchAction = re_nomatchType; pTpe->data.field.iMatchToUse = re_matchToUse; pTpe->data.field.iSubMatchToUse = re_submatchToUse; pTpe->data.field.has_regex = 1; if ((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) { int iOptions; iOptions = (pTpe->data.field.typeRegex == TPL_REGEX_ERE) ? REG_EXTENDED : 0; if (regexp.regcomp(&(pTpe->data.field.re), (char *)re_expr, iOptions) != 0) { LogError(0, NO_ERRCODE, "error compiling regex '%s'", re_expr); pTpe->data.field.has_regex = 2; ABORT_FINALIZE(RS_RET_ERR); } } else { /* regexp object could not be loaded */ if (bFirstRegexpErrmsg) { /* prevent flood of messages, maybe even an endless loop! */ bFirstRegexpErrmsg = 0; LogError(0, NO_ERRCODE, "regexp library could not be loaded (error %d), " "regexp ignored", iRetLocal); } pTpe->data.field.has_regex = 2; ABORT_FINALIZE(RS_RET_ERR); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &pblkProperty); free(name); free(outname); RETiRet; } /* create a template in list mode, is build from sub-objects */ static rsRetVal createListTpl(struct template *pTpl, struct cnfobj *o) { struct objlst *lst; DEFiRet; dbgprintf("create template from subobjs\n"); objlstPrint(o->subobjs); for (lst = o->subobjs; lst != NULL; lst = lst->next) { switch (lst->obj->objType) { case CNFOBJ_PROPERTY: CHKiRet(createPropertyTpe(pTpl, lst->obj)); break; case CNFOBJ_CONSTANT: CHKiRet(createConstantTpe(pTpl, lst->obj)); break; default: dbgprintf( "program error: invalid object type %d " "in createLstTpl\n", lst->obj->objType); break; } nvlstChkUnused(lst->obj->nvlst); } finalize_it: RETiRet; } /* Add a new template via the v6 config system. */ rsRetVal ATTR_NONNULL() tplProcessCnf(struct cnfobj *o) { struct template *pTpl = NULL; struct cnfparamvals *pvals = NULL; int lenName = 0; /* init just to keep compiler happy: mandatory parameter */ char *name = NULL; uchar *tplStr = NULL; uchar *plugin = NULL; uchar *p; msgPropDescr_t subtree; sbool bHaveSubtree = 0; enum { T_STRING, T_PLUGIN, T_LIST, T_SUBTREE } tplType = T_STRING; /* init just to keep compiler happy: mandatory parameter */ int i; int o_sql = 0, o_stdsql = 0, o_jsonf = 0, o_jsonftree = 0, o_json = 0, o_casesensitive = 0; /* options */ int numopts; rsRetVal localRet; DEFiRet; pvals = nvlstGetParams(o->nvlst, &pblk, NULL); if (pvals == NULL) { parser_errmsg("error processing template config parameters"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } cnfparamsPrint(&pblk, pvals); for (i = 0; i < pblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblk.descr[i].name, "name")) { lenName = es_strlen(pvals[i].val.d.estr); name = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "type")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"string", sizeof("string") - 1)) { tplType = T_STRING; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"plugin", sizeof("plugin") - 1)) { tplType = T_PLUGIN; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"list", sizeof("list") - 1)) { tplType = T_LIST; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"subtree", sizeof("subtree") - 1)) { tplType = T_SUBTREE; } else { uchar *typeStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid template type '%s'", typeStr); free(typeStr); ABORT_FINALIZE(RS_RET_ERR); } } else if (!strcmp(pblk.descr[i].name, "string")) { tplStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "subtree")) { uchar *st_str = es_getBufAddr(pvals[i].val.d.estr); if (st_str[0] != '$' || st_str[1] != '!') { char *cstr = es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_ERR, "invalid subtree " "parameter, variable must start with '$!' but " "var name is '%s'", cstr); free(cstr); free(name); /* overall assigned */ ABORT_FINALIZE(RS_RET_ERR); } else { uchar *cstr; cstr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); CHKiRet(msgPropDescrFill(&subtree, cstr, ustrlen(cstr))); free(cstr); bHaveSubtree = 1; } } else if (!strcmp(pblk.descr[i].name, "plugin")) { plugin = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "option.stdsql")) { o_stdsql = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "option.sql")) { o_sql = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "option.json")) { o_json = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "option.jsonf")) { o_jsonf = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "option.jsonftree")) { o_jsonftree = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "option.casesensitive")) { o_casesensitive = pvals[i].val.d.n; } else { dbgprintf( "template: program error, non-handled " "param '%s'\n", pblk.descr[i].name); } } /* the following check is just for clang static anaylzer: this condition * cannot occur if all is setup well, because "name" is a required parameter * inside the param block and so the code should err out above. */ if (name == NULL) { DBGPRINTF("template/tplProcessConf: logic error name == NULL - pblk wrong?\n"); ABORT_FINALIZE(RS_RET_ERR); } /* do config sanity checks */ if (tplStr == NULL) { if (tplType == T_STRING) { LogError(0, RS_RET_ERR, "template '%s' of type string needs " "string parameter", name); ABORT_FINALIZE(RS_RET_ERR); } } else { if (tplType != T_STRING) { LogError(0, RS_RET_ERR, "template '%s' is not a string " "template but has a string specified - ignored", name); } } if (plugin == NULL) { if (tplType == T_PLUGIN) { LogError(0, RS_RET_ERR, "template '%s' of type plugin needs " "plugin parameter", name); ABORT_FINALIZE(RS_RET_ERR); } } else { if (tplType != T_PLUGIN) { LogError(0, RS_RET_ERR, "template '%s' is not a plugin " "template but has a plugin specified - ignored", name); } } if (!bHaveSubtree) { if (tplType == T_SUBTREE) { LogError(0, RS_RET_ERR, "template '%s' of type subtree needs " "subtree parameter", name); ABORT_FINALIZE(RS_RET_ERR); } } else { if (tplType != T_SUBTREE) { LogError(0, RS_RET_ERR, "template '%s' is not a subtree " "template but has a subtree specified - ignored", name); } } if (o->subobjs == NULL) { if (tplType == T_LIST) { LogError(0, RS_RET_ERR, "template '%s' of type list has " "no parameters specified", name); ABORT_FINALIZE(RS_RET_ERR); } } else { if (tplType != T_LIST) { LogError(0, RS_RET_ERR, "template '%s' is not a list " "template but has parameters specified - ignored", name); } } numopts = 0; if (o_sql) ++numopts; if (o_stdsql) ++numopts; if (o_json) ++numopts; if (o_jsonf) ++numopts; if (o_jsonftree) ++numopts; if (numopts > 1) { LogError(0, RS_RET_ERR, "template '%s' has multiple incompatible " "options of sql, stdsql, json, jsonf or jsonftree specified", name); ABORT_FINALIZE(RS_RET_ERR); } /* config ok */ if ((pTpl = tplConstruct(loadConf)) == NULL) { DBGPRINTF("template.c: tplConstruct failed!\n"); ABORT_FINALIZE(RS_RET_ERR); } pTpl->pszName = name; pTpl->iLenName = lenName; switch (tplType) { case T_STRING: p = tplStr; while (*p) { switch (*p) { case '%': /* parameter */ ++p; /* eat '%' */ CHKiRet(do_Parameter(&p, pTpl)); break; default: /* constant */ do_Constant(&p, pTpl, 0); break; } } break; case T_PLUGIN: p = plugin; /* TODO: the use of tplAddTplMod() can be improved! */ localRet = tplAddTplMod(pTpl, &p); if (localRet != RS_RET_OK) { LogError(0, localRet, "template '%s': error %d " "defining template via plugin (strgen) module", pTpl->pszName, localRet); ABORT_FINALIZE(localRet); } break; case T_LIST: createListTpl(pTpl, o); break; case T_SUBTREE: memcpy(&pTpl->subtree, &subtree, sizeof(msgPropDescr_t)); pTpl->bHaveSubtree = 1; break; default: // No action needed for other cases break; } pTpl->optFormatEscape = NO_ESCAPE; if (o_stdsql) pTpl->optFormatEscape = STDSQL_ESCAPE; else if (o_sql) pTpl->optFormatEscape = SQL_ESCAPE; else if (o_json) pTpl->optFormatEscape = JSON_ESCAPE; else if (o_jsonf || o_jsonftree) pTpl->optFormatEscape = JSONF; if (o_jsonftree) pTpl->bJsonTreeEnabled = 1; if (o_casesensitive) pTpl->optCaseSensitive = 1; apply_case_sensitivity(pTpl); if (pTpl->optFormatEscape == JSONF) tplWarnDuplicateJsonKeys(pTpl); finalize_it: free(tplStr); free(plugin); if (pvals != NULL) cnfparamvalsDestruct(pvals, &pblk); if (iRet != RS_RET_OK) { if (pTpl != NULL) { /* we simply make the template defunct in this case by setting * its name to a zero-string. We do not free it, as this would * require additional code and causes only a very small memory * consumption. TODO: maybe in next iteration... */ *pTpl->pszName = '\0'; } } RETiRet; } /* Find a template object based on name. Search * currently is case-sensitive (should we change?). * returns pointer to template object if found and * NULL otherwise. * rgerhards 2004-11-17 */ struct template *tplFind(rsconf_t *conf, char *pName, int iLenName) { struct template *pTpl; assert(pName != NULL); pTpl = conf->templates.root; while (pTpl != NULL && !(pTpl->iLenName == iLenName && !strcmp(pTpl->pszName, pName))) { pTpl = pTpl->pNext; } return (pTpl); } /* Destroy the template structure. This is for de-initialization * at program end. Everything is deleted. * rgerhards 2005-02-22 * I have commented out dbgprintfs, because they are not needed for * "normal" debugging. Uncomment them, if they are needed. * rgerhards, 2007-07-05 */ void tplDeleteAll(rsconf_t *conf) { struct template *pTpl, *pTplDel; struct templateEntry *pTpe, *pTpeDel; pTpl = conf->templates.root; while (pTpl != NULL) { pTpe = pTpl->pEntryRoot; while (pTpe != NULL) { pTpeDel = pTpe; pTpe = pTpe->pNext; switch (pTpeDel->eEntryType) { case UNDEFINED: break; case CONSTANT: free(pTpeDel->data.constant.pConstant); break; case FIELD: /* check if we have a regexp and, if so, delete it */ #ifdef FEATURE_REGEXP if (pTpeDel->data.field.has_regex != 0) { if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { regexp.regfree(&(pTpeDel->data.field.re)); } } #endif msgPropDescrDestruct(&pTpeDel->data.field.msgProp); break; default: // No action needed for other cases break; } free(pTpeDel->fieldName); free(pTpeDel); } pTplDel = pTpl; pTpl = pTpl->pNext; free(pTplDel->pszName); if (pTplDel->bHaveSubtree) msgPropDescrDestruct(&pTplDel->subtree); tplJsonNodeFree(pTplDel->pJsonRoot); free(pTplDel); } } /* Destroy all templates obtained from conf file * preserving hardcoded ones. This is called from init(). */ void tplDeleteNew(rsconf_t *conf) { struct template *pTpl, *pTplDel; struct templateEntry *pTpe, *pTpeDel; if (conf->templates.root == NULL || conf->templates.lastStatic == NULL) return; pTpl = conf->templates.lastStatic->pNext; conf->templates.lastStatic->pNext = NULL; conf->templates.last = conf->templates.lastStatic; while (pTpl != NULL) { pTpe = pTpl->pEntryRoot; while (pTpe != NULL) { pTpeDel = pTpe; pTpe = pTpe->pNext; switch (pTpeDel->eEntryType) { case UNDEFINED: break; case CONSTANT: free(pTpeDel->data.constant.pConstant); break; case FIELD: #ifdef FEATURE_REGEXP /* check if we have a regexp and, if so, delete it */ if (pTpeDel->data.field.has_regex != 0) { if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { regexp.regfree(&(pTpeDel->data.field.re)); } } #endif msgPropDescrDestruct(&pTpeDel->data.field.msgProp); break; default: // No action needed for other cases break; } free(pTpeDel); } pTplDel = pTpl; pTpl = pTpl->pNext; free(pTplDel->pszName); if (pTplDel->bHaveSubtree) msgPropDescrDestruct(&pTplDel->subtree); tplJsonNodeFree(pTplDel->pJsonRoot); free(pTplDel); } } /* Store the pointer to the last hardcoded template */ void tplLastStaticInit(rsconf_t *conf, struct template *tpl) { conf->templates.lastStatic = tpl; } /* Print the template structure. This is more or less a * debug or test aid, but anyhow I think it's worth it... */ void tplPrintList(rsconf_t *conf) { struct template *pTpl; struct templateEntry *pTpe; pTpl = conf->templates.root; while (pTpl != NULL) { dbgprintf("Template: Name='%s' ", pTpl->pszName == NULL ? "NULL" : pTpl->pszName); if (pTpl->optFormatEscape == SQL_ESCAPE) dbgprintf("[SQL-Format (MySQL)] "); else if (pTpl->optFormatEscape == JSON_ESCAPE) dbgprintf("[JSON-Escaped Format] "); else if (pTpl->optFormatEscape == STDSQL_ESCAPE) dbgprintf("[SQL-Format (standard SQL)] "); else if (pTpl->optFormatEscape == JSONF) dbgprintf("[JSON fields] "); if (pTpl->optCaseSensitive) dbgprintf("[Case Sensitive Vars] "); dbgprintf("\n"); pTpe = pTpl->pEntryRoot; while (pTpe != NULL) { dbgprintf("\tEntry(%lx): type %d, ", (unsigned long)pTpe, pTpe->eEntryType); switch (pTpe->eEntryType) { case UNDEFINED: dbgprintf("(UNDEFINED)"); break; case CONSTANT: dbgprintf("(CONSTANT), value: '%s'", pTpe->data.constant.pConstant); break; case FIELD: dbgprintf("(FIELD), value: '%d' ", pTpe->data.field.msgProp.id); if (pTpe->data.field.msgProp.id == PROP_CEE) { dbgprintf("[EE-Property: '%s'] ", pTpe->data.field.msgProp.name); } else if (pTpe->data.field.msgProp.id == PROP_LOCAL_VAR) { dbgprintf("[Local Var: '%s'] ", pTpe->data.field.msgProp.name); } switch (pTpe->data.field.eDateFormat) { case tplFmtDefault: break; case tplFmtMySQLDate: dbgprintf("[Format as MySQL-Date] "); break; case tplFmtPgSQLDate: dbgprintf("[Format as PgSQL-Date] "); break; case tplFmtRFC3164Date: dbgprintf("[Format as RFC3164-Date] "); break; case tplFmtRFC3339Date: dbgprintf("[Format as RFC3339-Date] "); break; case tplFmtUnixDate: dbgprintf("[Format as Unix timestamp] "); break; case tplFmtSecFrac: dbgprintf("[fractional seconds, only] "); break; case tplFmtRFC3164BuggyDate: dbgprintf("[Format as buggy RFC3164-Date] "); break; case tplFmtWDayName: dbgprintf("[Format as weekday name] "); break; case tplFmtYear: dbgprintf("[Format as year] "); break; case tplFmtMonth: dbgprintf("[Format as month] "); break; case tplFmtDay: dbgprintf("[Format as day] "); break; case tplFmtHour: dbgprintf("[Format as hour] "); break; case tplFmtMinute: dbgprintf("[Format as minute] "); break; case tplFmtSecond: dbgprintf("[Format as second] "); break; case tplFmtTZOffsHour: dbgprintf("[Format as offset hour] "); break; case tplFmtTZOffsMin: dbgprintf("[Format as offset minute] "); break; case tplFmtTZOffsDirection: dbgprintf("[Format as offset direction] "); break; case tplFmtWDay: dbgprintf("[Format as weekday] "); break; case tplFmtOrdinal: dbgprintf("[Format as ordinal] "); break; case tplFmtWeek: dbgprintf("[Format as week] "); break; default: dbgprintf("[UNKNOWN eDateFormat %d] ", pTpe->data.field.eDateFormat); } switch (pTpe->data.field.eCaseConv) { case tplCaseConvNo: break; case tplCaseConvLower: dbgprintf("[Converted to Lower Case] "); break; case tplCaseConvUpper: dbgprintf("[Converted to Upper Case] "); break; default: // No action needed for other cases break; } if (pTpe->data.field.options.bEscapeCC) { dbgprintf("[escape control-characters] "); } if (pTpe->data.field.options.bDropCC) { dbgprintf("[drop control-characters] "); } if (pTpe->data.field.options.bSpaceCC) { dbgprintf("[replace control-characters with space] "); } if (pTpe->data.field.options.bSecPathDrop) { dbgprintf("[slashes are dropped] "); } if (pTpe->data.field.options.bSecPathReplace) { dbgprintf("[slashes are replaced by '_'] "); } if (pTpe->data.field.options.bSPIffNo1stSP) { dbgprintf("[SP iff no first SP] "); } if (pTpe->data.field.options.bCSV) { dbgprintf("[format as CSV (RFC4180)]"); } if (pTpe->data.field.options.bJSON) { dbgprintf("[format as JSON] "); } if (pTpe->data.field.options.bJSONf) { dbgprintf("[format as JSON field] "); } if (pTpe->data.field.options.bJSONr) { dbgprintf("[format as JSON without re-escaping] "); } if (pTpe->data.field.options.bJSONfr) { dbgprintf("[format as JSON field without re-escaping] "); } if (pTpe->data.field.options.bMandatory) { dbgprintf("[mandatory field] "); } if (pTpe->data.field.options.bDropLastLF) { dbgprintf("[drop last LF in msg] "); } if (pTpe->data.field.has_fields == 1) { dbgprintf("[substring, field #%d only (delimiter %d)] ", pTpe->data.field.iFieldNr, pTpe->data.field.field_delim); } if (pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) { dbgprintf("[substring, from character %d to %d] ", pTpe->data.field.iFromPos, pTpe->data.field.iToPos); } break; default: // No action needed for other cases break; } if (pTpe->bComplexProcessing) dbgprintf("[COMPLEX]"); dbgprintf("\n"); pTpe = pTpe->pNext; } pTpl = pTpl->pNext; /* done, go next */ } } int tplGetEntryCount(struct template *pTpl) { assert(pTpl != NULL); return (pTpl->tpenElements); } rsRetVal templateInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(strgen, CORE_COMPONENT)); finalize_it: RETiRet; } rsyslog-8.2512.0/PaxHeaders/outchannel.h0000644000000000000000000000013115055605325015047 xustar0030 mtime=1756826325.634800457 30 atime=1764930981.682706017 29 ctime=1764935923.31157854 rsyslog-8.2512.0/outchannel.h0000664000175000017500000000237315055605325014521 0ustar00rgerrger/* This is the header for the output channel code of rsyslog. * begun 2005-06-21 rgerhards * * Copyright(C) 2005-2012 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OUTCHANNEL_H #define OUTCHANNEL_H struct outchannel { struct outchannel *pNext; char *pszName; int iLenName; uchar *pszFileTemplate; off_t uSizeLimit; uchar *cmdOnSizeLimit; }; struct outchannel *ochConstruct(void); struct outchannel *ochAddLine(char *pName, unsigned char **pRestOfConfLine); struct outchannel *ochFind(char *pName, int iLenName); void ochDeleteAll(void); void ochPrintList(rsconf_t *cnf); #endif /* #ifdef OUTCHANNEL_H */ rsyslog-8.2512.0/PaxHeaders/COPYING.ASL200000644000000000000000000000013115035412264014345 xustar0029 mtime=1752569012.32130663 30 atime=1764931121.672006417 30 ctime=1764935920.449534723 rsyslog-8.2512.0/COPYING.ASL200000664000175000017500000002166115035412264014020 0ustar00rgerrgerApache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. rsyslog-8.2512.0/PaxHeaders/missing0000644000000000000000000000013215114544315014130 xustar0030 mtime=1764935885.475999122 30 atime=1764935889.345058387 30 ctime=1764935920.429534417 rsyslog-8.2512.0/missing0000755000175000017500000001533615114544315013605 0ustar00rgerrger#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: rsyslog-8.2512.0/PaxHeaders/action.h0000644000000000000000000000013215073421710014157 xustar0030 mtime=1760437192.757710634 30 atime=1764930980.032678423 30 ctime=1764935923.282578096 rsyslog-8.2512.0/action.h0000664000175000017500000001650615073421710013633 0ustar00rgerrger/* action.h * Header file for the action object * * File begun on 2007-08-06 by RGerhards (extracted from syslogd.c, which * was under BSD license at the time of rsyslog fork) * * Copyright 2007-2018 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file action.h * @brief Public API for output actions. * * Actions represent configured output destinations. Each action may run * via its own queue or directly from a worker thread. When supported by * the output module, actions treat a batch of messages as a transaction * and coordinate commits via this interface. These are not strict * database-style transactions; a rollback may not be possible and * message delivery follows an "at least once" principle. */ #ifndef ACTION_H_INCLUDED #define ACTION_H_INCLUDED 1 #include "syslogd-types.h" #include "queue.h" /* external data */ extern int glbliActionResumeRetryCount; /** * @struct action_s * @brief Runtime representation of an output action. * * Holds configuration and runtime state for a single action. * * Actions may be processed by multiple worker threads. The primary * mutex @c mutAction serializes state changes such as suspension and * resume handling. When the associated output module supports * transactions, the fields in this structure track in-flight batches * and commit status. These transactions are best-effort batches; on * failure only partial rollback may be possible, so delivery is * guaranteed at least once. */ struct action_s { time_t f_time; /* used for "max. n messages in m seconds" processing */ time_t tActNow; /* the current time for an action execution. Initially set to -1 and populated on an as-needed basis. This is a performance optimization. */ time_t tLastExec; /* time this action was last executed */ int iActionNbr; /* this action's number (ID) */ sbool bExecWhenPrevSusp; /* execute only when previous action is suspended? */ sbool bWriteAllMarkMsgs; /* should all mark msgs be written (not matter how recent the action was executed)? */ sbool bReportSuspension; /* should suspension (and reactivation) of the action reported */ sbool bReportSuspensionCont; sbool bDisabled; sbool isTransactional; sbool bCopyMsg; int iSecsExecOnceInterval; /* if non-zero, minimum seconds to wait until action is executed again */ time_t ttResumeRtry; /* when is it time to retry the resume? */ int iResumeInterval; /* resume interval for this action */ int iResumeIntervalMax; /* maximum resume interval for this action --> -1: unbounded */ int iResumeRetryCount; /* how often shall we retry a suspended action? (-1 --> eternal) */ int iNbrNoExec; /* number of matches that did not yet yield to an exec */ int iExecEveryNthOccur; /* execute this action only every n-th occurrence (with n=0,1 -> always) */ int iExecEveryNthOccurTO; /* timeout for n-th occurrence feature */ time_t tLastOccur; /* time last occurrence was seen (for timing them out) */ struct modInfo_s *pMod; /* pointer to output module handling this selector */ void *pModData; /* pointer to module data - content is module-specific */ sbool bRepMsgHasMsg; /* "message repeated..." has msg fragment in it (0-no, 1-yes) */ rsRetVal (*submitToActQ)(action_t *, wti_t *, smsg_t *); /* function submit message to action queue */ rsRetVal (*qConstruct)(struct queue_s *pThis); sbool bUsesMsgPassingMode; sbool bNeedReleaseBatch; /* do we need to release batch ressources? Depends on ParamPassig modes... */ int iNumTpls; /* number of array entries for template element below */ struct template **ppTpl; /* array of template to use - strings must be passed to doAction * in this order. */ paramPassing_t *peParamPassing; /* mode of parameter passing to action for that template */ qqueue_t *pQueue; /* action queue */ pthread_mutex_t mutAction; /* primary action mutex */ uchar *pszName; /* action name */ DEF_ATOMIC_HELPER_MUT(mutCAS); /* error file */ const char *pszErrFile; int fdErrFile; size_t maxErrFileSize; size_t currentErrFileSize; pthread_mutex_t mutErrFile; /* external stat file system */ const char *pszExternalStateFile; /* for per-worker HUP processing */ pthread_mutex_t mutWrkrDataTable; /* protects table structures */ void **wrkrDataTable; int wrkrDataTableSize; int nWrkr; /* for statistics subsystem */ statsobj_t *statsobj; STATSCOUNTER_DEF(ctrProcessed, mutCtrProcessed) STATSCOUNTER_DEF(ctrFail, mutCtrFail) STATSCOUNTER_DEF(ctrSuspend, mutCtrSuspend) STATSCOUNTER_DEF(ctrSuspendDuration, mutCtrSuspendDuration) STATSCOUNTER_DEF(ctrResume, mutCtrResume) }; /* function prototypes */ /** Create a new action instance. */ rsRetVal actionConstruct(action_t **ppThis); /** Finalize initialization after configuration parameters were applied. */ rsRetVal actionConstructFinalize(action_t *pThis, struct nvlst *lst); /** Destroy an action instance and free all associated resources. */ rsRetVal actionDestruct(action_t *pThis); /** Set the global default resume interval for actions. */ rsRetVal actionSetGlobalResumeInterval(int iNewVal); /** * Execute an action outside of a queue context. * Primarily used for historic modules that expect this style. */ rsRetVal actionDoAction(action_t *pAction); /** Enqueue a message for processing by an action. */ rsRetVal actionWriteToAction(action_t *pAction, smsg_t *pMsg, wti_t *); /** Trigger the HUP handler of an action if provided by the module. */ rsRetVal actionCallHUPHdlr(action_t *pAction); /** Initialize global resources used by the action subsystem. */ rsRetVal actionClassInit(void); /** * Register a configured action with the ruleset. * The action instance becomes owned by the configuration once added. */ rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, struct cnfparamvals *actParams, struct nvlst *lst); /** Start the message queues of all configured actions. */ rsRetVal activateActions(void); /** Create a new action from configuration parameters. */ rsRetVal actionNewInst(struct nvlst *lst, action_t **ppAction); rsRetVal actionProcessCnf(struct cnfobj *o); /** Commit all outstanding transactions for direct queues. */ void actionCommitAllDirect(wti_t *pWti); /** Remove a worker instance from the action's bookkeeping. */ void actionRemoveWorker(action_t *const pAction, void *const actWrkrData); /** Release parameter memory allocated by prepareDoActionParams(). */ void releaseDoActionParams(action_t *const pAction, wti_t *const pWti, int action_destruct); #endif /* #ifndef ACTION_H_INCLUDED */ rsyslog-8.2512.0/PaxHeaders/devtools0000644000000000000000000000013215114544377014326 xustar0030 mtime=1764935935.131759485 30 atime=1764935935.209760679 30 ctime=1764935935.131759485 rsyslog-8.2512.0/devtools/0000775000175000017500000000000015114544377014047 5ustar00rgerrgerrsyslog-8.2512.0/devtools/PaxHeaders/prep-mysql-db.sh0000644000000000000000000000013115035412264017421 xustar0030 mtime=1752569012.332230196 29 atime=1764931168.74876404 30 ctime=1764935935.128759439 rsyslog-8.2512.0/devtools/prep-mysql-db.sh0000775000175000017500000000040115035412264017064 0ustar00rgerrger#!/bin/bash # this script prepares a mysql instance for use by the rsyslog testbench mysql -u root -e "CREATE USER 'rsyslog'@'localhost' IDENTIFIED BY 'testbench';" mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'rsyslog'@'localhost'; FLUSH PRIVILEGES;" rsyslog-8.2512.0/devtools/PaxHeaders/prepare_clickhouse.sh0000644000000000000000000000013215035412264020575 xustar0030 mtime=1752569012.332230196 30 atime=1764931168.757764184 30 ctime=1764935935.131759485 rsyslog-8.2512.0/devtools/prepare_clickhouse.sh0000775000175000017500000000120615035412264020243 0ustar00rgerrger#!/bin/bash # this script prepares a clickhouse instance for use by the rsyslog testbench clickhouse-client --query="CREATE DATABASE rsyslog" echo clickouse create database RETURN STATE: $? # At the moment only the database is created for preperation. # Every test creates a table for itself and drops it afterwards. # This could look something like this: #clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.test ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id" #clickhouse-client --query="DROP TABLE rsyslog.test" rsyslog-8.2512.0/PaxHeaders/COPYING.LESSER0000644000000000000000000000013115035412264014561 xustar0029 mtime=1752569012.32130663 30 atime=1764931121.522003991 30 ctime=1764935920.406534065 rsyslog-8.2512.0/COPYING.LESSER0000664000175000017500000001672715035412264014243 0ustar00rgerrger GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. rsyslog-8.2512.0/PaxHeaders/Makefile.am0000644000000000000000000000013215114537777014606 xustar0030 mtime=1764933631.748099674 30 atime=1764933653.805440279 30 ctime=1764935920.369533498 rsyslog-8.2512.0/Makefile.am0000664000175000017500000021773315114537777014267 0ustar00rgerrgersbin_PROGRAMS = pkglib_LTLIBRARIES = pkgconfigdir = $(libdir)/pkgconfig EXTRA_DIST = \ README.md \ platform/README \ platform/freebsd/rsyslogd \ platform/slackware/rc.rsyslogd \ platform/redhat/rsyslog.conf \ contrib/README \ CONTRIBUTING.md \ COPYING \ COPYING.LESSER \ COPYING.ASL20 \ contrib/gnutls/ca.pem \ contrib/gnutls/cert.pem \ contrib/gnutls/key.pem # doc files - actual enumration, "pickup script" did not work well. EXTRA_DIST += \ doc/.gitignore \ doc/.travis.yml \ doc/AGENTS.md \ doc/BUILDS_README.md \ doc/CONTRIBUTING.md \ doc/IMPLEMENTATION_PLAN.md \ doc/LICENSE \ doc/Makefile \ doc/README.md \ doc/STRATEGY.md \ doc/ai/README.md \ doc/ai/authoring_guidelines.md \ doc/ai/chunking_and_embeddings.md \ doc/ai/crosslinking_and_nav.md \ doc/ai/drift_monitoring.md \ doc/ai/mermaid_rules.md \ doc/ai/module_map.yaml \ doc/ai/structure_and_paths.md \ doc/ai/templates/template-concept.rst \ doc/ai/templates/template-tutorial.rst \ doc/ai/terminology.md \ doc/contrib/README.md \ doc/contrib/cron_build_all_branches.sh \ doc/proposed-toc \ doc/requirements.txt \ doc/source/_ext/edit_on_github.py \ doc/source/_ext/rsyslog_lexer.py \ doc/source/_static/rsyslog.css \ doc/source/_static/vendor/README.md \ doc/source/_static/vendor/d3/d3.min.js \ doc/source/_static/vendor/mermaid/mermaid-layout-elk.esm.min.mjs \ doc/source/_static/vendor/mermaid/mermaid-layout-elk.min.js \ doc/source/_static/vendor/mermaid/mermaid.esm.min.mjs \ doc/source/_static/vendor/mermaid/mermaid.min.js \ doc/source/_templates/sourcelink.html \ doc/source/_templates_minimal/README \ doc/source/_templates_minimal/footer.html \ doc/source/_templates_minimal/header.html \ doc/source/_templates_minimal/relbar.html \ doc/source/about/ai_first.rst \ doc/source/about/history.rst \ doc/source/about/index.rst \ doc/source/about/origins.rst \ doc/source/about/release_versioning.rst \ doc/source/community.rst \ doc/source/concepts/index.rst \ doc/source/concepts/janitor.rst \ doc/source/concepts/log_pipeline/design_patterns.rst \ doc/source/concepts/log_pipeline/example_json_transform.rst \ doc/source/concepts/log_pipeline/index.rst \ doc/source/concepts/log_pipeline/stages.rst \ doc/source/concepts/log_pipeline/troubleshooting.rst \ doc/source/concepts/messageparser.rst \ doc/source/concepts/multi_ruleset.rst \ doc/source/concepts/netstrm_drvr.rst \ doc/source/concepts/ns_gtls.rst \ doc/source/concepts/ns_mbedtls.rst \ doc/source/concepts/ns_ossl.rst \ doc/source/concepts/ns_ptcp.rst \ doc/source/concepts/queues.rst \ doc/source/concepts/rfc5424layers.png \ doc/source/conf.py \ doc/source/conf_helpers.py \ doc/source/configuration/action/index.rst \ doc/source/configuration/action/rsconf1_actionexeconlywhenpreviousissuspended.rst \ doc/source/configuration/action/rsconf1_actionresumeinterval.rst \ doc/source/configuration/action/rsconf1_dirgroup.rst \ doc/source/configuration/action/rsconf1_dirowner.rst \ doc/source/configuration/action/rsconf1_dynafilecachesize.rst \ doc/source/configuration/action/rsconf1_filecreatemode.rst \ doc/source/configuration/action/rsconf1_filegroup.rst \ doc/source/configuration/action/rsconf1_fileowner.rst \ doc/source/configuration/action/rsconf1_gssforwardservicename.rst \ doc/source/configuration/action/rsconf1_gssmode.rst \ doc/source/configuration/action/rsconf1_omfileforcechown.rst \ doc/source/configuration/action/rsconf1_repeatedmsgreduction.rst \ doc/source/configuration/actions.rst \ doc/source/configuration/basic_structure.rst \ doc/source/configuration/conf_formats.rst \ doc/source/configuration/config_param_types.rst \ doc/source/configuration/converting_to_new_format.rst \ doc/source/configuration/cryprov_gcry.rst \ doc/source/configuration/cryprov_ossl.rst \ doc/source/configuration/droppriv.rst \ doc/source/configuration/dyn_stats.rst \ doc/source/configuration/examples.rst \ doc/source/configuration/filters.rst \ doc/source/configuration/global/index.rst \ doc/source/configuration/global/options/rsconf1_abortonuncleanconfig.rst \ doc/source/configuration/global/options/rsconf1_debugprintcfsyslinehandlerlist.rst \ doc/source/configuration/global/options/rsconf1_debugprintmodulelist.rst \ doc/source/configuration/global/options/rsconf1_debugprinttemplatelist.rst \ doc/source/configuration/global/options/rsconf1_failonchownfailure.rst \ doc/source/configuration/global/options/rsconf1_generateconfiggraph.rst \ doc/source/configuration/global/options/rsconf1_includeconfig.rst \ doc/source/configuration/global/options/rsconf1_mainmsgqueuesize.rst \ doc/source/configuration/global/options/rsconf1_maxopenfiles.rst \ doc/source/configuration/global/options/rsconf1_moddir.rst \ doc/source/configuration/global/options/rsconf1_modload.rst \ doc/source/configuration/global/options/rsconf1_resetconfigvariables.rst \ doc/source/configuration/global/options/rsconf1_umask.rst \ doc/source/configuration/global/options/rsyslog_confgraph_complex.png \ doc/source/configuration/global/options/rsyslog_confgraph_std.png \ doc/source/configuration/index.rst \ doc/source/configuration/index_directives.rst \ doc/source/configuration/input.rst \ doc/source/configuration/input_directives/index.rst \ doc/source/configuration/input_directives/rsconf1_allowedsender.rst \ doc/source/configuration/input_directives/rsconf1_controlcharacterescapeprefix.rst \ doc/source/configuration/input_directives/rsconf1_dropmsgswithmaliciousdnsptrrecords.rst \ doc/source/configuration/input_directives/rsconf1_droptrailinglfonreception.rst \ doc/source/configuration/input_directives/rsconf1_escape8bitcharsonreceive.rst \ doc/source/configuration/input_directives/rsconf1_escapecontrolcharactersonreceive.rst \ doc/source/configuration/input_directives/rsconf1_markmessageperiod.rst \ doc/source/configuration/ipv6.rst \ doc/source/configuration/lookup_tables.rst \ doc/source/configuration/modules/gssapi.png \ doc/source/configuration/modules/idx_input.rst \ doc/source/configuration/modules/idx_library.rst \ doc/source/configuration/modules/idx_messagemod.rst \ doc/source/configuration/modules/idx_output.rst \ doc/source/configuration/modules/idx_parser.rst \ doc/source/configuration/modules/idx_stringgen.rst \ doc/source/configuration/modules/im3195.rst \ doc/source/configuration/modules/imbatchreport.rst \ doc/source/configuration/modules/imczmq.rst \ doc/source/configuration/modules/imdiag.rst \ doc/source/configuration/modules/imdocker.rst \ doc/source/configuration/modules/imdtls.rst \ doc/source/configuration/modules/imfile.rst \ doc/source/configuration/modules/imgssapi.rst \ doc/source/configuration/modules/imhiredis.rst \ doc/source/configuration/modules/imhttp.rst \ doc/source/configuration/modules/imjournal.rst \ doc/source/configuration/modules/imkafka.rst \ doc/source/configuration/modules/imklog.rst \ doc/source/configuration/modules/imkmsg.rst \ doc/source/configuration/modules/immark.rst \ doc/source/configuration/modules/impcap.rst \ doc/source/configuration/modules/improg.rst \ doc/source/configuration/modules/impstats.rst \ doc/source/configuration/modules/imptcp.rst \ doc/source/configuration/modules/imrelp.rst \ doc/source/configuration/modules/imsolaris.rst \ doc/source/configuration/modules/imtcp.rst \ doc/source/configuration/modules/imtuxedoulog.rst \ doc/source/configuration/modules/imudp.rst \ doc/source/configuration/modules/imuxsock.rst \ doc/source/configuration/modules/index.rst \ doc/source/configuration/modules/mmaitag.rst \ doc/source/configuration/modules/mmanon.rst \ doc/source/configuration/modules/mmaudit.rst \ doc/source/configuration/modules/mmcount.rst \ doc/source/configuration/modules/mmdarwin.rst \ doc/source/configuration/modules/mmdblookup.rst \ doc/source/configuration/modules/mmexternal.rst \ doc/source/configuration/modules/mmfields.rst \ doc/source/configuration/modules/mmjsonparse.rst \ doc/source/configuration/modules/mmjsonrewrite.rst \ doc/source/configuration/modules/mmjsontransform.rst \ doc/source/configuration/modules/mmkubernetes.rst \ doc/source/configuration/modules/mmleefparse.rst \ doc/source/configuration/modules/mmnormalize.rst \ doc/source/configuration/modules/mmpstrucdata.rst \ doc/source/configuration/modules/mmrfc5424addhmac.rst \ doc/source/configuration/modules/mmrm1stspace.rst \ doc/source/configuration/modules/mmsequence.rst \ doc/source/configuration/modules/mmsnareparse.rst \ doc/source/configuration/modules/mmsnmptrapd.rst \ doc/source/configuration/modules/mmtaghostname.rst \ doc/source/configuration/modules/mmutf8fix.rst \ doc/source/configuration/modules/module_workflow.png \ doc/source/configuration/modules/omamqp1.rst \ doc/source/configuration/modules/omazureeventhubs.rst \ doc/source/configuration/modules/omclickhouse.rst \ doc/source/configuration/modules/omczmq.rst \ doc/source/configuration/modules/omdtls.rst \ doc/source/configuration/modules/omelasticsearch.rst \ doc/source/configuration/modules/omfile.rst \ doc/source/configuration/modules/omfwd.rst \ doc/source/configuration/modules/omfwd/parameters/basic.rst \ doc/source/configuration/modules/omfwd/parameters/module.rst \ doc/source/configuration/modules/omgssapi.rst \ doc/source/configuration/modules/omhdfs.rst \ doc/source/configuration/modules/omhiredis.rst \ doc/source/configuration/modules/omhttp.rst \ doc/source/configuration/modules/omhttpfs.rst \ doc/source/configuration/modules/omjournal.rst \ doc/source/configuration/modules/omkafka.rst \ doc/source/configuration/modules/omlibdbi.rst \ doc/source/configuration/modules/ommail.rst \ doc/source/configuration/modules/ommongodb.rst \ doc/source/configuration/modules/ommysql.rst \ doc/source/configuration/modules/omoracle.rst \ doc/source/configuration/modules/ompgsql.rst \ doc/source/configuration/modules/ompipe.rst \ doc/source/configuration/modules/omprog.rst \ doc/source/configuration/modules/omrabbitmq.rst \ doc/source/configuration/modules/omrelp.rst \ doc/source/configuration/modules/omruleset.rst \ doc/source/configuration/modules/omsendertrack.rst \ doc/source/configuration/modules/omsnmp.rst \ doc/source/configuration/modules/omstdout.rst \ doc/source/configuration/modules/omudpspoof.rst \ doc/source/configuration/modules/omusrmsg.rst \ doc/source/configuration/modules/omuxsock.rst \ doc/source/configuration/modules/pmciscoios.rst \ doc/source/configuration/modules/pmdb2diag.rst \ doc/source/configuration/modules/pmlastmsg.rst \ doc/source/configuration/modules/pmnormalize.rst \ doc/source/configuration/modules/pmnull.rst \ doc/source/configuration/modules/pmrfc3164.rst \ doc/source/configuration/modules/pmrfc3164sd.rst \ doc/source/configuration/modules/pmrfc5424.rst \ doc/source/configuration/modules/sigprov_gt.rst \ doc/source/configuration/modules/sigprov_ksi.rst \ doc/source/configuration/modules/sigprov_ksi12.rst \ doc/source/configuration/modules/workflow.rst \ doc/source/configuration/nomatch.rst \ doc/source/configuration/output_channels.rst \ doc/source/configuration/parser.rst \ doc/source/configuration/percentile_stats.rst \ doc/source/configuration/properties.rst \ doc/source/configuration/property_replacer.rst \ doc/source/configuration/rsyslog-example.conf \ doc/source/configuration/rsyslog_statistic_counter.rst \ doc/source/configuration/ruleset/index.rst \ doc/source/configuration/ruleset/rsconf1_rulesetcreatemainqueue.rst \ doc/source/configuration/ruleset/rsconf1_rulesetparser.rst \ doc/source/configuration/sysklogd_format.rst \ doc/source/configuration/templates.rst \ doc/source/configuration/timezone.rst \ doc/source/containers/collector.rst \ doc/source/containers/development_images.rst \ doc/source/containers/dockerlogs.rst \ doc/source/containers/index.rst \ doc/source/containers/minimal.rst \ doc/source/containers/standard.rst \ doc/source/containers/user_images.rst \ doc/source/dataflow.png \ doc/source/development/coding_practices.rst \ doc/source/development/coding_practices/embedded_ipv4_tail_helper.rst \ doc/source/development/coding_practices/externalized_helper_contracts.rst \ doc/source/development/config_data_model.rst \ doc/source/development/debugging.rst \ doc/source/development/dev_action_threads.rst \ doc/source/development/dev_codestyle.rst \ doc/source/development/dev_oplugins.rst \ doc/source/development/dev_queue.rst \ doc/source/development/dev_testbench.rst \ doc/source/development/doc_reference_section_guidelines.rst \ doc/source/development/doc_style_guide.rst \ doc/source/development/engine_overview.rst \ doc/source/development/generic_design.rst \ doc/source/development/index.rst \ doc/source/development/internal_tooling.rst \ doc/source/development/queueWorkerLogic.jpg \ doc/source/direct_queue0.png \ doc/source/direct_queue1.png \ doc/source/direct_queue2.png \ doc/source/direct_queue3.png \ doc/source/direct_queue_directq.png \ doc/source/direct_queue_rsyslog.png \ doc/source/direct_queue_rsyslog2.png \ doc/source/faq/common-config-mistakes.rst \ doc/source/faq/difference_queues.rst \ doc/source/faq/does-rsyslog-run-under-windows.rst \ doc/source/faq/encrypt_mysql_traffic_ommysql.rst \ doc/source/faq/etl_tool.rst \ doc/source/faq/faq_overall.rst \ doc/source/faq/imtcp-tls-gibberish.rst \ doc/source/faq/imudp-packet-loss.rst \ doc/source/faq/index.rst \ doc/source/faq/vespa-ai-integration.rst \ doc/source/features.rst \ doc/source/getting_started/ai-assistants.rst \ doc/source/getting_started/basic_configuration.rst \ doc/source/getting_started/beginner_tutorials/01-installation.rst \ doc/source/getting_started/beginner_tutorials/02-first-config.rst \ doc/source/getting_started/beginner_tutorials/03-default-config.rst \ doc/source/getting_started/beginner_tutorials/04-message-pipeline.rst \ doc/source/getting_started/beginner_tutorials/05-order-matters.rst \ doc/source/getting_started/beginner_tutorials/06-remote-server.rst \ doc/source/getting_started/beginner_tutorials/index.rst \ doc/source/getting_started/forwarding_logs.rst \ doc/source/getting_started/index.rst \ doc/source/getting_started/installation.rst \ doc/source/getting_started/next_steps.rst \ doc/source/getting_started/understanding_default_config.rst \ doc/source/gssapi.png \ doc/source/historical/high_performance.rst \ doc/source/historical/index.rst \ doc/source/historical/module_devel.rst \ doc/source/historical/multi_ruleset_legacy_format_samples.rst \ doc/source/historical/php_syslog_ng.rst \ doc/source/historical/v3compatibility.rst \ doc/source/historical/v4compatibility.rst \ doc/source/historical/v5compatibility.rst \ doc/source/historical/v6compatibility.rst \ doc/source/historical/v7compatibility.rst \ doc/source/historical/v8compatibility.rst \ doc/source/history.rst \ doc/source/how2help.rst \ doc/source/idx_reference.rst \ doc/source/includes/container_dev_env.inc.rst \ doc/source/includes/footer.inc.rst \ doc/source/includes/substitution_definitions.inc.rst \ doc/source/index.rst \ doc/source/installation/build_from_repo.rst \ doc/source/installation/index.rst \ doc/source/installation/install_from_source.rst \ doc/source/installation/packages.rst \ doc/source/installation/rsyslog_docker.rst \ doc/source/licensing.rst \ doc/source/module_workflow.png \ doc/source/proposals/index.rst \ doc/source/queue_analogy_tv.png \ doc/source/rainerscript/configuration_objects.rst \ doc/source/rainerscript/constant_strings.rst \ doc/source/rainerscript/control_structures.rst \ doc/source/rainerscript/data_types.rst \ doc/source/rainerscript/expressions.rst \ doc/source/rainerscript/functions/idx_built-in_functions.rst \ doc/source/rainerscript/functions/idx_module_functions.rst \ doc/source/rainerscript/functions/index.rst \ doc/source/rainerscript/functions/mo-ffaup.rst \ doc/source/rainerscript/functions/mo-hashXX.rst \ doc/source/rainerscript/functions/mo-hashXXmod.rst \ doc/source/rainerscript/functions/mo-http_request.rst \ doc/source/rainerscript/functions/mo-unflatten.rst \ doc/source/rainerscript/functions/rs-cnum.rst \ doc/source/rainerscript/functions/rs-cstr.rst \ doc/source/rainerscript/functions/rs-dyn_inc.rst \ doc/source/rainerscript/functions/rs-exec_template.rst \ doc/source/rainerscript/functions/rs-exists.rst \ doc/source/rainerscript/functions/rs-field.rst \ doc/source/rainerscript/functions/rs-format_time.rst \ doc/source/rainerscript/functions/rs-get_property.rst \ doc/source/rainerscript/functions/rs-getenv.rst \ doc/source/rainerscript/functions/rs-int2hex.rst \ doc/source/rainerscript/functions/rs-ipv4convert.rst \ doc/source/rainerscript/functions/rs-is_time.rst \ doc/source/rainerscript/functions/rs-lookup.rst \ doc/source/rainerscript/functions/rs-parse_json.rst \ doc/source/rainerscript/functions/rs-parse_time.rst \ doc/source/rainerscript/functions/rs-percentile_observe.rst \ doc/source/rainerscript/functions/rs-previous_action_suspended.rst \ doc/source/rainerscript/functions/rs-prifilt.rst \ doc/source/rainerscript/functions/rs-random.rst \ doc/source/rainerscript/functions/rs-re_extract.rst \ doc/source/rainerscript/functions/rs-re_extract_i.rst \ doc/source/rainerscript/functions/rs-re_match.rst \ doc/source/rainerscript/functions/rs-re_match_i.rst \ doc/source/rainerscript/functions/rs-replace.rst \ doc/source/rainerscript/functions/rs-script_error.rst \ doc/source/rainerscript/functions/rs-strlen.rst \ doc/source/rainerscript/functions/rs-substring.rst \ doc/source/rainerscript/functions/rs-tolower.rst \ doc/source/rainerscript/functions/rs-toupper.rst \ doc/source/rainerscript/functions/rs-trim.rst \ doc/source/rainerscript/functions/rs-wrap.rst \ doc/source/rainerscript/global.rst \ doc/source/rainerscript/include.rst \ doc/source/rainerscript/index.rst \ doc/source/rainerscript/lookup_tables.rst \ doc/source/rainerscript/queue_parameters.rst \ doc/source/rainerscript/rainerscript_call.rst \ doc/source/rainerscript/rainerscript_call_indirect.rst \ doc/source/rainerscript/variable_property_types.rst \ doc/source/reference/parameters/im3195-input3195listenport.rst \ doc/source/reference/parameters/imdiag-aborttimeout.rst \ doc/source/reference/parameters/imdiag-injectdelaymode.rst \ doc/source/reference/parameters/imdiag-listenportfilename.rst \ doc/source/reference/parameters/imdiag-maxsessions.rst \ doc/source/reference/parameters/imdiag-serverinputname.rst \ doc/source/reference/parameters/imdiag-serverrun.rst \ doc/source/reference/parameters/imdiag-serverstreamdriverauthmode.rst \ doc/source/reference/parameters/imdiag-serverstreamdrivermode.rst \ doc/source/reference/parameters/imdiag-serverstreamdriverpermittedpeer.rst \ doc/source/reference/parameters/imdocker-apiversionstr.rst \ doc/source/reference/parameters/imdocker-defaultfacility.rst \ doc/source/reference/parameters/imdocker-defaultseverity.rst \ doc/source/reference/parameters/imdocker-dockerapiunixsockaddr.rst \ doc/source/reference/parameters/imdocker-escapelf.rst \ doc/source/reference/parameters/imdocker-getcontainerlogoptions.rst \ doc/source/reference/parameters/imdocker-listcontainersoptions.rst \ doc/source/reference/parameters/imdocker-pollinginterval.rst \ doc/source/reference/parameters/imdocker-retrievenewlogsfromstart.rst \ doc/source/reference/parameters/imdtls-address.rst \ doc/source/reference/parameters/imdtls-name.rst \ doc/source/reference/parameters/imdtls-port.rst \ doc/source/reference/parameters/imdtls-ruleset.rst \ doc/source/reference/parameters/imdtls-timeout.rst \ doc/source/reference/parameters/imdtls-tls-authmode.rst \ doc/source/reference/parameters/imdtls-tls-cacert.rst \ doc/source/reference/parameters/imdtls-tls-mycert.rst \ doc/source/reference/parameters/imdtls-tls-myprivkey.rst \ doc/source/reference/parameters/imdtls-tls-permittedpeer.rst \ doc/source/reference/parameters/imdtls-tls-tlscfgcmd.rst \ doc/source/reference/parameters/imfile-addceetag.rst \ doc/source/reference/parameters/imfile-addmetadata.rst \ doc/source/reference/parameters/imfile-deletestateonfiledelete.rst \ doc/source/reference/parameters/imfile-deletestateonfilemove.rst \ doc/source/reference/parameters/imfile-discardtruncatedmsg.rst \ doc/source/reference/parameters/imfile-endmsg-regex.rst \ doc/source/reference/parameters/imfile-escapelf-replacement.rst \ doc/source/reference/parameters/imfile-escapelf.rst \ doc/source/reference/parameters/imfile-facility.rst \ doc/source/reference/parameters/imfile-file.rst \ doc/source/reference/parameters/imfile-freshstarttail.rst \ doc/source/reference/parameters/imfile-ignoreolderthan.rst \ doc/source/reference/parameters/imfile-maxbytesperminute.rst \ doc/source/reference/parameters/imfile-maxlinesatonce.rst \ doc/source/reference/parameters/imfile-maxlinesperminute.rst \ doc/source/reference/parameters/imfile-maxsubmitatonce.rst \ doc/source/reference/parameters/imfile-mode.rst \ doc/source/reference/parameters/imfile-msgdiscardingerror.rst \ doc/source/reference/parameters/imfile-needparse.rst \ doc/source/reference/parameters/imfile-persiststateaftersubmission.rst \ doc/source/reference/parameters/imfile-persiststateinterval.rst \ doc/source/reference/parameters/imfile-pollinginterval.rst \ doc/source/reference/parameters/imfile-readmode.rst \ doc/source/reference/parameters/imfile-readtimeout.rst \ doc/source/reference/parameters/imfile-reopenontruncate.rst \ doc/source/reference/parameters/imfile-ruleset.rst \ doc/source/reference/parameters/imfile-severity.rst \ doc/source/reference/parameters/imfile-sortfiles.rst \ doc/source/reference/parameters/imfile-startmsg-regex.rst \ doc/source/reference/parameters/imfile-statefile-directory.rst \ doc/source/reference/parameters/imfile-statefile.rst \ doc/source/reference/parameters/imfile-tag.rst \ doc/source/reference/parameters/imfile-timeoutgranularity.rst \ doc/source/reference/parameters/imfile-trimlineoverbytes.rst \ doc/source/reference/parameters/imgssapi-inputgsslistenportfilename.rst \ doc/source/reference/parameters/imgssapi-inputgssserverkeepalive.rst \ doc/source/reference/parameters/imgssapi-inputgssservermaxsessions.rst \ doc/source/reference/parameters/imgssapi-inputgssserverpermitplaintcp.rst \ doc/source/reference/parameters/imgssapi-inputgssserverrun.rst \ doc/source/reference/parameters/imgssapi-inputgssserverservicename.rst \ doc/source/reference/parameters/imjournal-defaultfacility.rst \ doc/source/reference/parameters/imjournal-defaultseverity.rst \ doc/source/reference/parameters/imjournal-defaulttag.rst \ doc/source/reference/parameters/imjournal-filecreatemode.rst \ doc/source/reference/parameters/imjournal-fsync.rst \ doc/source/reference/parameters/imjournal-ignorenonvalidstatefile.rst \ doc/source/reference/parameters/imjournal-ignorepreviousmessages.rst \ doc/source/reference/parameters/imjournal-main.rst \ doc/source/reference/parameters/imjournal-persiststateinterval.rst \ doc/source/reference/parameters/imjournal-ratelimit-burst.rst \ doc/source/reference/parameters/imjournal-ratelimit-interval.rst \ doc/source/reference/parameters/imjournal-remote.rst \ doc/source/reference/parameters/imjournal-statefile.rst \ doc/source/reference/parameters/imjournal-usepid.rst \ doc/source/reference/parameters/imjournal-usepidfromsystem.rst \ doc/source/reference/parameters/imjournal-workaroundjournalbug.rst \ doc/source/reference/parameters/imkafka-broker.rst \ doc/source/reference/parameters/imkafka-confparam.rst \ doc/source/reference/parameters/imkafka-consumergroup.rst \ doc/source/reference/parameters/imkafka-parsehostname.rst \ doc/source/reference/parameters/imkafka-ruleset.rst \ doc/source/reference/parameters/imkafka-topic.rst \ doc/source/reference/parameters/imklog-consoleloglevel.rst \ doc/source/reference/parameters/imklog-internalmsgfacility.rst \ doc/source/reference/parameters/imklog-keepkerneltimestamp.rst \ doc/source/reference/parameters/imklog-logpath.rst \ doc/source/reference/parameters/imklog-parsekerneltimestamp.rst \ doc/source/reference/parameters/imklog-permitnonkernelfacility.rst \ doc/source/reference/parameters/imklog-ratelimitburst.rst \ doc/source/reference/parameters/imklog-ratelimitinterval.rst \ doc/source/reference/parameters/immark-interval.rst \ doc/source/reference/parameters/immark-markmessagetext.rst \ doc/source/reference/parameters/immark-ruleset.rst \ doc/source/reference/parameters/immark-use-markflag.rst \ doc/source/reference/parameters/immark-use-syslogcall.rst \ doc/source/reference/parameters/impstats-bracketing.rst \ doc/source/reference/parameters/impstats-facility.rst \ doc/source/reference/parameters/impstats-format.rst \ doc/source/reference/parameters/impstats-interval.rst \ doc/source/reference/parameters/impstats-log-file.rst \ doc/source/reference/parameters/impstats-log-syslog.rst \ doc/source/reference/parameters/impstats-resetcounters.rst \ doc/source/reference/parameters/impstats-ruleset.rst \ doc/source/reference/parameters/impstats-severity.rst \ doc/source/reference/parameters/imptcp-address.rst \ doc/source/reference/parameters/imptcp-addtlframedelimiter.rst \ doc/source/reference/parameters/imptcp-compression-mode.rst \ doc/source/reference/parameters/imptcp-defaulttz.rst \ doc/source/reference/parameters/imptcp-discardtruncatedmsg.rst \ doc/source/reference/parameters/imptcp-failonchownfailure.rst \ doc/source/reference/parameters/imptcp-filecreatemode.rst \ doc/source/reference/parameters/imptcp-filegroup.rst \ doc/source/reference/parameters/imptcp-filegroupnum.rst \ doc/source/reference/parameters/imptcp-fileowner.rst \ doc/source/reference/parameters/imptcp-fileownernum.rst \ doc/source/reference/parameters/imptcp-flowcontrol.rst \ doc/source/reference/parameters/imptcp-framing-delimiter-regex.rst \ doc/source/reference/parameters/imptcp-framingfix-cisco-asa.rst \ doc/source/reference/parameters/imptcp-keepalive-interval.rst \ doc/source/reference/parameters/imptcp-keepalive-probes.rst \ doc/source/reference/parameters/imptcp-keepalive-time.rst \ doc/source/reference/parameters/imptcp-keepalive.rst \ doc/source/reference/parameters/imptcp-listenportfilename.rst \ doc/source/reference/parameters/imptcp-maxframesize.rst \ doc/source/reference/parameters/imptcp-maxsessions.rst \ doc/source/reference/parameters/imptcp-multiline.rst \ doc/source/reference/parameters/imptcp-name.rst \ doc/source/reference/parameters/imptcp-notifyonconnectionclose.rst \ doc/source/reference/parameters/imptcp-notifyonconnectionopen.rst \ doc/source/reference/parameters/imptcp-path.rst \ doc/source/reference/parameters/imptcp-port.rst \ doc/source/reference/parameters/imptcp-processonpoller.rst \ doc/source/reference/parameters/imptcp-ratelimit-burst.rst \ doc/source/reference/parameters/imptcp-ratelimit-interval.rst \ doc/source/reference/parameters/imptcp-ruleset.rst \ doc/source/reference/parameters/imptcp-socketbacklog.rst \ doc/source/reference/parameters/imptcp-supportoctetcountedframing.rst \ doc/source/reference/parameters/imptcp-threads.rst \ doc/source/reference/parameters/imptcp-unlink.rst \ doc/source/reference/parameters/imrelp-address.rst \ doc/source/reference/parameters/imrelp-flowcontrol.rst \ doc/source/reference/parameters/imrelp-keepalive-interval.rst \ doc/source/reference/parameters/imrelp-keepalive-probes.rst \ doc/source/reference/parameters/imrelp-keepalive-time.rst \ doc/source/reference/parameters/imrelp-keepalive.rst \ doc/source/reference/parameters/imrelp-maxdatasize.rst \ doc/source/reference/parameters/imrelp-name.rst \ doc/source/reference/parameters/imrelp-oversizemode.rst \ doc/source/reference/parameters/imrelp-port.rst \ doc/source/reference/parameters/imrelp-ruleset-input.rst \ doc/source/reference/parameters/imrelp-ruleset.rst \ doc/source/reference/parameters/imrelp-tls-authmode.rst \ doc/source/reference/parameters/imrelp-tls-cacert.rst \ doc/source/reference/parameters/imrelp-tls-compression.rst \ doc/source/reference/parameters/imrelp-tls-dhbits.rst \ doc/source/reference/parameters/imrelp-tls-mycert.rst \ doc/source/reference/parameters/imrelp-tls-myprivkey.rst \ doc/source/reference/parameters/imrelp-tls-permittedpeer.rst \ doc/source/reference/parameters/imrelp-tls-prioritystring.rst \ doc/source/reference/parameters/imrelp-tls-tlscfgcmd.rst \ doc/source/reference/parameters/imrelp-tls-tlslib.rst \ doc/source/reference/parameters/imrelp-tls.rst \ doc/source/reference/parameters/imsolaris-imsolarislogsocketname.rst \ doc/source/reference/parameters/imtcp-address.rst \ doc/source/reference/parameters/imtcp-addtlframedelimiter.rst \ doc/source/reference/parameters/imtcp-disablelfdelimiter.rst \ doc/source/reference/parameters/imtcp-discardtruncatedmsg.rst \ doc/source/reference/parameters/imtcp-flowcontrol.rst \ doc/source/reference/parameters/imtcp-gnutlsprioritystring.rst \ doc/source/reference/parameters/imtcp-keepalive-interval.rst \ doc/source/reference/parameters/imtcp-keepalive-probes.rst \ doc/source/reference/parameters/imtcp-keepalive-time.rst \ doc/source/reference/parameters/imtcp-keepalive.rst \ doc/source/reference/parameters/imtcp-listenportfilename.rst \ doc/source/reference/parameters/imtcp-maxframesize.rst \ doc/source/reference/parameters/imtcp-maxlisteners.rst \ doc/source/reference/parameters/imtcp-maxsessions.rst \ doc/source/reference/parameters/imtcp-name.rst \ doc/source/reference/parameters/imtcp-networknamespace.rst \ doc/source/reference/parameters/imtcp-notifyonconnectionclose.rst \ doc/source/reference/parameters/imtcp-notifyonconnectionopen.rst \ doc/source/reference/parameters/imtcp-permittedpeer.rst \ doc/source/reference/parameters/imtcp-port.rst \ doc/source/reference/parameters/imtcp-preservecase.rst \ doc/source/reference/parameters/imtcp-ratelimit-burst.rst \ doc/source/reference/parameters/imtcp-ratelimit-interval.rst \ doc/source/reference/parameters/imtcp-ruleset.rst \ doc/source/reference/parameters/imtcp-socketbacklog.rst \ doc/source/reference/parameters/imtcp-starvationprotection-maxreads.rst \ doc/source/reference/parameters/imtcp-streamdriver-authmode.rst \ doc/source/reference/parameters/imtcp-streamdriver-cafile.rst \ doc/source/reference/parameters/imtcp-streamdriver-certfile.rst \ doc/source/reference/parameters/imtcp-streamdriver-checkextendedkeypurpose.rst \ doc/source/reference/parameters/imtcp-streamdriver-crlfile.rst \ doc/source/reference/parameters/imtcp-streamdriver-keyfile.rst \ doc/source/reference/parameters/imtcp-streamdriver-mode.rst \ doc/source/reference/parameters/imtcp-streamdriver-name.rst \ doc/source/reference/parameters/imtcp-streamdriver-permitexpiredcerts.rst \ doc/source/reference/parameters/imtcp-streamdriver-prioritizesan.rst \ doc/source/reference/parameters/imtcp-streamdriver-tlsverifydepth.rst \ doc/source/reference/parameters/imtcp-supportoctetcountedframing.rst \ doc/source/reference/parameters/imtcp-workerthreads.rst \ doc/source/reference/parameters/imudp-address.rst \ doc/source/reference/parameters/imudp-batchsize.rst \ doc/source/reference/parameters/imudp-defaulttz.rst \ doc/source/reference/parameters/imudp-device.rst \ doc/source/reference/parameters/imudp-ipfreebind.rst \ doc/source/reference/parameters/imudp-name-appendport.rst \ doc/source/reference/parameters/imudp-name.rst \ doc/source/reference/parameters/imudp-port.rst \ doc/source/reference/parameters/imudp-preservecase.rst \ doc/source/reference/parameters/imudp-ratelimit-burst.rst \ doc/source/reference/parameters/imudp-ratelimit-interval.rst \ doc/source/reference/parameters/imudp-rcvbufsize.rst \ doc/source/reference/parameters/imudp-ruleset.rst \ doc/source/reference/parameters/imudp-schedulingpolicy.rst \ doc/source/reference/parameters/imudp-schedulingpriority.rst \ doc/source/reference/parameters/imudp-threads.rst \ doc/source/reference/parameters/imudp-timerequery.rst \ doc/source/reference/parameters/imuxsock-annotate.rst \ doc/source/reference/parameters/imuxsock-createpath.rst \ doc/source/reference/parameters/imuxsock-flowcontrol.rst \ doc/source/reference/parameters/imuxsock-hostname.rst \ doc/source/reference/parameters/imuxsock-ignoreownmessages.rst \ doc/source/reference/parameters/imuxsock-ignoretimestamp.rst \ doc/source/reference/parameters/imuxsock-parsehostname.rst \ doc/source/reference/parameters/imuxsock-parsetrusted.rst \ doc/source/reference/parameters/imuxsock-ratelimit-burst.rst \ doc/source/reference/parameters/imuxsock-ratelimit-interval.rst \ doc/source/reference/parameters/imuxsock-ratelimit-severity.rst \ doc/source/reference/parameters/imuxsock-ruleset.rst \ doc/source/reference/parameters/imuxsock-socket.rst \ doc/source/reference/parameters/imuxsock-syssock-annotate.rst \ doc/source/reference/parameters/imuxsock-syssock-flowcontrol.rst \ doc/source/reference/parameters/imuxsock-syssock-ignoreownmessages.rst \ doc/source/reference/parameters/imuxsock-syssock-ignoretimestamp.rst \ doc/source/reference/parameters/imuxsock-syssock-name.rst \ doc/source/reference/parameters/imuxsock-syssock-parsehostname.rst \ doc/source/reference/parameters/imuxsock-syssock-parsetrusted.rst \ doc/source/reference/parameters/imuxsock-syssock-ratelimit-burst.rst \ doc/source/reference/parameters/imuxsock-syssock-ratelimit-interval.rst \ doc/source/reference/parameters/imuxsock-syssock-ratelimit-severity.rst \ doc/source/reference/parameters/imuxsock-syssock-unlink.rst \ doc/source/reference/parameters/imuxsock-syssock-use.rst \ doc/source/reference/parameters/imuxsock-syssock-usepidfromsystem.rst \ doc/source/reference/parameters/imuxsock-syssock-usespecialparser.rst \ doc/source/reference/parameters/imuxsock-syssock-usesystimestamp.rst \ doc/source/reference/parameters/imuxsock-unlink.rst \ doc/source/reference/parameters/imuxsock-usepidfromsystem.rst \ doc/source/reference/parameters/imuxsock-usespecialparser.rst \ doc/source/reference/parameters/imuxsock-usesystimestamp.rst \ doc/source/reference/parameters/mmaitag-apikey.rst \ doc/source/reference/parameters/mmaitag-apikey_file.rst \ doc/source/reference/parameters/mmaitag-expert-initialprompt.rst \ doc/source/reference/parameters/mmaitag-inputproperty.rst \ doc/source/reference/parameters/mmaitag-model.rst \ doc/source/reference/parameters/mmaitag-provider.rst \ doc/source/reference/parameters/mmaitag-tag.rst \ doc/source/reference/parameters/mmanon-embeddedipv4-anonmode.rst \ doc/source/reference/parameters/mmanon-embeddedipv4-bits.rst \ doc/source/reference/parameters/mmanon-embeddedipv4-enable.rst \ doc/source/reference/parameters/mmanon-ipv4-bits.rst \ doc/source/reference/parameters/mmanon-ipv4-enable.rst \ doc/source/reference/parameters/mmanon-ipv4-mode.rst \ doc/source/reference/parameters/mmanon-ipv4-replacechar.rst \ doc/source/reference/parameters/mmanon-ipv6-anonmode.rst \ doc/source/reference/parameters/mmanon-ipv6-bits.rst \ doc/source/reference/parameters/mmanon-ipv6-enable.rst \ doc/source/reference/parameters/mmcount-appname.rst \ doc/source/reference/parameters/mmcount-key.rst \ doc/source/reference/parameters/mmcount-value.rst \ doc/source/reference/parameters/mmdarwin-container.rst \ doc/source/reference/parameters/mmdarwin-fields.rst \ doc/source/reference/parameters/mmdarwin-filtercode.rst \ doc/source/reference/parameters/mmdarwin-key.rst \ doc/source/reference/parameters/mmdarwin-response.rst \ doc/source/reference/parameters/mmdarwin-send_partial.rst \ doc/source/reference/parameters/mmdarwin-socketpath.rst \ doc/source/reference/parameters/mmdblookup-container.rst \ doc/source/reference/parameters/mmdblookup-fields.rst \ doc/source/reference/parameters/mmdblookup-key.rst \ doc/source/reference/parameters/mmdblookup-mmdbfile.rst \ doc/source/reference/parameters/mmdblookup-reloadonhup.rst \ doc/source/reference/parameters/mmexternal-binary.rst \ doc/source/reference/parameters/mmexternal-forcesingleinstance.rst \ doc/source/reference/parameters/mmexternal-interface-input.rst \ doc/source/reference/parameters/mmexternal-output.rst \ doc/source/reference/parameters/mmfields-jsonroot.rst \ doc/source/reference/parameters/mmfields-separator.rst \ doc/source/reference/parameters/mmjsonparse-allow_trailing.rst \ doc/source/reference/parameters/mmjsonparse-container.rst \ doc/source/reference/parameters/mmjsonparse-cookie.rst \ doc/source/reference/parameters/mmjsonparse-max_scan_bytes.rst \ doc/source/reference/parameters/mmjsonparse-mode.rst \ doc/source/reference/parameters/mmjsonparse-userawmsg.rst \ doc/source/reference/parameters/mmjsonrewrite-input.rst \ doc/source/reference/parameters/mmjsonrewrite-output.rst \ doc/source/reference/parameters/mmjsontransform-input.rst \ doc/source/reference/parameters/mmjsontransform-mode.rst \ doc/source/reference/parameters/mmjsontransform-output.rst \ doc/source/reference/parameters/mmkubernetes-allowunsignedcerts.rst \ doc/source/reference/parameters/mmkubernetes-annotation-match.rst \ doc/source/reference/parameters/mmkubernetes-busyretryinterval.rst \ doc/source/reference/parameters/mmkubernetes-cacheentryttl.rst \ doc/source/reference/parameters/mmkubernetes-cacheexpireinterval.rst \ doc/source/reference/parameters/mmkubernetes-containerrulebase.rst \ doc/source/reference/parameters/mmkubernetes-containerrules.rst \ doc/source/reference/parameters/mmkubernetes-de-dot-separator.rst \ doc/source/reference/parameters/mmkubernetes-de-dot.rst \ doc/source/reference/parameters/mmkubernetes-dstmetadatapath.rst \ doc/source/reference/parameters/mmkubernetes-filenamerulebase.rst \ doc/source/reference/parameters/mmkubernetes-filenamerules.rst \ doc/source/reference/parameters/mmkubernetes-kubernetesurl.rst \ doc/source/reference/parameters/mmkubernetes-skipverifyhost.rst \ doc/source/reference/parameters/mmkubernetes-srcmetadatapath.rst \ doc/source/reference/parameters/mmkubernetes-sslpartialchain.rst \ doc/source/reference/parameters/mmkubernetes-tls-cacert.rst \ doc/source/reference/parameters/mmkubernetes-tls-mycert.rst \ doc/source/reference/parameters/mmkubernetes-tls-myprivkey.rst \ doc/source/reference/parameters/mmkubernetes-token.rst \ doc/source/reference/parameters/mmkubernetes-tokenfile.rst \ doc/source/reference/parameters/mmnormalize-allowregex.rst \ doc/source/reference/parameters/mmnormalize-path.rst \ doc/source/reference/parameters/mmnormalize-rule.rst \ doc/source/reference/parameters/mmnormalize-rulebase.rst \ doc/source/reference/parameters/mmnormalize-userawmsg.rst \ doc/source/reference/parameters/mmnormalize-variable.rst \ doc/source/reference/parameters/mmpstrucdata-jsonroot.rst \ doc/source/reference/parameters/mmpstrucdata-sd_name.lowercase.rst \ doc/source/reference/parameters/mmrfc5424addhmac-hashfunction.rst \ doc/source/reference/parameters/mmrfc5424addhmac-key.rst \ doc/source/reference/parameters/mmrfc5424addhmac-sd-id.rst \ doc/source/reference/parameters/mmsnmptrapd-severitymapping.rst \ doc/source/reference/parameters/mmsnmptrapd-tag.rst \ doc/source/reference/parameters/mmtaghostname-forcelocalhostname.rst \ doc/source/reference/parameters/mmtaghostname-tag.rst \ doc/source/reference/parameters/mmutf8fix-mode.rst \ doc/source/reference/parameters/mmutf8fix-replacementchar.rst \ doc/source/reference/parameters/omazureeventhubs-amqp_address.rst \ doc/source/reference/parameters/omazureeventhubs-azure_key.rst \ doc/source/reference/parameters/omazureeventhubs-azure_key_name.rst \ doc/source/reference/parameters/omazureeventhubs-azurehost.rst \ doc/source/reference/parameters/omazureeventhubs-azureport.rst \ doc/source/reference/parameters/omazureeventhubs-container.rst \ doc/source/reference/parameters/omazureeventhubs-eventproperties.rst \ doc/source/reference/parameters/omazureeventhubs-statsname.rst \ doc/source/reference/parameters/omazureeventhubs-template.rst \ doc/source/reference/parameters/omclickhouse-allowunsignedcerts.rst \ doc/source/reference/parameters/omclickhouse-bulkmode.rst \ doc/source/reference/parameters/omclickhouse-errorfile.rst \ doc/source/reference/parameters/omclickhouse-healthchecktimeout.rst \ doc/source/reference/parameters/omclickhouse-maxbytes.rst \ doc/source/reference/parameters/omclickhouse-port.rst \ doc/source/reference/parameters/omclickhouse-pwd.rst \ doc/source/reference/parameters/omclickhouse-server.rst \ doc/source/reference/parameters/omclickhouse-skipverifyhost.rst \ doc/source/reference/parameters/omclickhouse-template.rst \ doc/source/reference/parameters/omclickhouse-timeout.rst \ doc/source/reference/parameters/omclickhouse-usehttps.rst \ doc/source/reference/parameters/omclickhouse-user.rst \ doc/source/reference/parameters/omdtls-port.rst \ doc/source/reference/parameters/omdtls-statsname.rst \ doc/source/reference/parameters/omdtls-target.rst \ doc/source/reference/parameters/omdtls-template.rst \ doc/source/reference/parameters/omdtls-tls-authmode.rst \ doc/source/reference/parameters/omdtls-tls-cacert.rst \ doc/source/reference/parameters/omdtls-tls-mycert.rst \ doc/source/reference/parameters/omdtls-tls-myprivkey.rst \ doc/source/reference/parameters/omdtls-tls-tlscfgcmd.rst \ doc/source/reference/parameters/omelasticsearch-allowunsignedcerts.rst \ doc/source/reference/parameters/omelasticsearch-apikey.rst \ doc/source/reference/parameters/omelasticsearch-asyncrepl.rst \ doc/source/reference/parameters/omelasticsearch-bulkid.rst \ doc/source/reference/parameters/omelasticsearch-bulkmode.rst \ doc/source/reference/parameters/omelasticsearch-dynbulkid.rst \ doc/source/reference/parameters/omelasticsearch-dynparent.rst \ doc/source/reference/parameters/omelasticsearch-dynpipelinename.rst \ doc/source/reference/parameters/omelasticsearch-dynsearchindex.rst \ doc/source/reference/parameters/omelasticsearch-dynsearchtype.rst \ doc/source/reference/parameters/omelasticsearch-errorfile.rst \ doc/source/reference/parameters/omelasticsearch-esversion-major.rst \ doc/source/reference/parameters/omelasticsearch-healthchecktimeout.rst \ doc/source/reference/parameters/omelasticsearch-indextimeout.rst \ doc/source/reference/parameters/omelasticsearch-maxbytes.rst \ doc/source/reference/parameters/omelasticsearch-parent.rst \ doc/source/reference/parameters/omelasticsearch-pipelinename.rst \ doc/source/reference/parameters/omelasticsearch-pwd.rst \ doc/source/reference/parameters/omelasticsearch-ratelimit-burst.rst \ doc/source/reference/parameters/omelasticsearch-ratelimit-interval.rst \ doc/source/reference/parameters/omelasticsearch-rebindinterval.rst \ doc/source/reference/parameters/omelasticsearch-retryfailures.rst \ doc/source/reference/parameters/omelasticsearch-retryruleset.rst \ doc/source/reference/parameters/omelasticsearch-searchindex.rst \ doc/source/reference/parameters/omelasticsearch-searchtype.rst \ doc/source/reference/parameters/omelasticsearch-server.rst \ doc/source/reference/parameters/omelasticsearch-serverport.rst \ doc/source/reference/parameters/omelasticsearch-skippipelineifempty.rst \ doc/source/reference/parameters/omelasticsearch-skipverifyhost.rst \ doc/source/reference/parameters/omelasticsearch-template.rst \ doc/source/reference/parameters/omelasticsearch-timeout.rst \ doc/source/reference/parameters/omelasticsearch-tls-cacert.rst \ doc/source/reference/parameters/omelasticsearch-tls-mycert.rst \ doc/source/reference/parameters/omelasticsearch-tls-myprivkey.rst \ doc/source/reference/parameters/omelasticsearch-uid.rst \ doc/source/reference/parameters/omelasticsearch-usehttps.rst \ doc/source/reference/parameters/omelasticsearch-writeoperation.rst \ doc/source/reference/parameters/omfile-addlf.rst \ doc/source/reference/parameters/omfile-asyncwriting.rst \ doc/source/reference/parameters/omfile-closetimeout.rst \ doc/source/reference/parameters/omfile-compression-driver.rst \ doc/source/reference/parameters/omfile-compression-zstd-workers.rst \ doc/source/reference/parameters/omfile-createdirs.rst \ doc/source/reference/parameters/omfile-cry-provider.rst \ doc/source/reference/parameters/omfile-dircreatemode.rst \ doc/source/reference/parameters/omfile-dirgroup.rst \ doc/source/reference/parameters/omfile-dirgroupnum.rst \ doc/source/reference/parameters/omfile-dirowner.rst \ doc/source/reference/parameters/omfile-dirownernum.rst \ doc/source/reference/parameters/omfile-dynafile-donotsuspend.rst \ doc/source/reference/parameters/omfile-dynafile.rst \ doc/source/reference/parameters/omfile-dynafilecachesize.rst \ doc/source/reference/parameters/omfile-failonchownfailure.rst \ doc/source/reference/parameters/omfile-file.rst \ doc/source/reference/parameters/omfile-filecreatemode.rst \ doc/source/reference/parameters/omfile-filegroup.rst \ doc/source/reference/parameters/omfile-filegroupnum.rst \ doc/source/reference/parameters/omfile-fileowner.rst \ doc/source/reference/parameters/omfile-fileownernum.rst \ doc/source/reference/parameters/omfile-flushinterval.rst \ doc/source/reference/parameters/omfile-flushontxend.rst \ doc/source/reference/parameters/omfile-iobuffersize.rst \ doc/source/reference/parameters/omfile-rotation-sizelimit.rst \ doc/source/reference/parameters/omfile-rotation-sizelimitcommand.rst \ doc/source/reference/parameters/omfile-sig-provider.rst \ doc/source/reference/parameters/omfile-sync.rst \ doc/source/reference/parameters/omfile-template.rst \ doc/source/reference/parameters/omfile-veryrobustzip.rst \ doc/source/reference/parameters/omfile-ziplevel.rst \ doc/source/reference/parameters/omgssapi-actiongssforwarddefaulttemplate.rst \ doc/source/reference/parameters/omgssapi-gssforwardservicename.rst \ doc/source/reference/parameters/omgssapi-gssmode.rst \ doc/source/reference/parameters/omhdfs-omhdfsdefaulttemplate.rst \ doc/source/reference/parameters/omhdfs-omhdfsfilename.rst \ doc/source/reference/parameters/omhdfs-omhdfshost.rst \ doc/source/reference/parameters/omhdfs-omhdfsport.rst \ doc/source/reference/parameters/omhttp-allowunsignedcerts.rst \ doc/source/reference/parameters/omhttp-batch-format.rst \ doc/source/reference/parameters/omhttp-batch-maxbytes.rst \ doc/source/reference/parameters/omhttp-batch-maxsize.rst \ doc/source/reference/parameters/omhttp-batch.rst \ doc/source/reference/parameters/omhttp-checkpath.rst \ doc/source/reference/parameters/omhttp-compress-level.rst \ doc/source/reference/parameters/omhttp-compress.rst \ doc/source/reference/parameters/omhttp-dynrestpath.rst \ doc/source/reference/parameters/omhttp-errorfile.rst \ doc/source/reference/parameters/omhttp-healthchecktimeout.rst \ doc/source/reference/parameters/omhttp-httpcontenttype.rst \ doc/source/reference/parameters/omhttp-httpheaderkey.rst \ doc/source/reference/parameters/omhttp-httpheaders.rst \ doc/source/reference/parameters/omhttp-httpheadervalue.rst \ doc/source/reference/parameters/omhttp-httpignorablecodes.rst \ doc/source/reference/parameters/omhttp-httpretrycodes.rst \ doc/source/reference/parameters/omhttp-proxyhost.rst \ doc/source/reference/parameters/omhttp-proxyport.rst \ doc/source/reference/parameters/omhttp-pwd.rst \ doc/source/reference/parameters/omhttp-ratelimit-burst.rst \ doc/source/reference/parameters/omhttp-ratelimit-interval.rst \ doc/source/reference/parameters/omhttp-reloadonhup.rst \ doc/source/reference/parameters/omhttp-restpath.rst \ doc/source/reference/parameters/omhttp-restpathtimeout.rst \ doc/source/reference/parameters/omhttp-retry-addmetadata.rst \ doc/source/reference/parameters/omhttp-retry-ruleset.rst \ doc/source/reference/parameters/omhttp-retry.rst \ doc/source/reference/parameters/omhttp-server.rst \ doc/source/reference/parameters/omhttp-serverport.rst \ doc/source/reference/parameters/omhttp-skipverifyhost.rst \ doc/source/reference/parameters/omhttp-statsname.rst \ doc/source/reference/parameters/omhttp-template.rst \ doc/source/reference/parameters/omhttp-tls-cacert.rst \ doc/source/reference/parameters/omhttp-tls-mycert.rst \ doc/source/reference/parameters/omhttp-tls-myprivkey.rst \ doc/source/reference/parameters/omhttp-uid.rst \ doc/source/reference/parameters/omhttp-usehttps.rst \ doc/source/reference/parameters/omjournal-namespace.rst \ doc/source/reference/parameters/omjournal-template.rst \ doc/source/reference/parameters/omkafka-broker.rst \ doc/source/reference/parameters/omkafka-closetimeout.rst \ doc/source/reference/parameters/omkafka-confparam.rst \ doc/source/reference/parameters/omkafka-dynakey.rst \ doc/source/reference/parameters/omkafka-dynatopic-cachesize.rst \ doc/source/reference/parameters/omkafka-dynatopic.rst \ doc/source/reference/parameters/omkafka-errorfile.rst \ doc/source/reference/parameters/omkafka-failedmsgfile.rst \ doc/source/reference/parameters/omkafka-kafkaheader.rst \ doc/source/reference/parameters/omkafka-keepfailedmessages.rst \ doc/source/reference/parameters/omkafka-key.rst \ doc/source/reference/parameters/omkafka-partitions-auto.rst \ doc/source/reference/parameters/omkafka-partitions-number.rst \ doc/source/reference/parameters/omkafka-partitions-usefixed.rst \ doc/source/reference/parameters/omkafka-resubmitonfailure.rst \ doc/source/reference/parameters/omkafka-statsfile.rst \ doc/source/reference/parameters/omkafka-statsname.rst \ doc/source/reference/parameters/omkafka-template.rst \ doc/source/reference/parameters/omkafka-topic.rst \ doc/source/reference/parameters/omkafka-topicconfparam.rst \ doc/source/reference/parameters/omlibdbi-db.rst \ doc/source/reference/parameters/omlibdbi-driver.rst \ doc/source/reference/parameters/omlibdbi-driverdirectory.rst \ doc/source/reference/parameters/omlibdbi-pwd.rst \ doc/source/reference/parameters/omlibdbi-server.rst \ doc/source/reference/parameters/omlibdbi-template.rst \ doc/source/reference/parameters/omlibdbi-uid.rst \ doc/source/reference/parameters/ommail-body-enable.rst \ doc/source/reference/parameters/ommail-mailfrom.rst \ doc/source/reference/parameters/ommail-mailto.rst \ doc/source/reference/parameters/ommail-port.rst \ doc/source/reference/parameters/ommail-server.rst \ doc/source/reference/parameters/ommail-subject-template.rst \ doc/source/reference/parameters/ommail-subject-text.rst \ doc/source/reference/parameters/ommail-template.rst \ doc/source/reference/parameters/omprog-begintransactionmark.rst \ doc/source/reference/parameters/omprog-binary.rst \ doc/source/reference/parameters/omprog-closetimeout.rst \ doc/source/reference/parameters/omprog-committransactionmark.rst \ doc/source/reference/parameters/omprog-confirmmessages.rst \ doc/source/reference/parameters/omprog-confirmtimeout.rst \ doc/source/reference/parameters/omprog-filecreatemode.rst \ doc/source/reference/parameters/omprog-forcesingleinstance.rst \ doc/source/reference/parameters/omprog-hup-signal.rst \ doc/source/reference/parameters/omprog-killunresponsive.rst \ doc/source/reference/parameters/omprog-output.rst \ doc/source/reference/parameters/omprog-reportfailures.rst \ doc/source/reference/parameters/omprog-signalonclose.rst \ doc/source/reference/parameters/omprog-template.rst \ doc/source/reference/parameters/omprog-usetransactions.rst \ doc/source/reference/parameters/omsendertrack-cmdfile.rst \ doc/source/reference/parameters/omsendertrack-interval.rst \ doc/source/reference/parameters/omsendertrack-senderid.rst \ doc/source/reference/parameters/omsendertrack-statefile.rst \ doc/source/reference/parameters/omsnmp-community.rst \ doc/source/reference/parameters/omsnmp-enterpriseoid.rst \ doc/source/reference/parameters/omsnmp-messageoid.rst \ doc/source/reference/parameters/omsnmp-port.rst \ doc/source/reference/parameters/omsnmp-server.rst \ doc/source/reference/parameters/omsnmp-snmpv1dynsource.rst \ doc/source/reference/parameters/omsnmp-specifictype.rst \ doc/source/reference/parameters/omsnmp-transport.rst \ doc/source/reference/parameters/omsnmp-trapoid.rst \ doc/source/reference/parameters/omsnmp-traptype.rst \ doc/source/reference/parameters/omsnmp-version.rst \ doc/source/reference/parameters/omuxsock-abstract.rst \ doc/source/reference/parameters/omuxsock-networknamespace.rst \ doc/source/reference/parameters/omuxsock-socketname.rst \ doc/source/reference/parameters/omuxsock-sockettype.rst \ doc/source/reference/parameters/omuxsock-template.rst \ doc/source/reference/parameters/pmrfc3164-detect-headerless.rst \ doc/source/reference/parameters/pmrfc3164-detect-yearaftertimestamp.rst \ doc/source/reference/parameters/pmrfc3164-force-tagendingbycolon.rst \ doc/source/reference/parameters/pmrfc3164-headerless-drop.rst \ doc/source/reference/parameters/pmrfc3164-headerless-errorfile.rst \ doc/source/reference/parameters/pmrfc3164-headerless-hostname.rst \ doc/source/reference/parameters/pmrfc3164-headerless-ruleset.rst \ doc/source/reference/parameters/pmrfc3164-headerless-tag.rst \ doc/source/reference/parameters/pmrfc3164-permit-atsignsinhostname.rst \ doc/source/reference/parameters/pmrfc3164-permit-slashesinhostname.rst \ doc/source/reference/parameters/pmrfc3164-permit-squarebracketsinhostname.rst \ doc/source/reference/parameters/pmrfc3164-remove-msgfirstspace.rst \ doc/source/reference/properties/message-app-name.rst \ doc/source/reference/properties/message-fromhost-ip.rst \ doc/source/reference/properties/message-fromhost-port.rst \ doc/source/reference/properties/message-fromhost.rst \ doc/source/reference/properties/message-hostname.rst \ doc/source/reference/properties/message-inputname.rst \ doc/source/reference/properties/message-iut.rst \ doc/source/reference/properties/message-jsonmesg.rst \ doc/source/reference/properties/message-msg.rst \ doc/source/reference/properties/message-msgid.rst \ doc/source/reference/properties/message-pri-text.rst \ doc/source/reference/properties/message-pri.rst \ doc/source/reference/properties/message-procid.rst \ doc/source/reference/properties/message-programname.rst \ doc/source/reference/properties/message-protocol-version.rst \ doc/source/reference/properties/message-rawmsg-after-pri.rst \ doc/source/reference/properties/message-rawmsg.rst \ doc/source/reference/properties/message-source.rst \ doc/source/reference/properties/message-structured-data.rst \ doc/source/reference/properties/message-syslogfacility-text.rst \ doc/source/reference/properties/message-syslogfacility.rst \ doc/source/reference/properties/message-syslogpriority-text.rst \ doc/source/reference/properties/message-syslogpriority.rst \ doc/source/reference/properties/message-syslogseverity-text.rst \ doc/source/reference/properties/message-syslogseverity.rst \ doc/source/reference/properties/message-syslogtag.rst \ doc/source/reference/properties/message-timegenerated.rst \ doc/source/reference/properties/message-timereported.rst \ doc/source/reference/properties/message-timestamp.rst \ doc/source/reference/properties/message-uuid.rst \ doc/source/reference/properties/system-bom.rst \ doc/source/reference/properties/system-myhostname.rst \ doc/source/reference/properties/system-time-day.rst \ doc/source/reference/properties/system-time-hhour.rst \ doc/source/reference/properties/system-time-hour.rst \ doc/source/reference/properties/system-time-minute.rst \ doc/source/reference/properties/system-time-month.rst \ doc/source/reference/properties/system-time-now-unixtimestamp.rst \ doc/source/reference/properties/system-time-now.rst \ doc/source/reference/properties/system-time-qhour.rst \ doc/source/reference/properties/system-time-wday.rst \ doc/source/reference/properties/system-time-year.rst \ doc/source/reference/templates/templates-examples.rst \ doc/source/reference/templates/templates-legacy.rst \ doc/source/reference/templates/templates-options.rst \ doc/source/reference/templates/templates-reserved-names.rst \ doc/source/reference/templates/templates-statement-constant.rst \ doc/source/reference/templates/templates-statement-property.rst \ doc/source/reference/templates/templates-type-list.rst \ doc/source/reference/templates/templates-type-plugin.rst \ doc/source/reference/templates/templates-type-string.rst \ doc/source/reference/templates/templates-type-subtree.rst \ doc/source/rsyslog-vers.png \ doc/source/rsyslog_confgraph_complex.png \ doc/source/rsyslog_confgraph_std.png \ doc/source/tls_cert.jpg \ doc/source/tls_cert_100.jpg \ doc/source/tls_cert_ca.jpg \ doc/source/troubleshooting/debug.rst \ doc/source/troubleshooting/file_not_written.rst \ doc/source/troubleshooting/howtodebug.rst \ doc/source/troubleshooting/index.rst \ doc/source/troubleshooting/selinux.rst \ doc/source/troubleshooting/troubleshoot.rst \ doc/source/tutorials/cert-script.tar.gz \ doc/source/tutorials/database.rst \ doc/source/tutorials/failover_syslog_server.rst \ doc/source/tutorials/gelf_forwarding.rst \ doc/source/tutorials/hash_sampling.rst \ doc/source/tutorials/high_database_rate.rst \ doc/source/tutorials/index.rst \ doc/source/tutorials/log_rotation_fix_size.rst \ doc/source/tutorials/log_sampling.rst \ doc/source/tutorials/random_sampling.rst \ doc/source/tutorials/recording_pri.rst \ doc/source/tutorials/reliable_forwarding.rst \ doc/source/tutorials/tls.rst \ doc/source/tutorials/tls_cert.jpg \ doc/source/tutorials/tls_cert_100.jpg \ doc/source/tutorials/tls_cert_ca.jpg \ doc/source/tutorials/tls_cert_ca.rst \ doc/source/tutorials/tls_cert_client.rst \ doc/source/tutorials/tls_cert_errmsgs.rst \ doc/source/tutorials/tls_cert_machine.rst \ doc/source/tutorials/tls_cert_scenario.rst \ doc/source/tutorials/tls_cert_script.rst \ doc/source/tutorials/tls_cert_server.rst \ doc/source/tutorials/tls_cert_summary.rst \ doc/source/tutorials/tls_cert_udp_relay.rst \ doc/source/whitepapers/dataflow.png \ doc/source/whitepapers/direct_queue0.png \ doc/source/whitepapers/direct_queue1.png \ doc/source/whitepapers/direct_queue2.png \ doc/source/whitepapers/direct_queue3.png \ doc/source/whitepapers/direct_queue_directq.png \ doc/source/whitepapers/direct_queue_rsyslog.png \ doc/source/whitepapers/direct_queue_rsyslog2.png \ doc/source/whitepapers/index.rst \ doc/source/whitepapers/preserve_in_nat.rst \ doc/source/whitepapers/queue_analogy_tv.png \ doc/source/whitepapers/queues_analogy.rst \ doc/source/whitepapers/reliable_logging.rst \ doc/source/whitepapers/syslog_parsing.rst \ doc/source/whitepapers/syslog_protocol.rst \ doc/tools/README.md \ doc/tools/build-doc-linux.sh \ doc/tools/build-doc-windows.ps1 \ doc/tools/buildenv/.dockerignore \ doc/tools/buildenv/Dockerfile \ doc/tools/buildenv/README.md \ doc/tools/buildenv/starter.sh \ doc/tools/buildenv/tools/bash \ doc/tools/buildenv/tools/build-doc \ doc/tools/buildenv/tools/git-clone \ doc/tools/buildenv/tools/help \ doc/tools/buildenv/tools/version-info \ doc/tools/fix-mermaid-offline.py \ doc/tools/release_build.sh \ doc/utils/release_build.sh SUBDIRS = compat runtime grammar . plugins/immark plugins/imuxsock plugins/imtcp plugins/imudp plugins/omtesting # external plugin driver is always enabled (core component) SUBDIRS += plugins/mmexternal if ENABLE_RSYSLOGD SUBDIRS += tools endif if ENABLE_IMKLOG SUBDIRS += plugins/imklog endif if ENABLE_IMKMSG SUBDIRS += contrib/imkmsg endif if ENABLE_IMPSTATS SUBDIRS += plugins/impstats endif if ENABLE_IMSOLARIS SUBDIRS += plugins/imsolaris endif if ENABLE_GSSAPI SUBDIRS += plugins/omgssapi plugins/imgssapi endif if ENABLE_RELP SUBDIRS += plugins/omrelp plugins/imrelp endif if ENABLE_OMFILE_HARDENED SUBDIRS += contrib/omfile-hardened endif if ENABLE_MYSQL SUBDIRS += plugins/ommysql endif if ENABLE_OMLIBDBI SUBDIRS += plugins/omlibdbi endif if ENABLE_PGSQL SUBDIRS += plugins/ompgsql endif if ENABLE_SNMP SUBDIRS += plugins/omsnmp endif if ENABLE_OMSTDOUT SUBDIRS += plugins/omstdout endif if ENABLE_OMSENDERTRACK SUBDIRS += plugins/omsendertrack endif if ENABLE_PMCISCONAMES SUBDIRS += contrib/pmcisconames endif if ENABLE_PMCISCOIOS SUBDIRS += plugins/pmciscoios endif if ENABLE_PMNULL SUBDIRS += plugins/pmnull endif if ENABLE_PMNORMALIZE SUBDIRS += plugins/pmnormalize endif if ENABLE_PMAIXFORWARDEDFROM SUBDIRS += contrib/pmaixforwardedfrom endif if ENABLE_PMSNARE SUBDIRS += contrib/pmsnare endif if ENABLE_PMPANNGFW SUBDIRS += contrib/pmpanngfw endif if ENABLE_PMLASTMSG SUBDIRS += plugins/pmlastmsg endif if ENABLE_OMRULESET SUBDIRS += plugins/omruleset endif if ENABLE_OMUDPSPOOF SUBDIRS += plugins/omudpspoof endif if ENABLE_OMMONGODB SUBDIRS += plugins/ommongodb endif if ENABLE_OMHIREDIS SUBDIRS += contrib/omhiredis endif if ENABLE_OMCZMQ SUBDIRS += contrib/omczmq endif if ENABLE_OMRABBITMQ SUBDIRS += contrib/omrabbitmq endif if ENABLE_IMCZMQ SUBDIRS += contrib/imczmq endif if ENABLE_OMUXSOCK SUBDIRS += plugins/omuxsock endif if ENABLE_OMHDFS SUBDIRS += plugins/omhdfs endif if ENABLE_OMJOURNAL SUBDIRS += plugins/omjournal endif if ENABLE_IMJOURNAL SUBDIRS += plugins/imjournal endif if ENABLE_ELASTICSEARCH SUBDIRS += plugins/omelasticsearch endif if ENABLE_CLICKHOUSE SUBDIRS += plugins/omclickhouse endif if ENABLE_OMHTTP SUBDIRS += contrib/omhttp endif if ENABLE_SNMP SUBDIRS += plugins/omsnmp endif if ENABLE_MMSNMPTRAPD SUBDIRS += plugins/mmsnmptrapd endif if ENABLE_IMFILE SUBDIRS += plugins/imfile endif if ENABLE_IMDOCKER SUBDIRS += contrib/imdocker endif if ENABLE_IMPTCP SUBDIRS += plugins/imptcp endif if ENABLE_IMDIAG SUBDIRS += plugins/imdiag endif if ENABLE_MAIL SUBDIRS += plugins/ommail endif if ENABLE_FMHTTP SUBDIRS += plugins/fmhttp endif if ENABLE_FMHASH SUBDIRS += contrib/fmhash endif if ENABLE_FMUNFLATTEN SUBDIRS += contrib/fmunflatten endif if ENABLE_FMPCRE SUBDIRS += plugins/fmpcre endif if ENABLE_FFAUP SUBDIRS += contrib/ffaup endif if ENABLE_OMKAFKA SUBDIRS += plugins/omkafka endif if ENABLE_IMKAFKA SUBDIRS += plugins/imkafka endif if ENABLE_OMAZUREEVENTHUBS SUBDIRS += plugins/omazureeventhubs endif if ENABLE_IMDTLS SUBDIRS += plugins/imdtls endif if ENABLE_OMDTLS SUBDIRS += plugins/omdtls endif if ENABLE_OMPROG SUBDIRS += plugins/omprog endif if ENABLE_RFC3195 SUBDIRS += plugins/im3195 endif if ENABLE_MMNORMALIZE SUBDIRS += plugins/mmnormalize endif if ENABLE_MMLEEFPARSE SUBDIRS += plugins/mmleefparse endif if ENABLE_MMJSONPARSE SUBDIRS += plugins/mmjsonparse endif if ENABLE_MMJSONTRANSFORM SUBDIRS += plugins/mmjsontransform endif if ENABLE_MMGROK SUBDIRS += contrib/mmgrok endif if ENABLE_MMAUDIT SUBDIRS += plugins/mmaudit endif if ENABLE_MMANON SUBDIRS += plugins/mmanon endif if ENABLE_MMRM1STSPACE SUBDIRS += plugins/mmrm1stspace endif if ENABLE_MMUTF8FIX SUBDIRS += plugins/mmutf8fix endif if ENABLE_MMCOUNT SUBDIRS += contrib/mmcount endif if ENABLE_MMSEQUENCE SUBDIRS += contrib/mmsequence endif if ENABLE_MMDBLOOKUP SUBDIRS += plugins/mmdblookup endif if ENABLE_MMDARWIN SUBDIRS += contrib/mmdarwin endif if ENABLE_MMFIELDS SUBDIRS += plugins/mmfields endif if ENABLE_MMPSTRUCDATA SUBDIRS += plugins/mmpstrucdata endif if ENABLE_MMAITAG SUBDIRS += plugins/mmaitag endif if ENABLE_MMRFC5424ADDHMAC SUBDIRS += contrib/mmrfc5424addhmac endif if ENABLE_MMSNAREPARSE SUBDIRS += plugins/mmsnareparse endif # omhttpfs if ENABLE_OMHTTPFS SUBDIRS += contrib/omhttpfs endif # omamqp1 if ENABLE_OMAMQP1 SUBDIRS += contrib/omamqp1 endif # imbatchreport if ENABLE_IMBATCHREPORT SUBDIRS += contrib/imbatchreport endif # omtcl if ENABLE_OMTCL SUBDIRS += contrib/omtcl endif # mmkubernetes if ENABLE_MMKUBERNETES SUBDIRS += contrib/mmkubernetes endif # impcap if ENABLE_IMPCAP SUBDIRS += contrib/impcap endif # imtuxedoulog if ENABLE_IMTUXEDOULOG SUBDIRS += contrib/imtuxedoulog endif # improg if ENABLE_IMPROG SUBDIRS += contrib/improg endif # imhttp if ENABLE_IMHTTP SUBDIRS += contrib/imhttp endif # mmtaghostname if ENABLE_MMTAGHOSTNAME SUBDIRS += contrib/mmtaghostname endif # imdb2diag if ENABLE_PMDB2DIAG SUBDIRS += contrib/pmdb2diag endif # imhiredis if ENABLE_IMHIREDIS SUBDIRS += contrib/imhiredis endif # tests are added as last element, because tests may need different # modules that need to be generated first SUBDIRS += tests DISTCHECK_CONFIGURE_FLAGS= # make sure "make distcheck" tries to build all modules. This means that # a developer must always have an environment where every supporting library # is available. If that is not the case, the respective configure option may # temporarily be removed below. The intent behind forcing everthing to compile # in a make distcheck is so that we detect code that accidently was not updated # when some global update happened. DISTCHECK_CONFIGURE_FLAGS+= \ --enable-silent-rules \ --enable-rsyslogd \ --enable-omstdout \ --enable-omsendertrack \ --enable-imdiag \ --enable-testbench \ --enable-valgrind # currently not supported in make distcheck: # --enable-pgsql-tests # --enable-extended-tests --> should probably never be enabled due to runtime if ENABLE_DEFAULT_TESTS DISTCHECK_CONFIGURE_FLAGS+= \ --enable-diagtools \ --enable-impstats \ --enable-imptcp \ --enable-klog \ --enable-mail \ --enable-mmanon \ --enable-mmaudit \ --enable-mmcount \ --enable-mmexternal \ --enable-mmfields \ --enable-mmjsonparse \ --enable-mmpstrucdata \ --enable-mmrm1stspace \ --enable-mmsequence \ --enable-mmutf8fix \ --enable-omruleset \ --enable-omuxsock \ --enable-pmaixforwardedfrom \ --enable-pmciscoios \ --enable-pmcisconames \ --enable-pmlastmsg \ --enable-pmnull \ --enable-pmsnare \ --enable-usertools else DISTCHECK_CONFIGURE_FLAGS+= \ --disable-default-tests endif # if ENABLE_DEFAULT_TESTS if ENABLE_IMPROG DISTCHECK_CONFIGURE_FLAGS+= --enable-improg endif if ENABLE_IMHTTP DISTCHECK_CONFIGURE_FLAGS+= --enable-imhttp endif if ENABLE_OMPROG DISTCHECK_CONFIGURE_FLAGS+= --enable-omprog endif if ENABLE_GSSAPI DISTCHECK_CONFIGURE_FLAGS+= --enable-gssapi-krb5 endif if ENABLE_PMNORMALIZE DISTCHECK_CONFIGURE_FLAGS+= --enable-pmnormalize endif if ENABLE_MMDBLOOKUP DISTCHECK_CONFIGURE_FLAGS+= --enable-mmdblookup endif if ENABLE_MMDARWIN DISTCHECK_CONFIGURE_FLAGS+= --enable-mmdarwin endif if ENABLE_MMNORMALIZE DISTCHECK_CONFIGURE_FLAGS+= --enable-mmnormalize endif if ENABLE_OMMONGODB DISTCHECK_CONFIGURE_FLAGS+= --enable-ommongodb endif if ENABLE_OMHIREDIS DISTCHECK_CONFIGURE_FLAGS+= --enable-omhiredis endif if ENABLE_MMSNMPTRAPD DISTCHECK_CONFIGURE_FLAGS+= --enable-mmsnmptrapd endif if ENABLE_OMLIBDBI DISTCHECK_CONFIGURE_FLAGS+= --enable-libdbi endif if ENABLE_LIBGCRYPT DISTCHECK_CONFIGURE_FLAGS+= --enable-libgcrypt endif if ENABLE_OMHTTP DISTCHECK_CONFIGURE_FLAGS+= --enable-omhttp endif if ENABLE_OMHTTPFS DISTCHECK_CONFIGURE_FLAGS+= --enable-omhttpfs endif if ENABLE_OMTCL DISTCHECK_CONFIGURE_FLAGS+= --enable-omtcl endif if ENABLE_SNMP DISTCHECK_CONFIGURE_FLAGS+= --enable-snmp endif if ENABLE_SNMP_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-snmp-tests endif if ENABLE_FMHTTP DISTCHECK_CONFIGURE_FLAGS+= --enable-fmhttp endif if ENABLE_OMUDPSPOOF DISTCHECK_CONFIGURE_FLAGS+= --enable-omudpspoof endif if ENABLE_PGSQL DISTCHECK_CONFIGURE_FLAGS+= --enable-pgsql endif if ENABLE_GNUTLS DISTCHECK_CONFIGURE_FLAGS+= --enable-gnutls endif if ENABLE_GNUTLS_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-gnutls-tests else DISTCHECK_CONFIGURE_FLAGS+= --disable-gnutls-tests endif if ENABLE_OPENSSL DISTCHECK_CONFIGURE_FLAGS+= --enable-openssl endif if ENABLE_MYSQL DISTCHECK_CONFIGURE_FLAGS+= --enable-mysql endif if ENABLE_MYSQL_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-mysql-tests endif if ENABLE_ELASTICSEARCH DISTCHECK_CONFIGURE_FLAGS+= --enable-elasticsearch endif if ENABLE_ELASTICSEARCH_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-elasticsearch-tests endif if ENABLE_CLICKHOUSE DISTCHECK_CONFIGURE_FLAGS+= --enable-clickhouse endif if ENABLE_CLICKHOUSE_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-clickhouse-tests endif if ENABLE_MMGROK DISTCHECK_CONFIGURE_FLAGS+= --enable-mmgrok endif if ENABLE_RELP DISTCHECK_CONFIGURE_FLAGS+= --enable-relp --enable-omrelp-default-port=13515 endif if ENABLE_IMKAFKA DISTCHECK_CONFIGURE_FLAGS+= --enable-imkafka endif if ENABLE_OMKAFKA DISTCHECK_CONFIGURE_FLAGS+= --enable-omkafka endif if ENABLE_KAFKA_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-kafka-tests endif if ENABLE_OMAZUREEVENTHUBS DISTCHECK_CONFIGURE_FLAGS+= --enable-omazureeventhubs endif if ENABLE_IMDTLS DISTCHECK_CONFIGURE_FLAGS+= --enable-imdtls endif if ENABLE_OMDTLS DISTCHECK_CONFIGURE_FLAGS+= --enable-omdtls endif if ENABLE_IMJOURNAL DISTCHECK_CONFIGURE_FLAGS+= --enable-imjournal endif if ENABLE_OMJOURNAL DISTCHECK_CONFIGURE_FLAGS+= --enable-omjournal endif if ENABLE_JOURNAL_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-journal-tests endif if ENABLE_IMCZMQ DISTCHECK_CONFIGURE_FLAGS+= --enable-imczmq endif if ENABLE_OMCZMQ DISTCHECK_CONFIGURE_FLAGS+= --enable-omczmq endif if ENABLE_MMTAGHOSTNAME DISTCHECK_CONFIGURE_FLAGS+= --enable-mmtaghostname endif if ENABLE_IMTUXEDOULOG DISTCHECK_CONFIGURE_FLAGS+= --enable-imtuxedolog endif if ENABLE_PMDB2DIAG DISTCHECK_CONFIGURE_FLAGS+= --enable-pmdb2diag endif if ENABLE_IMBATCHREPORT DISTCHECK_CONFIGURE_FLAGS+= --enable-imbatchreport endif if ENABLE_IMFILE DISTCHECK_CONFIGURE_FLAGS+= --enable-imfile endif if ENABLE_IMFILE_TESTS DISTCHECK_CONFIGURE_FLAGS+= --enable-imfile-tests else DISTCHECK_CONFIGURE_FLAGS+= --disable-imfile-tests endif if ENABLE_IMPCAP DISTCHECK_CONFIGURE_FLAGS+= --enable-impcap endif if ENABLE_IMDOCKER DISTCHECK_CONFIGURE_FLAGS+= --enable-imdocker endif if ENABLE_OMRABBITMQ DISTCHECK_CONFIGURE_FLAGS+= --enable-omrabbitmq endif if ENABLE_MMKUBERNETES DISTCHECK_CONFIGURE_FLAGS+= --enable-mmkubernetes endif if ENABLE_OMAMQP1 DISTCHECK_CONFIGURE_FLAGS+= --enable-omamqp1 endif if ENABLE_DISTCHECK_WORKAROUND DISTCHECK_CONFIGURE_FLAGS+= --disable-testbench else DISTCHECK_CONFIGURE_FLAGS+= --enable-testbench endif if ENABLE_IMHIREDIS DISTCHECK_CONFIGURE_FLAGS+= --enable-imhiredis endif dist-hook: $(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version ACLOCAL_AMFLAGS = -I m4 rsyslog-8.2512.0/PaxHeaders/config.guess0000644000000000000000000000013215114544315015051 xustar0030 mtime=1764935885.466998984 30 atime=1764935888.514045658 30 ctime=1764935920.420534279 rsyslog-8.2512.0/config.guess0000755000175000017500000014051215114544315014521 0ustar00rgerrger#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2022 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2022-01-09' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_X32 >/dev/null then LIBCABI=${LIBC}x32 fi fi GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; x86_64:Haiku:*:*) GUESS=x86_64-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: rsyslog-8.2512.0/PaxHeaders/tools0000644000000000000000000000013215114544364013623 xustar0030 mtime=1764935924.191592013 30 atime=1764935930.040681554 30 ctime=1764935924.191592013 rsyslog-8.2512.0/tools/0000775000175000017500000000000015114544364013344 5ustar00rgerrgerrsyslog-8.2512.0/tools/PaxHeaders/recover_qi.pl0000644000000000000000000000013115035412264016365 xustar0029 mtime=1752569012.42259788 30 atime=1764931133.548198228 30 ctime=1764935924.191592013 rsyslog-8.2512.0/tools/recover_qi.pl0000775000175000017500000001372215035412264016042 0ustar00rgerrger#!/usr/bin/perl -w # recover rsyslog disk queue index (.qi) from queue files (.nnnnnnnn). # # See: # runtime/queue.c: qqueuePersist() # runtime/queue.c: qqueueTryLoadPersistedInfo() # # kaiwang.chen@gmail.com 2012-03-14 # use strict; use Getopt::Long; my %opt = (); GetOptions(\%opt,"spool|w=s","basename|f=s","digits|d=i","help!"); if ($opt{help}) { print "Usage: \t$0 -w WorkDirectory -f QueueFileName -d 8 > QueueFileName.qi "; exit; } # runtime/queue.c: qConstructDisk() my $iMaxFiles = 10000000; # 0+"1".( "0"x($opt{digits} - 1)); # get the list of queue files, spool directory excluded my $re = qr/^\Q$opt{basename}\E\.\d{$opt{digits}}$/; opendir(DIR, $opt{spool}) or die "can’t open spool: $!"; my @qf = grep { /$re/ && -f "$opt{spool}/$_" } readdir(DIR); closedir DIR; # ensure order and continuity @qf = sort @qf; my ($head) = ($qf[0] =~ /(\d+)$/); my ($tail) = ($qf[-1] =~ /(\d+)$/); $head += 0; $tail += 0; if ($tail-$head+1 != @qf || $tail > $iMaxFiles) { die "broken queue: missing file(s) or wrong tail\n"; } # collect some counters about the queue, assuming all are unprocessed entries. my $sizeOnDisk = 0; my $iQueueSize = 0; chdir($opt{spool}) or die "can't chdir to spool: $!"; print STDERR "traversing ". @qf ." files, please wait...\n"; for (@qf) { open FH, "<", $_ or die "can't read queue file $_\n"; $sizeOnDisk += (stat FH)[7]; while () { $iQueueSize++ if /^new("qqueue",1); $qqueue->property("iQueueSize", "INT", $iQueueSize); $qqueue->property("tVars.disk.sizeOnDisk", "INT64", $sizeOnDisk); $qqueue->property("tVars.disk.bytesRead", "INT64", 0); # runtime/stream.h: strmType_t my $STREAMTYPE_FILE_CIRCULAR = 1; # runtime/stream.h: strmMode_t my $STREAMMODE_READ = 1; my $STREAMMODE_WRITE_APPEND = 4; # runtime/stream.c: strmSerialize() # write to end my $strm_Write = Rsyslog::Obj->new("strm",1); $strm_Write->property( "iCurrFNum", "INT", $tail); $strm_Write->property( "pszFName", "PSZ", $opt{basename}); $strm_Write->property( "iMaxFiles", "INT", $iMaxFiles); $strm_Write->property( "bDeleteOnClose", "INT", 0); $strm_Write->property( "sType", "INT", $STREAMTYPE_FILE_CIRCULAR); $strm_Write->property("tOperationsMode", "INT", $STREAMMODE_WRITE_APPEND); $strm_Write->property( "tOpenMode", "INT", 0600); $strm_Write->property( "iCurrOffs","INT64", $iCurrOffs_Write); # read from head my $strm_ReadDel = Rsyslog::Obj->new("strm",1); $strm_ReadDel->property( "iCurrFNum", "INT", $head); $strm_ReadDel->property( "pszFName", "PSZ", $opt{basename}); $strm_ReadDel->property( "iMaxFiles", "INT", $iMaxFiles); $strm_ReadDel->property( "bDeleteOnClose", "INT", 1); $strm_ReadDel->property( "sType", "INT", $STREAMTYPE_FILE_CIRCULAR); $strm_ReadDel->property("tOperationsMode", "INT", $STREAMMODE_READ); $strm_ReadDel->property( "tOpenMode", "INT", 0600); $strm_ReadDel->property( "iCurrOffs","INT64", 0); # .qi print $qqueue->serialize(); print $strm_Write->serialize(); print $strm_ReadDel->serialize(); exit; #----------------------------------------------------------------------------- package Rsyslog::Serializable; # runtime/obj.c sub COOKIE_OBJLINE { '<' } sub COOKIE_PROPLINE { '+' } sub COOKIE_ENDLINE { '>' } sub COOKIE_BLANKLINE { '.' } # VARTYPE(short_ptype) sub VARTYPE { my ($t) = @_; # runtime/obj-types.h: propType_t my $ptype = "PROPTYPE_".$t; # runtime/var.h: varType_t my %vm = ( VARTYPE_NONE => 0, VARTYPE_STR => 1, VARTYPE_NUMBER => 2, VARTYPE_SYSLOGTIME => 3, ); # runtime/obj.c: SerializeProp() my %p2v = ( #PROPTYPE_NONE => "", PROPTYPE_PSZ => "VARTYPE_STR", PROPTYPE_SHORT => "VARTYPE_NUMBER", PROPTYPE_INT => "VARTYPE_NUMBER", PROPTYPE_LONG => "VARTYPE_NUMBER", PROPTYPE_INT64 => "VARTYPE_NUMBER", PROPTYPE_CSTR => "VARTYPE_STR", #PROPTYPE_SYSLOGTIME => "VARTYPE_SYSLOGTIME", ); my $vtype = $p2v{$ptype}; unless ($vtype) { die "property type $t is not supported!\n"; } return $vm{$vtype}; } sub serialize { my $self = shift; # runtime/obj.c: objSerializeHeader() my $x = COOKIE_OBJLINE(); $x .= join(":", $self->type(), $self->cver(), $self->id(), $self->version()); $x .= ":\n"; for ( values %{$self->{props}} ) { # runtime/obj.c: SerializeProp() $x .= COOKIE_PROPLINE(); $x .= join(":", $_->{name}, VARTYPE($_->{type}), length($_->{value}), $_->{value}); $x .= ":\n"; } # runtime/obj.c: EndSerialize() $x .= COOKIE_ENDLINE() . "End\n"; $x .= COOKIE_BLANKLINE() . "\n"; } # constructor: new(id,version) sub new { my ($class, $id, $version) = @_; $class = ref $class if ref $class; bless { id => $id, version => $version, props => {}, }, $class; } sub id { my $self = shift; if (@_) { my $x = $self->{id}; $self->{id} = shift; return $x; } return $self->{id}; } sub version { my $self = shift; if (@_) { my $x = $self->{version}; $self->{version} = shift; return $x; } return $self->{version}; } # property(name, type, value) sub property { my $self = shift; my $name = shift; if (@_) { my $x = $self->{props}{$name}; $self->{props}{$name}{name} = $name; $self->{props}{$name}{type} = shift; $self->{props}{$name}{value} = shift; return $x; } return $self->{props}{$name}; } 1; package Rsyslog::OPB; use base qw(Rsyslog::Serializable); sub type { 'OPB' } sub cver { 1 } sub new { shift->SUPER::new(@_) } 1; package Rsyslog::Obj; use base qw(Rsyslog::Serializable); sub type { 'Obj' } sub cver { 1 } sub new { shift->SUPER::new(@_) } 1; rsyslog-8.2512.0/tools/PaxHeaders/smtradfwd.h0000644000000000000000000000013115055605325016042 xustar0030 mtime=1756826325.661800864 29 atime=1764930982.72372342 30 ctime=1764935924.174591752 rsyslog-8.2512.0/tools/smtradfwd.h0000664000175000017500000000226615055605325015515 0ustar00rgerrger/* smtradfwd.h * * File begun on 2010-06-04 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SMTRADFWD_H_INCLUDED #define SMTRADFWD_H_INCLUDED 1 /* prototypes */ rsRetVal modInitsmtradfwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef SMTRADFWD_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/smfwd.c0000644000000000000000000000013215055605325015163 xustar0030 mtime=1756826325.661800864 30 atime=1764931034.722586719 30 ctime=1764935924.167591645 rsyslog-8.2512.0/tools/smfwd.c0000664000175000017500000001012715055605325014630 0ustar00rgerrger/* smfwd.c * This is a strgen module for the traditional (network) forwarding format. * * Format generated: * "<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%" * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2010-06-01 by RGerhards * * Copyright 2010-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "unicode-helper.h" MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP; STRGEN_NAME("RSYSLOG_ForwardFormat") /* internal structures */ DEF_SMOD_STATIC_DATA; /* config data */ /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. */ BEGINstrgen register int iBuf; const char *pPRI; size_t lenPRI; uchar *pTimeStamp; size_t lenTimeStamp; uchar *pHOSTNAME; size_t lenHOSTNAME; uchar *pTAG; int lenTAG; uchar *pMSG; size_t lenMSG; size_t lenTotal; CODESTARTstrgen; /* first obtain all strings and their length (if not fixed) */ pPRI = getPRI(pMsg); lenPRI = strlen(pPRI); pTimeStamp = (uchar *)getTimeReported(pMsg, tplFmtRFC3339Date); lenTimeStamp = ustrlen(pTimeStamp); pHOSTNAME = (uchar *)getHOSTNAME(pMsg); lenHOSTNAME = getHOSTNAMELen(pMsg); getTAG(pMsg, &pTAG, &lenTAG, LOCK_MUTEX); if (lenTAG > 32) lenTAG = 32; /* for forwarding, a max of 32 chars is permitted (RFC!) */ pMSG = getMSG(pMsg); lenMSG = getMSGLen(pMsg); /* calculate len, constants for spaces and similar fixed strings */ lenTotal = 1 + lenPRI + 1 + lenTimeStamp + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 1; if (pMSG[0] != ' ') ++lenTotal; /* then we need to introduce one additional space */ /* now make sure buffer is large enough */ if (lenTotal >= iparam->lenBuf) CHKiRet(ExtendBuf(iparam, lenTotal)); /* and concatenate the resulting string */ iparam->param[0] = '<'; memcpy(iparam->param + 1, pPRI, lenPRI); iBuf = lenPRI + 1; iparam->param[iBuf++] = '>'; memcpy(iparam->param + iBuf, pTimeStamp, lenTimeStamp); iBuf += lenTimeStamp; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pHOSTNAME, lenHOSTNAME); iBuf += lenHOSTNAME; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pTAG, lenTAG); iBuf += lenTAG; if (pMSG[0] != ' ') iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pMSG, lenMSG); iBuf += lenMSG; /* string terminator */ iparam->param[iBuf] = '\0'; iparam->lenStr = lenTotal - 1; /* do not count \0! */ finalize_it: ENDstrgen BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_SMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(smfwd) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf( "rsyslog standard (network) forward format strgen init called, compiled with version" " %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/omdiscard.h0000644000000000000000000000013215055605325016015 xustar0030 mtime=1756826325.659800834 30 atime=1764930982.715723286 30 ctime=1764935924.145591308 rsyslog-8.2512.0/tools/omdiscard.h0000664000175000017500000000240715055605325015464 0ustar00rgerrger/* omdiscard.h * These are the definitions for the built-in discard output module. * * File begun on 2007-07-24 by RGerhards * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMDISCARD_H_INCLUDED #define OMDISCARD_H_INCLUDED 1 /* prototypes */ rsRetVal modInitDiscard(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef OMDISCARD_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/smtradfile.c0000644000000000000000000000013215055605325016175 xustar0030 mtime=1756826325.661800864 30 atime=1764931034.220578439 30 ctime=1764935924.158591507 rsyslog-8.2512.0/tools/smtradfile.c0000664000175000017500000000740215055605325015644 0ustar00rgerrger/* smtradfile.c * This is a strgen module for the traditional file format. * * Format generated: * "%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2010-06-01 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "unicode-helper.h" MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP; STRGEN_NAME("RSYSLOG_TraditionalFileFormat") /* internal structures */ DEF_SMOD_STATIC_DATA; /* config data */ /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. */ BEGINstrgen register int iBuf; uchar *pTimeStamp; uchar *pHOSTNAME; size_t lenHOSTNAME; uchar *pTAG; int lenTAG; uchar *pMSG; size_t lenMSG; size_t lenTotal; CODESTARTstrgen; /* first obtain all strings and their length (if not fixed) */ pTimeStamp = (uchar *)getTimeReported(pMsg, tplFmtRFC3164Date); pHOSTNAME = (uchar *)getHOSTNAME(pMsg); lenHOSTNAME = getHOSTNAMELen(pMsg); getTAG(pMsg, &pTAG, &lenTAG, LOCK_MUTEX); pMSG = getMSG(pMsg); lenMSG = getMSGLen(pMsg); /* calculate len, constants for spaces and similar fixed strings */ lenTotal = CONST_LEN_TIMESTAMP_3164 + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 2; if (pMSG[0] != ' ') ++lenTotal; /* then we need to introduce one additional space */ /* now make sure buffer is large enough */ if (lenTotal >= iparam->lenBuf) CHKiRet(ExtendBuf(iparam, lenTotal)); /* and concatenate the resulting string */ memcpy(iparam->param, pTimeStamp, CONST_LEN_TIMESTAMP_3164); iparam->param[CONST_LEN_TIMESTAMP_3164] = ' '; memcpy(iparam->param + CONST_LEN_TIMESTAMP_3164 + 1, pHOSTNAME, lenHOSTNAME); iBuf = CONST_LEN_TIMESTAMP_3164 + 1 + lenHOSTNAME; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pTAG, lenTAG); iBuf += lenTAG; if (pMSG[0] != ' ') iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pMSG, lenMSG); iBuf += lenMSG; /* trailer */ iparam->param[iBuf++] = '\n'; iparam->param[iBuf] = '\0'; iparam->lenStr = lenTotal - 1; /* do not count \0! */ finalize_it: ENDstrgen BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_SMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(smtradfile) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf("traditional file format strgen init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/omfwd.c0000644000000000000000000000013215103061376015153 xustar0030 mtime=1762419454.862381423 30 atime=1764931032.230545603 30 ctime=1764935924.128591048 rsyslog-8.2512.0/tools/omfwd.c0000664000175000017500000024761215103061376014633 0ustar00rgerrger/* omfwd.c * This is the implementation of the build-in forwarding output module. * * NOTE: read comments in module-template.h to understand how this file * works! * * Copyright 2007-2024 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "net.h" #include "netstrms.h" #include "netstrm.h" #include "omfwd.h" #include "template.h" #include "msg.h" #include "tcpclt.h" #include "cfsysline.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "unicode-helper.h" #include "parserif.h" #include "ratelimit.h" #include "statsobj.h" #include "datetime.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omfwd") /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(netstrms) DEFobjCurrIf(netstrm) DEFobjCurrIf(tcpclt) DEFobjCurrIf(statsobj) DEFobjCurrIf(datetime) /* some local constants (just) for better readybility */ #define IS_FLUSH 1 #define NO_FLUSH 0 typedef struct _targetStats { statsobj_t *stats; intctr_t sentBytes; intctr_t sentMsgs; DEF_ATOMIC_HELPER_MUT64(mut_sentBytes); DEF_ATOMIC_HELPER_MUT64(mut_sentMsgs); } targetStats_t; typedef struct _instanceData { uchar *tplName; /* name of assigned template */ uchar *pszStrmDrvr; uchar *pszStrmDrvrAuthMode; uchar *pszStrmDrvrPermitExpiredCerts; permittedPeers_t *pPermPeers; int iStrmDrvrMode; int iStrmDrvrExtendedCertCheck; /* verify also purpose OID in certificate extended field */ int iStrmDrvrSANPreference; /* ignore CN when any SAN set */ int iStrmTlsVerifyDepth; /**< Verify Depth for certificate chains */ const uchar *pszStrmDrvrCAFile; const uchar *pszStrmDrvrCRLFile; const uchar *pszStrmDrvrKeyFile; const uchar *pszStrmDrvrCertFile; int nTargets; int nActiveTargets; /* how many targets have been active the last time? */ DEF_ATOMIC_HELPER_MUT(mut_nActiveTargets); char **target_name; int nPorts; char **ports; char *address; char *device; int compressionLevel; /* 0 - no compression, else level for zlib */ int protocol; char *networkNamespace; int originalNamespace; int iRebindInterval; /* rebind interval */ sbool bKeepAlive; int iKeepAliveIntvl; int iKeepAliveProbes; int iKeepAliveTime; int iConErrSkip; /* skipping excessive connection errors */ uchar *gnutlsPriorityString; int ipfreebind; #define FORW_UDP 0 #define FORW_TCP 1 /* following fields for UDP-based delivery */ int bSendToAll; int iUDPSendDelay; int UDPSendBuf; /* following fields for TCP-based delivery */ TCPFRAMINGMODE tcp_framing; uchar tcp_framingDelimiter; int bResendLastOnRecon; /* should the last message be re-sent on a successful reconnect? */ int bExtendedConnCheck; /* do extended connection checking? */ #define COMPRESS_NEVER 0 #define COMPRESS_SINGLE_MSG 1 /* old, single-message compression */ /* all other settings are for stream-compression */ #define COMPRESS_STREAM_ALWAYS 2 uint8_t compressionMode; sbool strmCompFlushOnTxEnd; /* flush stream compression on transaction end? */ unsigned poolResumeInterval; unsigned int ratelimitInterval; unsigned int ratelimitBurst; ratelimit_t *ratelimiter; targetStats_t *target_stats; } instanceData; typedef struct targetData { instanceData *pData; struct wrkrInstanceData *pWrkrData; /* forward def of struct */ netstrms_t *pNS; /* netstream subsystem */ netstrm_t *pNetstrm; /* our output netstream */ char *target_name; char *port; struct addrinfo *f_addr; int *pSockArray; /* sockets to use for UDP */ int bIsConnected; /* are we connected to remote host? 0 - no, 1 - yes, UDP means addr resolved */ int nXmit; /* number of transmissions since last (re-)bind */ tcpclt_t *pTCPClt; /* our tcpclt object */ sbool bzInitDone; /* did we do an init of zstrm already? */ z_stream zstrm; /* zip stream to use for tcp compression */ /* we know int is sufficient, as we have the fixed buffer size above! so no need for size_t */ int maxLenSndBuf; /* max usable length of sendbuf - primarily for testing */ int offsSndBuf; /* next free spot in send buffer */ time_t ttResume; targetStats_t *pTargetStats; /* sndBuf buffer size is intensionally fixed -- see no good reason to make configurable */ #define SNDBUF_FIXED_BUFFER_SIZE (16 * 1024) uchar sndBuf[SNDBUF_FIXED_BUFFER_SIZE]; } targetData_t; typedef struct wrkrInstanceData { instanceData *pData; targetData_t *target; int nXmit; /* number of transmissions since last (re-)bind */ unsigned actualTarget; unsigned wrkrID; /* an internal monotonically increasing id for correlating worker messages */ } wrkrInstanceData_t; static unsigned wrkrID = 0; /* config data */ typedef struct configSettings_s { uchar *pszTplName; /* name of the default template to use */ uchar *pszStrmDrvr; /* name of the stream driver to use */ int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ int bResendLastOnRecon; /* should the last message be re-sent on a successful reconnect? */ uchar *pszStrmDrvrAuthMode; /* authentication mode to use */ uchar *pszStrmDrvrPermitExpiredCerts; /* control how to handly expired certificates */ int iTCPRebindInterval; /* support for automatic re-binding (load balancers!). 0 - no rebind */ int iUDPRebindInterval; /* support for automatic re-binding (load balancers!). 0 - no rebind */ int bKeepAlive; int iKeepAliveIntvl; int iKeepAliveProbes; int iKeepAliveTime; int iConErrSkip; uchar *gnutlsPriorityString; permittedPeers_t *pPermPeers; } configSettings_t; static configSettings_t cs; /* tables for interfacing with the v6 config system */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = {{"iobuffer.maxsize", eCmdHdlrNonNegInt, 0}, {"template", eCmdHdlrGetWord, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"target", eCmdHdlrArray, CNFPARAM_REQUIRED}, {"address", eCmdHdlrGetWord, 0}, {"device", eCmdHdlrGetWord, 0}, {"port", eCmdHdlrArray, 0}, {"protocol", eCmdHdlrGetWord, 0}, {"networknamespace", eCmdHdlrGetWord, 0}, {"tcp_framing", eCmdHdlrGetWord, 0}, {"tcp_framedelimiter", eCmdHdlrInt, 0}, {"ziplevel", eCmdHdlrInt, 0}, {"compression.mode", eCmdHdlrGetWord, 0}, {"compression.stream.flushontxend", eCmdHdlrBinary, 0}, {"ipfreebind", eCmdHdlrInt, 0}, {"maxerrormessages", eCmdHdlrInt, CNFPARAM_DEPRECATED}, {"rebindinterval", eCmdHdlrInt, 0}, {"keepalive", eCmdHdlrBinary, 0}, {"keepalive.probes", eCmdHdlrNonNegInt, 0}, {"keepalive.time", eCmdHdlrNonNegInt, 0}, {"keepalive.interval", eCmdHdlrNonNegInt, 0}, {"conerrskip", eCmdHdlrNonNegInt, 0}, {"gnutlsprioritystring", eCmdHdlrString, 0}, {"streamdriver", eCmdHdlrGetWord, 0}, {"streamdriver.name", eCmdHdlrGetWord, 0}, /* alias for streamdriver */ {"streamdrivermode", eCmdHdlrInt, 0}, {"streamdriver.mode", eCmdHdlrInt, 0}, /* alias for streamdrivermode */ {"streamdriverauthmode", eCmdHdlrGetWord, 0}, {"streamdriver.authmode", eCmdHdlrGetWord, 0}, /* alias for streamdriverauthmode */ {"streamdriverpermittedpeers", eCmdHdlrGetWord, 0}, {"streamdriver.permitexpiredcerts", eCmdHdlrGetWord, 0}, {"streamdriver.CheckExtendedKeyPurpose", eCmdHdlrBinary, 0}, {"streamdriver.PrioritizeSAN", eCmdHdlrBinary, 0}, {"streamdriver.TlsVerifyDepth", eCmdHdlrPositiveInt, 0}, {"streamdriver.cafile", eCmdHdlrString, 0}, {"streamdriver.crlfile", eCmdHdlrString, 0}, {"streamdriver.keyfile", eCmdHdlrString, 0}, {"streamdriver.certfile", eCmdHdlrString, 0}, {"resendlastmsgonreconnect", eCmdHdlrBinary, 0}, {"extendedconnectioncheck", eCmdHdlrBinary, 0}, {"udp.sendtoall", eCmdHdlrBinary, 0}, {"udp.senddelay", eCmdHdlrInt, 0}, {"udp.sendbuf", eCmdHdlrSize, 0}, {"template", eCmdHdlrGetWord, 0}, {"pool.resumeinterval", eCmdHdlrPositiveInt, 0}, {"ratelimit.interval", eCmdHdlrInt, 0}, {"ratelimit.burst", eCmdHdlrInt, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ uchar *tplName; /* default template */ int maxLenSndBuf; /* default max usable length of sendbuf - primarily for testing */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ static rsRetVal initTCP(wrkrInstanceData_t *pWrkrData); BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars; cs.pszTplName = NULL; /* name of the default template to use */ cs.pszStrmDrvr = NULL; /* name of the stream driver to use */ cs.iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ cs.bResendLastOnRecon = 0; /* should the last message be re-sent on a successful reconnect? */ cs.pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ cs.iUDPRebindInterval = 0; /* support for automatic re-binding (load balancers!). 0 - no rebind */ cs.iTCPRebindInterval = 0; /* support for automatic re-binding (load balancers!). 0 - no rebind */ cs.pPermPeers = NULL; ENDinitConfVars static rsRetVal doTryResume(targetData_t *); static rsRetVal doZipFinish(targetData_t *); /* this function gets the default template. It coordinates action between * old-style and new-style configuration parts. */ static uchar *getDfltTpl(void) { if (loadModConf != NULL && loadModConf->tplName != NULL) return loadModConf->tplName; else if (cs.pszTplName == NULL) return (uchar *)"RSYSLOG_TraditionalForwardFormat"; else return cs.pszTplName; } /* set the default template to be used * This is a module-global parameter, and as such needs special handling. It needs to * be coordinated with values set via the v2 config system (rsyslog v6+). What we do * is we do not permit this directive after the v2 config system has been used to set * the parameter. */ static rsRetVal setLegacyDfltTpl(void __attribute__((unused)) * pVal, uchar *newVal) { DEFiRet; if (loadModConf != NULL && loadModConf->tplName != NULL) { free(newVal); LogError(0, RS_RET_ERR, "omfwd default template already set via module " "global parameter - can no longer be changed"); ABORT_FINALIZE(RS_RET_ERR); } free(cs.pszTplName); cs.pszTplName = newVal; finalize_it: RETiRet; } /* Close the UDP sockets. * rgerhards, 2009-05-29 */ static rsRetVal closeUDPSockets(wrkrInstanceData_t *pWrkrData) { DEFiRet; if (pWrkrData->target[0].pSockArray != NULL) { net.closeUDPListenSockets(pWrkrData->target[0].pSockArray); pWrkrData->target[0].pSockArray = NULL; freeaddrinfo(pWrkrData->target[0].f_addr); pWrkrData->target[0].f_addr = NULL; } pWrkrData->target[0].bIsConnected = 0; RETiRet; } static void DestructTCPTargetData(targetData_t *const pTarget) { // TODO: do we need to do a final send? if so, old bug! doZipFinish(pTarget); if (pTarget->pNetstrm != NULL) { netstrm.Destruct(&pTarget->pNetstrm); } if (pTarget->pNS != NULL) { netstrms.Destruct(&pTarget->pNS); } /* set resume time for interal retries */ datetime.GetTime(&pTarget->ttResume); pTarget->ttResume += pTarget->pData->poolResumeInterval; pTarget->bIsConnected = 0; DBGPRINTF("omfwd: DestructTCPTargetData: %p %s:%s, connected %d, ttResume %lld\n", &pTarget, pTarget->target_name, pTarget->port, pTarget->bIsConnected, (long long)pTarget->ttResume); } /* destruct the TCP helper objects * This, for example, is needed after something went wrong. * This function is void because it "can not" fail. * rgerhards, 2008-06-04 * Note that we DO NOT discard the current buffer contents * (if any). This permits us to save data between sessions. In * the worst case, some duplication occurs, but we do not * loose data. */ static void DestructTCPInstanceData(wrkrInstanceData_t *pWrkrData) { LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: Destructing TCP target pool of %d targets (DestructTCPInstanceData)", pWrkrData->pData->nTargets); for (int j = 0; j < pWrkrData->pData->nTargets; ++j) { DestructTCPTargetData(&(pWrkrData->target[j])); } } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; pModConf->tplName = NULL; pModConf->maxLenSndBuf = -1; ENDbeginCnfLoad BEGINsetModCnf int i; CODESTARTsetModCnf; const struct cnfparamvals *const __restrict__ pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for omfwd:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "template")) { loadModConf->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (cs.pszTplName != NULL) { LogError(0, RS_RET_DUP_PARAM, "omfwd: warning: default template " "was already set via legacy directive - may lead to inconsistent " "results."); } } else if (!strcmp(modpblk.descr[i].name, "iobuffer.maxsize")) { const int newLen = (int)pvals[i].val.d.n; if (newLen > SNDBUF_FIXED_BUFFER_SIZE) { LogMsg(0, RS_RET_PARAM_ERROR, LOG_WARNING, "omfwd: module parameter \"iobuffer.maxsize\" specified larger " "than actual buffer size (%d bytes) - ignored", SNDBUF_FIXED_BUFFER_SIZE); } else { if (newLen > 0) { loadModConf->maxLenSndBuf = newLen; } } } else { LogMsg(0, RS_RET_INTERNAL_ERROR, LOG_ERR, "omfwd: internal error, non-handled param '%s' in beginCnfLoad", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ /* free legacy config vars */ free(cs.pszTplName); cs.pszTplName = NULL; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free(pModConf->tplName); ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; /* We always have at least one target and port */ pData->nTargets = 1; pData->nActiveTargets = 0; INIT_ATOMIC_HELPER_MUT64(pData->mut_nActiveTargets); pData->nPorts = 1; pData->target_name = NULL; if (cs.pszStrmDrvr != NULL) CHKmalloc(pData->pszStrmDrvr = (uchar *)strdup((char *)cs.pszStrmDrvr)); if (cs.pszStrmDrvrAuthMode != NULL) CHKmalloc(pData->pszStrmDrvrAuthMode = (uchar *)strdup((char *)cs.pszStrmDrvrAuthMode)); finalize_it: ENDcreateInstance /* Among others, all worker-specific targets are initialized here. */ BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; time_t ttNow; datetime.GetTime(&ttNow); ttNow--; /* make sure it is expired */ assert(pData->nTargets > 0); pWrkrData->actualTarget = 0; pWrkrData->wrkrID = wrkrID++; CHKmalloc(pWrkrData->target = (targetData_t *)calloc(pData->nTargets, sizeof(targetData_t))); for (int i = 0; i < pData->nTargets; ++i) { pWrkrData->target[i].pData = pWrkrData->pData; pWrkrData->target[i].pWrkrData = pWrkrData; pWrkrData->target[i].target_name = pData->target_name[i]; pWrkrData->target[i].pTargetStats = &(pData->target_stats[i]); /* if insufficient ports are configured, we use ports[0] for the * missing ports. */ pWrkrData->target[i].port = pData->ports[(i < pData->nPorts) ? i : 0]; pWrkrData->target[i].maxLenSndBuf = (runModConf->maxLenSndBuf == -1) ? SNDBUF_FIXED_BUFFER_SIZE : runModConf->maxLenSndBuf; pWrkrData->target[i].offsSndBuf = 0; pWrkrData->target[i].ttResume = ttNow; } iRet = initTCP(pWrkrData); LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: worker with id %u initialized", pWrkrData->wrkrID); finalize_it: ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; free(pData->pszStrmDrvr); free(pData->pszStrmDrvrAuthMode); free(pData->pszStrmDrvrPermitExpiredCerts); free(pData->gnutlsPriorityString); free(pData->networkNamespace); if (pData->ports != NULL) { /* could happen in error case (very unlikely) */ for (int j = 0; j < pData->nPorts; ++j) { free(pData->ports[j]); } free(pData->ports); } if (pData->target_stats != NULL) { for (int j = 0; j < pData->nTargets; ++j) { free(pData->target_name[j]); if (pData->target_stats[j].stats != NULL) statsobj.Destruct(&(pData->target_stats[j].stats)); } free(pData->target_stats); } free(pData->target_name); free(pData->address); free(pData->device); free((void *)pData->pszStrmDrvrCAFile); free((void *)pData->pszStrmDrvrCRLFile); free((void *)pData->pszStrmDrvrKeyFile); free((void *)pData->pszStrmDrvrCertFile); net.DestructPermittedPeers(&pData->pPermPeers); if (pData->ratelimiter != NULL) { ratelimitDestruct(pData->ratelimiter); pData->ratelimiter = NULL; } DESTROY_ATOMIC_HELPER_MUT(pData->mut_nActiveTargets); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: [wrkr %u/%" PRIuPTR "] Destructing worker instance", pWrkrData->wrkrID, (uintptr_t)pthread_self()); DestructTCPInstanceData(pWrkrData); closeUDPSockets(pWrkrData); if (pWrkrData->pData->protocol == FORW_TCP) { for (int i = 0; i < pWrkrData->pData->nTargets; ++i) { tcpclt.Destruct(&pWrkrData->target[i].pTCPClt); } } free(pWrkrData->target); /* note: this frees all target memory,calloc()ed array! */ ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; dbgprintf("omfwd\n"); ENDdbgPrintInstInfo /* Send a message via UDP * rgehards, 2007-12-20 */ #define UDP_MAX_MSGSIZE 65507 /* limit per RFC definition */ static rsRetVal UDPSend(wrkrInstanceData_t *__restrict__ const pWrkrData, uchar *__restrict__ const msg, size_t len) { DEFiRet; struct addrinfo *r; int i; ssize_t lsent = 0; sbool bSendSuccess; sbool reInit = RSFALSE; int lasterrno = ENOENT; int lasterr_sock = -1; targetData_t *const pTarget = &(pWrkrData->target[0]); targetStats_t *const pTargetStats = &(pWrkrData->pData->target_stats[0]); if (pWrkrData->pData->iRebindInterval && (pTarget->nXmit++ % pWrkrData->pData->iRebindInterval == 0)) { dbgprintf("omfwd dropping UDP 'connection' (as configured)\n"); pTarget->nXmit = 1; /* else we have an addtl wrap at 2^31-1 */ CHKiRet(closeUDPSockets(pWrkrData)); } if (pWrkrData->target[0].pSockArray == NULL) { CHKiRet(doTryResume(pTarget)); /* for UDP, we have only a single tartget! */ } if (pTarget->pSockArray == NULL) { FINALIZE; } if (len > UDP_MAX_MSGSIZE) { LogError(0, RS_RET_UDP_MSGSIZE_TOO_LARGE, "omfwd/udp: message is %u " "bytes long, but UDP can send at most %d bytes (by RFC limit) " "- truncating message", (unsigned)len, UDP_MAX_MSGSIZE); len = UDP_MAX_MSGSIZE; } /* we need to track if we have success sending to the remote * peer. Success is indicated by at least one sendto() call * succeeding. We track this be bSendSuccess. We can not simply * rely on lsent, as a call might initially work, but a later * call fails. Then, lsent has the error status, even though * the sendto() succeeded. -- rgerhards, 2007-06-22 */ bSendSuccess = RSFALSE; for (r = pTarget->f_addr; r; r = r->ai_next) { int runSockArrayLoop = 1; for (i = 0; runSockArrayLoop && (i < *pTarget->pSockArray); i++) { int try_send = 1; size_t lenThisTry = len; while (try_send) { lsent = sendto(pTarget->pSockArray[i + 1], msg, lenThisTry, 0, r->ai_addr, r->ai_addrlen); if (lsent == (ssize_t)lenThisTry) { bSendSuccess = RSTRUE; ATOMIC_ADD_uint64(&pTargetStats->sentBytes, &pTargetStats->mut_sentBytes, lenThisTry); try_send = 0; runSockArrayLoop = 0; } else if (errno == EMSGSIZE) { const size_t newlen = (lenThisTry > 1024) ? lenThisTry - 1024 : 512; LogError(0, RS_RET_UDP_MSGSIZE_TOO_LARGE, "omfwd/udp: send failed due to message being too " "large for this system. Message size was %u bytes. " "Truncating to %u bytes and retrying.", (unsigned)lenThisTry, (unsigned)newlen); lenThisTry = newlen; } else { reInit = RSTRUE; lasterrno = errno; lasterr_sock = pTarget->pSockArray[i + 1]; LogError(lasterrno, RS_RET_ERR_UDPSEND, "omfwd/udp: socket %d: sendto() error", lasterr_sock); try_send = 0; } } } if (lsent == (ssize_t)len && !pWrkrData->pData->bSendToAll) break; } /* one or more send failures; close sockets and re-init */ if (reInit == RSTRUE) { CHKiRet(closeUDPSockets(pWrkrData)); } /* finished looping */ if (bSendSuccess == RSTRUE) { if (pWrkrData->pData->iUDPSendDelay > 0) { srSleep(pWrkrData->pData->iUDPSendDelay / 1000000, pWrkrData->pData->iUDPSendDelay % 1000000); } } else { LogError(lasterrno, RS_RET_ERR_UDPSEND, "omfwd: socket %d: error %d sending via udp", lasterr_sock, lasterrno); iRet = RS_RET_SUSPENDED; } finalize_it: RETiRet; } /* set the permitted peers -- rgerhards, 2008-05-19 */ static rsRetVal setPermittedPeer(void __attribute__((unused)) * pVal, uchar *pszID) { DEFiRet; CHKiRet(net.AddPermittedPeer(&cs.pPermPeers, pszID)); free(pszID); /* no longer needed, but we must free it as of interface def */ finalize_it: RETiRet; } /* CODE FOR SENDING TCP MESSAGES */ /* This is a common function so that we can emit consistent error * messages whenever we have trouble with a connection, e.g. when * sending or checking if it's broken. */ static void emitConnectionErrorMsg(const targetData_t *const pTarget, const rsRetVal iRet) { wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; if (iRet == RS_RET_IO_ERROR || iRet == RS_RET_PEER_CLOSED_CONN) { static unsigned int conErrCnt = 0; const int skipFactor = pWrkrData->pData->iConErrSkip; const char *actualErrMsg; if (iRet == RS_RET_PEER_CLOSED_CONN) { actualErrMsg = "remote server closed connection. "; } else { actualErrMsg = "we had a generic or IO error with the remote server. " "The actual error message should already have been provided. "; } if (skipFactor <= 1) { /* All the connection errors are printed. */ LogError(0, iRet, "omfwd: [wrkr %u/%" PRIuPTR "] %s Server is %s:%s. " "This can be caused by the remote server or an interim system like a load " "balancer or firewall. Rsyslog will re-open the connection if configured " "to do so.", pTarget->pWrkrData->wrkrID, (uintptr_t)pthread_self(), actualErrMsg, pTarget->target_name, pTarget->port); } else if ((conErrCnt++ % skipFactor) == 0) { /* Every N'th error message is printed where N is a skipFactor. */ LogError(0, iRet, "omfwd: [wrkr %u] %s Server is %s:%s. " "This can be caused by the remote server or an interim system like a load " "balancer or firewall. Rsyslog will re-open the connection if configured " "to do so. Note that the next %d connection error messages will be " "skipped.", pTarget->pWrkrData->wrkrID, actualErrMsg, pTarget->target_name, pTarget->port, skipFactor - 1); } } else { LogError(0, iRet, "omfwd: TCPSendBuf error %d, destruct TCP Connection to %s:%s", iRet, pTarget->target_name, pTarget->port); } } /* hack to check connections for plain tcp syslog - see ptcp driver for details */ static rsRetVal CheckConnection(targetData_t *const pTarget) { DEFiRet; if ((pTarget->pData->protocol == FORW_TCP) && (pTarget->pData->bExtendedConnCheck)) { CHKiRet(netstrm.CheckConnection(pTarget->pNetstrm)); } finalize_it: if (iRet != RS_RET_OK) { emitConnectionErrorMsg(pTarget, iRet); DestructTCPTargetData(pTarget); iRet = RS_RET_SUSPENDED; } RETiRet; } static rsRetVal TCPSendBufUncompressed(targetData_t *const pTarget, uchar *const buf, const unsigned len) { DEFiRet; unsigned alreadySent; ssize_t lenSend; alreadySent = 0; if (pTarget->pData->bExtendedConnCheck) { CHKiRet(netstrm.CheckConnection(pTarget->pNetstrm)); /* hack for plain tcp syslog - see ptcp driver for details */ } while (alreadySent != len) { lenSend = len - alreadySent; CHKiRet(netstrm.Send(pTarget->pNetstrm, buf + alreadySent, &lenSend)); DBGPRINTF("omfwd: TCP sent %zd bytes, requested %u\n", lenSend, len - alreadySent); alreadySent += lenSend; } ATOMIC_ADD_uint64(&pTarget->pTargetStats->sentBytes, &pTarget->pTargetStats->mut_sentBytes, len); finalize_it: if (iRet != RS_RET_OK) { emitConnectionErrorMsg(pTarget, iRet); DestructTCPTargetData(pTarget); iRet = RS_RET_SUSPENDED; } RETiRet; } static rsRetVal TCPSendBufCompressed(targetData_t *pTarget, uchar *const buf, unsigned len, sbool bIsFlush) { wrkrInstanceData_t *const pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; int zRet; /* zlib return state */ unsigned outavail; uchar zipBuf[32 * 1024]; int op; DEFiRet; if (!pTarget->bzInitDone) { /* allocate deflate state */ pTarget->zstrm.zalloc = Z_NULL; pTarget->zstrm.zfree = Z_NULL; pTarget->zstrm.opaque = Z_NULL; /* see note in file header for the params we use with deflateInit2() */ zRet = deflateInit(&pTarget->zstrm, pWrkrData->pData->compressionLevel); if (zRet != Z_OK) { DBGPRINTF("error %d returned from zlib/deflateInit()\n", zRet); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } pTarget->bzInitDone = RSTRUE; } /* now doing the compression */ pTarget->zstrm.next_in = (Bytef *)buf; pTarget->zstrm.avail_in = len; if (pWrkrData->pData->strmCompFlushOnTxEnd && bIsFlush) op = Z_SYNC_FLUSH; else op = Z_NO_FLUSH; /* run deflate() on buffer until everything has been compressed */ do { DBGPRINTF("omfwd: in deflate() loop, avail_in %d, total_in %ld, isFlush %d\n", pTarget->zstrm.avail_in, pTarget->zstrm.total_in, bIsFlush); pTarget->zstrm.avail_out = sizeof(zipBuf); pTarget->zstrm.next_out = zipBuf; zRet = deflate(&pTarget->zstrm, op); /* no bad return value */ DBGPRINTF("after deflate, ret %d, avail_out %d\n", zRet, pTarget->zstrm.avail_out); outavail = sizeof(zipBuf) - pTarget->zstrm.avail_out; if (outavail != 0) { CHKiRet(TCPSendBufUncompressed(pTarget, zipBuf, outavail)); } } while (pTarget->zstrm.avail_out == 0); finalize_it: RETiRet; } static rsRetVal TCPSendBuf(targetData_t *pTarget, uchar *buf, unsigned len, sbool bIsFlush) { wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; DEFiRet; if (pWrkrData->pData->compressionMode >= COMPRESS_STREAM_ALWAYS) iRet = TCPSendBufCompressed(pTarget, buf, len, bIsFlush); else iRet = TCPSendBufUncompressed(pTarget, buf, len); RETiRet; } /* finish zlib buffer, to be called before closing the ZIP file (if * running in stream mode). */ static rsRetVal doZipFinish(targetData_t *pTarget) { int zRet; /* zlib return state */ DEFiRet; unsigned outavail; uchar zipBuf[32 * 1024]; if (!pTarget->bzInitDone) goto done; // TODO: can we get this into a single common function? pTarget->zstrm.avail_in = 0; /* run deflate() on buffer until everything has been compressed */ do { DBGPRINTF("in deflate() loop, avail_in %d, total_in %ld\n", pTarget->zstrm.avail_in, pTarget->zstrm.total_in); pTarget->zstrm.avail_out = sizeof(zipBuf); pTarget->zstrm.next_out = zipBuf; zRet = deflate(&pTarget->zstrm, Z_FINISH); /* no bad return value */ DBGPRINTF("after deflate, ret %d, avail_out %d\n", zRet, pTarget->zstrm.avail_out); outavail = sizeof(zipBuf) - pTarget->zstrm.avail_out; if (outavail != 0) { CHKiRet(TCPSendBufUncompressed(pTarget, zipBuf, outavail)); } } while (pTarget->zstrm.avail_out == 0); finalize_it: zRet = deflateEnd(&pTarget->zstrm); if (zRet != Z_OK) { DBGPRINTF("error %d returned from zlib/deflateEnd()\n", zRet); } pTarget->bzInitDone = 0; done: RETiRet; } /* Add frame to send buffer (or send, if requried) */ static rsRetVal TCPSendFrame(void *pvData, char *msg, const size_t len) { DEFiRet; targetData_t *pTarget = (targetData_t *)pvData; DBGPRINTF("omfwd: add %zu bytes to send buffer (curr offs %u, max len %d) msg: %*s\n", len, pTarget->offsSndBuf, pTarget->maxLenSndBuf, (int)len, msg); if (pTarget->offsSndBuf != 0 && (pTarget->offsSndBuf + len) >= (size_t)pTarget->maxLenSndBuf) { /* no buffer space left, need to commit previous records. With the * current API, there unfortunately is no way to signal this * state transition to the upper layer. */ DBGPRINTF( "omfwd: we need to do a tcp send due to buffer " "out of space. If the transaction fails, this will " "lead to duplication of messages"); CHKiRet(TCPSendBuf(pTarget, pTarget->sndBuf, pTarget->offsSndBuf, NO_FLUSH)); pTarget->offsSndBuf = 0; } /* check if the message is too large to fit into buffer */ if (len > sizeof(pTarget->sndBuf)) { CHKiRet(TCPSendBuf(pTarget, (uchar *)msg, len, NO_FLUSH)); ABORT_FINALIZE(RS_RET_OK); /* committed everything so far */ } /* we now know the buffer has enough free space */ memcpy(pTarget->sndBuf + pTarget->offsSndBuf, msg, len); pTarget->offsSndBuf += len; iRet = RS_RET_DEFER_COMMIT; finalize_it: RETiRet; } /* initializes a TCP session to a single Target */ static rsRetVal TCPSendInitTarget(targetData_t *const pTarget) { DEFiRet; wrkrInstanceData_t *const pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; instanceData *pData = pWrkrData->pData; // TODO-RG: check error case - we need to make sure that we handle the situation correctly // when SOME calls fails - else we may get into big trouble during de-init if (pTarget->pNetstrm == NULL) { dbgprintf("TCPSendInitTarget CREATE %s:%s, conn %d\n", pTarget->target_name, pTarget->port, pTarget->bIsConnected); CHKiRet(netstrms.Construct(&pTarget->pNS)); /* the stream driver must be set before the object is finalized! */ CHKiRet(netstrms.SetDrvrName(pTarget->pNS, pData->pszStrmDrvr)); CHKiRet(netstrms.ConstructFinalize(pTarget->pNS)); /* now create the actual stream and connect to the server */ CHKiRet(netstrms.CreateStrm(pTarget->pNS, &pTarget->pNetstrm)); CHKiRet(netstrm.ConstructFinalize(pTarget->pNetstrm)); CHKiRet(netstrm.SetDrvrMode(pTarget->pNetstrm, pData->iStrmDrvrMode)); CHKiRet(netstrm.SetDrvrCheckExtendedKeyUsage(pTarget->pNetstrm, pData->iStrmDrvrExtendedCertCheck)); CHKiRet(netstrm.SetDrvrPrioritizeSAN(pTarget->pNetstrm, pData->iStrmDrvrSANPreference)); CHKiRet(netstrm.SetDrvrTlsVerifyDepth(pTarget->pNetstrm, pData->iStrmTlsVerifyDepth)); /* now set optional params, but only if they were actually configured */ if (pData->pszStrmDrvrAuthMode != NULL) { CHKiRet(netstrm.SetDrvrAuthMode(pTarget->pNetstrm, pData->pszStrmDrvrAuthMode)); } /* Call SetDrvrPermitExpiredCerts required * when param is NULL default handling for ExpiredCerts is set! */ CHKiRet(netstrm.SetDrvrPermitExpiredCerts(pTarget->pNetstrm, pData->pszStrmDrvrPermitExpiredCerts)); CHKiRet(netstrm.SetDrvrTlsCAFile(pTarget->pNetstrm, pData->pszStrmDrvrCAFile)); CHKiRet(netstrm.SetDrvrTlsCRLFile(pTarget->pNetstrm, pData->pszStrmDrvrCRLFile)); CHKiRet(netstrm.SetDrvrTlsKeyFile(pTarget->pNetstrm, pData->pszStrmDrvrKeyFile)); CHKiRet(netstrm.SetDrvrTlsCertFile(pTarget->pNetstrm, pData->pszStrmDrvrCertFile)); if (pData->pPermPeers != NULL) { CHKiRet(netstrm.SetDrvrPermPeers(pTarget->pNetstrm, pData->pPermPeers)); } /* params set, now connect */ if (pData->gnutlsPriorityString != NULL) { CHKiRet(netstrm.SetGnutlsPriorityString(pTarget->pNetstrm, pData->gnutlsPriorityString)); } CHKiRet(netstrm.Connect(pTarget->pNetstrm, glbl.GetDefPFFamily(runModConf->pConf), (uchar *)pTarget->port, (uchar *)pTarget->target_name, pData->device)); /* set keep-alive if enabled */ if (pData->bKeepAlive) { CHKiRet(netstrm.SetKeepAliveProbes(pTarget->pNetstrm, pData->iKeepAliveProbes)); CHKiRet(netstrm.SetKeepAliveIntvl(pTarget->pNetstrm, pData->iKeepAliveIntvl)); CHKiRet(netstrm.SetKeepAliveTime(pTarget->pNetstrm, pData->iKeepAliveTime)); CHKiRet(netstrm.EnableKeepAlive(pTarget->pNetstrm)); } LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: [wrkr %u] TCPSendInitTarget established connection to %s:%s", pTarget->pWrkrData->wrkrID, pTarget->target_name, pTarget->port); } finalize_it: if (iRet != RS_RET_OK) { dbgprintf("TCPSendInitTarget FAILED with %d.\n", iRet); DestructTCPTargetData(pTarget); } RETiRet; } /* Callback to initialize the provided target. * rgerhards, 2007-12-28 */ static rsRetVal TCPSendInit(void *pvData) { return TCPSendInitTarget((targetData_t *)pvData); } /* This callback function is called immediately before a send retry is attempted. * It shall clean up whatever makes sense. * side-note: TCPSendInit() is called afterwards by the generic tcp client code. */ static rsRetVal TCPSendPrepRetry(void *pvData) { DestructTCPTargetData((targetData_t *)pvData); /* Even if the destruct fails, it does not help to provide this info to * the upper layer. Also, DestructTCPTargtData() does currently not * provide a return status. */ return RS_RET_OK; } /* change to network namespace pData->networkNamespace and keep the file * descriptor to the original namespace. */ static rsRetVal changeToNs(instanceData *const pData __attribute__((unused))) { DEFiRet; #ifdef HAVE_SETNS if (pData->networkNamespace) { CHKiRet(net.netns_save(&pData->originalNamespace)); CHKiRet(net.netns_switch(pData->networkNamespace)); } finalize_it: #else /* #ifdef HAVE_SETNS */ dbgprintf("omfwd: OS does not support network namespaces\n"); #endif /* #ifdef HAVE_SETNS */ RETiRet; } /* return to the original network namespace. This should be called after * changeToNs(). */ static rsRetVal returnToOriginalNs(instanceData *const pData __attribute__((unused))) { DEFiRet; #ifdef HAVE_SETNS /* only in case a network namespace is given and a file descriptor to * the original namespace exists */ if (pData->networkNamespace && pData->originalNamespace >= 0) { CHKiRet(net.netns_restore(&pData->originalNamespace)); dbgprintf("omfwd: returned to original network namespace\n"); } finalize_it: #endif /* #ifdef HAVE_SETNS */ RETiRet; } /* count the actual number of active targets. */ static void countActiveTargets(const wrkrInstanceData_t *const pWrkrData) { int activeTargets = 0; for (int j = 0; j < pWrkrData->pData->nTargets; ++j) { if (pWrkrData->target[j].bIsConnected) { activeTargets++; } } /* Use atomic CAS to update the value safely */ int oldVal, newVal; do { oldVal = ATOMIC_FETCH_32BIT(&pWrkrData->pData->nActiveTargets, &pWrkrData->pData->mut_nActiveTargets); if (oldVal == activeTargets) { break; /* no change, so no log message either */ } newVal = activeTargets; } while (!ATOMIC_CAS(&pWrkrData->pData->nActiveTargets, oldVal, newVal, &pWrkrData->pData->mut_nActiveTargets)); if (oldVal != activeTargets) { LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: [wrkr %u] number of active targets changed from %d to %d", pWrkrData->wrkrID, oldVal, activeTargets); } } /* check if the action as while is working (one target is OK) or suspended. * Try to resume initially not working targets along the way. */ static rsRetVal poolTryResume(wrkrInstanceData_t *const pWrkrData) { DEFiRet; int oneTargetOK = 0; for (int j = 0; j < pWrkrData->pData->nTargets; ++j) { if (pWrkrData->target[j].bIsConnected) { if (CheckConnection(&(pWrkrData->target[j])) == RS_RET_OK) { oneTargetOK = 1; } } else { DBGPRINTF("omfwd: poolTryResume, calling tryResume, target %d\n", j); iRet = doTryResume(&(pWrkrData->target[j])); DBGPRINTF("omfwd: poolTryResume, done tryResume, target %d, iRet %d\n", j, iRet); if (iRet == RS_RET_OK) { oneTargetOK = 1; } } } if (oneTargetOK) { iRet = RS_RET_OK; } DBGPRINTF("poolTryResume: oneTargetOK %d, iRet %d\n", oneTargetOK, iRet); RETiRet; } /* try to resume connection if it is not ready * When done, we set the time of earliest resumption. This is to handle * suspend and resume within the target connection pool. * rgerhards, 2007-08-02 */ static rsRetVal doTryResume(targetData_t *pTarget) { wrkrInstanceData_t *const pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; instanceData *const pData = pWrkrData->pData; ; int iErr; struct addrinfo *res = NULL; struct addrinfo hints; int bBindRequired = 0; int bNeedReturnNs = 0; const char *address; DEFiRet; const int nActiveTargets = ATOMIC_FETCH_32BIT(&pTarget->pData->nActiveTargets, &pTarget->pData->mut_nActiveTargets); DBGPRINTF("doTryResume: isConnected: %d, ttResume %lld, LastActiveTargets: %d\n", pTarget->bIsConnected, (long long)pTarget->ttResume, nActiveTargets); if (pTarget->bIsConnected) FINALIZE; /* we look at the resume counter only if we have active targets at all - otherwise * rsyslog core handles the retry timing. */ if (pTarget->ttResume > 0 && nActiveTargets > 0) { time_t ttNow; datetime.GetTime(&ttNow); if (ttNow < pTarget->ttResume) { DBGPRINTF("omfwd: doTryResume: %s not yet time to retry, time %lld, ttResume %lld\n", pTarget->target_name, (long long)ttNow, (long long)pTarget->ttResume); ABORT_FINALIZE(RS_RET_SUSPENDED); } } /* The remote address is not yet known and needs to be obtained */ if (pData->protocol == FORW_UDP) { memset(&hints, 0, sizeof(hints)); /* port must be numeric, because config file syntax requires this */ hints.ai_flags = AI_NUMERICSERV; hints.ai_family = glbl.GetDefPFFamily(runModConf->pConf); hints.ai_socktype = SOCK_DGRAM; if ((iErr = (getaddrinfo(pTarget->target_name, pTarget->port, &hints, &res))) != 0) { LogError(0, RS_RET_SUSPENDED, "omfwd: could not get addrinfo for hostname '%s':'%s': %s", pTarget->target_name, pTarget->port, gai_strerror(iErr)); ABORT_FINALIZE(RS_RET_SUSPENDED); } address = pTarget->target_name; if (pData->address) { struct addrinfo *addr; /* The AF of the bind addr must match that of target */ hints.ai_family = res->ai_family; hints.ai_flags |= AI_PASSIVE; iErr = getaddrinfo(pData->address, pTarget->port, &hints, &addr); if (iErr != 0) { LogError(0, RS_RET_SUSPENDED, "omfwd: cannot use bind address '%s' for host '%s': %s", pData->address, pTarget->target_name, gai_strerror(iErr)); ABORT_FINALIZE(RS_RET_SUSPENDED); } freeaddrinfo(addr); bBindRequired = 1; address = pData->address; } DBGPRINTF("%s found, resuming.\n", pTarget->target_name); pTarget->f_addr = res; res = NULL; if (pTarget->pSockArray == NULL) { CHKiRet(changeToNs(pData)); bNeedReturnNs = 1; pTarget->pSockArray = net.create_udp_socket((uchar *)address, NULL, bBindRequired, 0, pData->UDPSendBuf, pData->ipfreebind, pData->device); CHKiRet(returnToOriginalNs(pData)); bNeedReturnNs = 0; } if (pTarget->pSockArray != NULL) { pTarget->bIsConnected = 1; } } else { CHKiRet(changeToNs(pData)); bNeedReturnNs = 1; CHKiRet(TCPSendInitTarget((void *)pTarget)); CHKiRet(returnToOriginalNs(pData)); bNeedReturnNs = 0; pTarget->bIsConnected = 1; } finalize_it: if (res != NULL) { freeaddrinfo(res); } if (iRet != RS_RET_OK) { if (bNeedReturnNs) { returnToOriginalNs(pData); } if (pTarget->f_addr != NULL) { freeaddrinfo(pTarget->f_addr); pTarget->f_addr = NULL; } iRet = RS_RET_SUSPENDED; } RETiRet; } BEGINtryResume CODESTARTtryResume; iRet = poolTryResume(pWrkrData); countActiveTargets(pWrkrData); const int nActiveTargets = ATOMIC_FETCH_32BIT(&pWrkrData->pData->nActiveTargets, &pWrkrData->pData->mut_nActiveTargets); LogMsg(0, RS_RET_DEBUG, LOG_DEBUG, "omfwd: [wrkr %u/%" PRIuPTR "] tryResume was called by rsyslog core: " "active targets: %d, overall return state %d", pWrkrData->wrkrID, (uintptr_t)pthread_self(), nActiveTargets, iRet); ENDtryResume BEGINbeginTransaction CODESTARTbeginTransaction; dbgprintf("omfwd: beginTransaction\n"); /* note: we need to try resume so that we are at least at the start * of the transaction aware of target states. It is not useful to * start a transaction when we know it will most probably fail. */ iRet = poolTryResume(pWrkrData); if (iRet == RS_RET_SUSPENDED) { LogMsg(0, RS_RET_SUSPENDED, LOG_WARNING, "omfwd: [wrkr %d/%" PRIuPTR "] no working target servers in " "pool available, suspending action (state: beginTx)", pWrkrData->wrkrID, (uintptr_t)pthread_self()); } ENDbeginTransaction static rsRetVal processMsg(targetData_t *__restrict__ const pTarget, actWrkrIParams_t *__restrict__ const iparam) { wrkrInstanceData_t *const pWrkrData = (wrkrInstanceData_t *)pTarget->pWrkrData; uchar *psz; /* temporary buffering */ register unsigned l; int iMaxLine; Bytef *out = NULL; /* for compression */ instanceData *__restrict__ const pData = pWrkrData->pData; DEFiRet; iMaxLine = glbl.GetMaxLine(runModConf->pConf); psz = iparam->param; l = iparam->lenStr; if ((int)l > iMaxLine) l = iMaxLine; /* Check if we should compress and, if so, do it. We also * check if the message is large enough to justify compression. * The smaller the message, the less likely is a gain in compression. * To save CPU cycles, we do not try to compress very small messages. * What "very small" means needs to be configured. Currently, it is * hard-coded but this may be changed to a config parameter. * rgerhards, 2006-11-30 */ if (pData->compressionMode == COMPRESS_SINGLE_MSG && (l > CONF_MIN_SIZE_FOR_COMPRESS)) { uLongf destLen = iMaxLine + iMaxLine / 100 + 12; /* recommended value from zlib doc */ uLong srcLen = l; int ret; CHKmalloc(out = (Bytef *)malloc(destLen)); out[0] = 'z'; out[1] = '\0'; ret = compress2((Bytef *)out + 1, &destLen, (Bytef *)psz, srcLen, pData->compressionLevel); dbgprintf("Compressing message, length was %d now %d, return state %d.\n", l, (int)destLen, ret); if (ret != Z_OK) { /* if we fail, we complain, but only in debug mode * Otherwise, we are silent. In any case, we ignore the * failed compression and just sent the uncompressed * data, which is still valid. So this is probably the * best course of action. * rgerhards, 2006-11-30 */ dbgprintf("Compression failed, sending uncompressed message\n"); } else if (destLen + 1 < l) { /* only use compression if there is a gain in using it! */ dbgprintf("there is gain in compression, so we do it\n"); psz = out; l = destLen + 1; /* take care for the "z" at message start! */ } ++destLen; } if (pData->protocol == FORW_UDP) { /* forward via UDP */ CHKiRet(UDPSend(pWrkrData, psz, l)); // TODO-RG: always add "actualTarget"! } else { /* forward via TCP */ iRet = tcpclt.Send(pTarget->pTCPClt, pTarget, (char *)psz, l); if (iRet != RS_RET_OK && iRet != RS_RET_DEFER_COMMIT && iRet != RS_RET_PREVIOUS_COMMITTED) { /* error! */ LogError(0, iRet, "omfwd: error forwarding via tcp to %s:%s, suspending target", pTarget->target_name, pTarget->port); DestructTCPTargetData(pTarget); iRet = RS_RET_SUSPENDED; } } finalize_it: if (iRet == RS_RET_OK || iRet == RS_RET_DEFER_COMMIT || iRet == RS_RET_PREVIOUS_COMMITTED) { ATOMIC_INC_uint64(&pTarget->pTargetStats->sentMsgs, &pTarget->pTargetStats->mut_sentMsgs); } free(out); /* is NULL if it was never used... */ RETiRet; } BEGINcommitTransaction unsigned i; char namebuf[264]; /* 256 for FQDN, 5 for port and 3 for transport => 264 */ CODESTARTcommitTransaction; /* if needed, rebind first. This ensure we can deliver to the rebound addresses. * Note that rebind requires reconnect to the new targets. This is done by the * poolTryResume(), which needs to be made in any case. */ if (pWrkrData->pData->iRebindInterval && (pWrkrData->nXmit++ >= pWrkrData->pData->iRebindInterval)) { dbgprintf("REBIND (sent %d, interval %d) - omfwd dropping target connection (as configured)\n", pWrkrData->nXmit, pWrkrData->pData->iRebindInterval); pWrkrData->nXmit = 0; /* else we have an addtl wrap at 2^31-1 */ DestructTCPInstanceData(pWrkrData); initTCP(pWrkrData); LogMsg(0, RS_RET_PARAM_ERROR, LOG_WARNING, "omfwd: dropped connections due to configured rebind interval"); } CHKiRet(poolTryResume(pWrkrData)); countActiveTargets(pWrkrData); DBGPRINTF("pool %s:%s/%s\n", pWrkrData->pData->target_name[0], pWrkrData->pData->ports[0], pWrkrData->pData->protocol == FORW_UDP ? "udp" : "tcp"); /* we use a rate-limiter based on the first pool members name. This looks * good enough. As an alternative, we may consider creating a special pool * name. But we leave this for when need actually arises. */ if (pWrkrData->pData->ratelimiter) { snprintf(namebuf, sizeof namebuf, "%s:[%s]:%s", pWrkrData->pData->protocol == FORW_UDP ? "udp" : "tcp", pWrkrData->pData->target_name[0], pWrkrData->pData->ports[0]); } for (i = 0; i < nParams; ++i) { /* If rate limiting is enabled, check whether this message has to be discarded */ if (pWrkrData->pData->ratelimiter) { iRet = ratelimitMsgCount(pWrkrData->pData->ratelimiter, 0, namebuf); if (iRet == RS_RET_DISCARDMSG) { iRet = RS_RET_OK; continue; } else if (iRet != RS_RET_OK) { LogError(0, RS_RET_ERR, "omfwd: error during rate limit : %d.\n", iRet); } } int trynbr = 0; int dotry = 1; while (dotry && trynbr < pWrkrData->pData->nTargets) { /* In the future we may consider if we would like to have targets on a per-worker or global basis. We now use worker because otherwise we have thread interdependence, which hurts performance. But this can lead to uneven distribution of messages when multiple workers run. */ const unsigned actualTarget = (pWrkrData->actualTarget++) % pWrkrData->pData->nTargets; targetData_t *pTarget = &(pWrkrData->target[actualTarget]); DBGPRINTF("load balancer: trying actualTarget %u [%u]: try %d, isConnected %d, wrkr %p\n", actualTarget, (pWrkrData->actualTarget - 1), trynbr, pTarget->bIsConnected, pWrkrData); if (pTarget->bIsConnected) { DBGPRINTF("RGER: sending to actualTarget %d: try %d\n", actualTarget, trynbr); iRet = processMsg(pTarget, &actParam(pParams, 1, i, 0)); if (iRet == RS_RET_OK || iRet == RS_RET_DEFER_COMMIT || iRet == RS_RET_PREVIOUS_COMMITTED) { dotry = 0; } } trynbr++; } if (dotry == 1) { LogMsg(0, RS_RET_SUSPENDED, LOG_INFO, "omfwd: [wrkr %u] found no working target server when trying to send " "messages (main loop)", pWrkrData->wrkrID); ABORT_FINALIZE(RS_RET_SUSPENDED); } pWrkrData->nXmit++; } for (int j = 0; j < pWrkrData->pData->nTargets; ++j) { if (pWrkrData->target[j].bIsConnected && pWrkrData->target[j].offsSndBuf != 0) { iRet = TCPSendBuf(&(pWrkrData->target[j]), pWrkrData->target[j].sndBuf, pWrkrData->target[j].offsSndBuf, IS_FLUSH); if (iRet == RS_RET_OK || iRet == RS_RET_DEFER_COMMIT || iRet == RS_RET_PREVIOUS_COMMITTED) { pWrkrData->target[j].offsSndBuf = 0; } else { LogMsg(0, RS_RET_SUSPENDED, LOG_WARNING, "omfwd: [wrkr %u] target %s:%s became unavailable during buffer flush. " "Remaining messages will be sent when it is online again.", pWrkrData->wrkrID, pWrkrData->target[j].target_name, pWrkrData->target[j].port); DestructTCPTargetData(&(pWrkrData->target[j])); /* Note: do not return RS_RET_SUSPENDED here. We only return SUSPENDED * when no pool member is left active (see block below after pool stats). * For multi-target pools, other active targets may continue to work * and the remaining buffered data for this target will be flushed once * it resumes on a subsequent transaction. */ iRet = RS_RET_OK; } } } finalize_it: /* * Return semantics for commitTransaction: * - Only return RS_RET_SUSPENDED when no pool member is left active. * We determine this by calling countActiveTargets() and inspecting * the atomic nActiveTargets value. When it is zero, the whole pool * is unavailable and the action engine must enter retry logic. * - If at least one target remains active, we keep returning OK here * so that the action is not suspended at pool level. Any buffered * frames for failed targets remain in that target's send buffer and * will be flushed once doTryResume() re-establishes the connection * on a subsequent transaction. */ /* do pool stats */ countActiveTargets(pWrkrData); const int nActiveTargets = ATOMIC_FETCH_32BIT(&pWrkrData->pData->nActiveTargets, &pWrkrData->pData->mut_nActiveTargets); if (nActiveTargets == 0) { /* * All pool members are currently unavailable. Only in this case we * return RS_RET_SUSPENDED from commitTransaction, as required by the * omfwd pool contract. */ iRet = RS_RET_SUSPENDED; } if (iRet == RS_RET_SUSPENDED) { LogMsg(0, RS_RET_SUSPENDED, LOG_WARNING, "omfwd: [wrkr %d/%" PRIuPTR "] no working target servers in pool available, suspending action", pWrkrData->wrkrID, (uintptr_t)pthread_self()); } ENDcommitTransaction /* This function loads TCP support, if not already loaded. It will be called * during config processing. To server ressources, TCP support will only * be loaded if it actually is used. -- rgerhard, 2008-04-17 */ static rsRetVal loadTCPSupport(void) { DEFiRet; CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME)); finalize_it: RETiRet; } /* initialize TCP structures (if necessary) after the instance has been * created. */ static rsRetVal initTCP(wrkrInstanceData_t *pWrkrData) { instanceData *pData; DEFiRet; pData = pWrkrData->pData; if (pData->protocol == FORW_TCP) { for (int i = 0; i < pData->nTargets; ++i) { /* create our tcpclt */ CHKiRet(tcpclt.Construct(&pWrkrData->target[i].pTCPClt)); CHKiRet(tcpclt.SetResendLastOnRecon(pWrkrData->target[i].pTCPClt, pData->bResendLastOnRecon)); CHKiRet(tcpclt.SetFraming(pWrkrData->target[i].pTCPClt, pData->tcp_framing)); CHKiRet(tcpclt.SetFramingDelimiter(pWrkrData->target[i].pTCPClt, pData->tcp_framingDelimiter)); /* and set callbacks */ CHKiRet(tcpclt.SetSendInit(pWrkrData->target[i].pTCPClt, TCPSendInit)); CHKiRet(tcpclt.SetSendFrame(pWrkrData->target[i].pTCPClt, TCPSendFrame)); CHKiRet(tcpclt.SetSendPrepRetry(pWrkrData->target[i].pTCPClt, TCPSendPrepRetry)); } } finalize_it: RETiRet; } static void setInstParamDefaults(instanceData *pData) { pData->tplName = NULL; pData->protocol = FORW_UDP; pData->networkNamespace = NULL; pData->originalNamespace = -1; pData->tcp_framing = TCP_FRAMING_OCTET_STUFFING; pData->tcp_framingDelimiter = '\n'; pData->pszStrmDrvr = NULL; pData->pszStrmDrvrAuthMode = NULL; pData->pszStrmDrvrPermitExpiredCerts = NULL; pData->iStrmDrvrMode = 0; pData->iStrmDrvrExtendedCertCheck = 0; pData->iStrmDrvrSANPreference = 0; pData->iStrmTlsVerifyDepth = 0; pData->pszStrmDrvrCAFile = NULL; pData->pszStrmDrvrCRLFile = NULL; pData->pszStrmDrvrKeyFile = NULL; pData->pszStrmDrvrCertFile = NULL; pData->iRebindInterval = 0; pData->bKeepAlive = 0; pData->iKeepAliveProbes = 0; pData->iKeepAliveIntvl = 0; pData->iKeepAliveTime = 0; pData->iConErrSkip = 0; pData->gnutlsPriorityString = NULL; pData->bResendLastOnRecon = 0; pData->bExtendedConnCheck = 1; /* traditionally enabled! */ pData->bSendToAll = -1; /* unspecified */ pData->iUDPSendDelay = 0; pData->UDPSendBuf = 0; pData->pPermPeers = NULL; pData->compressionLevel = 9; pData->strmCompFlushOnTxEnd = 1; pData->compressionMode = COMPRESS_NEVER; pData->ipfreebind = IPFREEBIND_ENABLED_WITH_LOG; pData->poolResumeInterval = 30; pData->ratelimiter = NULL; pData->ratelimitInterval = 0; pData->ratelimitBurst = 200; } /* support statistics gathering - note: counter names are the same as for * previous non-pool based code. This permits easy migration in our opinion. */ static rsRetVal setupInstStatsCtrs(instanceData *const pData) { uchar ctrName[512]; DEFiRet; if (pData->target_name == NULL) { /* This is primarily introduced to keep the static analyzer happy. We * do not understand how this situation could actually happen. */ LogError(0, RS_RET_INTERNAL_ERROR, "internal error: target_name is NULL in setupInstStatsCtrs() -" "statistics countes are disable. Report this error to the " "rsyslog project please."); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } CHKmalloc(pData->target_stats = (targetStats_t *)calloc(pData->nTargets, sizeof(targetStats_t))); for (int i = 0; i < pData->nTargets; ++i) { /* if insufficient ports are configured, we use ports[0] for the * missing ports. */ snprintf((char *)ctrName, sizeof(ctrName), "%s-%s-%s", (pData->protocol == FORW_TCP) ? "TCP" : "UDP", pData->target_name[i], pData->ports[(i < pData->nPorts) ? i : 0]); ctrName[sizeof(ctrName) - 1] = '\0'; /* be on the save side */ CHKiRet(statsobj.Construct(&(pData->target_stats[i].stats))); CHKiRet(statsobj.SetName(pData->target_stats[i].stats, ctrName)); CHKiRet(statsobj.SetOrigin(pData->target_stats[i].stats, (uchar *)"omfwd")); pData->target_stats[i].sentBytes = 0; INIT_ATOMIC_HELPER_MUT64(pData->target_stats[i].mut_sentBytes); CHKiRet(statsobj.AddCounter(pData->target_stats[i].stats, UCHAR_CONSTANT("bytes.sent"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->target_stats[i].sentBytes))); pData->target_stats[i].sentMsgs = 0; INIT_ATOMIC_HELPER_MUT64(pData->target_stats[i].mut_sentMsgs); CHKiRet(statsobj.AddCounter(pData->target_stats[i].stats, UCHAR_CONSTANT("messages.sent"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->target_stats[i].sentMsgs))); CHKiRet(statsobj.ConstructFinalize(pData->target_stats[i].stats)); } finalize_it: RETiRet; } BEGINnewActInst struct cnfparamvals *pvals; uchar *tplToUse; char *cstr; int i; rsRetVal localRet; int complevel = -1; CODESTARTnewActInst; DBGPRINTF("newActInst (omfwd)\n"); pvals = nvlstGetParams(lst, &actpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("action param blk in omfwd:\n"); cnfparamsPrint(&actpblk, pvals); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); pData->nPorts = 0; /* we need this to detect missing port param */ for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "target")) { const int nTargets = pvals[i].val.d.ar->nmemb; /* keep static analyzer happy */ pData->nTargets = nTargets; CHKmalloc(pData->target_name = (char **)calloc(pData->nTargets, sizeof(char *))); for (int j = 0; j < nTargets; ++j) { pData->target_name[j] = (char *)es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); } } else if (!strcmp(actpblk.descr[i].name, "address")) { pData->address = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "device")) { pData->device = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "port")) { pData->nPorts = pvals[i].val.d.ar->nmemb; CHKmalloc(pData->ports = (char **)calloc(pData->nPorts, sizeof(char *))); for (int j = 0; j < pData->nPorts; ++j) { pData->ports[j] = (char *)es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); } } else if (!strcmp(actpblk.descr[i].name, "protocol")) { if (!es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"udp", 3)) { pData->protocol = FORW_UDP; } else if (!es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"tcp", 3)) { localRet = loadTCPSupport(); if (localRet != RS_RET_OK) { LogError(0, localRet, "could not activate network stream modules for TCP " "(internal error %d) - are modules missing?", localRet); ABORT_FINALIZE(localRet); } pData->protocol = FORW_TCP; } else { uchar *str; str = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_INVLD_PROTOCOL, "omfwd: invalid protocol \"%s\"", str); free(str); ABORT_FINALIZE(RS_RET_INVLD_PROTOCOL); } } else if (!strcmp(actpblk.descr[i].name, "networknamespace")) { pData->networkNamespace = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "tcp_framing")) { if (!es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"traditional", 11)) { pData->tcp_framing = TCP_FRAMING_OCTET_STUFFING; } else if (!es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"octet-counted", 13)) { pData->tcp_framing = TCP_FRAMING_OCTET_COUNTING; } else { uchar *str; str = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_CNF_INVLD_FRAMING, "omfwd: invalid framing \"%s\"", str); free(str); ABORT_FINALIZE(RS_RET_CNF_INVLD_FRAMING); } } else if (!strcmp(actpblk.descr[i].name, "rebindinterval")) { pData->iRebindInterval = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "keepalive")) { pData->bKeepAlive = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "keepalive.probes")) { pData->iKeepAliveProbes = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "keepalive.interval")) { pData->iKeepAliveIntvl = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "keepalive.time")) { pData->iKeepAliveTime = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "conerrskip")) { pData->iConErrSkip = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "gnutlsprioritystring")) { pData->gnutlsPriorityString = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriver") || !strcmp(actpblk.descr[i].name, "streamdriver.name")) { pData->pszStrmDrvr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdrivermode") || !strcmp(actpblk.descr[i].name, "streamdrivermode")) { pData->iStrmDrvrMode = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) { pData->iStrmDrvrExtendedCertCheck = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "streamdriver.PrioritizeSAN")) { pData->iStrmDrvrSANPreference = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "streamdriver.TlsVerifyDepth")) { if (pvals[i].val.d.n >= 2) { pData->iStrmTlsVerifyDepth = pvals[i].val.d.n; } else { parser_errmsg("streamdriver.TlsVerifyDepth must be 2 or higher but is %d", (int)pvals[i].val.d.n); } } else if (!strcmp(actpblk.descr[i].name, "streamdriverauthmode") || !strcmp(actpblk.descr[i].name, "streamdriverauthmode")) { pData->pszStrmDrvrAuthMode = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriver.permitexpiredcerts")) { uchar *val = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"off", 3) && es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"on", 2) && es_strcasebufcmp(pvals[i].val.d.estr, (uchar *)"warn", 4)) { parser_errmsg( "streamdriver.permitExpiredCerts must be 'warn', 'off' or 'on' " "but is '%s' - ignoring parameter, using 'off' instead.", val); free(val); } else { pData->pszStrmDrvrPermitExpiredCerts = val; } } else if (!strcmp(actpblk.descr[i].name, "streamdriver.cafile")) { pData->pszStrmDrvrCAFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriver.crlfile")) { pData->pszStrmDrvrCRLFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriver.keyfile")) { pData->pszStrmDrvrKeyFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriver.certfile")) { pData->pszStrmDrvrCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "streamdriverpermittedpeers")) { uchar *start, *str; uchar *p; int lenStr; str = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); start = str; lenStr = ustrlen(start); /* we need length after '\0' has been dropped... */ while (lenStr > 0) { p = start; while (*p && *p != ',' && lenStr--) p++; if (*p == ',') { *p = '\0'; } if (*start == '\0') { DBGPRINTF("omfwd: ignoring empty permitted peer\n"); } else { dbgprintf("omfwd: adding permitted peer: '%s'\n", start); CHKiRet(net.AddPermittedPeer(&(pData->pPermPeers), start)); } start = p + 1; if (lenStr) --lenStr; } free(str); } else if (!strcmp(actpblk.descr[i].name, "ziplevel")) { complevel = pvals[i].val.d.n; if (complevel >= 0 && complevel <= 10) { pData->compressionLevel = complevel; pData->compressionMode = COMPRESS_SINGLE_MSG; } else { LogError(0, NO_ERRCODE, "Invalid ziplevel %d specified in " "forwarding action - NOT turning on compression.", complevel); } } else if (!strcmp(actpblk.descr[i].name, "tcp_framedelimiter")) { if (pvals[i].val.d.n > 255) { parser_errmsg("tcp_frameDelimiter must be below 255 but is %d", (int)pvals[i].val.d.n); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } pData->tcp_framingDelimiter = (uchar)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "resendlastmsgonreconnect")) { pData->bResendLastOnRecon = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "extendedconnectioncheck")) { pData->bExtendedConnCheck = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "udp.sendtoall")) { pData->bSendToAll = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "udp.senddelay")) { pData->iUDPSendDelay = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "udp.sendbuf")) { pData->UDPSendBuf = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "compression.stream.flushontxend")) { pData->strmCompFlushOnTxEnd = (sbool)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "compression.mode")) { cstr = es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcasecmp(cstr, "stream:always")) { pData->compressionMode = COMPRESS_STREAM_ALWAYS; } else if (!strcasecmp(cstr, "none")) { pData->compressionMode = COMPRESS_NEVER; } else if (!strcasecmp(cstr, "single")) { pData->compressionMode = COMPRESS_SINGLE_MSG; } else { LogError(0, RS_RET_PARAM_ERROR, "omfwd: invalid value for 'compression.mode' " "parameter (given is '%s')", cstr); free(cstr); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } free(cstr); } else if (!strcmp(actpblk.descr[i].name, "ipfreebind")) { pData->ipfreebind = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "pool.resumeinterval")) { pData->poolResumeInterval = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ratelimit.burst")) { pData->ratelimitBurst = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ratelimit.interval")) { pData->ratelimitInterval = (unsigned int)pvals[i].val.d.n; } else { LogError(0, RS_RET_INTERNAL_ERROR, "omfwd: program error, non-handled parameter '%s'", actpblk.descr[i].name); } } if (pData->protocol == FORW_UDP && pData->nTargets > 1) { parser_warnmsg( "you have defined %d targets. Multiple targets are ONLY " "supported in TCP mode ignoring all but the first target in UDP mode", pData->nTargets); } /* check if no port is set. If so, we use the IANA-assigned port of 514 */ if (pData->nPorts == 0) { pData->nPorts = 1; CHKmalloc(pData->ports = (char **)calloc(pData->nPorts, sizeof(char *))); CHKmalloc(pData->ports[0] = strdup("514")); } if (pData->nPorts > pData->nTargets) { parser_warnmsg( "defined %d ports, but only %d targets - ignoring " "extra ports", pData->nPorts, pData->nTargets); } if (pData->nPorts < pData->nTargets) { parser_warnmsg( "defined %d ports, but %d targets - using port %s " "as default for the additional targets", pData->nPorts, pData->nTargets, pData->ports[0]); } if (complevel != -1) { pData->compressionLevel = complevel; if (pData->compressionMode == COMPRESS_NEVER) { /* to keep compatible with pre-7.3.11, only setting the * compresion level means old-style single-message mode. */ pData->compressionMode = COMPRESS_SINGLE_MSG; } } CODE_STD_STRING_REQUESTnewActInst(1); tplToUse = ustrdup((pData->tplName == NULL) ? getDfltTpl() : pData->tplName); CHKiRet(OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS)); if (pData->bSendToAll == -1) { pData->bSendToAll = send_to_all; } else { if (pData->protocol == FORW_TCP) { LogError(0, RS_RET_PARAM_ERROR, "omfwd: parameter udp.sendToAll " "cannot be used with tcp transport -- ignored"); } } if (pData->address && (pData->protocol == FORW_TCP)) { LogError(0, RS_RET_PARAM_ERROR, "omfwd: parameter \"address\" not supported for tcp -- ignored"); } if (pData->ratelimitInterval > 0) { CHKiRet(ratelimitNew(&pData->ratelimiter, "omfwd", NULL)); ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst); ratelimitSetNoTimeCache(pData->ratelimiter); } setupInstStatsCtrs(pData); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINparseSelectorAct uchar *q; int i; rsRetVal localRet; struct addrinfo; TCPFRAMINGMODE tcp_framing = TCP_FRAMING_OCTET_STUFFING; CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) if (*p != '@') ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); CHKiRet(createInstance(&pData)); pData->tcp_framingDelimiter = '\n'; ++p; /* eat '@' */ if (*p == '@') { /* indicator for TCP! */ localRet = loadTCPSupport(); if (localRet != RS_RET_OK) { LogError(0, localRet, "could not activate network stream modules for TCP " "(internal error %d) - are modules missing?", localRet); ABORT_FINALIZE(localRet); } pData->protocol = FORW_TCP; ++p; /* eat this '@', too */ } else { pData->protocol = FORW_UDP; } /* we are now after the protocol indicator. Now check if we should * use compression. We begin to use a new option format for this: * @(option,option)host:port * The first option defined is "z[0..9]" where the digit indicates * the compression level. If it is not given, 9 (best compression) is * assumed. An example action statement might be: * @@(z5,o)127.0.0.1:1400 * Which means send via TCP with medium (5) compresion (z) to the local * host on port 1400. The '0' option means that octet-couting (as in * IETF I-D syslog-transport-tls) is to be used for framing (this option * applies to TCP-based syslog only and is ignored when specified with UDP). * That is not yet implemented. * rgerhards, 2006-12-07 * In order to support IPv6 addresses, we must introduce an extension to * the hostname. If it is in square brackets, whatever is in them is treated as * the hostname - without any exceptions ;) -- rgerhards, 2008-08-05 */ if (*p == '(') { /* at this position, it *must* be an option indicator */ do { ++p; /* eat '(' or ',' (depending on when called) */ /* check options */ if (*p == 'z') { /* compression */ ++p; /* eat */ if (isdigit((int)*p)) { int iLevel; iLevel = *p - '0'; ++p; /* eat */ pData->compressionLevel = iLevel; pData->compressionMode = COMPRESS_SINGLE_MSG; } else { LogError(0, NO_ERRCODE, "Invalid compression level '%c' specified in " "forwarding action - NOT turning on compression.", *p); } } else if (*p == 'o') { /* octet-couting based TCP framing? */ ++p; /* eat */ /* no further options settable */ tcp_framing = TCP_FRAMING_OCTET_COUNTING; } else { /* invalid option! Just skip it... */ LogError(0, NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p); ++p; /* eat invalid option */ } /* the option processing is done. We now do a generic skip * to either the next option or the end of the option * block. */ while (*p && *p != ')' && *p != ',') ++p; /* just skip it */ } while (*p && *p == ','); /* Attention: do.. while() */ if (*p == ')') ++p; /* eat terminator, on to next */ else /* we probably have end of string - leave it for the rest * of the code to handle it (but warn the user) */ LogError(0, NO_ERRCODE, "Option block not terminated in forwarding action."); } /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0') * now skip to port and then template name. rgerhards 2005-07-06 */ if (*p == '[') { /* everything is hostname upto ']' */ ++p; /* skip '[' */ for (q = p; *p && *p != ']'; ++p) /* JUST SKIP */ ; if (*p == ']') { *p = '\0'; /* trick to obtain hostname (later)! */ ++p; /* eat it */ } } else { /* traditional view of hostname */ for (q = p; *p && *p != ';' && *p != ':' && *p != '#'; ++p) /* JUST SKIP */ ; } pData->tcp_framing = tcp_framing; pData->ports = NULL; pData->networkNamespace = NULL; CHKmalloc(pData->target_name = (char **)malloc(sizeof(char *) * pData->nTargets)); CHKmalloc(pData->ports = (char **)calloc(pData->nTargets, sizeof(char *))); if (*p == ':') { /* process port */ uchar *tmp; *p = '\0'; /* trick to obtain hostname (later)! */ tmp = ++p; for (i = 0; *p && isdigit((int)*p); ++p, ++i) /* SKIP AND COUNT */ ; pData->ports[0] = malloc(i + 1); if (pData->ports[0] == NULL) { LogError(0, NO_ERRCODE, "Could not get memory to store syslog forwarding port, " "using default port, results may not be what you intend"); /* we leave f_forw.port set to NULL, this is then handled below */ } else { memcpy(pData->ports[0], tmp, i); *(pData->ports[0] + i) = '\0'; } } /* check if no port is set. If so, we use the IANA-assigned port of 514 */ if (pData->ports[0] == NULL) { CHKmalloc(pData->ports[0] = strdup("514")); } /* now skip to template */ while (*p && *p != ';' && *p != '#' && !isspace((int)*p)) ++p; /*JUST SKIP*/ if (*p == ';' || *p == '#' || isspace(*p)) { uchar cTmp = *p; *p = '\0'; /* trick to obtain hostname (later)! */ CHKmalloc(pData->target_name[0] = strdup((char *)q)); *p = cTmp; } else { CHKmalloc(pData->target_name[0] = strdup((char *)q)); } /* We have a port at ports[0], so we must tell the module it is allocated. * Otherwise, the port would not be freed. */ pData->nPorts = 1; /* copy over config data as needed */ pData->iRebindInterval = (pData->protocol == FORW_TCP) ? cs.iTCPRebindInterval : cs.iUDPRebindInterval; pData->bKeepAlive = cs.bKeepAlive; pData->iKeepAliveProbes = cs.iKeepAliveProbes; pData->iKeepAliveIntvl = cs.iKeepAliveIntvl; pData->iKeepAliveTime = cs.iKeepAliveTime; pData->iConErrSkip = cs.iConErrSkip; /* process template */ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); if (pData->protocol == FORW_TCP) { pData->bResendLastOnRecon = cs.bResendLastOnRecon; pData->iStrmDrvrMode = cs.iStrmDrvrMode; if (cs.pPermPeers != NULL) { pData->pPermPeers = cs.pPermPeers; cs.pPermPeers = NULL; } } CODE_STD_FINALIZERparseSelectorAct if (iRet == RS_RET_OK) { setupInstStatsCtrs(pData); } ENDparseSelectorAct /* a common function to free our configuration variables - used both on exit * and on $ResetConfig processing. -- rgerhards, 2008-05-16 */ static void freeConfigVars(void) { free(cs.pszStrmDrvr); cs.pszStrmDrvr = NULL; free(cs.pszStrmDrvrAuthMode); cs.pszStrmDrvrAuthMode = NULL; free(cs.pPermPeers); cs.pPermPeers = NULL; } BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(net, LM_NET_FILENAME); objRelease(netstrm, LM_NETSTRMS_FILENAME); objRelease(netstrms, LM_NETSTRMS_FILENAME); objRelease(tcpclt, LM_TCPCLT_FILENAME); objRelease(statsobj, CORE_COMPONENT); freeConfigVars(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMODTX_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt /* Reset config variables for this module to default values. * rgerhards, 2008-03-28 */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { freeConfigVars(); /* we now must reset all non-string values */ cs.iStrmDrvrMode = 0; cs.bResendLastOnRecon = 0; cs.iUDPRebindInterval = 0; cs.iTCPRebindInterval = 0; cs.bKeepAlive = 0; cs.iKeepAliveProbes = 0; cs.iKeepAliveIntvl = 0; cs.iKeepAliveTime = 0; cs.iConErrSkip = 0; return RS_RET_OK; } BEGINmodInit(Fwd) CODESTARTmodInit; INITLegCnfVars; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet( regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, NULL)); CHKiRet( regCfSysLineHdlr((uchar *)"actionsendtcprebindinterval", 0, eCmdHdlrInt, NULL, &cs.iTCPRebindInterval, NULL)); CHKiRet( regCfSysLineHdlr((uchar *)"actionsendudprebindinterval", 0, eCmdHdlrInt, NULL, &cs.iUDPRebindInterval, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendtcpkeepalive", 0, eCmdHdlrBinary, NULL, &cs.bKeepAlive, NULL)); CHKiRet( regCfSysLineHdlr((uchar *)"actionsendtcpkeepalive_probes", 0, eCmdHdlrInt, NULL, &cs.iKeepAliveProbes, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendtcpkeepalive_intvl", 0, eCmdHdlrInt, NULL, &cs.iKeepAliveIntvl, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendtcpkeepalive_time", 0, eCmdHdlrInt, NULL, &cs.iKeepAliveTime, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriver", 0, eCmdHdlrGetWord, NULL, &cs.pszStrmDrvr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdrivermode", 0, eCmdHdlrInt, NULL, &cs.iStrmDrvrMode, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriverauthmode", 0, eCmdHdlrGetWord, NULL, &cs.pszStrmDrvrAuthMode, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriverpermittedpeer", 0, eCmdHdlrGetWord, setPermittedPeer, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionsendresendlastmsgonreconnect", 0, eCmdHdlrBinary, NULL, &cs.bResendLastOnRecon, NULL)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/Makefile.am0000644000000000000000000000013215055603742015734 xustar0030 mtime=1756825570.305069173 30 atime=1764930935.213924097 30 ctime=1764935924.097590574 rsyslog-8.2512.0/tools/Makefile.am0000664000175000017500000000604715055603742015407 0ustar00rgerrgersbin_PROGRAMS = bin_PROGRAMS = CLEANFILES = man1_MANS = man_MANS = rsyslogd.8 rsyslog.conf.5 sbin_PROGRAMS += rsyslogd rsyslogd_SOURCES = \ syslogd.c \ rsyslogd.c \ syslogd.h \ omshell.c \ omshell.h \ omusrmsg.c \ omusrmsg.h \ omfwd.c \ omfwd.h \ omfile.c \ omfile.h \ ompipe.c \ ompipe.h \ omdiscard.c \ omdiscard.h \ pmrfc5424.c \ pmrfc5424.h \ pmrfc3164.c \ pmrfc3164.h \ smtradfile.c \ smtradfile.h \ smfile.c \ smfile.h \ smfwd.c \ smfwd.h \ smtradfwd.c \ smtradfwd.h \ iminternal.c \ iminternal.h \ \ ../dirty.h rsyslogd_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) if ENABLE_LIBLOGGING_STDLOG rsyslogd_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) endif rsyslogd_CPPFLAGS += -DSD_EXPORT_SYMBOLS # note: it looks like librsyslog.la must be explicitely given on LDDADD, # otherwise dependencies are not properly calculated (resulting in a # potentially incomplete build, a problem we had several times...) rsyslogd_LDADD = ../grammar/libgrammar.la ../runtime/librsyslog.la ../compat/compat.la $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) $(LIBUUID_LIBS) $(HASH_XXHASH_LIBS) # Note: do NOT indent the if chain - it will not work! if OS_LINUX rsyslogd_LDFLAGS = -export-dynamic \ #-Wl,--whole-archive,$(top_builddir)/runtime/.libs/librsyslog.a,--no-whole-archive exports_list_file = else if OS_APPLE rsyslogd_LDFLAGS = -export-dynamic \ -Wl,$(top_builddir)/runtime/.libs/librsyslog.a exports_list_file = else if OS_AIX rsyslogd_LDFLAGS = -brtl -bexpall -f"aix_exports_list" -lsrc exports_list_file = aix_exports_list else # e.g. FreeBSD rsyslogd_LDFLAGS = -export-dynamic exports_list_file = endif # if OS_AIX endif # if OS_APPLE endif # if OS_LINUX EXTRA_DIST = $(man_MANS) \ rscryutil.rst \ recover_qi.pl EXTRA_rsyslogd_DEPENDENCIES = $(exports_list_file) if ENABLE_LIBLOGGING_STDLOG rsyslogd_LDADD += $(LIBLOGGING_STDLOG_LIBS) endif if ENABLE_DIAGTOOLS sbin_PROGRAMS += rsyslog_diag_hostname msggen rsyslog_diag_hostname_SOURCES = gethostn.c msggen_SOURCES = msggen.c endif if ENABLE_USERTOOLS if ENABLE_OMMONGODB bin_PROGRAMS += logctl logctl_SOURCES = logctl.c logctl_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(LIBMONGOC_CFLAGS) logctl_LDADD = $(LIBMONGOC_LIBS) endif if ENABLE_RSCRYUTIL bin_PROGRAMS += rscryutil rscryutil = rscryutil.c rscryutil_CPPFLAGS = -I../runtime $(RSRT_CFLAGS) rscryutil_LDADD = if ENABLE_LIBGCRYPT rscryutil_CPPFLAGS += $(LIBGCRYPT_CFLAGS) rscryutil_LDADD += ../runtime/libgcry.la $(LIBGCRYPT_LIBS) endif if ENABLE_OPENSSL_CRYPTO_PROVIDER rscryutil_CPPFLAGS += $(OPENSSL_CFLAGS) rscryutil_LDADD += ../runtime/libossl.la $(OPENSSL_LIBS) endif rscryutil_LDFLAGS = \ -Wl,--whole-archive,--no-whole-archive if ENABLE_GENERATE_MAN_PAGES RSTMANFILE = rscryutil.rst rscryutil.1: $(RSTMANFILE) $(AM_V_GEN) $(RST2MAN) $(RSTMANFILE) $@ man1_MANS += rscryutil.1 CLEANFILES += rscryutil.1 EXTRA_DIST+= rscryutil.1 endif endif endif aix_exports_list: echo "$(top_builddir)/runtime/.libs/librsyslog_la-*.o" > $@ echo "$(top_builddir)/.libs/librsyslog_la-*.o" >> $@ echo "$(top_builddir)/grammar/.libs/libgrammar_la-*.o" >> $@ rsyslog-8.2512.0/tools/PaxHeaders/omdiscard.c0000644000000000000000000000013215055605325016010 xustar0030 mtime=1756826325.659800834 30 atime=1764931033.399564894 30 ctime=1764935924.143591278 rsyslog-8.2512.0/tools/omdiscard.c0000664000175000017500000000747415055605325015470 0ustar00rgerrger/* omdiscard.c * This is the implementation of the built-in discard output module. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2007-07-24 by RGerhards * * Copyright 2007-2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include "syslogd.h" #include "syslogd-types.h" #include "omdiscard.h" #include "module-template.h" #include "errmsg.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; /* internal structures */ DEF_OMOD_STATIC_DATA; typedef struct _instanceData { EMPTY_STRUCT } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; /* we do not need a createInstance()! BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance */ BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; /* do nothing */ ENDdbgPrintInstInfo BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; /* we are not compatible with repeated msg reduction feature, so do not allow it */ ENDisCompatibleWithFeature BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINdoAction_NoStrings CODESTARTdoAction; (void)pMsgData; /* Suppress compiler warning on unused var */ dbgprintf("\n"); iRet = RS_RET_DISCARDMSG; ENDdoAction BEGINfreeInstance CODESTARTfreeInstance; /* we do not have instance data, so we do not need to * do anything here. -- rgerhards, 2007-07-25 */ ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINparseSelectorAct CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(0) pData = NULL; /* this action does not have any instance data */ p = *pp; if (*p == '~') { dbgprintf("discard\n"); LogMsg(0, RS_RET_DEPRECATED, LOG_WARNING, "warning: ~ action is deprecated, consider " "using the 'stop' statement instead"); } else { iRet = RS_RET_CONFLINE_UNPROCESSED; } /* we do not use the macro * CODE_STD_FINALIZERparseSelectorAct * here as this causes a Coverity ID "false positive" (CID 185431). * We don't see an issue with using the copy&pasted code as it is unlikly * to change for this (outdated) module. */ finalize_it: ATTR_UNUSED; /* semi-colon needed according to gcc doc! */ if (iRet == RS_RET_OK || iRet == RS_RET_OK_WARN || iRet == RS_RET_SUSPENDED) { *ppModData = pData; *pp = p; } else { /* cleanup, we failed */ if (*ppOMSR != NULL) { OMSRdestruct(*ppOMSR); *ppOMSR = NULL; } } /* END modified macro text */ ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; ENDqueryEtryPt BEGINmodInit(Discard) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr ENDmodInit /* * vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/smtradfile.h0000644000000000000000000000013115055605325016201 xustar0030 mtime=1756826325.661800864 29 atime=1764930982.72072337 30 ctime=1764935924.160591538 rsyslog-8.2512.0/tools/smtradfile.h0000664000175000017500000000241515055605325015650 0ustar00rgerrger/* smtradfile.h * These are the definitions for the traditional file format stringen module. * * File begun on 2010-06-01 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SMTRADFILE_H_INCLUDED #define SMTRADFILE_H_INCLUDED 1 /* prototypes */ rsRetVal modInitsmtradfile(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef SMTRADFILE_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/smfile.c0000644000000000000000000000013215055605325015322 xustar0030 mtime=1756826325.661800864 30 atime=1764931034.470582563 30 ctime=1764935924.162591569 rsyslog-8.2512.0/tools/smfile.c0000664000175000017500000000766715055605325015006 0ustar00rgerrger/* smfile.c * This is a strgen module for the traditional file format. * * Format generated: * "%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" * Note that this is the same as smtradfile.c, except that we do have a RFC3339 timestamp. However, * we have copied over the code from there, it is too simple to go through all the hassle * of having a single code base. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2010-06-01 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "unicode-helper.h" MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP; STRGEN_NAME("RSYSLOG_FileFormat") /* internal structures */ DEF_SMOD_STATIC_DATA; /* config data */ /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. */ BEGINstrgen register int iBuf; uchar *pTimeStamp; size_t lenTimeStamp; uchar *pHOSTNAME; size_t lenHOSTNAME; uchar *pTAG; int lenTAG; uchar *pMSG; size_t lenMSG; size_t lenTotal; CODESTARTstrgen; /* first obtain all strings and their length (if not fixed) */ pTimeStamp = (uchar *)getTimeReported(pMsg, tplFmtRFC3339Date); lenTimeStamp = ustrlen(pTimeStamp); pHOSTNAME = (uchar *)getHOSTNAME(pMsg); lenHOSTNAME = getHOSTNAMELen(pMsg); getTAG(pMsg, &pTAG, &lenTAG, LOCK_MUTEX); pMSG = getMSG(pMsg); lenMSG = getMSGLen(pMsg); /* calculate len, constants for spaces and similar fixed strings */ lenTotal = lenTimeStamp + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 2; if (pMSG[0] != ' ') ++lenTotal; /* then we need to introduce one additional space */ /* now make sure buffer is large enough */ if (lenTotal >= iparam->lenBuf) CHKiRet(ExtendBuf(iparam, lenTotal)); /* and concatenate the resulting string */ memcpy(iparam->param, pTimeStamp, lenTimeStamp); iBuf = lenTimeStamp; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pHOSTNAME, lenHOSTNAME); iBuf += lenHOSTNAME; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pTAG, lenTAG); iBuf += lenTAG; if (pMSG[0] != ' ') iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pMSG, lenMSG); iBuf += lenMSG; /* trailer */ iparam->param[iBuf++] = '\n'; iparam->param[iBuf] = '\0'; iparam->lenStr = lenTotal - 1; /* do not count \0! */ finalize_it: ENDstrgen BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_SMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(smfile) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf("rsyslog standard file format strgen init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/pmrfc5424.h0000644000000000000000000000013215055605325015476 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.716723303 30 ctime=1764935924.150591385 rsyslog-8.2512.0/tools/pmrfc5424.h0000664000175000017500000000241415055605325015143 0ustar00rgerrger/* pmrfc5424.h * These are the definitions for the RFCC5424 parser module. * * File begun on 2009-11-03 by RGerhards * * Copyright 2009-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PMRFC54254_H_INCLUDED #define PMRFC54254_H_INCLUDED 1 /* prototypes */ rsRetVal modInitpmrfc5424(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef PMRFC54254_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/syslogd.c0000644000000000000000000000013215055605325015527 xustar0030 mtime=1756826325.661800864 30 atime=1764931031.017525581 30 ctime=1764935924.111590788 rsyslog-8.2512.0/tools/syslogd.c0000664000175000017500000000736015055605325015201 0ustar00rgerrger/** * main rsyslog file with GPLv3 content. * * *********************** NOTE ************************ * * Do no longer patch this file. If there is hard * * * need to, talk to Rainer as to how we can make any * * * patch be licensed under ASL 2.0. * * * THIS FILE WILL GO AWAY. The new main file is * * * rsyslogd.c. * * ***************************************************** * * Please visit the rsyslog project at * https://www.rsyslog.com * to learn more about it and discuss any questions you may have. * * rsyslog had initially been forked from the sysklogd project. * I would like to express my thanks to the developers of the sysklogd * package - without it, I would have had a much harder start... * * Please note that while rsyslog started from the sysklogd code base, * it nowadays has almost nothing left in common with it. Allmost all * parts of the code have been rewritten. * * This Project was intiated and is maintained by * Rainer Gerhards . * * rsyslog - An Enhanced syslogd Replacement. * Copyright 2003-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef OS_SOLARIS #include #include #include #include #else #include #endif #include #include #include #include #include #ifdef HAVE_SYS_TIMESPEC_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #ifdef HAVE_PATHS_H #include #endif #include "srUtils.h" #include "stringbuf.h" #include "syslogd-types.h" #include "template.h" #include "outchannel.h" #include "syslogd.h" #include "msg.h" #include "iminternal.h" #include "threads.h" #include "parser.h" #include "unicode-helper.h" #include "dnscache.h" #include "ratelimit.h" #ifndef HAVE_SETSID /* stems back to sysklogd in whole */ void untty(void) { int i; pid_t pid; if (!Debug) { /* Peng Haitao contribution */ pid = getpid(); if (setpgid(pid, pid) < 0) { perror("setpgid"); exit(1); } /* end Peng Haitao contribution */ i = open(_PATH_TTY, O_RDWR | O_CLOEXEC); if (i >= 0) { #if !defined(__hpux) (void)ioctl(i, (int)TIOCNOTTY, NULL); #else /* TODO: we need to implement something for HP UX! -- rgerhards, 2008-03-04 */ /* actually, HP UX should have setsid, so the code directly above should * trigger. So the actual question is why it doesn't do that... */ #endif close(i); } } } #endif rsyslog-8.2512.0/tools/PaxHeaders/ompipe.h0000644000000000000000000000013215055605325015341 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.713723253 30 ctime=1764935924.140591232 rsyslog-8.2512.0/tools/ompipe.h0000664000175000017500000000227515055605325015013 0ustar00rgerrger/* ompipe.h * These are the definitions for the build-in pipe output module. * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This pipe is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMPIPE_H_INCLUDED #define OMPIPE_H_INCLUDED 1 /* prototypes */ rsRetVal modInitPipe(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef OMPIPE_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/rsyslog.conf.50000644000000000000000000000013215114522477016415 xustar0030 mtime=1764926783.046632128 30 atime=1764926784.241661461 30 ctime=1764935924.186591936 rsyslog-8.2512.0/tools/rsyslog.conf.50000664000175000017500000007402615114522477016072 0ustar00rgerrger.\" rsyslog.conf - rsyslogd(8) configuration file .\" Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH. .\" .\" This file is part of the rsyslog package, an enhanced system log daemon. .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. .\" .TH RSYSLOG.CONF 5 "18 February 2025" "Version 8.2502.0" "Linux System Administration" .SH NAME rsyslog.conf \- rsyslogd(8) configuration file .SH DESCRIPTION The .I rsyslog.conf file is the main configuration file for the .BR rsyslogd (8) which logs system messages on *nix systems. This file specifies rules for logging. For special features see the .BR rsyslogd (8) manpage. Rsyslog.conf is backward-compatible with sysklogd's syslog.conf file. So if you migrate from sysklogd you can rename it and it should work. .B Note that this version of rsyslog ships with extensive documentation in HTML format. This is provided in the ./doc subdirectory and probably in a separate package if you installed rsyslog via a packaging system. To use rsyslog's advanced features, you .B need to look at the HTML documentation, because the man pages only cover basic aspects of operation. .SH MODULES Rsyslog has a modular design. Consequently, there is a growing number of modules. See the HTML documentation for their full description. .TP .I omsnmp SNMP trap output module .TP .I omgssapi Output module for GSS-enabled syslog .TP .I ommysql Output module for MySQL .TP .I omrelp Output module for the reliable RELP protocol (prevents message loss). For details, see below at imrelp and the HTML documentation. It can be used like this: .IP *.* :omrelp:server:port .IP *.* :omrelp:192.168.0.1:2514 # actual sample .TP .I ompgsql Output module for PostgreSQL .TP .I omlibdbi Generic database output module (Firebird/Interbase, MS SQL, Sybase, SQLite, Ingres, Oracle, mSQL) .TP .I imfile Input module for text files .TP .I imudp Input plugin for UDP syslog. Replaces the deprecated -r option. Can be used like this: .IP $ModLoad imudp .IP $UDPServerRun 514 .TP .I imtcp Input plugin for plain TCP syslog. Replaces the deprecated -t option. Can be used like this: .IP $ModLoad imtcp .IP $InputTCPServerRun 514 .TP .TP .I imrelp Input plugin for the RELP protocol. RELP can be used instead of UDP or plain TCP syslog to provide reliable delivery of syslog messages. Please note that plain TCP syslog does NOT provide truly reliable delivery, with it messages may be lost when there is a connection problem or the server shuts down. RELP prevents message loss in those cases. It can be used like this: .IP $ModLoad imrelp .IP $InputRELPServerRun 2514 .TP .I imgssapi Input plugin for plain TCP and GSS-enable syslog .TP .I immark Support for mark messages .TP .I imklog Kernel logging. To include kernel log messages, you need to do .IP $ModLoad imklog Please note that the klogd daemon is no longer necessary and consequently no longer provided by the rsyslog package. .TP .I imuxsock Unix sockets, including the system log socket. You need to specify .IP $ModLoad imuxsock in order to receive log messages from local system processes. This config directive should only left out if you know exactly what you are doing. .SH BASIC STRUCTURE Lines starting with a hash mark ('#') and empty lines are ignored. Rsyslog.conf should contain following sections (sorted by recommended order in file): .TP Global directives Global directives set some global properties of whole rsyslog daemon, for example size of main message queue ($MainMessageQueueSize), loading external modules ($ModLoad) and so on. All global directives need to be specified on a line by their own and must start with a dollar-sign. The complete list of global directives can be found in HTML documentation in doc directory or online on web pages. .TP Templates Templates allow you to specify format of the logged message. They are also used for dynamic file name generation. They have to be defined before they are used in rules. For more info about templates see TEMPLATES section of this manpage. .TP Output channels Output channels provide an umbrella for any type of output that the user might want. They have to be defined before they are used in rules. For more info about output channels see OUTPUT CHANNELS section of this manpage. .TP Rules (selector + action) Every rule line consists of two fields, a selector field and an action field. These two fields are separated by one or more spaces or tabs. The selector field specifies a pattern of facilities and priorities belonging to the specified action. .SH SELECTORS The selector field itself again consists of two parts, a facility and a priority, separated by a period ('.'). Both parts are case insensitive and can also be specified as decimal numbers, but don't do that, you have been warned. Both facilities and priorities are described in syslog(3). The names mentioned below correspond to the similar LOG_-values in /usr/include/syslog.h. The facility is one of the following keywords: auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, security (same as auth), syslog, user, uucp and local0 through local7. The keyword security should not be used anymore and mark is only for internal use and therefore should not be used in applications. Anyway, you may want to specify and redirect these messages here. The facility specifies the subsystem that produced the message, i.e. all mail programs log with the mail facility (LOG_MAIL) if they log using syslog. The priority is one of the following keywords, in ascending order: debug, info, notice, warning, warn (same as warning), err, error (same as err), crit, alert, emerg, panic (same as emerg). The keywords error, warn and panic are deprecated and should not be used anymore. The priority defines the severity of the message. The behavior of the original BSD syslogd is that all messages of the specified priority and higher are logged according to the given action. Rsyslogd behaves the same, but has some extensions. In addition to the above mentioned names the rsyslogd(8) understands the following extensions: An asterisk ('*') stands for all facilities or all priorities, depending on where it is used (before or after the period). The keyword none stands for no priority of the given facility. You can specify multiple facilities with the same priority pattern in one statement using the comma (',') operator. You may specify as much facilities as you want. Remember that only the facility part from such a statement is taken, a priority part would be skipped. Multiple selectors may be specified for a single action using the semicolon (';') separator. Remember that each selector in the selector field is capable to overwrite the preceding ones. Using this behavior you can exclude some priorities from the pattern. Rsyslogd has a syntax extension to the original BSD source, that makes its use more intuitively. You may precede every priority with an equals sign ('=') to specify only this single priority and not any of the above. You may also (both is valid, too) precede the priority with an exclamation mark ('!') to ignore all that priorities, either exact this one or this and any higher priority. If you use both extensions then the exclamation mark must occur before the equals sign, just use it intuitively. However, please note that there are some restrictions over the traditional BSD syslog behaviour. These restrictions stem back to sysklogd, exist probably since at least the 1990's and as such have always been in rsyslog. Namely, in BSD syslogd you can craft a selector like this: *.debug;local6.err The intent is to log all facilities at debug or higher, except for local6, which should only log at err or higher. Unfortunately, local6.err will permit error severity and higher, but will not exclude lower severity messages from facility local6. As an alternative, you can explicitly exclude all severities that you do not want to match. For the above case, this selector is equivalent to the BSD syslog selector: *.debug;local6.!=info;local6.!=notice;local6.!=warn An easier approach is probably to do if ... then based matching in script. .SH ACTIONS The action field of a rule describes what to do with the message. In general, message content is written to a kind of "logfile". But also other actions might be done, like writing to a database table or forwarding to another host. .SS Regular file Typically messages are logged to real files. The file has to be specified with full pathname, beginning with a slash ('/'). .B Example: .RS *.* /var/log/traditionalfile.log;RSYSLOG_TraditionalFileFormat # log to a file in the traditional format .RE Note: if you would like to use high-precision timestamps in your log files, just remove the ";RSYSLOG_TraditionalFormat". That will select the default template, which, if not changed, uses RFC 3339 timestamps. .B Example: .RS *.* /var/log/file.log # log to a file with RFC3339 timestamps .RE By default, files are not synced after each write. To enable syncing of log files globally, use either the "$ActionFileEnableSync" directive or the "sync" parameter to omfile. Enabling this option degrades performance and it is advised not to enable syncing unless you know what you are doing. To selectively disable syncing for certain files, you may prefix the file path with a minus sign ("-"). .SS Named pipes This version of rsyslogd(8) has support for logging output to named pipes (fifos). A fifo or named pipe can be used as a destination for log messages by prepending a pipe symbol ('|') to the name of the file. This is handy for debugging. Note that the fifo must be created with the mkfifo(1) command before rsyslogd(8) is started. .SS Terminal and console If the file you specified is a tty, special tty-handling is done, same with /dev/console. .SS Remote machine There are three ways to forward message: the traditional UDP transport, which is extremely lossy but standard, the plain TCP based transport which loses messages only during certain situations but is widely available and the RELP transport which does not lose messages but is currently available only as part of rsyslogd 3.15.0 and above. To forward messages to another host via UDP, prepend the hostname with the at sign ("@"). To forward it via plain tcp, prepend two at signs ("@@"). To forward via RELP, prepend the string ":omrelp:" in front of the hostname. .B Example: .RS *.* @192.168.0.1 .RE .sp In the example above, messages are forwarded via UDP to the machine 192.168.0.1, the destination port defaults to 514. Due to the nature of UDP, you will probably lose some messages in transit. If you expect high traffic volume, you can expect to lose a quite noticeable number of messages (the higher the traffic, the more likely and severe is message loss). Sockets for forwarded messages can be bound to a specific device using the "device" option for the omfwd module. .B Example: .RS action(type="omfwd" Target="192.168.0.1" Device="eth0" Port="514" Protocol="udp") .RE .sp In the example above, messages are forwarded via UDP to the machine 192.168.0.1 at port 514 over the device eth0. TCP can be used by setting Protocol to "tcp" in the above example. For Linux with VRF support, the device option is used to specify the VRF to send messages. .B If you would like to prevent message loss, use RELP: .RS *.* :omrelp:192.168.0.1:2514 .RE .sp Note that a port number was given as there is no standard port for relp. Keep in mind that you need to load the correct input and output plugins (see "Modules" above). Please note that rsyslogd offers a variety of options in regarding to remote forwarding. For full details, please see the HTML documentation. .SS List of users Usually critical messages are also directed to ``root'' on that machine. You can specify a list of users that shall get the message by simply writing ":omusrmsg:" followed by the login name. You may specify more than one user by separating them with commas (','). If they're logged in they get the message (for example: ":omusrmsg:root,user1,user2"). .SS Everyone logged on Emergency messages often go to all users currently online to notify them that something strange is happening with the system. To specify this wall(1)-feature use an ":omusrmsg:*". .SS Database table This allows logging of the message to a database table. By default, a MonitorWare-compatible schema is required for this to work. You can create that schema with the createDB.SQL file that came with the rsyslog package. You can also use any other schema of your liking - you just need to define a proper template and assign this template to the action. See the HTML documentation for further details on database logging. .SS Discard If the discard action is carried out, the received message is immediately discarded. Discard can be highly effective if you want to filter out some annoying messages that otherwise would fill your log files. To do that, place the discard actions early in your log files. This often plays well with property-based filters, giving you great freedom in specifying what you do not want. Discard is just the single 'stop' command with no further parameters. .sp .B Example: .RS *.* stop # discards everything. .RE .SS Output channel Binds an output channel definition (see there for details) to this action. Output channel actions must start with a $-sign, e.g. if you would like to bind your output channel definition "mychannel" to the action, use "$mychannel". Output channels support template definitions like all all other actions. .SS Shell execute This executes a program in a subshell. The program is passed the template-generated message as the only command line parameter. Rsyslog waits until the program terminates and only then continues to run. .B Example: .RS ^program-to-execute;template .RE The program-to-execute can be any valid executable. It receives the template string as a single parameter (argv[1]). .SH FILTER CONDITIONS Rsyslog offers three different types "filter conditions": .sp 0 * "traditional" severity and facility based selectors .sp 0 * property-based filters .sp 0 * expression-based filters .RE .SS Selectors .B Selectors are the traditional way of filtering syslog messages. They have been kept in rsyslog with their original syntax, because it is well-known, highly effective and also needed for compatibility with stock syslogd configuration files. If you just need to filter based on priority and facility, you should do this with selector lines. They are not second-class citizens in rsyslog and offer the best performance for this job. .SS Property-Based Filters Property-based filters are unique to rsyslogd. They allow one to filter on any property, like HOSTNAME, syslogtag and msg. A property-based filter must start with a colon in column 0. This tells rsyslogd that it is the new filter type. The colon must be followed by the property name, a comma, the name of the compare operation to carry out, another comma and then the value to compare against. This value must be quoted. There can be spaces and tabs between the commas. Property names and compare operations are case-sensitive, so "msg" works, while "MSG" is an invalid property name. In brief, the syntax is as follows: .sp .RS :property, [!]compare-operation, "value" .RE The following compare-operations are currently supported: .sp .RS .B contains .RS Checks if the string provided in value is contained in the property .RE .sp .B isequal .RS Compares the "value" string provided and the property contents. These two values must be exactly equal to match. .RE .sp .B startswith .RS Checks if the value is found exactly at the beginning of the property value .RE .sp .B regex .RS Compares the property against the provided regular expression. .RE .SS Expression-Based Filters See the HTML documentation for this feature. .SH TEMPLATES Every output in rsyslog uses templates - this holds true for files, user messages and so on. Templates compatible with the stock syslogd formats are hardcoded into rsyslogd. If no template is specified, we use one of these hardcoded templates. Search for "template_" in syslogd.c and you will find the hardcoded ones. A template consists of a template directive, a name, the actual template text and optional options. A sample is: .RS .B $template MyTemplateName,"\\\\7Text %property% some more text\\\\n", .RE The "$template" is the template directive. It tells rsyslog that this line contains a template. The backslash is an escape character. For example, \\7 rings the bell (this is an ASCII value), \\n is a new line. The set in rsyslog is a bit restricted currently. All text in the template is used literally, except for things within percent signs. These are properties and allow you access to the contents of the syslog message. Properties are accessed via the property replacer and it can for example pick a substring or do date-specific formatting. More on this is the PROPERTY REPLACER section of this manpage. To escape: .sp 0 % = \\% .sp 0 \\ = \\\\ --> '\\' is used to escape (as in C) .sp 0 $template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\\n" Properties can be accessed by the property replacer (see there for details). .B Please note that templates can also by used to generate selector lines with dynamic file names. For example, if you would like to split syslog messages from different hosts to different files (one per host), you can define the following template: .RS .B $template DynFile,"/var/log/system-%HOSTNAME%.log" .RE This template can then be used when defining an output selector line. It will result in something like "/var/log/system-localhost.log" .SS Template options The part is optional. It carries options influencing the template as whole. See details below. Be sure NOT to mistake template options with property options - the later ones are processed by the property replacer and apply to a SINGLE property, only (and not the whole template). Template options are case-insensitive. Currently defined are: .RS .TP sql format the string suitable for a SQL statement in MySQL format. This will replace single quotes ("'") and the backslash character by their backslash-escaped counterpart ("\'" and "\\") inside each field. Please note that in MySQL configuration, the NO_BACKSLASH_ESCAPES mode must be turned off for this format to work (this is the default). .TP stdsql format the string suitable for a SQL statement that is to be sent to a standards-compliant sql server. This will replace single quotes ("'") by two single quotes ("''") inside each field. You must use stdsql together with MySQL if in MySQL configuration the NO_BACKSLASH_ESCAPES is turned on. .RE Either the .B sql or .B stdsql option .B MUST be specified when a template is used for writing to a database, otherwise injection might occur. Please note that due to the unfortunate fact that several vendors have violated the sql standard and introduced their own escape methods, it is impossible to have a single option doing all the work. So you yourself must make sure you are using the right format. .B If you choose the wrong one, you are still vulnerable to sql injection. Please note that the database writer *checks* that the sql option is present in the template. If it is not present, the write database action is disabled. This is to guard you against accidental forgetting it and then becoming vulnerable to SQL injection. The sql option can also be useful with files - especially if you want to import them into a database on another machine for performance reasons. However, do NOT use it if you do not have a real need for it - among others, it takes some toll on the processing time. Not much, but on a really busy system you might notice it ;) The default template for the write to database action has the sql option set. .SS Template examples Please note that the samples are split across multiple lines. A template MUST NOT actually be split across multiple lines. A template that resembles traditional syslogd file output: .sp .RS $template TraditionalFormat,"%timegenerated% %HOSTNAME% .sp 0 %syslogtag%%msg:::drop-last-lf%\\n" .RE A template that tells you a little more about the message: .sp .RS $template precise,"%syslogpriority%,%syslogfacility%,%timegenerated%,%HOSTNAME%, .sp 0 %syslogtag%,%msg%\\n" .RE A template for RFC 3164 format: .sp .RS $template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%" .RE A template for the format traditionally used for user messages: .sp .RS $template usermsg," XXXX%syslogtag%%msg%\\n\\r" .RE And a template with the traditional wall-message format: .sp .RS $template wallmsg,"\\r\\n\\7Message from syslogd@%HOSTNAME% at %timegenerated%" .RE .B A template that can be used for writing to a database (please note the SQL template option) .sp .RS .ad l $template MySQLInsert,"insert iut, message, receivedat values ('%iut%', '%msg:::UPPERCASE%', '%timegenerated:::date-mysql%') into systemevents\\r\\n", SQL NOTE 1: This template is embedded into core application under name .B StdDBFmt , so you don't need to define it. .sp NOTE 2: You have to have MySQL module installed to use this template. .ad .RE .SH OUTPUT CHANNELS Output Channels are a new concept first introduced in rsyslog 0.9.0. As of this writing, it is most likely that they will be replaced by something different in the future. So if you use them, be prepared to change you configuration file syntax when you upgrade to a later release. Output channels are defined via an $outchannel directive. It's syntax is as follows: .sp .RS .B $outchannel name,file-name,max-size,action-on-max-size .RE name is the name of the output channel (not the file), file-name is the file name to be written to, max-size the maximum allowed size and action-on-max-size a command to be issued when the max size is reached. This command always has exactly one parameter. The binary is that part of action-on-max-size before the first space, its parameter is everything behind that space. Keep in mind that $outchannel just defines a channel with "name". It does not activate it. To do so, you must use a selector line (see below). That selector line includes the channel name plus ":omfile:$" in front of it. A sample might be: .sp .RS *.* :omfile:$mychannel .RE .SH PROPERTY REPLACER The property replacer is a core component in rsyslogd's output system. A syslog message has a number of well-defined properties (see below). Each of this properties can be accessed and manipulated by the property replacer. With it, it is easy to use only part of a property value or manipulate the value, e.g. by converting all characters to lower case. .SS Accessing Properties Syslog message properties are used inside templates. They are accessed by putting them between percent signs. Properties can be modified by the property replacer. The full syntax is as follows: .sp .RS .B %propname:fromChar:toChar:options% .RE propname is the name of the property to access. .B It is case-sensitive. .SS Available Properties .TP .B msg the MSG part of the message (aka "the message" ;)) .TP .B rawmsg the message exactly as it was received from the socket. Should be useful for debugging. .TP .B HOSTNAME hostname from the message .TP .B FROMHOST hostname of the system the message was received from (in a relay chain, this is the system immediately in front of us and not necessarily the original sender) .TP .B syslogtag TAG from the message .TP .B programname the "static" part of the tag, as defined by BSD syslogd. For example, when TAG is "named[12345]", programname is "named". .TP .B PRI PRI part of the message - undecoded (single value) .TP .B PRI-text the PRI part of the message in a textual form (e.g. "syslog.info") .TP .B IUT the monitorware InfoUnitType - used when talking to a MonitorWare backend (also for phpLogCon) .TP .B syslogfacility the facility from the message - in numerical form .TP .B syslogfacility-text the facility from the message - in text form .TP .B syslogseverity severity from the message - in numerical form .TP .B syslogseverity-text severity from the message - in text form .TP .B timegenerated timestamp when the message was RECEIVED. Always in high resolution .TP .B timereported timestamp from the message. Resolution depends on what was provided in the message (in most cases, only seconds) .TP .B TIMESTAMP alias for timereported .TP .B PROTOCOL-VERSION The contents of the PROTOCOL-VERSION field from IETF draft draft-ietf-syslog-protocol .TP .B STRUCTURED-DATA The contents of the STRUCTURED-DATA field from IETF draft draft-ietf-syslog-protocol .TP .B APP-NAME The contents of the APP-NAME field from IETF draft draft-ietf-syslog-protocol .TP .B PROCID The contents of the PROCID field from IETF draft draft-ietf-syslog-protocol .TP .B MSGID The contents of the MSGID field from IETF draft draft-ietf-syslog-protocol .TP .B $NOW The current date stamp in the format YYYY-MM-DD .TP .B $YEAR The current year (4-digit) .TP .B $MONTH The current month (2-digit) .TP .B $DAY The current day of the month (2-digit) .TP .B $HOUR The current hour in military (24 hour) time (2-digit) .TP .B $MINUTE The current minute (2-digit) .P Properties starting with a $-sign are so-called system properties. These do NOT stem from the message but are rather internally-generated. .SS Character Positions FromChar and toChar are used to build substrings. They specify the offset within the string that should be copied. Offset counting starts at 1, so if you need to obtain the first 2 characters of the message text, you can use this syntax: "%msg:1:2%". If you do not wish to specify from and to, but you want to specify options, you still need to include the colons. For example, if you would like to convert the full message text to lower case, use "%msg:::lowercase%". If you would like to extract from a position until the end of the string, you can place a dollar-sign ("$") in toChar (e.g. %msg:10:$%, which will extract from position 10 to the end of the string). There is also support for .B regular expressions. To use them, you need to place a "R" into FromChar. This tells rsyslog that a regular expression instead of position-based extraction is desired. The actual regular expression .B must then be provided in toChar. The regular expression must be followed by the string "--end". It denotes the end of the regular expression and will not become part of it. If you are using regular expressions, the property replacer will return the part of the property text that matches the regular expression. An example for a property replacer sequence with a regular expression is: "%msg:R:.*Sev:. \\(.*\\) \\[.*--end%" Also, extraction can be done based on so-called "fields". To do so, place a "F" into FromChar. A field in its current definition is anything that is delimited by a delimiter character. The delimiter by default is TAB (US-ASCII value 9). However, if can be changed to any other US-ASCII character by specifying a comma and the decimal US-ASCII value of the delimiter immediately after the "F". For example, to use comma (",") as a delimiter, use this field specifier: "F,44". If your syslog data is delimited, this is a quicker way to extract than via regular expressions (actually, a *much* quicker way). Field counting starts at 1. Field zero is accepted, but will always lead to a "field not found" error. The same happens if a field number higher than the number of fields in the property is requested. The field number must be placed in the "ToChar" parameter. An example where the 3rd field (delimited by TAB) from the msg property is extracted is as follows: "%msg:F:3%". The same example with semicolon as delimiter is "%msg:F,59:3%". Please note that the special characters "F" and "R" are case-sensitive. Only upper case works, lower case will return an error. There are no white spaces permitted inside the sequence (that will lead to error messages and will NOT provide the intended result). .SS Property Options Property options are case-insensitive. Currently, the following options are defined: .TP uppercase convert property to lowercase only .TP lowercase convert property text to uppercase only .TP drop-last-lf The last LF in the message (if any), is dropped. Especially useful for PIX. .TP date-mysql format as mysql date .TP date-rfc3164 format as RFC 3164 date .TP date-rfc3339 format as RFC 3339 date .TP escape-cc replace control characters (ASCII value 127 and values less then 32) with an escape sequence. The sequence is "#" where charval is the 3-digit decimal value of the control character. For example, a tabulator would be replaced by "#009". .TP space-cc replace control characters by spaces .TP drop-cc drop control characters - the resulting string will neither contain control characters, escape sequences nor any other replacement character like space. .SH QUEUED OPERATIONS Rsyslogd supports queued operations to handle offline outputs (like remote syslogd's or database servers being down). When running in queued mode, rsyslogd buffers messages to memory and optionally to disk (on an as-needed basis). Queues survive rsyslogd restarts. It is highly suggested to use remote forwarding and database writing in queued mode, only. To learn more about queued operations, see the HTML documentation. .SH FILES .PD 0 .TP .I /etc/rsyslog.conf Configuration file for .B rsyslogd .SH SEE ALSO .BR rsyslogd (8), .BR logger (1), .BR syslog (3) The complete documentation can be found in the doc folder of the rsyslog distribution or online at .RS .B https://www.rsyslog.com/doc/ .RE Please note that the man page reflects only a subset of the configuration options. Be sure to read the HTML documentation for all features and details. This is especially vital if you plan to set up a more-then-extremely-simple system. .SH AUTHORS .B rsyslogd is taken from sysklogd sources, which have been heavily modified by Rainer Gerhards (rgerhards@adiscon.com) and others. rsyslog-8.2512.0/tools/PaxHeaders/pmrfc3164.h0000644000000000000000000000013215055605325015475 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.718723337 30 ctime=1764935924.155591461 rsyslog-8.2512.0/tools/pmrfc3164.h0000664000175000017500000000240315055605325015140 0ustar00rgerrger/* pmrfc3164.h * These are the definitions for the RFC3164 parser module. * * File begun on 2009-11-04 by RGerhards * * Copyright 2009 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef PMRFC3164_H_INCLUDED #define PMRFC3164_H_INCLUDED 1 /* prototypes */ rsRetVal modInitpmrfc3164(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef PMRFC3164_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/rscryutil.rst0000644000000000000000000000013215114522477016473 xustar0030 mtime=1764926783.046632128 30 atime=1764926784.241661461 30 ctime=1764935924.188591967 rsyslog-8.2512.0/tools/rscryutil.rst0000664000175000017500000001355615114522477016151 0ustar00rgerrger========= rscryutil ========= -------------------------- Manage Encrypted Log Files -------------------------- :Author: Rainer Gerhards :Date: 2013-04-15 :Manual section: 1 SYNOPSIS ======== :: rscryutil [OPTIONS] [FILE] ... DESCRIPTION =========== This tool performs various operations on encrypted log files. Most importantly, it provides the ability to decrypt them. OPTIONS ======= -d, --decrypt Select decryption mode. This is the default mode. -W, --write-keyfile Utility function to write a key to a keyfile. The key can be obtained via any method. -l, --lib Select the crypto library to be used. Either "ossl" or "gcry". Defaults to "gcry" or whatever is currently available. -v, --verbose Select verbose mode. -f, --force Forces operations that otherwise would fail. -k, --keyfile Reads the key from . File _must_ contain the key, only, no headers or other meta information. Keyfiles can be generated via the *--write-keyfile* option. -p, --key-program In this mode, the key is provided by a so-called "key program". This program is executed and must return the key to (as well as some meta information) via stdout. The core idea of key programs is that using this interface the user can implement as complex (and secure) method to obtain keys as desired, all without the need to make modifications to rsyslog. -K, --key TESTING AID, NOT FOR PRODUCTION USE. This uses the KEY specified on the command line. This is the actual key, and as such this mode is highly insecure. However, it can be useful for initial testing steps. This option may be removed in the future. -a, --algo Sets the encryption algorightm (cipher) to be used. Refer to the list of supported algorithms below for the "gcry" library. The default algorithm for "gcry" is "AES128". For the "ossl" library, both the algorithm and mode are specified using this option, with "AES-128-CBC" as the default. -m, --mode Sets the ciphermode to be used. See below for supported modes. The default is "CBC". In case of "ossl" library, this options is ignored. -r, --generate-random-key Generates a random key of length . This option is meant to be used together with *--write-keyfile* (and it is hard to envision any other valid use for it). OPERATION MODES =============== The operation mode specifies what exactly the tool does with the provided files. The default operation mode is "dump", but this may change in the future. Thus, it is recommended to always set the operations mode explicitely. If multiple operations mode are set on the command line, results are unpredictable. decrypt ------- The provided log files are decrypted. Note that the *.encinfo* side files must exist and be accessible in order for decryption to to work. write-keyfile ------------- In this mode no log files are processed; thus it is an error to specify any on the command line. The specified keyfile is written. The key itself is obtained via the usual key commands. If *--keyfile* is used, that file is effectively copied. For security reasons, existing key files are _not_ overwritten. To permit this, specify the *--force* option. When doing so, keep in mind that lost keys cannot be recovered and data encrypted with them may also be considered lost. Keyfiles are always created with 0400 permission, that is read access for only the user. An exception is when an existing file is overwritten via the *--force* option, in which case the former permissions still apply. EXIT CODES ========== The command returns an exit code of 0 if everything went fine, and some other code in case of failures. SUPPORTED ALGORITHMS ==================== In case of "ossl", see "ALGORITHM FETCHING" in crypto(7) for further information. In case of "gcry" we basically support what libgcrypt supports and that is: 3DES CAST5 BLOWFISH AES128 AES192 AES256 TWOFISH TWOFISH128 ARCFOUR DES SERPENT128 SERPENT192 SERPENT256 RFC2268_40 SEED CAMELLIA128 CAMELLIA192 CAMELLIA256 SUPPORTED CIPHER MODES ====================== In case of "gcry", we basically support what libgcrypt supports. This is: ECB CFB CBC STREAM OFB CTR AESWRAP EXAMPLES ======== **rscryutil logfile** Decrypts "logfile" and sends data to stdout. **rscryutil -k keyfile -l ossl -a AES-256-CBC encryptedfile** Decrypts encryptedfile using ossl library with AES256 algorithm and CBC mode **rscryutil -k keyfile -l gcry -a AES256 -m CBC encryptedfile** Decrypts encryptedfile using gcry library with AES256 algorithm and CBC mode **rscryutil --generate-random-key 16 --keyfile /some/secured/path/keyfile** Generates random key and stores it in the specified keyfile. LOG SIGNATURES ============== Encrypted log files can be used together with signing. To verify such a file, it must be decrypted first, and the verification tool **rsgtutil(1)** must be run on the decrypted file. SECURITY CONSIDERATIONS ======================= Specifying keys directly on the command line (*--key* option) is very insecure and should not be done, except for testing purposes with test keys. Even then it is recommended to use keyfiles, which are also easy to handle during testing. Keep in mind that command history is usally be kept by bash and can also easily be monitored. Local keyfiles are also a security risk. At a minimum, they should be used with very restrictive file permissions. For this reason, the *rscryutil* tool creates them with read permissions for the user, only, no matter what umask is set to. When selecting cipher algorithms and modes, care needs to be taken. The defaults should be reasonable safe to use, but this tends to change over time. Keep up with the most current crypto recommendations. SEE ALSO ======== **rsgtutil(1)**, **rsyslogd(8)** COPYRIGHT ========= This page is part of the *rsyslog* project, and is available under LGPLv2. rsyslog-8.2512.0/tools/PaxHeaders/omusrmsg.c0000644000000000000000000000013215071746523015723 xustar0030 mtime=1760021843.915422201 30 atime=1764931031.928540619 30 ctime=1764935924.124590987 rsyslog-8.2512.0/tools/omusrmsg.c0000664000175000017500000004243715071746523015401 0ustar00rgerrger/** * @file omusrmsg.c * @brief Implementation of the built-in user message output module. * * This module provides message delivery to logged-in users. Depending on * configuration it can either send messages to specific user terminals or * broadcast them using a "wall" style interface. * * NOTE: read comments in module-template.h to understand how this file works! * * File begun on 2007-07-20 by Rainer Gerhards (extracted from syslogd.c, * which at the time of the fork from sysklogd was under BSD license). * * Copyright 2007-2025 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef HAVE_UTMPX_H #include #define STRUCTUTMP struct utmpx #define UTNAME ut_user #define setutent setutxent #define getutent getutxent #define endutent endutxent #ifndef UT_LINESIZE /* __UT_LINESIZE for glibc; _UTX_LINESIZE common on Solaris */ #ifdef __UT_LINESIZE #define UT_LINESIZE __UT_LINESIZE #elif defined(_UTX_LINESIZE) #define UT_LINESIZE _UTX_LINESIZE #else /* method of last resort */ #define UT_LINESIZE 32 #endif #endif #elif defined(HAVE_UTMP_H) #include #define STRUCTUTMP struct utmp #define UTNAME ut_name #endif #include #include #include #include #if HAVE_FCNTL_H #include #else #include #endif #ifdef HAVE_PATHS_H #include #endif #ifndef _PATH_UTMP #define _PATH_UTMP "/var/run/utmp" #endif #ifdef HAVE_LIBSYSTEMD #include #include #include #endif #include "rsyslog.h" #include "srUtils.h" #include "stringbuf.h" #include "syslogd-types.h" #include "conf.h" #include "omusrmsg.h" #include "module-template.h" #include "errmsg.h" /* portability: */ #ifndef _PATH_DEV #define _PATH_DEV "/dev/" #endif #ifdef UT_NAMESIZE #define UNAMESZ UT_NAMESIZE /* length of a login name */ #else #define UNAMESZ 32 /* length of a login name, 32 seems current (2018) good bet */ #endif #define MAXUNAMES 20 /* maximum number of user names */ #ifdef OS_SOLARIS #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omusrmsg") /* internal structures */ DEF_OMOD_STATIC_DATA; typedef struct _instanceData { int bIsWall; /* 1- is wall, 0 - individual users */ char uname[MAXUNAMES][UNAMESZ + 1]; uchar *tplName; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; typedef struct configSettings_s { EMPTY_STRUCT } configSettings_t; static configSettings_t __attribute__((unused)) cs; /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"users", eCmdHdlrString, CNFPARAM_REQUIRED}, {"template", eCmdHdlrGetWord, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars; ENDinitConfVars BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; free(pData->tplName); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINdbgPrintInstInfo register int i; CODESTARTdbgPrintInstInfo; for (i = 0; i < MAXUNAMES && *pData->uname[i]; i++) dbgprintf("%s, ", pData->uname[i]); ENDdbgPrintInstInfo /** * BSD setutent/getutent() replacement routines * The following routines emulate setutent() and getutent() under * BSD because they are not available there. We only emulate what we actually * need! rgerhards 2005-03-18 */ #ifdef OS_BSD /* Since version 900007, FreeBSD has a POSIX compliant */ #if defined(__FreeBSD__) && (__FreeBSD_version >= 900007) #ifndef setutent #define setutent() setutxent() #endif #ifndef getutent #define getutent() getutxent() #endif #ifndef endutent #define endutent() endutxent() #endif #else static FILE *BSD_uf = NULL; void setutent(void) { assert(BSD_uf == NULL); if ((BSD_uf = fopen(_PATH_UTMP, "r")) == NULL) { LogError(errno, NO_ERRCODE, "error opening utmp %s", _PATH_UTMP); return; } } STRUCTUTMP *getutent(void) { static STRUCTUTMP st_utmp; if (fread((char *)&st_utmp, sizeof(st_utmp), 1, BSD_uf) != 1) return NULL; return (&st_utmp); } void endutent(void) { fclose(BSD_uf); BSD_uf = NULL; } #endif /* if defined(__FreeBSD__) */ #endif /* #ifdef OS_BSD */ /** * Send a message to a specific terminal device. * * The function builds the full device path from the supplied tty name * and writes the message using non-blocking I/O so that a blocked * terminal does not stall the caller. * * @param tty terminal name (e.g. "pts/0") * @param pMsg message text to send */ static void sendwallmsg(const char *tty, uchar *pMsg) { uchar szErr[512]; int errnoSave; char p[sizeof(_PATH_DEV) + UT_LINESIZE]; int ttyf; struct stat statb; int wrRet; /* compute the device name */ strcpy(p, _PATH_DEV); size_t base_len = strlen(p); size_t avail = sizeof(p) - base_len - 1; size_t ttylen = strnlen(tty, avail); memcpy(p + base_len, tty, ttylen); p[base_len + ttylen] = '\0'; /* we must be careful when writing to the terminal. A terminal may block * (for example, a user has pressed -s). In that case, we can not * wait indefinitely. So we need to use non-blocking I/O. In case we would * block, we simply do not send the message, because that's the best we can * do. -- rgerhards, 2008-07-04 */ /* open the terminal */ if ((ttyf = open(p, O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) { if (fstat(ttyf, &statb) == 0 && (statb.st_mode & S_IWRITE)) { wrRet = write(ttyf, pMsg, strlen((char *)pMsg)); if (Debug && wrRet == -1) { /* we record the state to the debug log */ errnoSave = errno; rs_strerror_r(errno, (char *)szErr, sizeof(szErr)); dbgprintf("write to terminal '%s' failed with [%d]:%s\n", p, errnoSave, szErr); } } close(ttyf); } } /** * Write a message to the world at large. * * The message can either be broadcast to all logged-in users or sent only * to the set configured in @a pData. The implementation avoids forking a * helper process and instead performs delivery on the caller's thread. * * @param[in] pMsg message text to deliver * @param[in] pData per-action configuration * * @return rsRetVal */ static rsRetVal wallmsg(uchar *pMsg, instanceData *pData) { register int i; STRUCTUTMP ut; STRUCTUTMP *uptr; DEFiRet; assert(pMsg != NULL); #ifdef HAVE_LIBSYSTEMD if (sd_booted() > 0) { register int j; int sdRet; char **sessions_list; int sessions = sd_get_sessions(&sessions_list); for (j = 0; j < sessions; j++) { uchar szErr[512]; char *tty; const char *user = NULL; uid_t uid; struct passwd *pws; sdRet = sd_session_get_uid(sessions_list[j], &uid); if (sdRet >= 0) { pws = getpwuid(uid); if (pws == NULL) { LogError(0, NO_ERRCODE, "failed to get passwd for userid '%d'\n", uid); free(sessions_list[j]); continue; } user = pws->pw_name; /* DO NOT FREE, OS/LIB internal memory! */ if (user == NULL) { LogError(0, NO_ERRCODE, "failed to get username for userid '%d'\n", uid); free(sessions_list[j]); continue; } } else { /* we record the state to the debug log */ rs_strerror_r(-sdRet, (char *)szErr, sizeof(szErr)); LogError(0, NO_ERRCODE, "get userid for session '%s' failed with [%d]:%s\n", sessions_list[j], -sdRet, szErr); free(sessions_list[j]); continue; /* try next session */ } /* should we send the message to this user? */ if (pData->bIsWall == 0) { for (i = 0; i < MAXUNAMES; i++) { if (!pData->uname[i][0]) { i = MAXUNAMES; break; } if (strncmp(pData->uname[i], user, UNAMESZ) == 0) break; } if (i == MAXUNAMES) { /* user not found? */ free(sessions_list[j]); continue; /* on to next user! */ } } if ((sdRet = sd_session_get_tty(sessions_list[j], &tty)) < 0) { /* we record the state to the debug log */ rs_strerror_r(-sdRet, (char *)szErr, sizeof(szErr)); LogError(0, NO_ERRCODE, "get tty for session '%s' failed with [%d]:%s\n", sessions_list[j], -sdRet, szErr); free(sessions_list[j]); continue; /* try next session */ } sendwallmsg(tty, pMsg); free(tty); free(sessions_list[j]); } free(sessions_list); } else { #endif /* open the user login file */ setutent(); /* scan the user login file */ while ((uptr = getutent())) { memcpy(&ut, uptr, sizeof(ut)); /* is this slot used? */ if (ut.UTNAME[0] == '\0') continue; #ifndef OS_BSD if (ut.ut_type != USER_PROCESS) continue; #endif if (!(memcmp(ut.UTNAME, "LOGIN", 6))) /* paranoia */ continue; /* should we send the message to this user? */ if (pData->bIsWall == 0) { for (i = 0; i < MAXUNAMES; i++) { if (!pData->uname[i][0]) { i = MAXUNAMES; break; } if (strncmp(pData->uname[i], ut.UTNAME, UNAMESZ) == 0) break; } if (i == MAXUNAMES) /* user not found? */ continue; /* on to next user! */ } sendwallmsg(ut.ut_line, pMsg); } /* close the user login file */ endutent(); #ifdef HAVE_LIBSYSTEMD } #endif RETiRet; } BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINdoAction CODESTARTdoAction; dbgprintf("\n"); iRet = wallmsg(ppString[0], pWrkrData->pData); ENDdoAction static void /** * Parse a comma separated list of usernames. * * The user list is copied into the instance data. Whitespace is skipped * and overly long names are reported via the error log. If more than * MAXUNAMES users are specified, excess entries are ignored. * * @param[in] pData Instance configuration to populate * @param[in] usrs comma separated list of users */ populateUsers(instanceData *pData, es_str_t *usrs) { int i; int iDst; es_size_t iUsr; es_size_t len; uchar *c; len = es_strlen(usrs); c = es_getBufAddr(usrs); pData->bIsWall = 0; /* write to individual users */ iUsr = 0; for (i = 0; i < MAXUNAMES && iUsr < len; ++i) { for (iDst = 0; iDst < UNAMESZ && iUsr < len && c[iUsr] != ','; ++iDst, ++iUsr) { pData->uname[i][iDst] = c[iUsr]; } pData->uname[i][iDst] = '\0'; DBGPRINTF("omusrmsg: send to user '%s'\n", pData->uname[i]); if (iUsr < len && c[iUsr] != ',') { LogError(0, RS_RET_ERR, "user name '%s...' too long - " "ignored", pData->uname[i]); --i; ++iUsr; while (iUsr < len && c[iUsr] != ',') ++iUsr; /* skip to next name */ } else if (iDst == 0) { LogError(0, RS_RET_ERR, "no user name given - " "ignored"); --i; ++iUsr; while (iUsr < len && c[iUsr] != ',') ++iUsr; /* skip to next name */ } if (iUsr < len) { ++iUsr; /* skip "," */ while (iUsr < len && isspace(c[iUsr])) ++iUsr; /* skip whitespace */ } } if (i == MAXUNAMES && iUsr != len) { LogError(0, RS_RET_ERR, "omusrmsg supports only up to %d " "user names in a single action - all others have been ignored", MAXUNAMES); } } static inline void setInstParamDefaults(instanceData *pData) { pData->bIsWall = 0; pData->tplName = NULL; } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); CODE_STD_STRING_REQUESTnewActInst(1); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "users")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"*", 1)) { pData->bIsWall = 1; } else { populateUsers(pData, pvals[i].val.d.estr); } } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf( "omusrmsg: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } if (pData->tplName == NULL) { CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)strdup(pData->bIsWall ? " WallFmt" : " StdUsrMsgFmt"), OMSR_NO_RQD_TPL_OPTS)); } else { CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)strdup((char *)pData->tplName), OMSR_NO_RQD_TPL_OPTS)); } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINparseSelectorAct es_str_t *usrs; int bHadWarning; CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) bHadWarning = 0; if (!strncmp((char *)p, ":omusrmsg:", sizeof(":omusrmsg:") - 1)) { p += sizeof(":omusrmsg:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ } else { if (!*p || !((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_' || *p == '.' || *p == '*')) { ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); } else { LogMsg(0, RS_RET_OUTDATED_STMT, LOG_WARNING, "action '%s' treated as ':omusrmsg:%s' - please " "use ':omusrmsg:%s' syntax instead, '%s' will " "not be supported in the future", p, p, p, p); bHadWarning = 1; } } CHKiRet(createInstance(&pData)); if (*p == '*') { /* wall */ dbgprintf("write-all"); ++p; /* eat '*' */ pData->bIsWall = 1; /* write to all users */ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar *)" WallFmt")); } else { /* everything else is currently treated as a user name */ usrs = es_newStr(128); while (*p && *p != ';') { es_addChar(&usrs, *p); ++p; } populateUsers(pData, usrs); es_deleteStr(usrs); if ((iRet = cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar *)" StdUsrMsgFmt")) != RS_RET_OK) goto finalize_it; } if (iRet == RS_RET_OK && bHadWarning) iRet = RS_RET_OK_WARN; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(UsrMsg) CODESTARTmodInit; INITLegCnfVars; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr; ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/rsyslogd.80000644000000000000000000000013215114522477015640 xustar0030 mtime=1764926783.046632128 30 atime=1764926784.241661461 30 ctime=1764935924.184591905 rsyslog-8.2512.0/tools/rsyslogd.80000664000175000017500000002473415114522477015316 0ustar00rgerrger.\" Copyright 2004-2014 Rainer Gerhards and Adiscon for the rsyslog modifications .\" May be distributed under the GNU General Public License .\" .TH RSYSLOGD 8 "18 February 2025" "Version 8.2502.0" "Linux System Administration" .SH NAME rsyslogd \- reliable and extended syslogd .SH SYNOPSIS .B rsyslogd .RB [ " \-d " ] .RB [ " \-D " ] .RB [ " \-f " .I config file ] .RB [ " \-i " .I pid file ] .RB [ " \-n " ] .RB [ " \-N " .I level ] .RB [ " \-o " .I fullconf ] .RB [ " \-C " ] .RB [ " \-v " ] .LP .SH DESCRIPTION .B Rsyslogd is a system utility providing support for message logging. Support of both internet and unix domain sockets enables this utility to support both local and remote logging. .B Note that this version of rsyslog ships with extensive documentation in HTML format. This is provided in the ./doc subdirectory and probably in a separate package if you installed rsyslog via a packaging system. To use rsyslog's advanced features, you .B need to look at the HTML documentation, because the man pages only covers basic aspects of operation. .B For details and configuration examples, see the rsyslog.conf (5) .B man page and the online documentation at https://www.rsyslog.com/doc/ .BR Rsyslogd (8) is derived from the sysklogd package which in turn is derived from the stock BSD sources. .B Rsyslogd provides a kind of logging that many modern programs use. Every logged message contains at least a time and a hostname field, normally a program name field, too, but that depends on how trusty the logging program is. The rsyslog package supports free definition of output formats via templates. It also supports precise timestamps and writing directly to databases. If the database option is used, tools like phpLogCon can be used to view the log data. While the .B rsyslogd sources have been heavily modified a couple of notes are in order. First of all there has been a systematic attempt to ensure that rsyslogd follows its default, standard BSD behavior. Of course, some configuration file changes are necessary in order to support the template system. However, rsyslogd should be able to use a standard syslog.conf and act like the original syslogd. However, an original syslogd will not work correctly with a rsyslog-enhanced configuration file. At best, it will generate funny looking file names. The second important concept to note is that this version of rsyslogd interacts transparently with the version of syslog found in the standard libraries. If a binary linked to the standard shared libraries fails to function correctly we would like an example of the anomalous behavior. The main configuration file .I /etc/rsyslog.conf or an alternative file, given with the .B "\-f" option, is read at startup. Any lines that begin with the hash mark (``#'') and empty lines are ignored. If an error occurs during parsing the error element is ignored. It is tried to parse the rest of the line. .LP .SH OPTIONS .TP .B "\-D" Runs the Bison config parser in debug mode. This may help when hard to find syntax errors are reported. Please note that the output generated is deeply technical and originally targeted towards developers. .TP .B "\-d" Turns on debug mode. See the DEBUGGING section for more information. .TP .BI "\-f " "config file" Specify an alternative configuration file instead of .IR /etc/rsyslog.conf "," which is the default. .TP .BI "\-i " "pid file" Specify an alternative pid file instead of the default one. This option must be used if multiple instances of rsyslogd should run on a single machine. To disable writing a pid file, use the reserved name "NONE" (all upper case!), so "-iNONE". .TP .B "\-n" Avoid auto-backgrounding. This is needed especially if the .B rsyslogd is started and controlled by .BR init (8). .TP .B "\-N " "level" Do a config check. Do NOT run in regular mode, just check configuration file correctness. This option is meant to verify a config file. To do so, run rsyslogd interactively in foreground, specifying -f and -N level. The level argument modifies behaviour. Currently, 0 is the same as not specifying the -N option at all (so this makes limited sense) and 1 actually activates the code. Later, higher levels will mean more verbosity (this is a forward-compatibility option). .TP .B "\-o " "fullconf" Generates a consolidated config file .I fullconf that contains all of rsyslog's configuration in a single file. Include files are exploded into that file in exactly the way rsyslog sees them. This option is useful for troubleshooting, especially if problems with the order of action processing is suspected. It may also be used to check for "unexepectedly" included config content. .TP .BI "\-C" This prevents rsyslogd from changing to the root directory. This is almost never a good idea in production use. This option was introduced in support of the internal testbed. .TP .B "\-v" Print version and exit. .LP .SH SIGNALS .B Rsyslogd reacts to a set of signals. You may easily send a signal to .B rsyslogd using the following: .IP .nf kill -SIGNAL $(cat /var/run/rsyslogd.pid) .fi .PP Note that -SIGNAL must be replaced with the actual signal you are trying to send, e.g. with HUP. So it then becomes: .IP .nf kill -HUP $(cat /var/run/rsyslogd.pid) .fi .PP .TP .B HUP This lets .B rsyslogd perform close all open files. .TP .B TERM ", " QUIT .B Rsyslogd will die. .TP .B INT .B Rsyslogd will die. This signal is only processed if .B rsyslogd was started with the .B "\-d" debug option, if the .B shutdown.enable.ctl-c global config parameter is set, or if running as PID 1 (e.g. in a container). .TP .B USR1 Switch debugging on/off. This option can only be used if .B rsyslogd is started with the .B "\-d" debug option. .TP .B CHLD Wait for children if some were born, because of wall'ing messages. .LP .SH SECURITY THREATS There is the potential for the rsyslogd daemon to be used as a conduit for a denial of service attack. A rogue program(mer) could very easily flood the rsyslogd daemon with syslog messages resulting in the log files consuming all the remaining space on the filesystem. Activating logging over the inet domain sockets will of course expose a system to risks outside of programs or individuals on the local machine. There are a number of methods of protecting a machine: .IP 1. Implement kernel firewalling to limit which hosts or networks have access to the 514/UDP socket. .IP 2. Logging can be directed to an isolated or non-root filesystem which, if filled, will not impair the machine. .IP 3. The ext2 filesystem can be used which can be configured to limit a certain percentage of a filesystem to usage by root only. \fBNOTE\fP that this will require rsyslogd to be run as a non-root process. \fBALSO NOTE\fP that this will prevent usage of remote logging on the default port since rsyslogd will be unable to bind to the 514/UDP socket. .IP 4. Disabling inet domain sockets will limit risk to the local machine. .SS Message replay and spoofing If remote logging is enabled, messages can easily be spoofed and replayed. As the messages are transmitted in clear-text, an attacker might use the information obtained from the packets for malicious things. Also, an attacker might replay recorded messages or spoof a sender's IP address, which could lead to a wrong perception of system activity. These can be prevented by using GSS-API authentication and encryption. Be sure to think about syslog network security before enabling it. .LP .SH DEBUGGING When debugging is turned on using the .B "\-d" option, .B rsyslogd produces debugging information according to the .B RSYSLOG_DEBUG environment variable and the signals received. When run in foreground, the information is written to stdout. An additional output file can be specified using the .B RSYSLOG_DEBUGLOG environment variable. .SH FILES .PD 0 .TP .I /etc/rsyslog.conf Configuration file for .BR rsyslogd . See .BR rsyslog.conf (5) for exact information. .TP .I /dev/log The Unix domain socket to from where local syslog messages are read. .TP .I /var/run/rsyslogd.pid The file containing the process id of .BR rsyslogd . .TP .I prefix/lib/rsyslog Default directory for .B rsyslogd modules. The .I prefix is specified during compilation (e.g. /usr/local). .SH ENVIRONMENT .TP .B RSYSLOG_DEBUG Controls runtime debug support. It contains an option string with the following options possible (all are case insensitive): .RS .IP Debug Turns on debugging and prevents forking. This is processed earlier in the startup than command line options (i.e. -d) and as such enables earlier debugging output. Mutually exclusive with DebugOnDemand. .IP DebugOnDemand Enables debugging but turns off debug output. The output can be toggled by sending SIGUSR1. Mutually exclusive with Debug. .IP LogFuncFlow Print out the logical flow of functions (entering and exiting them) .IP FileTrace Specifies which files to trace LogFuncFlow. If not set (the default), a LogFuncFlow trace is provided for all files. Set to limit it to the files specified.FileTrace may be specified multiple times, one file each (e.g. export RSYSLOG_DEBUG="LogFuncFlow FileTrace=vm.c FileTrace=expr.c" .IP PrintFuncDB Print the content of the debug function database whenever debug information is printed (e.g. abort case)! .IP PrintAllDebugInfoOnExit Print all debug information immediately before rsyslogd exits (currently not implemented!) .IP PrintMutexAction Print mutex action as it happens. Useful for finding deadlocks and such. .IP NoLogTimeStamp Do not prefix log lines with a timestamp (default is to do that). .IP NoStdOut Do not emit debug messages to stdout. If RSYSLOG_DEBUGLOG is not set, this means no messages will be displayed at all. .IP Help Display a very short list of commands - hopefully a life saver if you can't access the documentation... .RE .TP .B RSYSLOG_DEBUGLOG If set, writes (almost) all debug message to the specified log file in addition to stdout. .TP .B RSYSLOG_MODDIR Provides the default directory in which loadable modules reside. .PD .SH BUGS Please review the file BUGS for up-to-date information on known bugs and annoyances. .SH Further Information Please visit .BR https://www.rsyslog.com/doc/ for additional information, tutorials and a support forum. .SH SEE ALSO .BR rsyslog.conf (5), .BR logger (1), .BR syslog (2), .BR syslog (3), .BR services (5), .BR savelog (8) .LP .SH COLLABORATORS .B rsyslogd is derived from sysklogd sources, which in turn was taken from the BSD sources. Special thanks to Greg Wettstein (greg@wind.enjellic.com) and Martin Schulze (joey@linux.de) for the fine sysklogd package. .PD 0 .TP Rainer Gerhards .TP Adiscon GmbH .TP Grossrinderfeld, Germany .TP rgerhards@adiscon.com .PD rsyslog-8.2512.0/tools/PaxHeaders/smtradfwd.c0000644000000000000000000000013215055605325016036 xustar0030 mtime=1756826325.661800864 30 atime=1764931034.977590926 30 ctime=1764935924.172591722 rsyslog-8.2512.0/tools/smtradfwd.c0000664000175000017500000001004215055605325015477 0ustar00rgerrger/* smtradfwd.c * This is a strgen module for the traditional forwarding format. * * Format generated: * "<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%" * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2010-06-01 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "unicode-helper.h" MODULE_TYPE_STRGEN MODULE_TYPE_NOKEEP; STRGEN_NAME("RSYSLOG_TraditionalForwardFormat") /* internal structures */ DEF_SMOD_STATIC_DATA; /* config data */ /* This strgen tries to minimize the amount of reallocs be first obtaining pointers to all strings * needed (including their length) and then calculating the actual space required. So when we * finally copy, we know exactly what we need. So we do at most one alloc. */ BEGINstrgen register int iBuf; const char *pPRI; size_t lenPRI; uchar *pTimeStamp; uchar *pHOSTNAME; size_t lenHOSTNAME; uchar *pTAG; int lenTAG; uchar *pMSG; size_t lenMSG; size_t lenTotal; CODESTARTstrgen; /* first obtain all strings and their length (if not fixed) */ pPRI = getPRI(pMsg); lenPRI = strlen(pPRI); pTimeStamp = (uchar *)getTimeReported(pMsg, tplFmtRFC3164Date); pHOSTNAME = (uchar *)getHOSTNAME(pMsg); lenHOSTNAME = getHOSTNAMELen(pMsg); getTAG(pMsg, &pTAG, &lenTAG, LOCK_MUTEX); if (lenTAG > 32) lenTAG = 32; /* for forwarding, a max of 32 chars is permitted (RFC!) */ pMSG = getMSG(pMsg); lenMSG = getMSGLen(pMsg); /* calculate len, constants for spaces and similar fixed strings */ lenTotal = 1 + lenPRI + 1 + CONST_LEN_TIMESTAMP_3164 + 1 + lenHOSTNAME + 1 + lenTAG + lenMSG + 1; if (pMSG[0] != ' ') ++lenTotal; /* then we need to introduce one additional space */ /* now make sure buffer is large enough */ if (lenTotal >= iparam->lenBuf) CHKiRet(ExtendBuf(iparam, lenTotal)); /* and concatenate the resulting string */ iparam->param[0] = '<'; memcpy(iparam->param + 1, pPRI, lenPRI); iBuf = lenPRI + 1; iparam->param[iBuf++] = '>'; memcpy(iparam->param + iBuf, pTimeStamp, CONST_LEN_TIMESTAMP_3164); iBuf += CONST_LEN_TIMESTAMP_3164; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pHOSTNAME, lenHOSTNAME); iBuf += lenHOSTNAME; iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pTAG, lenTAG); iBuf += lenTAG; if (pMSG[0] != ' ') iparam->param[iBuf++] = ' '; memcpy(iparam->param + iBuf, pMSG, lenMSG); iBuf += lenMSG; /* string terminator */ iparam->param[iBuf] = '\0'; iparam->lenStr = lenTotal - 1; /* do not count \0! */ finalize_it: ENDstrgen BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_SMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(smtradfwd) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf( "rsyslog traditional (network) forward format strgen init called, compiled with " "version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/gethostn.c0000644000000000000000000000013215055605325015676 xustar0030 mtime=1756826325.659800834 30 atime=1764931133.290194066 30 ctime=1764935924.109590757 rsyslog-8.2512.0/tools/gethostn.c0000664000175000017500000000270215055605325015343 0ustar00rgerrger/* gethostn - a small diagnostic utility to show what the * gethostname() API returns. Of course, this tool duplicates * functionality already found in other tools. But the point is * that the API shall be called by a program that is compiled like * rsyslogd and does exactly what rsyslog does. * * Copyright 2008 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include int main(int __attribute__((unused)) argc, char __attribute__((unused)) * argv[]) { char hostname[4096]; /* this should always be sufficient ;) */ int err; err = gethostname(hostname, sizeof(hostname)); if (err) { perror("gethostname failed"); exit(1); } printf("hostname of this system is '%s'.\n", hostname); return 0; } rsyslog-8.2512.0/tools/PaxHeaders/omshell.h0000644000000000000000000000013215055605325015513 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.707723153 30 ctime=1764935924.121590941 rsyslog-8.2512.0/tools/omshell.h0000664000175000017500000000240015055605325015153 0ustar00rgerrger/* omshell.c * These are the definitions for the build-in shell output module. * * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c) * * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ACTSHELL_H_INCLUDED #define ACTSHELL_H_INCLUDED 1 /* prototypes */ rsRetVal modInitShell(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef ACTSHELL_H_INCLUDED */ /* * vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/smfwd.h0000644000000000000000000000013215055605325015170 xustar0030 mtime=1756826325.661800864 30 atime=1764930982.722723403 30 ctime=1764935924.170591691 rsyslog-8.2512.0/tools/smfwd.h0000664000175000017500000000222215055605325014632 0ustar00rgerrger/* smfwd.h * * File begun on 2010-06-04 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SMFWD_H_INCLUDED #define SMFWD_H_INCLUDED 1 /* prototypes */ rsRetVal modInitsmfwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef SMFWD_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/omusrmsg.h0000644000000000000000000000013215055605325015724 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.709723186 30 ctime=1764935924.126591018 rsyslog-8.2512.0/tools/omusrmsg.h0000664000175000017500000000364015055605325015373 0ustar00rgerrger/** * @file omusrmsg.h * @brief Interface for the built-in user message output module. * * This header exposes the initialization routine for the `omusrmsg` * module. The module implements delivery of log messages directly to * logged-in users (either individually or via "wall" style broadcast). * * File begun on 2007-07-13 by Rainer Gerhards. * * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMUSRMSG_H_INCLUDED #define OMUSRMSG_H_INCLUDED 1 /* prototypes */ /** * Initialize the omusrmsg module. * * @param[in] iIFVersRequested interface version requested by the core * @param[out] ipIFVersProvided the interface version actually provided * @param[out] pQueryEtryPt receives module entry points * @param[in] pHostQueryEtryPt callback used to query host entry points * @param[in] pModInfo pointer to the module information block * * @return rsRetVal standard return code */ rsRetVal modInitUsrMsg(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *pModInfo); #endif /* #ifndef OMUSRMSG_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/iminternal.c0000644000000000000000000000013215055605325016205 xustar0030 mtime=1756826325.659800834 30 atime=1764931035.225595016 30 ctime=1764935924.177591798 rsyslog-8.2512.0/tools/iminternal.c0000664000175000017500000001202415055605325015650 0ustar00rgerrger/* iminternal.c * This file set implements the internal messages input module for rsyslog. * Note: we currently do not have an input module spec, but * we will have one in the future. This module needs then to be * adapted. * * File begun on 2007-08-03 by RGerhards * * Copyright 2007-2022 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include "syslogd.h" #include "linkedlist.h" #include "iminternal.h" #include "unicode-helper.h" static linkedList_t llMsgs; static pthread_mutex_t mutList = PTHREAD_MUTEX_INITIALIZER; /* destructs an iminternal object */ static rsRetVal iminternalDestruct(iminternal_t *pThis) { DEFiRet; if (pThis->pMsg != NULL) msgDestruct(&pThis->pMsg); free(pThis); RETiRet; } /* Construct an iminternal object */ static rsRetVal iminternalConstruct(iminternal_t **ppThis) { DEFiRet; if ((*ppThis = (iminternal_t *)calloc(1, sizeof(iminternal_t))) == NULL) { iRet = RS_RET_OUT_OF_MEMORY; } RETiRet; } /* add a message to the linked list * Note: the pMsg reference counter is not incremented. Consequently, * the caller must NOT decrement it. The caller actually hands over * full ownership of the pMsg object. */ rsRetVal iminternalAddMsg(smsg_t *pMsg) { DEFiRet; iminternal_t *pThis = NULL; struct timespec to; int r; int is_locked = 0; /* we guard against deadlock, so we can guarantee rsyslog will never * block due to internal messages. The 1 second timeout should be * sufficient under all circumstances. */ to.tv_sec = time(NULL) + 1; to.tv_nsec = 0; #if !defined(__APPLE__) r = pthread_mutex_timedlock(&mutList, &to); #else r = pthread_mutex_trylock(&mutList); // must check #endif if (r != 0) { dbgprintf("iminternalAddMsg: timedlock for mutex failed with %d, msg %s\n", r, getMSG(pMsg)); /* the message is lost, nothing we can do against this! */ msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_ERR); } is_locked = 1; CHKiRet(iminternalConstruct(&pThis)); pThis->pMsg = pMsg; CHKiRet(llAppend(&llMsgs, NULL, (void *)pThis)); if (PREFER_FETCH_32BIT(bHaveMainQueue)) { DBGPRINTF("signaling new internal message via SIGTTOU: '%s'\n", pThis->pMsg->pszRawMsg); kill(glblGetOurPid(), SIGTTOU); } finalize_it: if (is_locked) { pthread_mutex_unlock(&mutList); } if (iRet != RS_RET_OK) { dbgprintf("iminternalAddMsg() error %d - can not otherwise report this error, message lost\n", iRet); if (pThis != NULL) iminternalDestruct(pThis); } RETiRet; } /* pull the first error message from the linked list, remove it * from the list and return it to the caller. The caller is * responsible for freeing the message! */ rsRetVal iminternalRemoveMsg(smsg_t **ppMsg) { DEFiRet; iminternal_t *pThis; linkedListCookie_t llCookie = NULL; pthread_mutex_lock(&mutList); CHKiRet(llGetNextElt(&llMsgs, &llCookie, (void *)&pThis)); if (!strcmp((char *)pThis->pMsg->pszHOSTNAME, "[localhost]")) { /* early (pre-conf) startup message detected, need to set real hostname now */ MsgSetHOSTNAME(pThis->pMsg, glblGetLocalHostName(), ustrlen(glblGetLocalHostName())); } *ppMsg = pThis->pMsg; pThis->pMsg = NULL; /* we do no longer own it - important for destructor */ if (llDestroyRootElt(&llMsgs) != RS_RET_OK) { dbgprintf( "Root element of iminternal linked list could not be destroyed - there is " "nothing we can do against it, we ignore it for now. Things may go wild " "from here on. This is most probably a program logic error.\n"); } finalize_it: pthread_mutex_unlock(&mutList); RETiRet; } /* initialize the iminternal subsystem * must be called once at the start of the program */ rsRetVal modInitIminternal(void) { DEFiRet; iRet = llInit(&llMsgs, (rsRetVal(*)(void *))iminternalDestruct, NULL, NULL); RETiRet; } /* de-initialize the iminternal subsystem * must be called once at the end of the program * Note: the error list must have been pulled first. We do * NOT care if there are any errors left - we simply destroy * them. */ rsRetVal modExitIminternal(void) { DEFiRet; iRet = llDestroy(&llMsgs); RETiRet; } rsyslog-8.2512.0/tools/PaxHeaders/logctl.c0000644000000000000000000000013115071746523015332 xustar0030 mtime=1760021843.913422169 30 atime=1764931029.411499062 29 ctime=1764935924.10259065 rsyslog-8.2512.0/tools/logctl.c0000664000175000017500000003116115071746523015001 0ustar00rgerrger/** * logctl - a tool to access lumberjack logs in MongoDB * ... and potentially other sources in the future. * * Copyright 2012-2022 Ulrike Gerhards and Adiscon GmbH. * * Copyright 2017 Hugo Soszynski and aDvens * * long short * level l read records with level x * severity s read records with severity x * ret r number of records to return * skip k number of records to skip * sys y read records of system x * msg m read records with message containing x * datef f read records starting on time received x * dateu u read records until time received x * * examples: * * logctl -f 15/05/2012-12:00:00 -u 15/05/2012-12:37:00 * logctl -s 50 --ret 10 * logctl -m "closed" * logctl -l "INFO" * logctl -s 3 * logctl -y "ubuntu" * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #define _XOPEN_SOURCE 700 /* Need to define POSIX version to use strptime() */ #include #include #include #include #include #include #include #include "rsyslog.h" /* we need this to avoid issues with older versions of libbson */ PRAGMA_DIAGNOSTIC_PUSH; PRAGMA_IGNORE_Wpragmas; PRAGMA_IGNORE_Wunknown_warning_option; PRAGMA_IGNORE_Wunknown_attribute; PRAGMA_IGNORE_Wexpansion_to_defined; PRAGMA_IGNORE_Wstrict_prototypes; PRAGMA_IGNORE_Wold_style_definition; #ifdef HAVE_LIBMONGOC1 #include #include #else #include #include #endif PRAGMA_DIAGNOSTIC_POP; #define N 80 static struct option long_options[] = {{"level", required_argument, NULL, 'l'}, {"severity", required_argument, NULL, 's'}, {"ret", required_argument, NULL, 'r'}, {"skip", required_argument, NULL, 'k'}, {"sys", required_argument, NULL, 'y'}, {"msg", required_argument, NULL, 'm'}, {"datef", required_argument, NULL, 'f'}, {"dateu", required_argument, NULL, 'u'}, {NULL, 0, NULL, 0}}; struct queryopt { int32_t e_sever; int32_t e_ret; int32_t e_skip; char* e_date; char* e_level; char* e_msg; char* e_sys; char* e_dateu; int bsever; int blevel; int bskip; int bret; int bsys; int bmsg; int bdate; int bdatef; int bdateu; }; struct ofields { const char* msg; const char* syslog_tag; const char* prog; char* date; int64_t date_r; }; struct query_doc { bson_t* query; }; struct select_doc { bson_t* select; }; struct db_connect { mongoc_client_t* conn; }; struct db_collection { mongoc_collection_t* collection; }; struct db_cursor { mongoc_cursor_t* cursor; }; struct results { const bson_t* result; }; static void formater(struct ofields* fields) { char str[N]; time_t rtime; struct tm now; rtime = (time_t)(fields->date_r / 1000); strftime(str, N, "%b %d %H:%M:%S", gmtime_r(&rtime, &now)); printf("%s %s %s %s\n", str, fields->prog, fields->syslog_tag, fields->msg); } static struct ofields* get_data(struct results* res) { struct ofields* fields; const char* msg; const char* prog; const char* syslog_tag; int64_t date_r; bson_iter_t c; fields = malloc(sizeof(struct ofields)); bson_iter_init_find(&c, res->result, "msg"); if (!(msg = bson_iter_utf8(&c, NULL))) { perror("bson_cursor_get_string()"); exit(1); } bson_iter_init_find(&c, res->result, "sys"); if (!(prog = bson_iter_utf8(&c, NULL))) { perror("bson_cursor_get_string()"); exit(1); } bson_iter_init_find(&c, res->result, "syslog_tag"); if (!(syslog_tag = bson_iter_utf8(&c, NULL))) { perror("bson_cursor_get_string()"); exit(1); } bson_iter_init_find(&c, res->result, "time_rcvd"); if (!(date_r = bson_iter_date_time(&c))) { perror("bson_cursor_get_utc_datetime()"); exit(1); } fields->msg = msg; fields->prog = prog; fields->syslog_tag = syslog_tag; fields->date_r = date_r; return fields; } static void getoptions(int argc, char* argv[], struct queryopt* opt) { int iarg; while ((iarg = getopt_long(argc, argv, "l:s:r:k:y:f:u:m:", long_options, NULL)) != -1) { /* check to see if a single character or long option came through */ switch (iarg) { /* short option 's' */ case 's': opt->bsever = 1; opt->e_sever = atoi(optarg); break; /* short option 'r' */ case 'r': opt->bret = 1; opt->e_ret = atoi(optarg); break; /* short option 'f' : date from */ case 'f': opt->bdate = 1; opt->bdatef = 1; opt->e_date = optarg; break; /* short option 'u': date until */ case 'u': opt->bdate = 1; opt->bdateu = 1; opt->e_dateu = optarg; break; /* short option 'k' */ case 'k': opt->bskip = 1; opt->e_skip = atoi(optarg); break; /* short option 'l' */ case 'l': opt->blevel = 1; opt->e_level = optarg; break; /* short option 'm' */ case 'm': opt->bmsg = 1; opt->e_msg = optarg; break; /* short option 'y' */ case 'y': opt->bsys = 1; opt->e_sys = optarg; break; default: break; } /* end switch iarg */ } /* end while */ } /* end void getoptions */ static struct select_doc* create_select(void) /* BSON object indicating the fields to return */ { struct select_doc* s_doc; s_doc = malloc(sizeof(struct select_doc)); s_doc->select = bson_new(); bson_append_utf8(s_doc->select, "syslog_tag", 10, "s", 1); bson_append_utf8(s_doc->select, "msg", 3, "ERROR", 5); bson_append_utf8(s_doc->select, "sys", 3, "sys", 3); bson_append_date_time(s_doc->select, "time_rcvd", 9, 1ll); return s_doc; } static struct query_doc* create_query(struct queryopt* opt) { struct query_doc* qu_doc; bson_t *query_what, *order_what, *msg_what, *date_what; struct tm tm; time_t t; int64_t ts; qu_doc = malloc(sizeof(struct query_doc)); qu_doc->query = bson_new(); query_what = bson_new(); bson_init(query_what); bson_append_document_begin(qu_doc->query, "$query", 6, query_what); if (opt->bsever == 1) { bson_append_int32(query_what, "syslog_sever", 12, opt->e_sever); } if (opt->blevel == 1) { bson_append_utf8(query_what, "level", 5, opt->e_level, -1); } if (opt->bmsg == 1) { msg_what = bson_new(); bson_init(msg_what); bson_append_document_begin(query_what, "msg", 3, msg_what); bson_append_utf8(msg_what, "$regex", 6, opt->e_msg, -1); bson_append_utf8(msg_what, "$options", 8, "i", 1); bson_append_document_end(query_what, msg_what); } if (opt->bdate == 1) { date_what = bson_new(); bson_init(date_what); bson_append_document_begin(query_what, "time_rcvd", 9, date_what); if (opt->bdatef == 1) { tm.tm_isdst = -1; strptime(opt->e_date, "%d/%m/%Y-%H:%M:%S", &tm); tm.tm_hour = tm.tm_hour + 1; t = mktime(&tm); ts = 1000 * (int64_t)t; bson_append_date_time(date_what, "$gt", 3, ts); } if (opt->bdateu == 1) { tm.tm_isdst = -1; strptime(opt->e_dateu, "%d/%m/%Y-%H:%M:%S", &tm); tm.tm_hour = tm.tm_hour + 1; t = mktime(&tm); ts = 1000 * (int64_t)t; bson_append_date_time(date_what, "$lt", 3, ts); } bson_append_document_end(query_what, date_what); } if (opt->bsys == 1) { bson_append_utf8(query_what, "sys", 3, opt->e_sys, -1); } bson_append_document_end(qu_doc->query, query_what); order_what = bson_new(); bson_init(order_what); bson_append_document_begin(qu_doc->query, "$orderby", 8, order_what); bson_append_date_time(order_what, "time_rcvd", 9, 1ll); bson_append_document_end(qu_doc->query, order_what); bson_free(order_what); return qu_doc; } static struct db_connect* create_conn(void) { struct db_connect* db_conn; db_conn = malloc(sizeof(struct db_connect)); db_conn->conn = mongoc_client_new("mongodb://localhost:27017"); if (!db_conn->conn) { perror("mongo_sync_connect()"); exit(1); } return db_conn; } static void close_conn(struct db_connect* db_conn) { mongoc_client_destroy(db_conn->conn); free(db_conn); } static void free_cursor(struct db_cursor* db_c) { mongoc_cursor_destroy(db_c->cursor); free(db_c); } static struct db_cursor* launch_query(struct queryopt* opt, __attribute__((unused)) struct select_doc* s_doc, struct query_doc* qu_doc, struct db_collection* db_coll) { struct db_cursor* out; #if MONGOC_CHECK_VERSION(1, 5, 0) /* Declaration before code (ISO C90) */ const bson_t* opts = BCON_NEW("skip", BCON_INT32(opt->e_skip), "limit", BCON_INT32(opt->e_ret)); #endif /* MONGOC_CHECK_VERSION (1, 5, 0) */ out = malloc(sizeof(struct db_cursor)); if (!out) { perror("mongo_sync_cmd_query()"); printf("malloc failed\n"); exit(1); } #if MONGOC_CHECK_VERSION(1, 5, 0) out->cursor = mongoc_collection_find_with_opts(db_coll->collection, qu_doc->query, opts, NULL); #else /* !MONGOC_CHECK_VERSION (1, 5, 0) */ out->cursor = mongoc_collection_find(db_coll->collection, MONGOC_QUERY_NONE, (uint32_t)opt->e_skip, (uint32_t)opt->e_ret, 0, qu_doc->query, s_doc->select, NULL); #endif /* MONGOC_CHECK_VERSION (1, 5, 0) */ if (!out->cursor) { perror("mongo_sync_cmd_query()"); printf("no records found\n"); exit(1); } return out; } static int cursor_next(struct db_cursor* db_c, struct results* res) { if (mongoc_cursor_next(db_c->cursor, &res->result)) return true; return false; } static struct db_collection* get_collection(struct db_connect* db_conn) { struct db_collection* coll; coll = malloc(sizeof(struct db_collection)); coll->collection = mongoc_client_get_collection(db_conn->conn, "syslog", "log"); return coll; } static void release_collection(struct db_collection* db_coll) { mongoc_collection_destroy(db_coll->collection); free(db_coll); } int main(int argc, char* argv[]) { struct queryopt opt; struct ofields* fields; struct select_doc* s_doc; struct query_doc* qu_doc; struct db_connect* db_conn; struct db_cursor* db_c; struct db_collection* db_coll; struct results* res; memset(&opt, 0, sizeof(struct queryopt)); mongoc_init(); /* Initialisation of mongo-c-driver */ getoptions(argc, argv, &opt); qu_doc = create_query(&opt); /* create query */ s_doc = create_select(); db_conn = create_conn(); /* create connection */ db_coll = get_collection(db_conn); /* Get the collection to perform query on */ db_c = launch_query(&opt, s_doc, qu_doc, db_coll); /* launch the query and get the related cursor */ res = malloc(sizeof(struct results)); while (cursor_next(db_c, res)) /* Move cursor & get pointed data */ { fields = get_data(res); formater(fields); /* format output */ free(fields); } free(res); free_cursor(db_c); release_collection(db_coll); close_conn(db_conn); free(s_doc); free(qu_doc); mongoc_cleanup(); /* Cleanup of mongo-c-driver */ return (0); } rsyslog-8.2512.0/tools/PaxHeaders/ompipe.c0000644000000000000000000000013215055605325015334 xustar0030 mtime=1756826325.660800849 30 atime=1764931033.112560159 30 ctime=1764935924.138591201 rsyslog-8.2512.0/tools/ompipe.c0000664000175000017500000003135715055605325015011 0ustar00rgerrger/* ompipe.c * This is the implementation of the build-in pipe output module. * Note that this module stems back to the "old" (4.4.2 and below) * omfile. There were some issues with the new omfile code and pipes * (namely in regard to xconsole), so we took out the pipe code and moved * that to a separate module. That a) immediately solves the issue for a * less common use case and probably makes it much easier to enhance * file and pipe support (now independently) in the future (we always * needed to think about pipes in omfile so far, what we now no longer * need to, hopefully resulting in reduction of complexity). * * NOTE: read comments in module-template.h to understand how this pipe * works! * * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "ompipe.h" #include "omfile.h" /* for dirty trick: access to $ActionFileDefaultTemplate value */ #include "cfsysline.h" #include "module-template.h" #include "conf.h" #include "errmsg.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("ompipe") /* internal structures */ DEF_OMOD_STATIC_DATA; typedef struct _instanceData { uchar *pipe; /* pipe or template name (display only) */ uchar *tplName; /* format template to use */ short fd; /* pipe descriptor for (current) pipe */ pthread_mutex_t mutWrite; /* guard against multiple instances writing to same pipe */ sbool bHadError; /* did we already have/report an error on this pipe? */ sbool bTryResumeReopen; /* should we attempt to reopen the pipe on action resume? */ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; typedef struct configSettings_s { EMPTY_STRUCT } configSettings_t; static configSettings_t __attribute__((unused)) cs; /* tables for interfacing with the v6 config system */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"template", eCmdHdlrGetWord, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"pipe", eCmdHdlrString, CNFPARAM_REQUIRED}, {"template", eCmdHdlrGetWord, 0}, {"tryResumeReopen", eCmdHdlrBinary, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ uchar *tplName; /* default template */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* this function gets the default template */ static uchar *getDfltTpl(void) { if (loadModConf != NULL && loadModConf->tplName != NULL) return loadModConf->tplName; else return (uchar *)"RSYSLOG_FileFormat"; } BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars; ENDinitConfVars BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; dbgprintf("pipe %s", pData->pipe); if (pData->fd == -1) dbgprintf(" (unused)"); ENDdbgPrintInstInfo /* This is now shared code for all types of files. It simply prepares * pipe access, which, among others, means the the pipe wil be opened * and any directories in between will be created (based on config, of * course). -- rgerhards, 2008-10-22 * changed to iRet interface - 2009-03-19 */ static rsRetVal preparePipe(instanceData *pData) { DEFiRet; pData->fd = open((char *)pData->pipe, O_RDWR | O_NONBLOCK | O_CLOEXEC); if (pData->fd < 0) { pData->fd = -1; if (!pData->bHadError) { LogError(errno, RS_RET_NO_FILE_ACCESS, "Could not open output pipe '%s':", pData->pipe); pData->bHadError = 1; } DBGPRINTF("Error opening log pipe: %s\n", pData->pipe); } RETiRet; } /* rgerhards 2004-11-11: write to a pipe output. This * will be called for all outputs using pipe semantics, * for example also for pipes. */ static rsRetVal writePipe(uchar **ppString, instanceData *pData) { int iLenWritten; DEFiRet; assert(pData != NULL); if (pData->fd == -1) { rsRetVal iRetLocal; iRetLocal = preparePipe(pData); if ((iRetLocal != RS_RET_OK) || (pData->fd == -1)) ABORT_FINALIZE(RS_RET_SUSPENDED); /* whatever the failure was, we need to retry */ } /* create the message based on format specified */ iLenWritten = write(pData->fd, ppString[0], strlen((char *)ppString[0])); if (iLenWritten < 0) { const int e = errno; /* If a named pipe is full, we suspend this action for a while */ if (e == EAGAIN) ABORT_FINALIZE(RS_RET_SUSPENDED); close(pData->fd); pData->fd = -1; /* tell that fd is no longer open! */ iRet = RS_RET_SUSPENDED; LogError(e, NO_ERRCODE, "write error on pipe %s", pData->pipe); } finalize_it: RETiRet; } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; pModConf->tplName = NULL; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for ompipe:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "template")) { loadModConf->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (pszFileDfltTplName != NULL) { LogError(0, RS_RET_DUP_PARAM, "ompipe: warning: default template " "was already set via legacy directive - may lead to inconsistent " "results."); } } else { dbgprintf( "ompipe: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ /* free legacy config vars */ free(pszFileDfltTplName); pszFileDfltTplName = NULL; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free(pModConf->tplName); ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; pData->pipe = NULL; pData->fd = -1; pData->bHadError = 0; pData->bTryResumeReopen = 0; pthread_mutex_init(&pData->mutWrite, NULL); ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINfreeInstance CODESTARTfreeInstance; pthread_mutex_destroy(&pData->mutWrite); free(pData->pipe); if (pData->fd != -1) close(pData->fd); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINtryResume instanceData *__restrict__ const pData = pWrkrData->pData; fd_set wrds; struct timeval tv; int ready; CODESTARTtryResume; if (pData->fd == -1) { rsRetVal iRetLocal; iRetLocal = preparePipe(pData); if ((iRetLocal != RS_RET_OK) || (pData->fd == -1)) ABORT_FINALIZE(RS_RET_SUSPENDED); } else { /* we can reach this if the pipe is full, so we need * to check if we can write again. /dev/xconsole is the * ugly example of why this is necessary. */ FD_ZERO(&wrds); FD_SET(pData->fd, &wrds); tv.tv_sec = 0; tv.tv_usec = 0; ready = select(pData->fd + 1, NULL, &wrds, NULL, &tv); DBGPRINTF("ompipe: tryResume: ready to write fd %d: %d\n", pData->fd, ready); if (ready != 1) { if (pData->bTryResumeReopen && pData->fd != -1) { close(pData->fd); pData->fd = -1; } ABORT_FINALIZE(RS_RET_SUSPENDED); } } finalize_it: ENDtryResume BEGINdoAction instanceData *pData; CODESTARTdoAction; pData = pWrkrData->pData; DBGPRINTF("ompipe: writing to %s\n", pData->pipe); /* this module is single-threaded by nature */ pthread_mutex_lock(&pData->mutWrite); iRet = writePipe(ppString, pData); pthread_mutex_unlock(&pData->mutWrite); ENDdoAction static inline void setInstParamDefaults(instanceData *pData) { pData->tplName = NULL; } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); CODE_STD_STRING_REQUESTnewActInst(1); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "pipe")) { pData->pipe = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "tryResumeReopen")) { pData->bTryResumeReopen = (int)pvals[i].val.d.n; } else { dbgprintf( "ompipe: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)strdup((pData->tplName == NULL) ? "RSYSLOG_FileFormat" : (char *)pData->tplName), OMSR_NO_RQD_TPL_OPTS)); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINparseSelectorAct CODESTARTparseSelectorAct; /* yes, the if below is redundant, but I need it now. Will go away as * the code further changes. -- rgerhards, 2007-07-25 */ if (*p == '|') { if ((iRet = createInstance(&pData)) != RS_RET_OK) { return iRet; /* this can not use RET_iRet! */ } } else { /* this is not clean, but we need it for the time being * TODO: remove when cleaning up modularization */ return RS_RET_CONFLINE_UNPROCESSED; } CODE_STD_STRING_REQUESTparseSelectorAct(1) CHKmalloc(pData->pipe = malloc(512)); ++p; CHKiRet(cflineParseFileName(p, (uchar *)pData->pipe, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINdoHUP CODESTARTdoHUP; pthread_mutex_lock(&pData->mutWrite); if (pData->fd != -1) { close(pData->fd); pData->fd = -1; } pthread_mutex_unlock(&pData->mutWrite); ENDdoHUP BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_doHUP CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(Pipe) CODESTARTmodInit; INITLegCnfVars; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr ENDmodInit /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/smfile.h0000644000000000000000000000013215055605325015327 xustar0030 mtime=1756826325.661800864 30 atime=1764930982.719723353 30 ctime=1764935924.165591615 rsyslog-8.2512.0/tools/smfile.h0000664000175000017500000000235115055605325014774 0ustar00rgerrger/* smfile.h * These are the definitions for the traditional file format stringen module. * * File begun on 2010-06-04 by RGerhards * * Copyright 2010-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SMFILE_H_INCLUDED #define SMFILE_H_INCLUDED 1 /* prototypes */ rsRetVal modInitsmfile(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef SMFILE_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/pmrfc3164.c0000644000000000000000000000013215062756615015477 xustar0030 mtime=1758190989.242641701 30 atime=1764931033.915573407 30 ctime=1764935924.153591431 rsyslog-8.2512.0/tools/pmrfc3164.c0000664000175000017500000005456515062756615015162 0ustar00rgerrger/* pmrfc3164.c * This is a parser module for RFC3164(legacy syslog)-formatted messages. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2009-11-04 by RGerhards * * Copyright 2007-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" #include "ruleset.h" #include "rsconf.h" #include "atomic.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.rfc3164") MODULE_CNFNAME("pmrfc3164") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl); DEFobjCurrIf(parser); DEFobjCurrIf(datetime); DEFobjCurrIf(ruleset); /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ /* parser instance parameters */ static struct cnfparamdescr parserpdescr[] = { {"detect.yearaftertimestamp", eCmdHdlrBinary, 0}, {"permit.squarebracketsinhostname", eCmdHdlrBinary, 0}, {"permit.slashesinhostname", eCmdHdlrBinary, 0}, {"permit.atsignsinhostname", eCmdHdlrBinary, 0}, {"force.tagendingbycolon", eCmdHdlrBinary, 0}, {"remove.msgfirstspace", eCmdHdlrBinary, 0}, {"detect.headerless", eCmdHdlrBinary, 0}, {"headerless.hostname", eCmdHdlrString, 0}, {"headerless.tag", eCmdHdlrString, 0}, {"headerless.ruleset", eCmdHdlrString, 0}, {"headerless.errorfile", eCmdHdlrString, 0}, {"headerless.drop", eCmdHdlrBinary, 0}, }; static struct cnfparamblk parserpblk = {CNFPARAMBLK_VERSION, sizeof(parserpdescr) / sizeof(struct cnfparamdescr), parserpdescr}; struct instanceConf_s { int bDetectYearAfterTimestamp; int bPermitSquareBracketsInHostname; int bPermitSlashesInHostname; int bPermitAtSignsInHostname; int bForceTagEndingByColon; int bRemoveMsgFirstSpace; int bHdrLessMode; /** < is headerless mode activated? 0 - no, other - yes */ uchar* pszHeaderlessHostname; /** < HOSTNAME to use for headerless messages */ uchar* pszHeaderlessTag; /** < TAG to use for headerless messages */ uchar* pszHeaderlessRulesetName; /** < name of Ruleset to use for headerless messages */ ruleset_t* pHeaderlessRuleset; /**< Ruleset to use for headerless messages */ DEF_ATOMIC_HELPER_MUT(mutHeaderlessRuleset); /**< mutex for atomic operations on pHeaderlessRuleset */ uchar* pszHeaderlessErrFile; /**< name of error file for headerless messages */ FILE* fpHeaderlessErr; /**< file pointer for error file (headerless) */ pthread_mutex_t mutErrFile; int bDropHeaderless; }; BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature /* create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal createInstance(instanceConf_t** pinst) { instanceConf_t* inst; DEFiRet; CHKmalloc(inst = malloc(sizeof(instanceConf_t))); inst->bDetectYearAfterTimestamp = 0; inst->bPermitSquareBracketsInHostname = 0; inst->bPermitSlashesInHostname = 0; inst->bPermitAtSignsInHostname = 0; inst->bForceTagEndingByColon = 0; inst->bRemoveMsgFirstSpace = 0; inst->bHdrLessMode = 0; inst->pszHeaderlessHostname = NULL; inst->pszHeaderlessTag = NULL; inst->pszHeaderlessRulesetName = NULL; inst->pHeaderlessRuleset = NULL; INIT_ATOMIC_HELPER_MUT(inst->mutHeaderlessRuleset); inst->pszHeaderlessErrFile = NULL; inst->fpHeaderlessErr = NULL; pthread_mutex_init(&inst->mutErrFile, NULL); inst->bDropHeaderless = 0; bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); *pinst = inst; finalize_it: RETiRet; } BEGINnewParserInst struct cnfparamvals* pvals = NULL; int i; CODESTARTnewParserInst; DBGPRINTF("newParserInst (pmrfc3164)\n"); inst = NULL; CHKiRet(createInstance(&inst)); if (lst == NULL) FINALIZE; /* just set defaults, no param block! */ if ((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("parser param blk in pmrfc3164:\n"); cnfparamsPrint(&parserpblk, pvals); } for (i = 0; i < parserpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(parserpblk.descr[i].name, "detect.yearaftertimestamp")) { inst->bDetectYearAfterTimestamp = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "permit.squarebracketsinhostname")) { inst->bPermitSquareBracketsInHostname = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "permit.slashesinhostname")) { inst->bPermitSlashesInHostname = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "permit.atsignsinhostname")) { inst->bPermitAtSignsInHostname = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "force.tagendingbycolon")) { inst->bForceTagEndingByColon = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "remove.msgfirstspace")) { inst->bRemoveMsgFirstSpace = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "detect.headerless")) { inst->bHdrLessMode = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "headerless.hostname")) { inst->pszHeaderlessHostname = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(parserpblk.descr[i].name, "headerless.tag")) { inst->pszHeaderlessTag = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(parserpblk.descr[i].name, "headerless.ruleset")) { inst->pszHeaderlessRulesetName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(parserpblk.descr[i].name, "headerless.errorfile")) { inst->pszHeaderlessErrFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(parserpblk.descr[i].name, "headerless.drop")) { inst->bDropHeaderless = (int)pvals[i].val.d.n; } else { dbgprintf( "pmrfc3164: program error, non-handled " "param '%s'\n", parserpblk.descr[i].name); } } finalize_it: CODE_STD_FINALIZERnewParserInst if (lst != NULL) cnfparamvalsDestruct(pvals, &parserpblk); if (iRet != RS_RET_OK) free(inst); ENDnewParserInst BEGINfreeParserInst CODESTARTfreeParserInst; free(pInst->pszHeaderlessHostname); free(pInst->pszHeaderlessTag); free(pInst->pszHeaderlessRulesetName); free(pInst->pszHeaderlessErrFile); if (pInst->fpHeaderlessErr != NULL) fclose(pInst->fpHeaderlessErr); pthread_mutex_destroy(&pInst->mutErrFile); DESTROY_ATOMIC_HELPER_MUT(pInst->mutHeaderlessRuleset); dbgprintf("pmrfc3164: free parser instance %p\n", pInst); ENDfreeParserInst BEGINcheckParserInst CODESTARTcheckParserInst; if (pInst->pszHeaderlessRulesetName != NULL) { ruleset_t* myRuleset = NULL; rsRetVal localRet = ruleset.GetRuleset(loadConf, &myRuleset, pInst->pszHeaderlessRulesetName); if (localRet == RS_RET_OK && myRuleset != NULL) { pInst->pHeaderlessRuleset = myRuleset; } else { LogError(0, localRet, "pmrfc3164: ruleset '%s' not found, cannot route headerless messages, " "not assigning any ruleset to these messages.", pInst->pszHeaderlessRulesetName); } } ENDcheckParserInst BEGINdoHUPParser CODESTARTdoHUPParser; instanceConf_t* pInst = (instanceConf_t*)pData; /* Close and reopen error file on HUP signal to support log rotation */ if (pInst->pszHeaderlessErrFile != NULL) { pthread_mutex_lock(&pInst->mutErrFile); if (pInst->fpHeaderlessErr != NULL) { fclose(pInst->fpHeaderlessErr); pInst->fpHeaderlessErr = NULL; DBGPRINTF("pmrfc3164: closed error file %s on HUP\n", pInst->pszHeaderlessErrFile); } /* File will be reopened on next write attempt in handleHeaderlessMessage() */ pthread_mutex_unlock(&pInst->mutErrFile); } ENDdoHUPParser /** Handle a headerless message by setting defaults and marking the object */ static ATTR_NONNULL() rsRetVal handleHeaderlessMessage(smsg_t* pMsg, instanceConf_t* const pInst, uchar* p2parse) { DEFiRet; uchar* hostname = pInst->pszHeaderlessHostname ? pInst->pszHeaderlessHostname : getRcvFrom(pMsg); if (hostname == NULL) hostname = (uchar*)"unknown"; MsgSetHOSTNAME(pMsg, hostname, strlen((char*)hostname)); uchar* tag = pInst->pszHeaderlessTag ? pInst->pszHeaderlessTag : (uchar*)"headerless"; MsgSetTAG(pMsg, tag, strlen((char*)tag)); MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); if (pInst->pHeaderlessRuleset != NULL) MsgSetRuleset(pMsg, pInst->pHeaderlessRuleset); if (pInst->pszHeaderlessErrFile != NULL) { pthread_mutex_lock(&pInst->mutErrFile); if (pInst->fpHeaderlessErr == NULL) { pInst->fpHeaderlessErr = fopen((char*)pInst->pszHeaderlessErrFile, "a"); if (pInst->fpHeaderlessErr == NULL) { LogError(errno, RS_RET_ERR, "pmrfc3164: cannot open error file %s", pInst->pszHeaderlessErrFile); } } if (pInst->fpHeaderlessErr != NULL) { /* Write the raw message followed by a newline */ if (fwrite(pMsg->pszRawMsg, 1, pMsg->iLenRawMsg, pInst->fpHeaderlessErr) != (size_t)pMsg->iLenRawMsg || fputc('\n', pInst->fpHeaderlessErr) == EOF) { LogError(errno, RS_RET_IO_ERROR, "pmrfc3164: error writing to error file %s", pInst->pszHeaderlessErrFile); fclose(pInst->fpHeaderlessErr); pInst->fpHeaderlessErr = NULL; } } pthread_mutex_unlock(&pInst->mutErrFile); } DBGPRINTF("pmrfc3164: headerless message handled with hostname='%s', tag='%s'\n", hostname, tag); if (pInst->bDropHeaderless) ABORT_FINALIZE(RS_RET_DISCARDMSG); finalize_it: RETiRet; } /* parse a legay-formatted syslog message. * We apply heuristics during header detection. These are not 100% failure * prove, but the best compromise we came up within 20+ years of adapting * the heuristics. */ BEGINparse2 uchar* p2parse; int lenMsg; int i; /* general index for parsing */ uchar bufParseTAG[CONF_TAG_MAXSIZE]; uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE]; CODESTARTparse; assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; DBGPRINTF("Message will now be parsed by the legacy syslog parser (offAfterPRI=%d, lenMsg=%d.\n", pMsg->offAfterPRI, lenMsg); /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ setProtocolVersion(pMsg, MSG_LEGACY_PROTOCOL); if (pMsg->iFacility == (LOG_INVLD >> 3)) { DBGPRINTF("facility LOG_INVLD, do not parse\n"); FINALIZE; } /* now check if we have a completely headerless message. This is always the * case if it starts with spaces or tabs followed '{' or '['. * Note that this is from the grown heuristics and not controlled by the * headerless options. // TODO: make transparent in conf? */ i = 0; while (i < lenMsg && (p2parse[i] == ' ' || p2parse[i] == '\t')) { ++i; } if (i < lenMsg && (p2parse[i] == '{' || p2parse[i] == '[')) { DBGPRINTF("msg seems to be headerless, treating it as such\n"); FINALIZE; } /* Check to see if msg contains a timestamp. We start by assuming * that the message timestamp is the time of reception (which we * generated ourselfs and then try to actually find one inside the * message. There we go from high-to low precison and are done * when we find a matching one. -- rgerhards, 2008-09-16 */ int bFoundTimestamp = 0; /**< indicates if we found a timestamp or not */ if (datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { bFoundTimestamp = 1; /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; } else if (datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg, NO_PARSE3164_TZSTRING, pInst->bDetectYearAfterTimestamp) == RS_RET_OK) { if (pMsg->dfltTZ[0] != '\0') applyDfltTZ(&pMsg->tTIMESTAMP, pMsg->dfltTZ); bFoundTimestamp = 1; /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; } else if (*p2parse == ' ' && lenMsg > 1) { /* try to see if it is slightly malformed - HP procurve seems to do that sometimes */ ++p2parse; /* move over space */ --lenMsg; if (datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg, NO_PARSE3164_TZSTRING, pInst->bDetectYearAfterTimestamp) == RS_RET_OK) { /* indeed, we got it! */ bFoundTimestamp = 1; /* we are done - parse pointer is moved by ParseTIMESTAMP3164 */; } else { /* parse pointer needs to be restored, as we moved it off-by-one * for this try. */ --p2parse; ++lenMsg; } } if (pInst->bHdrLessMode != 0 && bFoundTimestamp == 0) { /* we do not have a valid timestamp in any of the formats we support * This is a strong indication that the message is headerless. So let's * process it according to headerless rules. */ DBGPRINTF("msg seems to be headerless (no PRI, no timestamp), treating it as such\n"); CHKiRet(handleHeaderlessMessage(pMsg, pInst, p2parse)); } if (pMsg->msgFlags & IGNDATE) { /* we need to ignore the msg data, so simply copy over reception date */ memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); } /* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we * do this only when the user has not forbidden this. I now introduce some * code that allows a user to configure rsyslogd to treat the rest of the * message as MSG part completely. In this case, the hostname will be the * machine that we received the message from and the tag will be empty. This * is meant to be an interim solution, but for now it is in the code. */ if (bParseHOSTNAMEandTAG && !(pMsg->msgFlags & INTERNAL_MSG)) { /* parse HOSTNAME - but only if this is network-received! * rger, 2005-11-14: we still have a problem with BSD messages. These messages * do NOT include a host name. In most cases, this leads to the TAG to be treated * as hostname and the first word of the message as the TAG. Clearly, this is not * of advantage ;) I think I have now found a way to handle this situation: there * are certain characters which are frequently used in TAG (e.g. ':'), which are * *invalid* in host names. So while parsing the hostname, I check for these characters. * If I find them, I set a simple flag but continue. After parsing, I check the flag. * If it was set, then we most probably do not have a hostname but a TAG. Thus, I change * the fields. I think this logic shall work with any type of syslog message. * rgerhards, 2009-06-23: and I now have extended this logic to every character * that is not a valid hostname. * A "hostname" can validly include "[]" at the beginning and end. This sometimes * happens with IP address (e.g. "[192.168.0.1]"). This must be turned on via * an option as it may interfere with non-hostnames in some message formats. * rgerhards, 2015-04-20 */ if (lenMsg > 0 && pMsg->msgFlags & PARSE_HOSTNAME) { i = 0; int bHadSBracket = 0; if (pInst->bPermitSquareBracketsInHostname) { assert(i < lenMsg); if (p2parse[i] == '[') { bHadSBracket = 1; bufParseHOSTNAME[0] = '['; ++i; } } while (i < lenMsg && (isalnum(p2parse[i]) || p2parse[i] == '.' || p2parse[i] == '_' || p2parse[i] == '-' || (p2parse[i] == ']' && bHadSBracket) || (p2parse[i] == '@' && pInst->bPermitAtSignsInHostname) || (p2parse[i] == '/' && pInst->bPermitSlashesInHostname)) && i < (CONF_HOSTNAME_MAXSIZE - 1)) { bufParseHOSTNAME[i] = p2parse[i]; ++i; if (p2parse[i] == ']') break; /* must be closing bracket */ } if (i == lenMsg) { /* we have a message that is empty immediately after the hostname, * but the hostname thus is valid! -- rgerhards, 2010-02-22 */ p2parse += i; lenMsg -= i; bufParseHOSTNAME[i] = '\0'; MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); } else { int isHostName = 0; if (i > 0) { if (bHadSBracket) { if (p2parse[i] == ']') { bufParseHOSTNAME[i] = ']'; ++i; isHostName = 1; } } else { if (isalnum(p2parse[i - 1])) { isHostName = 1; } } if (p2parse[i] != ' ') isHostName = 0; } if (isHostName) { /* we got a hostname! */ p2parse += i + 1; /* "eat" it (including SP delimiter) */ lenMsg -= i + 1; bufParseHOSTNAME[i] = '\0'; MsgSetHOSTNAME(pMsg, bufParseHOSTNAME, i); } } } /* now parse TAG - that should be present in message from all sources. * This code is somewhat not compliant with RFC 3164. As of 3164, * the TAG field is ended by any non-alphanumeric character. In * practice, however, the TAG often contains dashes and other things, * which would end the TAG. So it is not desirable. As such, we only * accept colon and SP to be terminators. Even there is a slight difference: * a colon is PART of the TAG, while a SP is NOT part of the tag * (it is CONTENT). Starting 2008-04-04, we have removed the 32 character * size limit (from RFC3164) on the tag. This had bad effects on existing * environments, as sysklogd didn't obey it either (probably another bug * in RFC3164...). We now receive the full size, but will modify the * outputs so that only 32 characters max are used by default. */ i = 0; while (lenMsg > 0 && *p2parse != ':' && *p2parse != ' ' && i < CONF_TAG_MAXSIZE - 2) { bufParseTAG[i++] = *p2parse++; --lenMsg; } if (lenMsg > 0 && *p2parse == ':') { ++p2parse; --lenMsg; bufParseTAG[i++] = ':'; } else if (pInst->bForceTagEndingByColon) { /* Tag need to be ended by a colon or it's not a tag but the * begin of the message */ p2parse -= (i + 1); lenMsg += (i + 1); i = 0; /* Default TAG is dash (without ':') */ bufParseTAG[i++] = '-'; } /* no TAG can only be detected if the message immediately ends, in which case an empty TAG * is considered OK. So we do not need to check for empty TAG. -- rgerhards, 2009-06-23 */ bufParseTAG[i] = '\0'; /* terminate string */ MsgSetTAG(pMsg, bufParseTAG, i); } else { /* we enter this code area when the user has instructed rsyslog NOT * to parse HOSTNAME and TAG - rgerhards, 2006-03-13 */ if (!(pMsg->msgFlags & INTERNAL_MSG)) { DBGPRINTF("HOSTNAME and TAG not parsed by user configuration.\n"); } } finalize_it: if (pInst->bRemoveMsgFirstSpace && *p2parse == ' ') { /* Bypass first space found in MSG part */ p2parse++; lenMsg--; } MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); ENDparse2 BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD2_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; CODEqueryEtryPt_doHUPParser; ENDqueryEtryPt BEGINmodInit(pmrfc3164) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); DBGPRINTF("rfc3164 parser init called\n"); /* cache value, is set only during rsyslogd option processing */ bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/omshell.c0000644000000000000000000000013115055605325015505 xustar0030 mtime=1756826325.660800849 30 atime=1764931031.676536459 29 ctime=1764935924.11959091 rsyslog-8.2512.0/tools/omshell.c0000664000175000017500000001024615055605325015155 0ustar00rgerrger/* omshell.c * This is the implementation of the build-in shell output module. * * ************* DO NOT EXTEND THIS MODULE ************** * This is pure legacy, omprog has much better and more * secure functionality than this module. It is NOT * recommended to base new work on it! * 2012-01-19 rgerhards * ****************************************************** * * NOTE: read comments in module-template.h to understand how this file * works! * * shell support was initially written by bkalkbrenner 2005-09-20 * * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c) * This file is under development and has not yet arrived at being fully * self-contained and a real object. So far, it is mostly an excerpt * of the "old" message code without any modifications. However, it * helps to have things at the right place one we go to the meat of it. * * Copyright 2007-2016 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "omshell.h" #include "module-template.h" #include "errmsg.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; /* internal structures */ DEF_OMOD_STATIC_DATA; typedef struct _instanceData { uchar progName[MAXFNAME]; /* program to execute */ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; printf("%s", pData->progName); ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINdoAction CODESTARTdoAction; dbgprintf("\n"); if (execProg((uchar *)pWrkrData->pData->progName, 1, ppString[0]) == 0) LogError(0, NO_ERRCODE, "Executing program '%s' failed", (char *)pWrkrData->pData->progName); ENDdoAction BEGINparseSelectorAct CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) /* yes, the if below is redundant, but I need it now. Will go away as * the code further changes. -- rgerhards, 2007-07-25 */ if (*p == '^') { if ((iRet = createInstance(&pData)) != RS_RET_OK) goto finalize_it; } switch (*p) { case '^': /* bkalkbrenner 2005-09-20: execute shell command */ dbgprintf("exec\n"); ++p; iRet = cflineParseFileName(p, (uchar *)pData->progName, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar *)"RSYSLOG_TraditionalFileFormat"); break; default: iRet = RS_RET_CONFLINE_UNPROCESSED; break; } CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; ENDqueryEtryPt BEGINmodInit(Shell) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr ENDmodInit /* * vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/omfile.c0000644000000000000000000000013215071746523015322 xustar0030 mtime=1760021843.914422185 30 atime=1764931032.702553393 30 ctime=1764935924.133591125 rsyslog-8.2512.0/tools/omfile.c0000664000175000017500000021765415071746523015005 0ustar00rgerrger/* omfile.c * This is the implementation of the build-in file output module. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2007-07-21 by RGerhards (extracted from syslogd.c, which * at the time of the fork from sysklogd was under BSD license) * * A large re-write of this file was done in June, 2009. The focus was * to introduce many more features (like zipped writing), clean up the code * and make it more reliable. In short, that rewrite tries to provide a new * solid basis for the next three to five years to come. During it, bugs * may have been introduced ;) -- rgerhards, 2009-06-04 * * Note that as of 2010-02-28 this module does no longer handle * pipes. These have been moved to ompipe, to reduced the entanglement * between the two different functionalities. -- rgerhards * * Copyright 2007-2024 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ATOMIC_BUILTINS #include #endif #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "outchannel.h" #include "omfile.h" #include "cfsysline.h" #include "module-template.h" #include "errmsg.h" #include "stream.h" #include "unicode-helper.h" #include "atomic.h" #include "statsobj.h" #include "sigprov.h" #include "cryprov.h" #include "parserif.h" #include "janitor.h" #include "rsconf.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omfile") /* forward definitions */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal); /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(strm) DEFobjCurrIf(statsobj) /** * @brief Global counter/clock for file access timestamping. * * This counter is used as a "Lamport logical clock" for the LRU mechanism * of the dynamic file cache. It provides a monotonically increasing sequence * number to track the access order of files, rather than actual time. * It is highly unlikely to wrap within the lifetime of a process. */ #ifdef HAVE_ATOMIC_BUILTINS64 static uint64 clockFileAccess = 0; #else static unsigned clockFileAccess = 0; #endif /** * @brief Mutex for protecting clockFileAccess in non-atomic builtins environments. */ #ifndef HAVE_ATOMIC_BUILTINS static pthread_mutex_t mutClock; #endif /** * @brief Retrieves and increments the global file access clock. * * This function provides a monotonically increasing counter used for the LRU * mechanism in the dynamic file cache. It is thread-safe. * * @return The incremented value of the file access clock. */ static uint64 getClockFileAccess(void) { #ifdef HAVE_ATOMIC_BUILTINS64 return ATOMIC_INC_AND_FETCH_uint64(&clockFileAccess, &mutClock); #else return ATOMIC_INC_AND_FETCH_unsigned(&clockFileAccess, &mutClock); #endif } /** * @brief Structure for a dynamic file name cache entry. * * This structure holds information about a dynamically opened file, * including its name, the associated stream, signature provider data, * and access timestamp for LRU management. */ struct s_dynaFileCacheEntry { uchar *pName; /**< name currently open, if dynamic name */ strm_t *pStrm; /**< our output stream */ void *sigprovFileData; /**< opaque data ptr for provider use */ uint64 clkTickAccessed; /**< for LRU - based on clockFileAccess */ short nInactive; /**< number of minutes not writen - for close timeout */ }; typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; #define IOBUF_DFLT_SIZE 4096 /**< default size for io buffers */ #define FLUSH_INTRVL_DFLT 1 /**< default buffer flush interval (in seconds) */ #define USE_ASYNCWRITER_DFLT 0 /**< default buffer use async writer */ #define FLUSHONTX_DFLT 1 /**< default for flush on TX end */ #define ADDLF_SIGBUF_STACKLEN 1024 /**< stack buffer size for addLF signing helper */ /** * @brief Instance data for the omfile module. * * This structure holds the configuration and runtime state for each * file output action. */ typedef struct _instanceData { pthread_mutex_t mutWrite; /**< guard against multiple instances writing to single file */ uchar *fname; /**< file or template name (display only) */ uchar *tplName; /**< name of assigned template */ strm_t *pStrm; /**< our output stream */ short nInactive; /**< number of minutes not writen (STATIC files only) */ char bDynamicName; /**< 0 - static name, 1 - dynamic name (with properties) */ int isDevNull; /**< do we "write" to /dev/null? - if so, do nothing */ int fCreateMode; /**< file creation mode for open() */ int fDirCreateMode; /**< creation mode for mkdir() */ int bCreateDirs; /**< auto-create directories? */ int bSyncFile; /**< should the file by sync()'ed? 1- yes, 0- no */ uint8_t iNumTpls; /**< number of tpls we use */ uid_t fileUID; /**< IDs for creation */ uid_t dirUID; gid_t fileGID; gid_t dirGID; int bFailOnChown; /**< fail creation if chown fails? */ uchar *sigprovName; /**< signature provider */ uchar *sigprovNameFull; /**< full internal signature provider name */ sigprov_if_t sigprov; /**< ptr to signature provider interface */ void *sigprovData; /**< opaque data ptr for provider use */ void *sigprovFileData; /**< opaque data ptr for file instance */ sbool useSigprov; /**< quicker than checkig ptr (1 vs 8 bytes!) */ uchar *cryprovName; /**< crypto provider */ uchar *cryprovNameFull; /**< full internal crypto provider name */ void *cryprovData; /**< opaque data ptr for provider use */ cryprov_if_t cryprov; /**< ptr to crypto provider interface */ sbool useCryprov; /**< quicker than checkig ptr (1 vs 8 bytes!) */ int iCurrElt; /**< currently active cache element (-1 = none) */ int iCurrCacheSize; /**< currently cache size (1-based) */ int iDynaFileCacheSize; /**< size of file handle cache */ /** * The cache is implemented as an array. An empty element is indicated * by a NULL pointer. Memory is allocated as needed. The following * pointer points to the overall structure. */ dynaFileCacheEntry **dynCache; off_t iSizeLimit; /**< file size limit, 0 = no limit */ uchar *pszSizeLimitCmd; /**< command to carry out when size limit is reached */ int iZipLevel; /**< zip mode to use for this selector */ int iIOBufSize; /**< size of associated io buffer */ int iFlushInterval; /**< how fast flush buffer on inactivity? */ short iCloseTimeout; /**< after how many *minutes* shall the file be closed if inactive? */ sbool bFlushOnTXEnd; /**< flush write buffers when transaction has ended? */ sbool bUseAsyncWriter; /**< use async stream writer? */ sbool bVeryRobustZip; sbool bAddLF; /**< append LF to records that are missing it? */ statsobj_t *stats; /**< dynafile, primarily cache stats */ STATSCOUNTER_DEF(ctrRequests, mutCtrRequests); STATSCOUNTER_DEF(ctrLevel0, mutCtrLevel0); STATSCOUNTER_DEF(ctrEvict, mutCtrEvict); STATSCOUNTER_DEF(ctrMiss, mutCtrMiss); STATSCOUNTER_DEF(ctrMax, mutCtrMax); STATSCOUNTER_DEF(ctrCloseTimeouts, mutCtrCloseTimeouts); char janitorID[128]; /**< holds ID for janitor calls */ } instanceData; /** * @brief Worker instance data for the omfile module. * * This structure holds a pointer to the main instance data for use * by worker threads. */ typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; /** * @brief Module-global configuration settings. * * This structure holds the configuration settings that apply globally * to the omfile module. */ typedef struct configSettings_s { int iDynaFileCacheSize; /**< max cache for dynamic files */ int fCreateMode; /**< mode to use when creating files */ int fDirCreateMode; /**< mode to use when creating files */ int bFailOnChown; /**< fail if chown fails? */ uid_t fileUID; /**< UID to be used for newly created files */ uid_t fileGID; /**< GID to be used for newly created files */ uid_t dirUID; /**< UID to be used for newly created directories */ uid_t dirGID; /**< GID to be used for newly created directories */ int bCreateDirs; /**< auto-create directories for dynaFiles: 0 - no, 1 - yes */ int bEnableSync; /**< enable syncing of files (no dash in front of pathname in conf): 0 - no, 1 - yes */ int iZipLevel; /**< zip compression mode (0..9 as usual) */ sbool bFlushOnTXEnd; /**< flush write buffers when transaction has ended? */ int64 iIOBufSize; /**< size of an io buffer */ int iFlushInterval; /**< how often flush the output buffer on inactivity? */ int bUseAsyncWriter; /**< should we enable asynchronous writing? */ sbool bAddLF; /**< append LF to records that are missing it? */ EMPTY_STRUCT } configSettings_t; static configSettings_t cs; uchar *pszFileDfltTplName; /**< name of the default template to use */ /** * @brief Module configuration data for the v6 config system. */ struct modConfData_s { rsconf_t *pConf; /**< our overall config object */ uchar *tplName; /**< default template */ int fCreateMode; /**< default mode to use when creating files */ int fDirCreateMode; /**< default mode to use when creating files */ uid_t fileUID; /**< default IDs for creation */ uid_t dirUID; gid_t fileGID; gid_t dirGID; int bDynafileDoNotSuspend; strm_compressionDriver_t compressionDriver; int compressionDriver_workers; sbool bAddLF; /**< default setting for addLF action parameter */ }; static modConfData_t *loadModConf = NULL; /**< modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /**< modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"template", eCmdHdlrGetWord, 0}, {"addlf", eCmdHdlrBinary, 0}, {"compression.driver", eCmdHdlrGetWord, 0}, {"compression.zstd.workers", eCmdHdlrPositiveInt, 0}, {"dircreatemode", eCmdHdlrFileCreateMode, 0}, {"filecreatemode", eCmdHdlrFileCreateMode, 0}, {"dirowner", eCmdHdlrUID, 0}, {"dirownernum", eCmdHdlrInt, 0}, {"dirgroup", eCmdHdlrGID, 0}, {"dirgroupnum", eCmdHdlrInt, 0}, {"fileowner", eCmdHdlrUID, 0}, {"fileownernum", eCmdHdlrInt, 0}, {"filegroup", eCmdHdlrGID, 0}, {"dynafile.donotsuspend", eCmdHdlrBinary, 0}, {"filegroupnum", eCmdHdlrInt, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"dynafilecachesize", eCmdHdlrInt, 0}, /* legacy: dynafilecachesize */ {"ziplevel", eCmdHdlrInt, 0}, /* legacy: omfileziplevel */ {"flushinterval", eCmdHdlrInt, 0}, /* legacy: omfileflushinterval */ {"asyncwriting", eCmdHdlrBinary, 0}, /* legacy: omfileasyncwriting */ {"veryrobustzip", eCmdHdlrBinary, 0}, {"flushontxend", eCmdHdlrBinary, 0}, /* legacy: omfileflushontxend */ {"iobuffersize", eCmdHdlrSize, 0}, /* legacy: omfileiobuffersize */ {"dirowner", eCmdHdlrUID, 0}, /* legacy: dirowner */ {"dirownernum", eCmdHdlrInt, 0}, /* legacy: dirownernum */ {"dirgroup", eCmdHdlrGID, 0}, /* legacy: dirgroup */ {"dirgroupnum", eCmdHdlrInt, 0}, /* legacy: dirgroupnum */ {"fileowner", eCmdHdlrUID, 0}, /* legacy: fileowner */ {"fileownernum", eCmdHdlrInt, 0}, /* legacy: fileownernum */ {"filegroup", eCmdHdlrGID, 0}, /* legacy: filegroup */ {"filegroupnum", eCmdHdlrInt, 0}, /* legacy: filegroupnum */ {"dircreatemode", eCmdHdlrFileCreateMode, 0}, /* legacy: dircreatemode */ {"filecreatemode", eCmdHdlrFileCreateMode, 0}, /* legacy: filecreatemode */ {"failonchownfailure", eCmdHdlrBinary, 0}, /* legacy: failonchownfailure */ {"createdirs", eCmdHdlrBinary, 0}, /* legacy: createdirs */ {"sync", eCmdHdlrBinary, 0}, /* legacy: actionfileenablesync */ {"file", eCmdHdlrString, 0}, /* either "file" or ... */ {"dynafile", eCmdHdlrString, 0}, /* "dynafile" MUST be present */ {"sig.provider", eCmdHdlrGetWord, 0}, {"cry.provider", eCmdHdlrGetWord, 0}, {"closetimeout", eCmdHdlrPositiveInt, 0}, {"rotation.sizelimit", eCmdHdlrSize, 0}, {"rotation.sizelimitcommand", eCmdHdlrString, 0}, {"template", eCmdHdlrGetWord, 0}, {"addlf", eCmdHdlrBinary, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /** * @brief Gets the default template name to be used. * * This function coordinates the default template name between old-style * and new-style configuration parts. * * @return A pointer to the default template name string. */ static uchar *getDfltTpl(void) { if (loadModConf != NULL && loadModConf->tplName != NULL) return loadModConf->tplName; else if (pszFileDfltTplName == NULL) return (uchar *)"RSYSLOG_FileFormat"; else return pszFileDfltTplName; } BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars; pszFileDfltTplName = NULL; /* make sure this can be free'ed! */ iRet = resetConfigVariables(NULL, NULL); /* params are dummies */ ENDinitConfVars BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; if (pData->bDynamicName) { dbgprintf("[dynamic]\n"); } else { /* regular file */ dbgprintf("%s%s\n", pData->fname, (pData->pStrm == NULL) ? " (closed)" : ""); } dbgprintf("\ttemplate='%s'\n", pData->fname); dbgprintf("\tuse async writer=%d\n", pData->bUseAsyncWriter); dbgprintf("\tflush on TX end=%d\n", pData->bFlushOnTXEnd); dbgprintf("\tflush interval=%d\n", pData->iFlushInterval); dbgprintf("\tappend LF=%d\n", pData->bAddLF); dbgprintf("\tfile cache size=%d\n", pData->iDynaFileCacheSize); dbgprintf("\tcreate directories: %s\n", pData->bCreateDirs ? "on" : "off"); dbgprintf("\tvery robust zip: %s\n", pData->bCreateDirs ? "on" : "off"); dbgprintf("\tfile owner %d, group %d\n", (int)pData->fileUID, (int)pData->fileGID); dbgprintf("\tdirectory owner %d, group %d\n", (int)pData->dirUID, (int)pData->dirGID); dbgprintf("\tdir create mode 0%3.3o, file create mode 0%3.3o\n", pData->fDirCreateMode, pData->fCreateMode); dbgprintf("\tfail if owner/group can not be set: %s\n", pData->bFailOnChown ? "yes" : "no"); ENDdbgPrintInstInfo /** * @brief Sets the default template to be used for output files (legacy method). * * This is a module-global parameter and needs special handling to coordinate * with values set via the v2 config system (rsyslog v6+). This directive is * not permitted after the v2 config system has been used to set the parameter. * * @param pVal Unused pointer, kept for compatibility with command handler signature. * @param newVal The new default template name. Ownership is transferred to this function. * @return RS_RET_OK on success, RS_RET_ERR if already set by new config system. */ static rsRetVal setLegacyDfltTpl(void __attribute__((unused)) * pVal, uchar *newVal) { DEFiRet; if (loadModConf != NULL && loadModConf->tplName != NULL) { free(newVal); parser_errmsg( "omfile: default template already set via module " "global parameter - can no longer be changed"); ABORT_FINALIZE(RS_RET_ERR); } free(pszFileDfltTplName); pszFileDfltTplName = newVal; finalize_it: RETiRet; } /** * @brief Sets the dynamic file cache size. * * Performs limit checking to ensure the new value is valid and logs warnings * for unusually large values. * * @param pVal Unused pointer, kept for compatibility with command handler signature. * @param iNewVal The new size for the dynamic file cache. * @return RS_RET_OK on success, RS_RET_VAL_OUT_OF_RANGE if the value was invalid * (the value will be adjusted to a valid range in this case). */ static rsRetVal setDynaFileCacheSize(void __attribute__((unused)) * pVal, int iNewVal) { DEFiRet; if (iNewVal < 1) { errno = 0; parser_errmsg("DynaFileCacheSize must be greater 0 (%d given), changed to 1.", iNewVal); iRet = RS_RET_VAL_OUT_OF_RANGE; iNewVal = 1; } else if (iNewVal > 25000) { errno = 0; parser_warnmsg( "DynaFileCacheSize is larger than 25,000 (%d given) - this looks very " "large. Is it intended?", iNewVal); } cs.iDynaFileCacheSize = iNewVal; DBGPRINTF("DynaFileCacheSize changed to %d.\n", iNewVal); RETiRet; } /** * @brief Parses an output channel name and associates it with the action. * * This is a helper function to `cfline()`. It parses an output channel name * from the configuration line, looks up the channel, and extracts its * associated file template and size limit settings, storing them in the * provided `instanceData` structure. * * @param pData Pointer to the instance data structure to populate. * @param p Pointer to the current position in the configuration line. * @param pOMSR Pointer to the OMOD String Request structure. * @param iEntry Index for the OMOD String Request. * @param iTplOpts Template options. * @return RS_RET_OK on success, or an error code if the output channel * is not found or has no valid file name template. */ static rsRetVal cflineParseOutchannel( instanceData *pData, uchar *p, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts) { DEFiRet; size_t i; struct outchannel *pOch; char szBuf[128]; /* should be more than sufficient */ ++p; /* skip '$' */ i = 0; /* get outchannel name */ while (*p && *p != ';' && *p != ' ' && i < (sizeof(szBuf) - 1)) { szBuf[i++] = *p++; } szBuf[i] = '\0'; /* got the name, now look up the channel... */ pOch = ochFind(szBuf, i); if (pOch == NULL) { parser_errmsg("outchannel '%s' not found - ignoring action line", szBuf); ABORT_FINALIZE(RS_RET_NOT_FOUND); } /* check if there is a file name in the outchannel... */ if (pOch->pszFileTemplate == NULL) { parser_errmsg("outchannel '%s' has no file name template - ignoring action line", szBuf); ABORT_FINALIZE(RS_RET_ERR); } /* OK, we finally got a correct template. So let's use it... */ pData->fname = ustrdup(pOch->pszFileTemplate); pData->iSizeLimit = pOch->uSizeLimit; /* WARNING: It is dangerous "just" to pass the pointer. As we * never rebuild the output channel description, this is acceptable here. */ pData->pszSizeLimitCmd = pOch->cmdOnSizeLimit; iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, getDfltTpl()); finalize_it: RETiRet; } /** * @brief Deletes an entry from the dynamic file name cache. * * This function closes the associated file stream, frees memory for the * file name, and optionally frees the cache entry structure itself. * * @param pData Pointer to the instance data containing the dynamic file cache. * @param iEntry The index of the entry to be deleted in the cache array. * @param bFreeEntry If 1, the cache entry structure itself is free()ed; * if 0, only its contents are freed (e.g., if it's being * reused for a new entry). * @return RS_RET_OK on success. */ static rsRetVal dynaFileDelCacheEntry(instanceData *__restrict__ const pData, const int iEntry, const int bFreeEntry) { dynaFileCacheEntry **pCache = pData->dynCache; DEFiRet; assert(pCache != NULL); if (pCache[iEntry] == NULL) FINALIZE; DBGPRINTF("Removing entry %d for file '%s' from dynaCache.\n", iEntry, pCache[iEntry]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[iEntry]->pName); if (pCache[iEntry]->pName != NULL) { free(pCache[iEntry]->pName); pCache[iEntry]->pName = NULL; } if (pCache[iEntry]->pStrm != NULL) { if (iEntry == pData->iCurrElt) { pData->iCurrElt = -1; pData->pStrm = NULL; } strm.Destruct(&pCache[iEntry]->pStrm); if (pData->useSigprov) { pData->sigprov.OnFileClose(pCache[iEntry]->sigprovFileData); pCache[iEntry]->sigprovFileData = NULL; } } if (bFreeEntry) { free(pCache[iEntry]); pCache[iEntry] = NULL; } finalize_it: RETiRet; } /** * @brief Frees all dynamic file name cache entries and closes relevant files. * * This function is typically called during module shutdown or HUP processing * to release all resources held by the dynamic file cache. * * @param pData Pointer to the instance data containing the dynamic file cache. */ static void dynaFileFreeCacheEntries(instanceData *__restrict__ const pData) { register int i; assert(pData != NULL); for (i = 0; i < pData->iCurrCacheSize; ++i) { dynaFileDelCacheEntry(pData, i, 1); } /* invalidate current element */ pData->iCurrElt = -1; pData->pStrm = NULL; } /** * @brief Frees the dynamic file name cache structure. * * This function first frees all entries within the cache and then * deallocates the cache array itself. * * @param pData Pointer to the instance data containing the dynamic file cache. */ static void dynaFileFreeCache(instanceData *__restrict__ const pData) { assert(pData != NULL); dynaFileFreeCacheEntries(pData); if (pData->dynCache != NULL) free(pData->dynCache); } /** * @brief Closes the currently open file stream for a given instance. * * If a signature provider is in use, its `OnFileClose` method is also called. * * @param pData Pointer to the instance data whose file stream is to be closed. * @return RS_RET_OK on success. */ static rsRetVal closeFile(instanceData *__restrict__ const pData) { DEFiRet; if (pData->useSigprov) { pData->sigprov.OnFileClose(pData->sigprovFileData); pData->sigprovFileData = NULL; } strm.Destruct(&pData->pStrm); RETiRet; } /** * @brief Prepares the signature provider for processing a file. * * This function calls the `OnFileOpen` method of the configured signature * provider, passing the file name and obtaining an opaque data pointer for * file-specific signature operations. * * @param pData Pointer to the instance data containing the signature provider. * @param fn The name of the file to be processed. * @return RS_RET_OK on success. */ static rsRetVal sigprovPrepare(instanceData *__restrict__ const pData, uchar *__restrict__ const fn) { DEFiRet; pData->sigprov.OnFileOpen(pData->sigprovData, fn, &pData->sigprovFileData); RETiRet; } /** * @brief Prepares file access for a given file name. * * This function handles the creation of parent directories (if configured), * creates the file itself (if it doesn't exist), sets its ownership and * permissions, and then constructs and finalizes the rsyslog stream object * for writing to the file. It also initializes signature and crypto providers * if enabled. * * @param pData Pointer to the instance data for the file output action. * @param newFileName The name of the file to prepare access for. * @return RS_RET_OK on success, or an error code if file creation, * directory creation, or stream construction fails. */ static rsRetVal prepareFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) { int fd; char errStr[1024]; /* buffer for strerr() */ DEFiRet; pData->pStrm = NULL; if (access((char *)newFileName, F_OK) != 0) { /* file does not exist, create it (and eventually parent directories */ if (pData->bCreateDirs) { /* We first need to create parent dirs if they are missing. * We do not report any errors here ourselfs but let the code * fall through to error handler below. */ if (makeFileParentDirs(newFileName, ustrlen(newFileName), pData->fDirCreateMode, pData->dirUID, pData->dirGID, pData->bFailOnChown) != 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); parser_errmsg( "omfile: creating parent " "directories for file '%s' failed: %s", newFileName, errStr); ABORT_FINALIZE(RS_RET_ERR); /* we give up */ } } /* no matter if we needed to create directories or not, we now try to create * the file. -- rgerhards, 2008-12-18 (based on patch from William Tisater) */ fd = open((char *)newFileName, O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY | O_CLOEXEC, pData->fCreateMode); if (fd != -1) { /* check and set uid/gid */ if (pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t)-1) { /* we need to set owner/group */ if (fchown(fd, pData->fileUID, pData->fileGID) != 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); parser_errmsg("omfile: chown for file '%s' failed: %s", newFileName, errStr); if (pData->bFailOnChown) { close(fd); ABORT_FINALIZE(RS_RET_ERR); /* we give up */ } /* we will silently ignore the chown() failure * if configured to do so. */ } } close(fd); /* close again, as we need a stream further on */ } } /* the copies below are clumpsy, but there is no way around given the * anomalies in dirname() and basename() [they MODIFY the provided buffer...] */ uchar szNameBuf[MAXFNAME + 1]; uchar szDirName[MAXFNAME + 1]; uchar szBaseName[MAXFNAME + 1]; ustrncpy(szNameBuf, newFileName, MAXFNAME); szNameBuf[MAXFNAME] = '\0'; ustrncpy(szDirName, (uchar *)dirname((char *)szNameBuf), MAXFNAME); szDirName[MAXFNAME] = '\0'; ustrncpy(szNameBuf, newFileName, MAXFNAME); szNameBuf[MAXFNAME] = '\0'; ustrncpy(szBaseName, (uchar *)basename((char *)szNameBuf), MAXFNAME); szBaseName[MAXFNAME] = '\0'; CHKiRet(strm.Construct(&pData->pStrm)); CHKiRet(strm.SetFName(pData->pStrm, szBaseName, ustrlen(szBaseName))); CHKiRet(strm.SetDir(pData->pStrm, szDirName, ustrlen(szDirName))); CHKiRet(strm.SetiZipLevel(pData->pStrm, pData->iZipLevel)); CHKiRet(strm.SetbVeryReliableZip(pData->pStrm, pData->bVeryRobustZip)); CHKiRet(strm.SetsIOBufSize(pData->pStrm, (size_t)pData->iIOBufSize)); CHKiRet(strm.SettOperationsMode(pData->pStrm, STREAMMODE_WRITE_APPEND)); CHKiRet(strm.SettOpenMode(pData->pStrm, cs.fCreateMode)); CHKiRet(strm.SetcompressionDriver(pData->pStrm, runModConf->compressionDriver)); CHKiRet(strm.SetCompressionWorkers(pData->pStrm, runModConf->compressionDriver_workers)); CHKiRet(strm.SetbSync(pData->pStrm, pData->bSyncFile)); CHKiRet(strm.SetsType(pData->pStrm, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetiSizeLimit(pData->pStrm, pData->iSizeLimit)); if (pData->useCryprov) { CHKiRet(strm.Setcryprov(pData->pStrm, &pData->cryprov)); CHKiRet(strm.SetcryprovData(pData->pStrm, pData->cryprovData)); } /* set the flush interval only if we actually use it - otherwise it will activate * async processing, which is a real performance waste if we do not do buffered * writes! -- rgerhards, 2009-07-06 */ if (pData->bUseAsyncWriter) CHKiRet(strm.SetiFlushInterval(pData->pStrm, pData->iFlushInterval)); if (pData->pszSizeLimitCmd != NULL) CHKiRet(strm.SetpszSizeLimitCmd(pData->pStrm, ustrdup(pData->pszSizeLimitCmd))); CHKiRet(strm.ConstructFinalize(pData->pStrm)); if (pData->useSigprov) sigprovPrepare(pData, szNameBuf); finalize_it: if (iRet != RS_RET_OK) { if (pData->pStrm != NULL) { closeFile(pData); } } RETiRet; } /** * @brief Handles dynamic file names, ensuring the correct file is open for writing. * * This function checks if the requested dynamic file name is already present * in the cache. If so, it reuses the existing file handle. If not, it attempts * to open the new file, potentially evicting an older entry from the LRU cache * if the cache is full. * * @param pData Pointer to the instance data for the file output action. * @param newFileName The new dynamic file name to prepare. * @return RS_RET_OK on success, or an error code if the file cannot be opened * or memory allocation fails. */ static rsRetVal ATTR_NONNULL() prepareDynFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) { uint64 ctOldest; /* "timestamp" of oldest element */ int iOldest; int i; int iFirstFree; rsRetVal localRet; dynaFileCacheEntry **pCache; DEFiRet; assert(pData != NULL); assert(newFileName != NULL); pCache = pData->dynCache; /* first check, if we still have the current file */ if ((pData->iCurrElt != -1) && !ustrcmp(newFileName, pCache[pData->iCurrElt]->pName)) { /* great, we are all set */ pCache[pData->iCurrElt]->clkTickAccessed = getClockFileAccess(); STATSCOUNTER_INC(pData->ctrLevel0, pData->mutCtrLevel0); /* LRU needs only a strictly monotonically increasing counter, so such a one could do */ FINALIZE; } /* ok, no luck - current file cannot be re-used */ /* if we need to flush (at least) on TXEnd, we need to flush now - because * we do not know if we will otherwise come back to this file to flush it * at end of TX. see https://github.com/rsyslog/rsyslog/issues/2502 */ if (((runModConf->pConf->globals.glblDevOptions & DEV_OPTION_8_1905_HANG_TEST) == 0) && pData->bFlushOnTXEnd && pData->pStrm != NULL) { CHKiRet(strm.Flush(pData->pStrm)); } /* Now let's search the table if we find a matching spot. * While doing so, we also prepare for creation of a new one. */ pData->iCurrElt = -1; /* invalid current element pointer */ iFirstFree = -1; /* not yet found */ iOldest = 0; /* we assume the first element to be the oldest - that will change as we loop */ ctOldest = getClockFileAccess(); /* there must always be an older one */ for (i = 0; i < pData->iCurrCacheSize; ++i) { if (pCache[i] == NULL || pCache[i]->pName == NULL) { if (iFirstFree == -1) iFirstFree = i; } else { /* got an element, let's see if it matches */ if (!ustrcmp(newFileName, pCache[i]->pName)) { /* we found our element! */ pData->pStrm = pCache[i]->pStrm; if (pData->useSigprov) pData->sigprovFileData = pCache[i]->sigprovFileData; pData->iCurrElt = i; pCache[i]->clkTickAccessed = getClockFileAccess(); /* update "timestamp" for LRU */ FINALIZE; } /* did not find it - so lets keep track of the counters for LRU */ if (pCache[i]->clkTickAccessed < ctOldest) { ctOldest = pCache[i]->clkTickAccessed; iOldest = i; } } } /* we have not found an entry */ STATSCOUNTER_INC(pData->ctrMiss, pData->mutCtrMiss); /* similarly, we need to set the current pStrm to NULL, because otherwise, if prepareFile() fails, * we may end up using an old stream. This bug depends on how exactly prepareFile fails, * but it could be triggered in the common case of a failed open() system call. * rgerhards, 2010-03-22 */ pData->pStrm = NULL, pData->sigprovFileData = NULL; if (iFirstFree == -1 && (pData->iCurrCacheSize < pData->iDynaFileCacheSize)) { /* there is space left, so set it to that index */ iFirstFree = pData->iCurrCacheSize++; STATSCOUNTER_SETMAX_NOMUT(pData->ctrMax, (unsigned)pData->iCurrCacheSize); } /* Note that the following code sequence does not work with the cache entry itself, * but rather with pData->pStrm, the (sole) stream pointer in the non-dynafile case. * The cache array is only updated after the open was successful. -- rgerhards, 2010-03-21 */ if (iFirstFree == -1) { dynaFileDelCacheEntry(pData, iOldest, 0); STATSCOUNTER_INC(pData->ctrEvict, pData->mutCtrEvict); iFirstFree = iOldest; /* this one *is* now free ;) */ } else { /* we need to allocate memory for the cache structure */ CHKmalloc(pCache[iFirstFree] = (dynaFileCacheEntry *)calloc(1, sizeof(dynaFileCacheEntry))); } /* Ok, we finally can open the file */ localRet = prepareFile(pData, newFileName); /* ignore exact error, we check fd below */ /* check if we had an error */ if (localRet != RS_RET_OK) { /* We do no longer care about internal messages. The errmsg rate limiter * will take care of too-frequent error messages. */ parser_errmsg( "Could not open dynamic file '%s' [state %d] - discarding " "message", newFileName, localRet); ABORT_FINALIZE(localRet); } if ((pCache[iFirstFree]->pName = ustrdup(newFileName)) == NULL) { closeFile(pData); /* need to free failed entry! */ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pCache[iFirstFree]->pStrm = pData->pStrm; if (pData->useSigprov) pCache[iFirstFree]->sigprovFileData = pData->sigprovFileData; pCache[iFirstFree]->clkTickAccessed = getClockFileAccess(); pData->iCurrElt = iFirstFree; DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName); finalize_it: if (iRet == RS_RET_OK) pCache[pData->iCurrElt]->nInactive = 0; RETiRet; } /** * @brief Performs the actual buffered write operation to the file stream. * * This function writes the provided buffer to the stream associated with * the instance data. It also calls the signature provider's `OnRecordWrite` * method if a signature provider is in use. * * @param pData Pointer to the instance data containing the stream and provider info. * @param pszBuf Pointer to the buffer containing the data to write. * @param lenBuf The length of the data in the buffer. * @return RS_RET_OK on success, or an error code from the stream write operation. */ static rsRetVal doWrite(instanceData *__restrict__ const pData, uchar *__restrict__ const pszBuf, const int lenBuf) { DEFiRet; assert(pData != NULL); assert(pszBuf != NULL); const int needsLF = pData->bAddLF && (lenBuf == 0 || pszBuf[lenBuf - 1] != '\n'); uchar addlfBuf[ADDLF_SIGBUF_STACKLEN]; uchar *sigBuf = NULL; uchar *sigWriteBuf = pszBuf; size_t sigLen = 0; rs_size_t sigWriteLen = (rs_size_t)lenBuf; int freeSigBuf = 0; DBGPRINTF("omfile: write to stream, pData->pStrm %p, lenBuf %d, needsLF %d, strt data %.128s\n", pData->pStrm, lenBuf, needsLF, pszBuf); if (pData->pStrm != NULL) { if (lenBuf > 0) { CHKiRet(strm.Write(pData->pStrm, pszBuf, lenBuf)); } if (needsLF) { CHKiRet(strm.WriteChar(pData->pStrm, '\n')); } } if (pData->useSigprov) { if (needsLF) { sigLen = (size_t)lenBuf + 1; if (sigLen <= sizeof(addlfBuf)) { sigBuf = addlfBuf; } else { sigBuf = (uchar *)malloc(sigLen); if (sigBuf == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } freeSigBuf = 1; } if (lenBuf > 0) { memcpy(sigBuf, pszBuf, (size_t)lenBuf); } sigBuf[lenBuf] = '\n'; sigWriteBuf = sigBuf; sigWriteLen = (rs_size_t)sigLen; } CHKiRet(pData->sigprov.OnRecordWrite(pData->sigprovFileData, sigWriteBuf, sigWriteLen)); } finalize_it: if (freeSigBuf) { free(sigBuf); } RETiRet; } /** * @brief Writes a message to the configured file. * * This function determines whether the output is to a static file or a * dynamic file. If dynamic, it calls `prepareDynFile` to ensure the correct * file is open. It then calls `doWrite` to perform the actual write operation. * * @param pData Pointer to the instance data for the file output action. * @param pParam Pointer to the action worker instance parameters. * @param iMsg The index of the message within the batch to process. * @return RS_RET_OK on success, or an error code if file preparation * or writing fails. */ static rsRetVal writeFile(instanceData *__restrict__ const pData, const actWrkrIParams_t *__restrict__ const pParam, const int iMsg) { DEFiRet; STATSCOUNTER_INC(pData->ctrRequests, pData->mutCtrRequests); /* first check if we have a dynamic file name and, if so, * check if it still is ok or a new file needs to be created */ if (pData->bDynamicName) { DBGPRINTF("omfile: file to log to: %s\n", actParam(pParam, pData->iNumTpls, iMsg, 1).param); CHKiRet(prepareDynFile(pData, actParam(pParam, pData->iNumTpls, iMsg, 1).param)); } else { /* "regular", non-dynafile */ if (pData->pStrm == NULL) { CHKiRet(prepareFile(pData, pData->fname)); if (pData->pStrm == NULL) { parser_errmsg("Could not open output file '%s'", pData->fname); } } pData->nInactive = 0; } iRet = doWrite(pData, actParam(pParam, pData->iNumTpls, iMsg, 0).param, actParam(pParam, pData->iNumTpls, iMsg, 0).lenStr); finalize_it: RETiRet; } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; pModConf->tplName = NULL; pModConf->fCreateMode = 0644; pModConf->fDirCreateMode = 0700; pModConf->fileUID = -1; pModConf->dirUID = -1; pModConf->fileGID = -1; pModConf->dirGID = -1; pModConf->bDynafileDoNotSuspend = 1; pModConf->bAddLF = 1; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { parser_errmsg( "error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for omfile:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } if (!strcmp(modpblk.descr[i].name, "template")) { loadModConf->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (pszFileDfltTplName != NULL) { parser_errmsg( "omfile: warning: default template was already " "set via legacy directive - may lead to inconsistent " "results."); } } else if (!strcmp(modpblk.descr[i].name, "addlf")) { loadModConf->bAddLF = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "compression.driver")) { if (!es_strcasebufcmp(pvals[i].val.d.estr, (const unsigned char *)"zlib", 4)) { loadModConf->compressionDriver = STRM_COMPRESS_ZIP; } else if (!es_strcasebufcmp(pvals[i].val.d.estr, (const unsigned char *)"zstd", 4)) { loadModConf->compressionDriver = STRM_COMPRESS_ZSTD; } else { parser_errmsg( "omfile: error: invalid compression.driver driver " "name - noch applying setting. Valid drivers: 'zlib' and " "'zstd'."); } } else if (!strcmp(modpblk.descr[i].name, "compression.zstd.workers")) { loadModConf->compressionDriver_workers = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dircreatemode")) { loadModConf->fDirCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filecreatemode")) { loadModConf->fCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirowner")) { loadModConf->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirownernum")) { loadModConf->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirgroup")) { loadModConf->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirgroupnum")) { loadModConf->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "fileowner")) { loadModConf->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "fileownernum")) { loadModConf->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filegroup")) { loadModConf->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filegroupnum")) { loadModConf->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dynafile.donotsuspend")) { loadModConf->bDynafileDoNotSuspend = (int)pvals[i].val.d.n; } else { dbgprintf( "omfile: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf /** * @brief Checks the dynamic file cache for entries exceeding their close timeout. * * This function iterates through the dynamic file cache and closes/deletes * entries that have been inactive for longer than their configured * `iCloseTimeout`. It is typically called by the janitor. * * @param pData Pointer to the instance data containing the dynamic file cache. */ static void janitorChkDynaFiles(instanceData *__restrict__ const pData) { int i; dynaFileCacheEntry **pCache = pData->dynCache; for (i = 0; i < pData->iCurrCacheSize; ++i) { if (pCache[i] == NULL) continue; DBGPRINTF("omfile janitor: checking dynafile %d:%s, inactive since %d\n", i, pCache[i]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[i]->pName, (int)pCache[i]->nInactive); if (pCache[i]->nInactive >= pData->iCloseTimeout) { STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); dynaFileDelCacheEntry(pData, i, 1); if (pData->iCurrElt == i) pData->iCurrElt = -1; /* no longer available! */ } else { pCache[i]->nInactive += runModConf->pConf->globals.janitorInterval; } } } /** * @brief Callback function for the janitor. * * This function is called periodically by the rsyslog janitor to clean out * inactive files (both static and dynamic) based on their configured * `iCloseTimeout`. It acquires a mutex to protect access to the file data. * * @param pUsr A pointer to the `instanceData` structure for the file action. */ static void janitorCB(void *pUsr) { instanceData *__restrict__ const pData = (instanceData *)pUsr; pthread_mutex_lock(&pData->mutWrite); if (pData->bDynamicName) { janitorChkDynaFiles(pData); } else { if (pData->pStrm != NULL) { DBGPRINTF("omfile janitor: checking file %s, inactive since %d\n", pData->fname, pData->nInactive); if (pData->nInactive >= pData->iCloseTimeout) { STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); closeFile(pData); } else { pData->nInactive += runModConf->pConf->globals.janitorInterval; } } } pthread_mutex_unlock(&pData->mutWrite); } BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ /* free legacy config vars */ free(pszFileDfltTplName); pszFileDfltTplName = NULL; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free(pModConf->tplName); ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; pData->pStrm = NULL; pData->bAddLF = 1; pthread_mutex_init(&pData->mutWrite, NULL); ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINfreeInstance CODESTARTfreeInstance; free(pData->tplName); free(pData->fname); if (pData->iCloseTimeout > 0) janitorDelEtry(pData->janitorID); if (pData->bDynamicName) { dynaFileFreeCache(pData); } else if (pData->pStrm != NULL) closeFile(pData); if (pData->stats != NULL) statsobj.Destruct(&(pData->stats)); if (pData->useSigprov) { pData->sigprov.Destruct(&pData->sigprovData); obj.ReleaseObj(__FILE__, pData->sigprovNameFull + 2, pData->sigprovNameFull, (void *)&pData->sigprov); free(pData->sigprovName); free(pData->sigprovNameFull); } if (pData->useCryprov) { pData->cryprov.Destruct(&pData->cryprovData); obj.ReleaseObj(__FILE__, pData->cryprovNameFull + 2, pData->cryprovNameFull, (void *)&pData->cryprov); free(pData->cryprovName); free(pData->cryprovNameFull); } pthread_mutex_destroy(&pData->mutWrite); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINbeginTransaction CODESTARTbeginTransaction; /* we have nothing to do to begin a transaction */ ENDbeginTransaction BEGINcommitTransaction instanceData *__restrict__ const pData = pWrkrData->pData; unsigned i; CODESTARTcommitTransaction; if (pData->isDevNull) { goto terminate; } pthread_mutex_lock(&pData->mutWrite); for (i = 0; i < nParams; ++i) { writeFile(pData, pParams, i); } /* Note: pStrm may be NULL if there was an error opening the stream */ /* if bFlushOnTXEnd is set, we need to flush on transaction end - in * any case. It is not relevant if this is using background writes * (which then become pretty slow) or not. And, similarly, no flush * happens when it is not set. Please see * https://github.com/rsyslog/rsyslog/issues/1297 * for a discussion of why we actually need this. * rgerhards, 2017-01-13 */ if (pData->bFlushOnTXEnd && pData->pStrm != NULL) { CHKiRet(strm.Flush(pData->pStrm)); } finalize_it: pthread_mutex_unlock(&pData->mutWrite); if (iRet == RS_RET_FILE_OPEN_ERROR || iRet == RS_RET_FILE_NOT_FOUND) { iRet = (pData->bDynamicName && runModConf->bDynafileDoNotSuspend) ? RS_RET_OK : RS_RET_SUSPENDED; } terminate: ENDcommitTransaction /** * @brief Sets default parameter values for a new omfile action instance. * * This function initializes various fields of the `instanceData` structure * with their default values, some of which are derived from module-global * configuration settings. * * @param pData Pointer to the `instanceData` structure to be initialized. */ static void setInstParamDefaults(instanceData *__restrict__ const pData) { pData->fname = NULL; pData->tplName = NULL; pData->fileUID = loadModConf->fileUID; pData->fileGID = loadModConf->fileGID; pData->dirUID = loadModConf->dirUID; pData->dirGID = loadModConf->dirGID; pData->bFailOnChown = 1; pData->iDynaFileCacheSize = 10; pData->fCreateMode = loadModConf->fCreateMode; pData->fDirCreateMode = loadModConf->fDirCreateMode; pData->bCreateDirs = 1; pData->bSyncFile = 0; pData->iZipLevel = 0; pData->bVeryRobustZip = 0; pData->bFlushOnTXEnd = FLUSHONTX_DFLT; pData->iIOBufSize = IOBUF_DFLT_SIZE; pData->iFlushInterval = FLUSH_INTRVL_DFLT; pData->bUseAsyncWriter = USE_ASYNCWRITER_DFLT; pData->bAddLF = loadModConf->bAddLF; pData->sigprovName = NULL; pData->cryprovName = NULL; pData->useSigprov = 0; pData->useCryprov = 0; pData->iCloseTimeout = -1; pData->iSizeLimit = 0; pData->isDevNull = 0; pData->pszSizeLimitCmd = NULL; } /** * @brief Sets up statistics counters for a new omfile instance. * * This function initializes and registers statistics counters for dynamic * file actions, including requests, cache hits/misses, evictions, and * close timeouts. * * @param pData Pointer to the `instanceData` structure for which to set up stats. * @return RS_RET_OK on success, or an error code if statsobj construction fails. */ static rsRetVal setupInstStatsCtrs(instanceData *__restrict__ const pData) { uchar ctrName[512]; DEFiRet; if (!pData->bDynamicName) { FINALIZE; } /* support statistics gathering */ snprintf((char *)ctrName, sizeof(ctrName), "dynafile cache %s", pData->fname); ctrName[sizeof(ctrName) - 1] = '\0'; /* be on the save side */ CHKiRet(statsobj.Construct(&(pData->stats))); CHKiRet(statsobj.SetName(pData->stats, ctrName)); CHKiRet(statsobj.SetOrigin(pData->stats, (uchar *)"omfile")); STATSCOUNTER_INIT(pData->ctrRequests, pData->mutCtrRequests); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("requests"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrRequests))); STATSCOUNTER_INIT(pData->ctrLevel0, pData->mutCtrLevel0); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("level0"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrLevel0))); STATSCOUNTER_INIT(pData->ctrMiss, pData->mutCtrMiss); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("missed"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMiss))); STATSCOUNTER_INIT(pData->ctrEvict, pData->mutCtrEvict); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("evicted"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrEvict))); STATSCOUNTER_INIT(pData->ctrMax, pData->mutCtrMax); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("maxused"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMax))); STATSCOUNTER_INIT(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("closetimeouts"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrCloseTimeouts))); CHKiRet(statsobj.ConstructFinalize(pData->stats)); finalize_it: RETiRet; } /** * @brief Initializes the signature provider for an omfile instance. * * This function loads the specified signature provider module, constructs * its data instance, and sets its configuration parameters. If any step * fails, signatures are disabled for this instance. * * @param pData Pointer to the `instanceData` structure. * @param lst List of configuration parameters for the signature provider. */ static void initSigprov(instanceData *__restrict__ const pData, struct nvlst *lst) { uchar szDrvrName[1024]; if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmsig_%s", pData->sigprovName) == sizeof(szDrvrName)) { parser_errmsg( "omfile: signature provider " "name is too long: '%s' - signatures disabled", pData->sigprovName); goto done; } pData->sigprovNameFull = ustrdup(szDrvrName); pData->sigprov.ifVersion = sigprovCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean enough. */ if (obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void *)&pData->sigprov) != RS_RET_OK) { parser_errmsg( "omfile: could not load " "signature provider '%s' - signatures disabled", szDrvrName); goto done; } if (pData->sigprov.Construct(&pData->sigprovData) != RS_RET_OK) { parser_errmsg( "omfile: error constructing " "signature provider %s dataset - signatures disabled", szDrvrName); goto done; } pData->sigprov.SetCnfParam(pData->sigprovData, lst); dbgprintf("loaded signature provider %s, data instance at %p\n", szDrvrName, pData->sigprovData); pData->useSigprov = 1; done: return; } /** * @brief Initializes the crypto provider for an omfile instance. * * This function loads the specified crypto provider module, constructs * its data instance, and sets its configuration parameters. If any step * fails, encryption is disabled for this instance. * * @param pData Pointer to the `instanceData` structure. * @param lst List of configuration parameters for the crypto provider. * @return RS_RET_OK on success, or an error code if loading or construction fails. */ static rsRetVal initCryprov(instanceData *__restrict__ const pData, struct nvlst *lst) { uchar szDrvrName[1024]; DEFiRet; if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pData->cryprovName) == sizeof(szDrvrName)) { parser_errmsg( "omfile: crypto provider " "name is too long: '%s' - encryption disabled", pData->cryprovName); ABORT_FINALIZE(RS_RET_ERR); } pData->cryprovNameFull = ustrdup(szDrvrName); pData->cryprov.ifVersion = cryprovCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean enough. */ if (obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void *)&pData->cryprov) != RS_RET_OK) { parser_errmsg( "omfile: could not load " "crypto provider '%s' - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } if (pData->cryprov.Construct(&pData->cryprovData) != RS_RET_OK) { parser_errmsg( "omfile: error constructing " "crypto provider %s dataset - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst, CRYPROV_PARAMTYPE_REGULAR)); dbgprintf("loaded crypto provider %s, data instance at %p\n", szDrvrName, pData->cryprovData); pData->useCryprov = 1; finalize_it: RETiRet; } BEGINnewActInst struct cnfparamvals *pvals; uchar *tplToUse; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (omfile)\n"); pvals = nvlstGetParams(lst, &actpblk, NULL); if (pvals == NULL) { parser_errmsg( "omfile: either the \"file\" or " "\"dynafile\" parameter must be given"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("action param blk in omfile:\n"); cnfparamsPrint(&actpblk, pvals); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "dynafilecachesize")) { pData->iDynaFileCacheSize = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ziplevel")) { pData->iZipLevel = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "flushinterval")) { pData->iFlushInterval = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "veryrobustzip")) { pData->bVeryRobustZip = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "asyncwriting")) { pData->bUseAsyncWriter = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "flushontxend")) { pData->bFlushOnTXEnd = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "iobuffersize")) { pData->iIOBufSize = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirowner")) { pData->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirownernum")) { pData->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirgroup")) { pData->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirgroupnum")) { pData->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "fileowner")) { pData->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "fileownernum")) { pData->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filegroup")) { pData->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filegroupnum")) { pData->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dircreatemode")) { pData->fDirCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filecreatemode")) { pData->fCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "failonchownfailure")) { pData->bFailOnChown = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "sync")) { pData->bSyncFile = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "createdirs")) { pData->bCreateDirs = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "addlf")) { pData->bAddLF = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "file")) { pData->fname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); CODE_STD_STRING_REQUESTnewActInst(1); pData->bDynamicName = 0; } else if (!strcmp(actpblk.descr[i].name, "dynafile")) { if (pData->fname != NULL) { parser_errmsg("omfile: both \"file\" and \"dynafile\" set, will use dynafile"); } pData->fname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); CODE_STD_STRING_REQUESTnewActInst(2); pData->bDynamicName = 1; } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "sig.provider")) { pData->sigprovName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "cry.provider")) { pData->cryprovName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "closetimeout")) { pData->iCloseTimeout = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "rotation.sizelimit")) { pData->iSizeLimit = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "rotation.sizelimitcommand")) { pData->pszSizeLimitCmd = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf( "omfile: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } if (pData->fname == NULL || *pData->fname == '\0') { parser_errmsg( "omfile: either the \"file\" or " "\"dynafile\" parameter must be given"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } int allWhiteSpace = 1; for (const char *p = (const char *)pData->fname; *p; ++p) { if (!isspace(*p)) { allWhiteSpace = 0; break; } } if (allWhiteSpace) { parser_errmsg( "omfile: \"file\" or \"dynafile\" parameter " "consist only of whitespace - this is not permitted"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (!strcmp((const char *)pData->fname, "/dev/null")) { pData->isDevNull = 1; } if (pData->sigprovName != NULL) { initSigprov(pData, lst); } if (pData->cryprovName != NULL) { CHKiRet(initCryprov(pData, lst)); } tplToUse = ustrdup((pData->tplName == NULL) ? getDfltTpl() : pData->tplName); CHKiRet(OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS)); pData->iNumTpls = 1; if (pData->bDynamicName) { /* "filename" is actually a template name, we need this as string 1. So let's add it * to the pOMSR. -- rgerhards, 2007-07-27 */ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); pData->iNumTpls = 2; // TODO: create unified code for this (legacy+v6 system) /* we now allocate the cache table */ CHKmalloc(pData->dynCache = (dynaFileCacheEntry **)calloc(pData->iDynaFileCacheSize, sizeof(dynaFileCacheEntry *))); pData->iCurrElt = -1; /* no current element */ } // TODO: add pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ setupInstStatsCtrs(pData); if (pData->iCloseTimeout == -1) { /* unset? */ pData->iCloseTimeout = (pData->bDynamicName) ? 10 : 0; } snprintf(pData->janitorID, sizeof(pData->janitorID), "omfile:%sfile:%s:%p", (pData->bDynamicName) ? "dyna" : "", pData->fname, pData); pData->janitorID[sizeof(pData->janitorID) - 1] = '\0'; /* just in case... */ if (pData->iCloseTimeout > 0) janitorAddEtry(janitorCB, pData->janitorID, pData); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINparseSelectorAct uchar fname[MAXFNAME]; CODESTARTparseSelectorAct; /* Note: the indicator sequence permits us to use '$' to signify * outchannel, what otherwise is not possible due to truely * unresolvable grammar conflicts (*this time no way around*). * rgerhards, 2011-07-09 */ if (!strncmp((char *)p, ":omfile:", sizeof(":omfile:") - 1)) { p += sizeof(":omfile:") - 1; } if (!(*p == '$' || *p == '?' || *p == '/' || *p == '.' || *p == '-')) ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); CHKiRet(createInstance(&pData)); if (*p == '-') { pData->bSyncFile = 0; p++; } else { pData->bSyncFile = cs.bEnableSync; } pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ switch (*p) { case '$': CODE_STD_STRING_REQUESTparseSelectorAct(1) pData->iNumTpls = 1; /* rgerhards 2005-06-21: this is a special setting for output-channel * definitions. In the long term, this setting will probably replace * anything else, but for the time being we must co-exist with the * traditional mode lines. * rgerhards, 2007-07-24: output-channels will go away. We keep them * for compatibility reasons, but seems to have been a bad idea. */ CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); pData->bDynamicName = 0; break; case '?': /* This is much like a regular file handle, but we need to obtain * a template name. rgerhards, 2007-07-03 */ CODE_STD_STRING_REQUESTparseSelectorAct(2) pData->iNumTpls = 2; ++p; /* eat '?' */ CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); pData->fname = ustrdup(fname); pData->bDynamicName = 1; pData->iCurrElt = -1; /* no current element */ /* "filename" is actually a template name, we need this as string 1. So let's add it * to the pOMSR. -- rgerhards, 2007-07-27 */ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); /* we now allocate the cache table */ CHKmalloc(pData->dynCache = (dynaFileCacheEntry **)calloc(cs.iDynaFileCacheSize, sizeof(dynaFileCacheEntry *))); break; case '/': case '.': CODE_STD_STRING_REQUESTparseSelectorAct(1) pData->iNumTpls = 1; CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); pData->fname = ustrdup(fname); pData->bDynamicName = 0; break; default: ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); } /* freeze current paremeters for this action */ pData->iDynaFileCacheSize = cs.iDynaFileCacheSize; pData->fCreateMode = cs.fCreateMode; pData->fDirCreateMode = cs.fDirCreateMode; pData->bCreateDirs = cs.bCreateDirs; pData->bFailOnChown = cs.bFailOnChown; pData->fileUID = cs.fileUID; pData->fileGID = cs.fileGID; pData->dirUID = cs.dirUID; pData->dirGID = cs.dirGID; pData->iZipLevel = cs.iZipLevel; pData->bFlushOnTXEnd = cs.bFlushOnTXEnd; pData->iIOBufSize = (int)cs.iIOBufSize; pData->iFlushInterval = cs.iFlushInterval; pData->bUseAsyncWriter = cs.bUseAsyncWriter; pData->bVeryRobustZip = 0; /* cannot be specified via legacy conf */ pData->iCloseTimeout = 0; /* cannot be specified via legacy conf */ setupInstStatsCtrs(pData); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct /** * @brief Resets configuration variables for the omfile module to default values. * * This function is used to revert module-global configuration settings * to their initial states, typically during `resetconfigvariables` processing. * * @param pp Unused pointer, kept for compatibility. * @param pVal Unused pointer, kept for compatibility. * @return RS_RET_OK always. */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { cs.fileUID = -1; cs.fileGID = -1; cs.dirUID = -1; cs.dirGID = -1; cs.bFailOnChown = 1; cs.iDynaFileCacheSize = 10; cs.fCreateMode = 0644; cs.fDirCreateMode = 0700; cs.bCreateDirs = 1; cs.bEnableSync = 0; cs.iZipLevel = 0; cs.bFlushOnTXEnd = FLUSHONTX_DFLT; cs.iIOBufSize = IOBUF_DFLT_SIZE; cs.iFlushInterval = FLUSH_INTRVL_DFLT; cs.bUseAsyncWriter = USE_ASYNCWRITER_DFLT; free(pszFileDfltTplName); pszFileDfltTplName = NULL; return RS_RET_OK; } BEGINdoHUP CODESTARTdoHUP; pthread_mutex_lock(&pData->mutWrite); if (pData->bDynamicName) { dynaFileFreeCacheEntries(pData); } else { if (pData->pStrm != NULL) { closeFile(pData); } } pthread_mutex_unlock(&pData->mutWrite); ENDdoHUP BEGINmodExit CODESTARTmodExit; objRelease(strm, CORE_COMPONENT); objRelease(statsobj, CORE_COMPONENT); DESTROY_ATOMIC_HELPER_MUT(mutClock); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMODTX_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_doHUP ENDqueryEtryPt BEGINmodInit(File) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr INITLegCnfVars; CHKiRet(objUse(strm, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); INIT_ATOMIC_HELPER_MUT(mutClock); INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); DBGPRINTF("omfile: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dynafilecachesize", 0, eCmdHdlrInt, setDynaFileCacheSize, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileziplevel", 0, eCmdHdlrInt, NULL, &cs.iZipLevel, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushinterval", 0, eCmdHdlrInt, NULL, &cs.iFlushInterval, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileasyncwriting", 0, eCmdHdlrBinary, NULL, &cs.bUseAsyncWriter, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushontxend", 0, eCmdHdlrBinary, NULL, &cs.bFlushOnTXEnd, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileiobuffersize", 0, eCmdHdlrSize, NULL, &cs.iIOBufSize, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirowner", 0, eCmdHdlrUID, NULL, &cs.dirUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirownernum", 0, eCmdHdlrInt, NULL, &cs.dirUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroup", 0, eCmdHdlrGID, NULL, &cs.dirGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroupnum", 0, eCmdHdlrInt, NULL, &cs.dirGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileowner", 0, eCmdHdlrUID, NULL, &cs.fileUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileownernum", 0, eCmdHdlrInt, NULL, &cs.fileUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroup", 0, eCmdHdlrGID, NULL, &cs.fileGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroupnum", 0, eCmdHdlrInt, NULL, &cs.fileGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dircreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fDirCreateMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fCreateMode, STD_LOADABLE_MODULE_ID)); CHKiRet( omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &cs.bCreateDirs, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileforcechown", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit rsyslog-8.2512.0/tools/PaxHeaders/pmrfc5424.c0000644000000000000000000000013215055605325015471 xustar0030 mtime=1756826325.660800849 30 atime=1764931033.651569052 30 ctime=1764935924.148591354 rsyslog-8.2512.0/tools/pmrfc5424.c0000664000175000017500000002404515055605325015142 0ustar00rgerrger/* pmrfc5424.c * This is a parser module for RFC5424-formatted messages. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2009-11-03 by RGerhards * * Copyright 2007-2015 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "syslogd.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.rfc5424") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* config data */ BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature /* Helper to parseRFCSyslogMsg. This function parses a field up to * (and including) the SP character after it. The field contents is * returned in a caller-provided buffer. The parsepointer is advanced * to after the terminating SP. The caller must ensure that the * provided buffer is large enough to hold the to be extracted value. * Returns 0 if everything is fine or 1 if either the field is not * SP-terminated or any other error occurs. -- rger, 2005-11-24 * The function now receives the size of the string and makes sure * that it does not process more than that. The *pLenStr counter is * updated on exit. -- rgerhards, 2009-09-23 */ static int parseRFCField(uchar **pp2parse, uchar *pResult, int *pLenStr) { uchar *p2parse; int iRet = 0; assert(pp2parse != NULL); assert(*pp2parse != NULL); assert(pResult != NULL); p2parse = *pp2parse; /* this is the actual parsing loop */ while (*pLenStr > 0 && *p2parse != ' ') { *pResult++ = *p2parse++; --(*pLenStr); } if (*pLenStr > 0 && *p2parse == ' ') { ++p2parse; /* eat SP, but only if not at end of string */ --(*pLenStr); } else { iRet = 1; /* there MUST be an SP! */ } *pResult = '\0'; /* set the new parse pointer */ *pp2parse = p2parse; return iRet; } /* Helper to parseRFCSyslogMsg. This function parses the structured * data field of a message. It does NOT parse inside structured data, * just gets the field as whole. Parsing the single entities is left * to other functions. The parsepointer is advanced * to after the terminating SP. The caller must ensure that the * provided buffer is large enough to hold the to be extracted value. * Returns 0 if everything is fine or 1 if either the field is not * SP-terminated or any other error occurs. -- rger, 2005-11-24 * The function now receives the size of the string and makes sure * that it does not process more than that. The *pLenStr counter is * updated on exit. -- rgerhards, 2009-09-23 */ static int parseRFCStructuredData(uchar **pp2parse, uchar *pResult, int *pLenStr) { uchar *p2parse; int bCont = 1; int iRet = 0; int lenStr; assert(pp2parse != NULL); assert(*pp2parse != NULL); assert(pResult != NULL); p2parse = *pp2parse; lenStr = *pLenStr; /* this is the actual parsing loop * Remeber: structured data starts with [ and includes any characters * until the first ] followed by a SP. There may be spaces inside * structured data. There may also be \] inside the structured data, which * do NOT terminate an element. */ if (lenStr == 0 || (*p2parse != '[' && *p2parse != '-')) return 1; /* this is NOT structured data! */ if (*p2parse == '-') { /* empty structured data? */ *pResult++ = '-'; ++p2parse; --lenStr; } else { while (bCont) { if (lenStr < 2) { /* we now need to check if we have only structured data */ if (lenStr > 0 && *p2parse == ']') { *pResult++ = *p2parse; p2parse++; lenStr--; bCont = 0; } else { iRet = 1; /* this is not valid! */ bCont = 0; } } else if (*p2parse == '\\' && *(p2parse + 1) == ']') { /* this is escaped, need to copy both */ *pResult++ = *p2parse++; *pResult++ = *p2parse++; lenStr -= 2; } else if (*p2parse == ']' && *(p2parse + 1) == ' ') { /* found end, just need to copy the ] and eat the SP */ *pResult++ = *p2parse; p2parse += 1; lenStr -= 1; bCont = 0; } else { *pResult++ = *p2parse++; --lenStr; } } } if (lenStr > 0 && *p2parse == ' ') { ++p2parse; /* eat SP, but only if not at end of string */ --lenStr; } else { iRet = 1; /* there MUST be an SP! */ } *pResult = '\0'; /* set the new parse pointer */ *pp2parse = p2parse; *pLenStr = lenStr; return iRet; } /* parse a RFC5424-formatted syslog message. This function returns * 0 if processing of the message shall continue and 1 if something * went wrong and this messe should be ignored. This function has been * implemented in the effort to support syslog-protocol. Please note that * the name (parse *RFC*) stems from the hope that syslog-protocol will * some time become an RFC. Do not confuse this with informational * RFC 3164 (which is legacy syslog). * * currently supported format: * * VERSION SP TIMESTAMP SP HOSTNAME SP APP-NAME SP PROCID SP MSGID SP [SD-ID]s SP MSG * * is already stripped when this function is entered. VERSION already * has been confirmed to be "1", but has NOT been stripped from the message. * * rger, 2005-11-24 */ BEGINparse uchar *p2parse; uchar *pBuf = NULL; int lenMsg; int bContParse = 1; CODESTARTparse; assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* check if we are the right parser */ if (lenMsg < 2 || p2parse[0] != '1' || p2parse[1] != ' ') { ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } DBGPRINTF("Message has RFC5424/syslog-protocol format.\n"); setProtocolVersion(pMsg, MSG_RFC5424_PROTOCOL); p2parse += 2; lenMsg -= 2; /* Now get us some memory we can use as a work buffer while parsing. * We simply allocated a buffer sufficiently large to hold all of the * message, so we can not run into any troubles. I think this is * wiser than to use individual buffers. */ CHKmalloc(pBuf = malloc(lenMsg + 1)); /* IMPORTANT NOTE: * Validation is not actually done below nor are any errors handled. I have * NOT included this for the current proof of concept. However, it is strongly * advisable to add it when this code actually goes into production. * rgerhards, 2005-11-24 */ /* TIMESTAMP */ if (lenMsg >= 2 && p2parse[0] == '-' && p2parse[1] == ' ') { memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); p2parse += 2; lenMsg -= 2; } else if (datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse, &lenMsg) == RS_RET_OK) { if (pMsg->msgFlags & IGNDATE) { /* we need to ignore the msg data, so simply copy over reception date */ memcpy(&pMsg->tTIMESTAMP, &pMsg->tRcvdAt, sizeof(struct syslogTime)); } } else { DBGPRINTF("no TIMESTAMP detected!\n"); bContParse = 0; } /* HOSTNAME */ if (bContParse) { parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetHOSTNAME(pMsg, pBuf, ustrlen(pBuf)); } /* APP-NAME */ if (bContParse) { parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetAPPNAME(pMsg, (char *)pBuf); } /* PROCID */ if (bContParse) { parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetPROCID(pMsg, (char *)pBuf); } /* MSGID */ if (bContParse) { parseRFCField(&p2parse, pBuf, &lenMsg); MsgSetMSGID(pMsg, (char *)pBuf); } /* STRUCTURED-DATA */ if (bContParse) { parseRFCStructuredData(&p2parse, pBuf, &lenMsg); MsgSetStructuredData(pMsg, (char *)pBuf); } /* MSG */ MsgSetMSGoffs(pMsg, p2parse - pMsg->pszRawMsg); finalize_it: if (pBuf != NULL) free(pBuf); ENDparse BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit(pmrfc5424) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); dbgprintf("rfc5424 parser init called\n"); dbgprintf("GetParserName addr %p\n", GetParserName); ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/rscryutil.c0000644000000000000000000000013215071746523016107 xustar0030 mtime=1760021843.916422216 30 atime=1764931133.281193921 30 ctime=1764935924.106590711 rsyslog-8.2512.0/tools/rscryutil.c0000664000175000017500000006027415071746523015564 0ustar00rgerrger/* This is a tool for processing rsyslog encrypted log files. * * Copyright 2013-2019 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either exprs or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "libcry_common.h" #ifdef ENABLE_LIBGCRYPT #include #include "libgcry.h" #endif #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER #include #include "libossl.h" #endif #ifdef ENABLE_LIBGCRYPT typedef struct { int cry_algo; int cry_mode; gcry_cipher_hd_t gcry_chd; } gcry_data; #endif #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER typedef struct { const EVP_CIPHER *cipher; EVP_CIPHER_CTX *chd; } ossl_data; #endif /* rscryutil related config parameters and internals */ typedef struct rscry_config { /* General parameters */ enum { MD_DECRYPT, MD_WRITE_KEYFILE } mode; int verbose; size_t blkLength; char *keyfile; char *keyprog; int randomKeyLen; char *key; unsigned keylen; int optionForce; /* Library specific parameters */ enum { LIB_GCRY, LIB_OSSL } lib; union { #ifdef ENABLE_LIBGCRYPT gcry_data gcry; #endif #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER ossl_data ossl; #endif } libData; } rscry_config; rscry_config cnf; static int initConfig(const char *name) { cnf.mode = MD_DECRYPT; cnf.lib = LIB_GCRY; cnf.verbose = 0; cnf.blkLength = 0; cnf.keyfile = NULL; cnf.keyprog = NULL; cnf.randomKeyLen = -1; cnf.key = NULL; cnf.keylen = 0; cnf.optionForce = 0; /* If no library is set, we are using the default value. gcry must be the last so it remains backwards compatible. */ if (name == NULL) { #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER name = "ossl"; #endif #ifdef ENABLE_LIBGCRYPT name = "gcry"; #endif } if (name && strcmp(name, "gcry") == 0) { /* Use the libgcrypt lib */ #ifdef ENABLE_LIBGCRYPT cnf.lib = LIB_GCRY; cnf.libData.gcry.cry_algo = GCRY_CIPHER_AES128; cnf.libData.gcry.cry_mode = GCRY_CIPHER_MODE_CBC; cnf.libData.gcry.gcry_chd = NULL; #else fprintf(stderr, "rsyslog was not compiled with libgcrypt support.\n"); return 1; #endif } else if (name && strcmp(name, "ossl") == 0) { /* Use the openssl lib */ #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER cnf.lib = LIB_OSSL; cnf.libData.ossl.cipher = EVP_aes_128_cbc(); cnf.libData.ossl.chd = NULL; #else fprintf(stderr, "rsyslog was not compiled with libossl support.\n"); return 1; #endif } else { fprintf(stderr, "invalid option for lib: %s\n", name); return 1; } return 0; } /* We use some common code which expects rsyslog runtime to be * present, most importantly for debug output. As a stand-alone * tool, we do not really have this. So we do some dummy defines * in order to satisfy the needs of the common code. */ int Debug = 0; #ifndef DEBUGLESS void r_dbgprintf(const char *srcname __attribute__((unused)), const char *fmt __attribute__((unused)), ...) {}; #endif void srSleep(int a __attribute__((unused)), int b __attribute__((unused))); /* prototype (avoid compiler warning) */ void srSleep(int a __attribute__((unused)), int b __attribute__((unused))) {} /* this is not really needed by any of our code */ long randomNumber(void); /* prototype (avoid compiler warning) */ long randomNumber(void) { return 0l; } /* this is not really needed by any of our code */ /* rectype/value must be EIF_MAX_*_LEN+1 long! * returns 0 on success or something else on error/EOF */ static int eiGetRecord(FILE *eifp, char *rectype, char *value) { int r; unsigned short i, j; char buf[EIF_MAX_RECTYPE_LEN + EIF_MAX_VALUE_LEN + 128]; /* large enough for any valid record */ if (fgets(buf, sizeof(buf), eifp) == NULL) { r = 1; goto done; } for (i = 0; i < EIF_MAX_RECTYPE_LEN && buf[i] != ':'; ++i) if (buf[i] == '\0') { r = 2; goto done; } else rectype[i] = buf[i]; rectype[i] = '\0'; j = 0; for (++i; i < EIF_MAX_VALUE_LEN && buf[i] != '\n'; ++i, ++j) if (buf[i] == '\0') { r = 3; goto done; } else value[j] = buf[i]; value[j] = '\0'; r = 0; done: return r; } static int eiCheckFiletype(FILE *eifp) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; int r; if ((r = eiGetRecord(eifp, rectype, value)) != 0) goto done; if (strcmp(rectype, "FILETYPE") || strcmp(value, RSGCRY_FILETYPE_NAME)) { fprintf(stderr, "invalid filetype \"cookie\" in encryption " "info file\n"); fprintf(stderr, "\trectype: '%s', value: '%s'\n", rectype, value); r = 1; goto done; } r = 0; done: return r; } static int eiGetIV(FILE *eifp, char *iv, size_t leniv) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; size_t valueLen; unsigned short i, j; int r; unsigned char nibble; if ((r = eiGetRecord(eifp, rectype, value)) != 0) goto done; if (strcmp(rectype, "IV")) { fprintf(stderr, "no IV record found when expected, record type " "seen is '%s'\n", rectype); r = 1; goto done; } valueLen = strlen(value); if (valueLen / 2 != leniv) { fprintf(stderr, "length of IV is %lld, expected %lld\n", (long long)valueLen / 2, (long long)leniv); r = 1; goto done; } for (i = j = 0; i < valueLen; ++i) { if (value[i] >= '0' && value[i] <= '9') nibble = value[i] - '0'; else if (value[i] >= 'a' && value[i] <= 'f') nibble = value[i] - 'a' + 10; else { fprintf(stderr, "invalid IV '%s'\n", value); r = 1; goto done; } if (i % 2 == 0) iv[j] = nibble << 4; else iv[j++] |= nibble; } r = 0; done: return r; } static int eiGetEND(FILE *eifp, off64_t *offs) { char rectype[EIF_MAX_RECTYPE_LEN + 1] = ""; char value[EIF_MAX_VALUE_LEN + 1]; int r; if ((r = eiGetRecord(eifp, rectype, value)) != 0) goto done; if (strcmp(rectype, "END")) { fprintf(stderr, "no END record found when expected, record type " "seen is '%s'\n", rectype); r = 1; goto done; } *offs = atoll(value); r = 0; done: return r; } /* LIBGCRYPT RELATED STARTS */ #ifdef ENABLE_LIBGCRYPT static int gcryInit(FILE *eifp) { int r = 0; gcry_error_t gcryError; char iv[4096]; cnf.blkLength = gcry_cipher_get_algo_blklen(cnf.libData.gcry.cry_algo); // EVP_CIPHER_CTX_get_block_size if (cnf.blkLength > sizeof(iv)) { fprintf(stderr, "internal error[%s:%d]: block length %lld too large for " "iv buffer\n", __FILE__, __LINE__, (long long)cnf.blkLength); r = 1; goto done; } if ((r = eiGetIV(eifp, iv, cnf.blkLength)) != 0) goto done; size_t keyLength = gcry_cipher_get_algo_keylen(cnf.libData.gcry.cry_algo); // EVP_CIPHER_get_key_length assert(cnf.key != NULL); /* "fix" clang 10 static analyzer false positive */ if (strlen(cnf.key) != keyLength) { fprintf(stderr, "invalid key length; key is %u characters, but " "exactly %llu characters are required\n", cnf.keylen, (long long unsigned)keyLength); r = 1; goto done; } gcryError = gcry_cipher_open(&cnf.libData.gcry.gcry_chd, cnf.libData.gcry.cry_algo, cnf.libData.gcry.cry_mode, 0); if (gcryError) { fprintf(stderr, "gcry_cipher_open failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } gcryError = gcry_cipher_setkey(cnf.libData.gcry.gcry_chd, cnf.key, keyLength); if (gcryError) { fprintf(stderr, "gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } gcryError = gcry_cipher_setiv(cnf.libData.gcry.gcry_chd, iv, cnf.blkLength); if (gcryError) { fprintf(stderr, "gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); r = 1; goto done; } done: return r; } static void removePadding(char *buf, size_t *plen) { unsigned len = (unsigned)*plen; unsigned iSrc, iDst; char *frstNUL; frstNUL = memchr(buf, 0x00, *plen); if (frstNUL == NULL) goto done; iDst = iSrc = frstNUL - buf; while (iSrc < len) { if (buf[iSrc] != 0x00) buf[iDst++] = buf[iSrc]; ++iSrc; } *plen = iDst; done: return; } static void gcryDecryptBlock(FILE *fpin, FILE *fpout, off64_t blkEnd, off64_t *pCurrOffs) { gcry_error_t gcryError; size_t nRead, nWritten; size_t toRead; size_t leftTillBlkEnd; char buf[64 * 1024]; leftTillBlkEnd = blkEnd - *pCurrOffs; while (1) { toRead = sizeof(buf) <= leftTillBlkEnd ? sizeof(buf) : leftTillBlkEnd; toRead = toRead - toRead % cnf.blkLength; nRead = fread(buf, 1, toRead, fpin); if (nRead == 0) break; leftTillBlkEnd -= nRead, *pCurrOffs += nRead; gcryError = gcry_cipher_decrypt(cnf.libData.gcry.gcry_chd, // gcry_cipher_hd_t buf, // void * nRead, // size_t NULL, // const void * 0); // size_t if (gcryError) { fprintf(stderr, "gcry_cipher_decrypt failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); return; } removePadding(buf, &nRead); nWritten = fwrite(buf, 1, nRead, fpout); if (nWritten != nRead) { perror("fpout"); return; } } } static int gcryDoDecrypt(FILE *logfp, FILE *eifp, FILE *outfp) { off64_t blkEnd; off64_t currOffs = 0; int r = 1; int fd; struct stat buf; while (1) { /* process block */ if (gcryInit(eifp) != 0) goto done; /* set blkEnd to size of logfp and proceed. */ if ((fd = fileno(logfp)) == -1) { r = -1; goto done; } if ((r = fstat(fd, &buf)) != 0) goto done; blkEnd = buf.st_size; r = eiGetEND(eifp, &blkEnd); if (r != 0 && r != 1) goto done; gcryDecryptBlock(logfp, outfp, blkEnd, &currOffs); gcry_cipher_close(cnf.libData.gcry.gcry_chd); } r = 0; done: return r; } #else // Dummy function definitions static int gcryDoDecrypt(FILE __attribute__((unused)) * logfp, FILE __attribute__((unused)) * eifp, FILE __attribute__((unused)) * outfp) { return 0; } static int rsgcryAlgoname2Algo(char *const __attribute__((unused)) algoname) { return 0; } static int rsgcryModename2Mode(char *const __attribute__((unused)) modename) { return 0; } #endif /* LIBGCRYPT RELATED ENDS */ #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER static int osslInit(FILE *eifp) { int r = 0; char iv[4096]; size_t keyLength; if ((cnf.libData.ossl.chd = EVP_CIPHER_CTX_new()) == NULL) { fprintf(stderr, "internal error[%s:%d]: EVP_CIPHER_CTX_new failed\n", __FILE__, __LINE__); r = 1; goto done; } cnf.blkLength = EVP_CIPHER_get_block_size(cnf.libData.ossl.cipher); if (cnf.blkLength > sizeof(iv)) { fprintf(stderr, "internal error[%s:%d]: block length %lld too large for " "iv buffer\n", __FILE__, __LINE__, (long long)cnf.blkLength); r = 1; goto done; } if ((r = eiGetIV(eifp, iv, cnf.blkLength)) != 0) goto done; keyLength = EVP_CIPHER_get_key_length(cnf.libData.ossl.cipher); assert(cnf.key != NULL); /* "fix" clang 10 static analyzer false positive */ if (strlen(cnf.key) != keyLength) { fprintf(stderr, "invalid key length; key is %u characters, but " "exactly %llu characters are required\n", cnf.keylen, (long long unsigned)keyLength); r = 1; goto done; } if ((r = EVP_DecryptInit_ex(cnf.libData.ossl.chd, cnf.libData.ossl.cipher, NULL, (uchar *)cnf.key, (uchar *)iv)) != 1) { fprintf(stderr, "EVP_DecryptInit_ex failed: %d\n", r); goto done; } if ((r = EVP_CIPHER_CTX_set_padding(cnf.libData.ossl.chd, 0)) != 1) { fprintf(stderr, "EVP_CIPHER_set_padding failed: %d\n", r); goto done; } r = 0; done: return r; } static void osslDecryptBlock(FILE *fpin, FILE *fpout, off64_t blkEnd, off64_t *pCurrOffs) { size_t nRead, nWritten; size_t toRead; size_t leftTillBlkEnd; uchar buf[64 * 1024]; uchar outbuf[64 * 1024]; int r, tmplen, outlen; leftTillBlkEnd = blkEnd - *pCurrOffs; while (1) { toRead = sizeof(buf) <= leftTillBlkEnd ? sizeof(buf) : leftTillBlkEnd; toRead = toRead - toRead % cnf.blkLength; nRead = fread(buf, 1, toRead, fpin); if (nRead == 0) break; leftTillBlkEnd -= nRead, *pCurrOffs += nRead; r = EVP_DecryptUpdate(cnf.libData.ossl.chd, outbuf, &tmplen, buf, nRead); if (r != 1) { fprintf(stderr, "EVP_DecryptUpdate failed: %d\n", r); return; } outlen = tmplen; nWritten = fwrite(outbuf, sizeof(unsigned char), (size_t)outlen, fpout); if (nWritten != (size_t)outlen) { perror("fpout"); return; } } r = EVP_DecryptFinal_ex(cnf.libData.ossl.chd, outbuf + tmplen, &tmplen); if (r != 1) { fprintf(stderr, "EVP_DecryptFinal_ex failed: %d\n", r); return; } outlen += tmplen; } static int osslDoDecrypt(FILE *logfp, FILE *eifp, FILE *outfp) { off64_t blkEnd; off64_t currOffs = 0; int r = 1; int fd; struct stat buf; while (1) { /* process block */ if (osslInit(eifp) != 0) goto done; /* set blkEnd to size of logfp and proceed. */ if ((fd = fileno(logfp)) == -1) { r = -1; goto done; } if ((r = fstat(fd, &buf)) != 0) goto done; blkEnd = buf.st_size; r = eiGetEND(eifp, &blkEnd); if (r != 0 && r != 1) goto done; osslDecryptBlock(logfp, outfp, blkEnd, &currOffs); EVP_CIPHER_CTX_free(cnf.libData.ossl.chd); } r = 0; done: return r; } #else // Dummy function definitions static int osslDoDecrypt(FILE __attribute__((unused)) * logfp, FILE __attribute__((unused)) * eifp, FILE __attribute__((unused)) * outfp) { return 0; } #endif static void decrypt(const char *name) { FILE *logfp = NULL, *eifp = NULL; int r = 0; char eifname[4096]; if (!strcmp(name, "-")) { fprintf(stderr, "decrypt mode cannot work on stdin\n"); goto err; } else { if ((logfp = fopen(name, "r")) == NULL) { perror(name); goto err; } snprintf(eifname, sizeof(eifname), "%s%s", name, ENCINFO_SUFFIX); eifname[sizeof(eifname) - 1] = '\0'; if ((eifp = fopen(eifname, "r")) == NULL) { perror(eifname); goto err; } if (eiCheckFiletype(eifp) != 0) goto err; } if (cnf.lib == LIB_GCRY) { if ((r = gcryDoDecrypt(logfp, eifp, stdout)) != 0) goto err; } else if (cnf.lib == LIB_OSSL) { if ((r = osslDoDecrypt(logfp, eifp, stdout)) != 0) goto err; } fclose(logfp); logfp = NULL; fclose(eifp); eifp = NULL; return; err: fprintf(stderr, "error %d processing file %s\n", r, name); if (eifp != NULL) fclose(eifp); if (logfp != NULL) fclose(logfp); } static void write_keyfile(char *fn) { int fd; int r; mode_t fmode; fmode = O_WRONLY | O_CREAT; if (!cnf.optionForce) fmode |= O_EXCL; if (fn == NULL) { fprintf(stderr, "program error: keyfile is NULL"); exit(1); } if ((fd = open(fn, fmode, S_IRUSR)) == -1) { fprintf(stderr, "error opening keyfile "); perror(fn); exit(1); } if ((r = write(fd, cnf.key, cnf.keylen)) != (ssize_t)cnf.keylen) { fprintf(stderr, "error writing keyfile (ret=%d) ", r); perror(fn); exit(1); } close(fd); } static void getKeyFromFile(const char *fn) { const int r = cryGetKeyFromFile(fn, &cnf.key, &cnf.keylen); if (r != 0) { perror(fn); exit(1); } } static void getRandomKey(void) { int fd; cnf.keylen = cnf.randomKeyLen; cnf.key = malloc(cnf.randomKeyLen); /* do NOT zero-out! */ /* if we cannot obtain data from /dev/urandom, we use whatever * is present at the current memory location as random data. Of * course, this is very weak and we should consider a different * option, especially when not running under Linux (for Linux, * unavailability of /dev/urandom is just a theoretic thing, it * will always work...). -- TODO -- rgerhards, 2013-03-06 */ if ((fd = open("/dev/urandom", O_RDONLY)) >= 0) { if (read(fd, cnf.key, cnf.randomKeyLen) != cnf.randomKeyLen) { fprintf(stderr, "warning: could not read sufficient data " "from /dev/urandom - key may be weak\n"); }; close(fd); } } static void setKey(void) { if (cnf.randomKeyLen != -1) getRandomKey(); else if (cnf.keyfile != NULL) getKeyFromFile(cnf.keyfile); else if (cnf.keyprog != NULL) cryGetKeyFromProg(cnf.keyprog, &cnf.key, &cnf.keylen); if (cnf.key == NULL) { fprintf(stderr, "ERROR: key must be set via some method\n"); exit(1); } } /* Retrieve algorithm and mode from the choosen library. In libgcrypt, this is done in two steps (AES128 + CBC). However, other libraries expect this to be expressed in a single step, e.g. AES-128-CBC in openssl */ static void setAlgoMode(char *algo, char *mode) { if (cnf.lib == LIB_GCRY) { /* Set algorithm and mode for gcrypt */ #ifdef ENABLE_LIBGCRYPT if (algo != NULL) { cnf.libData.gcry.cry_algo = rsgcryAlgoname2Algo(algo); if (cnf.libData.gcry.cry_algo == GCRY_CIPHER_NONE) { fprintf(stderr, "ERROR: algorithm \"%s\" is not " "known/supported\n", algo); exit(1); } } if (mode != NULL) { cnf.libData.gcry.cry_mode = rsgcryModename2Mode(mode); if (cnf.libData.gcry.cry_mode == GCRY_CIPHER_MODE_NONE) { fprintf(stderr, "ERROR: cipher mode \"%s\" is not " "known/supported\n", mode); exit(1); } } #endif } else if (cnf.lib == LIB_OSSL) { #ifdef ENABLE_OPENSSL_CRYPTO_PROVIDER if (algo != NULL) { cnf.libData.ossl.cipher = EVP_CIPHER_fetch(NULL, algo, NULL); if (cnf.libData.ossl.cipher == NULL) { fprintf(stderr, "ERROR: cipher \"%s\" is not " "known/supported\n", algo); exit(1); } } #endif } } static struct option long_options[] = {{"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"decrypt", no_argument, NULL, 'd'}, {"force", no_argument, NULL, 'f'}, {"write-keyfile", required_argument, NULL, 'W'}, {"key", required_argument, NULL, 'K'}, {"generate-random-key", required_argument, NULL, 'r'}, {"keyfile", required_argument, NULL, 'k'}, {"key-program", required_argument, NULL, 'p'}, {"algo", required_argument, NULL, 'a'}, {"mode", required_argument, NULL, 'm'}, {"lib", required_argument, NULL, 'l'}, {NULL, 0, NULL, 0}}; static const char *short_options = "a:dfk:K:m:p:r:vVW:l:"; int main(int argc, char *argv[]) { int opt; char *newKeyFile = NULL; char *lib = NULL; char *algo = NULL, *mode = NULL; /* We need preprocessing to determine, which crypto library is going to be used */ while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1 && lib == NULL) { switch (opt) { case 'l': lib = optarg; break; default: break; } } /* Once we reach this point, we have library specific internals set */ if (initConfig(lib)) exit(1); optind = 1; while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (opt) { case 'd': cnf.mode = MD_DECRYPT; break; case 'W': cnf.mode = MD_WRITE_KEYFILE; newKeyFile = optarg; break; case 'k': cnf.keyfile = optarg; break; case 'p': cnf.keyprog = optarg; break; case 'f': cnf.optionForce = 1; break; case 'r': cnf.randomKeyLen = atoi(optarg); if (cnf.randomKeyLen > 64 * 1024) { fprintf(stderr, "ERROR: keys larger than 64KiB are " "not supported\n"); exit(1); } break; case 'K': fprintf(stderr, "WARNING: specifying the actual key " "via the command line is highly insecure\n" "Do NOT use this for PRODUCTION use.\n"); cnf.key = optarg; cnf.keylen = strlen(cnf.key); break; case 'a': algo = optarg; break; case 'm': mode = optarg; break; case 'v': cnf.verbose = 1; break; case 'V': fprintf(stderr, "rscryutil " VERSION "\n"); exit(0); break; case 'l': break; case '?': break; default: fprintf(stderr, "getopt_long() returns unknown value %d\n", opt); return 1; } } setKey(); setAlgoMode(algo, mode); assert(cnf.key != NULL); if (cnf.mode == MD_WRITE_KEYFILE) { if (optind != argc) { fprintf(stderr, "ERROR: no file parameters permitted in " "--write-keyfile mode\n"); exit(1); } write_keyfile(newKeyFile); } else { if (optind == argc) decrypt("-"); else { for (int i = optind; i < argc; ++i) decrypt(argv[i]); } } assert(cnf.key != NULL); memset(cnf.key, 0, cnf.keylen); /* zero-out key store */ cnf.keylen = 0; return 0; } rsyslog-8.2512.0/tools/PaxHeaders/Makefile.in0000644000000000000000000000013115114544320015734 xustar0030 mtime=1764935888.497045398 30 atime=1764935894.304134347 29 ctime=1764935924.10059062 rsyslog-8.2512.0/tools/Makefile.in0000664000175000017500000022450715114544320015413 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = rsyslogd$(EXEEXT) $(am__EXEEXT_3) bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_1 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_2 = $(LIBLOGGING_STDLOG_LIBS) @ENABLE_DIAGTOOLS_TRUE@am__append_3 = rsyslog_diag_hostname msggen @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_4 = logctl @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_5 = rscryutil @ENABLE_LIBGCRYPT_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_6 = $(LIBGCRYPT_CFLAGS) @ENABLE_LIBGCRYPT_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_7 = ../runtime/libgcry.la $(LIBGCRYPT_LIBS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_8 = $(OPENSSL_CFLAGS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_9 = ../runtime/libossl.la $(OPENSSL_LIBS) @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_10 = rscryutil.1 @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_11 = rscryutil.1 @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__append_12 = rscryutil.1 subdir = tools ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@am__EXEEXT_1 = \ @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@ logctl$(EXEEXT) @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__EXEEXT_2 = rscryutil$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man8dir)" @ENABLE_DIAGTOOLS_TRUE@am__EXEEXT_3 = rsyslog_diag_hostname$(EXEEXT) \ @ENABLE_DIAGTOOLS_TRUE@ msggen$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) am__logctl_SOURCES_DIST = logctl.c @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@am_logctl_OBJECTS = logctl-logctl.$(OBJEXT) logctl_OBJECTS = $(am_logctl_OBJECTS) am__DEPENDENCIES_1 = @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@logctl_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am__msggen_SOURCES_DIST = msggen.c @ENABLE_DIAGTOOLS_TRUE@am_msggen_OBJECTS = msggen.$(OBJEXT) msggen_OBJECTS = $(am_msggen_OBJECTS) msggen_LDADD = $(LDADD) rscryutil_SOURCES = rscryutil.c rscryutil_OBJECTS = rscryutil-rscryutil.$(OBJEXT) @ENABLE_LIBGCRYPT_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__DEPENDENCIES_2 = ../runtime/libgcry.la \ @ENABLE_LIBGCRYPT_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__DEPENDENCIES_1) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@am__DEPENDENCIES_3 = ../runtime/libossl.la \ @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__DEPENDENCIES_1) @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil_DEPENDENCIES = $(am__DEPENDENCIES_2) \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__DEPENDENCIES_3) rscryutil_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rscryutil_LDFLAGS) $(LDFLAGS) -o $@ am__rsyslog_diag_hostname_SOURCES_DIST = gethostn.c @ENABLE_DIAGTOOLS_TRUE@am_rsyslog_diag_hostname_OBJECTS = \ @ENABLE_DIAGTOOLS_TRUE@ gethostn.$(OBJEXT) rsyslog_diag_hostname_OBJECTS = $(am_rsyslog_diag_hostname_OBJECTS) rsyslog_diag_hostname_LDADD = $(LDADD) am_rsyslogd_OBJECTS = rsyslogd-syslogd.$(OBJEXT) \ rsyslogd-rsyslogd.$(OBJEXT) rsyslogd-omshell.$(OBJEXT) \ rsyslogd-omusrmsg.$(OBJEXT) rsyslogd-omfwd.$(OBJEXT) \ rsyslogd-omfile.$(OBJEXT) rsyslogd-ompipe.$(OBJEXT) \ rsyslogd-omdiscard.$(OBJEXT) rsyslogd-pmrfc5424.$(OBJEXT) \ rsyslogd-pmrfc3164.$(OBJEXT) rsyslogd-smtradfile.$(OBJEXT) \ rsyslogd-smfile.$(OBJEXT) rsyslogd-smfwd.$(OBJEXT) \ rsyslogd-smtradfwd.$(OBJEXT) rsyslogd-iminternal.$(OBJEXT) rsyslogd_OBJECTS = $(am_rsyslogd_OBJECTS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__DEPENDENCIES_4 = \ @ENABLE_LIBLOGGING_STDLOG_TRUE@ $(am__DEPENDENCIES_1) rsyslogd_DEPENDENCIES = ../grammar/libgrammar.la \ ../runtime/librsyslog.la ../compat/compat.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_4) rsyslogd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(rsyslogd_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gethostn.Po \ ./$(DEPDIR)/logctl-logctl.Po ./$(DEPDIR)/msggen.Po \ ./$(DEPDIR)/rscryutil-rscryutil.Po \ ./$(DEPDIR)/rsyslogd-iminternal.Po \ ./$(DEPDIR)/rsyslogd-omdiscard.Po \ ./$(DEPDIR)/rsyslogd-omfile.Po ./$(DEPDIR)/rsyslogd-omfwd.Po \ ./$(DEPDIR)/rsyslogd-ompipe.Po ./$(DEPDIR)/rsyslogd-omshell.Po \ ./$(DEPDIR)/rsyslogd-omusrmsg.Po \ ./$(DEPDIR)/rsyslogd-pmrfc3164.Po \ ./$(DEPDIR)/rsyslogd-pmrfc5424.Po \ ./$(DEPDIR)/rsyslogd-rsyslogd.Po \ ./$(DEPDIR)/rsyslogd-smfile.Po ./$(DEPDIR)/rsyslogd-smfwd.Po \ ./$(DEPDIR)/rsyslogd-smtradfile.Po \ ./$(DEPDIR)/rsyslogd-smtradfwd.Po \ ./$(DEPDIR)/rsyslogd-syslogd.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(logctl_SOURCES) $(msggen_SOURCES) rscryutil.c \ $(rsyslog_diag_hostname_SOURCES) $(rsyslogd_SOURCES) DIST_SOURCES = $(am__logctl_SOURCES_DIST) $(am__msggen_SOURCES_DIST) \ rscryutil.c $(am__rsyslog_diag_hostname_SOURCES_DIST) \ $(rsyslogd_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man1_MANS) $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = $(am__append_11) man1_MANS = $(am__append_10) man_MANS = rsyslogd.8 rsyslog.conf.5 rsyslogd_SOURCES = \ syslogd.c \ rsyslogd.c \ syslogd.h \ omshell.c \ omshell.h \ omusrmsg.c \ omusrmsg.h \ omfwd.c \ omfwd.h \ omfile.c \ omfile.h \ ompipe.c \ ompipe.h \ omdiscard.c \ omdiscard.h \ pmrfc5424.c \ pmrfc5424.h \ pmrfc3164.c \ pmrfc3164.h \ smtradfile.c \ smtradfile.h \ smfile.c \ smfile.h \ smfwd.c \ smfwd.h \ smtradfwd.c \ smtradfwd.h \ iminternal.c \ iminternal.h \ \ ../dirty.h rsyslogd_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(am__append_1) \ -DSD_EXPORT_SYMBOLS # note: it looks like librsyslog.la must be explicitely given on LDDADD, # otherwise dependencies are not properly calculated (resulting in a # potentially incomplete build, a problem we had several times...) rsyslogd_LDADD = ../grammar/libgrammar.la ../runtime/librsyslog.la \ ../compat/compat.la $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) \ $(SOL_LIBS) $(LIBUUID_LIBS) $(HASH_XXHASH_LIBS) \ $(am__append_2) @OS_AIX_FALSE@@OS_APPLE_FALSE@@OS_LINUX_FALSE@rsyslogd_LDFLAGS = -export-dynamic @OS_AIX_TRUE@@OS_APPLE_FALSE@@OS_LINUX_FALSE@rsyslogd_LDFLAGS = -brtl -bexpall -f"aix_exports_list" -lsrc @OS_APPLE_TRUE@@OS_LINUX_FALSE@rsyslogd_LDFLAGS = -export-dynamic \ @OS_APPLE_TRUE@@OS_LINUX_FALSE@ -Wl,$(top_builddir)/runtime/.libs/librsyslog.a # Note: do NOT indent the if chain - it will not work! @OS_LINUX_TRUE@rsyslogd_LDFLAGS = -export-dynamic \ @OS_LINUX_TRUE@ #-Wl,--whole-archive,$(top_builddir)/runtime/.libs/librsyslog.a,--no-whole-archive @OS_AIX_FALSE@@OS_APPLE_FALSE@@OS_LINUX_FALSE@exports_list_file = @OS_AIX_TRUE@@OS_APPLE_FALSE@@OS_LINUX_FALSE@exports_list_file = aix_exports_list @OS_APPLE_TRUE@@OS_LINUX_FALSE@exports_list_file = @OS_LINUX_TRUE@exports_list_file = EXTRA_DIST = $(man_MANS) rscryutil.rst recover_qi.pl $(am__append_12) EXTRA_rsyslogd_DEPENDENCIES = $(exports_list_file) @ENABLE_DIAGTOOLS_TRUE@rsyslog_diag_hostname_SOURCES = gethostn.c @ENABLE_DIAGTOOLS_TRUE@msggen_SOURCES = msggen.c @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@logctl_SOURCES = logctl.c @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@logctl_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(LIBMONGOC_CFLAGS) @ENABLE_OMMONGODB_TRUE@@ENABLE_USERTOOLS_TRUE@logctl_LDADD = $(LIBMONGOC_LIBS) @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil = rscryutil.c @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil_CPPFLAGS = \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ -I../runtime \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(RSRT_CFLAGS) \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__append_6) \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__append_8) @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil_LDADD = \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__append_7) \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(am__append_9) @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil_LDFLAGS = \ @ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@-Wl,--whole-archive,--no-whole-archive @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@RSTMANFILE = rscryutil.rst all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tools/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list logctl$(EXEEXT): $(logctl_OBJECTS) $(logctl_DEPENDENCIES) $(EXTRA_logctl_DEPENDENCIES) @rm -f logctl$(EXEEXT) $(AM_V_CCLD)$(LINK) $(logctl_OBJECTS) $(logctl_LDADD) $(LIBS) msggen$(EXEEXT): $(msggen_OBJECTS) $(msggen_DEPENDENCIES) $(EXTRA_msggen_DEPENDENCIES) @rm -f msggen$(EXEEXT) $(AM_V_CCLD)$(LINK) $(msggen_OBJECTS) $(msggen_LDADD) $(LIBS) rscryutil$(EXEEXT): $(rscryutil_OBJECTS) $(rscryutil_DEPENDENCIES) $(EXTRA_rscryutil_DEPENDENCIES) @rm -f rscryutil$(EXEEXT) $(AM_V_CCLD)$(rscryutil_LINK) $(rscryutil_OBJECTS) $(rscryutil_LDADD) $(LIBS) rsyslog_diag_hostname$(EXEEXT): $(rsyslog_diag_hostname_OBJECTS) $(rsyslog_diag_hostname_DEPENDENCIES) $(EXTRA_rsyslog_diag_hostname_DEPENDENCIES) @rm -f rsyslog_diag_hostname$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rsyslog_diag_hostname_OBJECTS) $(rsyslog_diag_hostname_LDADD) $(LIBS) rsyslogd$(EXEEXT): $(rsyslogd_OBJECTS) $(rsyslogd_DEPENDENCIES) $(EXTRA_rsyslogd_DEPENDENCIES) @rm -f rsyslogd$(EXEEXT) $(AM_V_CCLD)$(rsyslogd_LINK) $(rsyslogd_OBJECTS) $(rsyslogd_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gethostn.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logctl-logctl.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msggen.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rscryutil-rscryutil.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-iminternal.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-omdiscard.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-omfile.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-omfwd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-ompipe.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-omshell.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-omusrmsg.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-pmrfc3164.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-pmrfc5424.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-rsyslogd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-smfile.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-smfwd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-smtradfile.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-smtradfwd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsyslogd-syslogd.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< logctl-logctl.o: logctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(logctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT logctl-logctl.o -MD -MP -MF $(DEPDIR)/logctl-logctl.Tpo -c -o logctl-logctl.o `test -f 'logctl.c' || echo '$(srcdir)/'`logctl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/logctl-logctl.Tpo $(DEPDIR)/logctl-logctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logctl.c' object='logctl-logctl.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(logctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o logctl-logctl.o `test -f 'logctl.c' || echo '$(srcdir)/'`logctl.c logctl-logctl.obj: logctl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(logctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT logctl-logctl.obj -MD -MP -MF $(DEPDIR)/logctl-logctl.Tpo -c -o logctl-logctl.obj `if test -f 'logctl.c'; then $(CYGPATH_W) 'logctl.c'; else $(CYGPATH_W) '$(srcdir)/logctl.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/logctl-logctl.Tpo $(DEPDIR)/logctl-logctl.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logctl.c' object='logctl-logctl.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(logctl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o logctl-logctl.obj `if test -f 'logctl.c'; then $(CYGPATH_W) 'logctl.c'; else $(CYGPATH_W) '$(srcdir)/logctl.c'; fi` rscryutil-rscryutil.o: rscryutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rscryutil_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rscryutil-rscryutil.o -MD -MP -MF $(DEPDIR)/rscryutil-rscryutil.Tpo -c -o rscryutil-rscryutil.o `test -f 'rscryutil.c' || echo '$(srcdir)/'`rscryutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rscryutil-rscryutil.Tpo $(DEPDIR)/rscryutil-rscryutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rscryutil.c' object='rscryutil-rscryutil.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rscryutil_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rscryutil-rscryutil.o `test -f 'rscryutil.c' || echo '$(srcdir)/'`rscryutil.c rscryutil-rscryutil.obj: rscryutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rscryutil_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rscryutil-rscryutil.obj -MD -MP -MF $(DEPDIR)/rscryutil-rscryutil.Tpo -c -o rscryutil-rscryutil.obj `if test -f 'rscryutil.c'; then $(CYGPATH_W) 'rscryutil.c'; else $(CYGPATH_W) '$(srcdir)/rscryutil.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rscryutil-rscryutil.Tpo $(DEPDIR)/rscryutil-rscryutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rscryutil.c' object='rscryutil-rscryutil.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rscryutil_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rscryutil-rscryutil.obj `if test -f 'rscryutil.c'; then $(CYGPATH_W) 'rscryutil.c'; else $(CYGPATH_W) '$(srcdir)/rscryutil.c'; fi` rsyslogd-syslogd.o: syslogd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-syslogd.o -MD -MP -MF $(DEPDIR)/rsyslogd-syslogd.Tpo -c -o rsyslogd-syslogd.o `test -f 'syslogd.c' || echo '$(srcdir)/'`syslogd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-syslogd.Tpo $(DEPDIR)/rsyslogd-syslogd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syslogd.c' object='rsyslogd-syslogd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-syslogd.o `test -f 'syslogd.c' || echo '$(srcdir)/'`syslogd.c rsyslogd-syslogd.obj: syslogd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-syslogd.obj -MD -MP -MF $(DEPDIR)/rsyslogd-syslogd.Tpo -c -o rsyslogd-syslogd.obj `if test -f 'syslogd.c'; then $(CYGPATH_W) 'syslogd.c'; else $(CYGPATH_W) '$(srcdir)/syslogd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-syslogd.Tpo $(DEPDIR)/rsyslogd-syslogd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='syslogd.c' object='rsyslogd-syslogd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-syslogd.obj `if test -f 'syslogd.c'; then $(CYGPATH_W) 'syslogd.c'; else $(CYGPATH_W) '$(srcdir)/syslogd.c'; fi` rsyslogd-rsyslogd.o: rsyslogd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-rsyslogd.o -MD -MP -MF $(DEPDIR)/rsyslogd-rsyslogd.Tpo -c -o rsyslogd-rsyslogd.o `test -f 'rsyslogd.c' || echo '$(srcdir)/'`rsyslogd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-rsyslogd.Tpo $(DEPDIR)/rsyslogd-rsyslogd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsyslogd.c' object='rsyslogd-rsyslogd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-rsyslogd.o `test -f 'rsyslogd.c' || echo '$(srcdir)/'`rsyslogd.c rsyslogd-rsyslogd.obj: rsyslogd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-rsyslogd.obj -MD -MP -MF $(DEPDIR)/rsyslogd-rsyslogd.Tpo -c -o rsyslogd-rsyslogd.obj `if test -f 'rsyslogd.c'; then $(CYGPATH_W) 'rsyslogd.c'; else $(CYGPATH_W) '$(srcdir)/rsyslogd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-rsyslogd.Tpo $(DEPDIR)/rsyslogd-rsyslogd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsyslogd.c' object='rsyslogd-rsyslogd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-rsyslogd.obj `if test -f 'rsyslogd.c'; then $(CYGPATH_W) 'rsyslogd.c'; else $(CYGPATH_W) '$(srcdir)/rsyslogd.c'; fi` rsyslogd-omshell.o: omshell.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omshell.o -MD -MP -MF $(DEPDIR)/rsyslogd-omshell.Tpo -c -o rsyslogd-omshell.o `test -f 'omshell.c' || echo '$(srcdir)/'`omshell.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omshell.Tpo $(DEPDIR)/rsyslogd-omshell.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omshell.c' object='rsyslogd-omshell.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omshell.o `test -f 'omshell.c' || echo '$(srcdir)/'`omshell.c rsyslogd-omshell.obj: omshell.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omshell.obj -MD -MP -MF $(DEPDIR)/rsyslogd-omshell.Tpo -c -o rsyslogd-omshell.obj `if test -f 'omshell.c'; then $(CYGPATH_W) 'omshell.c'; else $(CYGPATH_W) '$(srcdir)/omshell.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omshell.Tpo $(DEPDIR)/rsyslogd-omshell.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omshell.c' object='rsyslogd-omshell.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omshell.obj `if test -f 'omshell.c'; then $(CYGPATH_W) 'omshell.c'; else $(CYGPATH_W) '$(srcdir)/omshell.c'; fi` rsyslogd-omusrmsg.o: omusrmsg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omusrmsg.o -MD -MP -MF $(DEPDIR)/rsyslogd-omusrmsg.Tpo -c -o rsyslogd-omusrmsg.o `test -f 'omusrmsg.c' || echo '$(srcdir)/'`omusrmsg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omusrmsg.Tpo $(DEPDIR)/rsyslogd-omusrmsg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omusrmsg.c' object='rsyslogd-omusrmsg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omusrmsg.o `test -f 'omusrmsg.c' || echo '$(srcdir)/'`omusrmsg.c rsyslogd-omusrmsg.obj: omusrmsg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omusrmsg.obj -MD -MP -MF $(DEPDIR)/rsyslogd-omusrmsg.Tpo -c -o rsyslogd-omusrmsg.obj `if test -f 'omusrmsg.c'; then $(CYGPATH_W) 'omusrmsg.c'; else $(CYGPATH_W) '$(srcdir)/omusrmsg.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omusrmsg.Tpo $(DEPDIR)/rsyslogd-omusrmsg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omusrmsg.c' object='rsyslogd-omusrmsg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omusrmsg.obj `if test -f 'omusrmsg.c'; then $(CYGPATH_W) 'omusrmsg.c'; else $(CYGPATH_W) '$(srcdir)/omusrmsg.c'; fi` rsyslogd-omfwd.o: omfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omfwd.o -MD -MP -MF $(DEPDIR)/rsyslogd-omfwd.Tpo -c -o rsyslogd-omfwd.o `test -f 'omfwd.c' || echo '$(srcdir)/'`omfwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omfwd.Tpo $(DEPDIR)/rsyslogd-omfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfwd.c' object='rsyslogd-omfwd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omfwd.o `test -f 'omfwd.c' || echo '$(srcdir)/'`omfwd.c rsyslogd-omfwd.obj: omfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omfwd.obj -MD -MP -MF $(DEPDIR)/rsyslogd-omfwd.Tpo -c -o rsyslogd-omfwd.obj `if test -f 'omfwd.c'; then $(CYGPATH_W) 'omfwd.c'; else $(CYGPATH_W) '$(srcdir)/omfwd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omfwd.Tpo $(DEPDIR)/rsyslogd-omfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfwd.c' object='rsyslogd-omfwd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omfwd.obj `if test -f 'omfwd.c'; then $(CYGPATH_W) 'omfwd.c'; else $(CYGPATH_W) '$(srcdir)/omfwd.c'; fi` rsyslogd-omfile.o: omfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omfile.o -MD -MP -MF $(DEPDIR)/rsyslogd-omfile.Tpo -c -o rsyslogd-omfile.o `test -f 'omfile.c' || echo '$(srcdir)/'`omfile.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omfile.Tpo $(DEPDIR)/rsyslogd-omfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfile.c' object='rsyslogd-omfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omfile.o `test -f 'omfile.c' || echo '$(srcdir)/'`omfile.c rsyslogd-omfile.obj: omfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omfile.obj -MD -MP -MF $(DEPDIR)/rsyslogd-omfile.Tpo -c -o rsyslogd-omfile.obj `if test -f 'omfile.c'; then $(CYGPATH_W) 'omfile.c'; else $(CYGPATH_W) '$(srcdir)/omfile.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omfile.Tpo $(DEPDIR)/rsyslogd-omfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfile.c' object='rsyslogd-omfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omfile.obj `if test -f 'omfile.c'; then $(CYGPATH_W) 'omfile.c'; else $(CYGPATH_W) '$(srcdir)/omfile.c'; fi` rsyslogd-ompipe.o: ompipe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-ompipe.o -MD -MP -MF $(DEPDIR)/rsyslogd-ompipe.Tpo -c -o rsyslogd-ompipe.o `test -f 'ompipe.c' || echo '$(srcdir)/'`ompipe.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-ompipe.Tpo $(DEPDIR)/rsyslogd-ompipe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ompipe.c' object='rsyslogd-ompipe.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-ompipe.o `test -f 'ompipe.c' || echo '$(srcdir)/'`ompipe.c rsyslogd-ompipe.obj: ompipe.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-ompipe.obj -MD -MP -MF $(DEPDIR)/rsyslogd-ompipe.Tpo -c -o rsyslogd-ompipe.obj `if test -f 'ompipe.c'; then $(CYGPATH_W) 'ompipe.c'; else $(CYGPATH_W) '$(srcdir)/ompipe.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-ompipe.Tpo $(DEPDIR)/rsyslogd-ompipe.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ompipe.c' object='rsyslogd-ompipe.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-ompipe.obj `if test -f 'ompipe.c'; then $(CYGPATH_W) 'ompipe.c'; else $(CYGPATH_W) '$(srcdir)/ompipe.c'; fi` rsyslogd-omdiscard.o: omdiscard.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omdiscard.o -MD -MP -MF $(DEPDIR)/rsyslogd-omdiscard.Tpo -c -o rsyslogd-omdiscard.o `test -f 'omdiscard.c' || echo '$(srcdir)/'`omdiscard.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omdiscard.Tpo $(DEPDIR)/rsyslogd-omdiscard.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omdiscard.c' object='rsyslogd-omdiscard.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omdiscard.o `test -f 'omdiscard.c' || echo '$(srcdir)/'`omdiscard.c rsyslogd-omdiscard.obj: omdiscard.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-omdiscard.obj -MD -MP -MF $(DEPDIR)/rsyslogd-omdiscard.Tpo -c -o rsyslogd-omdiscard.obj `if test -f 'omdiscard.c'; then $(CYGPATH_W) 'omdiscard.c'; else $(CYGPATH_W) '$(srcdir)/omdiscard.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-omdiscard.Tpo $(DEPDIR)/rsyslogd-omdiscard.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omdiscard.c' object='rsyslogd-omdiscard.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-omdiscard.obj `if test -f 'omdiscard.c'; then $(CYGPATH_W) 'omdiscard.c'; else $(CYGPATH_W) '$(srcdir)/omdiscard.c'; fi` rsyslogd-pmrfc5424.o: pmrfc5424.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-pmrfc5424.o -MD -MP -MF $(DEPDIR)/rsyslogd-pmrfc5424.Tpo -c -o rsyslogd-pmrfc5424.o `test -f 'pmrfc5424.c' || echo '$(srcdir)/'`pmrfc5424.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-pmrfc5424.Tpo $(DEPDIR)/rsyslogd-pmrfc5424.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmrfc5424.c' object='rsyslogd-pmrfc5424.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-pmrfc5424.o `test -f 'pmrfc5424.c' || echo '$(srcdir)/'`pmrfc5424.c rsyslogd-pmrfc5424.obj: pmrfc5424.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-pmrfc5424.obj -MD -MP -MF $(DEPDIR)/rsyslogd-pmrfc5424.Tpo -c -o rsyslogd-pmrfc5424.obj `if test -f 'pmrfc5424.c'; then $(CYGPATH_W) 'pmrfc5424.c'; else $(CYGPATH_W) '$(srcdir)/pmrfc5424.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-pmrfc5424.Tpo $(DEPDIR)/rsyslogd-pmrfc5424.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmrfc5424.c' object='rsyslogd-pmrfc5424.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-pmrfc5424.obj `if test -f 'pmrfc5424.c'; then $(CYGPATH_W) 'pmrfc5424.c'; else $(CYGPATH_W) '$(srcdir)/pmrfc5424.c'; fi` rsyslogd-pmrfc3164.o: pmrfc3164.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-pmrfc3164.o -MD -MP -MF $(DEPDIR)/rsyslogd-pmrfc3164.Tpo -c -o rsyslogd-pmrfc3164.o `test -f 'pmrfc3164.c' || echo '$(srcdir)/'`pmrfc3164.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-pmrfc3164.Tpo $(DEPDIR)/rsyslogd-pmrfc3164.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmrfc3164.c' object='rsyslogd-pmrfc3164.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-pmrfc3164.o `test -f 'pmrfc3164.c' || echo '$(srcdir)/'`pmrfc3164.c rsyslogd-pmrfc3164.obj: pmrfc3164.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-pmrfc3164.obj -MD -MP -MF $(DEPDIR)/rsyslogd-pmrfc3164.Tpo -c -o rsyslogd-pmrfc3164.obj `if test -f 'pmrfc3164.c'; then $(CYGPATH_W) 'pmrfc3164.c'; else $(CYGPATH_W) '$(srcdir)/pmrfc3164.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-pmrfc3164.Tpo $(DEPDIR)/rsyslogd-pmrfc3164.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmrfc3164.c' object='rsyslogd-pmrfc3164.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-pmrfc3164.obj `if test -f 'pmrfc3164.c'; then $(CYGPATH_W) 'pmrfc3164.c'; else $(CYGPATH_W) '$(srcdir)/pmrfc3164.c'; fi` rsyslogd-smtradfile.o: smtradfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smtradfile.o -MD -MP -MF $(DEPDIR)/rsyslogd-smtradfile.Tpo -c -o rsyslogd-smtradfile.o `test -f 'smtradfile.c' || echo '$(srcdir)/'`smtradfile.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smtradfile.Tpo $(DEPDIR)/rsyslogd-smtradfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtradfile.c' object='rsyslogd-smtradfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smtradfile.o `test -f 'smtradfile.c' || echo '$(srcdir)/'`smtradfile.c rsyslogd-smtradfile.obj: smtradfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smtradfile.obj -MD -MP -MF $(DEPDIR)/rsyslogd-smtradfile.Tpo -c -o rsyslogd-smtradfile.obj `if test -f 'smtradfile.c'; then $(CYGPATH_W) 'smtradfile.c'; else $(CYGPATH_W) '$(srcdir)/smtradfile.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smtradfile.Tpo $(DEPDIR)/rsyslogd-smtradfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtradfile.c' object='rsyslogd-smtradfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smtradfile.obj `if test -f 'smtradfile.c'; then $(CYGPATH_W) 'smtradfile.c'; else $(CYGPATH_W) '$(srcdir)/smtradfile.c'; fi` rsyslogd-smfile.o: smfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smfile.o -MD -MP -MF $(DEPDIR)/rsyslogd-smfile.Tpo -c -o rsyslogd-smfile.o `test -f 'smfile.c' || echo '$(srcdir)/'`smfile.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smfile.Tpo $(DEPDIR)/rsyslogd-smfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smfile.c' object='rsyslogd-smfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smfile.o `test -f 'smfile.c' || echo '$(srcdir)/'`smfile.c rsyslogd-smfile.obj: smfile.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smfile.obj -MD -MP -MF $(DEPDIR)/rsyslogd-smfile.Tpo -c -o rsyslogd-smfile.obj `if test -f 'smfile.c'; then $(CYGPATH_W) 'smfile.c'; else $(CYGPATH_W) '$(srcdir)/smfile.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smfile.Tpo $(DEPDIR)/rsyslogd-smfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smfile.c' object='rsyslogd-smfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smfile.obj `if test -f 'smfile.c'; then $(CYGPATH_W) 'smfile.c'; else $(CYGPATH_W) '$(srcdir)/smfile.c'; fi` rsyslogd-smfwd.o: smfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smfwd.o -MD -MP -MF $(DEPDIR)/rsyslogd-smfwd.Tpo -c -o rsyslogd-smfwd.o `test -f 'smfwd.c' || echo '$(srcdir)/'`smfwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smfwd.Tpo $(DEPDIR)/rsyslogd-smfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smfwd.c' object='rsyslogd-smfwd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smfwd.o `test -f 'smfwd.c' || echo '$(srcdir)/'`smfwd.c rsyslogd-smfwd.obj: smfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smfwd.obj -MD -MP -MF $(DEPDIR)/rsyslogd-smfwd.Tpo -c -o rsyslogd-smfwd.obj `if test -f 'smfwd.c'; then $(CYGPATH_W) 'smfwd.c'; else $(CYGPATH_W) '$(srcdir)/smfwd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smfwd.Tpo $(DEPDIR)/rsyslogd-smfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smfwd.c' object='rsyslogd-smfwd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smfwd.obj `if test -f 'smfwd.c'; then $(CYGPATH_W) 'smfwd.c'; else $(CYGPATH_W) '$(srcdir)/smfwd.c'; fi` rsyslogd-smtradfwd.o: smtradfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smtradfwd.o -MD -MP -MF $(DEPDIR)/rsyslogd-smtradfwd.Tpo -c -o rsyslogd-smtradfwd.o `test -f 'smtradfwd.c' || echo '$(srcdir)/'`smtradfwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smtradfwd.Tpo $(DEPDIR)/rsyslogd-smtradfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtradfwd.c' object='rsyslogd-smtradfwd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smtradfwd.o `test -f 'smtradfwd.c' || echo '$(srcdir)/'`smtradfwd.c rsyslogd-smtradfwd.obj: smtradfwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-smtradfwd.obj -MD -MP -MF $(DEPDIR)/rsyslogd-smtradfwd.Tpo -c -o rsyslogd-smtradfwd.obj `if test -f 'smtradfwd.c'; then $(CYGPATH_W) 'smtradfwd.c'; else $(CYGPATH_W) '$(srcdir)/smtradfwd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-smtradfwd.Tpo $(DEPDIR)/rsyslogd-smtradfwd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smtradfwd.c' object='rsyslogd-smtradfwd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-smtradfwd.obj `if test -f 'smtradfwd.c'; then $(CYGPATH_W) 'smtradfwd.c'; else $(CYGPATH_W) '$(srcdir)/smtradfwd.c'; fi` rsyslogd-iminternal.o: iminternal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-iminternal.o -MD -MP -MF $(DEPDIR)/rsyslogd-iminternal.Tpo -c -o rsyslogd-iminternal.o `test -f 'iminternal.c' || echo '$(srcdir)/'`iminternal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-iminternal.Tpo $(DEPDIR)/rsyslogd-iminternal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iminternal.c' object='rsyslogd-iminternal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-iminternal.o `test -f 'iminternal.c' || echo '$(srcdir)/'`iminternal.c rsyslogd-iminternal.obj: iminternal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rsyslogd-iminternal.obj -MD -MP -MF $(DEPDIR)/rsyslogd-iminternal.Tpo -c -o rsyslogd-iminternal.obj `if test -f 'iminternal.c'; then $(CYGPATH_W) 'iminternal.c'; else $(CYGPATH_W) '$(srcdir)/iminternal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsyslogd-iminternal.Tpo $(DEPDIR)/rsyslogd-iminternal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iminternal.c' object='rsyslogd-iminternal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(rsyslogd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rsyslogd-iminternal.obj `if test -f 'iminternal.c'; then $(CYGPATH_W) 'iminternal.c'; else $(CYGPATH_W) '$(srcdir)/iminternal.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) @list1='$(man1_MANS)'; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man5: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man5dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.5[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-man8: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gethostn.Po -rm -f ./$(DEPDIR)/logctl-logctl.Po -rm -f ./$(DEPDIR)/msggen.Po -rm -f ./$(DEPDIR)/rscryutil-rscryutil.Po -rm -f ./$(DEPDIR)/rsyslogd-iminternal.Po -rm -f ./$(DEPDIR)/rsyslogd-omdiscard.Po -rm -f ./$(DEPDIR)/rsyslogd-omfile.Po -rm -f ./$(DEPDIR)/rsyslogd-omfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-ompipe.Po -rm -f ./$(DEPDIR)/rsyslogd-omshell.Po -rm -f ./$(DEPDIR)/rsyslogd-omusrmsg.Po -rm -f ./$(DEPDIR)/rsyslogd-pmrfc3164.Po -rm -f ./$(DEPDIR)/rsyslogd-pmrfc5424.Po -rm -f ./$(DEPDIR)/rsyslogd-rsyslogd.Po -rm -f ./$(DEPDIR)/rsyslogd-smfile.Po -rm -f ./$(DEPDIR)/rsyslogd-smfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-smtradfile.Po -rm -f ./$(DEPDIR)/rsyslogd-smtradfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-syslogd.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man5 install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gethostn.Po -rm -f ./$(DEPDIR)/logctl-logctl.Po -rm -f ./$(DEPDIR)/msggen.Po -rm -f ./$(DEPDIR)/rscryutil-rscryutil.Po -rm -f ./$(DEPDIR)/rsyslogd-iminternal.Po -rm -f ./$(DEPDIR)/rsyslogd-omdiscard.Po -rm -f ./$(DEPDIR)/rsyslogd-omfile.Po -rm -f ./$(DEPDIR)/rsyslogd-omfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-ompipe.Po -rm -f ./$(DEPDIR)/rsyslogd-omshell.Po -rm -f ./$(DEPDIR)/rsyslogd-omusrmsg.Po -rm -f ./$(DEPDIR)/rsyslogd-pmrfc3164.Po -rm -f ./$(DEPDIR)/rsyslogd-pmrfc5424.Po -rm -f ./$(DEPDIR)/rsyslogd-rsyslogd.Po -rm -f ./$(DEPDIR)/rsyslogd-smfile.Po -rm -f ./$(DEPDIR)/rsyslogd-smfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-smtradfile.Po -rm -f ./$(DEPDIR)/rsyslogd-smtradfwd.Po -rm -f ./$(DEPDIR)/rsyslogd-syslogd.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man \ uninstall-sbinPROGRAMS uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool \ clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-man5 \ install-man8 install-pdf install-pdf-am install-ps \ install-ps-am install-sbinPROGRAMS install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 \ uninstall-sbinPROGRAMS .PRECIOUS: Makefile @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@rscryutil.1: $(RSTMANFILE) @ENABLE_GENERATE_MAN_PAGES_TRUE@@ENABLE_RSCRYUTIL_TRUE@@ENABLE_USERTOOLS_TRUE@ $(AM_V_GEN) $(RST2MAN) $(RSTMANFILE) $@ aix_exports_list: echo "$(top_builddir)/runtime/.libs/librsyslog_la-*.o" > $@ echo "$(top_builddir)/.libs/librsyslog_la-*.o" >> $@ echo "$(top_builddir)/grammar/.libs/libgrammar_la-*.o" >> $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/tools/PaxHeaders/iminternal.h0000644000000000000000000000013215055605325016212 xustar0030 mtime=1756826325.659800834 30 atime=1764931031.137527562 30 ctime=1764935924.179591829 rsyslog-8.2512.0/tools/iminternal.h0000664000175000017500000000300315055605325015652 0ustar00rgerrger/* Definition of the internal messages input module. * * Note: we currently do not have an input module spec, but * we will have one in the future. This module needs then to be * adapted. * * Copyright 2007 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IMINTERNAL_H_INCLUDED #define IMINTERNAL_H_INCLUDED #include "template.h" /* this is a single entry for a parse routine. It describes exactly * one entry point/handler. * The short name is cslch (Configfile SysLine CommandHandler) */ struct iminternal_s { /* config file sysline parse entry */ smsg_t *pMsg; /* the message (in all its glory) */ }; typedef struct iminternal_s iminternal_t; /* prototypes */ rsRetVal modInitIminternal(void); rsRetVal modExitIminternal(void); rsRetVal iminternalAddMsg(smsg_t *pMsg); rsRetVal iminternalRemoveMsg(smsg_t **ppMsg); #endif /* #ifndef IMINTERNAL_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/omfile.h0000644000000000000000000000013215055605325015323 xustar0030 mtime=1756826325.659800834 30 atime=1764930982.712723236 30 ctime=1764935924.136591171 rsyslog-8.2512.0/tools/omfile.h0000664000175000017500000000277015055605325014775 0ustar00rgerrger/* omfile.h * These are the definitions for the build-in file output module. * * File begun on 2007-07-21 by RGerhards * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMFILE_H_INCLUDED #define OMFILE_H_INCLUDED 1 /* prototypes */ rsRetVal modInitFile(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); /* the define below is dirty, but we need it for ompipe integration. There is no * other way to have the functionality (well, one way would be to go through the * globals, but that seems not yet justified. -- rgerhards, 2010-03-01 */ extern uchar *pszFileDfltTplName; #endif /* #ifndef OMFILE_H_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/tools/PaxHeaders/syslogd.h0000644000000000000000000000013215055605325015534 xustar0030 mtime=1756826325.661800864 30 atime=1764931031.133527496 30 ctime=1764935924.116590864 rsyslog-8.2512.0/tools/syslogd.h0000664000175000017500000000221215055605325015175 0ustar00rgerrger/* common header for syslogd * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SYSLOGD_H_INCLUDED #define SYSLOGD_H_INCLUDED 1 #include "syslogd-types.h" #include "objomsr.h" #include "modules.h" #include "template.h" #include "action.h" #include "linkedlist.h" /* the following prototypes should go away once we have an input * module interface -- rgerhards, 2007-12-12 */ extern int NoHops; extern int send_to_all; extern int Debug; #include "dirty.h" #endif /* #ifndef SYSLOGD_H_INCLUDED */ rsyslog-8.2512.0/tools/PaxHeaders/rsyslogd.c0000644000000000000000000000013215114522477015713 xustar0030 mtime=1764926783.047632152 30 atime=1764926784.241661461 30 ctime=1764935924.114590834 rsyslog-8.2512.0/tools/rsyslogd.c0000664000175000017500000024707615114522477015377 0ustar00rgerrger/* This is the main rsyslogd file. * It contains code * that is known to be validly under ASL 2.0, * because it was either written from scratch by me (rgerhards) or * contributors who agreed to ASL 2.0. * * Copyright 2004-2024 Rainer Gerhards and Adiscon * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #ifdef ENABLE_LIBLOGGING_STDLOG #include #else #include #endif #ifdef HAVE_LIBSYSTEMD #include #endif #ifdef ENABLE_LIBCAPNG #include #endif #if defined(HAVE_LINUX_CLOSE_RANGE_H) #include #endif #include "rsyslog.h" #include "wti.h" #include "ratelimit.h" #include "parser.h" #include "linkedlist.h" #include "ruleset.h" #include "action.h" #include "iminternal.h" #include "errmsg.h" #include "threads.h" #include "dnscache.h" #include "prop.h" #include "unicode-helper.h" #include "net.h" #include "glbl.h" #include "debug.h" #include "srUtils.h" #include "rsconf.h" #include "cfsysline.h" #include "datetime.h" #include "operatingstate.h" #include "dirty.h" #include "janitor.h" #include "parserif.h" /* some global vars we need to differentiate between environments, * for TZ-related things see * https://github.com/rsyslog/rsyslog/issues/2994 */ static int runningInContainer = 0; #ifdef OS_LINUX static int emitTZWarning = 0; #else static int emitTZWarning = 1; #endif static pthread_t mainthread = 0; #if defined(_AIX) /* AIXPORT : start * The following includes and declarations are for support of the System * Resource Controller (SRC) . */ #include /* AIXPORT : start*/ #define SRC_FD 13 #define SRCMSG (sizeof(srcpacket)) static void deinitAll(void); #include static struct srcreq srcpacket; int cont; struct srchdr *srchdr; char progname[128]; /* Normally defined as locals in main * But here since the functionality is split * across multiple functions, we make it global */ static int rc; static socklen_t addrsz; static struct sockaddr srcaddr; int src_exists = TRUE; /* src end */ /* * SRC packet processing - . */ #define SRCMIN(a, b) (a < b) ? a : b void dosrcpacket(msgno, txt, len) int msgno; char *txt; int len; { struct srcrep reply; reply.svrreply.rtncode = msgno; /* AIXPORT : srv was corrected to syslogd */ strcpy(reply.svrreply.objname, "syslogd"); snprintf(reply.svrreply.rtnmsg, SRCMIN(sizeof(reply.svrreply.rtnmsg) - 1, strlen(txt)), "%s", txt); srchdr = srcrrqs((char *)&srcpacket); srcsrpy(srchdr, (char *)&reply, len, cont); } #define AIX_SRC_EXISTS_IF if (!src_exists) { #define AIX_SRC_EXISTS_FI } static void aix_close_it(int i) { if (src_exists) { if (i != SRC_FD) (void)close(i); } else close(i); } #else #define AIX_SRC_EXISTS_IF #define AIX_SRC_EXISTS_FI #define aix_close_it(x) close(x) #endif /* AIXPORT : end */ DEFobjCurrIf(obj) DEFobjCurrIf(prop) DEFobjCurrIf(parser) DEFobjCurrIf(ruleset) DEFobjCurrIf(net) DEFobjCurrIf(rsconf) DEFobjCurrIf(module) DEFobjCurrIf(datetime) DEFobjCurrIf(glbl) extern int yydebug; /* interface to flex */ /* forward definitions */ void rsyslogd_submitErrMsg(const int severity, const int iErr, const uchar *msg); void rsyslogdDoDie(int sig); #ifndef PATH_PIDFILE #if defined(_AIX) /* AIXPORT : Add _AIX */ #define PATH_PIDFILE "/etc/rsyslogd.pid" #else #define PATH_PIDFILE "/var/run/rsyslogd.pid" #endif /*_AIX*/ #endif #ifndef PATH_CONFFILE #define PATH_CONFFILE "/etc/rsyslog.conf" #endif /* global data items */ static pthread_mutex_t mutChildDied; static int bChildDied = 0; static pthread_mutex_t mutHadHUP; static int bHadHUP; static int doFork = 1; /* fork - run in daemon mode - read-only after startup */ int bFinished = 0; /* used by termination signal handler, read-only except there * is either 0 or the number of the signal that requested the * termination. */ const char *PidFile = NULL; #define NO_PIDFILE "NONE" int iConfigVerify = 0; /* is this just a config verify run? */ rsconf_t *ourConf = NULL; /* our config object */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ ratelimit_t *dflt_ratelimiter = NULL; /* ratelimiter for submits without explicit one */ uchar *ConfFile = (uchar *)PATH_CONFFILE; int bHaveMainQueue = 0; /* set to 1 if the main queue - in queueing mode - is available * If the main queue is either not yet ready or not running in * queueing mode (mode DIRECT!), then this is set to 0. */ prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */ ratelimit_t *internalMsg_ratelimiter = NULL; /* ratelimiter for rsyslog-own messages */ int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */ static struct queuefilenames_s { struct queuefilenames_s *next; uchar *name; } *queuefilenames = NULL; static __attribute__((noreturn)) void rsyslogd_usage(void) { fprintf(stderr, "usage: rsyslogd [options]\n" "use \"man rsyslogd\" for details. To run rsyslog " "interactively, use \"rsyslogd -n\"\n" "to run it in debug mode use \"rsyslogd -dn\"\n" "For further information see https://www.rsyslog.com/doc/\n"); exit(1); /* "good" exit - done to terminate usage() */ } #ifndef HAVE_SETSID extern void untty(void); /* in syslogd.c, GPLv3 */ static int setsid(void) { untty(); return 0; } #endif /* helper for imdiag. Returns if HUP processing has been requested or * is not yet finished. We know this is racy, but imdiag handles this * part by repeating operations. The mutex look is primarily to force * a memory barrier, so that we have a change to see changes already * written, but not present in the core's cache. * 2023-07-26 Rainer Gerhards */ int get_bHadHUP(void) { pthread_mutex_lock(&mutHadHUP); const int ret = bHadHUP; pthread_mutex_unlock(&mutHadHUP); /* note: at this point ret can already be invalid */ return ret; } /* we need a pointer to the conf, because in early startup stage we * need to use loadConf, later on runConf. */ rsRetVal queryLocalHostname(rsconf_t *const pConf) { uchar *LocalHostName = NULL; uchar *LocalDomain = NULL; uchar *LocalFQDNName; DEFiRet; assert(net.getLocalHostname != NULL); /* keep clang static analyzer silent - this IS the case */ CHKiRet(net.getLocalHostname(pConf, &LocalFQDNName)); uchar *dot = (uchar *)strstr((char *)LocalFQDNName, "."); if (dot == NULL) { CHKmalloc(LocalHostName = (uchar *)strdup((char *)LocalFQDNName)); CHKmalloc(LocalDomain = (uchar *)strdup("")); } else { const size_t lenhn = dot - LocalFQDNName; CHKmalloc(LocalHostName = (uchar *)strndup((char *)LocalFQDNName, lenhn)); CHKmalloc(LocalDomain = (uchar *)strdup((char *)dot + 1)); } glbl.SetLocalFQDNName(LocalFQDNName); glbl.SetLocalHostName(LocalHostName); glbl.SetLocalDomain(LocalDomain); glbl.GenerateLocalHostNameProperty(); LocalHostName = NULL; /* handed over */ LocalDomain = NULL; /* handed over */ finalize_it: free(LocalHostName); free(LocalDomain); RETiRet; } static rsRetVal writePidFile(void) { FILE *fp; DEFiRet; const char *tmpPidFile = NULL; if (!strcmp(PidFile, NO_PIDFILE)) { FINALIZE; } if (asprintf((char **)&tmpPidFile, "%s.tmp", PidFile) == -1) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } if (tmpPidFile == NULL) tmpPidFile = PidFile; DBGPRINTF("rsyslogd: writing pidfile '%s'.\n", tmpPidFile); if ((fp = fopen((char *)tmpPidFile, "w")) == NULL) { perror("rsyslogd: error writing pid file (creation stage)\n"); ABORT_FINALIZE(RS_RET_ERR); } if (fprintf(fp, "%d", (int)glblGetOurPid()) < 0) { LogError(errno, iRet, "rsyslog: error writing pid file"); } fclose(fp); if (tmpPidFile != PidFile) { if (rename(tmpPidFile, PidFile) != 0) { perror("rsyslogd: error writing pid file (rename stage)"); } } finalize_it: if (tmpPidFile != PidFile) { free((void *)tmpPidFile); } RETiRet; } static void clearPidFile(void) { if (PidFile != NULL) { if (strcmp(PidFile, NO_PIDFILE)) { unlink(PidFile); } } } /* duplicate startup protection: check, based on pid file, if our instance * is already running. This MUST be called before we write our own pid file. */ static rsRetVal checkStartupOK(void) { FILE *fp = NULL; DEFiRet; DBGPRINTF("rsyslogd: checking if startup is ok, pidfile '%s'.\n", PidFile); if (!strcmp(PidFile, NO_PIDFILE)) { dbgprintf("no pid file shall be written, skipping check\n"); FINALIZE; } if ((fp = fopen((char *)PidFile, "r")) == NULL) FINALIZE; /* all well, no pid file yet */ int pf_pid; if (fscanf(fp, "%d", &pf_pid) != 1) { fprintf(stderr, "rsyslogd: error reading pid file, cannot start up\n"); ABORT_FINALIZE(RS_RET_ERR); } /* ok, we got a pid, let's check if the process is running */ const pid_t pid = (pid_t)pf_pid; if (kill(pid, 0) == 0 || errno != ESRCH) { fprintf(stderr, "rsyslogd: pidfile '%s' and pid %d already exist.\n" "If you want to run multiple instances of rsyslog, you need " "to specify\n" "different pid files for them (-i option).\n", PidFile, (int)getpid()); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (fp != NULL) fclose(fp); RETiRet; } /* note: this function is specific to OS'es which provide * the ability to read open file descriptors via /proc. * returns 0 - success, something else otherwise */ static int close_unneeded_open_files(const char *const procdir, const int beginClose, const int parentPipeFD) { DIR *dir; struct dirent *entry; dir = opendir(procdir); if (dir == NULL) { dbgprintf("closes unneeded files: opendir failed for %s\n", procdir); return 1; } while ((entry = readdir(dir)) != NULL) { const int fd = atoi(entry->d_name); if (fd >= beginClose && (((fd != dbgGetDbglogFd()) && (fd != parentPipeFD)))) { close(fd); } } closedir(dir); return 0; } /* prepares the background processes (if auto-backbrounding) for * operation. */ static void prepareBackground(const int parentPipeFD) { DBGPRINTF("rsyslogd: in child, finalizing initialization\n"); dbgTimeoutToStderr = 0; /* we loose stderr when backgrounding! */ int r = setsid(); if (r == -1) { char err[1024]; char em[2048]; rs_strerror_r(errno, err, sizeof(err)); snprintf(em, sizeof(em) - 1, "rsyslog: error " "auto-backgrounding: %s\n", err); dbgprintf("%s\n", em); fprintf(stderr, "%s", em); } int beginClose = 3; #ifdef HAVE_LIBSYSTEMD /* running under systemd? Then we must make sure we "forward" any * fds passed by it (adjust the pid). */ if (sd_booted()) { const char *lstnPid = getenv("LISTEN_PID"); if (lstnPid != NULL) { char szBuf[64]; const int lstnPidI = atoi(lstnPid); snprintf(szBuf, sizeof(szBuf), "%d", lstnPidI); if (!strcmp(szBuf, lstnPid) && lstnPidI == getppid()) { snprintf(szBuf, sizeof(szBuf), "%d", (int)getpid()); setenv("LISTEN_PID", szBuf, 1); /* ensure we do not close what systemd provided */ const int nFds = sd_listen_fds(0); if (nFds > 0) { beginClose = SD_LISTEN_FDS_START + nFds; } } } } #endif /* close unnecessary open files - first try to use /proc file system, * if that is not possible iterate through all potentially open file * descriptors. This can be lenghty, but in practice /proc should work * for almost all current systems, and the fallback is primarily for * Solaris and AIX, where we do expect a decent max numbers of fds. */ close(0); /* always close stdin, we do not need it */ /* try Linux, Cygwin, NetBSD */ if (close_unneeded_open_files("/proc/self/fd", beginClose, parentPipeFD) != 0) { /* try MacOS, FreeBSD */ if (close_unneeded_open_files("/proc/fd", beginClose, parentPipeFD) != 0) { /* did not work out, so let's close everything... */ int endClose = (parentPipeFD > dbgGetDbglogFd()) ? parentPipeFD : dbgGetDbglogFd(); for (int i = beginClose; i <= endClose; ++i) { if ((i != dbgGetDbglogFd()) && (i != parentPipeFD)) { aix_close_it(i); /* AIXPORT */ } } beginClose = endClose + 1; endClose = getdtablesize(); #if defined(HAVE_CLOSE_RANGE) if (close_range(beginClose, endClose, 0) != 0) { dbgprintf("errno %d after close_range(), fallback to loop\n", errno); #endif for (int i = beginClose; i <= endClose; ++i) { aix_close_it(i); /* AIXPORT */ } #if defined(HAVE_CLOSE_RANGE) } #endif } } seedRandomNumberForChild(); } /* This is called when rsyslog is set to auto-background itself. If so, a child * is forked and the parent waits until it is initialized. * The parent never returns from this function, only this happens for the child. * So if it returns, you know you are in the child. * return: file descriptor to which the child needs to write an "OK" or error * message. */ static int forkRsyslog(void) { int pipefd[2]; pid_t cpid; char err[1024]; char msgBuf[4096]; dbgprintf("rsyslogd: parent ready for forking\n"); if (pipe(pipefd) == -1) { perror("error creating rsyslog \"fork pipe\" - terminating"); exit(1); } AIX_SRC_EXISTS_IF /* AIXPORT */ cpid = fork(); if (cpid == -1) { perror("error forking rsyslogd process - terminating"); exit(1); } AIX_SRC_EXISTS_FI /* AIXPORT */ if (cpid == 0) { prepareBackground(pipefd[1]); close(pipefd[0]); return pipefd[1]; } /* we are now in the parent. All we need to do here is wait for the * startup message, emit it (if necessary) and then terminate. */ close(pipefd[1]); dbgprintf("rsyslogd: parent waiting up to 60 seconds to read startup message\n"); fd_set rfds; struct timeval tv; int retval; FD_ZERO(&rfds); FD_SET(pipefd[0], &rfds); tv.tv_sec = 60; tv.tv_usec = 0; retval = select(pipefd[0] + 1, &rfds, NULL, NULL, &tv); if (retval == -1) rs_strerror_r(errno, err, sizeof(err)); else strcpy(err, "OK"); dbgprintf("rsyslogd: select() returns %d: %s\n", retval, err); if (retval == -1) { fprintf(stderr, "rsyslog startup failure, select() failed: %s\n", err); exit(1); } else if (retval == 0) { fprintf(stderr, "rsyslog startup failure, child did not " "respond within startup timeout (60 seconds)\n"); exit(1); } int nRead = read(pipefd[0], msgBuf, sizeof(msgBuf) - 1); if (nRead > 0) { msgBuf[nRead] = '\0'; } else { rs_strerror_r(errno, err, sizeof(err)); snprintf(msgBuf, sizeof(msgBuf) - 1, "error reading \"fork pipe\": %s", err); } if (strcmp(msgBuf, "OK")) { dbgprintf("rsyslog parent startup failure: %s\n", msgBuf); fprintf(stderr, "rsyslog startup failure: %s\n", msgBuf); exit(1); } close(pipefd[0]); dbgprintf("rsyslogd: parent terminates after successful child startup\n"); exit(0); } /* startup processing: this signals the waiting parent that the child is ready * and the parent may terminate. */ static void tellChildReady(const int pipefd, const char *const msg) { dbgprintf("rsyslogd: child signaling OK\n"); const int nWritten = write(pipefd, msg, strlen(msg)); dbgprintf("rsyslogd: child signalled OK, nWritten %d\n", (int)nWritten); close(pipefd); sleep(1); } /* print version and compile-time setting information */ static void printVersion(void) { printf("rsyslogd " VERSION " (aka %4d.%2.2d) compiled with:\n", 2000 + VERSION_YEAR, VERSION_MONTH); printf("\tPLATFORM:\t\t\t\t%s\n", PLATFORM_ID); printf("\tPLATFORM (lsb_release -d):\t\t%s\n", PLATFORM_ID_LSB); #ifdef FEATURE_REGEXP printf("\tFEATURE_REGEXP:\t\t\t\tYes\n"); #else printf("\tFEATURE_REGEXP:\t\t\t\tNo\n"); #endif #if defined(SYSLOG_INET) && defined(USE_GSSAPI) printf("\tGSSAPI Kerberos 5 support:\t\tYes\n"); #else printf("\tGSSAPI Kerberos 5 support:\t\tNo\n"); #endif #ifndef NDEBUG printf("\tFEATURE_DEBUG (debug build, slow code):\tYes\n"); #else printf("\tFEATURE_DEBUG (debug build, slow code):\tNo\n"); #endif #ifdef HAVE_ATOMIC_BUILTINS printf("\t32bit Atomic operations supported:\tYes\n"); #else printf("\t32bit Atomic operations supported:\tNo\n"); #endif #ifdef HAVE_ATOMIC_BUILTINS64 printf("\t64bit Atomic operations supported:\tYes\n"); #else printf("\t64bit Atomic operations supported:\tNo\n"); #endif #ifdef HAVE_JEMALLOC printf("\tmemory allocator:\t\t\tjemalloc\n"); #else printf("\tmemory allocator:\t\t\tsystem default\n"); #endif #ifdef RTINST printf("\tRuntime Instrumentation (slow code):\tYes\n"); #else printf("\tRuntime Instrumentation (slow code):\tNo\n"); #endif #ifdef USE_LIBUUID printf("\tuuid support:\t\t\t\tYes\n"); #else printf("\tuuid support:\t\t\t\tNo\n"); #endif #ifdef HAVE_LIBSYSTEMD printf("\tsystemd support:\t\t\tYes\n"); #else printf("\tsystemd support:\t\t\tNo\n"); #endif /* we keep the following message to so that users don't need * to wonder. */ printf("\tConfig file:\t\t\t\t" PATH_CONFFILE "\n"); printf("\tPID file:\t\t\t\t" PATH_PIDFILE "%s\n", PATH_PIDFILE[0] != '/' ? "(relative to global workingdirectory)" : ""); printf("\tNumber of Bits in RainerScript integers: 64\n"); printf("\nSee https://www.rsyslog.com for more information.\n"); } static rsRetVal rsyslogd_InitStdRatelimiters(void) { DEFiRet; CHKiRet(ratelimitNew(&dflt_ratelimiter, "rsyslogd", "dflt")); CHKiRet(ratelimitNew(&internalMsg_ratelimiter, "rsyslogd", "internal_messages")); ratelimitSetThreadSafe(internalMsg_ratelimiter); ratelimitSetLinuxLike(internalMsg_ratelimiter, loadConf->globals.intMsgRateLimitItv, loadConf->globals.intMsgRateLimitBurst); /* TODO: make internalMsg ratelimit settings configurable */ finalize_it: RETiRet; } /* Method to initialize all global classes and use the objects that we need. * rgerhards, 2008-01-04 * rgerhards, 2008-04-16: the actual initialization is now carried out by the runtime */ static rsRetVal rsyslogd_InitGlobalClasses(void) { DEFiRet; const char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */ /* Intialize the runtime system */ pErrObj = "rsyslog runtime"; /* set in case the runtime errors before setting an object */ CHKiRet(rsrtInit(&pErrObj, &obj)); rsrtSetErrLogger(rsyslogd_submitErrMsg); /* Now tell the system which classes we need ourselfs */ pErrObj = "glbl"; CHKiRet(objUse(glbl, CORE_COMPONENT)); pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); pErrObj = "datetime"; CHKiRet(objUse(datetime, CORE_COMPONENT)); pErrObj = "ruleset"; CHKiRet(objUse(ruleset, CORE_COMPONENT)); pErrObj = "prop"; CHKiRet(objUse(prop, CORE_COMPONENT)); pErrObj = "parser"; CHKiRet(objUse(parser, CORE_COMPONENT)); pErrObj = "rsconf"; CHKiRet(objUse(rsconf, CORE_COMPONENT)); /* initialize some dummy classes that are not part of the runtime */ pErrObj = "action"; CHKiRet(actionClassInit()); pErrObj = "template"; CHKiRet(templateInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); dnscacheInit(); initRainerscript(); ratelimitModInit(); /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); finalize_it: if (iRet != RS_RET_OK) { /* we know we are inside the init sequence, so we can safely emit * messages to stderr. -- rgerhards, 2008-04-02 */ fprintf(stderr, "Error during class init for object '%s' - failing...\n", pErrObj); fprintf(stderr, "rsyslogd initialization failed - global classes could not be initialized.\n" "Did you do a \"make install\"?\n" "Suggested action: run rsyslogd with -d -n options to see what exactly " "fails.\n"); } RETiRet; } /* preprocess a batch of messages, that is ready them for actual processing. This is done * as a first stage and totally in parallel to any other worker active in the system. So * it helps us keep up the overall concurrency level. * rgerhards, 2010-06-09 */ static rsRetVal preprocessBatch(batch_t *pBatch, int *pbShutdownImmediate) { prop_t *ip; prop_t *fqdn; prop_t *localName; int bIsPermitted; smsg_t *pMsg; int i; rsRetVal localRet; DEFiRet; for (i = 0; i < pBatch->nElem && !*pbShutdownImmediate; i++) { pMsg = pBatch->pElem[i].pMsg; if ((pMsg->msgFlags & NEEDS_ACLCHK_U) != 0) { DBGPRINTF("msgConsumer: UDP ACL must be checked for message (hostname-based)\n"); if (net.cvthname(pMsg->rcvFrom.pfrominet, &localName, &fqdn, &ip) != RS_RET_OK) continue; bIsPermitted = net.isAllowedSender2((uchar *)"UDP", (struct sockaddr *)pMsg->rcvFrom.pfrominet, (char *)propGetSzStr(fqdn), 1); if (!bIsPermitted) { DBGPRINTF("Message from '%s' discarded, not a permitted sender host\n", propGetSzStr(fqdn)); pBatch->eltState[i] = BATCH_STATE_DISC; } else { /* save some of the info we obtained */ MsgSetRcvFrom(pMsg, localName); CHKiRet(MsgSetRcvFromIP(pMsg, ip)); pMsg->msgFlags &= ~NEEDS_ACLCHK_U; } } if ((pMsg->msgFlags & NEEDS_PARSING) != 0) { if ((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) { DBGPRINTF("Message discarded, parsing error %d\n", localRet); pBatch->eltState[i] = BATCH_STATE_DISC; } } } finalize_it: RETiRet; } /* The consumer of dequeued messages. This function is called by the * queue engine on dequeueing of a message. It runs on a SEPARATE * THREAD. It receives an array of pointers, which it must iterate * over. We do not do any further batching, as this is of no benefit * for the main queue. */ static rsRetVal msgConsumer(void __attribute__((unused)) * notNeeded, batch_t *pBatch, wti_t *pWti) { DEFiRet; assert(pBatch != NULL); preprocessBatch(pBatch, pWti->pbShutdownImmediate); ruleset.ProcessBatch(pBatch, pWti); // TODO: the BATCH_STATE_COMM must be set somewhere down the road, but we // do not have this yet and so we emulate -- 2010-06-10 int i; for (i = 0; i < pBatch->nElem && !*pWti->pbShutdownImmediate; i++) { pBatch->eltState[i] = BATCH_STATE_COMM; } RETiRet; } /* create a main message queue, now also used for ruleset queues. This function * needs to be moved to some other module, but it is considered acceptable for * the time being (remember that we want to restructure config processing at large!). * rgerhards, 2009-10-27 */ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct nvlst *lst) { struct queuefilenames_s *qfn; uchar *qfname = NULL; static int qfn_renamenum = 0; uchar qfrenamebuf[1024]; DEFiRet; /* create message queue */ CHKiRet_Hdlr(qqueueConstruct(ppQueue, ourConf->globals.mainQ.MainMsgQueType, ourConf->globals.mainQ.iMainMsgQueueNumWorkers, ourConf->globals.mainQ.iMainMsgQueueSize, msgConsumer)) { /* no queue is fatal, we need to give up in that case... */ LogError(0, iRet, "could not create (ruleset) main message queue"); } /* name our main queue object (it's not fatal if it fails...) */ obj.SetName((obj_t *)(*ppQueue), pszQueueName); if (lst == NULL) { /* use legacy parameters? */ /* ... set some properties ... */ #define setQPROP(func, directive, data) \ CHKiRet_Hdlr(func(*ppQueue, data)) { \ LogError(0, NO_ERRCODE, \ "Invalid " #directive \ ", error %d. Ignored, " \ "running with default setting", \ iRet); \ } #define setQPROPstr(func, directive, data) \ CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL) ? 0 : strlen((char *)data))) { \ LogError(0, NO_ERRCODE, \ "Invalid " #directive \ ", error %d. Ignored, " \ "running with default setting", \ iRet); \ } if (ourConf->globals.mainQ.pszMainMsgQFName != NULL) { /* check if the queue file name is unique, else emit an error */ for (qfn = queuefilenames; qfn != NULL; qfn = qfn->next) { dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, ourConf->globals.mainQ.pszMainMsgQFName); if (!ustrcmp(qfn->name, ourConf->globals.mainQ.pszMainMsgQFName)) { snprintf((char *)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", ++qfn_renamenum, ourConf->globals.mainQ.pszMainMsgQFName, (pszQueueName == NULL) ? "NONAME" : (char *)pszQueueName); qfname = ustrdup(qfrenamebuf); LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " " - using '%s' instead", ourConf->globals.mainQ.pszMainMsgQFName, qfname); break; } } if (qfname == NULL) qfname = ustrdup(ourConf->globals.mainQ.pszMainMsgQFName); qfn = malloc(sizeof(struct queuefilenames_s)); qfn->name = qfname; qfn->next = queuefilenames; queuefilenames = qfn; } setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown); setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); #undef setQPROP #undef setQPROPstr } else { /* use new style config! */ qqueueSetDefaultsRulesetQueue(*ppQueue); qqueueApplyCnfParam(*ppQueue, lst); } qqueueCorrectParams(*ppQueue); RETiRet; } rsRetVal startMainQueue(rsconf_t *cnf, qqueue_t *const pQueue) { DEFiRet; CHKiRet_Hdlr(qqueueStart(cnf, pQueue)) { /* no queue is fatal, we need to give up in that case... */ LogError(0, iRet, "could not start (ruleset) main message queue"); if (runConf->globals.bAbortOnFailedQueueStartup) { fprintf(stderr, "rsyslogd: could not start (ruleset) main message queue, " "abortOnFailedQueueStartup is set, so we abort rsyslog now.\n"); fflush(stderr); clearPidFile(); exit(1); /* "good" exit, this is intended here */ } pQueue->qType = QUEUETYPE_DIRECT; CHKiRet_Hdlr(qqueueStart(cnf, pQueue)) { /* no queue is fatal, we need to give up in that case... */ LogError(0, iRet, "fatal error: could not even start queue in direct mode"); } } RETiRet; } /* this is a special function used to submit an error message. This * function is also passed to the runtime library as the generic error * message handler. -- rgerhards, 2008-04-17 */ void rsyslogd_submitErrMsg(const int severity, const int iErr, const uchar *msg) { if (glbl.GetGlobalInputTermState() == 1) { /* After fork the stderr is unusable (dfltErrLogger uses is internally) */ if (!doFork) dfltErrLogger(severity, iErr, msg); } else { logmsgInternal(iErr, LOG_SYSLOG | (severity & 0x07), msg, 0); } } static inline rsRetVal submitMsgWithDfltRatelimiter(smsg_t *pMsg) { return ratelimitAddMsg(dflt_ratelimiter, NULL, pMsg); } static void logmsgInternal_doWrite(smsg_t *pMsg) { const int pri = getPRIi(pMsg); if (pri % 8 <= runConf->globals.intMsgsSeverityFilter) { if (runConf->globals.bProcessInternalMessages) { submitMsg2(pMsg); pMsg = NULL; /* msg obj handed over; do not destruct */ } else { uchar *const msg = getMSG(pMsg); #ifdef ENABLE_LIBLOGGING_STDLOG /* the "emit only once" rate limiter is quick and dirty and not * thread safe. However, that's no problem for the current intend * and it is not justified to create more robust code for the * functionality. -- rgerhards, 2018-05-14 */ static warnmsg_emitted = 0; if (warnmsg_emitted == 0) { stdlog_log(runConf->globals.stdlog_hdl, LOG_WARNING, "%s", "RSYSLOG WARNING: liblogging-stdlog " "functionality will go away soon. For details see " "https://github.com/rsyslog/rsyslog/issues/2706"); warnmsg_emitted = 1; } stdlog_log(runConf->globals.stdlog_hdl, pri2sev(pri), "%s", (char *)msg); #else syslog(pri, "%s", msg); #endif } } if (pMsg != NULL) { msgDestruct(&pMsg); } } /* This function creates a log message object out of the provided * message text and forwards it for logging. */ static rsRetVal logmsgInternalSubmit( const int iErr, const syslog_pri_t pri, const size_t lenMsg, const char *__restrict__ const msg, int flags) { uchar pszTag[33]; smsg_t *pMsg; DEFiRet; if (glblAbortOnProgramError && iErr == RS_RET_PROGRAM_ERROR) { fprintf(stderr, "\n\n\n========================================\n" "rsyslog reports program error: %s\n" "rsyslog is configured to abort in this case, " "this will be done now\n", msg); fflush(stdout); abort(); } CHKiRet(msgConstruct(&pMsg)); MsgSetInputName(pMsg, pInternalInputName); MsgSetRawMsg(pMsg, (char *)msg, lenMsg); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); /* check if we have an error code associated and, if so, * adjust the tag. -- rgerhards, 2008-06-27 */ if (iErr == NO_ERRCODE) { MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd:"), sizeof("rsyslogd:") - 1); } else { size_t len = snprintf((char *)pszTag, sizeof(pszTag), "rsyslogd%d:", iErr); pszTag[32] = '\0'; /* just to make sure... */ MsgSetTAG(pMsg, pszTag, len); } flags |= INTERNAL_MSG; pMsg->msgFlags = flags; msgSetPRI(pMsg, pri); iminternalAddMsg(pMsg); finalize_it: RETiRet; } /* rgerhards 2004-11-09: the following is a function that can be used * to log a message orginating from the syslogd itself. */ rsRetVal logmsgInternal(int iErr, const syslog_pri_t pri, const uchar *const msg, int flags) { size_t lenMsg; unsigned i; char *bufModMsg = NULL; /* buffer for modified message, should we need to modify */ DEFiRet; /* we first do a path the remove control characters that may have accidently * introduced (program error!). This costs performance, but we do not expect * to be called very frequently in any case ;) -- rgerhards, 2013-12-19. */ lenMsg = ustrlen(msg); for (i = 0; i < lenMsg; ++i) { if (msg[i] < 0x20 || msg[i] == 0x7f) { if (bufModMsg == NULL) { CHKmalloc(bufModMsg = strdup((char *)msg)); } bufModMsg[i] = ' '; } } CHKiRet(logmsgInternalSubmit(iErr, pri, lenMsg, (bufModMsg == NULL) ? (char *)msg : bufModMsg, flags)); /* we now check if we should print internal messages out to stderr. This was * suggested by HKS as a way to help people troubleshoot rsyslog configuration * (by running it interactively. This makes an awful lot of sense, so I add * it here. -- rgerhards, 2008-07-28 * Note that error messages can not be disabled during a config verify. This * permits us to process unmodified config files which otherwise contain a * supressor statement. */ int emit_to_stderr = (ourConf == NULL) ? 1 : (ourConf->globals.bErrMsgToStderr || ourConf->globals.bAllMsgToStderr); int emit_supress_msg = 0; if (Debug == DEBUG_FULL || !doFork) { emit_to_stderr = 1; } if (ourConf != NULL && ourConf->globals.maxErrMsgToStderr != -1) { if (emit_to_stderr && ourConf->globals.maxErrMsgToStderr != -1 && ourConf->globals.maxErrMsgToStderr) { --ourConf->globals.maxErrMsgToStderr; if (ourConf->globals.maxErrMsgToStderr == 0) emit_supress_msg = 1; } else { emit_to_stderr = 0; } } if (emit_to_stderr || iConfigVerify) { if ((ourConf != NULL && ourConf->globals.bAllMsgToStderr) || pri2sev(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", (bufModMsg == NULL) ? (char *)msg : bufModMsg); } if (emit_supress_msg) { fprintf(stderr, "rsyslogd: configured max number of error messages " "to stderr reached, further messages will not be output\n" "Consider adjusting\n" " global(errorMessagesToStderr.maxNumber=\"xx\")\n" "if you want more.\n"); } finalize_it: free(bufModMsg); RETiRet; } rsRetVal submitMsg(smsg_t *pMsg) { return submitMsgWithDfltRatelimiter(pMsg); } static rsRetVal ATTR_NONNULL() splitOversizeMessage(smsg_t *const pMsg) { DEFiRet; const char *rawmsg; int nsegments; int len_rawmsg; const int maxlen = glblGetMaxLine(runConf); ISOBJ_TYPE_assert(pMsg, msg); getRawMsg(pMsg, (uchar **)&rawmsg, &len_rawmsg); nsegments = len_rawmsg / maxlen; const int len_last_segment = len_rawmsg % maxlen; DBGPRINTF( "splitting oversize message, size %d, segment size %d, " "nsegments %d, bytes in last fragment %d\n", len_rawmsg, maxlen, nsegments, len_last_segment); smsg_t *pMsg_seg; /* process full segments */ for (int i = 0; i < nsegments; ++i) { CHKmalloc(pMsg_seg = MsgDup(pMsg)); MsgSetRawMsg(pMsg_seg, rawmsg + (i * maxlen), maxlen); submitMsg2(pMsg_seg); } /* if necessary, write partial last segment */ if (len_last_segment != 0) { CHKmalloc(pMsg_seg = MsgDup(pMsg)); MsgSetRawMsg(pMsg_seg, rawmsg + (nsegments * maxlen), len_last_segment); submitMsg2(pMsg_seg); } finalize_it: RETiRet; } /* submit a message to the main message queue. This is primarily * a hook to prevent the need for callers to know about the main message queue * rgerhards, 2008-02-13 */ rsRetVal submitMsg2(smsg_t *pMsg) { qqueue_t *pQueue; ruleset_t *pRuleset; DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); if (getRawMsgLen(pMsg) > glblGetMaxLine(runConf)) { uchar *rawmsg; int dummy; getRawMsg(pMsg, &rawmsg, &dummy); if (glblReportOversizeMessage(runConf)) { LogMsg(0, RS_RET_OVERSIZE_MSG, LOG_WARNING, "message too long (%d) with configured size %d, begin of " "message is: %.80s", getRawMsgLen(pMsg), glblGetMaxLine(runConf), rawmsg); } writeOversizeMessageLog(pMsg); if (glblGetOversizeMsgInputMode(runConf) == glblOversizeMsgInputMode_Split) { splitOversizeMessage(pMsg); /* we have submitted the message segments recursively, so we * can just deleted the original msg object and terminate. */ msgDestruct(&pMsg); FINALIZE; } else if (glblGetOversizeMsgInputMode(runConf) == glblOversizeMsgInputMode_Truncate) { MsgTruncateToMaxSize(pMsg); } else { /* in "accept" mode, we do nothing, simply because "accept" means * to use as-is. */ assert(glblGetOversizeMsgInputMode(runConf) == glblOversizeMsgInputMode_Accept); } } pRuleset = MsgGetRuleset(pMsg); assert(ruleset.GetRulesetQueue != NULL); /* This is only to keep clang static analyzer happy */ pQueue = (pRuleset == NULL) ? runConf->pMsgQueue : ruleset.GetRulesetQueue(pRuleset); /* if a plugin logs a message during shutdown, the queue may no longer exist */ if (pQueue == NULL) { DBGPRINTF( "submitMsg2() could not submit message - " "queue does (no longer?) exist - ignored\n"); FINALIZE; } qqueueEnqMsg(pQueue, pMsg->flowCtlType, pMsg); finalize_it: RETiRet; } /* submit multiple messages at once, very similar to submitMsg, just * for multi_submit_t. All messages need to go into the SAME queue! * rgerhards, 2009-06-16 */ rsRetVal ATTR_NONNULL() multiSubmitMsg2(multi_submit_t *const pMultiSub) { qqueue_t *pQueue; ruleset_t *pRuleset; DEFiRet; if (pMultiSub->nElem == 0) FINALIZE; pRuleset = MsgGetRuleset(pMultiSub->ppMsgs[0]); pQueue = (pRuleset == NULL) ? runConf->pMsgQueue : ruleset.GetRulesetQueue(pRuleset); /* if a plugin logs a message during shutdown, the queue may no longer exist */ if (pQueue == NULL) { DBGPRINTF( "multiSubmitMsg() could not submit message - " "queue does (no longer?) exist - ignored\n"); FINALIZE; } iRet = pQueue->MultiEnq(pQueue, pMultiSub); pMultiSub->nElem = 0; finalize_it: RETiRet; } rsRetVal multiSubmitMsg(multi_submit_t *pMultiSub) /* backward compat. level */ { return multiSubmitMsg2(pMultiSub); } /* flush multiSubmit, e.g. at end of read records */ rsRetVal multiSubmitFlush(multi_submit_t *pMultiSub) { DEFiRet; if (pMultiSub->nElem > 0) { iRet = multiSubmitMsg2(pMultiSub); } RETiRet; } /* some support for command line option parsing. Any non-trivial options must be * buffered until the complete command line has been parsed. This is necessary to * prevent dependencies between the options. That, in turn, means we need to have * something that is capable of buffering options and there values. The follwing * functions handle that. * rgerhards, 2008-04-04 */ typedef struct bufOpt { struct bufOpt *pNext; char optchar; char *arg; } bufOpt_t; static bufOpt_t *bufOptRoot = NULL; static bufOpt_t *bufOptLast = NULL; /* add option buffer */ static rsRetVal bufOptAdd(char opt, char *arg) { DEFiRet; bufOpt_t *pBuf; if ((pBuf = malloc(sizeof(bufOpt_t))) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pBuf->optchar = opt; pBuf->arg = arg; pBuf->pNext = NULL; if (bufOptLast == NULL) { bufOptRoot = pBuf; /* then there is also no root! */ } else { bufOptLast->pNext = pBuf; } bufOptLast = pBuf; finalize_it: RETiRet; } /* remove option buffer from top of list, return values and destruct buffer itself. * returns RS_RET_END_OF_LINKEDLIST when no more options are present. * (we use int *opt instead of char *opt to keep consistent with getopt()) */ static rsRetVal bufOptRemove(int *opt, char **arg) { DEFiRet; bufOpt_t *pBuf; if (bufOptRoot == NULL) ABORT_FINALIZE(RS_RET_END_OF_LINKEDLIST); pBuf = bufOptRoot; *opt = pBuf->optchar; *arg = pBuf->arg; bufOptRoot = pBuf->pNext; free(pBuf); finalize_it: RETiRet; } static void hdlr_sigttin_ou(void) { /* this is just a dummy to care for our sigttin input * module cancel interface and sigttou internal message * notificaton/mainloop wakeup mechanism. The important * point is that it actually does *NOTHING*. */ } static void hdlr_enable(int sig, void (*hdlr)()) { struct sigaction sigAct; memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = hdlr; sigaction(sig, &sigAct, NULL); } static void hdlr_sighup(void) { pthread_mutex_lock(&mutHadHUP); bHadHUP = 1; pthread_mutex_unlock(&mutHadHUP); /* at least on FreeBSD we seem not to necessarily awake the main thread. * So let's do it explicitely. */ dbgprintf("awaking mainthread on HUP\n"); pthread_kill(mainthread, SIGTTIN); } static void hdlr_sigchld(void) { pthread_mutex_lock(&mutChildDied); bChildDied = 1; pthread_mutex_unlock(&mutChildDied); } static void rsyslogdDebugSwitch(void) { time_t tTime; struct tm tp; datetime.GetTime(&tTime); localtime_r(&tTime, &tp); if (debugging_on == 0) { debugging_on = 1; dbgprintf("\n"); dbgprintf("\n"); dbgprintf("********************************************************************************\n"); dbgprintf("Switching debugging_on to true at %2.2d:%2.2d:%2.2d\n", tp.tm_hour, tp.tm_min, tp.tm_sec); dbgprintf("********************************************************************************\n"); } else { dbgprintf("********************************************************************************\n"); dbgprintf("Switching debugging_on to false at %2.2d:%2.2d:%2.2d\n", tp.tm_hour, tp.tm_min, tp.tm_sec); dbgprintf("********************************************************************************\n"); dbgprintf("\n"); dbgprintf("\n"); debugging_on = 0; } } /* This is the main entry point into rsyslogd. Over time, we should try to * modularize it a bit more... * * NOTE on stderr and stdout: they are kept open during a fork. Note that this * may introduce subtle security issues: if we are in a jail, one may break out of * it via these descriptors. But if I close them earlier, error messages will (once * again) not be emitted to the user that starts the daemon. Given that the risk * of a break-in is very low in the startup phase, we decide it is more important * to emit error messages. */ static void initAll(int argc, char **argv) { rsRetVal localRet; int ch; int iHelperUOpt; int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ char cwdbuf[128]; /* buffer to obtain/display current working directory */ int parentPipeFD = 0; /* fd of pipe to parent, if auto-backgrounding */ DEFiRet; /* prepare internal signaling */ hdlr_enable(SIGTTIN, hdlr_sigttin_ou); hdlr_enable(SIGTTOU, hdlr_sigttin_ou); /* first, parse the command line options. We do not carry out any actual work, just * see what we should do. This relieves us from certain anomalies and we can process * the parameters down below in the correct order. For example, we must know the * value of -M before we can do the init, but at the same time we need to have * the base classes init before we can process most of the options. Now, with the * split of functionality, this is no longer a problem. Thanks to varmofekoj for * suggesting this algo. * Note: where we just need to set some flags and can do so without knowledge * of other options, we do this during the inital option processing. * rgerhards, 2008-04-04 */ #if defined(_AIX) while ((ch = getopt(argc, argv, "46ACDdf:hi:M:nN:o:qQS:T:u:vwxR")) != EOF) { #else while ((ch = getopt(argc, argv, "46ACDdf:hi:M:nN:o:qQS:T:u:vwx")) != EOF) { #endif switch ((char)ch) { case '4': case '6': case 'A': case 'f': /* configuration file */ case 'i': /* pid file name */ case 'n': /* don't fork */ case 'N': /* enable config verify mode */ case 'q': /* add hostname if DNS resolving has failed */ case 'Q': /* dont resolve hostnames in ACL to IPs */ case 'S': /* Source IP for local client to be used on multihomed host */ case 'T': /* chroot on startup (primarily for testing) */ case 'u': /* misc user settings */ case 'w': /* disable disallowed host warnings */ case 'C': case 'o': /* write output config file */ case 'x': /* disable dns for remote messages */ CHKiRet(bufOptAdd(ch, optarg)); break; #if defined(_AIX) case 'R': /* This option is a no-op for AIX */ break; #endif case 'd': /* debug - must be handled now, so that debug is active during init! */ debugging_on = 1; Debug = 1; yydebug = 1; break; case 'D': /* BISON debug */ yydebug = 1; break; case 'M': /* default module load path -- this MUST be carried out immediately! */ glblModPath = (uchar *)optarg; break; case 'v': /* MUST be carried out immediately! */ printVersion(); exit(0); /* exit for -v option - so this is a "good one" */ case 'h': case '?': default: rsyslogd_usage(); } } if (argc - optind) rsyslogd_usage(); DBGPRINTF("rsyslogd %s startup, module path '%s', cwd:%s\n", VERSION, glblModPath == NULL ? "" : (char *)glblModPath, getcwd(cwdbuf, sizeof(cwdbuf))); /* we are done with the initial option parsing and processing. Now we init the system. */ CHKiRet(rsyslogd_InitGlobalClasses()); /* doing some core initializations */ if ((iRet = modInitIminternal()) != RS_RET_OK) { fprintf(stderr, "fatal error: could not initialize errbuf object (error code %d).\n", iRet); exit(1); /* "good" exit, leaving at init for fatal error */ } /* we now can emit error messages "the regular way" */ if (getenv("TZ") == NULL) { const char *const tz = (access("/etc/localtime", R_OK) == 0) ? "TZ=/etc/localtime" : "TZ=UTC"; putenv((char *)tz); if (emitTZWarning) { LogMsg(0, RS_RET_NO_TZ_SET, LOG_WARNING, "environment variable TZ is not " "set, auto correcting this to %s", tz); } else { dbgprintf("environment variable TZ is not set, auto correcting this to %s\n", tz); } } /* END core initializations - we now come back to carrying out command line options*/ while ((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { DBGPRINTF("deque option %c, optarg '%s'\n", ch, (arg == NULL) ? "" : arg); switch ((char)ch) { case '4': fprintf(stderr, "rsyslogd: the -4 command line option has gone away.\n" "Please use the global(net.ipprotocol=\"ipv4-only\") " "configuration parameter instead.\n"); break; case '6': fprintf(stderr, "rsyslogd: the -6 command line option will has gone away.\n" "Please use the global(net.ipprotocol=\"ipv6-only\") " "configuration parameter instead.\n"); break; case 'A': fprintf(stderr, "rsyslogd: the -A command line option will go away " "soon.\n" "Please use the omfwd parameter \"upd.sendToAll\" instead.\n"); send_to_all++; break; case 'S': /* Source IP for local client to be used on multihomed host */ fprintf(stderr, "rsyslogd: the -S command line option will go away " "soon.\n" "Please use the omrelp parameter \"localClientIP\" instead.\n"); if (glbl.GetSourceIPofLocalClient() != NULL) { fprintf(stderr, "rsyslogd: Only one -S argument allowed, the first one is taken.\n"); } else { glbl.SetSourceIPofLocalClient((uchar *)arg); } break; case 'f': /* configuration file */ ConfFile = (uchar *)arg; break; case 'i': /* pid file name */ free((void *)PidFile); PidFile = arg; break; case 'n': /* don't fork */ doFork = 0; break; case 'N': /* enable config verify mode */ iConfigVerify = (arg == NULL) ? 0 : atoi(arg); break; case 'o': if (fp_rs_full_conf_output != NULL) { fprintf(stderr, "warning: -o option given multiple times. Now " "using value %s\n", (arg == NULL) ? "-" : arg); fclose(fp_rs_full_conf_output); fp_rs_full_conf_output = NULL; } if (arg == NULL || !strcmp(arg, "-")) { fp_rs_full_conf_output = stdout; } else { fp_rs_full_conf_output = fopen(arg, "w"); } if (fp_rs_full_conf_output == NULL) { perror(arg); fprintf(stderr, "rsyslogd: cannot open config output file %s - " "-o option will be ignored\n", arg); } else { time_t tTime; struct tm tp; datetime.GetTime(&tTime); localtime_r(&tTime, &tp); fprintf(fp_rs_full_conf_output, "## full conf created by rsyslog version %s at " "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d ##\n", VERSION, tp.tm_year + 1900, tp.tm_mon + 1, tp.tm_mday, tp.tm_hour, tp.tm_min, tp.tm_sec); } break; case 'q': /* add hostname if DNS resolving has failed */ fprintf(stderr, "rsyslogd: the -q command line option has gone away.\n" "Please use the global(net.aclAddHostnameOnFail=\"on\") " "configuration parameter instead.\n"); break; case 'Q': /* dont resolve hostnames in ACL to IPs */ fprintf(stderr, "rsyslogd: the -Q command line option has gone away.\n" "Please use the global(net.aclResolveHostname=\"off\") " "configuration parameter instead.\n"); break; case 'T': /* chroot() immediately at program startup, but only for testing, NOT security yet */ if (arg == NULL) { /* note this case should already be handled by getopt, * but we want to keep the static analyzer happy. */ fprintf(stderr, "-T options needs a parameter\n"); exit(1); } if (chroot(arg) != 0) { perror("chroot"); exit(1); } if (chdir("/") != 0) { perror("chdir"); exit(1); } break; case 'u': /* misc user settings */ iHelperUOpt = (arg == NULL) ? 0 : atoi(arg); if (iHelperUOpt & 0x01) { fprintf(stderr, "rsyslogd: the -u command line option has gone away.\n" "For the 0x01 bit, please use the " "global(parser.parseHostnameAndTag=\"off\") " "configuration parameter instead.\n"); } if (iHelperUOpt & 0x02) { fprintf(stderr, "rsyslogd: the -u command line option will go away " "soon.\n" "For the 0x02 bit, please use the -C option instead."); bChDirRoot = 0; } break; case 'C': bChDirRoot = 0; break; case 'w': /* disable disallowed host warnigs */ fprintf(stderr, "rsyslogd: the -w command line option has gone away.\n" "Please use the global(net.permitWarning=\"off\") " "configuration parameter instead.\n"); break; case 'x': /* disable dns for remote messages */ fprintf(stderr, "rsyslogd: the -x command line option has gone away.\n" "Please use the global(net.enableDNS=\"off\") " "configuration parameter instead.\n"); break; case 'h': case '?': default: rsyslogd_usage(); } } if (iRet != RS_RET_END_OF_LINKEDLIST) FINALIZE; if (iConfigVerify) { doFork = 0; fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", VERSION, iConfigVerify, ConfFile); } resetErrMsgsFlag(); localRet = rsconf.Load(&ourConf, ConfFile); #ifdef ENABLE_LIBCAPNG if (loadConf->globals.bCapabilityDropEnabled) { /* * Drop capabilities to the necessary set */ int capng_rc, capng_failed = 0; typedef struct capabilities_s { int capability; /* capability code */ const char *name; /* name of the capability to be displayed */ /* is the capability present that is needed by rsyslog? if so we do not drop it */ sbool present; capng_type_t type; } capabilities_t; // clang-format off capabilities_t capabilities[] = { { CAP_BLOCK_SUSPEND, "CAP_BLOCK_SUSPEND", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_NET_RAW, "CAP_NET_RAW", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_CHOWN, "CAP_CHOWN", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_LEASE, "CAP_LEASE", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_NET_ADMIN, "CAP_NET_ADMIN", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_NET_BIND_SERVICE, "CAP_NET_BIND_SERVICE", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_DAC_OVERRIDE, "CAP_DAC_OVERRIDE", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED | CAPNG_BOUNDING_SET }, { CAP_SETGID, "CAP_SETGID", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_SETUID, "CAP_SETUID", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_SYS_ADMIN, "CAP_SYS_ADMIN", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_SYS_CHROOT, "CAP_SYS_CHROOT", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_SYS_RESOURCE, "CAP_SYS_RESOURCE", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED }, { CAP_SYSLOG, "CAP_SYSLOG", 0, CAPNG_EFFECTIVE | CAPNG_PERMITTED } }; // clang-format on if (capng_have_capabilities(CAPNG_SELECT_CAPS) > CAPNG_NONE) { /* Examine which capabilities are available to us, so we do not try to drop something that is not present. We need to do this in two steps, because capng_clear clears the capability set. In the second step, we add back those caps, which were present before clearing the selected posix capabilities set. */ unsigned long caps_len = sizeof(capabilities) / sizeof(capabilities_t); for (unsigned long i = 0; i < caps_len; i++) { if (capng_have_capability(CAPNG_EFFECTIVE, capabilities[i].capability)) { capabilities[i].present = 1; } } capng_clear(CAPNG_SELECT_BOTH); for (unsigned long i = 0; i < caps_len; i++) { if (capabilities[i].present) { DBGPRINTF( "The %s capability is present, " "will try to preserve it.\n", capabilities[i].name); if ((capng_rc = capng_update(CAPNG_ADD, capabilities[i].type, capabilities[i].capability)) != 0) { LogError(0, RS_RET_LIBCAPNG_ERR, "could not update the internal posix capabilities" " settings based on the options passed to it," " capng_update=%d", capng_rc); capng_failed = 1; } } else { DBGPRINTF( "The %s capability is not present, " "will not try to preserve it.\n", capabilities[i].name); } } if ((capng_rc = capng_apply(CAPNG_SELECT_BOTH)) != 0) { LogError(0, RS_RET_LIBCAPNG_ERR, "could not transfer the specified internal posix capabilities " "settings to the kernel, capng_apply=%d", capng_rc); capng_failed = 1; } if (capng_failed) { DBGPRINTF("Capabilities were not dropped successfully.\n"); if (loadConf->globals.bAbortOnFailedLibcapngSetup) { ABORT_FINALIZE(RS_RET_LIBCAPNG_ERR); } } else { DBGPRINTF("Capabilities were dropped successfully\n"); } } else { DBGPRINTF("No capabilities to drop\n"); } } #endif if (fp_rs_full_conf_output != NULL) { if (fp_rs_full_conf_output != stdout) { fclose(fp_rs_full_conf_output); } fp_rs_full_conf_output = NULL; } /* check for "hard" errors that needs us to abort in any case */ if ((localRet == RS_RET_CONF_FILE_NOT_FOUND) || (localRet == RS_RET_NO_ACTIONS)) { /* for extreme testing, we keep the ability to let rsyslog continue * even on hard config errors. Note that this may lead to segfaults * or other malfunction further down the road. */ if ((loadConf->globals.glblDevOptions & DEV_OPTION_KEEP_RUNNING_ON_HARD_CONF_ERROR) == 1) { fprintf(stderr, "rsyslogd: NOTE: developer-only option set to keep rsyslog " "running where it should abort - this can lead to " "more problems later in the run.\n"); } else { ABORT_FINALIZE(localRet); } } glbl.GenerateLocalHostNameProperty(); if (hadErrMsgs()) { if (loadConf->globals.bAbortOnUncleanConfig) { fprintf(stderr, "rsyslogd: global(AbortOnUncleanConfig=\"on\") is set, and " "config is not clean.\n" "Check error log for details, fix errors and restart. As a last\n" "resort, you may want to use global(AbortOnUncleanConfig=\"off\") \n" "to permit a startup with a dirty config.\n"); exit(2); } if (iConfigVerify) { /* a bit dirty, but useful... */ exit(1); } localRet = RS_RET_OK; } CHKiRet(localRet); CHKiRet(rsyslogd_InitStdRatelimiters()); if (bChDirRoot) { if (chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); } if (iConfigVerify) FINALIZE; /* after this point, we are in a "real" startup */ thrdInit(); CHKiRet(checkStartupOK()); if (doFork) { parentPipeFD = forkRsyslog(); } glblSetOurPid(getpid()); hdlr_enable(SIGPIPE, SIG_IGN); hdlr_enable(SIGXFSZ, SIG_IGN); if (Debug || loadConf->globals.permitCtlC) { hdlr_enable(SIGUSR1, rsyslogdDebugSwitch); hdlr_enable(SIGINT, rsyslogdDoDie); hdlr_enable(SIGQUIT, rsyslogdDoDie); } else { hdlr_enable(SIGUSR1, SIG_IGN); hdlr_enable(SIGINT, SIG_IGN); hdlr_enable(SIGQUIT, SIG_IGN); } hdlr_enable(SIGTERM, rsyslogdDoDie); hdlr_enable(SIGCHLD, hdlr_sigchld); hdlr_enable(SIGHUP, hdlr_sighup); if (rsconfNeedDropPriv(loadConf)) { /* need to write pid file early as we may loose permissions */ CHKiRet(writePidFile()); } CHKiRet(rsconf.Activate(ourConf)); if (runConf->globals.bLogStatusMsgs) { char bufStartUpMsg[512]; snprintf(bufStartUpMsg, sizeof(bufStartUpMsg), "[origin software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"https://www.rsyslog.com\"] start", (int)glblGetOurPid()); logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, (uchar *)bufStartUpMsg, 0); } if (!rsconfNeedDropPriv(runConf)) { CHKiRet(writePidFile()); } /* END OF INTIALIZATION */ DBGPRINTF("rsyslogd: initialization completed, transitioning to regular run mode\n"); if (doFork) { tellChildReady(parentPipeFD, "OK"); stddbg = -1; /* turn off writing to fd 1 */ close(1); close(2); runConf->globals.bErrMsgToStderr = 0; } finalize_it: if (iRet == RS_RET_VALIDATION_RUN) { fprintf(stderr, "rsyslogd: End of config validation run. Bye.\n"); exit(0); } else if (iRet != RS_RET_OK) { fprintf(stderr, "rsyslogd: run failed with error %d (see rsyslog.h " "or try https://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet * -1); exit(1); } } /* this function pulls all internal messages from the buffer * and puts them into the processing engine. * We can only do limited error handling, as this would not * really help us. TODO: add error messages? * rgerhards, 2007-08-03 */ void processImInternal(void) { smsg_t *pMsg; smsg_t *repMsg; while (iminternalRemoveMsg(&pMsg) == RS_RET_OK) { rsRetVal localRet = ratelimitMsg(internalMsg_ratelimiter, pMsg, &repMsg); if (repMsg != NULL) { logmsgInternal_doWrite(repMsg); } if (localRet == RS_RET_OK) { logmsgInternal_doWrite(pMsg); } } } /* This takes a received message that must be decoded and submits it to * the main message queue. This is a legacy function which is being provided * to aid older input plugins that do not support message creation via * the new interfaces themselves. It is not recommended to use this * function for new plugins. -- rgerhards, 2009-10-12 */ rsRetVal parseAndSubmitMessage(const uchar *const hname, const uchar *const hnameIP, const uchar *const msg, const int len, const int flags, const flowControl_t flowCtlType, prop_t *const pInputName, const struct syslogTime *const stTime, const time_t ttGenTime, ruleset_t *const pRuleset) { prop_t *pProp = NULL; smsg_t *pMsg = NULL; DEFiRet; /* we now create our own message object and submit it to the queue */ if (stTime == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); } if (pInputName != NULL) MsgSetInputName(pMsg, pInputName); MsgSetRawMsg(pMsg, (char *)msg, len); MsgSetFlowControlType(pMsg, flowCtlType); MsgSetRuleset(pMsg, pRuleset); pMsg->msgFlags = flags | NEEDS_PARSING; MsgSetRcvFromStr(pMsg, hname, ustrlen(hname), &pProp); CHKiRet(prop.Destruct(&pProp)); CHKiRet(MsgSetRcvFromIPStr(pMsg, hnameIP, ustrlen(hnameIP), &pProp)); CHKiRet(prop.Destruct(&pProp)); CHKiRet(submitMsg2(pMsg)); finalize_it: if (iRet != RS_RET_OK) { DBGPRINTF("parseAndSubmitMessage() error, discarding msg: %s\n", msg); if (pMsg != NULL) { msgDestruct(&pMsg); } } RETiRet; } /* helper to doHUP(), this "HUPs" each action. The necessary locking * is done inside the action class and nothing we need to take care of. * rgerhards, 2008-10-22 */ DEFFUNC_llExecFunc(doHUPActions) { actionCallHUPHdlr((action_t *)pData); return RS_RET_OK; /* we ignore errors, we can not do anything either way */ } /* This function processes a HUP after one has been detected. Note that this * is *NOT* the sighup handler. The signal is recorded by the handler, that record * detected inside the mainloop and then this function is called to do the * real work. -- rgerhards, 2008-10-22 * Note: there is a VERY slim chance of a data race when the hostname is reset. * We prefer to take this risk rather than sync all accesses, because to the best * of my analysis it can not really hurt (the actual property is reference-counted) * but the sync would require some extra CPU for *each* message processed. * rgerhards, 2012-04-11 */ static void doHUP(void) { char buf[512]; DBGPRINTF("doHUP: doing modules\n"); if (ourConf != NULL && ourConf->globals.bLogStatusMsgs) { snprintf(buf, sizeof(buf), "[origin software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"https://www.rsyslog.com\"] rsyslogd was HUPed", (int)glblGetOurPid()); errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, (uchar *)buf, 0); } queryLocalHostname(runConf); /* re-read our name */ ruleset.IterateAllActions(ourConf, doHUPActions, NULL); DBGPRINTF("doHUP: doing modules\n"); modDoHUP(); DBGPRINTF("doHUP: doing lookup tables\n"); lookupDoHUP(); DBGPRINTF("doHUP: doing errmsgs\n"); errmsgDoHUP(); } /* rsyslogdDoDie() is a signal handler. If called, it sets the bFinished variable * to indicate the program should terminate. However, it does not terminate * it itself, because that causes issues with multi-threading. The actual * termination is then done on the main thread. This solution might introduce * a minimal delay, but it is much cleaner than the approach of doing everything * inside the signal handler. * rgerhards, 2005-10-26 * Note: * - we do not call DBGPRINTF() as this may cause us to block in case something * with the threading is wrong. * - we do not really care about the return state of write(), but we need this * strange check we do to silence compiler warnings (thanks, Ubuntu!) */ void rsyslogdDoDie(int sig) { #define MSG1 "DoDie called.\n" #define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ dbgprintf(MSG1); if (Debug == DEBUG_FULL) { if (write(1, MSG1, sizeof(MSG1) - 1) == -1) { dbgprintf("%s:%d: write failed\n", __FILE__, __LINE__); } } if (iRetries++ == 4) { if (Debug == DEBUG_FULL) { if (write(1, MSG2, sizeof(MSG2) - 1) == -1) { dbgprintf("%s:%d: write failed\n", __FILE__, __LINE__); } } abort(); } bFinished = sig; if (runConf && runConf->globals.debugOnShutdown) { /* kind of hackish - set to 0, so that debug_swith will enable * and AND emit the "start debug log" message. */ debugging_on = 0; rsyslogdDebugSwitch(); } #undef MSG1 #undef MSG2 /* at least on FreeBSD we seem not to necessarily awake the main thread. * So let's do it explicitely. */ dbgprintf("awaking mainthread\n"); pthread_kill(mainthread, SIGTTIN); } static void wait_timeout(const sigset_t *sigmask) { struct timespec tvSelectTimeout; tvSelectTimeout.tv_sec = runConf->globals.janitorInterval * 60; /* interval is in minutes! */ tvSelectTimeout.tv_nsec = 0; #ifdef _AIX if (!src_exists) { /* it looks like select() is NOT interrupted by HUP, even though * SA_RESTART is not given in the signal setup. As this code is * not expected to be used in production (when running as a * service under src control), we simply make a kind of * "somewhat-busy-wait" algorithm. We compute our own * timeout value, which we count down to zero. We do this * in useful subsecond steps. */ const long wait_period = 500000000; /* wait period in nanoseconds */ int timeout = runConf->globals.janitorInterval * 60 * (1000000000 / wait_period); tvSelectTimeout.tv_sec = 0; tvSelectTimeout.tv_nsec = wait_period; do { pthread_mutex_lock(&mutHadHUP); if (bFinished || bHadHUP) { pthread_mutex_unlock(&mutHadHUP); break; } pthread_mutex_unlock(&mutHadHUP); pselect(1, NULL, NULL, NULL, &tvSelectTimeout, sigmask); } while (--timeout > 0); } else { char buf[256]; fd_set rfds; FD_ZERO(&rfds); FD_SET(SRC_FD, &rfds); if (pselect(SRC_FD + 1, (fd_set *)&rfds, NULL, NULL, &tvSelectTimeout, sigmask)) { if (FD_ISSET(SRC_FD, &rfds)) { rc = recvfrom(SRC_FD, &srcpacket, SRCMSG, 0, &srcaddr, &addrsz); if (rc < 0) { if (errno != EINTR) { fprintf(stderr, "%s: ERROR: '%d' recvfrom\n", progname, errno); exit(1); // TODO: this needs to be handled gracefully } else { /* punt on short read */ return; } switch (srcpacket.subreq.action) { case START: dosrcpacket(SRC_SUBMSG, "ERROR: rsyslogd does not support this " "option.\n", sizeof(struct srcrep)); break; case STOP: if (srcpacket.subreq.object == SUBSYSTEM) { dosrcpacket(SRC_OK, NULL, sizeof(struct srcrep)); (void)snprintf(buf, sizeof(buf) / sizeof(char), " [origin " "software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"https://www.rsyslog.com\"]" " exiting due to stopsrc.", (int)glblGetOurPid()); errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, (uchar *)buf, 0); return; } else dosrcpacket(SRC_SUBMSG, "ERROR: rsyslogd does not support " "this option.\n", sizeof(struct srcrep)); break; case REFRESH: dosrcpacket(SRC_SUBMSG, "ERROR: rsyslogd does not support this " "option.\n", sizeof(struct srcrep)); break; default: dosrcpacket(SRC_SUBICMD, NULL, sizeof(struct srcrep)); break; } } } } } #else pselect(0, NULL, NULL, NULL, &tvSelectTimeout, sigmask); #endif /* AIXPORT : SRC end */ } static void reapChild(void) { pid_t child; do { int status; child = waitpid(-1, &status, WNOHANG); if (child != -1 && child != 0) { glblReportChildProcessExit(runConf, NULL, child, status); } } while (child > 0); } /* This is the main processing loop. It is called after successful initialization. * When it returns, the syslogd terminates. * Its sole function is to provide some housekeeping things. The real work is done * by the other threads spawned. */ static void mainloop(void) { time_t tTime; sigset_t origmask; sigset_t sigblockset; int need_free_mutex; sigemptyset(&sigblockset); sigaddset(&sigblockset, SIGTERM); sigaddset(&sigblockset, SIGCHLD); sigaddset(&sigblockset, SIGHUP); do { sigemptyset(&origmask); pthread_sigmask(SIG_BLOCK, &sigblockset, &origmask); pthread_mutex_lock(&mutChildDied); need_free_mutex = 1; if (bChildDied) { bChildDied = 0; pthread_mutex_unlock(&mutChildDied); need_free_mutex = 0; reapChild(); } if (need_free_mutex) { pthread_mutex_unlock(&mutChildDied); } pthread_mutex_lock(&mutHadHUP); need_free_mutex = 1; if (bHadHUP) { need_free_mutex = 0; pthread_mutex_unlock(&mutHadHUP); doHUP(); pthread_mutex_lock(&mutHadHUP); bHadHUP = 0; pthread_mutex_unlock(&mutHadHUP); } if (need_free_mutex) { pthread_mutex_unlock(&mutHadHUP); } processImInternal(); if (bFinished) break; /* exit as quickly as possible */ wait_timeout(&origmask); pthread_sigmask(SIG_UNBLOCK, &sigblockset, NULL); janitorRun(); assert(datetime.GetTime != NULL); /* This is only to keep clang static analyzer happy */ datetime.GetTime(&tTime); checkGoneAwaySenders(tTime); } while (!bFinished); /* end do ... while() */ } /* Finalize and destruct all actions. */ static void rsyslogd_destructAllActions(void) { ruleset.DestructAllActions(runConf); PREFER_STORE_0_TO_INT(&bHaveMainQueue); /* flag that internal messages need to be temporarily stored */ } /* de-initialize everything, make ready for termination */ static void deinitAll(void) { char buf[256]; DBGPRINTF("exiting on signal %d\n", bFinished); /* IMPORTANT: we should close the inputs first, and THEN send our termination * message. If we do it the other way around, logmsgInternal() may block on * a full queue and the inputs still fill up that queue. Depending on the * scheduling order, we may end up with logmsgInternal being held for a quite * long time. When the inputs are terminated first, that should not happen * because the queue is drained in parallel. The situation could only become * an issue with extremely long running actions in a queue full environment. * However, such actions are at least considered poorly written, if not * outright wrong. So we do not care about this very remote problem. * rgerhards, 2008-01-11 */ /* close the inputs */ DBGPRINTF("Terminating input threads...\n"); glbl.SetGlobalInputTermination(); thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ if (bFinished && runConf->globals.bLogStatusMsgs) { (void)snprintf(buf, sizeof(buf), "[origin software=\"rsyslogd\" " "swVersion=\"" VERSION "\" x-pid=\"%d\" x-info=\"https://www.rsyslog.com\"]" " exiting on signal %d.", (int)glblGetOurPid(), bFinished); errno = 0; logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, (uchar *)buf, 0); } processImInternal(); /* make sure not-yet written internal messages are processed */ /* we sleep a couple of ms to give the queue a chance to pick up the late messages * (including exit message); otherwise we have seen cases where the message did * not make it to log files, even on idle systems. */ srSleep(0, 50); /* drain queue (if configured so) and stop main queue worker thread pool */ DBGPRINTF("Terminating main queue...\n"); qqueueDestruct(&runConf->pMsgQueue); runConf->pMsgQueue = NULL; /* Free ressources and close connections. This includes flushing any remaining * repeated msgs. */ DBGPRINTF("Terminating outputs...\n"); rsyslogd_destructAllActions(); DBGPRINTF("all primary multi-thread sources have been terminated - now doing aux cleanup...\n"); DBGPRINTF("destructing current config...\n"); rsconf.Destruct(&runConf); modExitIminternal(); if (pInternalInputName != NULL) prop.Destruct(&pInternalInputName); /* the following line cleans up CfSysLineHandlers that were not based on loadable * modules. As such, they are not yet cleared. */ unregCfSysLineHdlrs(); /* this is the last spot where this can be done - below output modules are unloaded! */ parserClassExit(); rsconfClassExit(); strExit(); ratelimitModExit(); dnscacheDeinit(); thrdExit(); objRelease(net, LM_NET_FILENAME); module.UnloadAndDestructAll(eMOD_LINK_ALL); rsrtExit(); /* runtime MUST always be deinitialized LAST (except for debug system) */ DBGPRINTF("Clean shutdown completed, bye\n"); errmsgExit(); /* dbgClassExit MUST be the last one, because it de-inits the debug system */ dbgClassExit(); /* NO CODE HERE - dbgClassExit() must be the last thing before exit()! */ clearPidFile(); } /* This is the main entry point into rsyslogd. This must be a function in its own * right in order to initialize the debug system in a portable way (otherwise we would * need to have a statement before variable definitions. * rgerhards, 20080-01-28 */ int main(int argc, char **argv) { #if defined(_AIX) /* SRC support : fd 0 (stdin) must be the SRC socket * startup. fd 0 is duped to a new descriptor so that stdin can be used * internally by rsyslogd. */ pthread_mutex_init(&mutHadHUP, NULL); pthread_mutex_init(&mutChildDied, NULL); strncpy(progname, argv[0], sizeof(progname) - 1); addrsz = sizeof(srcaddr); if ((rc = getsockname(0, &srcaddr, &addrsz)) < 0) { fprintf(stderr, "%s: continuing without SRC support\n", progname); src_exists = FALSE; } if (src_exists) if (dup2(0, SRC_FD) == -1) { fprintf(stderr, "%s: dup2 failed exiting now...\n", progname); /* In the unlikely event of dup2 failing we exit */ exit(-1); } #endif mainthread = pthread_self(); if ((int)getpid() == 1) { fprintf(stderr, "rsyslogd %s: running as pid 1, enabling " "container-specific defaults, press ctl-c to " "terminate rsyslog\n", VERSION); PidFile = strdup("NONE"); /* disables pid file writing */ glblPermitCtlC = 1; runningInContainer = 1; emitTZWarning = 1; } else { /* "dynamic defaults" - non-container case */ PidFile = strdup(PATH_PIDFILE); } if (PidFile == NULL) { fprintf(stderr, "rsyslogd: could not alloc memory for pid file " "default name - aborting\n"); exit(1); } /* disable case-sensitive comparisons in variable subsystem: */ fjson_global_do_case_sensitive_comparison(0); dbgClassInit(); initAll(argc, argv); #ifdef HAVE_LIBSYSTEMD sd_notify(0, "READY=1"); dbgprintf("done signaling to systemd that we are ready!\n"); #endif DBGPRINTF("max message size: %d\n", glblGetMaxLine(runConf)); DBGPRINTF("----RSYSLOGD INITIALIZED\n"); LogMsg(0, RS_RET_OK, LOG_DEBUG, "rsyslogd fully started up and initialized " "- begin actual processing"); mainloop(); LogMsg(0, RS_RET_OK, LOG_DEBUG, "rsyslogd shutting down"); deinitAll(); osf_close(); pthread_mutex_destroy(&mutChildDied); pthread_mutex_destroy(&mutHadHUP); return 0; } rsyslog-8.2512.0/tools/PaxHeaders/msggen.c0000644000000000000000000000013215055605325015323 xustar0030 mtime=1756826325.659800834 30 atime=1764931133.273193792 30 ctime=1764935924.104590681 rsyslog-8.2512.0/tools/msggen.c0000664000175000017500000000211015055605325014761 0ustar00rgerrger/* msggen - a small diagnostic utility that does very quick * syslog() calls. * * Copyright 2008-2014 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include int main(int __attribute__((unused)) argc, char __attribute__((unused)) * argv[]) { int i; openlog("msggen", 0, LOG_LOCAL0); for (i = 0; i < 10; ++i) syslog(LOG_NOTICE, "This is message number %d", i); closelog(); return 0; } rsyslog-8.2512.0/tools/PaxHeaders/omfwd.h0000644000000000000000000000013215055605325015164 xustar0030 mtime=1756826325.660800849 30 atime=1764930982.710723203 30 ctime=1764935924.131591094 rsyslog-8.2512.0/tools/omfwd.h0000664000175000017500000000232515055605325014632 0ustar00rgerrger/* omfwd.h * These are the definitions for the build-in forwarding output module. * * File begun on 2007-07-13 by RGerhards * * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OMFWD_H_INCLUDED #define OMFWD_H_INCLUDED 1 /* prototypes */ rsRetVal modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal (**)()), modInfo_t *); #endif /* #ifndef OMFWD_H_INCLUDED */ /* * vi:set ai: */ rsyslog-8.2512.0/PaxHeaders/runtime0000644000000000000000000000013215114544363014145 xustar0030 mtime=1764935923.422580239 30 atime=1764935930.037681508 30 ctime=1764935923.422580239 rsyslog-8.2512.0/runtime/0000775000175000017500000000000015114544363013666 5ustar00rgerrgerrsyslog-8.2512.0/runtime/PaxHeaders/tcpclt.c0000644000000000000000000000013215055605325015657 xustar0030 mtime=1756826325.653800744 30 atime=1764931018.105312073 30 ctime=1764935923.400579903 rsyslog-8.2512.0/runtime/tcpclt.c0000664000175000017500000004353715055605325015337 0ustar00rgerrger/* tcpclt.c * * This is the implementation of TCP-based syslog clients (the counterpart * of the tcpsrv class). * * Copyright 2007-2024 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #if HAVE_FCNTL_H #include #endif #include "rsyslog.h" #include "dirty.h" #include "syslogd-types.h" #include "net.h" #include "tcpclt.h" #include "module-template.h" #include "srUtils.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; /* Initialize TCP sockets (for sender) */ static int CreateSocket(struct addrinfo *addrDest) { int fd; struct addrinfo *r; r = addrDest; while (r != NULL) { fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol); if (fd != -1) { /* We can not allow the TCP sender to block syslogd, at least * not in a single-threaded design. That would cause rsyslogd to * loose input messages - which obviously also would affect * other selector lines, too. So we do set it to non-blocking and * handle the situation ourselfs (by discarding messages). IF we run * dual-threaded, however, the situation is different: in this case, * the receivers and the selector line processing are only loosely * coupled via a memory buffer. Now, I think, we can afford the extra * wait time. Thus, we enable blocking mode for TCP if we compile with * pthreads. -- rgerhards, 2005-10-25 * And now, we always run on multiple threads... -- rgerhards, 2007-12-20 */ if (connect(fd, r->ai_addr, r->ai_addrlen) != 0) { if (errno == EINPROGRESS) { /* this is normal - will complete later select */ return fd; } else { char errStr[1024]; dbgprintf("create tcp connection failed, reason %s", rs_strerror_r(errno, errStr, sizeof(errStr))); } } else { return fd; } close(fd); } else { char errStr[1024]; dbgprintf("couldn't create send socket, reason %s", rs_strerror_r(errno, errStr, sizeof(errStr))); } r = r->ai_next; } dbgprintf("no working socket could be obtained"); return -1; } /* Build frame based on selected framing * This function was created by pulling code from TCPSend() * on 2007-12-27 by rgerhards. Older comments are still relevant. * * In order to support compressed messages via TCP, we must support an * octet-counting based framing (LF may be part of the compressed message). * We are now supporting the same mode that is available in IETF I-D * syslog-transport-tls-05 (current at the time of this writing). This also * eases things when we go ahead and implement that framing. I have now made * available two cases where this framing is used: either by explitely * specifying it in the config file or implicitely when sending a compressed * message. In the later case, compressed and uncompressed messages within * the same session have different framings. If it is explicitely set to * octet-counting, only this framing mode is used within the session. * rgerhards, 2006-12-07 */ static rsRetVal TCPSendBldFrame(tcpclt_t *pThis, char **pmsg, size_t *plen, int *pbMustBeFreed) { DEFiRet; TCPFRAMINGMODE framingToUse; int bIsCompressed; size_t len; char *msg; char *buf = NULL; /* if this is non-NULL, it MUST be freed before return! */ assert(plen != NULL); assert(pbMustBeFreed != NULL); assert(pmsg != NULL); msg = *pmsg; len = *plen; bIsCompressed = *msg == 'z'; /* cache this, so that we can modify the message buffer */ /* select framing for this record. If we have a compressed record, we always need to * use octet counting because the data potentially contains all control characters * including LF. */ framingToUse = bIsCompressed ? TCP_FRAMING_OCTET_COUNTING : pThis->tcp_framing; /* now check if we need to add a line terminator. We need to * copy the string in memory in this case, this is probably * quicker than using writev and definitely quicker than doing * two socket calls. * rgerhards 2005-07-22 * * Some messages already contain a \n character at the end * of the message. We append one only if we there is not * already one. This seems the best fit, though this also * means the message does not arrive unaltered at the final * destination. But in the spirit of legacy syslog, this is * probably the best to do... * rgerhards 2005-07-20 */ /* Build frame based on selected framing */ if (framingToUse == TCP_FRAMING_OCTET_STUFFING) { if ((*(msg + len - 1) != pThis->tcp_framingDelimiter)) { /* in the malloc below, we need to add 2 to the length. The * reason is that we a) add one character and b) len does * not take care of the '\0' byte. Up until today, it was just * +1 , which caused rsyslogd to sometimes dump core. * I have added this comment so that the logic is not accidently * changed again. rgerhards, 2005-10-25 */ if ((buf = malloc(len + 2)) == NULL) { /* extreme mem shortage, try to solve * as good as we can. No point in calling * any alarms, they might as well run out * of memory (the risk is very high, so we * do NOT risk that). If we have a message of * more than 1 byte (what I guess), we simply * overwrite the last character. * rgerhards 2005-07-22 */ if (len > 1) { *(msg + len - 1) = pThis->tcp_framingDelimiter; } else { /* we simply can not do anything in * this case (its an error anyhow...). */ } } else { /* we got memory, so we can copy the message */ memcpy(buf, msg, len); /* do not copy '\0' */ *(buf + len) = pThis->tcp_framingDelimiter; *(buf + len + 1) = '\0'; msg = buf; /* use new one */ ++len; /* care for the \n */ } } } else { /* Octect-Counting * In this case, we need to always allocate a buffer. This is because * we need to put a header in front of the message text */ char szLenBuf[16]; int iLenBuf; /* important: the printf-mask is "%d" because there must be a * space after the len! *//* The chairs of the IETF syslog-sec WG have announced that it is * consensus to do the octet count on the SYSLOG-MSG part only. I am * now changing the code to reflect this. Hopefully, it will not change * once again (there can no compatibility layer programmed for this). * To be on the save side, I just comment the code out. I mark these * comments with "IETF20061218". * rgerhards, 2006-12-19 */ iLenBuf = snprintf(szLenBuf, sizeof(szLenBuf), "%d ", (int)len); /* IETF20061218 iLenBuf = snprintf(szLenBuf, sizeof(szLenBuf), "%d ", len + iLenBuf);*/ if ((buf = malloc(len + iLenBuf)) == NULL) { /* we are out of memory. This is an extreme situation. We do not * call any alarm handlers because they most likely run out of mem, * too. We are brave enough to call debug output, though. Other than * that, there is nothing left to do. We can not sent the message (as * in case of the other framing, because the message is incomplete. * We could, however, send two chunks (header and text separate), but * that would cause a lot of complexity in the code. So we think it * is appropriate enough to just make sure we do not crash in this * very unlikely case. For this, it is justified just to loose * the message. Rgerhards, 2006-12-07 */ dbgprintf( "Error: out of memory when building TCP octet-counted " "frame. Message is lost, trying to continue.\n"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } memcpy(buf, szLenBuf, iLenBuf); /* header */ memcpy(buf + iLenBuf, msg, len); /* message */ len += iLenBuf; /* new message size */ msg = buf; /* set message buffer */ } /* frame building complete, on to actual sending */ *plen = len; if (buf == NULL) { /* msg not modified */ *pbMustBeFreed = 0; } else { *pmsg = msg; *pbMustBeFreed = 1; } finalize_it: RETiRet; } /* Sends a TCP message. It is first checked if the * session is open and, if not, it is opened. Then the send * is tried. If it fails, one silent re-try is made. If the send * fails again, an error status (-1) is returned. If all goes well, * 0 is returned. The TCP session is NOT torn down. * For now, EAGAIN is ignored (causing message loss) - but it is * hard to do something intelligent in this case. With this * implementation here, we can not block and/or defer. Things are * probably a bit better when we move to liblogging. The alternative * would be to enhance the current select server with buffering and * write descriptors. This seems not justified, given the expected * short life span of this code (and the unlikeliness of this event). * rgerhards 2005-07-06 * This function is now expected to stay. Libloging won't be used for * that purpose. I have added the param "len", because it is known by the * caller and so saves us some time. Also, it MUST be given because there * may be NULs inside msg so that we can not rely on strlen(). Please note * that the restrictions outlined above do not existin in multi-threaded * mode, which we assume will now be most often used. So there is no * real issue with the potential message loss in single-threaded builds. * rgerhards, 2006-11-30 * I greatly restructured the function to be more generic and work * with function pointers. So it now can be used with any type of transport, * as long as it follows stream semantics. This was initially done to * support plain TCP and GSS via common code. */ static int Send(tcpclt_t *pThis, void *pData, char *msg, size_t len) { DEFiRet; int bDone = 0; int retry = 0; int bMsgMustBeFreed = 0; /* must msg be freed at end of function? 0 - no, 1 - yes */ ISOBJ_TYPE_assert(pThis, tcpclt); assert(pData != NULL); assert(msg != NULL); assert(len > 0); CHKiRet(TCPSendBldFrame(pThis, &msg, &len, &bMsgMustBeFreed)); while (!bDone) { /* loop is broken when send succeeds or error occurs */ CHKiRet(pThis->initFunc(pData)); iRet = pThis->sendFunc(pData, msg, len); if (iRet == RS_RET_OK || iRet == RS_RET_DEFER_COMMIT || iRet == RS_RET_PREVIOUS_COMMITTED) { /* we are done, we also use this as indication that the previous * message was succesfully received (it's not always the case, but its at * least our best shot at it -- rgerhards, 2008-03-12 * As of 2008-06-09, we have implemented an algorithm which detects connection * loss quite good in some (common) scenarios. Thus, the probability of * message duplication due to the code below has increased. We so now have * a config setting, default off, that enables the user to request retransmits. * However, if not requested, we do NOT need to do all the stuff needed for it. */ if (pThis->bResendLastOnRecon == 1) { if (pThis->prevMsg != NULL) free(pThis->prevMsg); /* if we can not alloc a new buffer, we silently ignore it. The worst that * happens is that we lose our message recovery buffer - anything else would * be worse, so don't try anything ;) -- rgerhards, 2008-03-12 */ if ((pThis->prevMsg = malloc(len)) != NULL) { memcpy(pThis->prevMsg, msg, len); pThis->lenPrevMsg = len; } } /* we are done with this record */ bDone = 1; } else { if (retry == 0) { /* OK, one retry */ ++retry; CHKiRet(pThis->prepRetryFunc(pData)); /* try to recover */ /* now try to send our stored previous message (which most probably * didn't make it. Note that if bResendLastOnRecon is 0, prevMsg will * never become non-NULL, so the check below covers all cases. */ if (pThis->prevMsg != NULL) { CHKiRet(pThis->initFunc(pData)); CHKiRet(pThis->sendFunc(pData, pThis->prevMsg, pThis->lenPrevMsg)); } } else { /* OK, max number of retries reached, nothing we can do */ bDone = 1; } } } finalize_it: if (bMsgMustBeFreed) free(msg); RETiRet; } /* set functions */ static rsRetVal SetResendLastOnRecon(tcpclt_t *pThis, const int bResendLastOnRecon) { pThis->bResendLastOnRecon = (short)bResendLastOnRecon; return RS_RET_OK; } static rsRetVal SetSendInit(tcpclt_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->initFunc = pCB; RETiRet; } static rsRetVal SetSendPrepRetry(tcpclt_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->prepRetryFunc = pCB; RETiRet; } static rsRetVal SetSendFrame(tcpclt_t *pThis, rsRetVal (*pCB)(void *, char *, size_t)) { DEFiRet; pThis->sendFunc = pCB; RETiRet; } static rsRetVal SetFraming(tcpclt_t *pThis, TCPFRAMINGMODE framing) { DEFiRet; pThis->tcp_framing = framing; RETiRet; } static rsRetVal SetFramingDelimiter(tcpclt_t *pThis, uchar tcp_framingDelimiter) { DEFiRet; pThis->tcp_framingDelimiter = tcp_framingDelimiter; RETiRet; } /* Standard-Constructor */ BEGINobjConstruct(tcpclt) /* be sure to specify the object type also in END macro! */ pThis->tcp_framingDelimiter = '\n'; ENDobjConstruct(tcpclt) /* ConstructionFinalizer */ static rsRetVal tcpcltConstructFinalize(tcpclt_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpclt); RETiRet; } /* destructor for the tcpclt object */ BEGINobjDestruct(tcpclt) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(tcpclt); if (pThis->prevMsg != NULL) free(pThis->prevMsg); ENDobjDestruct(tcpclt) /* ------------------------------ handling the interface plumbing ------------------------------ */ /* queryInterface function * rgerhards, 2008-03-12 */ BEGINobjQueryInterface(tcpclt) CODESTARTobjQueryInterface(tcpclt); if (pIf->ifVersion != tcpcltCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = tcpcltConstruct; pIf->ConstructFinalize = tcpcltConstructFinalize; pIf->Destruct = tcpcltDestruct; pIf->CreateSocket = CreateSocket; pIf->Send = Send; /* set functions */ pIf->SetResendLastOnRecon = SetResendLastOnRecon; pIf->SetSendInit = SetSendInit; pIf->SetSendFrame = SetSendFrame; pIf->SetSendPrepRetry = SetSendPrepRetry; pIf->SetFraming = SetFraming; pIf->SetFramingDelimiter = SetFramingDelimiter; finalize_it: ENDobjQueryInterface(tcpclt) /* exit our class * rgerhards, 2008-03-10 */ BEGINObjClassExit(tcpclt, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(tcpclt); /* release objects we no longer need */ ENDObjClassExit(tcpclt) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-29 */ BEGINObjClassInit(tcpclt, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */ /* request objects we use */ /* set our own handlers */ OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, tcpcltConstructFinalize); ENDObjClassInit(tcpclt) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; /* de-init in reverse order! */ tcpcltClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(tcpcltClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/zstdw.c0000644000000000000000000000013215055605325015541 xustar0030 mtime=1756826325.655800774 30 atime=1764931015.169263427 30 ctime=1764935923.419580194 rsyslog-8.2512.0/runtime/zstdw.c0000664000175000017500000001341415055605325015210 0ustar00rgerrger/* The zstdw object. * * This is an rsyslog object wrapper around zstd. * * Copyright 2022 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "errmsg.h" #include "stream.h" #include "module-template.h" #include "obj.h" #include "zstdw.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; /* finish buffer, to be called before closing the zstd file. */ static rsRetVal zstd_doCompressFinish(strm_t *pThis, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)) { size_t remaining = 0; DEFiRet; assert(pThis != NULL); if (!pThis->bzInitDone) goto done; char dummybuf; /* not sure if we can pass in NULL as buffer address in this special case */ ZSTD_inBuffer input = {&dummybuf, 0, 0}; do { ZSTD_outBuffer output = {pThis->pZipBuf, pThis->sIOBufSize, 0}; remaining = ZSTD_compressStream2(pThis->zstd.cctx, &output, &input, ZSTD_e_end); if (ZSTD_isError(remaining)) { LogError(0, RS_RET_ZLIB_ERR, "error returned from ZSTD_compressStream2(): %s\n", ZSTD_getErrorName(remaining)); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } CHKiRet(strmPhysWrite(pThis, (uchar *)pThis->pZipBuf, output.pos)); } while (remaining != 0); finalize_it: done: RETiRet; } static rsRetVal zstd_doStrmWrite(strm_t *pThis, uchar *const pBuf, const size_t lenBuf, const int bFlush, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)) { DEFiRet; assert(pThis != NULL); assert(pBuf != NULL); if (!pThis->bzInitDone) { pThis->zstd.cctx = (void *)ZSTD_createCCtx(); if (pThis->zstd.cctx == NULL) { LogError(0, RS_RET_ZLIB_ERR, "error creating zstd context (ZSTD_createCCtx failed, " "that's all we know"); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } ZSTD_CCtx_setParameter(pThis->zstd.cctx, ZSTD_c_compressionLevel, pThis->iZipLevel); ZSTD_CCtx_setParameter(pThis->zstd.cctx, ZSTD_c_checksumFlag, 1); if (pThis->zstd.num_wrkrs > 0) { ZSTD_CCtx_setParameter(pThis->zstd.cctx, ZSTD_c_nbWorkers, pThis->zstd.num_wrkrs); } pThis->bzInitDone = RSTRUE; } /* now doing the compression */ ZSTD_inBuffer input = {pBuf, lenBuf, 0}; // This following needs to be configurable? It's possibly sufficient to use e_flush // only, as this can also be controlled by veryRobustZip. However, testbench will than // not be able to check when all file lines are complete. ZSTD_EndDirective const mode = bFlush ? ZSTD_e_flush : ZSTD_e_continue; size_t remaining; do { ZSTD_outBuffer output = {pThis->pZipBuf, 128, 0}; remaining = ZSTD_compressStream2(pThis->zstd.cctx, &output, &input, mode); if (ZSTD_isError(remaining)) { LogError(0, RS_RET_ZLIB_ERR, "error returned from ZSTD_compressStream2(): %s", ZSTD_getErrorName(remaining)); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } CHKiRet(strmPhysWrite(pThis, (uchar *)pThis->pZipBuf, output.pos)); } while (mode == ZSTD_e_end ? (remaining != 0) : (input.pos != input.size)); finalize_it: if (pThis->bzInitDone && pThis->bVeryReliableZip) { zstd_doCompressFinish(pThis, strmPhysWrite); } RETiRet; } /* destruction of caller's zstd ressources */ static rsRetVal zstd_Destruct(strm_t *const pThis) { DEFiRet; assert(pThis != NULL); if (!pThis->bzInitDone) goto done; const int result = ZSTD_freeCCtx(pThis->zstd.cctx); if (ZSTD_isError(result)) { LogError(0, RS_RET_ZLIB_ERR, "error from ZSTD_freeCCtx(): %s", ZSTD_getErrorName(result)); } pThis->bzInitDone = 0; done: RETiRet; } /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(zstdw) CODESTARTobjQueryInterface(zstdw); if (pIf->ifVersion != zstdwCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } pIf->doStrmWrite = zstd_doStrmWrite; pIf->doCompressFinish = zstd_doCompressFinish; pIf->Destruct = zstd_Destruct; finalize_it: ENDobjQueryInterface(zstdw) /* Initialize the zstdw class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(zstdw, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ ENDObjClassInit(zstdw) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CHKiRet(zstdwClassInit(pModInfo)); ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/tcpclt.h0000644000000000000000000000013215055605325015664 xustar0030 mtime=1756826325.653800744 30 atime=1764931018.209313795 30 ctime=1764935923.403579949 rsyslog-8.2512.0/runtime/tcpclt.h0000664000175000017500000000517515055605325015340 0ustar00rgerrger/* tcpclt.h * * This are the definitions for the TCP based clients class. * * File begun on 2007-07-21 by RGerhards (extracted from syslogd.c) * * Copyright 2007-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef TCPCLT_H_INCLUDED #define TCPCLT_H_INCLUDED 1 #include "obj.h" /* the tcpclt object */ typedef struct tcpclt_s { BEGINobjInstance ; /**< Data to implement generic object - MUST be the first data element! */ TCPFRAMINGMODE tcp_framing; uchar tcp_framingDelimiter; char *prevMsg; short bResendLastOnRecon; /* should the last message be resent on a successful reconnect? */ size_t lenPrevMsg; /* session specific callbacks */ int iNumMsgs; /* number of messages during current "rebind session" */ rsRetVal (*initFunc)(void *); rsRetVal (*sendFunc)(void *, char *, size_t); rsRetVal (*prepRetryFunc)(void *); } tcpclt_t; /* interfaces */ BEGINinterface(tcpclt) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(tcpclt_t **ppThis); rsRetVal (*ConstructFinalize)(tcpclt_t __attribute__((unused)) * pThis); rsRetVal (*Destruct)(tcpclt_t **ppThis); int (*Send)(tcpclt_t *pThis, void *pData, char *msg, size_t len); int (*CreateSocket)(struct addrinfo *addrDest); /* set methods */ rsRetVal (*SetResendLastOnRecon)(tcpclt_t *, int); rsRetVal (*SetSendInit)(tcpclt_t *, rsRetVal (*)(void *)); rsRetVal (*SetSendFrame)(tcpclt_t *, rsRetVal (*)(void *, char *, size_t)); rsRetVal (*SetSendPrepRetry)(tcpclt_t *, rsRetVal (*)(void *)); rsRetVal (*SetFraming)(tcpclt_t *, TCPFRAMINGMODE framing); /* v4, 2017-06-10*/ rsRetVal (*SetFramingDelimiter)(tcpclt_t *, uchar tcp_framingDelimiter); ENDinterface(tcpclt) #define tcpcltCURR_IF_VERSION 5 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(tcpclt); /* the name of our library binary */ #define LM_TCPCLT_FILENAME "lmtcpclt" #endif /* #ifndef TCPCLT_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/linkedlist.h0000644000000000000000000000013215055605325016535 xustar0030 mtime=1756826325.646800638 30 atime=1764930980.040678557 30 ctime=1764935923.169576366 rsyslog-8.2512.0/runtime/linkedlist.h0000664000175000017500000000601215055605325016200 0ustar00rgerrger/* Definition of the linkedlist object. * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LINKEDLIST_H_INCLUDED #define LINKEDLIST_H_INCLUDED /* this is a single entry for a parse routine. It describes exactly * one entry point/handler. * The short name is cslch (Configfile SysLine CommandHandler) */ struct llElt_s { /* config file sysline parse entry */ struct llElt_s *pNext; void *pKey; /* key for this element */ void *pData; /* user-supplied data pointer */ }; typedef struct llElt_s llElt_t; /* this is the list of known configuration commands with pointers to * their handlers. * The short name is cslc (Configfile SysLine Command) */ struct linkedList_s { /* config file sysline parse entry */ int iNumElts; /* number of elements in list */ rsRetVal (*pEltDestruct)(void *pData); /* destructor for user pointer in llElt_t's */ rsRetVal (*pKeyDestruct)(void *pKey); /* destructor for key pointer in llElt_t's */ int (*cmpOp)(void *, void *); /* pointer to key compare operation function, retval like strcmp */ void *pKey; /* the list key (searchable, if set) */ llElt_t *pRoot; /* list root */ llElt_t *pLast; /* list tail */ }; typedef struct linkedList_s linkedList_t; typedef llElt_t *linkedListCookie_t; /* this type avoids exposing internals and keeps us flexible */ /* prototypes */ rsRetVal llInit(linkedList_t *pThis, rsRetVal (*pEltDestructor)(void *), rsRetVal (*pKeyDestructor)(void *), int (*pCmpOp)(void *, void *)); rsRetVal llDestroy(linkedList_t *pThis); rsRetVal llDestroyRootElt(linkedList_t *pThis); rsRetVal llGetNextElt(linkedList_t *pThis, linkedListCookie_t *ppElt, void **ppUsr); rsRetVal llAppend(linkedList_t *pThis, void *pKey, void *pData); rsRetVal llFind(linkedList_t *pThis, void *pKey, void **ppData); rsRetVal llGetKey(llElt_t *pThis, void *ppData); rsRetVal llGetNumElts(linkedList_t *pThis, int *piCnt); rsRetVal llExecFunc(linkedList_t *pThis, rsRetVal (*pFunc)(void *, void *), void *pParam); rsRetVal llFindAndDelete(linkedList_t *pThis, void *pKey); /* use the macro below to define a function that will be executed by * llExecFunc() */ #define DEFFUNC_llExecFunc(funcName) \ static rsRetVal funcName(void __attribute__((unused)) * pData, void __attribute__((unused)) * pParam) #endif /* #ifndef LINKEDLIST_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/perctile_ringbuf.h0000644000000000000000000000013215055605325017716 xustar0030 mtime=1756826325.650800698 30 atime=1764930991.594871526 30 ctime=1764935923.227577254 rsyslog-8.2512.0/runtime/perctile_ringbuf.h0000664000175000017500000000156415055605325017370 0ustar00rgerrger#include #include typedef int64_t ITEM; struct circ_buf { ITEM *buf; int head; int tail; }; struct ringbuf_s { struct circ_buf cb; size_t size; }; typedef struct ringbuf_s ringbuf_t; ringbuf_t *ringbuf_new(size_t count); void ringbuf_del(ringbuf_t *rb); int ringbuf_append(ringbuf_t *rb, ITEM item); int ringbuf_append_with_overwrite(ringbuf_t *rb, ITEM item); int ringbuf_read(ringbuf_t *rb, ITEM *buf, size_t count); size_t ringbuf_read_to_end(ringbuf_t *rb, ITEM *buf, size_t count); bool ringbuf_peek(ringbuf_t *rb, ITEM *item); size_t ringbuf_capacity(ringbuf_t *rb); /* ringbuffer tests */ void ringbuf_init_test(void); void ringbuf_simple_test(void); void ringbuf_append_test(void); void ringbuf_append_wrap_test(void); void ringbuf_append_overwrite_test(void); void ringbuf_read_test(void); void ringbuf_read_to_end_test(void); rsyslog-8.2512.0/runtime/PaxHeaders/ruleset.c0000644000000000000000000000013215073421710016043 xustar0030 mtime=1760437192.757710634 30 atime=1764930995.803941676 30 ctime=1764935923.258577729 rsyslog-8.2512.0/runtime/ruleset.c0000664000175000017500000011172715073421710015520 0ustar00rgerrger/* ruleset.c - rsyslog's ruleset object * * We have a two-way structure of linked lists: one config-specifc linked list * (conf->rulesets.llRulesets) hold alls rule sets that we know. Included in each * list is a list of rules (which contain a list of actions, but that's * a different story). * * Usually, only a single rule set is executed. However, there exist some * situations where all rules must be iterated over, for example on HUP. Thus, * we also provide interfaces to do that. * * Module begun 2009-06-10 by Rainer Gerhards * * Copyright 2009-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "obj.h" #include "cfsysline.h" #include "msg.h" #include "ruleset.h" #include "errmsg.h" #include "parser.h" #include "batch.h" #include "unicode-helper.h" #include "rsconf.h" #include "action.h" #include "rainerscript.h" #include "srUtils.h" #include "modules.h" #include "wti.h" #include "dirty.h" /* for main ruleset queue creation */ /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(parser) /* tables for interfacing with the v6 config system (as far as we need to) */ static struct cnfparamdescr rspdescr[] = {{"name", eCmdHdlrString, CNFPARAM_REQUIRED}, {"parser", eCmdHdlrArray, 0}}; static struct cnfparamblk rspblk = {CNFPARAMBLK_VERSION, sizeof(rspdescr) / sizeof(struct cnfparamdescr), rspdescr}; /* forward definitions */ static rsRetVal processBatch(batch_t *pBatch, wti_t *pWti); static rsRetVal scriptExec(struct cnfstmt *root, smsg_t *pMsg, wti_t *pWti); /* ---------- linked-list key handling functions (ruleset) ---------- */ /* destructor for linked list keys. */ rsRetVal rulesetKeyDestruct(void __attribute__((unused)) * pData) { free(pData); return RS_RET_OK; } /* ---------- END linked-list key handling functions (ruleset) ---------- */ /* iterate over all actions in a script (stmt subtree) */ static void scriptIterateAllActions(struct cnfstmt *root, rsRetVal (*pFunc)(void *, void *), void *pParam) { struct cnfstmt *stmt; for (stmt = root; stmt != NULL; stmt = stmt->next) { switch (stmt->nodetype) { case S_NOP: case S_STOP: case S_SET: case S_UNSET: case S_CALL_INDIRECT: case S_CALL: /* call does not need to do anything - done in called ruleset! */ break; case S_ACT: DBGPRINTF("iterateAllActions calling into action %p\n", stmt->d.act); pFunc(stmt->d.act, pParam); break; case S_IF: if (stmt->d.s_if.t_then != NULL) scriptIterateAllActions(stmt->d.s_if.t_then, pFunc, pParam); if (stmt->d.s_if.t_else != NULL) scriptIterateAllActions(stmt->d.s_if.t_else, pFunc, pParam); break; case S_FOREACH: if (stmt->d.s_foreach.body != NULL) scriptIterateAllActions(stmt->d.s_foreach.body, pFunc, pParam); break; case S_PRIFILT: if (stmt->d.s_prifilt.t_then != NULL) scriptIterateAllActions(stmt->d.s_prifilt.t_then, pFunc, pParam); if (stmt->d.s_prifilt.t_else != NULL) scriptIterateAllActions(stmt->d.s_prifilt.t_else, pFunc, pParam); break; case S_PROPFILT: scriptIterateAllActions(stmt->d.s_propfilt.t_then, pFunc, pParam); break; case S_RELOAD_LOOKUP_TABLE: /* this is a NOP */ break; default: dbgprintf("error: unknown stmt type %u during iterateAll\n", (unsigned)stmt->nodetype); #ifndef NDEBUG fprintf(stderr, "error: unknown stmt type %u during iterateAll\n", (unsigned)stmt->nodetype); #endif assert(0); /* abort under debugging */ break; } } } /* driver to iterate over all of this ruleset actions */ typedef struct iterateAllActions_s { rsRetVal (*pFunc)(void *, void *); void *pParam; } iterateAllActions_t; /* driver to iterate over all actions */ DEFFUNC_llExecFunc(doIterateAllActions) { DEFiRet; ruleset_t *pThis = (ruleset_t *)pData; iterateAllActions_t *pMyParam = (iterateAllActions_t *)pParam; scriptIterateAllActions(pThis->root, pMyParam->pFunc, pMyParam->pParam); RETiRet; } /* iterate over ALL actions present in the WHOLE system. * this is often needed, for example when HUP processing * must be done or a shutdown is pending. */ static rsRetVal iterateAllActions(rsconf_t *conf, rsRetVal (*pFunc)(void *, void *), void *pParam) { iterateAllActions_t params; DEFiRet; assert(pFunc != NULL); params.pFunc = pFunc; params.pParam = pParam; CHKiRet(llExecFunc(&(conf->rulesets.llRulesets), doIterateAllActions, ¶ms)); finalize_it: RETiRet; } /* driver to iterate over all rulesets */ DEFFUNC_llExecFunc(doActivateRulesetQueues) { DEFiRet; ruleset_t *pThis = (ruleset_t *)pData; dbgprintf("Activating Ruleset Queue[%p] for Ruleset %s\n", pThis->pQueue, pThis->pszName); if (pThis->pQueue != NULL) startMainQueue(runConf, pThis->pQueue); RETiRet; } /* activate all ruleset queues */ rsRetVal activateRulesetQueues(void) { llExecFunc(&(runConf->rulesets.llRulesets), doActivateRulesetQueues, NULL); return RS_RET_OK; } static rsRetVal execAct(struct cnfstmt *stmt, smsg_t *pMsg, wti_t *pWti) { DEFiRet; if (stmt->d.act->bDisabled) { DBGPRINTF("action %d died, do NOT execute\n", stmt->d.act->iActionNbr); FINALIZE; } DBGPRINTF("executing action %d\n", stmt->d.act->iActionNbr); stmt->d.act->submitToActQ(stmt->d.act, pWti, pMsg); if (iRet != RS_RET_DISCARDMSG) { /* note: we ignore the error code here, as we do NEVER want to * stop script execution due to action return code */ iRet = RS_RET_OK; } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL() execSet(const struct cnfstmt *const stmt, smsg_t *const pMsg, wti_t *const __restrict__ pWti) { struct svar result; DEFiRet; cnfexprEval(stmt->d.s_set.expr, &result, pMsg, pWti); msgSetJSONFromVar(pMsg, stmt->d.s_set.varname, &result, stmt->d.s_set.force_reset); varDelete(&result); RETiRet; } static rsRetVal execUnset(struct cnfstmt *stmt, smsg_t *pMsg) { DEFiRet; msgDelJSON(pMsg, stmt->d.s_unset.varname); RETiRet; } static rsRetVal execCallIndirect(struct cnfstmt *const __restrict__ stmt, smsg_t *pMsg, wti_t *const __restrict__ pWti) { ruleset_t *pRuleset; struct svar result; int bMustFree; /* dummy parameter */ DEFiRet; assert(stmt->d.s_call_ind.expr != NULL); cnfexprEval(stmt->d.s_call_ind.expr, &result, pMsg, pWti); uchar *const rsName = (uchar *)var2CString(&result, &bMustFree); const rsRetVal localRet = rulesetGetRuleset(runConf, &pRuleset, rsName); if (localRet != RS_RET_OK) { /* in that case, we accept that a NOP will "survive" */ LogError(0, RS_RET_RULESET_NOT_FOUND, "error: CALL_INDIRECT: " "ruleset '%s' cannot be found, treating as NOP\n", rsName); FINALIZE; } DBGPRINTF("CALL_INDIRECT obtained ruleset ptr %p for ruleset '%s' [hasQueue:%d]\n", pRuleset, rsName, rulesetHasQueue(pRuleset)); if (rulesetHasQueue(pRuleset)) { CHKmalloc(pMsg = MsgDup((smsg_t *)pMsg)); DBGPRINTF("CALL_INDIRECT: forwarding message to async ruleset %p\n", pRuleset->pQueue); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, pRuleset); /* Note: we intentionally use submitMsg2() here, as we process messages * that were already run through the rate-limiter. */ submitMsg2(pMsg); } else { CHKiRet(scriptExec(pRuleset->root, pMsg, pWti)); } finalize_it: varDelete(&result); free(rsName); RETiRet; } static rsRetVal execCall(struct cnfstmt *stmt, smsg_t *pMsg, wti_t *pWti) { DEFiRet; if (stmt->d.s_call.ruleset == NULL) { CHKiRet(scriptExec(stmt->d.s_call.stmt, pMsg, pWti)); } else { CHKmalloc(pMsg = MsgDup((smsg_t *)pMsg)); DBGPRINTF("CALL: forwarding message to async ruleset %p\n", stmt->d.s_call.ruleset->pQueue); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, stmt->d.s_call.ruleset); /* Note: we intentionally use submitMsg2() here, as we process messages * that were already run through the rate-limiter. */ submitMsg2(pMsg); } finalize_it: RETiRet; } static rsRetVal execIf(struct cnfstmt *const stmt, smsg_t *const pMsg, wti_t *const pWti) { sbool bRet; DEFiRet; bRet = cnfexprEvalBool(stmt->d.s_if.expr, pMsg, pWti); DBGPRINTF("if condition result is %d\n", bRet); if (bRet) { if (stmt->d.s_if.t_then != NULL) CHKiRet(scriptExec(stmt->d.s_if.t_then, pMsg, pWti)); } else { if (stmt->d.s_if.t_else != NULL) CHKiRet(scriptExec(stmt->d.s_if.t_else, pMsg, pWti)); } finalize_it: RETiRet; } static rsRetVal invokeForeachBodyWith(struct cnfstmt *stmt, json_object *o, smsg_t *pMsg, wti_t *pWti) { struct svar v; v.datatype = 'J'; v.d.json = o; DEFiRet; CHKiRet(msgSetJSONFromVar(pMsg, (uchar *)stmt->d.s_foreach.iter->var, &v, 1)); CHKiRet(scriptExec(stmt->d.s_foreach.body, pMsg, pWti)); finalize_it: RETiRet; } static rsRetVal callForeachArray(struct cnfstmt *stmt, json_object *arr, smsg_t *pMsg, wti_t *pWti) { DEFiRet; int len = json_object_array_length(arr); json_object *curr; for (int i = 0; i < len; i++) { curr = json_object_array_get_idx(arr, i); CHKiRet(invokeForeachBodyWith(stmt, curr, pMsg, pWti)); } finalize_it: RETiRet; } static rsRetVal callForeachObject(struct cnfstmt *stmt, json_object *arr, smsg_t *pMsg, wti_t *pWti) { json_object *entry = NULL; json_object *key = NULL; const char **keys = NULL; json_object *curr = NULL; const char **curr_key; struct json_object_iterator it; struct json_object_iterator itEnd; DEFiRet; int len = json_object_object_length(arr); CHKmalloc(keys = calloc(len, sizeof(char *))); curr_key = keys; it = json_object_iter_begin(arr); itEnd = json_object_iter_end(arr); while (!json_object_iter_equal(&it, &itEnd)) { *curr_key = json_object_iter_peek_name(&it); curr_key++; json_object_iter_next(&it); } CHKmalloc(entry = json_object_new_object()); for (int i = 0; i < len; i++) { if (json_object_object_get_ex(arr, keys[i], &curr)) { CHKmalloc(key = json_object_new_string(keys[i])); json_object_object_add(entry, "key", key); key = NULL; json_object_object_add(entry, "value", json_object_get(curr)); CHKiRet(invokeForeachBodyWith(stmt, entry, pMsg, pWti)); } } finalize_it: if (keys != NULL) free(keys); if (entry != NULL) json_object_put(entry); /* "fix" Coverity scan issue CID 185393: key currently can NOT be NULL * However, instead of just removing the * if (key != NULL) json_object_put(key); * we put an assertion in its place. */ assert(key == NULL); RETiRet; } static rsRetVal ATTR_NONNULL() execForeach(struct cnfstmt *const stmt, smsg_t *const pMsg, wti_t *const pWti) { json_object *arr = NULL; DEFiRet; /* arr can either be an array or an associative-array (obj) */ arr = cnfexprEvalCollection(stmt->d.s_foreach.iter->collection, pMsg, pWti); if (arr == NULL) { DBGPRINTF("foreach loop skipped, as object to iterate upon is empty\n"); FINALIZE; } else if (json_object_is_type(arr, json_type_array) && json_object_array_length(arr) > 0) { CHKiRet(callForeachArray(stmt, arr, pMsg, pWti)); } else if (json_object_is_type(arr, json_type_object) && json_object_object_length(arr) > 0) { CHKiRet(callForeachObject(stmt, arr, pMsg, pWti)); } else { DBGPRINTF("foreach loop skipped, as object to iterate upon is empty or is not an array\n"); FINALIZE; } CHKiRet(msgDelJSON(pMsg, (uchar *)stmt->d.s_foreach.iter->var)); finalize_it: if (arr != NULL) json_object_put(arr); RETiRet; } static rsRetVal execPRIFILT(struct cnfstmt *stmt, smsg_t *pMsg, wti_t *pWti) { int bRet; DEFiRet; if ((stmt->d.s_prifilt.pmask[pMsg->iFacility] == TABLE_NOPRI) || ((stmt->d.s_prifilt.pmask[pMsg->iFacility] & (1 << pMsg->iSeverity)) == 0)) bRet = 0; else bRet = 1; DBGPRINTF("PRIFILT condition result is %d\n", bRet); if (bRet) { if (stmt->d.s_prifilt.t_then != NULL) CHKiRet(scriptExec(stmt->d.s_prifilt.t_then, pMsg, pWti)); } else { if (stmt->d.s_prifilt.t_else != NULL) CHKiRet(scriptExec(stmt->d.s_prifilt.t_else, pMsg, pWti)); } finalize_it: RETiRet; } /* helper to execPROPFILT(), as the evaluation itself is quite lengthy */ static int evalPROPFILT(struct cnfstmt *stmt, smsg_t *pMsg) { unsigned short pbMustBeFreed; uchar *pszPropVal; int bRet = 0; rs_size_t propLen; if (stmt->d.s_propfilt.prop.id == PROP_INVALID) goto done; pszPropVal = MsgGetProp(pMsg, NULL, &stmt->d.s_propfilt.prop, &propLen, &pbMustBeFreed, NULL); /* Now do the compares (short list currently ;)) */ switch (stmt->d.s_propfilt.operation) { case FIOP_CONTAINS: if (rsCStrLocateInSzStr(stmt->d.s_propfilt.pCSCompValue, (uchar *)pszPropVal) != -1) bRet = 1; break; case FIOP_ISEMPTY: if (propLen == 0) bRet = 1; /* process message! */ break; case FIOP_ISEQUAL: if (rsCStrSzStrCmp(stmt->d.s_propfilt.pCSCompValue, pszPropVal, propLen) == 0) bRet = 1; /* process message! */ break; case FIOP_STARTSWITH: if (rsCStrSzStrStartsWithCStr(stmt->d.s_propfilt.pCSCompValue, pszPropVal, propLen) == 0) bRet = 1; /* process message! */ break; case FIOP_ENDSWITH: if (rsCStrSzStrEndsWithCStr(stmt->d.s_propfilt.pCSCompValue, pszPropVal, propLen) == 0) bRet = 1; /* process message! */ break; case FIOP_REGEX: if (rsCStrSzStrMatchRegex(stmt->d.s_propfilt.pCSCompValue, (unsigned char *)pszPropVal, 0, &stmt->d.s_propfilt.regex_cache) == RS_RET_OK) bRet = 1; break; case FIOP_EREREGEX: if (rsCStrSzStrMatchRegex(stmt->d.s_propfilt.pCSCompValue, (unsigned char *)pszPropVal, 1, &stmt->d.s_propfilt.regex_cache) == RS_RET_OK) bRet = 1; break; case FIOP_NOP: default: /* here, it handles NOP (for performance reasons) */ assert(stmt->d.s_propfilt.operation == FIOP_NOP); bRet = 1; /* as good as any other default ;) */ break; } /* now check if the value must be negated */ if (stmt->d.s_propfilt.isNegated) bRet = (bRet == 1) ? 0 : 1; if (Debug) { if (stmt->d.s_propfilt.prop.id == PROP_CEE) { DBGPRINTF("Filter: check for CEE property '%s' (value '%s') ", stmt->d.s_propfilt.prop.name, pszPropVal); } else if (stmt->d.s_propfilt.prop.id == PROP_LOCAL_VAR) { DBGPRINTF("Filter: check for local var '%s' (value '%s') ", stmt->d.s_propfilt.prop.name, pszPropVal); } else if (stmt->d.s_propfilt.prop.id == PROP_GLOBAL_VAR) { DBGPRINTF("Filter: check for global var '%s' (value '%s') ", stmt->d.s_propfilt.prop.name, pszPropVal); } else { DBGPRINTF("Filter: check for property '%s' (value '%s') ", propIDToName(stmt->d.s_propfilt.prop.id), pszPropVal); } if (stmt->d.s_propfilt.isNegated) DBGPRINTF("NOT "); if (stmt->d.s_propfilt.operation == FIOP_ISEMPTY) { DBGPRINTF("%s : %s\n", getFIOPName(stmt->d.s_propfilt.operation), bRet ? "TRUE" : "FALSE"); } else { DBGPRINTF("%s '%s': %s\n", getFIOPName(stmt->d.s_propfilt.operation), rsCStrGetSzStrNoNULL(stmt->d.s_propfilt.pCSCompValue), bRet ? "TRUE" : "FALSE"); } } /* cleanup */ if (pbMustBeFreed) free(pszPropVal); done: return bRet; } static rsRetVal execPROPFILT(struct cnfstmt *stmt, smsg_t *pMsg, wti_t *pWti) { sbool bRet; DEFiRet; bRet = evalPROPFILT(stmt, pMsg); DBGPRINTF("PROPFILT condition result is %d\n", bRet); if (bRet) CHKiRet(scriptExec(stmt->d.s_propfilt.t_then, pMsg, pWti)); finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL() execReloadLookupTable(struct cnfstmt *stmt) { assert(stmt != NULL); lookup_ref_t *t; DEFiRet; t = stmt->d.s_reload_lookup_table.table; if (t == NULL) { ABORT_FINALIZE(RS_RET_NONE); } iRet = lookupReload(t, stmt->d.s_reload_lookup_table.stub_value); /* Note that reload dispatched above is performed asynchronously, on a different thread. So rsRetVal it returns means it was triggered successfully, and not that it was reloaded successfully. */ finalize_it: RETiRet; } /* The rainerscript execution engine. It is debatable if that would be better * contained in grammer/rainerscript.c, HOWEVER, that file focusses primarily * on the parsing and object creation part. So as an actual executor, it is * better suited here. * rgerhards, 2012-09-04 */ static rsRetVal ATTR_NONNULL(2, 3) scriptExec(struct cnfstmt *const root, smsg_t *const pMsg, wti_t *const pWti) { struct cnfstmt *stmt; DEFiRet; for (stmt = root; stmt != NULL; stmt = stmt->next) { if (*pWti->pbShutdownImmediate) { DBGPRINTF( "scriptExec: ShutdownImmediate set, " "force terminating\n"); ABORT_FINALIZE(RS_RET_FORCE_TERM); } if (Debug) { cnfstmtPrintOnly(stmt, 2, 0); } switch (stmt->nodetype) { case S_NOP: break; case S_STOP: ABORT_FINALIZE(RS_RET_DISCARDMSG); break; case S_ACT: CHKiRet(execAct(stmt, pMsg, pWti)); break; case S_SET: CHKiRet(execSet(stmt, pMsg, pWti)); break; case S_UNSET: CHKiRet(execUnset(stmt, pMsg)); break; case S_CALL: CHKiRet(execCall(stmt, pMsg, pWti)); break; case S_CALL_INDIRECT: CHKiRet(execCallIndirect(stmt, pMsg, pWti)); break; case S_IF: CHKiRet(execIf(stmt, pMsg, pWti)); break; case S_FOREACH: CHKiRet(execForeach(stmt, pMsg, pWti)); break; case S_PRIFILT: CHKiRet(execPRIFILT(stmt, pMsg, pWti)); break; case S_PROPFILT: CHKiRet(execPROPFILT(stmt, pMsg, pWti)); break; case S_RELOAD_LOOKUP_TABLE: CHKiRet(execReloadLookupTable(stmt)); break; default: dbgprintf("error: unknown stmt type %u during exec\n", (unsigned)stmt->nodetype); break; } } finalize_it: RETiRet; } /* Process (consume) a batch of messages. Calls the actions configured. * This is called by MAIN queues. */ static rsRetVal processBatch(batch_t *pBatch, wti_t *pWti) { int i; smsg_t *pMsg; ruleset_t *pRuleset; rsRetVal localRet; DEFiRet; DBGPRINTF("processBATCH: batch of %d elements must be processed\n", pBatch->nElem); wtiResetExecState(pWti, pBatch); /* execution phase */ for (i = 0; i < batchNumMsgs(pBatch) && !*(pWti->pbShutdownImmediate); ++i) { pMsg = pBatch->pElem[i].pMsg; DBGPRINTF("processBATCH: next msg %d: %.128s\n", i, pMsg->pszRawMsg); pRuleset = (pMsg->pRuleset == NULL) ? runConf->rulesets.pDflt : pMsg->pRuleset; localRet = scriptExec(pRuleset->root, pMsg, pWti); /* the most important case here is that processing may be aborted * due to pbShutdownImmediate, in which case we MUST NOT flag this * message as committed. If we would do so, the message would * potentially be lost. */ if (localRet == RS_RET_OK) batchSetElemState(pBatch, i, BATCH_STATE_COMM); else if (localRet == RS_RET_SUSPENDED) --i; } /* commit phase */ DBGPRINTF( "END batch execution phase, entering to commit phase " "[processed %d of %d messages]\n", i, batchNumMsgs(pBatch)); actionCommitAllDirect(pWti); DBGPRINTF("processBATCH: batch of %d elements has been processed\n", pBatch->nElem); RETiRet; } /* return the ruleset-assigned parser list. NULL means use the default * parser list. * rgerhards, 2009-11-04 */ static parserList_t *GetParserList(rsconf_t *conf, smsg_t *pMsg) { return (pMsg->pRuleset == NULL) ? conf->rulesets.pDflt->pParserLst : pMsg->pRuleset->pParserLst; } /* Add a script block to the current ruleset */ static void ATTR_NONNULL(1) addScript(ruleset_t *const pThis, struct cnfstmt *const script) { if (script == NULL) /* happens for include() */ return; if (pThis->last == NULL) pThis->root = pThis->last = script; else { pThis->last->next = script; pThis->last = script; } } /* set name for ruleset */ static rsRetVal rulesetSetName(ruleset_t *pThis, uchar *pszName) { DEFiRet; free(pThis->pszName); CHKmalloc(pThis->pszName = ustrdup(pszName)); finalize_it: RETiRet; } /* get current ruleset * We use a non-standard calling interface, as nothing can go wrong and it * is really much more natural to return the pointer directly. */ static ruleset_t *GetCurrent(rsconf_t *conf) { return conf->rulesets.pCurr; } /* get main queue associated with ruleset. If no ruleset-specifc main queue * is set, the primary main message queue is returned. * We use a non-standard calling interface, as nothing can go wrong and it * is really much more natural to return the pointer directly. */ static qqueue_t *GetRulesetQueue(ruleset_t *pThis) { ISOBJ_TYPE_assert(pThis, ruleset); return (pThis->pQueue == NULL) ? runConf->pMsgQueue : pThis->pQueue; } /* Find the ruleset with the given name and return a pointer to its object. */ rsRetVal rulesetGetRuleset(rsconf_t *conf, ruleset_t **ppRuleset, uchar *pszName) { DEFiRet; assert(ppRuleset != NULL); assert(pszName != NULL); CHKiRet(llFind(&(conf->rulesets.llRulesets), pszName, (void *)ppRuleset)); finalize_it: RETiRet; } /* Set a new default rule set. If the default can not be found, no change happens. */ static rsRetVal SetDefaultRuleset(rsconf_t *conf, uchar *pszName) { ruleset_t *pRuleset; DEFiRet; assert(pszName != NULL); CHKiRet(rulesetGetRuleset(conf, &pRuleset, pszName)); conf->rulesets.pDflt = pRuleset; DBGPRINTF("default rule set changed to %p: '%s'\n", pRuleset, pszName); finalize_it: RETiRet; } /* Set a new current rule set. If the ruleset can not be found, no change happens */ static rsRetVal SetCurrRuleset(rsconf_t *conf, uchar *pszName) { ruleset_t *pRuleset; DEFiRet; assert(pszName != NULL); CHKiRet(rulesetGetRuleset(conf, &pRuleset, pszName)); conf->rulesets.pCurr = pRuleset; DBGPRINTF("current rule set changed to %p: '%s'\n", pRuleset, pszName); finalize_it: RETiRet; } /* Standard-Constructor */ BEGINobjConstruct(ruleset) /* be sure to specify the object type also in END macro! */ pThis->root = NULL; pThis->last = NULL; ENDobjConstruct(ruleset) /* ConstructionFinalizer * This also adds the rule set to the list of all known rulesets. */ static rsRetVal rulesetConstructFinalize(rsconf_t *conf, ruleset_t *pThis) { uchar *keyName; DEFiRet; ISOBJ_TYPE_assert(pThis, ruleset); /* we must duplicate our name, as the key destructer would also * free it, resulting in a double-free. It's also cleaner to have * two separate copies. */ CHKmalloc(keyName = ustrdup(pThis->pszName)); CHKiRet(llAppend(&(conf->rulesets.llRulesets), keyName, pThis)); /* and also the default, if so far none has been set */ if (conf->rulesets.pDflt == NULL) conf->rulesets.pDflt = pThis; finalize_it: RETiRet; } /* destructor for the ruleset object */ BEGINobjDestruct(ruleset) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(ruleset); DBGPRINTF("destructing ruleset %p, name %p\n", pThis, pThis->pszName); if (pThis->pQueue != NULL) { qqueueDestruct(&pThis->pQueue); } if (pThis->pParserLst != NULL) { parser.DestructParserList(&pThis->pParserLst); } free(pThis->pszName); ENDobjDestruct(ruleset) /* helper for Destructor, shut down queue workers */ DEFFUNC_llExecFunc(doShutdownQueueWorkers) { DEFiRet; ruleset_t *const pThis = (ruleset_t *)pData; DBGPRINTF("shutting down queue workers for ruleset %p, name %s, queue %p\n", pThis, pThis->pszName, pThis->pQueue); ISOBJ_TYPE_assert(pThis, ruleset); if (pThis->pQueue != NULL) { qqueueShutdownWorkers(pThis->pQueue); } RETiRet; } /* helper for Destructor, shut down actions (cnfstmt's in general) */ DEFFUNC_llExecFunc(doDestructCnfStmt) { DEFiRet; ruleset_t *const pThis = (ruleset_t *)pData; DBGPRINTF("shutting down actions and conf stmts for ruleset %p, name %s\n", pThis, pThis->pszName); ISOBJ_TYPE_assert(pThis, ruleset); cnfstmtDestructLst(pThis->root); RETiRet; } /* destruct ALL rule sets that reside in the system. This must * be callable before unloading this module as the module may * not be unloaded before unload of the actions is required. This is * kind of a left-over from previous logic and may be optimized one * everything runs stable again. -- rgerhards, 2009-06-10 */ static rsRetVal destructAllActions(rsconf_t *conf) { DEFiRet; DBGPRINTF("rulesetDestructAllActions\n"); /* we first need to stop all queue workers, else we * may run into trouble with "call" statements calling * into then-destroyed rulesets. * see: https://github.com/rsyslog/rsyslog/issues/1122 */ DBGPRINTF("destructAllActions: queue shutdown\n"); llExecFunc(&(conf->rulesets.llRulesets), doShutdownQueueWorkers, NULL); DBGPRINTF("destructAllActions: action and conf stmt shutdown\n"); llExecFunc(&(conf->rulesets.llRulesets), doDestructCnfStmt, NULL); CHKiRet(llDestroy(&(conf->rulesets.llRulesets))); CHKiRet(llInit(&(conf->rulesets.llRulesets), rulesetDestructForLinkedList, rulesetKeyDestruct, (int (*)(void *, void *))strcasecmp)); conf->rulesets.pDflt = NULL; finalize_it: RETiRet; } /* this is a special destructor for the linkedList class. LinkedList does NOT * provide a pointer to the pointer, but rather the raw pointer itself. So we * must map this, otherwise the destructor will abort. */ rsRetVal rulesetDestructForLinkedList(void *pData) { ruleset_t *pThis = (ruleset_t *)pData; return rulesetDestruct(&pThis); } /* debugprint for the ruleset object */ BEGINobjDebugPrint(ruleset) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(ruleset); dbgoprint((obj_t *)pThis, "rsyslog ruleset %s:\n", pThis->pszName); cnfstmtPrint(pThis->root, 0); dbgoprint((obj_t *)pThis, "ruleset %s assigned parser list:\n", pThis->pszName); printParserList(pThis->pParserLst); ENDobjDebugPrint(ruleset) /* helper for debugPrintAll(), prints a single ruleset */ DEFFUNC_llExecFunc(doDebugPrintAll) { return rulesetDebugPrint((ruleset_t *)pData); } /* debug print all rulesets */ static rsRetVal debugPrintAll(rsconf_t *conf) { DEFiRet; dbgprintf("All Rulesets:\n"); llExecFunc(&(conf->rulesets.llRulesets), doDebugPrintAll, NULL); dbgprintf("End of Rulesets.\n"); RETiRet; } struct cnfstmt *removeNOPs(struct cnfstmt *root); static void rulesetOptimize(ruleset_t *pRuleset) { if (Debug) { dbgprintf("ruleset '%s' before optimization:\n", pRuleset->pszName); rulesetDebugPrint((ruleset_t *)pRuleset); } pRuleset->root = cnfstmtOptimize(pRuleset->root); if (Debug) { dbgprintf("ruleset '%s' after optimization:\n", pRuleset->pszName); rulesetDebugPrint((ruleset_t *)pRuleset); } } /* helper for rulsetOptimizeAll(), optimizes a single ruleset */ DEFFUNC_llExecFunc(doRulesetOptimizeAll) { rulesetOptimize((ruleset_t *)pData); return RS_RET_OK; } /* optimize all rulesets */ rsRetVal rulesetOptimizeAll(rsconf_t *conf) { DEFiRet; dbgprintf("begin ruleset optimization phase\n"); llExecFunc(&(conf->rulesets.llRulesets), doRulesetOptimizeAll, NULL); dbgprintf("ruleset optimization phase finished.\n"); RETiRet; } /* Create a ruleset-specific "main" queue for this ruleset. If one is already * defined, an error message is emitted but nothing else is done. * Note: we use the main message queue parameters for queue creation and access * syslogd.c directly to obtain these. This is far from being perfect, but * considered acceptable for the time being. * rgerhards, 2009-10-27 */ static rsRetVal doRulesetCreateQueue(rsconf_t *conf, int *pNewVal) { uchar *rsname; DEFiRet; if (conf->rulesets.pCurr == NULL) { LogError(0, RS_RET_NO_CURR_RULESET, "error: currently no specific ruleset specified, thus a " "queue can not be added to it"); ABORT_FINALIZE(RS_RET_NO_CURR_RULESET); } if (conf->rulesets.pCurr->pQueue != NULL) { LogError(0, RS_RET_RULES_QUEUE_EXISTS, "error: ruleset already has a main queue, can not " "add another one"); ABORT_FINALIZE(RS_RET_RULES_QUEUE_EXISTS); } if (pNewVal == 0) FINALIZE; /* if it is turned off, we do not need to change anything ;) */ rsname = (conf->rulesets.pCurr->pszName == NULL) ? (uchar *)"[ruleset]" : conf->rulesets.pCurr->pszName; DBGPRINTF("adding a ruleset-specific \"main\" queue for ruleset '%s'\n", rsname); CHKiRet(createMainQueue(&conf->rulesets.pCurr->pQueue, rsname, NULL)); finalize_it: RETiRet; } static rsRetVal rulesetCreateQueue(void __attribute__((unused)) * pVal, int *pNewVal) { return doRulesetCreateQueue(ourConf, pNewVal); } /* Add a ruleset specific parser to the ruleset. Note that adding the first * parser automatically disables the default parsers. If they are needed as well, * the must be added via explicit config directives. * Note: this is the only spot in the code that requires the parser object. In order * to solve some class init bootstrap sequence problems, we get the object handle here * instead of during module initialization. Note that objUse() is capable of being * called multiple times. * rgerhards, 2009-11-04 */ static rsRetVal doRulesetAddParser(ruleset_t *pRuleset, uchar *pName) { parser_t *pParser; DEFiRet; CHKiRet(objUse(parser, CORE_COMPONENT)); iRet = parser.FindParser(loadConf->parsers.pParsLstRoot, &pParser, pName); if (iRet == RS_RET_PARSER_NOT_FOUND) { LogError(0, RS_RET_PARSER_NOT_FOUND, "error: parser '%s' unknown at this time " "(maybe defined too late in rsyslog.conf?)", pName); ABORT_FINALIZE(RS_RET_NO_CURR_RULESET); } else if (iRet != RS_RET_OK) { LogError(0, iRet, "error trying to find parser '%s'\n", pName); FINALIZE; } CHKiRet(parser.AddParserToList(&pRuleset->pParserLst, pParser)); DBGPRINTF("added parser '%s' to ruleset '%s'\n", pName, pRuleset->pszName); finalize_it: free(pName); /* no longer needed */ RETiRet; } static rsRetVal rulesetAddParser(void __attribute__((unused)) * pVal, uchar *pName) { return doRulesetAddParser(loadConf->rulesets.pCurr, pName); } /* Process ruleset() objects */ rsRetVal rulesetProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; rsRetVal localRet; uchar *rsName = NULL; uchar *parserName; int nameIdx, parserIdx; ruleset_t *pRuleset; struct cnfarray *ar; int i; int qtype; uchar *rsname; DEFiRet; pvals = nvlstGetParams(o->nvlst, &rspblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } DBGPRINTF("ruleset param blk after rulesetProcessCnf:\n"); cnfparamsPrint(&rspblk, pvals); nameIdx = cnfparamGetIdx(&rspblk, "name"); rsName = (uchar *)es_str2cstr(pvals[nameIdx].val.d.estr, NULL); localRet = rulesetGetRuleset(loadConf, &pRuleset, rsName); if (localRet == RS_RET_OK) { LogError(0, RS_RET_RULESET_EXISTS, "error: ruleset '%s' specified more than once", rsName); cnfstmtDestructLst(o->script); ABORT_FINALIZE(RS_RET_RULESET_EXISTS); } else if (localRet != RS_RET_NOT_FOUND) { ABORT_FINALIZE(localRet); } CHKiRet(rulesetConstruct(&pRuleset)); if ((localRet = rulesetSetName(pRuleset, rsName)) != RS_RET_OK) { rulesetDestruct(&pRuleset); ABORT_FINALIZE(localRet); } if ((localRet = rulesetConstructFinalize(loadConf, pRuleset)) != RS_RET_OK) { rulesetDestruct(&pRuleset); ABORT_FINALIZE(localRet); } addScript(pRuleset, o->script); /* we have only two params, so we do NOT do the usual param loop */ parserIdx = cnfparamGetIdx(&rspblk, "parser"); if (parserIdx != -1 && pvals[parserIdx].bUsed) { ar = pvals[parserIdx].val.d.ar; for (i = 0; i < ar->nmemb; ++i) { parserName = (uchar *)es_str2cstr(ar->arr[i], NULL); doRulesetAddParser(pRuleset, parserName); /* note parserName is freed in doRulesetAddParser()! */ } } /* pick up ruleset queue parameters */ if (queueCnfParamsSet(o->nvlst)) { if (pRuleset->pszName == NULL) { rsname = (uchar *)"[ruleset]"; qtype = pRuleset->pQueue->qType; } else { rsname = pRuleset->pszName; qtype = 3; } DBGPRINTF("adding a ruleset-specific \"main\" queue for ruleset '%s', mode %d\n", rsname, qtype); CHKiRet(createMainQueue(&pRuleset->pQueue, rsname, o->nvlst)); } finalize_it: free(rsName); cnfparamvalsDestruct(pvals, &rspblk); RETiRet; } /* queryInterface function * rgerhards, 2008-02-21 */ BEGINobjQueryInterface(ruleset) CODESTARTobjQueryInterface(ruleset); if (pIf->ifVersion != rulesetCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = rulesetConstruct; pIf->ConstructFinalize = rulesetConstructFinalize; pIf->Destruct = rulesetDestruct; pIf->DebugPrint = rulesetDebugPrint; pIf->IterateAllActions = iterateAllActions; pIf->DestructAllActions = destructAllActions; pIf->AddScript = addScript; pIf->ProcessBatch = processBatch; pIf->SetName = rulesetSetName; pIf->DebugPrintAll = debugPrintAll; pIf->GetCurrent = GetCurrent; pIf->GetRuleset = rulesetGetRuleset; pIf->SetDefaultRuleset = SetDefaultRuleset; pIf->SetCurrRuleset = SetCurrRuleset; pIf->GetRulesetQueue = GetRulesetQueue; pIf->GetParserList = GetParserList; finalize_it: ENDobjQueryInterface(ruleset) /* Exit the ruleset class. * rgerhards, 2009-04-06 */ BEGINObjClassExit(ruleset, OBJ_IS_CORE_MODULE) /* class, version */ objRelease(parser, CORE_COMPONENT); ENDObjClassExit(ruleset) /* Initialize the ruleset class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(ruleset, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ /* set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, rulesetDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, rulesetConstructFinalize); /* config file handlers */ CHKiRet(regCfSysLineHdlr((uchar *)"rulesetparser", 0, eCmdHdlrGetWord, rulesetAddParser, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"rulesetcreatemainqueue", 0, eCmdHdlrBinary, rulesetCreateQueue, NULL, NULL)); ENDObjClassInit(ruleset) rsyslog-8.2512.0/runtime/PaxHeaders/objomsr.h0000644000000000000000000000013215055605325016046 xustar0030 mtime=1756826325.650800698 30 atime=1764930979.999677872 30 ctime=1764935923.174576443 rsyslog-8.2512.0/runtime/objomsr.h0000664000175000017500000000417015055605325015514 0ustar00rgerrger/* Definition of the omsr (omodStringRequest) object. * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OBJOMSR_H_INCLUDED #define OBJOMSR_H_INCLUDED /* define flags for required template options */ #define OMSR_NO_RQD_TPL_OPTS 0 #define OMSR_RQD_TPL_OPT_SQL 1 /* only one of OMSR_TPL_AS_ARRAY, _AS_MSG, or _AS_JSON must be specified, * if all are given results are unpredictable. */ #define OMSR_TPL_AS_ARRAY 2 /* introduced in 4.1.6, 2009-04-03 */ #define OMSR_TPL_AS_MSG 4 /* introduced in 5.3.4, 2009-11-02 */ #define OMSR_TPL_AS_JSON 8 /* introduced in 6.5.1, 2012-09-02 */ /* next option is 16, 32, 64, ... */ struct omodStringRequest_s { /* strings requested by output module for doAction() */ int iNumEntries; /* number of array entries for data elements below */ uchar **ppTplName; /* pointer to array of template names */ int *piTplOpts; /* pointer to array of check-options when pulling template */ }; typedef struct omodStringRequest_s omodStringRequest_t; /* prototypes */ rsRetVal OMSRdestruct(omodStringRequest_t *pThis); rsRetVal OMSRconstruct(omodStringRequest_t **ppThis, int iNumEntries); rsRetVal OMSRsetEntry(omodStringRequest_t *pThis, int iEntry, uchar *pTplName, int iTplOpts); rsRetVal OMSRgetSupportedTplOpts(unsigned long *pOpts); int OMSRgetEntryCount(omodStringRequest_t *pThis); int OMSRgetEntry(omodStringRequest_t *pThis, int iEntry, uchar **ppTplName, int *piTplOpts); #endif /* #ifndef OBJOMSR_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/batch.h0000644000000000000000000000013215055605325015454 xustar0030 mtime=1756826325.643800593 30 atime=1764930980.029678373 30 ctime=1764935923.111575478 rsyslog-8.2512.0/runtime/batch.h0000664000175000017500000001302315055605325015117 0ustar00rgerrger/* Definition of the batch_t data structure. * I am not sure yet if this will become a full-blown object. For now, this header just * includes the object definition and is not accompanied by code. * * Copyright 2009-2013 by Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef BATCH_H_INCLUDED #define BATCH_H_INCLUDED #include #include #include "msg.h" /* enum for batch states. Actually, we violate a layer here, in that we assume that a batch is used * for action processing. So far, this seems acceptable, the status is simply ignored inside the * main message queue. But over time, it could potentially be useful to split the two. * rgerhad, 2009-05-12 */ #define BATCH_STATE_RDY 0 /* object ready for processing */ #define BATCH_STATE_BAD 1 /* unrecoverable failure while processing, do NOT resubmit to same action */ #define BATCH_STATE_SUB 2 /* message submitted for processing, outcome yet unknown */ #define BATCH_STATE_COMM 3 /* message successfully commited */ #define BATCH_STATE_DISC 4 /* discarded - processed OK, but do not submit to any other action */ typedef unsigned char batch_state_t; /* an object inside a batch, including any information (state!) needed for it to "life". */ struct batch_obj_s { smsg_t *pMsg; }; /* the batch * This object is used to dequeue multiple user pointers which are than handed over * to processing. The size of elements is fixed after queue creation, but may be * modified by config variables (better said: queue properties). * Note that a "user pointer" in rsyslog context so far always is a message * object. We stick to the more generic term because queues may potentially hold * other types of objects, too. * rgerhards, 2009-05-12 * Note that nElem is not necessarily equal to nElemDeq. This is the case when we * discard some elements (because of configuration) during dequeue processing. As * all Elements are only deleted when the batch is processed, we can not immediately * delete them. So we need to keep their number that we can delete them when the batch * is completed (else, the whole process does not work correctly). */ struct batch_s { int maxElem; /* maximum number of elements that this batch supports */ int nElem; /* actual number of element in this entry */ int nElemDeq; /* actual number of elements dequeued (and thus to be deleted) - see comment above! */ qDeqID deqID; /* ID of dequeue operation that generated this batch */ batch_obj_t *pElem; /* batch elements */ batch_state_t *eltState; /* state (array!) for individual objects. NOTE: we have moved this out of batch_obj_t because we get a *much* better cache hit ratio this way. So do not move it back into this structure! Note that this is really a HUGE saving, even if it doesn't look so (both profiler data as well as practical tests indicate that!). */ }; /* get number of msgs for this batch */ #define batchNumMsgs(pBatch) ((pBatch)->nElem) /* set the status of the i-th batch element. Note that once the status is * DISC, it will never be reset. So this function can NOT be used to initialize * the state table. -- rgerhards, 2010-06-10 */ static inline void __attribute__((unused)) batchSetElemState(batch_t *const pBatch, const int i, const batch_state_t newState) { if (pBatch->eltState[i] != BATCH_STATE_DISC) pBatch->eltState[i] = newState; } /* check if an element is a valid entry. We do NOT verify if the * element index is valid. -- rgerhards, 2010-06-10 */ #define batchIsValidElem(pBatch, i) ((pBatch)->eltState[(i)] != BATCH_STATE_DISC) /* free members of a batch "object". Note that we can not do the usual * destruction as the object typically is allocated on the stack and so the * object itself cannot be freed! -- rgerhards, 2010-06-15 */ static inline void __attribute__((unused)) batchFree(batch_t *const pBatch) { free(pBatch->pElem); free(pBatch->eltState); } /* initialiaze a batch "object". The record must already exist, * we "just" initialize it. The max number of elements must be * provided. -- rgerhards, 2010-06-15 */ static inline rsRetVal __attribute__((unused)) batchInit(batch_t *const pBatch, const int maxElem) { DEFiRet; pBatch->maxElem = maxElem; CHKmalloc(pBatch->pElem = calloc((size_t)maxElem, sizeof(batch_obj_t))); CHKmalloc(pBatch->eltState = calloc((size_t)maxElem, sizeof(batch_state_t))); finalize_it: RETiRet; } #endif /* #ifndef BATCH_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/stream.h0000644000000000000000000000013215055605325015666 xustar0030 mtime=1756826325.653800744 30 atime=1764930980.014678122 30 ctime=1764935923.236577392 rsyslog-8.2512.0/runtime/stream.h0000664000175000017500000003250215055605325015334 0ustar00rgerrger/* Definition of serial stream class (strm). * * A serial stream provides serial data access. In theory, serial streams * can be implemented via a number of methods (e.g. files or in-memory * streams). In practice, there currently only exist the file type (aka * "driver"). * * In practice, many stream features are bound to files. I have not yet made * any serious effort, except for the naming of this class, to try to make * the interfaces very generic. However, I assume that we could work much * like in the strm class, where some properties are simply ignored when * the wrong strm mode is selected (which would translate here to the wrong * stream mode). * * Most importantly, this class provides generic input and output functions * which can directly be used to work with the strms and file output. It * provides such useful things like a circular file buffer and, hopefully * at a later stage, a lazy writer. The object is also seriazable and thus * can easily be persistet. The bottom line is that it makes much sense to * use this class whereever possible as its features may grow in the future. * * An important note on writing gzip format via zlib (kept anonymous * by request): * * -------------------------------------------------------------------------- * We'd like to make sure the output file is in full gzip format * (compatible with gzip -d/zcat etc). There is a flag in how the output * is initialized within zlib to properly add the gzip wrappers to the * output. (gzip is effectively a small metadata wrapper around raw * zstream output.) * * I had written an old bit of code to do this - the documentation on * deflatInit2() was pretty tricky to nail down on this specific feature: * * int deflateInit2 (z_streamp strm, int level, int method, int windowBits, * int memLevel, int strategy); * * I believe "31" would be the value for the "windowBits" field that you'd * want to try: * * deflateInit2(zstrmptr, 6, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY); * -------------------------------------------------------------------------- * * Copyright 2008-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef STREAM_H_INCLUDED #define STREAM_H_INCLUDED typedef struct strm_s strm_t; /* forward reference because of zlib... */ #include // TODO: fix via own module #include #include #include #include "obj-types.h" #include "glbl.h" #include "stream.h" #include "zlibw.h" #include "cryprov.h" /* stream types */ typedef enum { STREAMTYPE_FILE_SINGLE = 0, /**< read a single file */ STREAMTYPE_FILE_CIRCULAR = 1, /**< circular files */ STREAMTYPE_FILE_MONITOR = 2, /**< monitor a (third-party) file */ STREAMTYPE_NAMED_PIPE = 3 /**< file is a named pipe (so far, tested for output only) */ } strmType_t; typedef enum { /* when extending, do NOT change existing modes! */ STREAMMMODE_INVALID = 0, STREAMMODE_READ = 1, STREAMMODE_WRITE = 2, STREAMMODE_WRITE_TRUNC = 3, STREAMMODE_WRITE_APPEND = 4 } strmMode_t; typedef enum { STRM_COMPRESS_ZIP = 0, STRM_COMPRESS_ZSTD = 1 } strm_compressionDriver_t; #define STREAM_ASYNC_NUMBUFS 2 /* must be a power of 2 -- TODO: make configurable */ /* The strm_t data structure */ struct strm_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ strmType_t sType; /* descriptive properties */ unsigned int iCurrFNum; /* current file number (NOT descriptor, but the number in the file name!) */ uchar *pszFName; /* prefix for generated filenames */ int lenFName; strmMode_t tOperationsMode; mode_t tOpenMode; int64 iMaxFileSize; /* maximum size a file may grow to */ unsigned int iMaxFiles; /* maximum number of files if a circular mode is in use */ int iFileNumDigits; /* min number of digits to use in file number (only in circular mode) */ sbool bDeleteOnClose; /* set to 1 to auto-delete on close -- be careful with that setting! */ int64 iCurrOffs; /* current offset */ int64 *pUsrWCntr; /* NULL or a user-provided counter that receives the nbr of bytes written since the last CntrSet() */ sbool bPrevWasNL; /* used for readLine() when reading multi-line messages */ /* dynamic properties, valid only during file open, not to be persistet */ sbool bDisabled; /* should file no longer be written to? (currently set only if omfile file size limit fails) */ sbool bSync; /* sync this file after every write? */ sbool bReopenOnTruncate; int rotationCheck; /* rotation check mode */ size_t sIOBufSize; /* size of IO buffer */ uchar *pszDir; /* Directory */ int lenDir; int fd; /* the file descriptor, -1 if closed */ int fdDir; /* the directory's descriptor, in case bSync is requested (-1 if closed) */ int readTimeout; /* 0: do not timeout */ time_t lastRead; /* for timeout processing */ ino_t inode; /* current inode for files being monitored (undefined else) */ uchar *pszCurrFName; /* name of current file (if open) */ uchar *pIOBuf; /* the iobuffer currently in use to gather data */ char *pIOBuf_truncation; /* iobuffer used during trucation detection block re-reads */ size_t iBufPtrMax; /* current max Ptr in Buffer (if partial read!) */ size_t iBufPtr; /* pointer into current buffer */ int iUngetC; /* char set via UngetChar() call or -1 if none set */ sbool bInRecord; /* if 1, indicates that we are currently writing a not-yet complete record */ int iZipLevel; /* zip level (0..9). If 0, zip is completely disabled */ Bytef *pZipBuf; /* support for async flush procesing */ sbool bAsyncWrite; /* do asynchronous writes (always if a flush interval is given) */ sbool bStopWriter; /* shall writer thread terminate? */ sbool bDoTimedWait; /* instruct writer thread to do a times wait to support flush timeouts */ sbool bzInitDone; /* did we do an init of zstrm already? */ sbool bFlushNow; /* shall we flush with the next async write? */ sbool bVeryReliableZip; /* shall we write interim headers to create a very reliable ZIP file? */ int iFlushInterval; /* flush in which interval - 0, no flushing */ pthread_mutex_t mut; /* mutex for flush in async mode */ pthread_cond_t notFull; pthread_cond_t notEmpty; pthread_cond_t isEmpty; unsigned short iEnq; /* this MUST be unsigned as we use module arithmetic (else invalid indexing happens!) */ unsigned short iDeq; /* this MUST be unsigned as we use module arithmetic (else invalid indexing happens!) */ cryprov_if_t *cryprov; /* ptr to crypto provider; NULL = do not encrypt */ void *cryprovData; /* opaque data ptr for provider use */ void *cryprovFileData; /* opaque data ptr for file instance */ short iCnt; /* current nbr of elements in buffer */ z_stream zstrm; /* zip stream to use */ struct { uchar *pBuf; size_t lenBuf; } asyncBuf[STREAM_ASYNC_NUMBUFS]; struct { int num_wrkrs; /* nbr of worker threads */ void *cctx; } zstd; /* supporting per-instance data if zstd is used */ pthread_t writerThreadID; /* support for omfile size-limiting commands, special counters, NOT persisted! */ off_t iSizeLimit; /* file size limit, 0 = no limit */ uchar *pszSizeLimitCmd; /* command to carry out when size limit is reached */ sbool bIsTTY; /* is this a tty file? */ cstr_t *prevLineSegment; /* for ReadLine, previous, unprocessed part of file */ cstr_t *prevMsgSegment; /* for ReadMultiLine, previous, yet unprocessed part of msg */ int64 strtOffs; /* start offset in file for current line/msg */ int fileNotFoundError; /* boolean; if set, report file not found errors, else silently ignore */ int noRepeatedErrorOutput; /* if a file is missing the Error is only given once */ int ignoringMsg; strm_compressionDriver_t compressionDriver; }; /* interfaces */ BEGINinterface(strm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(strm_t **ppThis); rsRetVal (*ConstructFinalize)(strm_t *pThis); rsRetVal (*Destruct)(strm_t **ppThis); rsRetVal (*SetFileName)(strm_t *pThis, uchar *pszName, size_t iLenName); rsRetVal (*ReadChar)(strm_t *pThis, uchar *pC); rsRetVal (*UnreadChar)(strm_t *pThis, uchar c); rsRetVal (*SeekCurrOffs)(strm_t *pThis); rsRetVal (*Write)(strm_t *const pThis, const uchar *const pBuf, size_t lenBuf); rsRetVal (*WriteChar)(strm_t *pThis, uchar c); rsRetVal (*WriteLong)(strm_t *pThis, long i); rsRetVal (*SetFileNotFoundError)(strm_t *pThis, int pFileNotFoundError); rsRetVal (*SetFName)(strm_t *pThis, uchar *pszPrefix, size_t iLenPrefix); rsRetVal (*SetDir)(strm_t *pThis, uchar *pszDir, size_t iLenDir); rsRetVal (*Flush)(strm_t *pThis); rsRetVal (*RecordBegin)(strm_t *pThis); rsRetVal (*RecordEnd)(strm_t *pThis); rsRetVal (*Serialize)(strm_t *pThis, strm_t *pStrm); rsRetVal (*GetCurrOffset)(strm_t *pThis, int64 *pOffs); rsRetVal (*SetWCntr)(strm_t *pThis, number_t *pWCnt); rsRetVal (*Dup)(strm_t *pThis, strm_t **ppNew); rsRetVal (*SetCompressionWorkers)(strm_t *const pThis, int num_wrkrs); INTERFACEpropSetMeth(strm, bDeleteOnClose, int); INTERFACEpropSetMeth(strm, iMaxFileSize, int64); INTERFACEpropSetMeth(strm, iMaxFiles, int); INTERFACEpropSetMeth(strm, iFileNumDigits, int); INTERFACEpropSetMeth(strm, tOperationsMode, int); INTERFACEpropSetMeth(strm, tOpenMode, mode_t); INTERFACEpropSetMeth(strm, compressionDriver, strm_compressionDriver_t); INTERFACEpropSetMeth(strm, sType, strmType_t); INTERFACEpropSetMeth(strm, iZipLevel, int); INTERFACEpropSetMeth(strm, bSync, int); INTERFACEpropSetMeth(strm, bReopenOnTruncate, int); INTERFACEpropSetMeth(strm, sIOBufSize, size_t); INTERFACEpropSetMeth(strm, iSizeLimit, off_t); INTERFACEpropSetMeth(strm, iFlushInterval, int); INTERFACEpropSetMeth(strm, pszSizeLimitCmd, uchar *); /* v6 added */ rsRetVal (*ReadLine)(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF, const uchar *, uint32_t trimLineOverBytes, int64 *const strtOffs); /* v7 added 2012-09-14 */ INTERFACEpropSetMeth(strm, bVeryReliableZip, int); /* v8 added 2013-03-21 */ rsRetVal (*CheckFileChange)(strm_t *pThis); /* v9 added 2013-04-04 */ INTERFACEpropSetMeth(strm, cryprov, cryprov_if_t *); INTERFACEpropSetMeth(strm, cryprovData, void *); ENDinterface(strm) #define strmCURR_IF_VERSION 14 /* increment whenever you change the interface structure! */ /* V10, 2013-09-10: added new parameter bEscapeLF, changed mode to uint8_t (rgerhards) */ /* V11, 2015-12-03: added new parameter bReopenOnTruncate */ /* V12, 2015-12-11: added new parameter trimLineOverBytes, changed mode to uint32_t */ /* V13, 2017-09-06: added new parameter strtoffs to ReadLine() */ /* V14, 2019-11-13: added new parameter bEscapeLFString (rgerhards) */ #define strmGetCurrFileNum(pStrm) ((pStrm)->iCurrFNum) /* prototypes */ PROTOTYPEObjClassInit(strm); rsRetVal strmMultiFileSeek(strm_t *pThis, unsigned int fileNum, off64_t offs, off64_t *bytesDel); rsRetVal ATTR_NONNULL(1, 2) strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *start_preg, regex_t *end_preg, const sbool bEscapeLF, const uchar *const escapeLFString, const sbool discardTruncatedMsg, const sbool msgDiscardingError, int64 *const strtOffs); int strmReadMultiLine_isTimedOut(const strm_t *const __restrict__ pThis); void strmDebugOutBuf(const strm_t *const pThis); void strmSetReadTimeout(strm_t *const __restrict__ pThis, const int val); const uchar *ATTR_NONNULL() strmGetPrevLineSegment(strm_t *const pThis); const uchar *ATTR_NONNULL() strmGetPrevMsgSegment(strm_t *const pThis); int ATTR_NONNULL() strmGetPrevWasNL(const strm_t *const pThis); #endif /* #ifndef STREAM_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/conf.h0000644000000000000000000000013215055605325015320 xustar0030 mtime=1756826325.643800593 30 atime=1764930980.037678507 30 ctime=1764935923.139575907 rsyslog-8.2512.0/runtime/conf.h0000664000175000017500000000575015055605325014773 0ustar00rgerrger/* Definitions for config file handling (not yet an object). * * Copyright 2008-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_CONF_H #define INCLUDED_CONF_H #include "action.h" /* definitions used for doNameLine to differentiate between different command types * (with otherwise identical code). This is a left-over from the previous config * system. It stays, because it is still useful. So do not wonder why it looks * somewhat strange (at least its name). -- rgerhards, 2007-08-01 */ enum eDirective { DIR_TEMPLATE = 0, DIR_OUTCHANNEL = 1, DIR_ALLOWEDSENDER = 2 }; extern ecslConfObjType currConfObj; extern int bConfStrictScoping; /* force strict scoping during config processing? */ /* interfaces */ BEGINinterface(conf) /* name must also be changed in ENDinterface macro! */ rsRetVal (*doNameLine)(uchar **pp, void *pVal); rsRetVal (*cfsysline)(uchar *p); rsRetVal (*doModLoad)(uchar **pp, __attribute__((unused)) void *pVal); rsRetVal (*GetNbrActActions)(rsconf_t *conf, int *); /* version 4 -- 2010-07-23 rgerhards */ /* "just" added global variables * FYI: we reconsider repacking as a non-object, as only the core currently * accesses this module. The current object structure complicates things without * any real benefit. */ /* version 5 -- 2011-04-19 rgerhards */ /* complete revamp, we now use the rsconf object */ /* version 6 -- 2011-07-06 rgerhards */ /* again a complete revamp, using flex/bison based parser now */ ENDinterface(conf) #define confCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */ /* in Version 3, entry point "ReInitConf()" was removed, as we do not longer need * to support restart-type HUP -- rgerhards, 2009-07-15 */ /* prototypes */ PROTOTYPEObj(conf); /* TODO: the following 2 need to go in conf obj interface... */ rsRetVal cflineParseTemplateName(uchar **pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName); rsRetVal cflineParseFileName( uchar *p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *pszTpl); rsRetVal DecodePRIFilter(uchar *pline, uchar pmask[]); rsRetVal cflineDoAction(rsconf_t *conf, uchar **p, action_t **ppAction); extern EHostnameCmpMode eDfltHostnameCmpMode; extern cstr_t *pDfltHostnameCmp; extern cstr_t *pDfltProgNameCmp; #endif /* #ifndef INCLUDED_CONF_H */ rsyslog-8.2512.0/runtime/PaxHeaders/msg.h0000644000000000000000000000012715071746523015171 xustar0029 mtime=1760021843.86342138 29 atime=1764930980.03067839 29 ctime=1764935923.16457629 rsyslog-8.2512.0/runtime/msg.h0000664000175000017500000003524015071746523014635 0ustar00rgerrger/* msg.h * Header file for all msg-related functions. * * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c) * * Copyright 2007-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "template.h" /* this is a quirk, but these two are too interdependant... */ #ifndef MSG_H_INCLUDED #define MSG_H_INCLUDED 1 #include #include #include #include #include "obj.h" #include "syslogd-types.h" #include "template.h" #include "atomic.h" /* rgerhards 2004-11-08: The following structure represents a * syslog message. * * Important Note: * The message object is used for multiple purposes (once it * has been created). Once created, it actully is a read-only * object (though we do not specifically express this). In order * to avoid multiple copies of the same object, we use a * reference counter. This counter is set to 1 by the constructer * and increased by 1 with a call to MsgAddRef(). The destructor * checks the reference count. If it is more than 1, only the counter * will be decremented. If it is 1, however, the object is actually * destroyed. To make this work, it is vital that MsgAddRef() is * called each time a "copy" is stored somewhere. * * WARNING: this structure is not calloc()ed, so be careful when * adding new fields. You need to initialize them in * msgBaseConstruct(). That function header comment also describes * why this is the case. */ struct msg { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ flowControl_t flowCtlType; /**< type of flow control we can apply, for enqueueing, needs not to be persisted because once data has entered the queue, this property is no longer needed. */ pthread_mutex_t mut; int iRefCount; /* reference counter (0 = unused) */ sbool bParseSuccess; /* set to reflect state of last executed higher level parser */ unsigned short iSeverity; /* the severity */ unsigned short iFacility; /* Facility code */ int offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */ int offMSG; /* offset at which the MSG part starts in pszRawMsg */ short iProtocolVersion; /* protocol version of message received 0 - legacy, 1 syslog-protocol) */ int msgFlags; /* flags associated with this message */ int iLenRawMsg; /* length of raw message */ int iLenMSG; /* Length of the MSG part */ int iLenTAG; /* Length of the TAG part */ int iLenHOSTNAME; /* Length of HOSTNAME */ int iLenPROGNAME; /* Length of PROGNAME (-1 = not yet set) */ uchar *pszRawMsg; /* message as it was received on the wire. This is important in case we * need to preserve cryptographic verifiers. */ uchar *pszHOSTNAME; /* HOSTNAME from syslog message */ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 characters) */ char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 characters at most) */ char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 characters) */ char *pszRcvdAt_PgSQL; /* rcvdAt as PgSQL formatted string (always 21 characters) */ char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 characters) */ char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 characters at most) */ char *pszTIMESTAMP_MySQL; /* TIMESTAMP as MySQL formatted string (always 14 characters) */ char *pszTIMESTAMP_PgSQL; /* TIMESTAMP as PgSQL formatted string (always 21 characters) */ uchar *pszStrucData; /* STRUCTURED-DATA */ uint16_t lenStrucData; /* (cached) length of STRUCTURED-DATA */ cstr_t *pCSAPPNAME; /* APP-NAME */ cstr_t *pCSPROCID; /* PROCID */ cstr_t *pCSMSGID; /* MSGID */ prop_t *pInputName; /* input name property */ prop_t *pRcvFromIP; /* IP of system message was received from */ prop_t *pRcvFromPort; /* port of system message was received from */ union { prop_t *pRcvFrom; /* name of system message was received from */ struct sockaddr_storage *pfrominet; /* unresolved name */ } rcvFrom; ruleset_t *pRuleset; /* ruleset to be used for processing this message */ time_t ttGenTime; /* time msg object was generated, same as tRcvdAt, but a Unix timestamp. While this field looks redundant, it is required because a Unix timestamp is used at later processing stages (namely in the output arena). Thanks to the subleties of how time is defined, there is no reliable way to reconstruct the Unix timestamp from the syslogTime fields (in practice, we may be close enough to reliable, but I prefer to leave the subtle things to the OS, where it obviously is solved in way or another...). */ struct syslogTime tRcvdAt; /* time the message entered this program */ struct syslogTime tTIMESTAMP; /* (parsed) value of the timestamp */ struct json_object *json; struct json_object *localvars; /* some fixed-size buffers to save malloc()/free() for frequently used fields (from the default templates) */ uchar szRawMsg[CONF_RAWMSG_BUFSIZE]; /* most messages are small, and these are stored here (without malloc/free!) */ uchar szHOSTNAME[CONF_HOSTNAME_BUFSIZE]; union { uchar *ptr; /* pointer to progname value */ uchar szBuf[CONF_PROGNAME_BUFSIZE]; } PROGNAME; union { uchar *pszTAG; /* pointer to tag value */ uchar szBuf[CONF_TAG_BUFSIZE]; } TAG; char pszTimestamp3164[CONST_LEN_TIMESTAMP_3164 + 1]; char pszTimestamp3339[CONST_LEN_TIMESTAMP_3339 + 1]; char pszTIMESTAMP_SecFrac[7]; /* Note: a pointer is 64 bits/8 char, so this is actually fewer than a pointer! */ char pszRcvdAt_SecFrac[7]; /* same as above. Both are fractional seconds for their respective timestamp */ char pszTIMESTAMP_Unix[12]; /* almost as small as a pointer! */ char pszRcvdAt_Unix[12]; char dfltTZ[8]; /* 7 chars max, less overhead than ptr! */ uchar *pszUUID; /* The message's UUID */ }; /* message flags (msgFlags), not an enum for historical reasons */ #define NOFLAG 0x000 /* no flag is set (to be used when a flag must be specified and none is required) */ #define INTERNAL_MSG 0x001 /* msg generated by logmsgInternal() --> special handling */ /* 0x002 not used because it was previously a known value - rgerhards, 2008-10-09 */ #define IGNDATE 0x004 /* ignore, if given, date in message and use date of reception as msg date */ #define MARK 0x008 /* this message is a mark */ #define NEEDS_PARSING 0x010 /* raw message, must be parsed before processing can be done */ #define PARSE_HOSTNAME 0x020 /* parse the hostname during message parsing */ #define NEEDS_DNSRESOL 0x040 /* fromhost address is unresolved and must be locked up via DNS reverse lookup first */ #define NEEDS_ACLCHK_U 0x080 /* check UDP ACLs after DNS resolution has been done in main queue consumer */ #define NO_PRI_IN_RAW 0x100 /* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */ #define PRESERVE_CASE 0x200 /* preserve case in fromhost */ /* (syslog) protocol types */ #define MSG_LEGACY_PROTOCOL 0 #define MSG_RFC5424_PROTOCOL 1 #define MAX_VARIABLE_NAME_LEN 1024 /* function prototypes */ PROTOTYPEObjClassInit(msg); rsRetVal msgConstruct(smsg_t **ppThis); rsRetVal msgConstructWithTime(smsg_t **ppThis, const struct syslogTime *stTime, const time_t ttGenTime); rsRetVal msgConstructForDeserializer(smsg_t **ppThis); rsRetVal msgConstructFinalizer(smsg_t *pThis); rsRetVal msgDestruct(smsg_t **ppM); smsg_t *MsgDup(smsg_t *pOld); smsg_t *MsgAddRef(smsg_t *pM); void setProtocolVersion(smsg_t *pM, int iNewVersion); void MsgSetInputName(smsg_t *pMsg, prop_t *); void MsgSetDfltTZ(smsg_t *pThis, char *tz); rsRetVal MsgSetAPPNAME(smsg_t *pMsg, const char *pszAPPNAME); rsRetVal MsgSetPROCID(smsg_t *pMsg, const char *pszPROCID); rsRetVal MsgSetMSGID(smsg_t *pMsg, const char *pszMSGID); void MsgSetParseSuccess(smsg_t *pMsg, int bSuccess); void MsgSetTAG(smsg_t *pMsg, const uchar *pszBuf, const size_t lenBuf); void MsgSetRuleset(smsg_t *pMsg, ruleset_t *); rsRetVal MsgSetFlowControlType(smsg_t *pMsg, flowControl_t eFlowCtl); rsRetVal MsgSetStructuredData(smsg_t *const pMsg, const char *pszStrucData); rsRetVal MsgAddToStructuredData(smsg_t *pMsg, uchar *toadd, rs_size_t len); void MsgGetStructuredData(smsg_t *pM, uchar **pBuf, rs_size_t *len); rsRetVal msgSetFromSockinfo(smsg_t *pThis, struct sockaddr_storage *sa); void MsgSetRcvFrom(smsg_t *pMsg, prop_t *); void MsgSetRcvFromStr(smsg_t *const pMsg, const uchar *pszRcvFrom, const int, prop_t **); rsRetVal MsgSetRcvFromIP(smsg_t *pMsg, prop_t *); rsRetVal MsgSetRcvFromIPStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp); rsRetVal MsgSetRcvFromPort(smsg_t *pMsg, prop_t *); rsRetVal MsgSetRcvFromPortStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp); void MsgSetHOSTNAME(smsg_t *pMsg, const uchar *pszHOSTNAME, const int lenHOSTNAME); rsRetVal MsgSetAfterPRIOffs(smsg_t *pMsg, int offs); void MsgSetMSGoffs(smsg_t *pMsg, int offs); void MsgSetRawMsgWOSize(smsg_t *pMsg, char *pszRawMsg); void ATTR_NONNULL() MsgSetRawMsg(smsg_t *const pThis, const char *const pszRawMsg, const size_t lenMsg); rsRetVal MsgReplaceMSG(smsg_t *pThis, const uchar *pszMSG, int lenMSG); uchar *MsgGetProp(smsg_t *pMsg, struct templateEntry *pTpe, msgPropDescr_t *pProp, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow); void getTAG(smsg_t *pM, uchar **ppBuf, int *piLen, sbool); const char *getTimeReported(smsg_t *pM, enum tplFormatTypes eFmt); const char *getPRI(smsg_t *pMsg); int getPRIi(const smsg_t *const pM); int ATTR_NONNULL() getRawMsgLen(const smsg_t *const pMsg); void getRawMsg(const smsg_t *pM, uchar **pBuf, int *piLen); void ATTR_NONNULL() MsgTruncateToMaxSize(smsg_t *const pThis); rsRetVal msgAddJSON(smsg_t *pM, uchar *name, struct json_object *json, int force_reset, int sharedReference); rsRetVal msgAddMetadata(smsg_t *msg, uchar *metaname, uchar *metaval); rsRetVal msgAddMultiMetadata(smsg_t *msg, const uchar **metaname, const uchar **metaval, const int count); rsRetVal MsgGetSeverity(smsg_t *pThis, int *piSeverity); rsRetVal MsgDeserialize(smsg_t *pMsg, strm_t *pStrm); rsRetVal MsgSetPropsViaJSON(smsg_t *__restrict__ const pMsg, const uchar *__restrict__ const json); rsRetVal MsgSetPropsViaJSON_Object(smsg_t *__restrict__ const pMsg, struct json_object *json); const uchar *msgGetJSONMESG(smsg_t *__restrict__ const pMsg); uchar *getMSG(smsg_t *pM); const char *getHOSTNAME(smsg_t *pM); char *getPROCID(smsg_t *pM, sbool bLockMutex); char *getAPPNAME(smsg_t *pM, sbool bLockMutex); void setMSGLen(smsg_t *pM, int lenMsg); int getMSGLen(smsg_t *pM); void getInputName(const smsg_t *const pM, uchar **ppsz, int *const plen); int getHOSTNAMELen(smsg_t *pM); uchar *getProgramName(smsg_t *pM, sbool bLockMutex); uchar *getRcvFrom(smsg_t *pM); rsRetVal propNameToID(const uchar *pName, propid_t *pPropID); uchar *propIDToName(propid_t propID); rsRetVal ATTR_NONNULL() msgCheckVarExists(smsg_t *const pMsg, msgPropDescr_t *pProp); rsRetVal msgGetJSONPropJSON(smsg_t *pMsg, msgPropDescr_t *pProp, struct json_object **pjson); rsRetVal msgGetJSONPropJSONorString(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **pjson, uchar **pcstr); rsRetVal getJSONPropVal( smsg_t *pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed); rsRetVal msgSetJSONFromVar(smsg_t *pMsg, uchar *varname, struct svar *var, int force_reset); rsRetVal msgDelJSON(smsg_t *pMsg, uchar *varname); rsRetVal jsonFind(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **jsonres); struct json_object *jsonDeepCopy(struct json_object *src); rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen); void msgPropDescrDestruct(msgPropDescr_t *pProp); void msgSetPRI(smsg_t *const __restrict__ pMsg, syslog_pri_t pri); #define msgGetProtocolVersion(pM) ((pM)->iProtocolVersion) /* returns non-zero if the message has structured data, 0 otherwise */ #define MsgHasStructuredData(pM) (((pM)->pszStrucData == NULL) ? 0 : 1) /* ------------------------------ some inline functions ------------------------------ */ /* add Metadata to the message. This is stored in a special JSON * container. Note that only string types are currently supported, * what should pose absolutely no problem with the string-ish nature * of rsyslog metadata. * added 2015-01-09 rgerhards */ /* set raw message size. This is needed in some cases where a trunctation is necessary * but the raw message must not be newly set. The most important (and currently only) * use case is if we remove trailing LF or NUL characters. Note that the size can NOT * be extended, only shrunk! * rgerhards, 2009-08-26 */ static inline void __attribute__((unused)) MsgSetRawMsgSize(smsg_t *const __restrict__ pMsg, const size_t newLen) { assert(newLen <= (size_t)pMsg->iLenRawMsg); pMsg->iLenRawMsg = newLen; pMsg->pszRawMsg[newLen] = '\0'; } /* get the ruleset that is associated with the ruleset. * May be NULL. -- rgerhards, 2009-10-27 */ #define MsgGetRuleset(pMsg) ((pMsg)->pRuleset) #endif /* #ifndef MSG_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_ptcp.h0000644000000000000000000000013215055605325016205 xustar0030 mtime=1756826325.649800683 30 atime=1764931010.426184769 30 ctime=1764935923.379579581 rsyslog-8.2512.0/runtime/nsd_ptcp.h0000664000175000017500000000372015055605325015653 0ustar00rgerrger/* An implementation of the nsd interface for plain tcp sockets. * * Copyright 2007-2020 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NSD_PTCP_H #define INCLUDED_NSD_PTCP_H #include #include "tcpsrv.h" #include "nsd.h" typedef nsd_if_t nsd_ptcp_if_t; /* we just *implement* this interface */ /* the nsd_ptcp object */ struct nsd_ptcp_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ prop_t *remoteIP; /**< IP address of remote peer (currently used in server mode, only) */ uchar *pRemHostName; /**< host name of remote peer (currently used in server mode, only) */ struct sockaddr_storage remAddr; /**< remote addr as sockaddr - used for legacy ACL code */ int sock; /**< the socket we use for regular, single-socket, operations */ int iKeepAliveIntvl; /**< socket layer KEEPALIVE interval */ int iKeepAliveProbes; /**< socket layer KEEPALIVE probes */ int iKeepAliveTime; /**< socket layer KEEPALIVE timeout */ }; /* interface is defined in nsd.h, we just implement it! */ #define nsd_ptcpCURR_IF_VERSION nsdCURR_IF_VERSION /* prototypes */ PROTOTYPEObj(nsd_ptcp); /* the name of our library binary */ #define LM_NSD_PTCP_FILENAME "lmnsd_ptcp" #endif /* #ifndef INCLUDED_NSD_PTCP_H */ rsyslog-8.2512.0/runtime/PaxHeaders/net.c0000644000000000000000000000013115071746523015157 xustar0030 mtime=1760021843.865421412 29 atime=1764931006.98512765 30 ctime=1764935923.338578954 rsyslog-8.2512.0/runtime/net.c0000664000175000017500000017071715071746523014641 0ustar00rgerrger/* net.c * Implementation of network-related stuff. * * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c) * This file is under development and has not yet arrived at being fully * self-contained and a real object. So far, it is mostly an excerpt * of the "old" networking code without any modifications. However, it * helps to have things at the right place one we go to the meat of it. * * Starting 2007-12-24, I have begun to shuffle more network-related code * from syslogd.c to over here. I am not sure if it will stay here in the * long term, but it is good to have it out of syslogd.c. Maybe this here is * an interim location ;) * * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETIFADDRS #include #else #include "compat/ifaddrs.h" #endif /* HAVE_GETIFADDRS */ #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "parse.h" #include "srUtils.h" #include "obj.h" #include "errmsg.h" #include "net.h" #include "dnscache.h" #include "prop.h" #include "rsconf.h" #ifdef OS_SOLARIS #include #define s6_addr32 _S6_un._S6_u32 typedef unsigned int u_int32_t; #endif MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) #ifndef HAVE_STRUCT_SOCKADDR_SA_LEN extern size_t SALEN(struct sockaddr *sa); #endif /* support for defining allowed TCP and UDP senders. We use the same * structure to implement this (a linked list), but we define two different * list roots, one for UDP and one for TCP. * rgerhards, 2005-09-26 */ /* All of the five below are read-only after startup */ struct AllowedSenders *pAllowedSenders_UDP = NULL; /* the roots of the allowed sender */ struct AllowedSenders *pAllowedSenders_TCP = NULL; /* lists. If NULL, all senders are ok! */ static struct AllowedSenders *pLastAllowedSenders_UDP = NULL; /* and now the pointers to the last */ static struct AllowedSenders *pLastAllowedSenders_TCP = NULL; /* element in the respective list */ #ifdef USE_GSSAPI struct AllowedSenders *pAllowedSenders_GSS = NULL; static struct AllowedSenders *pLastAllowedSenders_GSS = NULL; #endif /* ------------------------------ begin permitted peers code ------------------------------ */ /* sets the correct allow root pointer based on provided type * rgerhards, 2008-12-01 */ static rsRetVal setAllowRoot(struct AllowedSenders **ppAllowRoot, uchar *pszType) { DEFiRet; if (!strcmp((char *)pszType, "UDP")) *ppAllowRoot = pAllowedSenders_UDP; else if (!strcmp((char *)pszType, "TCP")) *ppAllowRoot = pAllowedSenders_TCP; #ifdef USE_GSSAPI else if (!strcmp((char *)pszType, "GSS")) *ppAllowRoot = pAllowedSenders_GSS; #endif else { dbgprintf("program error: invalid allowed sender ID '%s', denying...\n", pszType); ABORT_FINALIZE(RS_RET_CODE_ERR); /* everything is invalid for an invalid type */ } finalize_it: RETiRet; } /* re-initializes (sets to NULL) the correct allow root pointer * rgerhards, 2009-01-12 */ static rsRetVal reinitAllowRoot(uchar *pszType) { DEFiRet; if (!strcmp((char *)pszType, "UDP")) pAllowedSenders_UDP = NULL; else if (!strcmp((char *)pszType, "TCP")) pAllowedSenders_TCP = NULL; #ifdef USE_GSSAPI else if (!strcmp((char *)pszType, "GSS")) pAllowedSenders_GSS = NULL; #endif else { dbgprintf("program error: invalid allowed sender ID '%s', denying...\n", pszType); ABORT_FINALIZE(RS_RET_CODE_ERR); /* everything is invalid for an invalid type */ } finalize_it: RETiRet; } /* add a wildcard entry to this permitted peer. Entries are always * added at the tail of the list. pszStr and lenStr identify the wildcard * entry to be added. Note that the string is NOT \0 terminated, so * we must rely on lenStr for when it is finished. * rgerhards, 2008-05-27 */ static rsRetVal AddPermittedPeerWildcard(permittedPeers_t *pPeer, uchar *pszStr, size_t lenStr) { permittedPeerWildcard_t *pNew = NULL; size_t iSrc; size_t iDst; DEFiRet; assert(pPeer != NULL); assert(pszStr != NULL); CHKmalloc(pNew = calloc(1, sizeof(*pNew))); if (lenStr == 0) { /* empty domain components are permitted */ pNew->wildcardType = PEER_WILDCARD_EMPTY_COMPONENT; FINALIZE; } else { /* alloc memory for the domain component. We may waste a byte or * two, but that's ok. */ CHKmalloc(pNew->pszDomainPart = malloc(lenStr + 1)); } if (pszStr[0] == '*') { pNew->wildcardType = PEER_WILDCARD_AT_START; iSrc = 1; /* skip '*' */ } else { iSrc = 0; } for (iDst = 0; iSrc < lenStr && pszStr[iSrc] != '*'; ++iSrc, ++iDst) { pNew->pszDomainPart[iDst] = pszStr[iSrc]; } if (iSrc < lenStr) { if (iSrc + 1 == lenStr && pszStr[iSrc] == '*') { if (pNew->wildcardType == PEER_WILDCARD_AT_START) { ABORT_FINALIZE(RS_RET_INVALID_WILDCARD); } else { pNew->wildcardType = PEER_WILDCARD_AT_END; } } else { /* we have an invalid wildcard, something follows the asterisk! */ ABORT_FINALIZE(RS_RET_INVALID_WILDCARD); } } if (lenStr == 1 && pNew->wildcardType == PEER_WILDCARD_AT_START) { pNew->wildcardType = PEER_WILDCARD_MATCH_ALL; } /* if we reach this point, we had a valid wildcard. We now need to * properly terminate the domain component string. */ pNew->pszDomainPart[iDst] = '\0'; pNew->lenDomainPart = strlen((char *)pNew->pszDomainPart); finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) { if (pNew->pszDomainPart != NULL) free(pNew->pszDomainPart); free(pNew); } } else { /* enqueue the element */ if (pPeer->pWildcardRoot == NULL) { pPeer->pWildcardRoot = pNew; pPeer->pWildcardLast = pNew; } else { pPeer->pWildcardLast->pNext = pNew; } pPeer->pWildcardLast = pNew; } RETiRet; } /* Destruct a permitted peer's wildcard list -- rgerhards, 2008-05-27 */ static rsRetVal DestructPermittedPeerWildcards(permittedPeers_t *pPeer) { permittedPeerWildcard_t *pCurr; permittedPeerWildcard_t *pDel; DEFiRet; assert(pPeer != NULL); for (pCurr = pPeer->pWildcardRoot; pCurr != NULL; /*EMPTY*/) { pDel = pCurr; pCurr = pCurr->pNext; free(pDel->pszDomainPart); free(pDel); } pPeer->pWildcardRoot = NULL; pPeer->pWildcardLast = NULL; RETiRet; } /* add a permitted peer. PermittedPeers is an interim solution until we can provide * access control via enhanced RainerScript methods. * Note: the provided string is handed over to this function, caller must * no longer access it. -- rgerhards, 2008-05-19 */ static rsRetVal AddPermittedPeer(permittedPeers_t **ppRootPeer, uchar *pszID) { permittedPeers_t *pNew = NULL; DEFiRet; assert(ppRootPeer != NULL); assert(pszID != NULL); CHKmalloc(pNew = calloc(1, sizeof(permittedPeers_t))); /* we use calloc() for consistency with "real" objects */ CHKmalloc(pNew->pszID = (uchar *)strdup((char *)pszID)); if (*ppRootPeer != NULL) { pNew->pNext = *ppRootPeer; } *ppRootPeer = pNew; finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) free(pNew); } RETiRet; } /* Destruct a permitted peers list -- rgerhards, 2008-05-19 */ static rsRetVal DestructPermittedPeers(permittedPeers_t **ppRootPeer) { permittedPeers_t *pCurr; permittedPeers_t *pDel; DEFiRet; assert(ppRootPeer != NULL); for (pCurr = *ppRootPeer; pCurr != NULL; /*EMPTY*/) { pDel = pCurr; pCurr = pCurr->pNext; DestructPermittedPeerWildcards(pDel); free(pDel->pszID); free(pDel); } *ppRootPeer = NULL; RETiRet; } /* Compile a wildcard. The function first checks if there is a wildcard * present and compiles it only if so ;) It sets the etryType status * accordingly. * rgerhards, 2008-05-27 */ static rsRetVal PermittedPeerWildcardCompile(permittedPeers_t *pPeer) { uchar *pC; uchar *pStart; DEFiRet; assert(pPeer != NULL); assert(pPeer->pszID != NULL); /* first check if we have a wildcard */ for (pC = pPeer->pszID; *pC != '\0' && *pC != '*'; ++pC) /*EMPTY, just skip*/ ; if (*pC == '\0') { /* no wildcard found, we are mostly done */ pPeer->etryType = PERM_PEER_TYPE_PLAIN; FINALIZE; } /* if we reach this point, the string contains wildcards. So let's * compile the structure. To do so, we must parse from dot to dot * and create a wildcard entry for each domain component we find. * We must also flag problems if we have an asterisk in the middle * of the text (it is supported at the start or end only). */ pPeer->etryType = PERM_PEER_TYPE_WILDCARD; pC = pPeer->pszID; while (*pC != '\0') { pStart = pC; /* find end of domain component */ for (; *pC != '\0' && *pC != '.'; ++pC) /*EMPTY, just skip*/ ; CHKiRet(AddPermittedPeerWildcard(pPeer, pStart, pC - pStart)); /* now check if we have an empty component at end of string */ if (*pC == '.' && *(pC + 1) == '\0') { /* pStart is a dummy, it is not used if length is 0 */ CHKiRet(AddPermittedPeerWildcard(pPeer, pStart, 0)); } if (*pC != '\0') ++pC; } finalize_it: if (iRet != RS_RET_OK) { LogError(0, iRet, "error compiling wildcard expression '%s'", pPeer->pszID); } RETiRet; } /* Do a (potential) wildcard match. The function first checks if the wildcard * has already been compiled and, if not, compiles it. If the peer entry in * question does NOT contain a wildcard, a simple strcmp() is done. * *pbIsMatching is set to 0 if there is no match and something else otherwise. * rgerhards, 2008-05-27 */ static rsRetVal PermittedPeerWildcardMatch(permittedPeers_t *const pPeer, const uchar *pszNameToMatch, int *const pbIsMatching) { const permittedPeerWildcard_t *pWildcard; const uchar *pC; size_t iWildcard, iName; /* work indexes for backward comparisons */ DEFiRet; assert(pPeer != NULL); assert(pszNameToMatch != NULL); assert(pbIsMatching != NULL); if (pPeer->etryType == PERM_PEER_TYPE_UNDECIDED) { PermittedPeerWildcardCompile(pPeer); } if (pPeer->etryType == PERM_PEER_TYPE_PLAIN) { *pbIsMatching = !strcmp((char *)pPeer->pszID, (char *)pszNameToMatch); FINALIZE; } /* we have a wildcard, so we need to extract the domain components and * check then against the provided wildcards. */ pWildcard = pPeer->pWildcardRoot; pC = pszNameToMatch; while (*pC != '\0') { if (pWildcard == NULL) { /* we have more domain components than we have wildcards --> no match */ *pbIsMatching = 0; FINALIZE; } const uchar *const pStart = pC; /* start of current domain component */ while (*pC != '\0' && *pC != '.') { ++pC; } /* got the component, now do the match */ switch (pWildcard->wildcardType) { case PEER_WILDCARD_NONE: if (pWildcard->lenDomainPart != (size_t)(pC - pStart) || strncmp((char *)pStart, (char *)pWildcard->pszDomainPart, pC - pStart)) { *pbIsMatching = 0; FINALIZE; } break; case PEER_WILDCARD_AT_START: /* we need to do the backwards-matching manually */ if (pWildcard->lenDomainPart > (size_t)(pC - pStart)) { *pbIsMatching = 0; FINALIZE; } iName = (size_t)(pC - pStart) - pWildcard->lenDomainPart; iWildcard = 0; while (iWildcard < pWildcard->lenDomainPart) { // I give up, I see now way to remove false positive -- rgerhards, 2017-10-23 #ifndef __clang_analyzer__ if (pWildcard->pszDomainPart[iWildcard] != pStart[iName]) { *pbIsMatching = 0; FINALIZE; } #endif ++iName; ++iWildcard; } break; case PEER_WILDCARD_AT_END: if (pWildcard->lenDomainPart > (size_t)(pC - pStart) || strncmp((char *)pStart, (char *)pWildcard->pszDomainPart, pWildcard->lenDomainPart)) { *pbIsMatching = 0; FINALIZE; } break; case PEER_WILDCARD_MATCH_ALL: /* everything is OK, just continue */ break; case PEER_WILDCARD_EMPTY_COMPONENT: if (pC - pStart > 0) { /* if it is not empty, it is no match... */ *pbIsMatching = 0; FINALIZE; } break; default: // We need to satisfy compiler which does not properly handle enum break; } pWildcard = pWildcard->pNext; /* we processed this entry */ /* skip '.' if we had it and so prepare for next iteration */ if (*pC == '.') ++pC; } if (pWildcard != NULL) { /* we have more domain components than in the name to be * checked. So this is no match. */ *pbIsMatching = 0; FINALIZE; } *pbIsMatching = 1; /* finally... it matches ;) */ finalize_it: RETiRet; } /* ------------------------------ end permitted peers code ------------------------------ */ /* Code for handling allowed/disallowed senders */ static void MaskIP6(struct in6_addr *addr, uint8_t bits) { register uint8_t i; assert(addr != NULL); assert(bits <= 128); i = bits / 32; if (bits % 32) addr->s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32))); for (; i < (sizeof addr->s6_addr32) / 4; i++) addr->s6_addr32[i] = 0; } static void MaskIP4(struct in_addr *addr, uint8_t bits) { assert(addr != NULL); assert(bits <= 32); addr->s_addr &= htonl(0xffffffff << (32 - bits)); } #define SIN(sa) ((struct sockaddr_in *)(void *)(sa)) #define SIN6(sa) ((struct sockaddr_in6 *)(void *)(sa)) /* This is a cancel-safe getnameinfo() version, because we learned * (via drd/valgrind) that getnameinfo() seems to have some issues * when being cancelled, at least if the module was dlloaded. * rgerhards, 2008-09-30 */ static int mygetnameinfo( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { int iCancelStateSave; int i; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); i = getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); pthread_setcancelstate(iCancelStateSave, NULL); return i; } /* This function adds an allowed sender entry to the ACL linked list. * In any case, a single entry is added. If an error occurs, the * function does its error reporting itself. All validity checks * must already have been done by the caller. * This is a helper to AddAllowedSender(). * rgerhards, 2007-07-17 */ static rsRetVal AddAllowedSenderEntry(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast, struct NetAddr *iAllow, uint8_t iSignificantBits) { struct AllowedSenders *pEntry = NULL; assert(ppRoot != NULL); assert(ppLast != NULL); assert(iAllow != NULL); if ((pEntry = (struct AllowedSenders *)calloc(1, sizeof(struct AllowedSenders))) == NULL) { return RS_RET_OUT_OF_MEMORY; /* no options left :( */ } memcpy(&(pEntry->allowedSender), iAllow, sizeof(struct NetAddr)); pEntry->pNext = NULL; pEntry->SignificantBits = iSignificantBits; /* enqueue */ if (*ppRoot == NULL) { *ppRoot = pEntry; } else { (*ppLast)->pNext = pEntry; } *ppLast = pEntry; return RS_RET_OK; } /* function to clear the allowed sender structure in cases where * it must be freed (occurs most often when HUPed). * rgerhards, 2008-12-02: revamped this code when we fixed the interface * definition. Now an iterative algorithm is used. */ static void clearAllowedSenders(uchar *pszType) { struct AllowedSenders *pPrev; struct AllowedSenders *pCurr = NULL; if (setAllowRoot(&pCurr, pszType) != RS_RET_OK) return; /* if something went wrong, so let's leave */ while (pCurr != NULL) { pPrev = pCurr; pCurr = pCurr->pNext; /* now delete the entry we are right now processing */ if (F_ISSET(pPrev->allowedSender.flags, ADDR_NAME)) free(pPrev->allowedSender.addr.HostWildcard); else free(pPrev->allowedSender.addr.NetAddr); free(pPrev); } /* indicate root pointer is de-init (was forgotten previously, resulting in * all kinds of interesting things) -- rgerhards, 2009-01-12 */ reinitAllowRoot(pszType); } /* function to add an allowed sender to the allowed sender list. The * root of the list is caller-provided, so it can be used for all * supported lists. The caller must provide a pointer to the root, * as it eventually needs to be updated. Also, a pointer to the * pointer to the last element must be provided (to speed up adding * list elements). * rgerhards, 2005-09-26 * If a hostname is given there are possible multiple entries * added (all addresses from that host). */ static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast, struct NetAddr *iAllow, uint8_t iSignificantBits) { struct addrinfo *restmp = NULL; DEFiRet; assert(ppRoot != NULL); assert(ppLast != NULL); assert(iAllow != NULL); if (!F_ISSET(iAllow->flags, ADDR_NAME)) { if (iSignificantBits == 0) /* we handle this seperatly just to provide a better * error message. */ LogError(0, NO_ERRCODE, "You can not specify 0 bits of the netmask, this would " "match ALL systems. If you really intend to do that, " "remove all $AllowedSender directives."); switch (iAllow->addr.NetAddr->sa_family) { case AF_INET: if ((iSignificantBits < 1) || (iSignificantBits > 32)) { LogError(0, NO_ERRCODE, "Invalid number of bits (%d) in IPv4 address - adjusted to 32", (int)iSignificantBits); iSignificantBits = 32; } MaskIP4(&(SIN(iAllow->addr.NetAddr)->sin_addr), iSignificantBits); break; case AF_INET6: if ((iSignificantBits < 1) || (iSignificantBits > 128)) { LogError(0, NO_ERRCODE, "Invalid number of bits (%d) in IPv6 address - adjusted to 128", iSignificantBits); iSignificantBits = 128; } MaskIP6(&(SIN6(iAllow->addr.NetAddr)->sin6_addr), iSignificantBits); break; default: /* rgerhards, 2007-07-16: We have an internal program error in this * case. However, there is not much we can do against it right now. Of * course, we could abort, but that would probably cause more harm * than good. So we continue to run. We simply do not add this line - the * worst thing that happens is that one host will not be allowed to * log. */ LogError(0, NO_ERRCODE, "Internal error caused AllowedSender to be ignored, AF = %d", iAllow->addr.NetAddr->sa_family); ABORT_FINALIZE(RS_RET_ERR); } /* OK, entry constructed, now lets add it to the ACL list */ iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits); } else { /* we need to process a hostname ACL */ if (glbl.GetDisableDNS(loadConf)) { LogError(0, NO_ERRCODE, "Ignoring hostname based ACLs because DNS is disabled."); ABORT_FINALIZE(RS_RET_OK); } if (!strchr(iAllow->addr.HostWildcard, '*') && !strchr(iAllow->addr.HostWildcard, '?') && loadConf->globals.ACLDontResolve == 0) { /* single host - in this case, we pull its IP addresses from DNS * and add IP-based ACLs. */ struct addrinfo hints, *res; struct NetAddr allowIP; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; #ifdef AI_ADDRCONFIG /* seems not to be present on all systems */ hints.ai_flags = AI_ADDRCONFIG; #endif if (getaddrinfo(iAllow->addr.HostWildcard, NULL, &hints, &res) != 0) { LogError(0, NO_ERRCODE, "DNS error: Can't resolve \"%s\"", iAllow->addr.HostWildcard); if (loadConf->globals.ACLAddHostnameOnFail) { LogError(0, NO_ERRCODE, "Adding hostname \"%s\" to ACL as a wildcard " "entry.", iAllow->addr.HostWildcard); iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits); FINALIZE; } else { LogError(0, NO_ERRCODE, "Hostname \"%s\" WON\'T be added to ACL.", iAllow->addr.HostWildcard); ABORT_FINALIZE(RS_RET_NOENTRY); } } restmp = res; for (; res != NULL; res = res->ai_next) { switch (res->ai_family) { case AF_INET: /* add IPv4 */ iSignificantBits = 32; allowIP.flags = 0; if ((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen); if ((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP, iSignificantBits)) != RS_RET_OK) { free(allowIP.addr.NetAddr); FINALIZE; } break; case AF_INET6: /* IPv6 - but need to check if it is a v6-mapped IPv4 */ if (IN6_IS_ADDR_V4MAPPED(&SIN6(res->ai_addr)->sin6_addr)) { /* extract & add IPv4 */ iSignificantBits = 32; allowIP.flags = 0; if ((allowIP.addr.NetAddr = (struct sockaddr *)malloc(sizeof(struct sockaddr))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } SIN(allowIP.addr.NetAddr)->sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN SIN(allowIP.addr.NetAddr)->sin_len = sizeof(struct sockaddr_in); #endif SIN(allowIP.addr.NetAddr)->sin_port = 0; memcpy(&(SIN(allowIP.addr.NetAddr)->sin_addr.s_addr), &(SIN6(res->ai_addr)->sin6_addr.s6_addr32[3]), sizeof(in_addr_t)); if ((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP, iSignificantBits)) != RS_RET_OK) { free(allowIP.addr.NetAddr); FINALIZE; } } else { /* finally add IPv6 */ iSignificantBits = 128; allowIP.flags = 0; if ((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen); if ((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP, iSignificantBits)) != RS_RET_OK) { free(allowIP.addr.NetAddr); FINALIZE; } } break; default: // We need to satisfy compiler which does not properly handle enum break; } } } else { /* wildcards in hostname - we need to add a text-based ACL. * For this, we already have everything ready and just need * to pass it along... */ iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits); } } finalize_it: if (restmp != NULL) { freeaddrinfo(restmp); } RETiRet; } static const char *SENDER_TEXT[4] = {"", "UDP", "TCP", "GSS"}; /* Print an allowed sender list. The caller must tell us which one. * iListToPrint = 1 means UDP, 2 means TCP * rgerhards, 2005-09-27 */ static void PrintAllowedSenders(int iListToPrint) { struct AllowedSenders *pSender; uchar szIP[64]; #ifdef USE_GSSAPI #define iListToPrint_MAX 3 #else #define iListToPrint_MAX 2 #endif assert((iListToPrint > 0) && (iListToPrint <= iListToPrint_MAX)); dbgprintf("Allowed %s Senders:\n", SENDER_TEXT[iListToPrint]); pSender = (iListToPrint == 1) ? pAllowedSenders_UDP : #ifdef USE_GSSAPI (iListToPrint == 3) ? pAllowedSenders_GSS : #endif pAllowedSenders_TCP; if (pSender == NULL) { dbgprintf("\tNo restrictions set.\n"); } else { while (pSender != NULL) { if (F_ISSET(pSender->allowedSender.flags, ADDR_NAME)) dbgprintf("\t%s\n", pSender->allowedSender.addr.HostWildcard); else { if (mygetnameinfo(pSender->allowedSender.addr.NetAddr, SALEN(pSender->allowedSender.addr.NetAddr), (char *)szIP, 64, NULL, 0, NI_NUMERICHOST) == 0) { dbgprintf("\t%s/%u\n", szIP, pSender->SignificantBits); } else { /* getnameinfo() failed - but as this is only a * debug function, we simply spit out an error and do * not care much about it. */ dbgprintf( "\tERROR in getnameinfo() - something may be wrong " "- ignored for now\n"); } } pSender = pSender->pNext; } } } /* parse an allowed sender config line and add the allowed senders * (if the line is correct). * rgerhards, 2005-09-27 */ static rsRetVal addAllowedSenderLine(char *pName, uchar **ppRestOfConfLine) { struct AllowedSenders **ppRoot; struct AllowedSenders **ppLast; rsParsObj *pPars; rsRetVal iRet; struct NetAddr *uIP = NULL; int iBits; assert(pName != NULL); assert(ppRestOfConfLine != NULL); assert(*ppRestOfConfLine != NULL); if (!strcasecmp(pName, "udp")) { ppRoot = &pAllowedSenders_UDP; ppLast = &pLastAllowedSenders_UDP; } else if (!strcasecmp(pName, "tcp")) { ppRoot = &pAllowedSenders_TCP; ppLast = &pLastAllowedSenders_TCP; #ifdef USE_GSSAPI } else if (!strcasecmp(pName, "gss")) { ppRoot = &pAllowedSenders_GSS; ppLast = &pLastAllowedSenders_GSS; #endif } else { LogError(0, RS_RET_ERR, "Invalid protocol '%s' in allowed sender " "list, line ignored", pName); return RS_RET_ERR; } /* OK, we now know the protocol and have valid list pointers. * So let's process the entries. We are using the parse class * for this. */ /* create parser object starting with line string without leading colon */ if ((iRet = rsParsConstructFromSz(&pPars, (uchar *)*ppRestOfConfLine) != RS_RET_OK)) { LogError(0, iRet, "Error %d constructing parser object - ignoring allowed sender list", iRet); return (iRet); } while (!parsIsAtEndOfParseString(pPars)) { if (parsPeekAtCharAtParsPtr(pPars) == '#') break; /* a comment-sign stops processing of line */ /* now parse a single IP address */ if ((iRet = parsAddrWithBits(pPars, &uIP, &iBits)) != RS_RET_OK) { LogError(0, iRet, "Error %d parsing address in allowed sender" "list - ignoring.", iRet); rsParsDestruct(pPars); return (iRet); } if ((iRet = AddAllowedSender(ppRoot, ppLast, uIP, iBits)) != RS_RET_OK) { if (iRet == RS_RET_NOENTRY) { LogError(0, iRet, "Error %d adding allowed sender entry " "- ignoring.", iRet); } else { LogError(0, iRet, "Error %d adding allowed sender entry " "- terminating, nothing more will be added.", iRet); rsParsDestruct(pPars); free(uIP); return (iRet); } } free(uIP); /* copy stored in AllowedSenders list */ } /* cleanup */ *ppRestOfConfLine += parsGetCurrentPosition(pPars); return rsParsDestruct(pPars); } /* compares a host to an allowed sender list entry. Handles all subleties * including IPv4/v6 as well as domain name wildcards. * This is a helper to isAllowedSender. * Returns 0 if they do not match, 1 if they match and 2 if a DNS name would have been required. * contributed 2007-07-16 by mildew@gmail.com */ static int MaskCmp(struct NetAddr *pAllow, uint8_t bits, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS) { assert(pAllow != NULL); assert(pFrom != NULL); if (F_ISSET(pAllow->flags, ADDR_NAME)) { if (bChkDNS == 0) return 2; dbgprintf("MaskCmp: host=\"%s\"; pattern=\"%s\"\n", pszFromHost, pAllow->addr.HostWildcard); #if !defined(FNM_CASEFOLD) /* TODO: I don't know if that then works, seen on HP UX, what I have not in lab... ;) */ return (fnmatch(pAllow->addr.HostWildcard, pszFromHost, FNM_NOESCAPE) == 0); #else return (fnmatch(pAllow->addr.HostWildcard, pszFromHost, FNM_NOESCAPE | FNM_CASEFOLD) == 0); #endif } else { /* We need to compare an IP address */ switch (pFrom->sa_family) { case AF_INET: if (AF_INET == pAllow->addr.NetAddr->sa_family) return ((SIN(pFrom)->sin_addr.s_addr & htonl(0xffffffff << (32 - bits))) == SIN(pAllow->addr.NetAddr)->sin_addr.s_addr); else return 0; break; case AF_INET6: switch (pAllow->addr.NetAddr->sa_family) { case AF_INET6: { struct in6_addr ip, net; register uint8_t i; memcpy(&ip, &(SIN6(pFrom))->sin6_addr, sizeof(struct in6_addr)); memcpy(&net, &(SIN6(pAllow->addr.NetAddr))->sin6_addr, sizeof(struct in6_addr)); i = bits / 32; if (bits % 32) ip.s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32))); for (; i < (sizeof ip.s6_addr32) / 4; i++) ip.s6_addr32[i] = 0; return (memcmp(ip.s6_addr, net.s6_addr, sizeof ip.s6_addr) == 0 && (SIN6(pAllow->addr.NetAddr)->sin6_scope_id != 0 ? SIN6(pFrom)->sin6_scope_id == SIN6(pAllow->addr.NetAddr)->sin6_scope_id : 1)); } case AF_INET: { struct in6_addr *ip6 = &(SIN6(pFrom))->sin6_addr; struct in_addr *net = &(SIN(pAllow->addr.NetAddr))->sin_addr; if ((ip6->s6_addr32[3] & (u_int32_t)htonl((0xffffffff << (32 - bits)))) == net->s_addr && #if BYTE_ORDER == LITTLE_ENDIAN (ip6->s6_addr32[2] == (u_int32_t)0xffff0000) && #else (ip6->s6_addr32[2] == (u_int32_t)0x0000ffff) && #endif (ip6->s6_addr32[1] == 0) && (ip6->s6_addr32[0] == 0)) return 1; else return 0; } default: /* Unsupported AF */ return 0; } /* fallthrough */ default: /* Unsupported AF */ return 0; } } } /* check if a sender is allowed. The root of the the allowed sender. * list must be proveded by the caller. As such, this function can be * used to check both UDP and TCP allowed sender lists. * returns 1, if the sender is allowed, 0 if not and 2 if we could not * obtain a result because we would need a dns name, which we don't have * (2 was added rgerhards, 2009-11-16). * rgerhards, 2005-09-26 */ static int isAllowedSender2(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS) { struct AllowedSenders *pAllow; struct AllowedSenders *pAllowRoot = NULL; int bNeededDNS = 0; /* partial check because we could not resolve DNS? */ int ret; assert(pFrom != NULL); if (setAllowRoot(&pAllowRoot, pszType) != RS_RET_OK) return 0; /* if something went wrong, we deny access - that's the better choice... */ if (pAllowRoot == NULL) return 1; /* checking disabled, everything is valid! */ /* now we loop through the list of allowed senders. As soon as * we find a match, we return back (indicating allowed). We loop * until we are out of allowed senders. If so, we fall through the * loop and the function's terminal return statement will indicate * that the sender is disallowed. */ for (pAllow = pAllowRoot; pAllow != NULL; pAllow = pAllow->pNext) { ret = MaskCmp(&(pAllow->allowedSender), pAllow->SignificantBits, pFrom, pszFromHost, bChkDNS); if (ret == 1) return 1; else if (ret == 2) bNeededDNS = 2; } return bNeededDNS; } /* legacy API, not to be used any longer */ static int isAllowedSender(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost) { return isAllowedSender2(pszType, pFrom, pszFromHost, 1); } /* The following #ifdef sequence is a small compatibility * layer. It tries to work around the different availality * levels of SO_BSDCOMPAT on linuxes... * I borrowed this code from * http://www.erlang.org/ml-archive/erlang-questions/200307/msg00037.html * It still needs to be a bit better adapted to rsyslog. * rgerhards 2005-09-19 */ #include static int should_use_so_bsdcompat(void) { #ifndef OS_BSD static int use_so_bsdcompat = -1; /* we guard the init code just by an atomic fetch to local variable. This still * is racy, but the worst that can happen is that we do the very same init twice. * This does hurt less than locking a mutex. */ const int local_use_so_bsdcompat = PREFER_FETCH_32BIT(use_so_bsdcompat); if (local_use_so_bsdcompat == -1) { struct utsname myutsname; unsigned int version, patchlevel; if (uname(&myutsname) < 0) { char errStr[1024]; dbgprintf("uname: %s\r\n", rs_strerror_r(errno, errStr, sizeof(errStr))); PREFER_STORE_1_TO_INT(&use_so_bsdcompat); FINALIZE; } /* Format is .. * where the first three are unsigned integers and the last * is an arbitrary string. We only care about the first two. */ if (sscanf(myutsname.release, "%u.%u", &version, &patchlevel) != 2) { dbgprintf("uname: unexpected release '%s'\r\n", myutsname.release); PREFER_STORE_1_TO_INT(&use_so_bsdcompat); FINALIZE; } /* SO_BSCOMPAT is deprecated and triggers warnings in 2.5 * kernels. It is a no-op in 2.4 but not in 2.2 kernels. */ if (version > 2 || (version == 2 && patchlevel >= 5)) { PREFER_STORE_0_TO_INT(&use_so_bsdcompat); FINALIZE; } } finalize_it: return PREFER_FETCH_32BIT(use_so_bsdcompat); #else /* #ifndef OS_BSD */ return 1; #endif /* #ifndef OS_BSD */ } #ifndef SO_BSDCOMPAT /* this shall prevent compiler errors due to undfined name */ #define SO_BSDCOMPAT 0 #endif /* print out which socket we are listening on. This is only * a debug aid. rgerhards, 2007-07-02 */ static void debugListenInfo(int fd, char *type) { const char *szFamily; int port; union { struct sockaddr_storage sa; struct sockaddr_in sa4; struct sockaddr_in6 sa6; } sockaddr; socklen_t saLen = sizeof(sockaddr.sa); if (getsockname(fd, (struct sockaddr *)&sockaddr.sa, &saLen) == 0) { switch (sockaddr.sa.ss_family) { case PF_INET: szFamily = "IPv4"; port = ntohs(sockaddr.sa4.sin_port); break; case PF_INET6: szFamily = "IPv6"; port = ntohs(sockaddr.sa6.sin6_port); break; default: szFamily = "other"; port = -1; break; } dbgprintf("Listening on %s syslogd socket %d (%s/port %d).\n", type, fd, szFamily, port); return; } /* we can not obtain peer info. We are just providing * debug info, so this is no reason to break the program * or do any serious error reporting. */ dbgprintf("Listening on syslogd socket %d - could not obtain peer info.\n", fd); } /* Return a printable representation of a host addresses. If * a parameter is NULL, it is not set. rgerhards, 2013-01-22 */ static rsRetVal cvthname(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t **ip) { DEFiRet; assert(f != NULL); iRet = dnscacheLookup(f, fqdn, NULL, localName, ip); RETiRet; } /* get the name of the local host. A pointer to a character pointer is passed * in, which on exit points to the local hostname. This buffer is dynamically * allocated and must be free()ed by the caller. If the functions returns an * error, the pointer is NULL. * This function always tries to return a FQDN, even so be quering DNS. So it * is safe to assume for the caller that when the function does not return * a FQDN, it simply is not available. The domain part of that string is * normalized to lower case. The hostname is kept in mixed case for historic * reasons. */ #define EMPTY_HOSTNAME_REPLACEMENT "localhost-empty-hostname" static rsRetVal getLocalHostname(rsconf_t *const pConf, uchar **ppName) { DEFiRet; char hnbuf[8192]; uchar *fqdn = NULL; int empty_hostname = 1; if (gethostname(hnbuf, sizeof(hnbuf)) != 0) { strcpy(hnbuf, EMPTY_HOSTNAME_REPLACEMENT); } else { /* now guard against empty hostname * see https://github.com/rsyslog/rsyslog/issues/1040 */ if (hnbuf[0] == '\0') { strcpy(hnbuf, EMPTY_HOSTNAME_REPLACEMENT); } else { empty_hostname = 0; hnbuf[sizeof(hnbuf) - 1] = '\0'; /* be on the safe side... */ } } char *dot = strstr(hnbuf, "."); struct addrinfo *res = NULL; if (!empty_hostname && dot == NULL && pConf != NULL && !glbl.GetDisableDNS(pConf)) { /* we need to (try) to find the real name via resolver */ struct addrinfo flags; memset(&flags, 0, sizeof(flags)); flags.ai_flags = AI_CANONNAME; int error = getaddrinfo((char *)hnbuf, NULL, &flags, &res); if (error != 0 && error != EAI_NONAME && error != EAI_AGAIN && error != EAI_FAIL) { /* If we get one of errors above, network is probably * not working yet, so we fall back to local hostname below */ LogError(0, RS_RET_ERR, "getaddrinfo failed obtaining local " "hostname - using '%s' instead; error: %s", hnbuf, gai_strerror(error)); } if (res != NULL) { /* When AI_CANONNAME is set first member of res linked-list */ /* should contain what we need */ if (res->ai_canonname != NULL && res->ai_canonname[0] != '\0') { CHKmalloc(fqdn = (uchar *)strdup(res->ai_canonname)); dot = strstr((char *)fqdn, "."); } } } if (fqdn == NULL) { /* already was FQDN or we could not obtain a better one */ CHKmalloc(fqdn = (uchar *)strdup(hnbuf)); } if (dot != NULL) for (char *p = dot + 1; *p; ++p) *p = tolower(*p); *ppName = fqdn; finalize_it: if (res != NULL) { freeaddrinfo(res); } RETiRet; } /* closes the UDP listen sockets (if they exist) and frees * all dynamically assigned memory. */ static void closeUDPListenSockets(int *pSockArr) { register int i; assert(pSockArr != NULL); if (pSockArr != NULL) { for (i = 0; i < *pSockArr; i++) close(pSockArr[i + 1]); free(pSockArr); } } /* create a single UDP socket and bail out if an error occurs. * This is called from a loop inside create_udp_socket which * iterates through potentially multiple sockets. NOT to be * used elsewhere. */ static rsRetVal ATTR_NONNULL(1, 2) create_single_udp_socket(int *const s, /* socket */ struct addrinfo *const r, const uchar *const hostname, const int bIsServer, const int rcvbuf, const int sndbuf, const int ipfreebind, const char *const device) { const int on = 1; int sockflags; int actrcvbuf; int actsndbuf; socklen_t optlen; char errStr[1024]; DEFiRet; assert(r != NULL); // does NOT work with -O2 or higher due to ATTR_NONNULL! assert(s != NULL); #if defined(_AIX) /* AIXPORT : socktype will be SOCK_DGRAM, as set in hints before */ *s = socket(r->ai_family, SOCK_DGRAM, r->ai_protocol); #else *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); #endif if (*s < 0) { if (!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT)) { LogError(errno, NO_ERRCODE, "create_udp_socket(), socket"); /* it is debateble if PF_INET with EAFNOSUPPORT should * also be ignored... */ } ABORT_FINALIZE(RS_RET_ERR); } #ifdef IPV6_V6ONLY if (r->ai_family == AF_INET6) { int ion = 1; if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ion, sizeof(ion)) < 0) { LogError(errno, RS_RET_ERR, "error creating UDP socket - setsockopt"); ABORT_FINALIZE(RS_RET_ERR); } } #endif if (device) { #if defined(SO_BINDTODEVICE) if (setsockopt(*s, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) < 0) #endif { LogError(errno, RS_RET_ERR, "create UDP socket bound to device failed"); ABORT_FINALIZE(RS_RET_ERR); } } if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { LogError(errno, RS_RET_ERR, "create UDP socket failed to set REUSEADDR"); ABORT_FINALIZE(RS_RET_ERR); } /* We need to enable BSD compatibility. Otherwise an attacker * could flood our log files by sending us tons of ICMP errors. */ /* AIXPORT : SO_BSDCOMPAT socket option is deprecated, and its usage * has been discontinued on most unixes, AIX does not support this option, * hence avoid the call. */ #if !defined(OS_BSD) && !defined(__hpux) && !defined(_AIX) if (should_use_so_bsdcompat()) { if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT, (char *)&on, sizeof(on)) < 0) { LogError(errno, RS_RET_ERR, "create UDP socket failed to set BSDCOMPAT"); ABORT_FINALIZE(RS_RET_ERR); } } #endif if (bIsServer) { DBGPRINTF("net.c: trying to set server socket %d to non-blocking mode\n", *s); if ((sockflags = fcntl(*s, F_GETFL)) != -1) { sockflags |= O_NONBLOCK; /* SETFL could fail too, so get it caught by the subsequent * error check. */ sockflags = fcntl(*s, F_SETFL, sockflags); } if (sockflags == -1) { LogError(errno, RS_RET_ERR, "net.c: socket %d fcntl(O_NONBLOCK)", *s); ABORT_FINALIZE(RS_RET_ERR); } } if (sndbuf != 0) { #if defined(SO_SNDBUFFORCE) if (setsockopt(*s, SOL_SOCKET, SO_SNDBUFFORCE, &sndbuf, sizeof(sndbuf)) < 0) #endif { /* if we fail, try to do it the regular way. Experiments show that at * least some platforms do not return an error here, but silently set * it to the max permitted value. So we do our error check a bit * differently by querying the size below. */ if (setsockopt(*s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0) { /* keep Coverity happy */ DBGPRINTF( "setsockopt in %s:%d failed - this is expected and " "handled at later stages\n", __FILE__, __LINE__); } } /* report socket buffer sizes */ optlen = sizeof(actsndbuf); if (getsockopt(*s, SOL_SOCKET, SO_SNDBUF, &actsndbuf, &optlen) == 0) { LogMsg(0, NO_ERRCODE, LOG_INFO, "socket %d, actual os socket sndbuf size is %d", *s, actsndbuf); if (sndbuf != 0 && actsndbuf / 2 != sndbuf) { LogError(errno, NO_ERRCODE, "could not set os socket sndbuf size %d for socket %d, " "value now is %d", sndbuf, *s, actsndbuf / 2); } } else { DBGPRINTF("could not obtain os socket rcvbuf size for socket %d: %s\n", *s, rs_strerror_r(errno, errStr, sizeof(errStr))); } } if (rcvbuf != 0) { #if defined(SO_RCVBUFFORCE) if (setsockopt(*s, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof(rcvbuf)) < 0) #endif { /* if we fail, try to do it the regular way. Experiments show that at * least some platforms do not return an error here, but silently set * it to the max permitted value. So we do our error check a bit * differently by querying the size below. */ if (setsockopt(*s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0) { /* keep Coverity happy */ DBGPRINTF( "setsockopt in %s:%d failed - this is expected and " "handled at later stages\n", __FILE__, __LINE__); } } optlen = sizeof(actrcvbuf); if (getsockopt(*s, SOL_SOCKET, SO_RCVBUF, &actrcvbuf, &optlen) == 0) { LogMsg(0, NO_ERRCODE, LOG_INFO, "socket %d, actual os socket rcvbuf size %d\n", *s, actrcvbuf); if (rcvbuf != 0 && actrcvbuf / 2 != rcvbuf) { LogError(errno, NO_ERRCODE, "cannot set os socket rcvbuf size %d for socket %d, value now is %d", rcvbuf, *s, actrcvbuf / 2); } } else { DBGPRINTF("could not obtain os socket rcvbuf size for socket %d: %s\n", *s, rs_strerror_r(errno, errStr, sizeof(errStr))); } } if (bIsServer) { /* rgerhards, 2007-06-22: if we run on a kernel that does not support * the IPV6_V6ONLY socket option, we need to use a work-around. On such * systems the IPv6 socket does also accept IPv4 sockets. So an IPv4 * socket can not listen on the same port as an IPv6 socket. The only * workaround is to ignore the "socket in use" error. This is what we * do if we have to. */ if ((bind(*s, r->ai_addr, r->ai_addrlen) < 0) #ifndef IPV6_V6ONLY && (errno != EADDRINUSE) #endif ) { if (errno == EADDRNOTAVAIL && ipfreebind != IPFREEBIND_DISABLED) { if (setsockopt(*s, IPPROTO_IP, IP_FREEBIND, &on, sizeof(on)) < 0) { LogError(errno, RS_RET_ERR, "setsockopt(IP_FREEBIND)"); } else if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) { LogError(errno, RS_RET_ERR, "bind with IP_FREEBIND"); } else { if (ipfreebind >= IPFREEBIND_ENABLED_WITH_LOG) LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "bound address %s IP free", hostname); FINALIZE; } } ABORT_FINALIZE(RS_RET_ERR); } } finalize_it: if (iRet != RS_RET_OK) { if (*s != -1) { close(*s); *s = -1; } } RETiRet; } /* creates the UDP listen sockets * hostname and/or pszPort may be NULL, but not both! * bIsServer indicates if a server socket should be created * 1 - server, 0 - client * Note: server sockets are created in non-blocking mode, client ones * are blocking. * param rcvbuf indicates desired rcvbuf size; 0 means OS default, * similar for sndbuf. */ static int *create_udp_socket(uchar *hostname, uchar *pszPort, const int bIsServer, const int rcvbuf, const int sndbuf, const int ipfreebind, char *device) { struct addrinfo hints, *res, *r; int error, maxs, *s, *socks; rsRetVal localRet; assert(!((pszPort == NULL) && (hostname == NULL))); /* one of them must be non-NULL */ memset(&hints, 0, sizeof(hints)); if (bIsServer) hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; else hints.ai_flags = AI_NUMERICSERV; hints.ai_family = glbl.GetDefPFFamily(runConf); hints.ai_socktype = SOCK_DGRAM; #if defined(_AIX) /* AIXPORT : SOCK_DGRAM has the protocol IPPROTO_UDP * getaddrinfo needs this hint on AIX */ hints.ai_protocol = IPPROTO_UDP; #endif error = getaddrinfo((char *)hostname, (char *)pszPort, &hints, &res); if (error) { LogError(0, NO_ERRCODE, "%s", gai_strerror(error)); LogError(0, NO_ERRCODE, "UDP message reception disabled due to error logged in last message.\n"); return NULL; } /* Count max number of sockets we may open */ for (maxs = 0, r = res; r != NULL; r = r->ai_next, maxs++) /* EMPTY */ ; socks = malloc((maxs + 1) * sizeof(int)); if (socks == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "couldn't allocate memory for UDP " "sockets, suspending UDP message reception"); freeaddrinfo(res); return NULL; } *socks = 0; /* num of sockets counter at start of array */ s = socks + 1; for (r = res; r != NULL; r = r->ai_next) { localRet = create_single_udp_socket(s, r, hostname, bIsServer, rcvbuf, sndbuf, ipfreebind, device); if (localRet == RS_RET_OK) { (*socks)++; s++; } } if (res != NULL) freeaddrinfo(res); if (Debug && *socks != maxs) dbgprintf( "We could initialize %d UDP listen sockets out of %d we received " "- this may or may not be an error indication.\n", *socks, maxs); if (*socks == 0) { LogError(0, NO_ERRCODE, "No UDP socket could successfully be initialized, " "some functionality may be disabled.\n"); /* we do NOT need to close any sockets, because there were none... */ free(socks); return (NULL); } return (socks); } /* check if two provided socket addresses point to the same host. Note that the * length of the sockets must be provided as third parameter. This is necessary to * compare non IPv4/v6 hosts, in which case we do a simple memory compare of the * address structure (in that case, the same host may not reliably be detected). * Note that we need to do the comparison not on the full structure, because it contains things * like the port, which we do not need to look at when thinking about hostnames. So we look * at the relevant fields, what means a somewhat more complicated processing. * Also note that we use a non-standard calling interface, as this is much more natural and * it looks extremely unlikely that we get an exception of any kind here. What we * return is mimiced after memcmp(), and as such useful for building binary trees * (the order relation may be a bit arbritrary, but at least it is consistent). * rgerhards, 2009-09-03 */ static int CmpHost(struct sockaddr_storage *s1, struct sockaddr_storage *s2, size_t socklen) { int ret; if (((struct sockaddr *)s1)->sa_family != ((struct sockaddr *)s2)->sa_family) { ret = memcmp(s1, s2, socklen); goto finalize_it; } if (((struct sockaddr *)s1)->sa_family == AF_INET) { if (((struct sockaddr_in *)s1)->sin_addr.s_addr == ((struct sockaddr_in *)s2)->sin_addr.s_addr) { ret = 0; } else if (((struct sockaddr_in *)s1)->sin_addr.s_addr < ((struct sockaddr_in *)s2)->sin_addr.s_addr) { ret = -1; } else { ret = 1; } } else if (((struct sockaddr *)s1)->sa_family == AF_INET6) { /* IPv6 addresses are always 16 octets long */ ret = memcmp(((struct sockaddr_in6 *)s1)->sin6_addr.s6_addr, ((struct sockaddr_in6 *)s2)->sin6_addr.s6_addr, 16); } else { ret = memcmp(s1, s2, socklen); } finalize_it: return ret; } /* check if restrictions (ALCs) exists. The goal of this function is to disable the * somewhat time-consuming ACL checks if no restrictions are defined (the usual case). * This also permits to gain some speedup by using firewall-based ACLs instead of * rsyslog ACLs (the recommended method. * rgerhards, 2009-11-16 */ static rsRetVal HasRestrictions(uchar *pszType, int *bHasRestrictions) { struct AllowedSenders *pAllowRoot = NULL; DEFiRet; CHKiRet(setAllowRoot(&pAllowRoot, pszType)); *bHasRestrictions = (pAllowRoot == NULL) ? 0 : 1; finalize_it: if (iRet != RS_RET_OK) { *bHasRestrictions = 1; /* in this case it is better to check individually */ DBGPRINTF("Error %d trying to obtain ACL restriction state of '%s'\n", iRet, pszType); } RETiRet; } /* return the IP address (IPv4/6) for the provided interface. Returns * RS_RET_NOT_FOUND if interface can not be found in interface list. * The family must be correct (AF_INET vs. AF_INET6, AF_UNSPEC means * either of *these two*). * The function re-queries the interface list (at least in theory). * However, it caches entries in order to avoid too-frequent requery. * rgerhards, 2012-03-06 */ static rsRetVal getIFIPAddr(uchar *szif, int family, uchar *pszbuf, int lenBuf) { #ifdef _AIX struct ifaddrs_rsys *ifaddrs = NULL; struct ifaddrs_rsys *ifa; #else struct ifaddrs *ifaddrs = NULL; struct ifaddrs *ifa; #endif union { struct sockaddr *sa; struct sockaddr_in *ipv4; struct sockaddr_in6 *ipv6; } savecast; void *pAddr; DEFiRet; if (getifaddrs(&ifaddrs) != 0) { ABORT_FINALIZE(RS_RET_ERR); } for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { if (strcmp(ifa->ifa_name, (char *)szif)) continue; savecast.sa = ifa->ifa_addr; if ((family == AF_INET6 || family == AF_UNSPEC) && ifa->ifa_addr->sa_family == AF_INET6) { pAddr = &(savecast.ipv6->sin6_addr); inet_ntop(AF_INET6, pAddr, (char *)pszbuf, lenBuf); break; } else if (/* (family == AF_INET || family == AF_UNSPEC) &&*/ ifa->ifa_addr->sa_family == AF_INET) { pAddr = &(savecast.ipv4->sin_addr); inet_ntop(AF_INET, pAddr, (char *)pszbuf, lenBuf); break; } } if (ifaddrs != NULL) freeifaddrs(ifaddrs); if (ifa == NULL) iRet = RS_RET_NOT_FOUND; finalize_it: RETiRet; } /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(net) CODESTARTobjQueryInterface(net); if (pIf->ifVersion != netCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->cvthname = cvthname; /* things to go away after proper modularization */ pIf->addAllowedSenderLine = addAllowedSenderLine; pIf->PrintAllowedSenders = PrintAllowedSenders; pIf->clearAllowedSenders = clearAllowedSenders; pIf->debugListenInfo = debugListenInfo; pIf->create_udp_socket = create_udp_socket; pIf->closeUDPListenSockets = closeUDPListenSockets; pIf->isAllowedSender = isAllowedSender; pIf->isAllowedSender2 = isAllowedSender2; pIf->should_use_so_bsdcompat = should_use_so_bsdcompat; pIf->getLocalHostname = getLocalHostname; pIf->AddPermittedPeer = AddPermittedPeer; pIf->DestructPermittedPeers = DestructPermittedPeers; pIf->PermittedPeerWildcardMatch = PermittedPeerWildcardMatch; pIf->CmpHost = CmpHost; pIf->HasRestrictions = HasRestrictions; pIf->GetIFIPAddr = getIFIPAddr; pIf->netns_save = netns_save; pIf->netns_restore = netns_restore; pIf->netns_switch = netns_switch; pIf->netns_socket = netns_socket; finalize_it: ENDobjQueryInterface(net) /* exit our class * rgerhards, 2008-03-10 */ BEGINObjClassExit(net, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(net); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); ENDObjClassExit(net) /* Initialize the net class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(net, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); /* set our own handlers */ ENDObjClassInit(net) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; netClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(netClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/errmsg.h0000644000000000000000000000013215071746523015676 xustar0030 mtime=1760021843.862421364 30 atime=1764930980.025678306 30 ctime=1764935923.193576734 rsyslog-8.2512.0/runtime/errmsg.h0000664000175000017500000001077415071746523015353 0ustar00rgerrger/* The errmsg object. It is used to emit error message inside rsyslog. * * Copyright 2008-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_ERRMSG_H #define INCLUDED_ERRMSG_H #include "obj-types.h" #define NO_ERRCODE -1 /* prototypes */ /** * @brief Close and reset internal resources of the errmsg subsystem. * * Closes the oversize-message log fd if open. Intended for orderly shutdown. * @note This function is not thread-safe as it accesses a global flag without locks. */ void errmsgExit(void); /** * @brief Reopen oversize-message resources on configuration reload (HUP). * * Intended to be called from rsyslog's SIGHUP handler. This closes the * oversize-message log file descriptor so the next write will reopen it * using the current configuration. This follows the traditional syslogd * pattern of reloading or reopening resources on HUP. * * Thread-safe. */ void errmsgDoHUP(void); /** * @brief Reset the "had error messages" flag. * * Must be called before processing config files to start with a clean state. * @note This function is not thread-safe as it accesses a global flag without locks. */ void resetErrMsgsFlag(void); /** * @brief Query whether a LOG_ERR message has been logged since the last reset. * * @return nonzero if a LOG_ERR was emitted since resetErrMsgsFlag(), else 0. * * @note This function is not thread-safe as it accesses a global flag without locks. */ int hadErrMsgs(void); /** * @brief Log an error message with errno and error code context. * * Formats and writes an error message to the rsyslog internal log. * Use this for reporting fatal or unexpected conditions. * * @param iErrno The system errno value (0 if not applicable). * @param iErrCode Internal rsyslog error code. * @param fmt printf-style format string. * @param ... Arguments matching the format string. * * @note Pass the errno value obtained at the point of failure. * Do not pass 0 and later resolve errno via strerror() or * similar functions — this leads to incorrect messages. */ void __attribute__((format(printf, 3, 4))) LogError(const int iErrno, const int iErrCode, const char *fmt, ...); /** * @brief Log a message with severity, errno, and error code context. * * More general form of LogError() that permits explicit severity. * * @param iErrno The system errno value (0 if not applicable). * @param iErrCode Internal rsyslog error code. * @param severity Syslog severity level (LOG_ERR, LOG_WARNING, etc.). * @param fmt printf-style format string. * @param ... Arguments matching the format string. * * @note Always pass the errno value captured immediately after the * failing call. Do not pass 0 and later call strerror() or * equivalent — this is a common bug. */ void __attribute__((format(printf, 4, 5))) LogMsg( const int iErrno, const int iErrCode, const int severity, const char *fmt, ...); /** * @brief Append a JSON record about an oversize message to the oversize-message log. * * Behavior: * - No-op if the oversize message error file is not configured. * - Lazily opens the file on first use and reuses the file descriptor. * - Access is serialized via oversizeMsgLogMut. * - Writes one JSON line per entry with fields: "rawmsg" (original raw bytes) and "input" (input name). * - On open/write errors, emits LogError(...) but returns no error; no further recovery is attempted. * The reason is that there is nothing useful that could be done in that case. * * @param pMsg Pointer to the message object (must not be NULL). * @retval RS_RET_OK on success, or when no oversize log is configured. * @retval RS_RET_OUT_OF_MEMORY on memory allocation failure. * * @note Output is newline-terminated JSON (not NUL-terminated). */ rsRetVal ATTR_NONNULL() writeOversizeMessageLog(const smsg_t *const pMsg); #endif /* #ifndef INCLUDED_ERRMSG_H */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_ossl.c0000644000000000000000000000013215114522477016214 xustar0030 mtime=1764926783.041632005 30 atime=1764926784.239661412 30 ctime=1764935923.371579459 rsyslog-8.2512.0/runtime/nsd_ossl.c0000664000175000017500000016073515114522477015674 0ustar00rgerrger/* nsd_ossl.c * * An implementation of the nsd interface for OpenSSL. * * Copyright 2018-2025 Adiscon GmbH. * Author: Andre Lorbach * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "cfsysline.h" #include "obj.h" #include "stringbuf.h" #include "errmsg.h" #include "net.h" #include "netstrm.h" #include "netstrms.h" #include "datetime.h" #include "net_ossl.h" // Include OpenSSL Helpers #include "nsd_ptcp.h" #include "nsd_ossl.h" #include "unicode-helper.h" #include "rsconf.h" MODULE_TYPE_LIB MODULE_TYPE_KEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(datetime) DEFobjCurrIf(nsd_ptcp) DEFobjCurrIf(net_ossl) /* Some prototypes for helper functions used inside openssl driver */ static rsRetVal applyGnutlsPriorityString(nsd_ossl_t *const pNsd); /* retry an interrupted OSSL operation */ static rsRetVal doRetry(nsd_ossl_t *pNsd) { DEFiRet; nsd_ossl_t *pNsdOSSL = (nsd_ossl_t *)pNsd; dbgprintf("doRetry: requested retry of %d operation - executing\n", pNsd->rtryCall); /* We follow a common scheme here: first, we do the systen call and * then we check the result. So far, the result is checked after the * switch, because the result check is the same for all calls. Note that * this may change once we deal with the read and write calls (but * probably this becomes an issue only when we begin to work on TLS * for relp). -- rgerhards, 2008-04-30 */ switch (pNsd->rtryCall) { case osslRtry_handshake: dbgprintf("doRetry: start osslHandshakeCheck, nsd: %p\n", pNsd); /* Do the handshake again*/ CHKiRet(osslHandshakeCheck(pNsdOSSL)); pNsd->rtryCall = osslRtry_None; /* we are done */ break; case osslRtry_recv: case osslRtry_None: default: assert(0); /* this shall not happen! */ dbgprintf("doRetry: ERROR, pNsd->rtryCall invalid in nsdsel_ossl.c:%d\n", __LINE__); break; } finalize_it: if (iRet != RS_RET_OK && iRet != RS_RET_CLOSED && iRet != RS_RET_RETRY) pNsd->bAbortConn = 1; /* request abort */ RETiRet; } /*--------------------------------------OpenSSL helpers ------------------------------------------*/ void nsd_ossl_lastOpenSSLErrorMsg( nsd_ossl_t const *pThis, const int ret, SSL *ssl, int severity, const char *pszCallSource, const char *pszOsslApi) { uchar *fromHost = NULL; int errno_store = errno; if (pThis != NULL) { nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHost); } // Call helper in net_ossl net_ossl.osslLastOpenSSLErrorMsg(fromHost, ret, ssl, severity, pszCallSource, pszOsslApi); free(fromHost); errno = errno_store; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) long BIO_debug_callback_ex(BIO *bio, int cmd, const char __attribute__((unused)) * argp, size_t __attribute__((unused)) len, int argi, long __attribute__((unused)) argl, int ret, size_t __attribute__((unused)) * processed) #else long BIO_debug_callback( BIO *bio, int cmd, const char __attribute__((unused)) * argp, int argi, long __attribute__((unused)) argl, long ret) #endif { long ret2 = ret; // Helper value to avoid printf compile errors long<>int long r = 1; if (BIO_CB_RETURN & cmd) r = ret; dbgprintf("openssl debugmsg: BIO[%p]: ", (void *)bio); switch (cmd) { case BIO_CB_FREE: dbgprintf("Free - %s\n", RSYSLOG_BIO_method_name(bio)); break; /* Disabled due API changes for OpenSSL 1.1.0+ */ #if OPENSSL_VERSION_NUMBER < 0x10100000L case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) dbgprintf("read(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_read(bio)); else dbgprintf("read(%d,%lu) - %s\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) dbgprintf("write(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_written(bio)); else dbgprintf("write(%d,%lu) - %s\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; #else case BIO_CB_READ: dbgprintf("read %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_WRITE: dbgprintf("write %s\n", RSYSLOG_BIO_method_name(bio)); break; #endif case BIO_CB_PUTS: dbgprintf("puts() - %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_GETS: dbgprintf("gets(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_CTRL: dbgprintf("ctrl(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_RETURN | BIO_CB_READ: dbgprintf("read return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_WRITE: dbgprintf("write return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_GETS: dbgprintf("gets return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_PUTS: dbgprintf("puts return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_CTRL: dbgprintf("ctrl return %ld\n", ret2); break; default: dbgprintf("bio callback - unknown type (%d)\n", cmd); break; } return (r); } /* try to receive a record from the remote peer. This works with * our own abstraction and handles local buffering and EAGAIN. * See details on local buffering in Rcv(9 header-comment. * This function MUST only be called when the local buffer is * empty. Calling it otherwise will cause losss of current buffer * data. * rgerhards, 2008-06-24 */ rsRetVal osslRecordRecv(nsd_ossl_t *pThis, unsigned *const nextIODirection) { ssize_t lenRcvd; DEFiRet; int err; ISOBJ_TYPE_assert(pThis, nsd_ossl); DBGPRINTF("osslRecordRecv: start\n"); lenRcvd = SSL_read(pThis->pNetOssl->ssl, pThis->pszRcvBuf, NSD_OSSL_MAX_RCVBUF); if (lenRcvd > 0) { DBGPRINTF("osslRecordRecv: SSL_read received %zd bytes\n", lenRcvd); pThis->lenRcvBuf = lenRcvd; pThis->ptrRcvBuf = 0; /* Check for additional data in SSL buffer */ int iBytesLeft = SSL_pending(pThis->pNetOssl->ssl); if (iBytesLeft > 0) { DBGPRINTF("osslRecordRecv: %d Bytes pending after SSL_Read, expand buffer.\n", iBytesLeft); /* realloc buffer size and preserve char content */ char *const newbuf = realloc(pThis->pszRcvBuf, NSD_OSSL_MAX_RCVBUF + iBytesLeft); CHKmalloc(newbuf); pThis->pszRcvBuf = newbuf; /* 2nd read will read missing bytes from the current SSL Packet */ lenRcvd = SSL_read(pThis->pNetOssl->ssl, pThis->pszRcvBuf + NSD_OSSL_MAX_RCVBUF, iBytesLeft); if (lenRcvd > 0) { DBGPRINTF("osslRecordRecv: 2nd SSL_read received %zd bytes\n", (NSD_OSSL_MAX_RCVBUF + lenRcvd)); pThis->lenRcvBuf = NSD_OSSL_MAX_RCVBUF + lenRcvd; } else { goto sslerr; } } } else { sslerr: err = SSL_get_error(pThis->pNetOssl->ssl, lenRcvd); if (err == SSL_ERROR_ZERO_RETURN) { DBGPRINTF("osslRecordRecv: SSL_ERROR_ZERO_RETURN received, connection may closed already\n"); ABORT_FINALIZE(RS_RET_RETRY); } else if (err == SSL_ERROR_SYSCALL) { /* Output error and abort */ nsd_ossl_lastOpenSSLErrorMsg(pThis, lenRcvd, pThis->pNetOssl->ssl, LOG_INFO, "osslRecordRecv", "SSL_read 1"); iRet = RS_RET_TLS_ERR_SYSCALL; /* Check for underlaying socket errors **/ if (errno == ECONNRESET) { DBGPRINTF("osslRecordRecv: SSL_ERROR_SYSCALL Errno %d, connection reset by peer\n", errno); /* Connection was dropped from remote site */ iRet = RS_RET_CLOSED; } else { DBGPRINTF("osslRecordRecv: SSL_ERROR_SYSCALL Errno %d\n", errno); } ABORT_FINALIZE(iRet); } else if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { DBGPRINTF("osslRecordRecv: SSL_get_error #1 = %d, lenRcvd=%zd\n", err, lenRcvd); /* Output OpenSSL error*/ nsd_ossl_lastOpenSSLErrorMsg(pThis, lenRcvd, pThis->pNetOssl->ssl, LOG_ERR, "osslRecordRecv", "SSL_read 2"); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } else { DBGPRINTF("osslRecordRecv: SSL_get_error #2 = %d, lenRcvd=%zd\n", err, lenRcvd); pThis->rtryCall = osslRtry_recv; pThis->rtryOsslErr = err; /* Store SSL ErrorCode into*/ ABORT_FINALIZE(RS_RET_RETRY); } } finalize_it: if (pThis->rtryCall != osslRtry_None && pThis->rtryOsslErr == SSL_ERROR_WANT_WRITE) { *nextIODirection = NSDSEL_WR; } else { *nextIODirection = NSDSEL_RD; } dbgprintf("osslRecordRecv return. nsd %p, iRet %d, lenRcvd %zd, lenRcvBuf %d, ptrRcvBuf %d\n", pThis, iRet, lenRcvd, pThis->lenRcvBuf, pThis->ptrRcvBuf); RETiRet; } static rsRetVal osslInitSession(nsd_ossl_t *pThis, osslSslState_t osslType) /* , nsd_ossl_t *pServer) */ { DEFiRet; BIO *conn; char pristringBuf[4096]; nsd_ptcp_t *pPtcp = (nsd_ptcp_t *)pThis->pTcp; if (!(pThis->pNetOssl->ssl = SSL_new(pThis->pNetOssl->ctx))) { pThis->pNetOssl->ssl = NULL; nsd_ossl_lastOpenSSLErrorMsg(pThis, 0, pThis->pNetOssl->ssl, LOG_ERR, "osslInitSession", "SSL_new"); ABORT_FINALIZE(RS_RET_TLS_BASEINIT_FAIL); } // Set SSL_MODE_AUTO_RETRY to SSL obj SSL_set_mode(pThis->pNetOssl->ssl, SSL_MODE_AUTO_RETRY); if (pThis->pNetOssl->authMode != OSSL_AUTH_CERTANON) { dbgprintf("osslInitSession: enable certificate checking (Mode=%d, VerifyDepth=%d)\n", pThis->pNetOssl->authMode, pThis->DrvrVerifyDepth); /* Enable certificate valid checking */ net_ossl.osslSetSslVerifyCallback(pThis->pNetOssl->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); if (pThis->DrvrVerifyDepth != 0) { SSL_set_verify_depth(pThis->pNetOssl->ssl, pThis->DrvrVerifyDepth); } } else if (pThis->gnutlsPriorityString == NULL) { /* Allow ANON Ciphers only in ANON Mode and if no custom priority string is defined */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) /* NOTE: do never use: +eNULL, it DISABLES encryption! */ strncpy(pristringBuf, "ALL:+COMPLEMENTOFDEFAULT:+ADH:+ECDH:+aNULL@SECLEVEL=0", sizeof(pristringBuf)); #else strncpy(pristringBuf, "ALL:+COMPLEMENTOFDEFAULT:+ADH:+ECDH:+aNULL", sizeof(pristringBuf)); #endif dbgprintf("osslInitSession: setting anon ciphers: %s\n", pristringBuf); if (SSL_set_cipher_list(pThis->pNetOssl->ssl, pristringBuf) == 0) { dbgprintf("osslInitSession: Error setting ciphers '%s'\n", pristringBuf); ABORT_FINALIZE(RS_RET_SYS_ERR); } } /* Create BIO from ptcp socket! */ conn = BIO_new_socket(pPtcp->sock, BIO_CLOSE /*BIO_NOCLOSE*/); dbgprintf("osslInitSession: Init conn BIO[%p] done\n", (void *)conn); /* Set debug Callback for conn BIO as well! */ net_ossl.osslSetBioCallback(conn); /* TODO: still needed? Set to NON blocking ! */ BIO_set_nbio(conn, 1); SSL_set_bio(pThis->pNetOssl->ssl, conn, conn); if (osslType == osslServer) { /* Server Socket */ SSL_set_accept_state(pThis->pNetOssl->ssl); /* sets ssl to work in server mode. */ pThis->pNetOssl->sslState = osslServer; /*set Server state */ } else { /* Client Socket */ SSL_set_connect_state(pThis->pNetOssl->ssl); /*sets ssl to work in client mode.*/ pThis->pNetOssl->sslState = osslClient; /*set Client state */ } pThis->bHaveSess = 1; /* we are done */ FINALIZE; finalize_it: RETiRet; } /* check if it is OK to talk to the remote peer * rgerhards, 2008-05-21 */ rsRetVal osslChkPeerAuth(nsd_ossl_t *pThis) { DEFiRet; X509 *certpeer = NULL; ISOBJ_TYPE_assert(pThis, nsd_ossl); uchar *fromHostIP = NULL; nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHostIP); /* call the actual function based on current auth mode */ switch (pThis->pNetOssl->authMode) { case OSSL_AUTH_CERTNAME: /* if we check the name, we must ensure the cert is valid */ certpeer = net_ossl.osslGetpeercert(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP); dbgprintf("osslChkPeerAuth: Check peer certname[%p]=%s\n", (void *)pThis->pNetOssl->ssl, (certpeer != NULL ? "VALID" : "NULL")); CHKiRet(net_ossl.osslChkpeercertvalidity(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP)); CHKiRet(net_ossl.osslChkpeername(pThis->pNetOssl, certpeer, fromHostIP)); break; case OSSL_AUTH_CERTFINGERPRINT: certpeer = net_ossl.osslGetpeercert(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP); dbgprintf("osslChkPeerAuth: Check peer fingerprint[%p]=%s\n", (void *)pThis->pNetOssl->ssl, (certpeer != NULL ? "VALID" : "NULL")); CHKiRet(net_ossl.osslChkpeercertvalidity(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP)); CHKiRet(net_ossl.osslPeerfingerprint(pThis->pNetOssl, certpeer, fromHostIP)); break; case OSSL_AUTH_CERTVALID: certpeer = net_ossl.osslGetpeercert(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP); dbgprintf("osslChkPeerAuth: Check peer valid[%p]=%s\n", (void *)pThis->pNetOssl->ssl, (certpeer != NULL ? "VALID" : "NULL")); CHKiRet(net_ossl.osslChkpeercertvalidity(pThis->pNetOssl, pThis->pNetOssl->ssl, fromHostIP)); break; case OSSL_AUTH_CERTANON: default: break; } finalize_it: if (certpeer != NULL) { X509_free(certpeer); } if (fromHostIP != NULL) { free(fromHostIP); } RETiRet; } /* end a OpenSSL session * The function checks if we have a session and ends it only if so. So it can * always be called, even if there currently is no session. */ static rsRetVal osslEndSess(nsd_ossl_t *pThis) { DEFiRet; uchar *fromHostIP = NULL; int ret; int err; /* try closing SSL Connection */ if (pThis->bHaveSess) { DBGPRINTF("osslEndSess: closing SSL Session ...\n"); ret = SSL_shutdown(pThis->pNetOssl->ssl); nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHostIP); if (ret <= 0) { err = SSL_get_error(pThis->pNetOssl->ssl, ret); DBGPRINTF("osslEndSess: shutdown failed with err = %d\n", err); /* ignore those SSL Errors on shutdown */ if (err != SSL_ERROR_SYSCALL && err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { /* Output Warning only */ nsd_ossl_lastOpenSSLErrorMsg(pThis, ret, pThis->pNetOssl->ssl, LOG_WARNING, "osslEndSess", "SSL_shutdown"); } /* Shutdown not finished, call SSL_read to do a bidirectional shutdown, see doc for more: * https://www.openssl.org/docs/man1.1.1/man3/SSL_shutdown.html */ char rcvBuf[NSD_OSSL_MAX_RCVBUF]; int iBytesRet = SSL_read(pThis->pNetOssl->ssl, rcvBuf, NSD_OSSL_MAX_RCVBUF); DBGPRINTF("osslEndSess: Forcing ssl shutdown SSL_read (%d) to do a bidirectional shutdown\n", iBytesRet); if (ret < 0) { /* Unsuccessful shutdown, log as INFO */ LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "nsd_ossl: " "TLS session terminated successfully to remote syslog server '%s' with SSL Error '%d':" " End Session", fromHostIP, ret); } dbgprintf( "osslEndSess: TLS session terminated successfully to remote syslog server '%s'" " End Session", fromHostIP); } else { dbgprintf( "osslEndSess: TLS session terminated successfully with remote syslog server '%s':" " End Session", fromHostIP); } /* Session closed */ pThis->bHaveSess = 0; } if (fromHostIP != NULL) { free(fromHostIP); } RETiRet; } /* ---------------------------- end OpenSSL specifics ---------------------------- */ /* Standard-Constructor */ BEGINobjConstruct(nsd_ossl) /* be sure to specify the object type also in END macro! */ DBGPRINTF("nsd_ossl_construct: [%p]\n", pThis); /* construct nsd_ptcp helper */ CHKiRet(nsd_ptcp.Construct(&pThis->pTcp)); /* construct net_ossl helper */ CHKiRet(net_ossl.Construct(&pThis->pNetOssl)); finalize_it: ENDobjConstruct(nsd_ossl) /* destructor for the nsd_ossl object */ PROTOTYPEobjDestruct(nsd_ossl); BEGINobjDestruct(nsd_ossl) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(nsd_ossl); DBGPRINTF("nsd_ossl_destruct: [%p] Mode %d\n", pThis, pThis->iMode); if (pThis->iMode == 1) { osslEndSess(pThis); } /* TODO MOVE Free SSL obj also if we do not have a session - or are NOT in TLS mode! */ if (pThis->pNetOssl->ssl != NULL) { DBGPRINTF("nsd_ossl_destruct: [%p] FREE pThis->pNetOssl->ssl \n", pThis); SSL_free(pThis->pNetOssl->ssl); pThis->pNetOssl->ssl = NULL; } /**/ if (pThis->pTcp != NULL) { nsd_ptcp.Destruct(&pThis->pTcp); } if (pThis->pNetOssl != NULL) { net_ossl.Destruct(&pThis->pNetOssl); } free(pThis->pszConnectHost); free(pThis->pszRcvBuf); ENDobjDestruct(nsd_ossl) /* Set the driver mode. For us, this has the following meaning: * 0 - work in plain tcp mode, without tls (e.g. before a STARTTLS) * 1 - work in TLS mode * rgerhards, 2008-04-28 */ static rsRetVal SetMode(nsd_t *pNsd, const int mode) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (mode != 0 && mode != 1) { LogError(0, RS_RET_INVALID_DRVR_MODE, "error: driver mode %d not supported by" " ossl netstream driver", mode); } pThis->iMode = mode; RETiRet; } /* Set the authentication mode. For us, the following is supported: * anon - no certificate checks whatsoever (discouraged, but supported) * x509/certvalid - (just) check certificate validity * x509/fingerprint - certificate fingerprint * x509/name - cerfificate name check * mode == NULL is valid and defaults to x509/name * rgerhards, 2008-05-16 */ static rsRetVal SetAuthMode(nsd_t *const pNsd, uchar *const mode) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (mode == NULL || !strcasecmp((char *)mode, "x509/name")) { pThis->pNetOssl->authMode = OSSL_AUTH_CERTNAME; } else if (!strcasecmp((char *)mode, "x509/fingerprint")) { pThis->pNetOssl->authMode = OSSL_AUTH_CERTFINGERPRINT; } else if (!strcasecmp((char *)mode, "x509/certvalid")) { pThis->pNetOssl->authMode = OSSL_AUTH_CERTVALID; } else if (!strcasecmp((char *)mode, "anon")) { pThis->pNetOssl->authMode = OSSL_AUTH_CERTANON; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: authentication mode '%s' not supported by " "ossl netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetAuthMode: Set Mode %s/%d\n", mode, pThis->pNetOssl->authMode); finalize_it: RETiRet; } /* Set the PermitExpiredCerts mode. For us, the following is supported: * on - fail if certificate is expired * off - ignore expired certificates * warn - warn if certificate is expired * alorbach, 2018-12-20 */ static rsRetVal SetPermitExpiredCerts(nsd_t *pNsd, uchar *mode) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); /* default is set to off! */ if (mode == NULL || !strcasecmp((char *)mode, "off")) { pThis->permitExpiredCerts = OSSL_EXPIRED_DENY; } else if (!strcasecmp((char *)mode, "warn")) { pThis->permitExpiredCerts = OSSL_EXPIRED_WARN; } else if (!strcasecmp((char *)mode, "on")) { pThis->permitExpiredCerts = OSSL_EXPIRED_PERMIT; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: permitexpiredcerts mode '%s' not supported by " "ossl netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetPermitExpiredCerts: Set Mode %s/%d\n", mode, pThis->permitExpiredCerts); /* TODO: clear stored IDs! */ finalize_it: RETiRet; } /* Set permitted peers. It is depending on the auth mode if this are * fingerprints or names. -- rgerhards, 2008-05-19 */ static rsRetVal SetPermPeers(nsd_t *pNsd, permittedPeers_t *pPermPeers) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (pPermPeers == NULL) FINALIZE; if (pThis->pNetOssl->authMode != OSSL_AUTH_CERTFINGERPRINT && pThis->pNetOssl->authMode != OSSL_AUTH_CERTNAME) { LogError(0, RS_RET_VALUE_NOT_IN_THIS_MODE, "authentication not supported by " "ossl netstream driver in the configured authentication mode - ignored"); ABORT_FINALIZE(RS_RET_VALUE_NOT_IN_THIS_MODE); } pThis->pNetOssl->pPermPeers = pPermPeers; finalize_it: RETiRet; } /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_ossl) who utilize ourselfs * for some of their functionality. -- rgerhards, 2008-04-18 */ static rsRetVal SetSock(nsd_t *pNsd, int sock) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); assert(sock >= 0); DBGPRINTF("SetSock for [%p]: Setting sock %d\n", pNsd, sock); nsd_ptcp.SetSock(pThis->pTcp, sock); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveIntvl(nsd_t *pNsd, int keepAliveIntvl) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); assert(keepAliveIntvl >= 0); dbgprintf("SetKeepAliveIntvl: keepAliveIntvl=%d\n", keepAliveIntvl); nsd_ptcp.SetKeepAliveIntvl(pThis->pTcp, keepAliveIntvl); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveProbes(nsd_t *pNsd, int keepAliveProbes) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); assert(keepAliveProbes >= 0); dbgprintf("SetKeepAliveProbes: keepAliveProbes=%d\n", keepAliveProbes); nsd_ptcp.SetKeepAliveProbes(pThis->pTcp, keepAliveProbes); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveTime(nsd_t *pNsd, int keepAliveTime) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); assert(keepAliveTime >= 0); dbgprintf("SetKeepAliveTime: keepAliveTime=%d\n", keepAliveTime); nsd_ptcp.SetKeepAliveTime(pThis->pTcp, keepAliveTime); RETiRet; } /* abort a connection. This is meant to be called immediately * before the Destruct call. -- rgerhards, 2008-03-24 */ static rsRetVal Abort(nsd_t *pNsd) { nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (pThis->iMode == 0) { nsd_ptcp.Abort(pThis->pTcp); } RETiRet; } /* Callback after netstrm obj init in nsd_ptcp - permits us to add some data */ static rsRetVal LstnInitDrvr(netstrm_t *const pThis) { DEFiRet; nsd_ossl_t *pNsdOssl = (nsd_ossl_t *)pThis->pDrvrData; /* Create main CTX Object. Use SSLv23_method for < Openssl 1.1.0 and TLS_method for all newer versions! */ #if OPENSSL_VERSION_NUMBER < 0x10100000L CHKiRet(net_ossl.osslCtxInit(pNsdOssl->pNetOssl, SSLv23_method())); #else CHKiRet(net_ossl.osslCtxInit(pNsdOssl->pNetOssl, TLS_method())); #endif // Apply PriorityString after Ctx Creation applyGnutlsPriorityString(pNsdOssl); finalize_it: RETiRet; } /* initialize the tcp socket for a listner * Here, we use the ptcp driver - because there is nothing special * at this point with OpenSSL. Things become special once we accept * a session, but not during listener setup. */ static rsRetVal LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal (*fAddLstn)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params) { DEFiRet; dbgprintf("LstnInit for openssl: entering LstnInit (%p) for %s:%s SessMax=%d\n", fAddLstn, cnf_params->pszAddr, cnf_params->pszPort, iSessMax); pNS->fLstnInitDrvr = LstnInitDrvr; /* Init TCP Listener using base ptcp class */ iRet = nsd_ptcp.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params); RETiRet; } /* This function checks if the connection is still alive - well, kind of... * This is a dummy here. For details, check function common in ptcp driver. * rgerhards, 2008-06-09 */ static rsRetVal CheckConnection(nsd_t __attribute__((unused)) * pNsd) { nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); dbgprintf("CheckConnection for %p\n", pNsd); return nsd_ptcp.CheckConnection(pThis->pTcp); } /* Provide access to the underlying OS socket. */ static rsRetVal GetSock(nsd_t *pNsd, int *pSock) { nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; return nsd_ptcp.GetSock(pThis->pTcp, pSock); } /* get the remote hostname. The returned hostname must be freed by the caller. * rgerhards, 2008-04-25 */ static rsRetVal GetRemoteHName(nsd_t *pNsd, uchar **ppszHName) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); iRet = nsd_ptcp.GetRemoteHName(pThis->pTcp, ppszHName); dbgprintf("GetRemoteHName for %p = %s\n", pNsd, *ppszHName); RETiRet; } /* Provide access to the sockaddr_storage of the remote peer. This * is needed by the legacy ACL system. --- gerhards, 2008-12-01 */ static rsRetVal GetRemAddr(nsd_t *pNsd, struct sockaddr_storage **ppAddr) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); iRet = nsd_ptcp.GetRemAddr(pThis->pTcp, ppAddr); dbgprintf("GetRemAddr for %p\n", pNsd); RETiRet; } /* get the remote host's IP address. Caller must Destruct the object. */ static rsRetVal GetRemoteIP(nsd_t *pNsd, prop_t **ip) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); iRet = nsd_ptcp.GetRemoteIP(pThis->pTcp, ip); dbgprintf("GetRemoteIP for %p\n", pNsd); RETiRet; } /* Perform all necessary checks after Handshake */ rsRetVal osslPostHandshakeCheck(nsd_ossl_t *pNsd) { DEFiRet; uchar *fromHostIP = NULL; char szDbg[255]; const SSL_CIPHER *sslCipher; nsd_ptcp.GetRemoteHName((nsd_t *)pNsd->pTcp, &fromHostIP); /* Some extra output for debugging openssl */ if (SSL_get_shared_ciphers(pNsd->pNetOssl->ssl, szDbg, sizeof szDbg) != NULL) dbgprintf("osslPostHandshakeCheck: Debug Shared ciphers = %s\n", szDbg); #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (SSL_get_shared_curve(pNsd->pNetOssl->ssl, -1) == 0) { // This is not a failure LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "nsd_ossl: " "Information, no shared curve between syslog client '%s' and server", fromHostIP); } #endif dbgprintf("osslPostHandshakeCheck: Debug Protocol Version: %s\n", SSL_get_version(pNsd->pNetOssl->ssl)); sslCipher = (const SSL_CIPHER *)SSL_get_current_cipher(pNsd->pNetOssl->ssl); if (sslCipher != NULL) { if (SSL_CIPHER_get_version(sslCipher) == NULL) { LogError(0, RS_RET_NO_ERRCODE, "nsd_ossl:" "TLS version mismatch between syslog client '%s' and server.", fromHostIP); } dbgprintf("osslPostHandshakeCheck: Debug Cipher Version: %s Name: %s\n", SSL_CIPHER_get_version(sslCipher), SSL_CIPHER_get_name(sslCipher)); } else { LogError(0, RS_RET_NO_ERRCODE, "nsd_ossl:No shared ciphers between syslog client '%s' and server.", fromHostIP); } FINALIZE; finalize_it: if (fromHostIP != NULL) { free(fromHostIP); } RETiRet; } /* Perform all necessary actions for Handshake */ rsRetVal osslHandshakeCheck(nsd_ossl_t *pNsd) { DEFiRet; uchar *fromHostIP = NULL; int remotePort = -1; uchar remotePortStr[8]; int res, resErr; dbgprintf("osslHandshakeCheck: Starting TLS Handshake for ssl[%p]\n", (void *)pNsd->pNetOssl->ssl); if (pNsd->pNetOssl->sslState == osslServer) { /* Handle Server SSL Object */ if ((res = SSL_accept(pNsd->pNetOssl->ssl)) <= 0) { /* Obtain SSL Error code */ nsd_ptcp.GetRemoteHName(pNsd->pTcp, &fromHostIP); nsd_ptcp.GetRemotePort(pNsd->pTcp, &remotePort); resErr = SSL_get_error(pNsd->pNetOssl->ssl, res); if (resErr == SSL_ERROR_WANT_READ || resErr == SSL_ERROR_WANT_WRITE) { pNsd->rtryCall = osslRtry_handshake; pNsd->rtryOsslErr = resErr; /* Store SSL ErrorCode into*/ dbgprintf( "osslHandshakeCheck: OpenSSL Server handshake does not complete " "immediately - setting to retry (this is OK and normal)\n"); FINALIZE; } else { nsd_ptcp.FmtRemotePortStr(remotePort, remotePortStr, sizeof(remotePortStr)); if (resErr == SSL_ERROR_SYSCALL) { dbgprintf( "osslHandshakeCheck: OpenSSL Server handshake failed with " "SSL_ERROR_SYSCALL - Aborting handshake.\n"); nsd_ossl_lastOpenSSLErrorMsg(pNsd, res, pNsd->pNetOssl->ssl, LOG_WARNING, "osslHandshakeCheck Server", "SSL_accept"); LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "nsd_ossl:TLS session terminated with remote client '%s:%s': " "Handshake failed with SSL_ERROR_SYSCALL", fromHostIP, remotePortStr); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } else { nsd_ossl_lastOpenSSLErrorMsg(pNsd, res, pNsd->pNetOssl->ssl, LOG_ERR, "osslHandshakeCheck Server", "SSL_accept"); LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "nsd_ossl:TLS session terminated with remote client '%s:%s': " "Handshake failed with error code: %d", fromHostIP, remotePortStr, resErr); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } } } } else { /* Handle Client SSL Object */ if ((res = SSL_do_handshake(pNsd->pNetOssl->ssl)) <= 0) { /* Obtain SSL Error code */ nsd_ptcp.GetRemoteHName(pNsd->pTcp, &fromHostIP); resErr = SSL_get_error(pNsd->pNetOssl->ssl, res); if (resErr == SSL_ERROR_WANT_READ || resErr == SSL_ERROR_WANT_WRITE) { pNsd->rtryCall = osslRtry_handshake; pNsd->rtryOsslErr = resErr; /* Store SSL ErrorCode into*/ dbgprintf( "osslHandshakeCheck: OpenSSL Client handshake does not complete " "immediately - setting to retry (this is OK and normal)\n"); FINALIZE; } else if (resErr == SSL_ERROR_SYSCALL) { dbgprintf( "osslHandshakeCheck: OpenSSL Client handshake failed with SSL_ERROR_SYSCALL " "- Aborting handshake.\n"); nsd_ossl_lastOpenSSLErrorMsg(pNsd, res, pNsd->pNetOssl->ssl, LOG_WARNING, "osslHandshakeCheck Client", "SSL_do_handshake"); ABORT_FINALIZE(RS_RET_NO_ERRCODE /*RS_RET_RETRY*/); } else { dbgprintf( "osslHandshakeCheck: OpenSSL Client handshake failed with %d " "- Aborting handshake.\n", resErr); nsd_ossl_lastOpenSSLErrorMsg(pNsd, res, pNsd->pNetOssl->ssl, LOG_ERR, "osslHandshakeCheck Client", "SSL_do_handshake"); nsd_ptcp.GetRemotePort(pNsd->pTcp, &remotePort); nsd_ptcp.FmtRemotePortStr(remotePort, remotePortStr, sizeof(remotePortStr)); LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "nsd_ossl:TLS session terminated with remote syslog server '%s:%s':" "Handshake failed with error code: %d", fromHostIP, remotePortStr, resErr); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } } } /* Do post handshake stuff */ CHKiRet(osslPostHandshakeCheck(pNsd)); /* Now check authorization */ CHKiRet(osslChkPeerAuth(pNsd)); finalize_it: if (fromHostIP != NULL) { free(fromHostIP); } if (iRet == RS_RET_OK) { /* If no error occurred, set socket to SSL mode */ pNsd->iMode = 1; } RETiRet; } /* accept an incoming connection request - here, we do the usual accept * handling. TLS specific handling is done thereafter (and if we run in TLS * mode at this time). * rgerhards, 2008-04-25 */ static rsRetVal AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew, char *const connInfo) { DEFiRet; nsd_ossl_t *pNew = NULL; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); CHKiRet(nsd_osslConstruct(&pNew)); CHKiRet(nsd_ptcp.Destruct(&pNew->pTcp)); dbgprintf("AcceptConnReq for [%p]: Accepting connection ... \n", (void *)pThis); CHKiRet(nsd_ptcp.AcceptConnReq(pThis->pTcp, &pNew->pTcp, connInfo)); if (pThis->iMode == 0) { /*we are in non-TLS mode, so we are done */ DBGPRINTF("AcceptConnReq: NOT in TLS mode!\n"); *ppNew = (nsd_t *)pNew; FINALIZE; } /* If we reach this point, we are in TLS mode */ pNew->pNetOssl->authMode = pThis->pNetOssl->authMode; pNew->permitExpiredCerts = pThis->permitExpiredCerts; pNew->pNetOssl->pPermPeers = pThis->pNetOssl->pPermPeers; pNew->pNetOssl->bSANpriority = pThis->pNetOssl->bSANpriority; pNew->DrvrVerifyDepth = pThis->DrvrVerifyDepth; pNew->gnutlsPriorityString = pThis->gnutlsPriorityString; pNew->pNetOssl->ctx = pThis->pNetOssl->ctx; pNew->pNetOssl->ctx_is_copy = 1; // do not free on pNew Destruction CHKiRet(osslInitSession(pNew, osslServer)); /* Store nsd_ossl_t* reference in SSL obj */ SSL_set_ex_data(pNew->pNetOssl->ssl, 0, pThis->pTcp); SSL_set_ex_data(pNew->pNetOssl->ssl, 1, &pThis->permitExpiredCerts); /* We now do the handshake */ CHKiRet(osslHandshakeCheck(pNew)); *ppNew = (nsd_t *)pNew; finalize_it: /* Accept appears to be done here */ if (pNew != NULL) { DBGPRINTF("AcceptConnReq: END iRet = %d, pNew=[%p], pNsd->rtryCall=%d\n", iRet, pNew, pNew->rtryCall); } if (iRet != RS_RET_OK) { if (pNew != NULL) { nsd_osslDestruct(&pNew); } } RETiRet; } /* receive data from a tcp socket * The lenBuf parameter must contain the max buffer size on entry and contains * the number of octets read on exit. This function * never blocks, not even when called on a blocking socket. That is important * for client sockets, which are set to block during send, but should not * block when trying to read data. -- rgerhards, 2008-03-17 * The function now follows the usual iRet calling sequence. * With GnuTLS, we may need to restart a recv() system call. If so, we need * to supply the SAME buffer on the retry. We can not assure this, as the * caller is free to call us with any buffer location (and in current * implementation, it is on the stack and extremely likely to change). To * work-around this problem, we allocate a buffer ourselfs and always receive * into that buffer. We pass data on to the caller only after we have received it. * To save some space, we allocate that internal buffer only when it is actually * needed, which means when we reach this function for the first time. To keep * the algorithm simple, we always supply data only from the internal buffer, * even if it is a single byte. As we have a stream, the caller must be prepared * to accept messages in any order, so we do not need to take care about this. * Please note that the logic also forces us to do some "faking" in select(), as * we must provide a fake "is ready for readign" status if we have data inside our * buffer. -- rgerhards, 2008-06-23 */ static rsRetVal Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf, int *const oserr, unsigned *const nextIODirection) { DEFiRet; ssize_t iBytesCopy; /* how many bytes are to be copied to the client buffer? */ nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); DBGPRINTF("Rcv for %p\n", pNsd); if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf, oserr, nextIODirection)); FINALIZE; } /* --- in TLS mode now --- */ if (pThis->rtryCall == osslRtry_handshake) { /* note: we are in receive, so we acually will retry receive in any case */ CHKiRet(doRetry(pThis)); ABORT_FINALIZE(RS_RET_RETRY); } /* Buffer logic applies only if we are in TLS mode. Here we * assume that we will switch from plain to TLS, but never back. This * assumption may be unsafe, but it is the model for the time being and I * do not see any valid reason why we should switch back to plain TCP after * we were in TLS mode. However, in that case we may lose something that * is already in the receive buffer ... risk accepted. -- rgerhards, 2008-06-23 */ if (pThis->pszRcvBuf == NULL) { /* we have no buffer, so we need to malloc one */ CHKmalloc(pThis->pszRcvBuf = malloc(NSD_OSSL_MAX_RCVBUF)); pThis->lenRcvBuf = -1; } /* now check if we have something in our buffer. If so, we satisfy * the request from buffer contents. */ if (pThis->lenRcvBuf == -1) { /* no data present, must read */ CHKiRet(osslRecordRecv(pThis, nextIODirection)); } if (pThis->lenRcvBuf == 0) { /* EOS */ *oserr = errno; ABORT_FINALIZE(RS_RET_CLOSED); } /* if we reach this point, data is present in the buffer and must be copied */ iBytesCopy = pThis->lenRcvBuf - pThis->ptrRcvBuf; if (iBytesCopy > *pLenBuf) { iBytesCopy = *pLenBuf; } else { pThis->lenRcvBuf = -1; /* buffer will be emptied below */ } memcpy(pBuf, pThis->pszRcvBuf + pThis->ptrRcvBuf, iBytesCopy); pThis->ptrRcvBuf += iBytesCopy; *pLenBuf = iBytesCopy; finalize_it: if (iRet != RS_RET_OK) { if (iRet == RS_RET_CLOSED) { if (pThis->pNetOssl->ssl != NULL) { /* Set SSL Shutdown */ SSL_shutdown(pThis->pNetOssl->ssl); dbgprintf("osslRcv SSL_shutdown done\n"); } } else if (iRet != RS_RET_RETRY) { /* We need to free the receive buffer in error error case unless a retry is wanted. , if we * allocated one. -- rgerhards, 2008-12-03 -- moved here by alorbach, 2015-12-01 */ *pLenBuf = 0; free(pThis->pszRcvBuf); pThis->pszRcvBuf = NULL; } else { /* RS_RET_RETRY | Check for SSL Shutdown */ if (SSL_get_shutdown(pThis->pNetOssl->ssl) == SSL_RECEIVED_SHUTDOWN) { dbgprintf("osslRcv received SSL_RECEIVED_SHUTDOWN!\n"); iRet = RS_RET_CLOSED; /* Send Shutdown message back */ SSL_shutdown(pThis->pNetOssl->ssl); } } } dbgprintf("osslRcv return. nsd %p, iRet %d, lenRcvBuf %d, ptrRcvBuf %d\n", pThis, iRet, pThis->lenRcvBuf, pThis->ptrRcvBuf); RETiRet; } /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has * been written. * rgerhards, 2008-03-19 */ static rsRetVal Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) { DEFiRet; int iSent; int err; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; DBGPRINTF("Send for %p\n", pNsd); ISOBJ_TYPE_assert(pThis, nsd_ossl); if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Send(pThis->pTcp, pBuf, pLenBuf)); FINALIZE; } while (1) { iSent = SSL_write(pThis->pNetOssl->ssl, pBuf, *pLenBuf); if (iSent > 0) { *pLenBuf = iSent; break; } else { err = SSL_get_error(pThis->pNetOssl->ssl, iSent); if (err == SSL_ERROR_ZERO_RETURN) { DBGPRINTF("Send: SSL_ERROR_ZERO_RETURN received, connection closed by peer\n"); ABORT_FINALIZE(RS_RET_CLOSED); } else if (err == SSL_ERROR_SYSCALL) { /* Output error and abort */ nsd_ossl_lastOpenSSLErrorMsg(pThis, iSent, pThis->pNetOssl->ssl, LOG_INFO, "Send", "SSL_write"); iRet = RS_RET_TLS_ERR_SYSCALL; /* Check for underlaying socket errors **/ if (errno == ECONNRESET) { dbgprintf("Send: SSL_ERROR_SYSCALL Connection was reset by remote\n"); /* Connection was dropped from remote site */ iRet = RS_RET_CLOSED; } else { DBGPRINTF("Send: SSL_ERROR_SYSCALL Errno %d\n", errno); } ABORT_FINALIZE(iRet); } else if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { /* Output error and abort */ nsd_ossl_lastOpenSSLErrorMsg(pThis, iSent, pThis->pNetOssl->ssl, LOG_ERR, "Send", "SSL_write"); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } else { /* * OpenSSL needs us to READ or WRITE to make progress. * In TLS 1.3, servers may send post-handshake messages (e.g. KeyUpdate) * which require the client to read before it can continue writing. * Use the buffered receive helper to preserve any application data. */ if (err == SSL_ERROR_WANT_READ) { unsigned nextIODirection ATTR_UNUSED; rsRetVal rcvRet = osslRecordRecv(pThis, &nextIODirection); if (rcvRet == RS_RET_CLOSED) { ABORT_FINALIZE(RS_RET_CLOSED); } else if (rcvRet != RS_RET_OK && rcvRet != RS_RET_RETRY) { ABORT_FINALIZE(rcvRet); } if (SSL_get_shutdown(pThis->pNetOssl->ssl) == SSL_RECEIVED_SHUTDOWN) { dbgprintf("Send: detected SSL_RECEIVED_SHUTDOWN while handling WANT_READ\n"); ABORT_FINALIZE(RS_RET_CLOSED); } /* Continue loop to retry SSL_write */ } else { /* Check for SSL Shutdown */ if (SSL_get_shutdown(pThis->pNetOssl->ssl) == SSL_RECEIVED_SHUTDOWN) { dbgprintf("osslRcv received SSL_RECEIVED_SHUTDOWN!\n"); ABORT_FINALIZE(RS_RET_CLOSED); } } } } } finalize_it: RETiRet; } /* Enable KEEPALIVE handling on the socket. * rgerhards, 2009-06-02 */ static rsRetVal EnableKeepAlive(nsd_t *pNsd) { nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); return nsd_ptcp.EnableKeepAlive(pThis->pTcp); } /* open a connection to a remote host (server). With OpenSSL, we always * open a plain tcp socket and then, if in TLS mode, do a handshake on it. */ static rsRetVal Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) { DEFiRet; DBGPRINTF("openssl: entering Connect family=%d, device=%s\n", family, device); nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; uchar *fromHostIP = NULL; ISOBJ_TYPE_assert(pThis, nsd_ossl); assert(port != NULL); assert(host != NULL); /* Create main CTX Object. Use SSLv23_method for < Openssl 1.1.0 and TLS_method for all newer versions! */ #if OPENSSL_VERSION_NUMBER < 0x10100000L CHKiRet(net_ossl.osslCtxInit(pThis->pNetOssl, SSLv23_method())); #else CHKiRet(net_ossl.osslCtxInit(pThis->pNetOssl, TLS_method())); #endif // Apply PriorityString after Ctx Creation applyGnutlsPriorityString(pThis); // Perform TCP Connect CHKiRet(nsd_ptcp.Connect(pThis->pTcp, family, port, host, device)); if (pThis->iMode == 0) { /*we are in non-TLS mode, so we are done */ DBGPRINTF("Connect: NOT in TLS mode!\n"); FINALIZE; } nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHostIP); LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "nsd_ossl: " "TLS Connection initiated with remote syslog server '%s'.", fromHostIP); /*if we reach this point we are in tls mode */ DBGPRINTF("Connect: TLS Mode\n"); /* Do SSL Session init */ CHKiRet(osslInitSession(pThis, osslClient)); /* Store nsd_ossl_t* reference in SSL obj */ SSL_set_ex_data(pThis->pNetOssl->ssl, 0, pThis->pTcp); SSL_set_ex_data(pThis->pNetOssl->ssl, 1, &pThis->permitExpiredCerts); /* We now do the handshake */ iRet = osslHandshakeCheck(pThis); finalize_it: if (fromHostIP != NULL) { free(fromHostIP); } /* Connect appears to be done here */ dbgprintf("Connect: END iRet = %d, pThis=[%p], pNsd->rtryCall=%d\n", iRet, pThis, pThis->rtryCall); if (iRet != RS_RET_OK) { if (pThis->bHaveSess) { pThis->bHaveSess = 0; SSL_free(pThis->pNetOssl->ssl); pThis->pNetOssl->ssl = NULL; } } RETiRet; } static rsRetVal SetGnutlsPriorityString(nsd_t *const pNsd, uchar *const gnutlsPriorityString) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ossl); #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) sbool ApplySettings = 0; if ((gnutlsPriorityString != NULL && pThis->gnutlsPriorityString == NULL) || (gnutlsPriorityString != NULL && strcmp((const char *)pThis->gnutlsPriorityString, (const char *)gnutlsPriorityString) != 0)) { ApplySettings = 1; } pThis->gnutlsPriorityString = gnutlsPriorityString; dbgprintf("gnutlsPriorityString: set to '%s' Apply %s\n", (gnutlsPriorityString != NULL ? (char *)gnutlsPriorityString : "NULL"), (ApplySettings == 1 ? "TRUE" : "FALSE")); if (ApplySettings == 1) { /* Apply Settings if necessary */ applyGnutlsPriorityString(pThis); } #else LogError(0, RS_RET_SYS_ERR, "Warning: TLS library does not support SSL_CONF_cmd API" "(maybe it is too old?). Cannot use gnutlsPriorityString ('%s'). For more see: " "https://www.rsyslog.com/doc/master/configuration/modules/imtcp.html#gnutlsprioritystring", gnutlsPriorityString); #endif RETiRet; } static rsRetVal applyGnutlsPriorityString(nsd_ossl_t *const pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_ossl); #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) /* Note: we disable unkonwn functions. The corresponding error message is * generated during SetGntuTLSPriorityString(). */ if (pThis->gnutlsPriorityString == NULL || pThis->pNetOssl->ctx == NULL) { FINALIZE; } else { CHKiRet(net_ossl.osslApplyTlscgfcmd(pThis->pNetOssl, pThis->gnutlsPriorityString)); } #endif finalize_it: RETiRet; } /* Set the driver cert extended key usage check setting, for now it is empty wrapper. * TODO: implement openSSL version * jvymazal, 2019-08-16 */ static rsRetVal SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) * pNsd, int ChkExtendedKeyUsage) { DEFiRet; if (ChkExtendedKeyUsage != 0) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d " "not supported by ossl netstream driver", ChkExtendedKeyUsage); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set the driver name checking strictness * 0 - less strict per RFC 5280, section 4.1.2.6 - either SAN or CN match is good * 1 - more strict per RFC 6125 - if any SAN present it must match (CN is ignored) * jvymazal, 2019-08-16, csiltala, 2025-07-28 */ static rsRetVal SetPrioritizeSAN(nsd_t *pNsd, int prioritizeSan) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (prioritizeSan != 0 && prioritizeSan != 1) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d " "not supported by ossl netstream driver", prioritizeSan); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } pThis->pNetOssl->bSANpriority = prioritizeSan; finalize_it: RETiRet; } /* Set the driver tls verifyDepth * alorbach, 2019-12-20 */ static rsRetVal SetTlsVerifyDepth(nsd_t *pNsd, int verifyDepth) { DEFiRet; nsd_ossl_t *pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (verifyDepth == 0) { FINALIZE; } assert(verifyDepth >= 2); pThis->DrvrVerifyDepth = verifyDepth; finalize_it: RETiRet; } static rsRetVal SetTlsCAFile(nsd_t *pNsd, const uchar *const caFile) { DEFiRet; nsd_ossl_t *const pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (caFile == NULL) { pThis->pNetOssl->pszCAFile = NULL; } else { CHKmalloc(pThis->pNetOssl->pszCAFile = (const uchar *)strdup((const char *)caFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCRLFile(nsd_t *pNsd, const uchar *const crlFile) { DEFiRet; nsd_ossl_t *const pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (crlFile == NULL) { pThis->pNetOssl->pszCRLFile = NULL; } else { CHKmalloc(pThis->pNetOssl->pszCRLFile = (const uchar *)strdup((const char *)crlFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsKeyFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_ossl_t *const pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (pszFile == NULL) { pThis->pNetOssl->pszKeyFile = NULL; } else { CHKmalloc(pThis->pNetOssl->pszKeyFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCertFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_ossl_t *const pThis = (nsd_ossl_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_ossl); if (pszFile == NULL) { pThis->pNetOssl->pszCertFile = NULL; } else { CHKmalloc(pThis->pNetOssl->pszCertFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(nsd_ossl) CODESTARTobjQueryInterface(nsd_ossl); if (pIf->ifVersion != nsdCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = (rsRetVal(*)(nsd_t **))nsd_osslConstruct; pIf->Destruct = (rsRetVal(*)(nsd_t **))nsd_osslDestruct; pIf->Abort = Abort; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->Rcv = Rcv; pIf->Send = Send; pIf->Connect = Connect; pIf->GetSock = GetSock; pIf->SetSock = SetSock; pIf->SetMode = SetMode; pIf->SetAuthMode = SetAuthMode; pIf->SetPermitExpiredCerts = SetPermitExpiredCerts; pIf->SetPermPeers = SetPermPeers; pIf->CheckConnection = CheckConnection; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->GetRemAddr = GetRemAddr; pIf->EnableKeepAlive = EnableKeepAlive; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; /* we don't NEED this interface! */ pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; /* we don't NEED this interface! */ pIf->SetPrioritizeSAN = SetPrioritizeSAN; pIf->SetTlsVerifyDepth = SetTlsVerifyDepth; pIf->SetTlsCAFile = SetTlsCAFile; pIf->SetTlsCRLFile = SetTlsCRLFile; pIf->SetTlsKeyFile = SetTlsKeyFile; pIf->SetTlsCertFile = SetTlsCertFile; finalize_it: ENDobjQueryInterface(nsd_ossl) /* exit our class */ BEGINObjClassExit(nsd_ossl, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(nsd_ossl); /* release objects we no longer need */ objRelease(net_ossl, CORE_COMPONENT); objRelease(nsd_ptcp, LM_NSD_PTCP_FILENAME); objRelease(net, LM_NET_FILENAME); objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDObjClassExit(nsd_ossl) /* Initialize the nsd_ossl class. Must be called as the very first method * before anything else is called inside this class. */ BEGINObjClassInit(nsd_ossl, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(nsd_ptcp, LM_NSD_PTCP_FILENAME)); CHKiRet(objUse(net_ossl, CORE_COMPONENT)); ENDObjClassInit(nsd_ossl) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; nsd_osslClassExit(); net_osslClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ DBGPRINTF("modInit\n"); CHKiRet(net_osslClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ CHKiRet(nsd_osslClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/prop.c0000644000000000000000000000013215055605325015346 xustar0030 mtime=1756826325.650800698 30 atime=1764930996.401951636 30 ctime=1764935923.263577806 rsyslog-8.2512.0/runtime/prop.c0000664000175000017500000001745115055605325015022 0ustar00rgerrger/* prop.c - rsyslog's prop object * * This object is meant to support message properties that are stored * seperately from the message. The main intent is to support properties * that are "constant" during a period of time, so that many messages may * contain a reference to the same property. It is important, though, that * properties are destroyed when they are no longer needed. * * Please note that this is a performance-critical part of the software and * as such we may use some methods in here which do not look elegant, but * which are fast... * * Module begun 2009-06-17 by Rainer Gerhards * * Copyright 2009-2016 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "obj.h" #include "obj-types.h" #include "unicode-helper.h" #include "atomic.h" #include "prop.h" /* static data */ DEFobjStaticHelpers; // extern uchar *propGetSzStr(prop_t *pThis); /* expand inline function here */ /* Standard-Constructor */ BEGINobjConstruct(prop) /* be sure to specify the object type also in END macro! */ pThis->iRefCount = 1; INIT_ATOMIC_HELPER_MUT(pThis->mutRefCount); ENDobjConstruct(prop) /* destructor for the prop object */ BEGINobjDestruct(prop) /* be sure to specify the object type also in END and CODESTART macros! */ int currRefCount; CODESTARTobjDestruct(prop); currRefCount = ATOMIC_DEC_AND_FETCH(&pThis->iRefCount, &pThis->mutRefCount); if (currRefCount == 0) { /* (only) in this case we need to actually destruct the object */ if (pThis->len >= CONF_PROP_BUFSIZE) free(pThis->szVal.psz); DESTROY_ATOMIC_HELPER_MUT(pThis->mutRefCount); } else { pThis = NULL; /* tell framework NOT to destructing the object! */ } ENDobjDestruct(prop) /* set string, we make our own private copy! This MUST only be called BEFORE * ConstructFinalize()! */ static rsRetVal SetString(prop_t *pThis, const uchar *psz, const int len) { DEFiRet; ISOBJ_TYPE_assert(pThis, prop); if (pThis->len >= CONF_PROP_BUFSIZE) free(pThis->szVal.psz); pThis->len = len; if (len < CONF_PROP_BUFSIZE) { memcpy(pThis->szVal.sz, psz, len + 1); } else { if (pThis->szVal.psz != NULL) { free(pThis->szVal.psz); } CHKmalloc(pThis->szVal.psz = malloc(len + 1)); memcpy(pThis->szVal.psz, psz, len + 1); } finalize_it: RETiRet; } /* get string length */ static int GetStringLen(prop_t *pThis) { return pThis->len; } /* get string */ static rsRetVal GetString(prop_t *pThis, uchar **ppsz, int *plen) { ISOBJ_TYPE_assert(pThis, prop); if (pThis->len < CONF_PROP_BUFSIZE) { *ppsz = pThis->szVal.sz; } else { *ppsz = pThis->szVal.psz; } *plen = pThis->len; return RS_RET_OK; } /* ConstructionFinalizer * rgerhards, 2008-01-09 */ static rsRetVal propConstructFinalize(prop_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, prop); RETiRet; } /* add a new reference. It is VERY IMPORTANT to call this function whenever * the property is handed over to some entitiy that later call Destruct() on it. */ static rsRetVal AddRef(prop_t *pThis) { if (pThis == NULL) { DBGPRINTF( "prop/AddRef is passed a NULL ptr - ignoring it " "- further problems may occur\n"); FINALIZE; } ATOMIC_INC(&pThis->iRefCount, &pThis->mutRefCount); finalize_it: return RS_RET_OK; } /* this is a "do it all in one shot" function that creates a new property, * assigns the provided string to it and finalizes the property. Among the * convenience, it is also (very, very) slightly faster. * rgerhards, 2009-07-01 */ static rsRetVal CreateStringProp(prop_t **ppThis, const uchar *psz, const int len) { prop_t *pThis = NULL; DEFiRet; CHKiRet(propConstruct(&pThis)); CHKiRet(SetString(pThis, psz, len)); CHKiRet(propConstructFinalize(pThis)); *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK) { if (pThis != NULL) propDestruct(&pThis); } RETiRet; } /* another one-stop function, quite useful: it takes a property pointer and * a string. If the string is already contained in the property, nothing happens. * If the string is different (or the pointer NULL), the current property * is destructed and a new one created. This can be used to get a specific * name in those cases where there is a good chance that the property * immediatly previously processed already contained the value we need - in * which case we save us all the creation overhead by just reusing the already * existing property). * rgerhards, 2009-07-01 */ static rsRetVal CreateOrReuseStringProp(prop_t **ppThis, const uchar *psz, const int len) { uchar *pszPrev; int lenPrev; DEFiRet; assert(ppThis != NULL); if (*ppThis == NULL) { /* we need to create a property */ CHKiRet(CreateStringProp(ppThis, psz, len)); } else { /* already exists, check if we can re-use it */ GetString(*ppThis, &pszPrev, &lenPrev); if (len != lenPrev || ustrcmp(psz, pszPrev)) { /* different, need to discard old & create new one */ propDestruct(ppThis); CHKiRet(CreateStringProp(ppThis, psz, len)); } /* else we can re-use the existing one! */ } finalize_it: RETiRet; } /* debugprint for the prop object */ BEGINobjDebugPrint(prop) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(prop); dbgprintf("prop object %p - no further debug info implemented\n", pThis); ENDobjDebugPrint(prop) /* queryInterface function * rgerhards, 2008-02-21 */ BEGINobjQueryInterface(prop) CODESTARTobjQueryInterface(prop); if (pIf->ifVersion != propCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = propConstruct; pIf->ConstructFinalize = propConstructFinalize; pIf->Destruct = propDestruct; pIf->DebugPrint = propDebugPrint; pIf->SetString = SetString; pIf->GetString = GetString; pIf->GetStringLen = GetStringLen; pIf->AddRef = AddRef; pIf->CreateStringProp = CreateStringProp; pIf->CreateOrReuseStringProp = CreateOrReuseStringProp; finalize_it: ENDobjQueryInterface(prop) /* Exit the prop class. * rgerhards, 2009-04-06 */ BEGINObjClassExit(prop, OBJ_IS_CORE_MODULE) /* class, version */ ENDObjClassExit(prop) /* Initialize the prop class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(prop, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ /* set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, propDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, propConstructFinalize); ENDObjClassInit(prop) /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/lmcry_gcry.c0000644000000000000000000000013115055605325016537 xustar0030 mtime=1756826325.646800638 29 atime=1764931130.86615495 30 ctime=1764935923.324578739 rsyslog-8.2512.0/runtime/lmcry_gcry.c0000664000175000017500000002474715055605325016222 0ustar00rgerrger/* lmcry_gcry.c * * An implementation of the cryprov interface for libgcrypt. * * Copyright 2013-2017 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "cryprov.h" #include "parserif.h" #include "libgcry.h" #include "lmcry_gcry.h" #include "libcry_common.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfpdescrRegular[] = {{"cry.key", eCmdHdlrGetWord, 0}, {"cry.keyfile", eCmdHdlrGetWord, 0}, {"cry.keyprogram", eCmdHdlrGetWord, 0}, {"cry.mode", eCmdHdlrGetWord, 0}, /* CBC, ECB, etc */ {"cry.algo", eCmdHdlrGetWord, 0}}; static struct cnfparamblk pblkRegular = {CNFPARAMBLK_VERSION, sizeof(cnfpdescrRegular) / sizeof(struct cnfparamdescr), cnfpdescrRegular}; static struct cnfparamdescr cnfpdescrQueue[] = {{"queue.cry.key", eCmdHdlrGetWord, 0}, {"queue.cry.keyfile", eCmdHdlrGetWord, 0}, {"queue.cry.keyprogram", eCmdHdlrGetWord, 0}, {"queue.cry.mode", eCmdHdlrGetWord, 0}, /* CBC, ECB, etc */ {"queue.cry.algo", eCmdHdlrGetWord, 0}}; static struct cnfparamblk pblkQueue = {CNFPARAMBLK_VERSION, sizeof(cnfpdescrQueue) / sizeof(struct cnfparamdescr), cnfpdescrQueue}; #if 0 static void errfunc(__attribute__((unused)) void *usrptr, uchar *emsg) { LogError(0, RS_RET_CRYPROV_ERR, "Crypto Provider" "Error: %s - disabling encryption", emsg); } #endif /* Standard-Constructor */ BEGINobjConstruct(lmcry_gcry) CHKmalloc(pThis->ctx = gcryCtxNew()); finalize_it: ENDobjConstruct(lmcry_gcry) /* destructor for the lmcry_gcry object */ BEGINobjDestruct(lmcry_gcry) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(lmcry_gcry); rsgcryCtxDel(pThis->ctx); ENDobjDestruct(lmcry_gcry) /* apply all params from param block to us. This must be called * after construction, but before the OnFileOpen() entry point. * Defaults are expected to have been set during construction. */ static rsRetVal SetCnfParam(void *pT, struct nvlst *lst, int paramType) { lmcry_gcry_t *pThis = (lmcry_gcry_t *)pT; int i, r; unsigned keylen = 0; uchar *key = NULL; uchar *keyfile = NULL; uchar *keyprogram = NULL; uchar *algo = NULL; uchar *mode = NULL; int nKeys; /* number of keys (actually methods) specified */ struct cnfparamvals *pvals; struct cnfparamblk *pblk; DEFiRet; pblk = (paramType == CRYPROV_PARAMTYPE_REGULAR) ? &pblkRegular : &pblkQueue; nKeys = 0; pvals = nvlstGetParams(lst, pblk, NULL); if (pvals == NULL) { parser_errmsg("error crypto provider gcryconfig parameters]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("param blk in lmcry_gcry:\n"); cnfparamsPrint(pblk, pvals); } for (i = 0; i < pblk->nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblk->descr[i].name, "cry.key") || !strcmp(pblk->descr[i].name, "queue.cry.key")) { key = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); ++nKeys; } else if (!strcmp(pblk->descr[i].name, "cry.keyfile") || !strcmp(pblk->descr[i].name, "queue.cry.keyfile")) { keyfile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); ++nKeys; } else if (!strcmp(pblk->descr[i].name, "cry.keyprogram") || !strcmp(pblk->descr[i].name, "queue.cry.keyprogram")) { keyprogram = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); ++nKeys; } else if (!strcmp(pblk->descr[i].name, "cry.mode") || !strcmp(pblk->descr[i].name, "queue.cry.mode")) { mode = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk->descr[i].name, "cry.algo") || !strcmp(pblk->descr[i].name, "queue.cry.algo")) { algo = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { DBGPRINTF( "lmcry_gcry: program error, non-handled " "param '%s'\n", pblk->descr[i].name); } } if (algo != NULL) { iRet = rsgcrySetAlgo(pThis->ctx, algo); if (iRet != RS_RET_OK) { LogError(0, iRet, "cry.algo '%s' is not know/supported", algo); FINALIZE; } } if (mode != NULL) { iRet = rsgcrySetMode(pThis->ctx, mode); if (iRet != RS_RET_OK) { LogError(0, iRet, "cry.mode '%s' is not know/supported", mode); FINALIZE; } } /* note: key must be set AFTER algo/mode is set (as it depends on them) */ if (nKeys != 1) { LogError(0, RS_RET_INVALID_PARAMS, "excactly one of the following " "parameters can be specified: cry.key, cry.keyfile, cry.keyprogram\n"); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } if (key != NULL) { LogError(0, RS_RET_ERR, "Note: specifying an actual key directly from the " "config file is highly insecure - DO NOT USE FOR PRODUCTION"); keylen = strlen((char *)key); } if (keyfile != NULL) { r = cryGetKeyFromFile((char *)keyfile, (char **)&key, &keylen); if (r != 0) { LogError(errno, RS_RET_ERR, "error reading keyfile %s", keyfile); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } } if (keyprogram != NULL) { r = cryGetKeyFromProg((char *)keyprogram, (char **)&key, &keylen); if (r != 0) { LogError(0, RS_RET_ERR, "error %d obtaining key from program %s\n", r, keyprogram); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } } /* if we reach this point, we have a valid key */ r = rsgcrySetKey(pThis->ctx, key, keylen); if (r > 0) { LogError(0, RS_RET_INVALID_PARAMS, "Key length %d expected, but " "key of length %d given", r, keylen); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } finalize_it: free(key); free(keyfile); free(algo); free(keyprogram); free(mode); if (pvals != NULL) cnfparamvalsDestruct(pvals, pblk); RETiRet; } static void SetDeleteOnClose(void *pF, int val) { gcryfileSetDeleteOnClose(pF, val); } static rsRetVal GetBytesLeftInBlock(void *pF, ssize_t *left) { return gcryfileGetBytesLeftInBlock((gcryfile)pF, left); } static rsRetVal DeleteStateFiles(uchar *logfn) { return gcryfileDeleteState(logfn); } static rsRetVal OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode) { lmcry_gcry_t *pThis = (lmcry_gcry_t *)pT; gcryfile *pgf = (gcryfile *)pGF; DEFiRet; DBGPRINTF("lmcry_gcry: open file '%s', mode '%c'\n", fn, openMode); iRet = rsgcryInitCrypt(pThis->ctx, pgf, fn, openMode); if (iRet != RS_RET_OK) { LogError(0, iRet, "Encryption Provider" "Error: cannot open .encinfo file - disabling log file"); } RETiRet; } static rsRetVal Decrypt(void *pF, uchar *rec, size_t *lenRec) { DEFiRet; iRet = rsgcryDecrypt(pF, rec, lenRec); RETiRet; } static rsRetVal Encrypt(void *pF, uchar *rec, size_t *lenRec) { DEFiRet; iRet = rsgcryEncrypt(pF, rec, lenRec); RETiRet; } static rsRetVal OnFileClose(void *pF, off64_t offsLogfile) { DEFiRet; gcryfileDestruct(pF, offsLogfile); RETiRet; } BEGINobjQueryInterface(lmcry_gcry) CODESTARTobjQueryInterface(lmcry_gcry); if (pIf->ifVersion != cryprovCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } pIf->Construct = (rsRetVal(*)(void *))lmcry_gcryConstruct; pIf->SetCnfParam = SetCnfParam; pIf->SetDeleteOnClose = SetDeleteOnClose; pIf->Destruct = (rsRetVal(*)(void *))lmcry_gcryDestruct; pIf->OnFileOpen = OnFileOpen; pIf->Encrypt = Encrypt; pIf->Decrypt = Decrypt; pIf->OnFileClose = OnFileClose; pIf->DeleteStateFiles = DeleteStateFiles; pIf->GetBytesLeftInBlock = GetBytesLeftInBlock; finalize_it: ENDobjQueryInterface(lmcry_gcry) BEGINObjClassExit(lmcry_gcry, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(lmcry_gcry); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); rsgcryExit(); ENDObjClassExit(lmcry_gcry) BEGINObjClassInit(lmcry_gcry, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); if (rsgcryInit() != 0) { LogError(0, RS_RET_CRYPROV_ERR, "error initializing " "crypto provider - cannot encrypt"); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } ENDObjClassInit(lmcry_gcry) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; lmcry_gcryClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(lmcry_gcryClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/perctile_stats.h0000644000000000000000000000013215055605325017420 xustar0030 mtime=1756826325.650800698 30 atime=1764930980.046678658 30 ctime=1764935923.231577315 rsyslog-8.2512.0/runtime/perctile_stats.h0000664000175000017500000000517415055605325017073 0ustar00rgerrger/* * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_PERCTILE_STATS_H #define INCLUDED_PERCTILE_STATS_H #include "hashtable.h" #include "statsobj.h" struct perctile_ctr_s { // percentile [0,100] uint8_t percentile; size_t index; intctr_t ctr_perctile_stat; ctr_t *ref_ctr_percentile_stat; }; struct perctile_stat_s { uchar name[128]; sbool bReported; struct ringbuf_s *rb_observed_stats; // array of requested perctile to track struct perctile_ctr_s *ctrs; size_t perctile_ctrs_count; pthread_rwlock_t stats_lock; intctr_t ctrWindowCount; ctr_t *refCtrWindowCount; intctr_t ctrWindowMin; ctr_t *refCtrWindowMin; intctr_t ctrWindowMax; ctr_t *refCtrWindowMax; intctr_t ctrWindowSum; ctr_t *refCtrWindowSum; }; struct perctile_bucket_s { uchar *name; uchar *delim; // lock for entire bucket pthread_rwlock_t lock; struct hashtable *htable; struct perctile_bucket_s *next; statsobj_t *statsobj; STATSCOUNTER_DEF(ctrNewKeyAdd, mutCtrNewKeyAdd); ctr_t *pNewKeyAddCtr; STATSCOUNTER_DEF(ctrOpsOverflow, mutCtrOpsOverflow); ctr_t *pOpsOverflowCtr; uint32_t window_size; // These percentile values apply to all perctile stats in this bucket. uint8_t *perctile_values; size_t perctile_values_count; }; struct perctile_buckets_s { uint8_t initialized; statsobj_t *global_stats; pthread_rwlock_t lock; struct perctile_bucket_s *listBuckets; }; // keep these local for now. typedef struct perctile_ctr_s perctile_ctr_t; typedef struct perctile_stat_s perctile_stat_t; typedef struct perctile_bucket_s perctile_bucket_t; rsRetVal perctileClassInit(void); void perctileBucketsDestruct(void); rsRetVal perctile_initCnf(perctile_buckets_t *b); perctile_bucket_t *perctile_findBucket(const uchar *name); rsRetVal perctile_processCnf(struct cnfobj *cnf); rsRetVal perctile_obs(perctile_bucket_t *perctile_bkt, uchar *key, int64_t value); #endif /* #ifndef INCLUDED_PERCTILE_STATS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/cfsysline.h0000644000000000000000000000013215055605325016372 xustar0030 mtime=1756826325.643800593 30 atime=1764930981.018694914 30 ctime=1764935923.280578066 rsyslog-8.2512.0/runtime/cfsysline.h0000664000175000017500000000541615055605325016044 0ustar00rgerrger/* Definition of the cfsysline (config file system line) object. * * Copyright 2007-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CFSYSLINE_H_INCLUDED #define CFSYSLINE_H_INCLUDED #include "linkedlist.h" /* this is a single entry for a parse routine. It describes exactly * one entry point/handler. * The short name is cslch (Configfile SysLine CommandHandler) */ struct cslCmdHdlr_s { /* config file sysline parse entry */ ecslConfObjType __attribute__((deprecated)) eConfObjType; /* which config object is this for? */ ecslCmdHdrlType eType; /* which type of handler is this? */ rsRetVal (*cslCmdHdlr)(); /* function pointer to use with handler (params depending on eType) */ void *pData; /* user-supplied data pointer */ int *permitted; /* is this parameter currently permitted? (NULL=don't check) */ }; typedef struct cslCmdHdlr_s cslCmdHdlr_t; /* this is the list of known configuration commands with pointers to * their handlers. * The short name is cslc (Configfile SysLine Command) */ struct cslCmd_s { /* config file sysline parse entry */ int bChainingPermitted; /* may multiple handlers be chained for this command? */ linkedList_t llCmdHdlrs; /* linked list of command handlers */ }; typedef struct cslCmd_s cslCmd_t; /* prototypes */ rsRetVal regCfSysLineHdlr(const uchar *pCmdName, int bChainingPermitted, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, void *pOwnerCookie); rsRetVal regCfSysLineHdlr2(const uchar *pCmdName, int bChainingPermitted, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, void *pOwnerCookie, int *permitted); rsRetVal unregCfSysLineHdlrs(void); rsRetVal unregCfSysLineHdlrs4Owner(void *pOwnerCookie); rsRetVal processCfSysLineCommand(uchar *pCmd, uchar **p); rsRetVal cfsyslineInit(void); void dbgPrintCfSysLineHandlers(void); #endif /* #ifndef CFSYSLINE_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/wti.c0000644000000000000000000000013215055605325015171 xustar0030 mtime=1756826325.654800759 30 atime=1764930994.422918667 30 ctime=1764935923.249577591 rsyslog-8.2512.0/runtime/wti.c0000664000175000017500000004622715055605325014650 0ustar00rgerrger/* wti.c * * This file implements the worker thread instance (wti) class. * * File begun on 2008-01-20 by RGerhards based on functions from the * previous queue object class (the wti functions have been extracted) * * There is some in-depth documentation available in doc/dev_queue.html * (and in the web doc set on https://www.rsyslog.com/doc/). Be sure to read it * if you are getting aquainted to the object. * * Copyright 2008-2025 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include "rsyslog.h" #include "stringbuf.h" #include "srUtils.h" #include "errmsg.h" #include "wtp.h" #include "wti.h" #include "obj.h" #include "glbl.h" #include "action.h" #include "atomic.h" #include "rsconf.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) pthread_key_t thrd_wti_key; /* methods */ /* get the header for debug messages * The caller must NOT free or otherwise modify the returned string! */ uchar *ATTR_NONNULL() wtiGetDbgHdr(const wti_t *const pThis) { ISOBJ_TYPE_assert(pThis, wti); if (pThis->pszDbgHdr == NULL) return (uchar *)"wti"; /* should not normally happen */ else return pThis->pszDbgHdr; } /* return the current worker processing state. For the sake of * simplicity, we do not use the iRet interface. -- rgerhards, 2009-07-17 */ int ATTR_NONNULL() wtiGetState(wti_t *pThis) { return ATOMIC_FETCH_32BIT(&pThis->bIsRunning, &pThis->mutIsRunning); } /* join terminated worker thread * This may be called in any thread state, it will be a NOP if the * thread is not to join. */ void ATTR_NONNULL() wtiJoinThrd(wti_t *const pThis) { int r; ISOBJ_TYPE_assert(pThis, wti); if (wtiGetState(pThis) == WRKTHRD_WAIT_JOIN) { DBGPRINTF("%s: joining terminated worker\n", wtiGetDbgHdr(pThis)); if ((r = pthread_join(pThis->thrdID, NULL)) != 0) { LogMsg(r, RS_RET_INTERNAL_ERROR, LOG_WARNING, "rsyslog bug? wti cannot join terminated wrkr"); } DBGPRINTF("%s: worker fully terminated\n", wtiGetDbgHdr(pThis)); wtiSetState(pThis, WRKTHRD_STOPPED); if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: thread joined\n", wtiGetDbgHdr(pThis)); } } } /* Set this thread to "always running" state (can not be unset) * rgerhards, 2009-07-20 */ rsRetVal ATTR_NONNULL() wtiSetAlwaysRunning(wti_t *pThis) { ISOBJ_TYPE_assert(pThis, wti); pThis->bAlwaysRunning = RSTRUE; return RS_RET_OK; } /* Set status (thread is running or not), actually an property of * use for wtp, but we need to have it per thread instance (thus it * is inside wti). -- rgerhards, 2009-07-17 */ rsRetVal ATTR_NONNULL() wtiSetState(wti_t *pThis, const int newVal) { ISOBJ_TYPE_assert(pThis, wti); if (newVal == WRKTHRD_STOPPED) { ATOMIC_STORE_0_TO_INT(&pThis->bIsRunning, &pThis->mutIsRunning); } else { ATOMIC_OR_INT_TO_INT(&pThis->bIsRunning, &pThis->mutIsRunning, newVal); } return RS_RET_OK; } /* advise all workers to start by interrupting them. That should unblock all srSleep() * calls. */ rsRetVal wtiWakeupThrd(wti_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); if (wtiGetState(pThis)) { /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("sent SIGTTIN to worker thread %p\n", (void *)pThis->thrdID); } RETiRet; } /* Cancel the thread. If the thread is not running. But it is save and legal to * call wtiCancelThrd() in such situations. This function only returns when the * thread has terminated. Else we may get race conditions all over the code... * Note that when waiting for the thread to terminate, we do a busy wait, checking * progress every 10ms. It is very unlikely that we will ever cancel a thread * and, if so, it will only happen at the end of the rsyslog run. So doing this * kind of non-optimal wait is considered preferable over using condition variables. * rgerhards, 2008-02-26 */ rsRetVal ATTR_NONNULL() wtiCancelThrd(wti_t *pThis, const uchar *const cancelobj) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); wtiJoinThrd(pThis); if (wtiGetState(pThis) != WRKTHRD_STOPPED) { LogMsg(0, RS_RET_ERR, LOG_WARNING, "%s: need to do cooperative cancellation " "- some data may be lost, increase timeout?", cancelobj); /* we first try the cooperative "cancel" interface */ pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("sent SIGTTIN to worker thread %p, giving it a chance to terminate\n", (void *)pThis->thrdID); srSleep(0, 50000); wtiJoinThrd(pThis); } if (wtiGetState(pThis) != WRKTHRD_STOPPED) { LogMsg(0, RS_RET_ERR, LOG_WARNING, "%s: need to do hard cancellation", cancelobj); if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: need to do hard cancellation\n", cancelobj); } pthread_cancel(pThis->thrdID); pthread_kill(pThis->thrdID, SIGTTIN); DBGPRINTF("cooperative worker termination failed, using cancellation...\n"); DBGOPRINT((obj_t *)pThis, "canceling worker thread\n"); pthread_cancel(pThis->thrdID); /* now wait until the thread terminates... */ while (wtiGetState(pThis) != WRKTHRD_STOPPED && wtiGetState(pThis) != WRKTHRD_WAIT_JOIN) { DBGOPRINT((obj_t *)pThis, "waiting on termination, state %d\n", wtiGetState(pThis)); srSleep(0, 10000); } } wtiJoinThrd(pThis); RETiRet; } /* note: this function is only called once in action.c */ rsRetVal wtiNewIParam(wti_t *const pWti, action_t *const pAction, actWrkrIParams_t **piparams) { actWrkrInfo_t *const wrkrInfo = &(pWti->actWrkrInfo[pAction->iActionNbr]); actWrkrIParams_t *iparams; int newMax; DEFiRet; if (wrkrInfo->p.tx.currIParam == wrkrInfo->p.tx.maxIParams) { /* we need to extend */ newMax = (wrkrInfo->p.tx.maxIParams == 0) ? CONF_IPARAMS_BUFSIZE : 2 * wrkrInfo->p.tx.maxIParams; CHKmalloc(iparams = realloc(wrkrInfo->p.tx.iparams, sizeof(actWrkrIParams_t) * pAction->iNumTpls * newMax)); memset(iparams + (wrkrInfo->p.tx.currIParam * pAction->iNumTpls), 0, sizeof(actWrkrIParams_t) * pAction->iNumTpls * (newMax - wrkrInfo->p.tx.maxIParams)); wrkrInfo->p.tx.iparams = iparams; wrkrInfo->p.tx.maxIParams = newMax; } *piparams = wrkrInfo->p.tx.iparams + wrkrInfo->p.tx.currIParam * pAction->iNumTpls; ++wrkrInfo->p.tx.currIParam; finalize_it: RETiRet; } /* Destructor */ BEGINobjDestruct(wti) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(wti); if (wtiGetState(pThis) != WRKTHRD_STOPPED) { DBGPRINTF("%s: rsyslog bug: worker not stopped during shutdown\n", wtiGetDbgHdr(pThis)); if (dbgTimeoutToStderr) { fprintf(stderr, "RSYSLOG BUG: %s: worker not stopped during shutdown\n", wtiGetDbgHdr(pThis)); } else { assert(wtiGetState(pThis) == WRKTHRD_STOPPED); } } /* actual destruction */ batchFree(&pThis->batch); free(pThis->actWrkrInfo); pthread_cond_destroy(&pThis->pcondBusy); DESTROY_ATOMIC_HELPER_MUT(pThis->mutIsRunning); free(pThis->pszDbgHdr); ENDobjDestruct(wti) /* Standard-Constructor for the wti object */ BEGINobjConstruct(wti) /* be sure to specify the object type also in END macro! */ INIT_ATOMIC_HELPER_MUT(pThis->mutIsRunning); pthread_cond_init(&pThis->pcondBusy, NULL); ENDobjConstruct(wti) /* Construction finalizer * rgerhards, 2008-01-17 */ rsRetVal wtiConstructFinalize(wti_t *pThis) { DEFiRet; int iDeqBatchSize; ISOBJ_TYPE_assert(pThis, wti); DBGPRINTF("%s: finalizing construction of worker instance data (for %d actions)\n", wtiGetDbgHdr(pThis), runConf->actions.iActionNbr); /* initialize our thread instance descriptor (no concurrency here) */ pThis->bIsRunning = WRKTHRD_STOPPED; /* must use calloc as we need zero-init */ CHKmalloc(pThis->actWrkrInfo = calloc(runConf->actions.iActionNbr, sizeof(actWrkrInfo_t))); if (pThis->pWtp == NULL) { dbgprintf("wtiConstructFinalize: pWtp not set, this may be intentional\n"); FINALIZE; } /* we now alloc the array for user pointers. We obtain the max from the queue itself. */ CHKiRet(pThis->pWtp->pfGetDeqBatchSize(pThis->pWtp->pUsr, &iDeqBatchSize)); CHKiRet(batchInit(&pThis->batch, iDeqBatchSize)); finalize_it: RETiRet; } /* cancellation cleanup handler for queueWorker () * Most importantly, it must bring back the batch into a consistent state. * Keep in mind that cancellation is disabled if we run into * the cancel cleanup handler (and have been cancelled). * rgerhards, 2008-01-16 */ static void wtiWorkerCancelCleanup(void *arg) { wti_t *pThis = (wti_t *)arg; wtp_t *pWtp; ISOBJ_TYPE_assert(pThis, wti); pWtp = pThis->pWtp; ISOBJ_TYPE_assert(pWtp, wtp); DBGPRINTF("%s: cancellation cleanup handler called.\n", wtiGetDbgHdr(pThis)); pWtp->pfObjProcessed(pWtp->pUsr, pThis); DBGPRINTF("%s: done cancellation cleanup handler.\n", wtiGetDbgHdr(pThis)); } /* wait for queue to become non-empty or timeout * this is introduced as helper to support queue minimum batch sizes, but may * also be used for other cases. This function waits until the queue is non-empty * or a timeout occurs. The timeout must be passed in as absolute value. * @returns 0 if timeout occurs (queue still empty), something else otherwise */ int ATTR_NONNULL() wtiWaitNonEmpty(wti_t *const pThis, const struct timespec timeout) { wtp_t *__restrict__ const pWtp = pThis->pWtp; int r; DBGOPRINT((obj_t *)pThis, "waiting on queue to become non-empty\n"); if (d_pthread_cond_timedwait(&pThis->pcondBusy, pWtp->pmutUsr, &timeout) != 0) { r = 0; } else { r = 1; } DBGOPRINT((obj_t *)pThis, "waited on queue to become non-empty, result %d\n", r); return r; } /* wait for queue to become non-empty or timeout * helper to wtiWorker. Note the the predicate is * re-tested by the caller, so it is OK to NOT do it here. * rgerhards, 2009-05-20 */ static void ATTR_NONNULL() doIdleProcessing(wti_t *const pThis, wtp_t *const pWtp, int *const pbInactivityTOOccurred) { struct timespec t; DBGPRINTF("%s: worker IDLE, waiting for work.\n", wtiGetDbgHdr(pThis)); if (pThis->bAlwaysRunning) { /* never shut down any started worker */ d_pthread_cond_wait(&pThis->pcondBusy, pWtp->pmutUsr); } else { timeoutComp(&t, pWtp->toWrkShutdown); /* get absolute timeout */ if (d_pthread_cond_timedwait(&pThis->pcondBusy, pWtp->pmutUsr, &t) != 0) { DBGPRINTF("%s: inactivity timeout, worker terminating...\n", wtiGetDbgHdr(pThis)); *pbInactivityTOOccurred = 1; /* indicate we had a timeout */ } } DBGOPRINT((obj_t *)pThis, "worker awoke from idle processing\n"); } /* generic worker thread framework. Note that we prohibit cancellation * during almost all times, because it can have very undesired side effects. * However, we may need to cancel a thread if the consumer blocks for too * long (during shutdown). So what we do is block cancellation, and every * consumer must enable it during the periods where it is safe. */ PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wempty_body rsRetVal wtiWorker(wti_t *__restrict__ const pThis) { wtp_t *__restrict__ const pWtp = pThis->pWtp; /* our worker thread pool -- shortcut */ action_t *__restrict__ pAction; rsRetVal localRet; rsRetVal terminateRet; actWrkrInfo_t *__restrict__ wrkrInfo; int iCancelStateSave; int i, j, k; DEFiRet; dbgSetThrdName(pThis->pszDbgHdr); pthread_cleanup_push(wtiWorkerCancelCleanup, pThis); int bInactivityTOOccurred = 0; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); DBGPRINTF("wti %p: worker starting\n", pThis); /* now we have our identity, on to real processing */ /* note: in this loop, the mutex is "never" unlocked. Of course, * this is not true: it actually is unlocked when the actual processing * is done, as part of pWtp->pfDoWork() processing. Note that this * function is required to re-lock it when done. We cannot do the * lock/unlock here ourselfs, as pfDoWork() needs to access queue * structures itself. * The same goes for pfRateLimiter(). While we could unlock/lock when * we call it, in practice the function is often called without any * ratelimiting actually done. Only the rate limiter itself knows * that. As such, it needs to bear the burden of doing the locking * when required. -- rgerhards, 2013-11-20 */ d_pthread_mutex_lock(pWtp->pmutUsr); while (1) { /* loop will be broken below */ if (pWtp->pfRateLimiter != NULL) { /* call rate-limiter, if defined */ pWtp->pfRateLimiter(pWtp->pUsr); } /* first check if we are in shutdown process (but evaluate a bit later) */ terminateRet = wtpChkStopWrkr(pWtp, MUTEX_ALREADY_LOCKED); if (terminateRet == RS_RET_TERMINATE_NOW) { /* we now need to free the old batch */ localRet = pWtp->pfObjProcessed(pWtp->pUsr, pThis); DBGOPRINT((obj_t *)pThis, "terminating worker because of " "TERMINATE_NOW mode, del iRet %d\n", localRet); break; } /* try to execute and process whatever we have */ localRet = pWtp->pfDoWork(pWtp->pUsr, pThis); if (localRet == RS_RET_ERR_QUEUE_EMERGENCY) { break; /* end of loop */ } else if (localRet == RS_RET_IDLE) { if (terminateRet == RS_RET_TERMINATE_WHEN_IDLE || bInactivityTOOccurred) { DBGOPRINT((obj_t *)pThis, "terminating worker terminateRet=%d, " "bInactivityTOOccurred=%d\n", terminateRet, bInactivityTOOccurred); break; /* end of loop */ } doIdleProcessing(pThis, pWtp, &bInactivityTOOccurred); continue; /* request next iteration */ } bInactivityTOOccurred = 0; /* reset for next run */ } d_pthread_mutex_unlock(pWtp->pmutUsr); DBGPRINTF("DDDD: wti %p: worker cleanup action instances\n", pThis); for (i = 0; i < runConf->actions.iActionNbr; ++i) { wrkrInfo = &(pThis->actWrkrInfo[i]); dbgprintf("wti %p, action %d, ptr %p\n", pThis, i, wrkrInfo->actWrkrData); if (wrkrInfo->actWrkrData != NULL) { pAction = wrkrInfo->pAction; actionRemoveWorker(pAction, wrkrInfo->actWrkrData); pAction->pMod->mod.om.freeWrkrInstance(wrkrInfo->actWrkrData); if (pAction->isTransactional) { /* free iparam "cache" - we need to go through to max! */ for (j = 0; j < wrkrInfo->p.tx.maxIParams; ++j) { for (k = 0; k < pAction->iNumTpls; ++k) { free(actParam(wrkrInfo->p.tx.iparams, pAction->iNumTpls, j, k).param); } } free(wrkrInfo->p.tx.iparams); wrkrInfo->p.tx.iparams = NULL; wrkrInfo->p.tx.currIParam = 0; wrkrInfo->p.tx.maxIParams = 0; } else { releaseDoActionParams(pAction, pThis, 1); } wrkrInfo->actWrkrData = NULL; /* re-init for next activation */ } } /* indicate termination */ pthread_cleanup_pop(0); /* remove cleanup handler */ pthread_setcancelstate(iCancelStateSave, NULL); dbgprintf("wti %p: exiting\n", pThis); RETiRet; } PRAGMA_DIAGNOSTIC_POP /* some simple object access methods */ rsRetVal wtiSetpWtp(wti_t *pThis, wtp_t *pVal) { pThis->pWtp = pVal; return RS_RET_OK; } /* set the debug header message * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. Must be called only before object is finalized. * rgerhards, 2008-01-09 */ rsRetVal wtiSetDbgHdr(wti_t *pThis, uchar *pszMsg, const size_t lenMsg) { DEFiRet; ISOBJ_TYPE_assert(pThis, wti); assert(pszMsg != NULL); if (lenMsg < 1) ABORT_FINALIZE(RS_RET_PARAM_ERROR); if (pThis->pszDbgHdr != NULL) { free(pThis->pszDbgHdr); } if ((pThis->pszDbgHdr = malloc(lenMsg + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pszDbgHdr, pszMsg, lenMsg + 1); /* always think about the \0! */ finalize_it: RETiRet; } /* This function returns (and creates if necessary) a dummy wti suitable * for use by the rule engine. It is intended to be used for direct-mode * main queues (folks, don't do that!). Once created, data is stored in * thread-specific storage. * Note: we do NOT do error checking -- if this functions fails, all the * rest will fail as well... (also, it will only fail under OOM, so...). * Memleak: we leak pWti's when run in direct mode. However, this is only * a cosmetic leak, as we need them until all inputs are terminated, * what means essentially until rsyslog itself is terminated. So we * don't care -- it's just not nice in valgrind, but that's it. */ wti_t *wtiGetDummy(void) { wti_t *pWti; pWti = (wti_t *)pthread_getspecific(thrd_wti_key); if (pWti == NULL) { wtiConstruct(&pWti); if (pWti != NULL) wtiConstructFinalize(pWti); if (pthread_setspecific(thrd_wti_key, pWti) != 0) { DBGPRINTF("wtiGetDummy: error setspecific thrd_wti_key\n"); } } return pWti; } /* dummy */ static rsRetVal wtiQueryInterface(interface_t __attribute__((unused)) * i) { return RS_RET_NOT_IMPLEMENTED; } /* exit our class */ BEGINObjClassExit(wti, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(wti); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); pthread_key_delete(thrd_wti_key); ENDObjClassExit(wti) /* Initialize the wti class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 */ BEGINObjClassInit(wti, 1, OBJ_IS_CORE_MODULE) /* one is the object version (most important for persisting) */ int r; /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); r = pthread_key_create(&thrd_wti_key, NULL); if (r != 0) { dbgprintf("wti.c: pthread_key_create failed\n"); ABORT_FINALIZE(RS_RET_ERR); } ENDObjClassInit(wti) rsyslog-8.2512.0/runtime/PaxHeaders/gss-misc.h0000644000000000000000000000013215055605325016120 xustar0030 mtime=1756826325.645800623 30 atime=1764931130.908155628 30 ctime=1764935923.336578923 rsyslog-8.2512.0/runtime/gss-misc.h0000664000175000017500000000274615055605325015575 0ustar00rgerrger/* Definitions for gssutil class. This implements a session of the * plain TCP server. * * Copyright 2008 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef GSS_MISC_H_INCLUDED #define GSS_MISC_H_INCLUDED 1 #include #include "obj.h" /* interfaces */ BEGINinterface(gssutil) /* name must also be changed in ENDinterface macro! */ int (*recv_token)(int s, gss_buffer_t tok); int (*send_token)(int s, gss_buffer_t tok); void (*display_status)(char *m, OM_uint32 maj_stat, OM_uint32 min_stat); void (*display_ctx_flags)(OM_uint32 flags); ENDinterface(gssutil) #define gssutilCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(gssutil); /* the name of our library binary */ #define LM_GSSUTIL_FILENAME "lmgssutil" #endif /* #ifndef GSS_MISC_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/timezones.h0000644000000000000000000000013215055605325016410 xustar0030 mtime=1756826325.654800759 30 atime=1764930980.048678691 30 ctime=1764935923.321578693 rsyslog-8.2512.0/runtime/timezones.h0000664000175000017500000000221115055605325016050 0ustar00rgerrger/* header for timezones.c * * Copyright 2022 Attila Lakatos and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_TIMEZONES_H #define INCLUDED_TIMEZONES_H #include "rsconf.h" /* timezone specific parameters*/ struct timezones_s { tzinfo_t *tzinfos; int ntzinfos; }; void displayTimezones(rsconf_t *cnf); void sortTimezones(rsconf_t *cnf); void glblProcessTimezone(struct cnfobj *o); tzinfo_t *glblFindTimezone(rsconf_t *cnf, char *id); void freeTimezones(rsconf_t *cnf); #endif rsyslog-8.2512.0/runtime/PaxHeaders/rsconf.h0000644000000000000000000000013015103061376015657 xustar0030 mtime=1762419454.858381305 29 atime=1764930980.03967854 29 ctime=1764935923.14957606 rsyslog-8.2512.0/runtime/rsconf.h0000664000175000017500000003222215103061376015326 0ustar00rgerrger/* The rsconf object. It models a complete rsyslog configuration. * * Copyright 2011-2023 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_RSCONF_H #define INCLUDED_RSCONF_H #include "linkedlist.h" #include "queue.h" #include "lookup.h" #include "dynstats.h" #include "perctile_stats.h" #include "timezones.h" /* --- configuration objects (the plan is to have ALL upper layers in this file) --- */ #define REPORT_CHILD_PROCESS_EXITS_NONE 0 #define REPORT_CHILD_PROCESS_EXITS_ERRORS 1 #define REPORT_CHILD_PROCESS_EXITS_ALL 2 #ifndef DFLT_INT_MSGS_SEV_FILTER #define DFLT_INT_MSGS_SEV_FILTER 6 /* Warning level and more important */ #endif struct queuecnf_s { int iMainMsgQueueSize; /* size of the main message queue above */ int iMainMsgQHighWtrMark; /* high water mark for disk-assisted queues */ int iMainMsgQLowWtrMark; /* low water mark for disk-assisted queues */ int iMainMsgQDiscardMark; /* begin to discard messages */ int iMainMsgQDiscardSeverity; /* by default, discard nothing to prevent unintentional loss */ int iMainMsgQueueNumWorkers; /* number of worker threads for the mm queue above */ queueType_t MainMsgQueType; /* type of the main message queue above */ uchar *pszMainMsgQFName; /* prefix for the main message queue file */ int64 iMainMsgQueMaxFileSize; int iMainMsgQPersistUpdCnt; /* persist queue info every n updates */ int bMainMsgQSyncQeueFiles; /* sync queue files on every write? */ int iMainMsgQtoQShutdown; /* queue shutdown (ms) */ int iMainMsgQtoActShutdown; /* action shutdown (in phase 2) */ int iMainMsgQtoEnq; /* timeout for queue enque */ int iMainMsgQtoWrkShutdown; /* timeout for worker thread shutdown */ int iMainMsgQWrkMinMsgs; /* minimum messages per worker needed to start a new one */ int iMainMsgQDeqSlowdown; /* dequeue slowdown (simple rate limiting) */ int64 iMainMsgQueMaxDiskSpace; /* max disk space allocated 0 ==> unlimited */ int64 iMainMsgQueDeqBatchSize; /* dequeue batch size */ int bMainMsgQSaveOnShutdown; /* save queue on shutdown (when DA enabled)? */ int iMainMsgQueueDeqtWinFromHr; /* hour begin of time frame when queue is to be dequeued */ int iMainMsgQueueDeqtWinToHr; /* hour begin of time frame when queue is to be dequeued */ }; /* parser config parameters */ struct parsercnf_s { uchar cCCEscapeChar; /* character to be used to start an escape sequence for control chars */ int bDropTrailingLF; /* drop trailing LF's on reception? */ int bEscapeCCOnRcv; /* escape control characters on reception: 0 - no, 1 - yes */ int bSpaceLFOnRcv; /* replace newlines with spaces on reception: 0 - no, 1 - yes */ int bEscape8BitChars; /* escape characters > 127 on reception: 0 - no, 1 - yes */ int bEscapeTab; /* escape tab control character when doing CC escapes: 0 - no, 1 - yes */ int bParserEscapeCCCStyle; /* escape control characters in c style: 0 - no, 1 - yes */ int bPermitSlashInProgramname; int bParseHOSTNAMEandTAG; /* parser modification (based on startup params!) */ }; /* globals are data items that are really global, and can be set only * once (at least in theory, because the legacy system permits them to * be re-set as often as the user likes). */ struct globals_s { #ifdef ENABLE_LIBCAPNG int bAbortOnFailedLibcapngSetup; int bCapabilityDropEnabled; #endif int bDebugPrintTemplateList; int bDebugPrintModuleList; int bDebugPrintCfSysLineHandlerList; int bLogStatusMsgs; /* log rsyslog start/stop/HUP messages? */ int bAllMsgToStderr; /* print all internal messages to stderr */ int bErrMsgToStderr; /* print error messages to stderr (in addition to everything else)? */ int maxErrMsgToStderr; /* how many messages to forward at most to stderr? */ int bAbortOnUncleanConfig; /* abort run (rather than starting with partial config) if there was any issue in conf */ int bAbortOnFailedQueueStartup; /* similar to bAbortOnUncleanConfig, but abort if a queue startup fails. This is not exactly an unclan config. */ int uidDropPriv; /* user-id to which priveleges should be dropped to */ int gidDropPriv; /* group-id to which priveleges should be dropped to */ int gidDropPrivKeepSupplemental; /* keep supplemental groups when dropping? */ int abortOnIDResolutionFail; int umask; /* umask to use */ uchar *pszConfDAGFile; /* name of config DAG file, non-NULL means generate one */ uchar *pszWorkDir; int bDropMalPTRMsgs; /* Drop messages which have malicious PTR records during DNS lookup */ uchar *operatingStateFile; int debugOnShutdown; /* start debug log when we are shut down */ int iGnuTLSLoglevel; /* Sets GNUTLS Debug Level */ uchar *pszDfltNetstrmDrvrCAF; /* default CA file for the netstrm driver */ uchar *pszDfltNetstrmDrvrCRLF; /* default CRL file for the netstrm driver */ uchar *pszDfltNetstrmDrvrCertFile; /* default cert file for the netstrm driver (server) */ uchar *pszDfltNetstrmDrvrKeyFile; /* default key file for the netstrm driver (server) */ uchar *pszDfltNetstrmDrvr; /* module name of default netstream driver */ uchar *pszNetstrmDrvrCAExtraFiles; /* CA extra file for the netstrm driver */ uchar *pszDfltOpensslEngine; /* custom openssl engine */ uchar *oversizeMsgErrorFile; /* File where oversize messages are written to */ int reportOversizeMsg; /* shall error messages be generated for oversize messages? */ int oversizeMsgInputMode; /* Mode which oversize messages will be forwarded */ int reportChildProcessExits; int bActionReportSuspension; int bActionReportSuspensionCont; short janitorInterval; /* interval (in minutes) at which the janitor runs */ int reportNewSenders; int reportGoneAwaySenders; int senderStatsTimeout; int senderKeepTrack; /* keep track of known senders? */ int inputTimeoutShutdown; /* input shutdown timeout in ms */ int iDefPFFamily; /* protocol family (IPv4, IPv6 or both) */ int ACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */ int ACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */ int bDisableDNS; /* don't look up IP addresses of remote messages */ int bProcessInternalMessages; /* Should rsyslog itself process internal messages? * 1 - yes * 0 - send them to libstdlog (e.g. to push to journal) or syslog() */ uint64_t glblDevOptions; /* to be used by developers only */ int intMsgRateLimitItv; int intMsgRateLimitBurst; int intMsgsSeverityFilter; /* filter for logging internal messages by syslog sev. */ int permitCtlC; int actq_dflt_toQShutdown; /* queue shutdown */ int actq_dflt_toActShutdown; /* action shutdown (in phase 2) */ int actq_dflt_toEnq; /* timeout for queue enque */ int actq_dflt_toWrkShutdown; /* timeout for worker thread shutdown */ int ruleset_dflt_toQShutdown; /* queue shutdown */ int ruleset_dflt_toActShutdown; /* action shutdown (in phase 2) */ int ruleset_dflt_toEnq; /* timeout for queue enque */ int ruleset_dflt_toWrkShutdown; /* timeout for worker thread shutdown */ unsigned dnscacheDefaultTTL; /* 24 hrs default TTL */ int dnscacheEnableTTL; /* expire entries or not (0) ? */ int shutdownQueueDoubleSize; int optionDisallowWarning; /* complain if message from disallowed sender is received */ int bSupportCompressionExtension; #ifdef ENABLE_LIBLOGGING_STDLOG stdlog_channel_t stdlog_hdl; /* handle to be used for stdlog */ uchar *stdlog_chanspec; #endif int iMaxLine; /* maximum length of a syslog message */ // TODO are the following ones defaults? int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ // TODO: other representation for main queue? Or just load it differently? queuecnf_t mainQ; /* main queue parameters */ parsercnf_t parser; /* parser parameters */ }; /* (global) defaults are global in the sense that they are accessible * to all code, but they can change value and other objects (like * actions) actually copy the value a global had at the time the action * was defined. In that sense, a global default is just that, a default, * wich can (and will) be changed in the course of config file * processing. Once the config file has been processed, defaults * can be dropped. The current code does not do this for simplicity. * That is not a problem, because the defaults do not take up much memory. * At a later stage, we may think about dropping them. -- rgerhards, 2011-04-19 */ struct defaults_s { int remove_me_when_first_real_member_is_added; }; /* list of modules loaded in this configuration (config specific module list) */ struct cfgmodules_etry_s { cfgmodules_etry_t *next; modInfo_t *pMod; void *modCnf; /* pointer to the input module conf */ /* the following data is input module specific */ sbool canActivate; /* OK to activate this config? */ sbool canRun; /* OK to run this config? */ }; struct cfgmodules_s { cfgmodules_etry_t *root; }; /* outchannel-specific data */ struct outchannels_s { struct outchannel *ochRoot; /* the root of the outchannel list */ struct outchannel *ochLast; /* points to the last element of the outchannel list */ }; struct templates_s { struct template *root; /* the root of the template list */ struct template *last; /* points to the last element of the template list */ struct template *lastStatic; /* last static element of the template list */ }; struct parsers_s { /* This is the list of all parsers known to us. * This is also used to unload all modules on shutdown. */ parserList_t *pParsLstRoot; /* this is the list of the default parsers, to be used if no others * are specified. */ parserList_t *pDfltParsLst; }; struct actions_s { /* number of active actions */ unsigned nbrActions; /* number of actions created. It is used to obtain unique IDs for the action. They * should not be relied on for any long-term activity (e.g. disk queue names!), but they are nice * to have during one instance of an rsyslogd run. For example, I use them to name actions when there * is no better name available. */ int iActionNbr; }; struct rulesets_s { linkedList_t llRulesets; /* this is NOT a pointer - no typo here ;) */ /* support for legacy rsyslog.conf format */ ruleset_t *pCurr; /* currently "active" ruleset */ ruleset_t *pDflt; /* current default ruleset, e.g. for binding to actions which have no other */ }; /* --- end configuration objects --- */ /* the rsconf object */ struct rsconf_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ cfgmodules_t modules; globals_t globals; defaults_t defaults; templates_t templates; parsers_t parsers; lookup_tables_t lu_tabs; dynstats_buckets_t dynstats_buckets; perctile_buckets_t perctile_buckets; outchannels_t och; actions_t actions; rulesets_t rulesets; /* note: rulesets include the complete output part: * - rules * - filter (as part of the action) * - actions * Of course, we need to debate if we shall change that some time... */ timezones_t timezones; qqueue_t *pMsgQueue; /* the main message queue */ }; /* interfaces */ BEGINinterface(rsconf) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(rsconf); rsRetVal (*Destruct)(rsconf_t **ppThis); rsRetVal (*Load)(rsconf_t **ppThis, uchar *confFile); rsRetVal (*Activate)(rsconf_t *ppThis); ENDinterface(rsconf) // TODO: switch version to 1 for first "complete" version!!!! 2011-04-20 #define rsconfCURR_IF_VERSION 0 /* increment whenever you change the interface above! */ /* prototypes */ PROTOTYPEObj(rsconf); /* globally-visible external data */ extern rsconf_t *runConf; /* the currently running config */ extern rsconf_t *loadConf; /* the config currently being loaded (no concurrent config load supported!) */ int rsconfNeedDropPriv(rsconf_t *const cnf); /* some defaults (to be removed?) */ #define DFLT_bLogStatusMsgs 1 #endif /* #ifndef INCLUDED_RSCONF_H */ rsyslog-8.2512.0/runtime/PaxHeaders/glbl.c0000644000000000000000000000013015114522477015306 xustar0030 mtime=1764926783.039631956 30 atime=1764926784.238661387 28 ctime=1764935923.1325758 rsyslog-8.2512.0/runtime/glbl.c0000664000175000017500000017411615114522477014766 0ustar00rgerrger/* glbl.c - this module holds global defintions and data items. * These are shared among the runtime library. Their use should be * limited to cases where it is actually needed. The main intension for * implementing them was support for the transistion from v2 to v4 * (with fully modular design), but it turned out that there may also * be some other good use cases besides backwards-compatibility. * * Module begun 2008-04-16 by Rainer Gerhards * * Copyright 2008-2024 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "obj.h" #include "unicode-helper.h" #include "cfsysline.h" #include "glbl.h" #include "prop.h" #include "atomic.h" #include "errmsg.h" #include "action.h" #include "parserif.h" #include "rainerscript.h" #include "srUtils.h" #include "operatingstate.h" #include "net.h" #include "rsconf.h" #include "queue.h" #include "dnscache.h" #include "parser.h" #include "timezones.h" /* some defaults */ #ifndef DFLT_NETSTRM_DRVR #define DFLT_NETSTRM_DRVR ((uchar *)"ptcp") #endif /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(prop) DEFobjCurrIf(net) /* static data * For this object, these variables are obviously what makes the "meat" of the * class... */ static struct cnfobj *mainqCnfObj = NULL; /* main queue object, to be used later in startup sequence */ static int bPreserveFQDN = 0; /* should FQDNs always be preserved? */ static prop_t *propLocalIPIF = NULL; /* IP address to report for the local host (default is 127.0.0.1) */ static int propLocalIPIF_set = 0; /* is propLocalIPIF already set? */ static prop_t *propLocalHostName = NULL; /* our hostname as FQDN - read-only after startup */ static prop_t *propLocalHostNameToDelete = NULL; /* see GenerateLocalHostName function hdr comment! */ static uchar *LocalHostName = NULL; /* our hostname - read-only after startup, except HUP */ static uchar *LocalHostNameOverride = NULL; /* user-overridden hostname - read-only after startup */ static uchar *LocalFQDNName = NULL; /* our hostname as FQDN - read-only after startup, except HUP */ static uchar *LocalDomain = NULL; /* our local domain name - read-only after startup, except HUP */ static int iMaxLine = 8096; int bTerminateInputs = 0; /* global switch that inputs shall terminate ASAP (1=> terminate) */ int glblUnloadModules = 1; int glblAbortOnProgramError = 0; char **glblDbgFiles = NULL; size_t glblDbgFilesNum = 0; int glblDbgWhitelist = 1; int glblPermitCtlC = 0; /* For global option CompactJsonString: * Compact the JSON variable string, without extra space. * Considering compatibility issues, the default options(CompactJsonString = "off") * keep the same as before. */ int glblJsonFormatOpt = JSON_C_TO_STRING_SPACED; pid_t glbl_ourpid; #ifndef HAVE_ATOMIC_BUILTINS DEF_ATOMIC_HELPER_MUT(mutTerminateInputs); #endif #ifdef USE_UNLIMITED_SELECT static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof(fd_mask); /* size of select() bitmask in bytes */ #endif static uchar *SourceIPofLocalClient = NULL; /* [ar] Source IP for local client to be used on multihomed host */ /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfparamdescr[] = { {"workdirectory", eCmdHdlrString, 0}, {"operatingstatefile", eCmdHdlrString, 0}, {"dropmsgswithmaliciousdnsptrrecords", eCmdHdlrBinary, 0}, {"localhostname", eCmdHdlrGetWord, 0}, {"compactjsonstring", eCmdHdlrBinary, 0}, {"preservefqdn", eCmdHdlrBinary, 0}, {"debug.onshutdown", eCmdHdlrBinary, 0}, {"debug.logfile", eCmdHdlrString, 0}, {"debug.gnutls", eCmdHdlrNonNegInt, 0}, {"debug.abortonprogramerror", eCmdHdlrBinary, 0}, {"debug.unloadmodules", eCmdHdlrBinary, 0}, {"defaultnetstreamdrivercafile", eCmdHdlrString, 0}, {"defaultnetstreamdrivercrlfile", eCmdHdlrString, 0}, {"defaultnetstreamdriverkeyfile", eCmdHdlrString, 0}, {"defaultnetstreamdrivercertfile", eCmdHdlrString, 0}, {"defaultnetstreamdriver", eCmdHdlrString, 0}, {"defaultopensslengine", eCmdHdlrString, 0}, {"netstreamdrivercaextrafiles", eCmdHdlrString, 0}, {"maxmessagesize", eCmdHdlrSize, 0}, {"oversizemsg.errorfile", eCmdHdlrGetWord, 0}, {"oversizemsg.report", eCmdHdlrBinary, 0}, {"oversizemsg.input.mode", eCmdHdlrGetWord, 0}, {"reportchildprocessexits", eCmdHdlrGetWord, 0}, {"action.reportsuspension", eCmdHdlrBinary, 0}, {"action.reportsuspensioncontinuation", eCmdHdlrBinary, 0}, {"parser.controlcharacterescapeprefix", eCmdHdlrGetChar, 0}, {"parser.droptrailinglfonreception", eCmdHdlrBinary, 0}, {"parser.escapecontrolcharactersonreceive", eCmdHdlrBinary, 0}, {"parser.spacelfonreceive", eCmdHdlrBinary, 0}, {"parser.escape8bitcharactersonreceive", eCmdHdlrBinary, 0}, {"parser.escapecontrolcharactertab", eCmdHdlrBinary, 0}, {"parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0}, {"parser.parsehostnameandtag", eCmdHdlrBinary, 0}, {"parser.permitslashinprogramname", eCmdHdlrBinary, 0}, {"stdlog.channelspec", eCmdHdlrString, 0}, {"janitor.interval", eCmdHdlrPositiveInt, 0}, {"senders.reportnew", eCmdHdlrBinary, 0}, {"senders.reportgoneaway", eCmdHdlrBinary, 0}, {"senders.timeoutafter", eCmdHdlrPositiveInt, 0}, {"senders.keeptrack", eCmdHdlrBinary, 0}, {"inputs.timeout.shutdown", eCmdHdlrPositiveInt, 0}, {"privdrop.group.keepsupplemental", eCmdHdlrBinary, 0}, {"privdrop.group.id", eCmdHdlrPositiveInt, 0}, {"privdrop.group.name", eCmdHdlrGID, 0}, {"privdrop.user.id", eCmdHdlrPositiveInt, 0}, {"privdrop.user.name", eCmdHdlrUID, 0}, {"net.ipprotocol", eCmdHdlrGetWord, 0}, {"net.acladdhostnameonfail", eCmdHdlrBinary, 0}, {"net.aclresolvehostname", eCmdHdlrBinary, 0}, {"net.enabledns", eCmdHdlrBinary, 0}, {"net.permitACLwarning", eCmdHdlrBinary, 0}, {"abortonuncleanconfig", eCmdHdlrBinary, 0}, {"abortonfailedqueuestartup", eCmdHdlrBinary, 0}, {"variables.casesensitive", eCmdHdlrBinary, 0}, {"environment", eCmdHdlrArray, 0}, {"processinternalmessages", eCmdHdlrBinary, 0}, {"umask", eCmdHdlrFileCreateMode, 0}, {"security.abortonidresolutionfail", eCmdHdlrBinary, 0}, {"internal.developeronly.options", eCmdHdlrInt, 0}, {"internalmsg.ratelimit.interval", eCmdHdlrPositiveInt, 0}, {"internalmsg.ratelimit.burst", eCmdHdlrPositiveInt, 0}, {"internalmsg.severity", eCmdHdlrSeverity, 0}, {"allmessagestostderr", eCmdHdlrBinary, 0}, {"errormessagestostderr.maxnumber", eCmdHdlrPositiveInt, 0}, {"shutdown.enable.ctlc", eCmdHdlrBinary, 0}, {"default.action.queue.timeoutshutdown", eCmdHdlrInt, 0}, {"default.action.queue.timeoutactioncompletion", eCmdHdlrInt, 0}, {"default.action.queue.timeoutenqueue", eCmdHdlrInt, 0}, {"default.action.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0}, {"default.ruleset.queue.timeoutshutdown", eCmdHdlrInt, 0}, {"default.ruleset.queue.timeoutactioncompletion", eCmdHdlrInt, 0}, {"default.ruleset.queue.timeoutenqueue", eCmdHdlrInt, 0}, {"default.ruleset.queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0}, {"reverselookup.cache.ttl.default", eCmdHdlrNonNegInt, 0}, {"reverselookup.cache.ttl.enable", eCmdHdlrBinary, 0}, {"parser.supportcompressionextension", eCmdHdlrBinary, 0}, {"shutdown.queue.doublesize", eCmdHdlrBinary, 0}, {"debug.files", eCmdHdlrArray, 0}, {"debug.whitelist", eCmdHdlrBinary, 0}, {"libcapng.default", eCmdHdlrBinary, 0}, {"libcapng.enable", eCmdHdlrBinary, 0}, }; static struct cnfparamblk paramblk = {CNFPARAMBLK_VERSION, sizeof(cnfparamdescr) / sizeof(struct cnfparamdescr), cnfparamdescr}; static struct cnfparamvals *cnfparamvals = NULL; /* we need to support multiple calls into our param block, so we need * to persist the current settings. Note that this must be re-set * each time a new config load begins. This is a hint if we will * ever implement multi-config support, which is just an idea right now. */ int glblGetMaxLine(rsconf_t *cnf) { /* glblGetMaxLine might be invoked before our configuration exists */ return ((cnf != NULL) ? cnf->globals.iMaxLine : iMaxLine); } int GetGnuTLSLoglevel(rsconf_t *cnf) { return (cnf->globals.iGnuTLSLoglevel); } /* define a macro for the simple properties' set and get functions * (which are always the same). This is only suitable for pretty * simple cases which require neither checks nor memory allocation. */ #define SIMP_PROP(nameFunc, nameVar, dataType) \ SIMP_PROP_GET(nameFunc, nameVar, dataType) \ SIMP_PROP_SET(nameFunc, nameVar, dataType) #define SIMP_PROP_SET(nameFunc, nameVar, dataType) \ static rsRetVal Set##nameFunc(dataType newVal) { \ nameVar = newVal; \ return RS_RET_OK; \ } #define SIMP_PROP_GET(nameFunc, nameVar, dataType) \ static dataType Get##nameFunc(void) { \ return (nameVar); \ } SIMP_PROP(PreserveFQDN, bPreserveFQDN, int) SIMP_PROP(mainqCnfObj, mainqCnfObj, struct cnfobj *) #ifdef USE_UNLIMITED_SELECT SIMP_PROP(FdSetSize, iFdSetSize, int) #endif #undef SIMP_PROP #undef SIMP_PROP_SET #undef SIMP_PROP_GET /* This is based on the previous SIMP_PROP but as a getter it uses * additional parameter specifying the configuration it belongs to. * The setter uses loadConf */ #define SIMP_PROP(nameFunc, nameVar, dataType) \ SIMP_PROP_GET(nameFunc, nameVar, dataType) \ SIMP_PROP_SET(nameFunc, nameVar, dataType) #define SIMP_PROP_SET(nameFunc, nameVar, dataType) \ static rsRetVal Set##nameFunc(dataType newVal) { \ loadConf->globals.nameVar = newVal; \ return RS_RET_OK; \ } #define SIMP_PROP_GET(nameFunc, nameVar, dataType) \ static dataType Get##nameFunc(rsconf_t *cnf) { \ return (cnf->globals.nameVar); \ } SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int) SIMP_PROP(DisableDNS, bDisableDNS, int) SIMP_PROP(ParserEscapeControlCharactersCStyle, parser.bParserEscapeCCCStyle, int) SIMP_PROP(ParseHOSTNAMEandTAG, parser.bParseHOSTNAMEandTAG, int) SIMP_PROP(OptionDisallowWarning, optionDisallowWarning, int) /* We omit setter on purpose, because we want to customize it */ SIMP_PROP_GET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar *) SIMP_PROP_GET(DfltNetstrmDrvrCRLF, pszDfltNetstrmDrvrCRLF, uchar *) SIMP_PROP_GET(DfltNetstrmDrvrCertFile, pszDfltNetstrmDrvrCertFile, uchar *) SIMP_PROP_GET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar *) SIMP_PROP_GET(NetstrmDrvrCAExtraFiles, pszNetstrmDrvrCAExtraFiles, uchar *) SIMP_PROP_GET(ParserControlCharacterEscapePrefix, parser.cCCEscapeChar, uchar) SIMP_PROP_GET(ParserDropTrailingLFOnReception, parser.bDropTrailingLF, int) SIMP_PROP_GET(ParserEscapeControlCharactersOnReceive, parser.bEscapeCCOnRcv, int) SIMP_PROP_GET(ParserSpaceLFOnReceive, parser.bSpaceLFOnRcv, int) SIMP_PROP_GET(ParserEscape8BitCharactersOnReceive, parser.bEscape8BitChars, int) SIMP_PROP_GET(ParserEscapeControlCharacterTab, parser.bEscapeTab, int) #undef SIMP_PROP #undef SIMP_PROP_SET #undef SIMP_PROP_GET /* return global input termination status * rgerhards, 2009-07-20 */ static int GetGlobalInputTermState(void) { return ATOMIC_FETCH_32BIT(&bTerminateInputs, &mutTerminateInputs); } /* set global termination state to "terminate". Note that this is a * "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20 */ static void SetGlobalInputTermination(void) { ATOMIC_STORE_1_TO_INT(&bTerminateInputs, &mutTerminateInputs); } /* set the local host IP address to a specific string. Helper to * small set of functions. No checks done, caller must ensure it is * ok to call. Most importantly, the IP address must not already have * been set. -- rgerhards, 2012-03-21 */ static rsRetVal storeLocalHostIPIF(uchar *myIP) { DEFiRet; if (propLocalIPIF != NULL) { CHKiRet(prop.Destruct(&propLocalIPIF)); } CHKiRet(prop.Construct(&propLocalIPIF)); CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP))); CHKiRet(prop.ConstructFinalize(propLocalIPIF)); DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP); finalize_it: RETiRet; } /* This function is used to set the IP address that is to be * reported for the local host. Note that in order to ease things * for the v6 config interface, we do not allow this to be set more * than once. * rgerhards, 2012-03-21 */ static rsRetVal setLocalHostIPIF(void __attribute__((unused)) * pVal, uchar *pNewVal) { uchar myIP[128]; rsRetVal localRet; DEFiRet; CHKiRet(objUse(net, CORE_COMPONENT)); if (propLocalIPIF_set) { LogError(0, RS_RET_ERR, "$LocalHostIPIF is already set " "and cannot be reset; place it at TOP OF rsyslog.conf!"); ABORT_FINALIZE(RS_RET_ERR); } localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int)sizeof(myIP)); if (localRet != RS_RET_OK) { LogError(0, RS_RET_ERR, "$LocalHostIPIF: IP address for interface " "'%s' cannnot be obtained - ignoring directive", pNewVal); } else { storeLocalHostIPIF(myIP); } finalize_it: free(pNewVal); /* no longer needed -> is in prop! */ RETiRet; } /* This function is used to set the global work directory name. * It verifies that the provided directory actually exists and * emits an error message if not. * rgerhards, 2011-02-16 */ static rsRetVal setWorkDir(void __attribute__((unused)) * pVal, uchar *pNewVal) { size_t lenDir; int i; struct stat sb; DEFiRet; /* remove trailing slashes */ lenDir = ustrlen(pNewVal); i = lenDir - 1; while (i > 0 && pNewVal[i] == '/') { --i; } if (i < 0) { LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: empty value " "- directive ignored"); ABORT_FINALIZE(RS_RET_ERR_WRKDIR); } if (i != (int)lenDir - 1) { pNewVal[i + 1] = '\0'; LogError(0, RS_RET_WRN_WRKDIR, "$WorkDirectory: trailing slashes " "removed, new value is '%s'", pNewVal); } if (stat((char *)pNewVal, &sb) != 0) { LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s can not be " "accessed, probably does not exist - directive ignored", pNewVal); ABORT_FINALIZE(RS_RET_ERR_WRKDIR); } if (!S_ISDIR(sb.st_mode)) { LogError(0, RS_RET_ERR_WRKDIR, "$WorkDirectory: %s not a directory - directive ignored", pNewVal); ABORT_FINALIZE(RS_RET_ERR_WRKDIR); } free(loadConf->globals.pszWorkDir); loadConf->globals.pszWorkDir = pNewVal; finalize_it: RETiRet; } static rsRetVal setDfltNetstrmDrvrCAF(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; FILE *fp; free(loadConf->globals.pszDfltNetstrmDrvrCAF); loadConf->globals.pszDfltNetstrmDrvrCAF = pNewVal; fp = fopen((const char *)pNewVal, "r"); if (fp == NULL) { LogError(errno, RS_RET_NO_FILE_ACCESS, "error: defaultnetstreamdrivercafile file '%s' " "could not be accessed", pNewVal); } else { fclose(fp); } RETiRet; } static rsRetVal setNetstrmDrvrCAExtraFiles(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; FILE *fp; char *token; char *saveptr; int error = 0; char *valCopy = NULL; free(loadConf->globals.pszNetstrmDrvrCAExtraFiles); /* Validate files without modifying the original comma-separated string */ if (pNewVal != NULL) { valCopy = strdup((const char *)pNewVal); if (valCopy == NULL) { LogError(errno, RS_RET_OUT_OF_MEMORY, "error: strdup failed in setNetstrmDrvrCAExtraFiles"); free(pNewVal); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } for (token = strtok_r(valCopy, ",", &saveptr); token != NULL; token = strtok_r(NULL, ",", &saveptr)) { while (isspace((unsigned char)*token)) { token++; } char *end = token + strlen(token) - 1; while (end > token && isspace((unsigned char)*end)) { end--; } *(end + 1) = '\0'; if (*token == '\0') { continue; } fp = fopen((const char *)token, "r"); if (fp == NULL) { LogError(errno, RS_RET_NO_FILE_ACCESS, "error: netstreamdrivercaextrafiles file '%s' " "could not be accessed", token); error = 1; } else { fclose(fp); } } } if (!error) { loadConf->globals.pszNetstrmDrvrCAExtraFiles = pNewVal; } else { /* Validation failed: prevent leak of newly allocated pNewVal */ free(pNewVal); loadConf->globals.pszNetstrmDrvrCAExtraFiles = NULL; } finalize_it: if (valCopy != NULL) { free(valCopy); } RETiRet; } static rsRetVal setDfltNetstrmDrvrCRLF(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; FILE *fp; free(loadConf->globals.pszDfltNetstrmDrvrCRLF); loadConf->globals.pszDfltNetstrmDrvrCRLF = pNewVal; fp = fopen((const char *)pNewVal, "r"); if (fp == NULL) { LogError(errno, RS_RET_NO_FILE_ACCESS, "error: defaultnetstreamdrivercrlfile file '%s' " "could not be accessed", pNewVal); } else { fclose(fp); } RETiRet; } static rsRetVal setDfltNetstrmDrvrCertFile(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; FILE *fp; free(loadConf->globals.pszDfltNetstrmDrvrCertFile); loadConf->globals.pszDfltNetstrmDrvrCertFile = pNewVal; fp = fopen((const char *)pNewVal, "r"); if (fp == NULL) { LogError(errno, RS_RET_NO_FILE_ACCESS, "error: defaultnetstreamdrivercertfile '%s' " "could not be accessed", pNewVal); } else { fclose(fp); } RETiRet; } static rsRetVal setDfltNetstrmDrvrKeyFile(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; FILE *fp; free(loadConf->globals.pszDfltNetstrmDrvrKeyFile); loadConf->globals.pszDfltNetstrmDrvrKeyFile = pNewVal; fp = fopen((const char *)pNewVal, "r"); if (fp == NULL) { LogError(errno, RS_RET_NO_FILE_ACCESS, "error: defaultnetstreamdriverkeyfile '%s' " "could not be accessed", pNewVal); } else { fclose(fp); } RETiRet; } static rsRetVal setDfltNetstrmDrvr(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; free(loadConf->globals.pszDfltNetstrmDrvr); loadConf->globals.pszDfltNetstrmDrvr = pNewVal; RETiRet; } static rsRetVal setDfltOpensslEngine(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; free(loadConf->globals.pszDfltOpensslEngine); loadConf->globals.pszDfltOpensslEngine = pNewVal; RETiRet; } static rsRetVal setParserControlCharacterEscapePrefix(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; loadConf->globals.parser.cCCEscapeChar = *pNewVal; RETiRet; } static rsRetVal setParserDropTrailingLFOnReception(void __attribute__((unused)) * pVal, int pNewVal) { DEFiRet; loadConf->globals.parser.bDropTrailingLF = pNewVal; RETiRet; } static rsRetVal setParserEscapeControlCharactersOnReceive(void __attribute__((unused)) * pVal, int pNewVal) { DEFiRet; loadConf->globals.parser.bEscapeCCOnRcv = pNewVal; RETiRet; } static rsRetVal setParserSpaceLFOnReceive(void __attribute__((unused)) * pVal, int pNewVal) { DEFiRet; loadConf->globals.parser.bSpaceLFOnRcv = pNewVal; RETiRet; } static rsRetVal setParserEscape8BitCharactersOnReceive(void __attribute__((unused)) * pVal, int pNewVal) { DEFiRet; loadConf->globals.parser.bEscape8BitChars = pNewVal; RETiRet; } static rsRetVal setParserEscapeControlCharacterTab(void __attribute__((unused)) * pVal, int pNewVal) { DEFiRet; loadConf->globals.parser.bEscapeTab = pNewVal; RETiRet; } /* This function is used both by legacy and RainerScript conf. It is a real setter. */ static void setMaxLine(const int64_t iNew) { if (iNew < 128) { LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize tried to set " "to %lld, but cannot be less than 128 - set to 128 " "instead", (long long)iNew); loadConf->globals.iMaxLine = 128; } else if (iNew > (int64_t)INT_MAX) { LogError(0, RS_RET_INVALID_VALUE, "maxMessageSize larger than " "INT_MAX (%d) - reduced to INT_MAX", INT_MAX); loadConf->globals.iMaxLine = INT_MAX; } else { loadConf->globals.iMaxLine = (int)iNew; } } static rsRetVal legacySetMaxMessageSize(void __attribute__((unused)) * pVal, int64_t iNew) { setMaxLine(iNew); return RS_RET_OK; } static rsRetVal setDebugFile(void __attribute__((unused)) * pVal, uchar *pNewVal) { DEFiRet; dbgSetDebugFile(pNewVal); free(pNewVal); RETiRet; } static rsRetVal setDebugLevel(void __attribute__((unused)) * pVal, int level) { DEFiRet; dbgSetDebugLevel(level); dbgprintf("debug level %d set via config file\n", level); dbgprintf("This is rsyslog version " VERSION "\n"); RETiRet; } static rsRetVal ATTR_NONNULL() setOversizeMsgInputMode(const uchar *const mode) { DEFiRet; if (!strcmp((char *)mode, "truncate")) { loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate; } else if (!strcmp((char *)mode, "split")) { loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Split; } else if (!strcmp((char *)mode, "accept")) { loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Accept; } else { loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Truncate; } RETiRet; } static rsRetVal ATTR_NONNULL() setReportChildProcessExits(const uchar *const mode) { DEFiRet; if (!strcmp((char *)mode, "none")) { loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_NONE; } else if (!strcmp((char *)mode, "errors")) { loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS; } else if (!strcmp((char *)mode, "all")) { loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ALL; } else { LogError(0, RS_RET_CONF_PARAM_INVLD, "invalid value '%s' for global parameter reportChildProcessExits -- ignored", mode); iRet = RS_RET_CONF_PARAM_INVLD; } RETiRet; } static int getDefPFFamily(rsconf_t *cnf) { return cnf->globals.iDefPFFamily; } /* return our local IP. * If no local IP is set, "127.0.0.1" is selected *and* set. This * is an intensional side effect that we do in order to keep things * consistent and avoid config errors (this will make us not accept * setting the local IP address once a module has obtained it - so * it forces the $LocalHostIPIF directive high up in rsyslog.conf) * rgerhards, 2012-03-21 */ static prop_t *GetLocalHostIP(void) { assert(propLocalIPIF != NULL); return (propLocalIPIF); } /* set our local hostname. Free previous hostname, if it was already set. * Note that we do now do this in a thread. As such, the method here * is NOT 100% clean. If we run into issues, we need to think about * refactoring the whole way we handle the local host name processing. * Possibly using a PROP might be the right solution then. */ static rsRetVal SetLocalHostName(uchar *const newname) { uchar *toFree; if (LocalHostName == NULL || strcmp((const char *)LocalHostName, (const char *)newname)) { toFree = LocalHostName; LocalHostName = newname; } else { toFree = newname; } free(toFree); return RS_RET_OK; } /* return our local hostname. if it is not set, "[localhost]" is returned */ uchar *glblGetLocalHostName(void) { uchar *pszRet; if (LocalHostNameOverride != NULL) { pszRet = LocalHostNameOverride; goto done; } if (LocalHostName == NULL) pszRet = (uchar *)"[localhost]"; else { if (GetPreserveFQDN() == 1) pszRet = LocalFQDNName; else pszRet = LocalHostName; } done: return (pszRet); } /* return the name of the file where oversize messages are written to */ uchar *glblGetOversizeMsgErrorFile(rsconf_t *cnf) { return cnf->globals.oversizeMsgErrorFile; } const uchar *glblGetOperatingStateFile(rsconf_t *cnf) { return cnf->globals.operatingStateFile; } /* return the mode with which oversize messages will be put forward */ int glblGetOversizeMsgInputMode(rsconf_t *cnf) { return cnf->globals.oversizeMsgInputMode; } int glblReportOversizeMessage(rsconf_t *cnf) { return cnf->globals.reportOversizeMsg; } /* logs a message indicating that a child process has terminated. * If name != NULL, prints it as the program name. */ void glblReportChildProcessExit(rsconf_t *cnf, const uchar *name, pid_t pid, int status) { DBGPRINTF("waitpid for child %ld returned status: %2.2x\n", (long)pid, status); if (cnf->globals.reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_NONE || (cnf->globals.reportChildProcessExits == REPORT_CHILD_PROCESS_EXITS_ERRORS && WIFEXITED(status) && WEXITSTATUS(status) == 0)) { return; } if (WIFEXITED(status)) { int severity = WEXITSTATUS(status) == 0 ? LOG_INFO : LOG_WARNING; if (name != NULL) { LogMsg(0, NO_ERRCODE, severity, "program '%s' (pid %ld) exited with status %d", name, (long)pid, WEXITSTATUS(status)); } else { LogMsg(0, NO_ERRCODE, severity, "child process (pid %ld) exited with status %d", (long)pid, WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { if (name != NULL) { LogMsg(0, NO_ERRCODE, LOG_WARNING, "program '%s' (pid %ld) terminated by signal %d", name, (long)pid, WTERMSIG(status)); } else { LogMsg(0, NO_ERRCODE, LOG_WARNING, "child process (pid %ld) terminated by signal %d", (long)pid, WTERMSIG(status)); } } } /* set our local domain name. Free previous domain, if it was already set. */ static rsRetVal SetLocalDomain(uchar *newname) { free(LocalDomain); LocalDomain = newname; return RS_RET_OK; } /* return our local hostname. if it is not set, "[localhost]" is returned */ static uchar *GetLocalDomain(void) { return LocalDomain; } /* generate the local hostname property. This must be done after the hostname info * has been set as well as PreserveFQDN. * rgerhards, 2009-06-30 * NOTE: This function tries to avoid locking by not destructing the previous value * immediately. This is so that current readers can continue to use the previous name. * Otherwise, we would need to use read/write locks to protect the update process. * In order to do so, we save the previous value and delete it when we are called again * the next time. Note that this in theory is racy and can lead to a double-free. * In practice, however, the window of exposure to trigger this is extremely short * and as this functions is very infrequently being called (on HUP), the trigger * condition for this bug is so highly unlikely that it never occurs in practice. * Probably if you HUP rsyslog every few milliseconds, but who does that... * To further reduce risk potential, we do only update the property when there * actually is a hostname change, which makes it even less likely. * rgerhards, 2013-10-28 */ static rsRetVal GenerateLocalHostNameProperty(void) { uchar *pszPrev; int lenPrev; prop_t *hostnameNew; uchar *pszName; DEFiRet; if (propLocalHostNameToDelete != NULL) prop.Destruct(&propLocalHostNameToDelete); if (LocalHostNameOverride == NULL) { if (LocalHostName == NULL) pszName = (uchar *)"[localhost]"; else { if (GetPreserveFQDN() == 1) pszName = LocalFQDNName; else pszName = LocalHostName; } } else { /* local hostname is overriden via config */ pszName = LocalHostNameOverride; } DBGPRINTF("GenerateLocalHostName uses '%s'\n", pszName); if (propLocalHostName == NULL) pszPrev = (uchar *)""; /* make sure strcmp() below does not match */ else prop.GetString(propLocalHostName, &pszPrev, &lenPrev); if (ustrcmp(pszPrev, pszName)) { /* we need to update */ CHKiRet(prop.Construct(&hostnameNew)); CHKiRet(prop.SetString(hostnameNew, pszName, ustrlen(pszName))); CHKiRet(prop.ConstructFinalize(hostnameNew)); propLocalHostNameToDelete = propLocalHostName; propLocalHostName = hostnameNew; } finalize_it: RETiRet; } /* return our local hostname as a string property */ static prop_t *GetLocalHostNameProp(void) { return (propLocalHostName); } static rsRetVal SetLocalFQDNName(uchar *newname) { free(LocalFQDNName); LocalFQDNName = newname; return RS_RET_OK; } /* return the current localhost name as FQDN (requires FQDN to be set) */ static uchar *GetLocalFQDNName(void) { return (LocalFQDNName == NULL ? (uchar *)"[localhost]" : LocalFQDNName); } /* return the current working directory */ static uchar *GetWorkDir(rsconf_t *cnf) { return (cnf->globals.pszWorkDir == NULL ? (uchar *)"" : cnf->globals.pszWorkDir); } /* return the "raw" working directory, which means * NULL if unset. */ const uchar *glblGetWorkDirRaw(rsconf_t *cnf) { return cnf->globals.pszWorkDir; } /* return the current default netstream driver */ static uchar *GetDfltNetstrmDrvr(rsconf_t *cnf) { return (cnf->globals.pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : cnf->globals.pszDfltNetstrmDrvr); } /* return the current default openssl engine name */ static uchar *GetDfltOpensslEngine(rsconf_t *cnf) { return (cnf->globals.pszDfltOpensslEngine); } /* [ar] Source IP for local client to be used on multihomed host */ static rsRetVal SetSourceIPofLocalClient(uchar *newname) { if (SourceIPofLocalClient != NULL) { free(SourceIPofLocalClient); } SourceIPofLocalClient = newname; return RS_RET_OK; } static uchar *GetSourceIPofLocalClient(void) { return (SourceIPofLocalClient); } /* queryInterface function * rgerhards, 2008-02-21 */ BEGINobjQueryInterface(glbl) CODESTARTobjQueryInterface(glbl); if (pIf->ifVersion != glblCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->GetWorkDir = GetWorkDir; pIf->GenerateLocalHostNameProperty = GenerateLocalHostNameProperty; pIf->GetLocalHostNameProp = GetLocalHostNameProp; pIf->GetLocalHostIP = GetLocalHostIP; pIf->SetGlobalInputTermination = SetGlobalInputTermination; pIf->GetGlobalInputTermState = GetGlobalInputTermState; pIf->GetSourceIPofLocalClient = GetSourceIPofLocalClient; /* [ar] */ pIf->SetSourceIPofLocalClient = SetSourceIPofLocalClient; /* [ar] */ pIf->GetDefPFFamily = getDefPFFamily; pIf->GetDisableDNS = GetDisableDNS; pIf->GetMaxLine = glblGetMaxLine; pIf->GetOptionDisallowWarning = GetOptionDisallowWarning; pIf->GetDfltNetstrmDrvrCAF = GetDfltNetstrmDrvrCAF; pIf->GetDfltNetstrmDrvrCRLF = GetDfltNetstrmDrvrCRLF; pIf->GetDfltNetstrmDrvrCertFile = GetDfltNetstrmDrvrCertFile; pIf->GetDfltNetstrmDrvrKeyFile = GetDfltNetstrmDrvrKeyFile; pIf->GetDfltNetstrmDrvr = GetDfltNetstrmDrvr; pIf->GetDfltOpensslEngine = GetDfltOpensslEngine; pIf->GetNetstrmDrvrCAExtraFiles = GetNetstrmDrvrCAExtraFiles; pIf->GetParserControlCharacterEscapePrefix = GetParserControlCharacterEscapePrefix; pIf->GetParserDropTrailingLFOnReception = GetParserDropTrailingLFOnReception; pIf->GetParserEscapeControlCharactersOnReceive = GetParserEscapeControlCharactersOnReceive; pIf->GetParserSpaceLFOnReceive = GetParserSpaceLFOnReceive; pIf->GetParserEscape8BitCharactersOnReceive = GetParserEscape8BitCharactersOnReceive; pIf->GetParserEscapeControlCharacterTab = GetParserEscapeControlCharacterTab; pIf->GetLocalHostName = glblGetLocalHostName; pIf->SetLocalHostName = SetLocalHostName; #define SIMP_PROP(name) \ pIf->Get##name = Get##name; \ pIf->Set##name = Set##name; SIMP_PROP(PreserveFQDN); SIMP_PROP(DropMalPTRMsgs); SIMP_PROP(mainqCnfObj); SIMP_PROP(LocalFQDNName) SIMP_PROP(LocalDomain) SIMP_PROP(ParserEscapeControlCharactersCStyle) SIMP_PROP(ParseHOSTNAMEandTAG) #ifdef USE_UNLIMITED_SELECT SIMP_PROP(FdSetSize) #endif #undef SIMP_PROP finalize_it: ENDobjQueryInterface(glbl) /* Reset config variables to default values. * rgerhards, 2008-04-17 */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { free(loadConf->globals.pszDfltNetstrmDrvr); loadConf->globals.pszDfltNetstrmDrvr = NULL; free(loadConf->globals.pszDfltNetstrmDrvrCAF); loadConf->globals.pszDfltNetstrmDrvrCAF = NULL; free(loadConf->globals.pszDfltNetstrmDrvrCRLF); loadConf->globals.pszDfltNetstrmDrvrCRLF = NULL; free(loadConf->globals.pszDfltNetstrmDrvrKeyFile); loadConf->globals.pszDfltNetstrmDrvrKeyFile = NULL; free(loadConf->globals.pszDfltNetstrmDrvrCertFile); loadConf->globals.pszDfltNetstrmDrvrCertFile = NULL; free(loadConf->globals.pszDfltOpensslEngine); loadConf->globals.pszDfltOpensslEngine = NULL; free(LocalHostNameOverride); LocalHostNameOverride = NULL; free(loadConf->globals.oversizeMsgErrorFile); loadConf->globals.oversizeMsgErrorFile = NULL; loadConf->globals.oversizeMsgInputMode = glblOversizeMsgInputMode_Accept; loadConf->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS; free(loadConf->globals.pszWorkDir); loadConf->globals.pszWorkDir = NULL; free((void *)loadConf->globals.operatingStateFile); loadConf->globals.operatingStateFile = NULL; loadConf->globals.bDropMalPTRMsgs = 0; bPreserveFQDN = 0; loadConf->globals.iMaxLine = 8192; loadConf->globals.reportOversizeMsg = 1; loadConf->globals.parser.cCCEscapeChar = '#'; loadConf->globals.parser.bDropTrailingLF = 1; loadConf->globals.parser.bEscapeCCOnRcv = 1; /* default is to escape control characters */ loadConf->globals.parser.bSpaceLFOnRcv = 0; loadConf->globals.parser.bEscape8BitChars = 0; /* default is not to escape control characters */ loadConf->globals.parser.bEscapeTab = 1; /* default is to escape tab characters */ loadConf->globals.parser.bParserEscapeCCCStyle = 0; #ifdef USE_UNLIMITED_SELECT iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof(fd_mask); #endif return RS_RET_OK; } /* Prepare for new config */ void glblPrepCnf(void) { free(mainqCnfObj); mainqCnfObj = NULL; free(cnfparamvals); cnfparamvals = NULL; } /* handle the timezone() object. Each incarnation adds one additional * zone info to the global table of time zones. */ int bs_arrcmp_glblDbgFiles(const void *s1, const void *s2) { return strcmp((char *)s1, *(char **)s2); } /* handle a global config object. Note that multiple global config statements * are permitted (because of plugin support), so once we got a param block, * we need to hold to it. * rgerhards, 2011-07-19 */ void glblProcessCnf(struct cnfobj *o) { int i; cnfparamvals = nvlstGetParams(o->nvlst, ¶mblk, cnfparamvals); if (cnfparamvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing global " "config parameters [global(...)]"); goto done; } if (Debug) { dbgprintf("glbl param blk after glblProcessCnf:\n"); cnfparamsPrint(¶mblk, cnfparamvals); } /* The next thing is a bit hackish and should be changed in higher * versions. There are a select few parameters which we need to * act on immediately. These are processed here. */ for (i = 0; i < paramblk.nParams; ++i) { if (!cnfparamvals[i].bUsed) continue; if (!strcmp(paramblk.descr[i].name, "processinternalmessages")) { loadConf->globals.bProcessInternalMessages = (int)cnfparamvals[i].val.d.n; cnfparamvals[i].bUsed = TRUE; } else if (!strcmp(paramblk.descr[i].name, "internal.developeronly.options")) { loadConf->globals.glblDevOptions = (uint64_t)cnfparamvals[i].val.d.n; cnfparamvals[i].bUsed = TRUE; } else if (!strcmp(paramblk.descr[i].name, "stdlog.channelspec")) { #ifndef ENABLE_LIBLOGGING_STDLOG LogError(0, RS_RET_ERR, "rsyslog wasn't " "compiled with liblogging-stdlog support. " "The 'stdlog.channelspec' parameter " "is ignored. Note: the syslog API is used instead.\n"); #else loadConf->globals.stdlog_chanspec = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); /* we need to re-open with the new channel */ stdlog_close(loadConf->globals.stdlog_hdl); loadConf->globals.stdlog_hdl = stdlog_open("rsyslogd", 0, STDLOG_SYSLOG, (char *)loadConf->globals.stdlog_chanspec); cnfparamvals[i].bUsed = TRUE; #endif } else if (!strcmp(paramblk.descr[i].name, "operatingstatefile")) { if (loadConf->globals.operatingStateFile != NULL) { LogError(errno, RS_RET_PARAM_ERROR, "error: operatingStateFile already set to '%s' - " "new value ignored", loadConf->globals.operatingStateFile); } else { loadConf->globals.operatingStateFile = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); osf_open(); } } else if (!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) { loadConf->globals.abortOnIDResolutionFail = (int)cnfparamvals[i].val.d.n; cnfparamvals[i].bUsed = TRUE; } } done: return; } /* Set mainq parameters. Note that when this is not called, we'll use the * legacy parameter config. mainq parameters can only be set once. */ void glblProcessMainQCnf(struct cnfobj *o) { if (mainqCnfObj == NULL) { mainqCnfObj = o; } else { LogError(0, RS_RET_ERR, "main_queue() object can only be specified " "once - all but first ignored\n"); } } /* destruct the main q cnf object after it is no longer needed. This is * also used to do some final checks. */ void glblDestructMainqCnfObj(void) { /* Only destruct if not NULL! */ if (mainqCnfObj != NULL) { nvlstChkUnused(mainqCnfObj->nvlst); cnfobjDestruct(mainqCnfObj); mainqCnfObj = NULL; } } static int qs_arrcmp_glblDbgFiles(const void *s1, const void *s2) { return strcmp(*((char **)s1), *((char **)s2)); } /* set an environment variable */ static rsRetVal do_setenv(const char *const var) { char varname[128]; const char *val = var; size_t i; DEFiRet; for (i = 0; *val != '='; ++i, ++val) { if (i == sizeof(varname) - i) { parser_errmsg( "environment variable name too long " "[max %zu chars] or malformed entry: '%s'", sizeof(varname) - 1, var); ABORT_FINALIZE(RS_RET_ERR_SETENV); } if (*val == '\0') { parser_errmsg( "environment variable entry is missing " "equal sign (for value): '%s'", var); ABORT_FINALIZE(RS_RET_ERR_SETENV); } varname[i] = *val; } varname[i] = '\0'; ++val; DBGPRINTF("do_setenv, var '%s', val '%s'\n", varname, val); if (setenv(varname, val, 1) != 0) { char errStr[1024]; rs_strerror_r(errno, errStr, sizeof(errStr)); parser_errmsg( "error setting environment variable " "'%s' to '%s': %s", varname, val, errStr); ABORT_FINALIZE(RS_RET_ERR_SETENV); } finalize_it: RETiRet; } /* This processes the "regular" parameters which are to be set after the * config has been fully loaded. */ rsRetVal glblDoneLoadCnf(void) { int i; unsigned char *cstr; DEFiRet; CHKiRet(objUse(net, CORE_COMPONENT)); sortTimezones(loadConf); DBGPRINTF("Timezone information table (%d entries):\n", loadConf->timezones.ntzinfos); displayTimezones(loadConf); if (cnfparamvals == NULL) goto finalize_it; for (i = 0; i < paramblk.nParams; ++i) { if (!cnfparamvals[i].bUsed) continue; if (!strcmp(paramblk.descr[i].name, "workdirectory")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setWorkDir(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "libcapng.default")) { #ifdef ENABLE_LIBCAPNG loadConf->globals.bAbortOnFailedLibcapngSetup = (int)cnfparamvals[i].val.d.n; #else LogError(0, RS_RET_ERR, "rsyslog wasn't " "compiled with libcap-ng support."); #endif } else if (!strcmp(paramblk.descr[i].name, "libcapng.enable")) { #ifdef ENABLE_LIBCAPNG loadConf->globals.bCapabilityDropEnabled = (int)cnfparamvals[i].val.d.n; #else LogError(0, RS_RET_ERR, "rsyslog wasn't " "compiled with libcap-ng support."); #endif } else if (!strcmp(paramblk.descr[i].name, "variables.casesensitive")) { const int val = (int)cnfparamvals[i].val.d.n; fjson_global_do_case_sensitive_comparison(val); DBGPRINTF("global/config: set case sensitive variables to %d\n", val); } else if (!strcmp(paramblk.descr[i].name, "localhostname")) { free(LocalHostNameOverride); LocalHostNameOverride = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); } else if (!strcmp(paramblk.descr[i].name, "defaultnetstreamdriverkeyfile")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltNetstrmDrvrKeyFile(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercertfile")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltNetstrmDrvrCertFile(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercafile")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltNetstrmDrvrCAF(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "defaultnetstreamdrivercrlfile")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltNetstrmDrvrCRLF(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "defaultnetstreamdriver")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltNetstrmDrvr(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "defaultopensslengine")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setDfltOpensslEngine(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "netstreamdrivercaextrafiles")) { cstr = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setNetstrmDrvrCAExtraFiles(NULL, cstr); } else if (!strcmp(paramblk.descr[i].name, "preservefqdn")) { bPreserveFQDN = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "compactjsonstring")) { glblJsonFormatOpt = cnfparamvals[i].val.d.n ? JSON_C_TO_STRING_PLAIN : JSON_C_TO_STRING_SPACED; } else if (!strcmp(paramblk.descr[i].name, "dropmsgswithmaliciousdnsptrrecords")) { loadConf->globals.bDropMalPTRMsgs = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "action.reportsuspension")) { loadConf->globals.bActionReportSuspension = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "action.reportsuspensioncontinuation")) { loadConf->globals.bActionReportSuspensionCont = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "maxmessagesize")) { setMaxLine(cnfparamvals[i].val.d.n); } else if (!strcmp(paramblk.descr[i].name, "oversizemsg.errorfile")) { free(loadConf->globals.oversizeMsgErrorFile); loadConf->globals.oversizeMsgErrorFile = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); } else if (!strcmp(paramblk.descr[i].name, "oversizemsg.report")) { loadConf->globals.reportOversizeMsg = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "oversizemsg.input.mode")) { const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setOversizeMsgInputMode((uchar *)tmp); free((void *)tmp); } else if (!strcmp(paramblk.descr[i].name, "reportchildprocessexits")) { const char *const tmp = es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setReportChildProcessExits((uchar *)tmp); free((void *)tmp); } else if (!strcmp(paramblk.descr[i].name, "debug.onshutdown")) { loadConf->globals.debugOnShutdown = (int)cnfparamvals[i].val.d.n; LogError(0, RS_RET_OK, "debug: onShutdown set to %d", loadConf->globals.debugOnShutdown); } else if (!strcmp(paramblk.descr[i].name, "debug.gnutls")) { loadConf->globals.iGnuTLSLoglevel = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "debug.abortonprogramerror")) { glblAbortOnProgramError = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "debug.unloadmodules")) { glblUnloadModules = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "parser.controlcharacterescapeprefix")) { uchar *tmp = (uchar *)es_str2cstr(cnfparamvals[i].val.d.estr, NULL); setParserControlCharacterEscapePrefix(NULL, tmp); free(tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.droptrailinglfonreception")) { const int tmp = (int)cnfparamvals[i].val.d.n; setParserDropTrailingLFOnReception(NULL, tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactersonreceive")) { const int tmp = (int)cnfparamvals[i].val.d.n; setParserEscapeControlCharactersOnReceive(NULL, tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.spacelfonreceive")) { const int tmp = (int)cnfparamvals[i].val.d.n; setParserSpaceLFOnReceive(NULL, tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.escape8bitcharactersonreceive")) { const int tmp = (int)cnfparamvals[i].val.d.n; setParserEscape8BitCharactersOnReceive(NULL, tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharactertab")) { const int tmp = (int)cnfparamvals[i].val.d.n; setParserEscapeControlCharacterTab(NULL, tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.escapecontrolcharacterscstyle")) { const int tmp = (int)cnfparamvals[i].val.d.n; SetParserEscapeControlCharactersCStyle(tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.parsehostnameandtag")) { const int tmp = (int)cnfparamvals[i].val.d.n; SetParseHOSTNAMEandTAG(tmp); } else if (!strcmp(paramblk.descr[i].name, "parser.permitslashinprogramname")) { loadConf->globals.parser.bPermitSlashInProgramname = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "debug.logfile")) { if (pszAltDbgFileName == NULL) { pszAltDbgFileName = es_str2cstr(cnfparamvals[i].val.d.estr, NULL); /* can actually happen if debug system also opened altdbg */ if (altdbg != -1) { close(altdbg); } if ((altdbg = open(pszAltDbgFileName, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { LogError(0, RS_RET_ERR, "debug log file '%s' could not be opened", pszAltDbgFileName); } } LogError(0, RS_RET_OK, "debug log file is '%s', fd %d", pszAltDbgFileName, altdbg); } else if (!strcmp(paramblk.descr[i].name, "janitor.interval")) { loadConf->globals.janitorInterval = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "net.ipprotocol")) { char *proto = es_str2cstr(cnfparamvals[i].val.d.estr, NULL); if (!strcmp(proto, "unspecified")) { loadConf->globals.iDefPFFamily = PF_UNSPEC; } else if (!strcmp(proto, "ipv4-only")) { loadConf->globals.iDefPFFamily = PF_INET; } else if (!strcmp(proto, "ipv6-only")) { loadConf->globals.iDefPFFamily = PF_INET6; } else { LogError(0, RS_RET_ERR, "invalid net.ipprotocol " "parameter '%s' -- ignored", proto); } free(proto); } else if (!strcmp(paramblk.descr[i].name, "senders.reportnew")) { loadConf->globals.reportNewSenders = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "senders.reportgoneaway")) { loadConf->globals.reportGoneAwaySenders = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "senders.timeoutafter")) { loadConf->globals.senderStatsTimeout = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "senders.keeptrack")) { loadConf->globals.senderKeepTrack = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "inputs.timeout.shutdown")) { loadConf->globals.inputTimeoutShutdown = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "privdrop.group.keepsupplemental")) { loadConf->globals.gidDropPrivKeepSupplemental = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "privdrop.group.id")) { loadConf->globals.gidDropPriv = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "privdrop.group.name")) { loadConf->globals.gidDropPriv = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "privdrop.user.id")) { loadConf->globals.uidDropPriv = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "privdrop.user.name")) { loadConf->globals.uidDropPriv = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "security.abortonidresolutionfail")) { loadConf->globals.abortOnIDResolutionFail = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "net.acladdhostnameonfail")) { loadConf->globals.ACLAddHostnameOnFail = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "net.aclresolvehostname")) { loadConf->globals.ACLDontResolve = !((int)cnfparamvals[i].val.d.n); } else if (!strcmp(paramblk.descr[i].name, "net.enabledns")) { SetDisableDNS(!((int)cnfparamvals[i].val.d.n)); } else if (!strcmp(paramblk.descr[i].name, "net.permitwarning")) { SetOptionDisallowWarning(!((int)cnfparamvals[i].val.d.n)); } else if (!strcmp(paramblk.descr[i].name, "abortonuncleanconfig")) { loadConf->globals.bAbortOnUncleanConfig = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "abortonfailedqueuestartup")) { loadConf->globals.bAbortOnFailedQueueStartup = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.burst")) { loadConf->globals.intMsgRateLimitBurst = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "internalmsg.ratelimit.interval")) { loadConf->globals.intMsgRateLimitItv = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "internalmsg.severity")) { loadConf->globals.intMsgsSeverityFilter = (int)cnfparamvals[i].val.d.n; if ((loadConf->globals.intMsgsSeverityFilter < 0) || (loadConf->globals.intMsgsSeverityFilter > 7)) { parser_errmsg("invalid internalmsg.severity value"); loadConf->globals.intMsgsSeverityFilter = DFLT_INT_MSGS_SEV_FILTER; } } else if (!strcmp(paramblk.descr[i].name, "environment")) { for (int j = 0; j < cnfparamvals[i].val.d.ar->nmemb; ++j) { char *const var = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL); do_setenv(var); free(var); } } else if (!strcmp(paramblk.descr[i].name, "errormessagestostderr.maxnumber")) { loadConf->globals.maxErrMsgToStderr = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "allmessagestostderr")) { loadConf->globals.bAllMsgToStderr = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "debug.files")) { free(glblDbgFiles); /* "fix" Coverity false positive */ glblDbgFilesNum = cnfparamvals[i].val.d.ar->nmemb; glblDbgFiles = (char **)malloc(cnfparamvals[i].val.d.ar->nmemb * sizeof(char *)); for (int j = 0; j < cnfparamvals[i].val.d.ar->nmemb; ++j) { glblDbgFiles[j] = es_str2cstr(cnfparamvals[i].val.d.ar->arr[j], NULL); } qsort(glblDbgFiles, glblDbgFilesNum, sizeof(char *), qs_arrcmp_glblDbgFiles); } else if (!strcmp(paramblk.descr[i].name, "debug.whitelist")) { glblDbgWhitelist = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "shutdown.queue.doublesize")) { loadConf->globals.shutdownQueueDoubleSize = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "umask")) { loadConf->globals.umask = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "shutdown.enable.ctlc")) { loadConf->globals.permitCtlC = (int)cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutshutdown")) { loadConf->globals.actq_dflt_toQShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutactioncompletion")) { loadConf->globals.actq_dflt_toActShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutenqueue")) { loadConf->globals.actq_dflt_toEnq = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.action.queue.timeoutworkerthreadshutdown")) { loadConf->globals.actq_dflt_toWrkShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutshutdown")) { loadConf->globals.ruleset_dflt_toQShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutactioncompletion")) { loadConf->globals.ruleset_dflt_toActShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutenqueue")) { loadConf->globals.ruleset_dflt_toEnq = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "default.ruleset.queue.timeoutworkerthreadshutdown")) { loadConf->globals.ruleset_dflt_toWrkShutdown = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.default")) { loadConf->globals.dnscacheDefaultTTL = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "reverselookup.cache.ttl.enable")) { loadConf->globals.dnscacheEnableTTL = cnfparamvals[i].val.d.n; } else if (!strcmp(paramblk.descr[i].name, "parser.supportcompressionextension")) { loadConf->globals.bSupportCompressionExtension = cnfparamvals[i].val.d.n; } else { dbgprintf( "glblDoneLoadCnf: program error, non-handled " "param '%s'\n", paramblk.descr[i].name); } } if (loadConf->globals.debugOnShutdown && Debug != DEBUG_FULL) { Debug = DEBUG_ONDEMAND; stddbg = -1; } finalize_it: /* we have now read the config. We need to query the local host name now * as it was set by the config. * * Note: early messages are already emited, and have "[localhost]" as * hostname. These messages are currently in iminternal queue. Once they * are taken from that queue, the hostname will be adapted. */ queryLocalHostname(loadConf); RETiRet; } /* Initialize the glbl class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(prop, CORE_COMPONENT)); /* initialize properties */ storeLocalHostIPIF((uchar *)"127.0.0.1"); /* config handlers are never unregistered and need not be - we are always loaded ;) */ CHKiRet(regCfSysLineHdlr((uchar *)"debugfile", 0, eCmdHdlrGetWord, setDebugFile, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debuglevel", 0, eCmdHdlrInt, setDebugLevel, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, setWorkDir, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, SetDropMalPTRMsgs, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, setDfltNetstrmDrvr, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultopensslengine", 0, eCmdHdlrGetWord, setDfltOpensslEngine, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord, setDfltNetstrmDrvrCAF, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercrlfile", 0, eCmdHdlrGetWord, setDfltNetstrmDrvrCRLF, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, setDfltNetstrmDrvrKeyFile, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, setDfltNetstrmDrvrCertFile, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"localhostname", 0, eCmdHdlrGetWord, NULL, &LocalHostNameOverride, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"localhostipif", 0, eCmdHdlrGetWord, setLocalHostIPIF, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"netstreamdrivercaextrafiles", 0, eCmdHdlrGetWord, setNetstrmDrvrCAExtraFiles, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrGoneAway, NULL, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize, legacySetMaxMessageSize, NULL, NULL)); /* Deprecated parser config options */ CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, setParserControlCharacterEscapePrefix, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, setParserDropTrailingLFOnReception, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, setParserEscapeControlCharactersOnReceive, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"spacelfonreceive", 0, eCmdHdlrBinary, setParserSpaceLFOnReceive, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escape8bitcharactersonreceive", 0, eCmdHdlrBinary, setParserEscape8BitCharactersOnReceive, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactertab", 0, eCmdHdlrBinary, setParserEscapeControlCharacterTab, NULL, NULL)); CHKiRet( regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); INIT_ATOMIC_HELPER_MUT(mutTerminateInputs); ENDObjClassInit(glbl) /* Exit the glbl class. * rgerhards, 2008-04-17 */ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ free(LocalDomain); free(LocalHostName); free(LocalHostNameOverride); free(LocalFQDNName); objRelease(prop, CORE_COMPONENT); if (propLocalHostNameToDelete != NULL) prop.Destruct(&propLocalHostNameToDelete); DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs); ENDObjClassExit(glbl) rsyslog-8.2512.0/runtime/PaxHeaders/atomic.h0000644000000000000000000000013115062756615015655 xustar0029 mtime=1758190989.22564146 30 atime=1764930980.022678256 30 ctime=1764935923.109575448 rsyslog-8.2512.0/runtime/atomic.h0000664000175000017500000002427715062756615015336 0ustar00rgerrger/* This header supplies atomic operations. So far, we rely on GCC's * atomic builtins. During configure, we check if atomic operatons are * available. If they are not, I am making the necessary provisioning to live without them if * they are not available. Please note that you should only use the macros * here if you think you can actually live WITHOUT an explicit atomic operation, * because in the non-presence of them, we simply do it without atomicitiy. * Which, for word-aligned data types, usually (but only usually!) should work. * * We are using the functions described in * http:/gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html * * THESE MACROS MUST ONLY BE USED WITH WORD-SIZED DATA TYPES! * * Copyright 2008-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_ATOMIC_H #define INCLUDED_ATOMIC_H #include #include "typedefs.h" /* for this release, we disable atomic calls because there seem to be some * portability problems and we can not fix that without destabilizing the build. * They simply came in too late. -- rgerhards, 2008-04-02 */ #ifdef HAVE_ATOMIC_BUILTINS #define ATOMIC_SUB(data, val, phlpmut) __sync_fetch_and_sub(data, val) #define ATOMIC_SUB_unsigned(data, val, phlpmut) __sync_fetch_and_sub(data, val) #define ATOMIC_ADD(data, val) __sync_fetch_and_add(&(data), val) #define ATOMIC_INC(data, phlpmut) ((void)__sync_fetch_and_add(data, 1)) #define ATOMIC_INC_AND_FETCH_int(data, phlpmut) __sync_fetch_and_add(data, 1) #define ATOMIC_INC_AND_FETCH_unsigned(data, phlpmut) __sync_fetch_and_add(data, 1) #define ATOMIC_DEC(data, phlpmut) ((void)__sync_sub_and_fetch(data, 1)) #define ATOMIC_DEC_AND_FETCH(data, phlpmut) __sync_sub_and_fetch(data, 1) #define ATOMIC_FETCH_32BIT(data, phlpmut) ((int)__sync_fetch_and_and(data, 0xffffffff)) #define ATOMIC_FETCH_32BIT_unsigned(data, phlpmut) ((int)__sync_fetch_and_and(data, 0xffffffff)) #define ATOMIC_STORE_1_TO_32BIT(data) __sync_lock_test_and_set(&(data), 1) #define ATOMIC_STORE_0_TO_INT(data, phlpmut) __sync_fetch_and_and(data, 0) #define ATOMIC_STORE_1_TO_INT(data, phlpmut) __sync_fetch_and_or(data, 1) #define ATOMIC_OR_INT_TO_INT(data, phlpmut, val) __sync_fetch_and_or((data), (val)) #define ATOMIC_CAS(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal)) #define ATOMIC_CAS_time_t(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal)) #define ATOMIC_CAS_VAL(data, oldVal, newVal, phlpmut) __sync_val_compare_and_swap(data, (oldVal), (newVal)); /* functions below are not needed if we have atomics */ #define DEF_ATOMIC_HELPER_MUT(x) #define INIT_ATOMIC_HELPER_MUT(x) #define DESTROY_ATOMIC_HELPER_MUT(x) /* the following operations should preferrably be done atomic, but it is * not fatal if not -- that means we can live with some missed updates. So be * sure to use these macros only if that really does not matter! */ #define PREFER_ATOMIC_INC(data) ((void)__sync_fetch_and_add(&(data), 1)) #define PREFER_FETCH_32BIT(data) ((unsigned)__sync_fetch_and_and(&(data), 0xffffffff)) #define PREFER_STORE_0_TO_INT(data) __sync_fetch_and_and(data, 0) #define PREFER_STORE_1_TO_INT(data) __sync_fetch_and_or(data, 1) #else /* note that we gained parctical proof that theoretical problems DO occur * if we do not properly address them. See this blog post for details: * http://blog.gerhards.net/2009/01/rsyslog-data-race-analysis.html * The bottom line is that if there are no atomics available, we should NOT * simply go ahead and do without them - use mutexes or other things. The * code needs to be checked against all those cases. -- rgerhards, 2009-01-30 */ #include #define ATOMIC_INC(data, phlpmut) \ { \ pthread_mutex_lock(phlpmut); \ ++(*(data)); \ pthread_mutex_unlock(phlpmut); \ } #define ATOMIC_STORE_0_TO_INT(data, hlpmut) \ { \ pthread_mutex_lock(hlpmut); \ *(data) = 0; \ pthread_mutex_unlock(hlpmut); \ } #define ATOMIC_STORE_1_TO_INT(data, hlpmut) \ { \ pthread_mutex_lock(hlpmut); \ *(data) = 1; \ pthread_mutex_unlock(hlpmut); \ } #define ATOMIC_OR_INT_TO_INT(data, hlpmut, val) \ { \ pthread_mutex_lock(hlpmut); \ *(data) = val; \ pthread_mutex_unlock(hlpmut); \ } static inline int ATOMIC_CAS(int *data, int oldVal, int newVal, pthread_mutex_t *phlpmut) { int bSuccess; pthread_mutex_lock(phlpmut); if (*data == oldVal) { *data = newVal; bSuccess = 1; } else { bSuccess = 0; } pthread_mutex_unlock(phlpmut); return (bSuccess); } static inline int ATOMIC_CAS_time_t(time_t *data, time_t oldVal, time_t newVal, pthread_mutex_t *phlpmut) { int bSuccess; pthread_mutex_lock(phlpmut); if (*data == oldVal) { *data = newVal; bSuccess = 1; } else { bSuccess = 0; } pthread_mutex_unlock(phlpmut); return (bSuccess); } static inline int ATOMIC_CAS_VAL(int *data, int oldVal, int newVal, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); if (*data == oldVal) { *data = newVal; } val = *data; pthread_mutex_unlock(phlpmut); return (val); } #define ATOMIC_DEC(data, phlpmut) \ { \ pthread_mutex_lock(phlpmut); \ --(*(data)); \ pthread_mutex_unlock(phlpmut); \ } static inline int ATOMIC_INC_AND_FETCH_int(int *data, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); val = ++(*data); pthread_mutex_unlock(phlpmut); return (val); } static inline unsigned ATOMIC_INC_AND_FETCH_unsigned(unsigned *data, pthread_mutex_t *phlpmut) { unsigned val; pthread_mutex_lock(phlpmut); val = ++(*data); pthread_mutex_unlock(phlpmut); return (val); } static inline int ATOMIC_DEC_AND_FETCH(int *data, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); val = --(*data); pthread_mutex_unlock(phlpmut); return (val); } static inline int ATOMIC_FETCH_32BIT(int *data, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); val = (*data); pthread_mutex_unlock(phlpmut); return (val); } static inline int ATOMIC_FETCH_32BIT_unsigned(unsigned *data, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); val = (*data); pthread_mutex_unlock(phlpmut); return (val); } static inline void ATOMIC_SUB(int *data, int val, pthread_mutex_t *phlpmut) { pthread_mutex_lock(phlpmut); (*data) -= val; pthread_mutex_unlock(phlpmut); } static inline void ATOMIC_SUB_unsigned(unsigned *data, int val, pthread_mutex_t *phlpmut) { pthread_mutex_lock(phlpmut); (*data) -= val; pthread_mutex_unlock(phlpmut); } #define DEF_ATOMIC_HELPER_MUT(x) pthread_mutex_t x #define INIT_ATOMIC_HELPER_MUT(x) pthread_mutex_init(&(x), NULL) #define DESTROY_ATOMIC_HELPER_MUT(x) pthread_mutex_destroy(&(x)) #define PREFER_ATOMIC_INC(data) ((void)++data) #define PREFER_FETCH_32BIT(data) ((unsigned)(data)) #define PREFER_STORE_0_TO_INT(data) (*(data) = 0) #define PREFER_STORE_1_TO_INT(data) (*(data) = 1) #endif /* we need to handle 64bit atomics seperately as some platforms have * 32 bit atomics, but not 64 bit ones... -- rgerhards, 2010-12-01 */ #ifdef HAVE_ATOMIC_BUILTINS64 #define ATOMIC_INC_uint64(data, phlpmut) ((void)__sync_fetch_and_add(data, 1)) #define ATOMIC_ADD_uint64(data, phlpmut, value) ((void)__sync_fetch_and_add(data, value)) #define ATOMIC_DEC_uint64(data, phlpmut) ((void)__sync_sub_and_fetch(data, 1)) #define ATOMIC_INC_AND_FETCH_uint64(data, phlpmut) __sync_fetch_and_add(data, 1) #define DEF_ATOMIC_HELPER_MUT64(x) #define INIT_ATOMIC_HELPER_MUT64(x) #define DESTROY_ATOMIC_HELPER_MUT64(x) #else #define ATOMIC_INC_uint64(data, phlpmut) \ { \ pthread_mutex_lock(phlpmut); \ ++(*(data)); \ pthread_mutex_unlock(phlpmut); \ } #define ATOMIC_ADD_uint64(data, phlpmut, value) \ { \ pthread_mutex_lock(phlpmut); \ *data += value; \ pthread_mutex_unlock(phlpmut); \ } #define ATOMIC_DEC_uint64(data, phlpmut) \ { \ pthread_mutex_lock(phlpmut); \ --(*(data)); \ pthread_mutex_unlock(phlpmut); \ } static inline unsigned ATOMIC_INC_AND_FETCH_uint64(uint64 *data, pthread_mutex_t *phlpmut) { uint64 val; pthread_mutex_lock(phlpmut); val = ++(*data); pthread_mutex_unlock(phlpmut); return (val); } #define DEF_ATOMIC_HELPER_MUT64(x) pthread_mutex_t x #define INIT_ATOMIC_HELPER_MUT64(x) pthread_mutex_init(&(x), NULL) #define DESTROY_ATOMIC_HELPER_MUT64(x) pthread_mutex_destroy(&(x)) #endif /* #ifdef HAVE_ATOMIC_BUILTINS64 */ #endif /* #ifndef INCLUDED_ATOMIC_H */ rsyslog-8.2512.0/runtime/PaxHeaders/debug.h0000644000000000000000000000013215055605325015461 xustar0030 mtime=1756826325.644800608 30 atime=1764930979.971677403 30 ctime=1764935923.203576887 rsyslog-8.2512.0/runtime/debug.h0000664000175000017500000000622615055605325015133 0ustar00rgerrger/* debug.h * * Definitions for the debug module. * * Copyright 2008-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef DEBUG_H_INCLUDED #define DEBUG_H_INCLUDED #include #include "obj-types.h" /* some settings for various debug modes */ #define DEBUG_OFF 0 #define DEBUG_ONDEMAND 1 #define DEBUG_FULL 2 /* external static data elements (some time to be replaced) */ extern int Debug; /* debug flag - read-only after startup */ extern int debugging_on; /* read-only, except on sig USR1 */ extern int stddbg; /* the handle for regular debug output, set to stdout if not forking, -1 otherwise */ extern int dbgTimeoutToStderr; /* prototypes */ rsRetVal dbgClassInit(void); rsRetVal dbgClassExit(void); void dbgSetDebugFile(uchar *fn); void dbgSetDebugLevel(int level); void dbgSetThrdName(const uchar *pszName); void dbgOutputTID(char *name); int dbgGetDbglogFd(void); /* external data */ extern char *pszAltDbgFileName; /* if set, debug output is *also* sent to here */ extern int altdbg; /* and the handle for alternate debug output */ /* macros */ #ifdef DEBUGLESS #define DBGL_UNUSED __attribute__((__unused__)) static inline void r_dbgoprint(const char DBGL_UNUSED *srcname, obj_t DBGL_UNUSED *pObj, const char DBGL_UNUSED *fmt, ...) {} static inline void r_dbgprintf(const char DBGL_UNUSED *srcname, const char DBGL_UNUSED *fmt, ...) {} #else #define DBGL_UNUSED void r_dbgoprint(const char *srcname, obj_t *pObj, const char *fmt, ...) __attribute__((format(printf, 3, 4))); void r_dbgprintf(const char *srcname, const char *fmt, ...) __attribute__((format(printf, 2, 3))); #endif #define DBGPRINTF(...) \ if (Debug) { \ r_dbgprintf(__FILE__, __VA_ARGS__); \ } #define DBGOPRINT(...) \ if (Debug) { \ r_dbgoprint(__FILE__, __VA_ARGS__); \ } #define dbgprintf(...) r_dbgprintf(__FILE__, __VA_ARGS__) #define dbgoprint(...) r_dbgoprint(__FILE__, __VA_ARGS__) /* things originally introduced for now removed rtinst */ #define d_pthread_mutex_lock(x) pthread_mutex_lock(x) #define d_pthread_mutex_trylock(x) pthread_mutex_trylock(x) #define d_pthread_mutex_unlock(x) pthread_mutex_unlock(x) #define d_pthread_cond_wait(cond, mut) pthread_cond_wait(cond, mut) #define d_pthread_cond_timedwait(cond, mut, to) pthread_cond_timedwait(cond, mut, to) #endif /* #ifndef DEBUG_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/Makefile.am0000644000000000000000000000013215114522477016260 xustar0030 mtime=1764926783.038631931 30 atime=1764926784.238661387 30 ctime=1764935923.074574912 rsyslog-8.2512.0/runtime/Makefile.am0000664000175000017500000002013415114522477015724 0ustar00rgerrgersbin_PROGRAMS = man_MANS = noinst_LIBRARIES = noinst_LTLIBRARIES = librsyslog.la pkglib_LTLIBRARIES = #pkglib_LTLIBRARIES = librsyslog.la librsyslog_la_SOURCES = \ rsyslog.c \ rsyslog.h \ typedefs.h \ dnscache.c \ dnscache.h \ unicode-helper.h \ atomic.h \ batch.h \ syslogd-types.h \ module-template.h \ im-helper.h \ obj-types.h \ sigprov.h \ cryprov.h \ nsd.h \ glbl.h \ glbl.c \ unlimited_select.h \ conf.c \ conf.h \ janitor.c \ janitor.h \ rsconf.c \ rsconf.h \ parser.h \ parser.c \ strgen.h \ strgen.c \ msg.c \ msg.h \ linkedlist.c \ linkedlist.h \ objomsr.c \ objomsr.h \ stringbuf.c \ stringbuf.h \ datetime.c \ datetime.h \ srutils.c \ srUtils.h \ errmsg.c \ errmsg.h \ operatingstate.c \ operatingstate.h \ debug.c \ debug.h \ obj.c \ obj.h \ modules.c \ modules.h \ statsobj.c \ statsobj.h \ dynstats.c \ dynstats.h \ perctile_ringbuf.c \ perctile_ringbuf.h \ perctile_stats.c \ perctile_stats.h \ statsobj.h \ stream.c \ stream.h \ var.c \ var.h \ wtp.c \ wtp.h \ wti.c \ wti.h \ queue.c \ queue.h \ ruleset.c \ ruleset.h \ prop.c \ prop.h \ ratelimit.c \ ratelimit.h \ lookup.c \ lookup.h \ cfsysline.c \ cfsysline.h \ \ ../action.h \ ../action.c \ ../threads.c \ ../threads.h \ \ ../parse.c \ ../parse.h \ \ hashtable.c \ hashtable.h \ hashtable_itr.c \ hashtable_itr.h \ hashtable_private.h \ \ ../outchannel.c \ ../outchannel.h \ ../template.c \ ../template.h \ timezones.c \ timezones.h # the files with ../ we need to work on - so that they either become part of the # runtime or will no longer be needed. -- rgerhards, 2008-06-13 # #if OS_LINUX #librsyslog_la_SOURCES += \ #endif if WITH_MODDIRS librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\" else librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/\" -I\$(top_srcdir) -I\$(top_srcdir)/grammar endif #librsyslog_la_LDFLAGS = -module -avoid-version librsyslog_la_CPPFLAGS += $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(LIBUUID_CFLAGS) $(LIBFASTJSON_CFLAGS) ${LIBESTR_CFLAGS} librsyslog_la_LIBADD = $(DL_LIBS) $(RT_LIBS) $(LIBUUID_LIBS) $(LIBFASTJSON_LIBS) ${LIBESTR_LIBS} -lm if ENABLE_LIBLOGGING_STDLOG librsyslog_la_CPPFLAGS += ${LIBLOGGING_STDLOG_CFLAGS} librsyslog_la_LIBADD += $(LIBLOGGING_STDLOG_LIBS) endif librsyslog_la_CPPFLAGS += -I\$(top_srcdir)/tools # # regular expression support # if ENABLE_REGEXP pkglib_LTLIBRARIES += lmregexp.la lmregexp_la_SOURCES = regexp.c regexp.h lmregexp_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmregexp_la_LDFLAGS = -module -avoid-version lmregexp_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmregexp_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmregexp_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif endif # # zlib support # pkglib_LTLIBRARIES += lmzlibw.la lmzlibw_la_SOURCES = zlibw.c zlibw.h lmzlibw_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmzlibw_la_LDFLAGS = -module -avoid-version $(ZLIB_LIBS) lmzlibw_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmzlibw_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmzlibw_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif # # basic network support, needed for rsyslog startup (e.g. our own system name) # pkglib_LTLIBRARIES += lmnet.la lmnet_la_SOURCES = net.c net.h netns_socket.c netns_socket.h lmnet_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmnet_la_LDFLAGS = -module -avoid-version ../compat/compat_la-getifaddrs.lo lmnet_la_LIBADD = if ENABLE_INET pkglib_LTLIBRARIES += lmnetstrms.la if ENABLE_LIBLOGGING_STDLOG lmnet_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmnet_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif # network stream master class and stream factory lmnetstrms_la_SOURCES = netstrms.c netstrms.h \ netstrm.c netstrm.h lmnetstrms_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmnetstrms_la_LDFLAGS = -module -avoid-version lmnetstrms_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmnetstrms_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmnetstrms_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif # netstream drivers # plain tcp driver - main driver pkglib_LTLIBRARIES += lmnsd_ptcp.la lmnsd_ptcp_la_SOURCES = nsd_ptcp.c nsd_ptcp.h lmnsd_ptcp_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmnsd_ptcp_la_LDFLAGS = -module -avoid-version lmnsd_ptcp_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmnsd_ptcp_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmnsd_ptcp_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif endif # if ENABLE_INET # # openssl base and netstream driver # if ENABLE_OPENSSL # noinst_LTLIBRARIES += lmnsd_ossl.la pkglib_LTLIBRARIES += lmnsd_ossl.la lmnsd_ossl_la_SOURCES = net_ossl.c net_ossl.h nsd_ossl.c nsd_ossl.h lmnsd_ossl_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(OPENSSL_CFLAGS) lmnsd_ossl_la_LDFLAGS = -module -avoid-version lmnsd_ossl_la_LIBADD = $(OPENSSL_LIBS) endif # # GnuTLS netstream driver # if ENABLE_GNUTLS pkglib_LTLIBRARIES += lmnsd_gtls.la lmnsd_gtls_la_SOURCES = nsd_gtls.c nsd_gtls.h lmnsd_gtls_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(GNUTLS_CFLAGS) lmnsd_gtls_la_LDFLAGS = -module -avoid-version lmnsd_gtls_la_LIBADD = $(GNUTLS_LIBS) endif # # Mbed TLS netstream driver # if ENABLE_MBEDTLS pkglib_LTLIBRARIES += lmnsd_mbedtls.la lmnsd_mbedtls_la_SOURCES = nsd_mbedtls.c nsd_mbedtls.h lmnsd_mbedtls_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(MBEDTLS_CFLAGS) lmnsd_mbedtls_la_LDFLAGS = -module -avoid-version lmnsd_mbedtls_la_LIBADD = $(MBEDTLS_LIBS) endif # # support library for libgcrypt # if ENABLE_LIBGCRYPT noinst_LTLIBRARIES += libgcry.la libgcry_la_SOURCES = libgcry.c libcry_common.c libcry_common.h libgcry.h libgcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS) pkglib_LTLIBRARIES += lmcry_gcry.la lmcry_gcry_la_DEPENDENCIES = libgcry.la lmcry_gcry_la_SOURCES = lmcry_gcry.c lmcry_gcry.h lmcry_gcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS) lmcry_gcry_la_LDFLAGS = -module -avoid-version lmcry_gcry_la_LIBADD = libgcry.la $(LIBGCRYPT_LIBS) endif # # support library for openssl crypto provider # if ENABLE_OPENSSL_CRYPTO_PROVIDER # Helper noinst_LTLIBRARIES += libossl.la libossl_la_SOURCES = libossl.c libossl.h libcry_common.c libcry_common.h libossl_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(OPENSSL_CFLAGS) pkglib_LTLIBRARIES += lmcry_ossl.la lmcry_ossl_la_DEPENDENCIES = libossl.la lmcry_ossl_la_SOURCES = lmcry_ossl.c lmcry_ossl.h lmcry_ossl_la_CPPFLAGS = $(RSRT_CFLAGS) $(OPENSSL_FLAGS) lmcry_ossl_la_LDFLAGS = -module -avoid-version lmcry_ossl_la_LIBADD = libossl.la $(OPENSSL_LIBS) endif # # support library for zstd # if ENABLE_LIBZSTD pkglib_LTLIBRARIES += lmzstdw.la lmzstdw_la_SOURCES = zstdw.c zstdw.h lmzstdw_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmzstdw_la_LDFLAGS = -module -avoid-version $(ZSTD_LIBS) lmzstdw_la_LIBADD = -lzstd endif # # gssapi support # if ENABLE_GSSAPI pkglib_LTLIBRARIES += lmgssutil.la lmgssutil_la_SOURCES = gss-misc.c gss-misc.h lmgssutil_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmgssutil_la_LDFLAGS = -module -avoid-version lmgssutil_la_LIBADD = $(GSS_LIBS) endif pkglib_LTLIBRARIES += lmtcpsrv.la lmtcpclt.la # # # TCP (stream) server support # lmtcpsrv_la_SOURCES = \ tcps_sess.c \ tcps_sess.h \ tcpsrv.c \ tcpsrv.h lmtcpsrv_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmtcpsrv_la_LDFLAGS = -module -avoid-version lmtcpsrv_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmtcpsrv_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmtcpsrv_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif # # TCP (stream) client support # lmtcpclt_la_SOURCES = \ tcpclt.c \ tcpclt.h lmtcpclt_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) lmtcpclt_la_LDFLAGS = -module -avoid-version lmtcpclt_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG lmtcpclt_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) lmtcpclt_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif # # support library for Guardtime KSI-LS12 # if ENABLE_KSI_LS12 pkglib_LTLIBRARIES += lmsig_ksi_ls12.la lmsig_ksi_ls12_la_SOURCES = lmsig_ksi-ls12.c lmsig_ksi-ls12.h lib_ksils12.c \ lib_ksils12.h lib_ksi_queue.c lib_ksi_queue.h lmsig_ksi_ls12_la_CPPFLAGS = $(RSRT_CFLAGS) $(GT_KSI_LS12_CFLAGS) lmsig_ksi_ls12_la_LDFLAGS = -module -avoid-version $(GT_KSI_LS12_LIBS) endif rsyslog-8.2512.0/runtime/PaxHeaders/linkedlist.c0000644000000000000000000000013015055605325016526 xustar0030 mtime=1756826325.646800638 29 atime=1764930985.30676658 29 ctime=1764935923.16657632 rsyslog-8.2512.0/runtime/linkedlist.c0000664000175000017500000002463615055605325016207 0ustar00rgerrger/* linkedlist.c * This file set implements a generic linked list object. It can be used * wherever a linke list is required. * * NOTE: we do not currently provide a constructor and destructor for the * object itself as we assume it will always be part of another strucuture. * Having a pointer to it, I think, does not really make sense but costs * performance. Consequently, there is is llInit() and llDestroy() and they * do what a constructor and destructur do, except for creating the * linkedList_t structure itself. * * File begun on 2007-07-31 by RGerhards * * Copyright (C) 2007-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "linkedlist.h" /* Initialize an existing linkedList_t structure * pKey destructor may be zero to take care of non-keyed lists. */ rsRetVal llInit(linkedList_t *pThis, rsRetVal (*pEltDestructor)(void *), rsRetVal (*pKeyDestructor)(void *), int (*pCmpOp)(void *, void *)) { assert(pThis != NULL); assert(pEltDestructor != NULL); pThis->pEltDestruct = pEltDestructor; pThis->pKeyDestruct = pKeyDestructor; pThis->cmpOp = pCmpOp; pThis->pKey = NULL; pThis->iNumElts = 0; pThis->pRoot = NULL; pThis->pLast = NULL; return RS_RET_OK; }; /* llDestroyEltData - destroys a list element * It is a separate function as the * functionality is needed in multiple code-pathes. */ static rsRetVal llDestroyElt(linkedList_t *pList, llElt_t *pElt) { DEFiRet; assert(pList != NULL); assert(pElt != NULL); /* we ignore errors during destruction, as we need to try * free the element in any case. */ if (pElt->pData != NULL) pList->pEltDestruct(pElt->pData); if (pElt->pKey != NULL) pList->pKeyDestruct(pElt->pKey); free(pElt); pList->iNumElts--; /* one less */ RETiRet; } /* llDestroy - destroys a COMPLETE linkedList */ rsRetVal llDestroy(linkedList_t *pThis) { DEFiRet; llElt_t *pElt; assert(pThis != NULL); pElt = pThis->pRoot; while (pElt != NULL) { /* keep the list structure in a consistent state as * the destructor bellow may reference it again */ pThis->pRoot = pElt->pNext; if (pElt->pNext == NULL) pThis->pLast = NULL; /* we ignore errors during destruction, as we need to try * finish the linked list in any case. */ llDestroyElt(pThis, pElt); pElt = pThis->pRoot; } RETiRet; } /* llDestroyRootElt - destroy the root element but otherwise * keeps this list intact. -- rgerhards, 2007-08-03 */ rsRetVal llDestroyRootElt(linkedList_t *pThis) { DEFiRet; llElt_t *pPrev; if (pThis->pRoot == NULL) { ABORT_FINALIZE(RS_RET_EMPTY_LIST); } pPrev = pThis->pRoot; if (pPrev->pNext == NULL) { /* it was the only list element */ pThis->pLast = NULL; pThis->pRoot = NULL; } else { /* there are other list elements */ pThis->pRoot = pPrev->pNext; } CHKiRet(llDestroyElt(pThis, pPrev)); finalize_it: RETiRet; } /* get next user data element of a linked list. The caller must also * provide a "cookie" to the function. On initial call, it must be * NULL. Other than that, the caller is not allowed to to modify the * cookie. In the current implementation, the cookie is an actual * pointer to the current list element, but this is nothing that the * caller should rely on. */ rsRetVal llGetNextElt(linkedList_t *pThis, linkedListCookie_t *ppElt, void **ppUsr) { llElt_t *pElt; DEFiRet; assert(pThis != NULL); assert(ppElt != NULL); assert(ppUsr != NULL); pElt = *ppElt; pElt = (pElt == NULL) ? pThis->pRoot : pElt->pNext; if (pElt == NULL) { iRet = RS_RET_END_OF_LINKEDLIST; } else { *ppUsr = pElt->pData; } *ppElt = pElt; RETiRet; } /* return the key of an Elt * rgerhards, 2007-09-11: note that ppDatea is actually a void**, * but I need to make it a void* to avoid lots of compiler warnings. * It will be converted later down in the code. */ rsRetVal llGetKey(llElt_t *pThis, void *ppData) { assert(pThis != NULL); assert(ppData != NULL); *(void **)ppData = pThis->pKey; return RS_RET_OK; } /* construct a new llElt_t */ static rsRetVal llEltConstruct(llElt_t **ppThis, void *pKey, void *pData) { DEFiRet; llElt_t *pThis; assert(ppThis != NULL); if ((pThis = (llElt_t *)calloc(1, sizeof(llElt_t))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pThis->pKey = pKey; pThis->pData = pData; finalize_it: *ppThis = pThis; RETiRet; } /* append a user element to the end of the linked list. This includes setting a key. If no * key is desired, simply pass in a NULL pointer for it. */ rsRetVal llAppend(linkedList_t *pThis, void *pKey, void *pData) { llElt_t *pElt; DEFiRet; CHKiRet(llEltConstruct(&pElt, pKey, pData)); pThis->iNumElts++; /* one more */ if (pThis->pLast == NULL) { pThis->pRoot = pElt; } else { pThis->pLast->pNext = pElt; } pThis->pLast = pElt; finalize_it: RETiRet; } /* unlink a requested element. As we have singly-linked lists, the * caller also needs to pass in the previous element (or NULL, if it is the * root element). * rgerhards, 2007-11-21 */ static rsRetVal llUnlinkElt(linkedList_t *pThis, llElt_t *pElt, llElt_t *pEltPrev) { assert(pElt != NULL); if (pEltPrev == NULL) { /* root element? */ pThis->pRoot = pElt->pNext; } else { /* regular element */ pEltPrev->pNext = pElt->pNext; } if (pElt == pThis->pLast) pThis->pLast = pEltPrev; return RS_RET_OK; } /* unlinks and immediately deletes an element. Previous element must * be given (or zero if the root element is to be deleted). * rgerhards, 2007-11-21 */ static rsRetVal llUnlinkAndDelteElt(linkedList_t *pThis, llElt_t *pElt, llElt_t *pEltPrev) { DEFiRet; assert(pElt != NULL); CHKiRet(llUnlinkElt(pThis, pElt, pEltPrev)); CHKiRet(llDestroyElt(pThis, pElt)); finalize_it: RETiRet; } /* find a user element based on the provided key - this is the * internal variant, which also tracks the last element pointer * before the found element. This is necessary to delete elements. * NULL means there is no element in front of it, aka the found elt * is the root elt. * rgerhards, 2007-11-21 */ static rsRetVal llFindElt(linkedList_t *pThis, void *pKey, llElt_t **ppElt, llElt_t **ppEltPrev) { DEFiRet; llElt_t *pElt; llElt_t *pEltPrev = NULL; int bFound = 0; assert(pThis != NULL); assert(pKey != NULL); assert(ppElt != NULL); assert(ppEltPrev != NULL); pElt = pThis->pRoot; while (pElt != NULL && bFound == 0) { if (pThis->cmpOp(pKey, pElt->pKey) == 0) bFound = 1; else { pEltPrev = pElt; pElt = pElt->pNext; } } if (bFound == 1) { *ppElt = pElt; *ppEltPrev = pEltPrev; } else iRet = RS_RET_NOT_FOUND; RETiRet; } /* find a user element based on the provided key */ rsRetVal llFind(linkedList_t *pThis, void *pKey, void **ppData) { DEFiRet; llElt_t *pElt; llElt_t *pEltPrev; CHKiRet(llFindElt(pThis, pKey, &pElt, &pEltPrev)); /* if we reach this point, we have found the element */ *ppData = pElt->pData; finalize_it: RETiRet; } /* find a delete an element based on user-provided key. The element is * delete, the caller does not receive anything. If we need to receive * the element before destruction, we may implement an llFindAndUnlink() * at that time. * rgerhards, 2007-11-21 */ rsRetVal llFindAndDelete(linkedList_t *pThis, void *pKey) { DEFiRet; llElt_t *pElt; llElt_t *pEltPrev; CHKiRet(llFindElt(pThis, pKey, &pElt, &pEltPrev)); /* if we reach this point, we have found an element */ CHKiRet(llUnlinkAndDelteElt(pThis, pElt, pEltPrev)); finalize_it: RETiRet; } /* provide the count of linked list elements */ rsRetVal llGetNumElts(linkedList_t *pThis, int *piCnt) { DEFiRet; assert(pThis != NULL); assert(piCnt != NULL); *piCnt = pThis->iNumElts; RETiRet; } /* execute a function on all list members. The functions receives a * user-supplied parameter, which may be either a simple value * or a pointer to a structure with more data. If the user-supplied * function does not return RS_RET_OK, this function here terminates. * rgerhards, 2007-08-02 * rgerhards, 2007-11-21: added functionality to delete a list element. * If the called user function returns RS_RET_OK_DELETE_LISTENTRY the current element * is deleted. */ rsRetVal llExecFunc(linkedList_t *pThis, rsRetVal (*pFunc)(void *, void *), void *pParam) { DEFiRet; rsRetVal iRetLL; void *pData; linkedListCookie_t llCookie = NULL; linkedListCookie_t llCookiePrev = NULL; /* previous list element (needed for deletion, NULL = at root) */ assert(pThis != NULL); assert(pFunc != NULL); while ((iRetLL = llGetNextElt(pThis, &llCookie, (void **)&pData)) == RS_RET_OK) { iRet = pFunc(pData, pParam); if (iRet == RS_RET_OK_DELETE_LISTENTRY) { /* delete element */ CHKiRet(llUnlinkAndDelteElt(pThis, llCookie, llCookiePrev)); /* we need to revert back, as we have just deleted the current element. * So the actual current element is the one before it, which happens to be * stored in llCookiePrev. -- rgerhards, 2007-11-21 */ llCookie = llCookiePrev; } else if (iRet != RS_RET_OK) { FINALIZE; } llCookiePrev = llCookie; } if (iRetLL != RS_RET_END_OF_LINKEDLIST) iRet = iRetLL; finalize_it: RETiRet; } /* vim:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/dnscache.h0000644000000000000000000000013215055605325016143 xustar0030 mtime=1756826325.644800608 30 atime=1764930980.501686268 30 ctime=1764935923.103575356 rsyslog-8.2512.0/runtime/dnscache.h0000664000175000017500000000237115055605325015612 0ustar00rgerrger/* Definitions for dnscache module. * * Copyright 2011-2019 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_DNSCACHE_H #define INCLUDED_DNSCACHE_H rsRetVal dnscacheInit(void); rsRetVal dnscacheDeinit(void); rsRetVal ATTR_NONNULL(1, 5) dnscacheLookup(struct sockaddr_storage *const addr, prop_t **const fqdn, prop_t **const fqdnLowerCase, prop_t **const localName, prop_t **const ip); #endif /* #ifndef INCLUDED_DNSCACHE_H */ rsyslog-8.2512.0/runtime/PaxHeaders/modules.h0000644000000000000000000000013215055605325016043 xustar0030 mtime=1756826325.647800653 30 atime=1764930979.998677855 30 ctime=1764935923.212577025 rsyslog-8.2512.0/runtime/modules.h0000664000175000017500000002312215055605325015507 0ustar00rgerrger/* modules.h * * Definition for build-in and plug-ins module handler. This file is the base * for all dynamically loadable module support. In theory, in v3 all modules * are dynamically loaded, in practice we currently do have a few build-in * once. This may become removed. * * The loader keeps track of what is loaded. For library modules, it is also * used to find objects (libraries) and to obtain the queryInterface function * for them. A reference count is maintened for libraries, so that they are * unloaded only when nobody still accesses them. * * File begun on 2007-07-22 by RGerhards * * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef MODULES_H_INCLUDED #define MODULES_H_INCLUDED 1 #include "objomsr.h" #include "rainerscript.h" /* the following define defines the current version of the module interface. * It can be used by any module which want's to simply prevent version conflicts * and does not intend to do specific old-version emulations. * rgerhards, 2008-03-04 * version 3 adds modInfo_t ptr to call of modInit -- rgerhards, 2008-03-10 * version 4 removes needUDPSocket OM callback -- rgerhards, 2008-03-22 * version 5 changes the way parsing works for input modules. This is * an important change, parseAndSubmitMessage() goes away. Other * module types are not affected. -- rgerhards, 2008-10-09 * version 6 introduces scoping support (starting with the output * modules) -- rgerhards, 2010-07-27 */ #define CURR_MOD_IF_VERSION 6 typedef enum eModType_ { eMOD_IN = 0, /* input module */ eMOD_OUT = 1, /* output module */ eMOD_LIB = 2, /* library module */ eMOD_PARSER = 3, /* parser module */ eMOD_STRGEN = 4, /* strgen module */ eMOD_FUNCTION = 5, /*rscript function module*/ eMOD_ANY = 6 /* meta-name for "any type of module" -- to be used in function calls */ } eModType_t; #ifdef DEBUG typedef struct modUsr_s { struct modUsr_s *pNext; char *pszFile; } modUsr_t; #endif /* how is this module linked? */ typedef enum eModLinkType_ { eMOD_LINK_STATIC, eMOD_LINK_DYNAMIC_UNLOADED, /* dynalink module, currently not loaded */ eMOD_LINK_DYNAMIC_LOADED, /* dynalink module, currently loaded */ eMOD_LINK_ALL /* special: all linkage types, e.g. for unload */ } eModLinkType_t; /* remember which shared libs we dlopen()-ed */ struct dlhandle_s { uchar *pszName; void *pModHdlr; struct dlhandle_s *next; }; /* should this module be kept linked? */ typedef enum eModKeepType_ { eMOD_NOKEEP, eMOD_KEEP } eModKeepType_t; struct modInfo_s { struct modInfo_s *pPrev; /* support for creating a double linked module list */ struct modInfo_s *pNext; /* support for creating a linked module list */ int iIFVers; /* Interface version of module */ eModType_t eType; /* type of this module */ eModLinkType_t eLinkType; eModKeepType_t eKeepType; /* keep the module dynamically linked on unload */ uchar *pszName; /* printable module name, e.g. for dbgprintf */ uchar *cnfName; /* name to be used in config statements (e.g. 'name="omusrmsg"') */ unsigned uRefCnt; /* reference count for this module; 0 -> may be unloaded */ sbool bSetModCnfCalled; /* is setModCnf already called? Needed for built-in modules */ /* functions supported by all types of modules */ rsRetVal (*modInit)(int, int *, rsRetVal (**)(void *)); /* initialize the module */ /* be sure to support version handshake! */ rsRetVal (*modQueryEtryPt)(uchar *name, rsRetVal (**EtryPoint)()); /* query entry point addresses */ rsRetVal (*isCompatibleWithFeature)(syslogFeature); rsRetVal (*freeInstance)(void *); /* called before termination or module unload */ rsRetVal (*dbgPrintInstInfo)(void *); /* called before termination or module unload */ rsRetVal (*tryResume)(void *); /* called to see if module actin can be resumed now */ rsRetVal (*modExit)(void); /* called before termination or module unload */ rsRetVal (*modGetID)(void **); /* get its unique ID from module */ rsRetVal (*doHUP)(void *); /* HUP handler, action level */ rsRetVal (*doHUPWrkr)(void *); /* HUP handler, wrkr instance level */ /* v2 config system specific */ rsRetVal (*beginCnfLoad)(void *newCnf, rsconf_t *pConf); rsRetVal (*setModCnf)(struct nvlst *lst); rsRetVal (*endCnfLoad)(void *Cnf); rsRetVal (*checkCnf)(void *Cnf); rsRetVal (*activateCnfPrePrivDrop)(void *Cnf); rsRetVal (*activateCnf)(void *Cnf); /* make provided config the running conf */ rsRetVal (*freeCnf)(void *Cnf); /* end v2 config system specific */ union { struct { /* data for input modules */ /* TODO: remove? */ rsRetVal (*willRun)(void); /* check if the current config will be able to run*/ rsRetVal (*runInput)(thrdInfo_t *); /* function to gather input and submit to queue */ rsRetVal (*afterRun)(thrdInfo_t *); /* function to gather input and submit to queue */ rsRetVal (*newInpInst)(struct nvlst *lst); int bCanRun; /* cached value of whether willRun() succeeded */ } im; struct { /* data for output modules */ /* below: perform the configured action */ rsRetVal (*beginTransaction)(void *); rsRetVal (*commitTransaction)(void *const, actWrkrIParams_t *const, const unsigned); rsRetVal (*doAction)(void **params, void *pWrkrData); rsRetVal (*endTransaction)(void *); rsRetVal (*parseSelectorAct)(uchar **, void **, omodStringRequest_t **); rsRetVal (*newActInst)(uchar *modName, struct nvlst *lst, void **, omodStringRequest_t **); rsRetVal (*SetShutdownImmdtPtr)(void *pData, void *pPtr); rsRetVal (*createWrkrInstance)(void *ppWrkrData, void *pData); rsRetVal (*freeWrkrInstance)(void *pWrkrData); sbool supportsTX; /* set if the module supports transactions */ } om; struct { /* data for library modules */ char dummy; } lm; struct { /* data for parser modules */ rsRetVal (*newParserInst)(struct nvlst *lst, void *pinst); rsRetVal (*checkParserInst)(void *pinst); rsRetVal (*freeParserInst)(void *pinst); rsRetVal (*parse2)(instanceConf_t *const, smsg_t *); rsRetVal (*parse)(smsg_t *); } pm; struct { /* data for strgen modules */ rsRetVal (*strgen)(const smsg_t *const, actWrkrIParams_t *const iparam); } sm; struct { /* data for rscript modules */ rsRetVal (*getFunctArray)(int *const, struct scriptFunct **); } fm; } mod; void *pModHdlr; /* handler to the dynamic library holding the module */ #ifdef DEBUG /* we add some home-grown support to track our users (and detect who does not free us). */ modUsr_t *pModUsrRoot; #endif }; /* interfaces */ BEGINinterface(module) /* name must also be changed in ENDinterface macro! */ modInfo_t *(*GetNxt)(modInfo_t *pThis); cfgmodules_etry_t *(*GetNxtCnfType)(rsconf_t *cnf, cfgmodules_etry_t *pThis, eModType_t rqtdType); uchar *(*GetName)(modInfo_t *pThis); uchar *(*GetStateName)(modInfo_t *pThis); rsRetVal (*Use)(const char *srcFile, modInfo_t *pThis); /**< must be called before a module is used (ref counting) */ rsRetVal (*Release)(const char *srcFile, modInfo_t **ppThis); /**< release a module (ref counting) */ void (*PrintList)(void); rsRetVal (*UnloadAndDestructAll)(eModLinkType_t modLinkTypesToUnload); rsRetVal (*doModInit)(rsRetVal (*modInit)(), uchar *name, void *pModHdlr, modInfo_t **pNew); rsRetVal (*Load)(uchar *name, sbool bConfLoad, struct nvlst *lst); rsRetVal (*SetModDir)(uchar *name); modInfo_t *(*FindWithCnfName)(rsconf_t *cnf, uchar *name, eModType_t rqtdType); /* added v3, 2011-07-19 */ ENDinterface(module) #define moduleCURR_IF_VERSION 5 /* increment whenever you change the interface structure! */ /* Changes: * v2 * - added param bCondLoad to Load call - 2011-04-27 * - removed GetNxtType, added GetNxtCnfType - 2011-04-27 * v3 (see above) * v4 * - added third parameter to Load() - 2012-06-20 */ /* prototypes */ PROTOTYPEObj(module); /* in v6, we go back to in-core static link for core objects, at least those * that are not called from plugins. * ... and we need to know that none of the module functions are called from plugins! * rgerhards, 2012-09-24 */ rsRetVal modulesProcessCnf(struct cnfobj *o); uchar *modGetName(modInfo_t *pThis); rsRetVal ATTR_NONNULL(1) addModToCnfList(cfgmodules_etry_t **pNew, cfgmodules_etry_t *pLast); rsRetVal readyModForCnf(modInfo_t *pThis, cfgmodules_etry_t **ppNew, cfgmodules_etry_t **ppLast); void modDoHUP(void); #endif /* #ifndef MODULES_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/net_ossl.c0000644000000000000000000000013115055605325016213 xustar0030 mtime=1756826325.648800668 29 atime=1764931011.48520234 30 ctime=1764935923.367579398 rsyslog-8.2512.0/runtime/net_ossl.c0000664000175000017500000014607515055605325015675 0ustar00rgerrger/* net.c * Implementation of network-related stuff. * * File begun on 2023-08-29 by Alorbach (extracted from net.c) * * Copyright 2023 Andre Lorbach and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "parse.h" #include "srUtils.h" #include "obj.h" #include "errmsg.h" #include "net.h" #include "net_ossl.h" #include "nsd_ptcp.h" #include "rsconf.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(nsd_ptcp) /* Prototypes for openssl helper functions */ void net_ossl_lastOpenSSLErrorMsg( uchar *fromHost, int ret, SSL *ssl, int severity, const char *pszCallSource, const char *pszOsslApi); void net_ossl_set_ssl_verify_callback(SSL *pSsl, int flags); void net_ossl_set_ctx_verify_callback(SSL_CTX *pCtx, int flags); void net_ossl_set_bio_callback(BIO *conn); int net_ossl_verify_callback(int status, X509_STORE_CTX *store); #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) rsRetVal net_ossl_apply_tlscgfcmd(net_ossl_t *pThis, uchar *tlscfgcmd); #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L rsRetVal net_ossl_chkpeercertvalidity(net_ossl_t *pThis, SSL *ssl, uchar *fromHostIP); X509 *net_ossl_getpeercert(net_ossl_t *pThis, SSL *ssl, uchar *fromHostIP); rsRetVal net_ossl_peerfingerprint(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP); rsRetVal net_ossl_chkpeername(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP); /*--------------------------------------MT OpenSSL helpers ------------------------------------------*/ static MUTEX_TYPE *mutex_buf = NULL; static sbool openssl_initialized = 0; // Avoid multiple initialization / deinitialization void locking_function(int mode, int n, __attribute__((unused)) const char *file, __attribute__((unused)) int line) { if (mode & CRYPTO_LOCK) MUTEX_LOCK(mutex_buf[n]); else MUTEX_UNLOCK(mutex_buf[n]); } unsigned long id_function(void) { return ((unsigned long)THREAD_ID); } struct CRYPTO_dynlock_value *dyn_create_function(__attribute__((unused)) const char *file, __attribute__((unused)) int line) { struct CRYPTO_dynlock_value *value; value = (struct CRYPTO_dynlock_value *)malloc(sizeof(struct CRYPTO_dynlock_value)); if (!value) return NULL; MUTEX_SETUP(value->mutex); return value; } void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, __attribute__((unused)) const char *file, __attribute__((unused)) int line) { if (mode & CRYPTO_LOCK) MUTEX_LOCK(l->mutex); else MUTEX_UNLOCK(l->mutex); } void dyn_destroy_function(struct CRYPTO_dynlock_value *l, __attribute__((unused)) const char *file, __attribute__((unused)) int line) { MUTEX_CLEANUP(l->mutex); free(l); } /* set up support functions for openssl multi-threading. This must * be done at library initialisation. If the function fails, * processing can not continue normally. On failure, 0 is * returned, on success 1. */ int opensslh_THREAD_setup(void) { int i; if (openssl_initialized == 1) { DBGPRINTF("openssl: multithread setup already initialized\n"); return 1; } mutex_buf = (MUTEX_TYPE *)malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); if (mutex_buf == NULL) return 0; for (i = 0; i < CRYPTO_num_locks(); i++) MUTEX_SETUP(mutex_buf[i]); #if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_set_id_callback(id_function); #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ CRYPTO_set_locking_callback(locking_function); /* The following three CRYPTO_... functions are the OpenSSL functions for registering the callbacks we implemented above */ CRYPTO_set_dynlock_create_callback(dyn_create_function); CRYPTO_set_dynlock_lock_callback(dyn_lock_function); CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); DBGPRINTF("openssl: multithread setup finished\n"); openssl_initialized = 1; return 1; } /* shut down openssl - do this only when you are totally done * with openssl. */ int opensslh_THREAD_cleanup(void) { int i; if (openssl_initialized == 0) { DBGPRINTF("openssl: multithread cleanup already done\n"); return 1; } if (!mutex_buf) return 0; #if OPENSSL_VERSION_NUMBER < 0x10100000L CRYPTO_set_id_callback(NULL); #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ CRYPTO_set_locking_callback(NULL); CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); for (i = 0; i < CRYPTO_num_locks(); i++) MUTEX_CLEANUP(mutex_buf[i]); free(mutex_buf); mutex_buf = NULL; DBGPRINTF("openssl: multithread cleanup finished\n"); openssl_initialized = 0; return 1; } /*-------------------------------------- MT OpenSSL helpers -----------------------------------------*/ /*--------------------------------------OpenSSL helpers ------------------------------------------*/ /* globally initialize OpenSSL */ void osslGlblInit(void) { DBGPRINTF("osslGlblInit: ENTER\n"); if ((opensslh_THREAD_setup() == 0) || #if OPENSSL_VERSION_NUMBER < 0x10100000L /* Setup OpenSSL library < 1.1.0 */ !SSL_library_init() #else /* Setup OpenSSL library >= 1.1.0 with system default settings */ OPENSSL_init_ssl(0, NULL) == 0 #endif ) { LogError(0, RS_RET_NO_ERRCODE, "Error: OpenSSL initialization failed!"); } /* Load readable error strings */ SSL_load_error_strings(); #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) /* * ERR_load_*(), ERR_func_error_string(), ERR_get_error_line(), ERR_get_error_line_data(), ERR_get_state() * OpenSSL now loads error strings automatically so these functions are not needed. * SEE FOR MORE: * https://www.openssl.org/docs/manmaster/man7/migration_guide.html * */ #else /* Load error strings into mem*/ ERR_load_BIO_strings(); ERR_load_crypto_strings(); #endif PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wdeprecated_declarations #ifndef OPENSSL_NO_ENGINE // Initialize OpenSSL engine library ENGINE_load_builtin_engines(); /* Register all of them for every algorithm they collectively implement */ ENGINE_register_all_complete(); // Iterate through all available engines ENGINE *osslEngine = ENGINE_get_first(); const char *engine_id = NULL; const char *engine_name = NULL; while (osslEngine) { // Print engine ID and name if the engine is loaded if (ENGINE_get_init_function(osslEngine)) { // Check if engine is initialized engine_id = ENGINE_get_id(osslEngine); engine_name = ENGINE_get_name(osslEngine); DBGPRINTF("osslGlblInit: Loaded Engine: ID = %s, Name = %s\n", engine_id, engine_name); } osslEngine = ENGINE_get_next(osslEngine); } // Free the engine reference when done ENGINE_free(osslEngine); #else DBGPRINTF("osslGlblInit: OpenSSL compiled without ENGINE support - ENGINE support disabled\n"); #endif /* OPENSSL_NO_ENGINE */ PRAGMA_DIAGNOSTIC_POP } /* globally de-initialize OpenSSL */ void osslGlblExit(void) { DBGPRINTF("openssl: entering osslGlblExit\n"); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif ERR_free_strings(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); } /* initialize openssl context; called on * - listener creation * - outbound connection creation * Once created, the ctx object is used by-subobjects (accepted inbound connections) */ static rsRetVal net_ossl_osslCtxInit(net_ossl_t *pThis, const SSL_METHOD *method) { DEFiRet; int bHaveCA; int bHaveCRL; int bHaveCert; int bHaveKey; int bHaveExtraCAFiles; const char *caFile, *crlFile, *certFile, *keyFile; char *extraCaFiles, *extraCaFile; /* Setup certificates */ caFile = (char *)((pThis->pszCAFile == NULL) ? glbl.GetDfltNetstrmDrvrCAF(runConf) : pThis->pszCAFile); if (caFile == NULL) { LogMsg(0, RS_RET_CA_CERT_MISSING, LOG_WARNING, "Warning: CA certificate is not set"); bHaveCA = 0; } else { dbgprintf("osslCtxInit: OSSL CA file: '%s'\n", caFile); bHaveCA = 1; } crlFile = (char *)((pThis->pszCRLFile == NULL) ? glbl.GetDfltNetstrmDrvrCRLF(runConf) : pThis->pszCRLFile); if (crlFile == NULL) { bHaveCRL = 0; } else { dbgprintf("osslCtxInit: OSSL CRL file: '%s'\n", crlFile); bHaveCRL = 1; } certFile = (char *)((pThis->pszCertFile == NULL) ? glbl.GetDfltNetstrmDrvrCertFile(runConf) : pThis->pszCertFile); if (certFile == NULL) { LogMsg(0, RS_RET_CERT_MISSING, LOG_WARNING, "Warning: Certificate file is not set"); bHaveCert = 0; } else { dbgprintf("osslCtxInit: OSSL CERT file: '%s'\n", certFile); bHaveCert = 1; } keyFile = (char *)((pThis->pszKeyFile == NULL) ? glbl.GetDfltNetstrmDrvrKeyFile(runConf) : pThis->pszKeyFile); if (keyFile == NULL) { LogMsg(0, RS_RET_CERTKEY_MISSING, LOG_WARNING, "Warning: Key file is not set"); bHaveKey = 0; } else { dbgprintf("osslCtxInit: OSSL KEY file: '%s'\n", keyFile); bHaveKey = 1; } extraCaFiles = (char *)((pThis->pszExtraCAFiles == NULL) ? glbl.GetNetstrmDrvrCAExtraFiles(runConf) : pThis->pszExtraCAFiles); if (extraCaFiles == NULL) { bHaveExtraCAFiles = 0; } else { dbgprintf("osslCtxInit: OSSL EXTRA CA files: '%s'\n", extraCaFiles); bHaveExtraCAFiles = 1; } /* Create main CTX Object based on method parameter */ pThis->ctx = SSL_CTX_new(method); if (bHaveExtraCAFiles == 1) { while ((extraCaFile = strsep(&extraCaFiles, ","))) { if (SSL_CTX_load_verify_locations(pThis->ctx, extraCaFile, NULL) != 1) { LogError(0, RS_RET_TLS_CERT_ERR, "Error: Extra Certificate file could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "SSL_CTX_load_verify_locations"); ABORT_FINALIZE(RS_RET_TLS_CERT_ERR); } } } if (bHaveCA == 1 && SSL_CTX_load_verify_locations(pThis->ctx, caFile, NULL) != 1) { LogError(0, RS_RET_TLS_CERT_ERR, "Error: CA certificate could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "SSL_CTX_load_verify_locations"); ABORT_FINALIZE(RS_RET_TLS_CERT_ERR); } if (bHaveCRL == 1) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) // Get X509_STORE reference X509_STORE *store = SSL_CTX_get_cert_store(pThis->ctx); if (!X509_STORE_load_file(store, crlFile)) { LogError(0, RS_RET_CRL_INVALID, "Error: CRL could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "X509_STORE_load_file"); ABORT_FINALIZE(RS_RET_CRL_INVALID); } X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); #else #if OPENSSL_VERSION_NUMBER >= 0x10002000L // Get X509_STORE reference X509_STORE *store = SSL_CTX_get_cert_store(pThis->ctx); // Load the CRL PEM file FILE *fp = fopen(crlFile, "r"); if (fp == NULL) { LogError(0, RS_RET_CRL_MISSING, "Error: CRL could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "fopen"); ABORT_FINALIZE(RS_RET_CRL_MISSING); } X509_CRL *crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); fclose(fp); if (crl == NULL) { LogError(0, RS_RET_CRL_INVALID, "Error: Unable to read CRL." "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "PEM_read_X509_CRL"); ABORT_FINALIZE(RS_RET_CRL_INVALID); } // Add the CRL to the X509_STORE if (!X509_STORE_add_crl(store, crl)) { LogError(0, RS_RET_CRL_INVALID, "Error: Unable to add CRL to store." "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "X509_STORE_add_crl"); X509_CRL_free(crl); ABORT_FINALIZE(RS_RET_CRL_INVALID); } // Set the X509_STORE to the SSL_CTX // SSL_CTX_set_cert_store(pThis->ctx, store); // Enable CRL checking X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); SSL_CTX_set1_param(pThis->ctx, param); X509_VERIFY_PARAM_free(param); #else LogError(0, RS_RET_SYS_ERR, "Warning: TLS library does not support X509_STORE_load_file" "(requires OpenSSL 3.x or higher). Cannot use Certificate revocation list (CRL) '%s'.", crlFile); #endif #endif } if (bHaveCert == 1 && SSL_CTX_use_certificate_chain_file(pThis->ctx, certFile) != 1) { LogError(0, RS_RET_TLS_CERT_ERR, "Error: Certificate file could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "SSL_CTX_use_certificate_chain_file"); ABORT_FINALIZE(RS_RET_TLS_CERT_ERR); } if (bHaveKey == 1 && SSL_CTX_use_PrivateKey_file(pThis->ctx, keyFile, SSL_FILETYPE_PEM) != 1) { LogError(0, RS_RET_TLS_KEY_ERR, "Error: Key could not be accessed. " "Check at least: 1) file path is correct, 2) file exist, " "3) permissions are correct, 4) file content is correct. " "OpenSSL error info may follow in next messages"); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "osslCtxInit", "SSL_CTX_use_PrivateKey_file"); ABORT_FINALIZE(RS_RET_TLS_KEY_ERR); } /* Set CTX Options */ SSL_CTX_set_options(pThis->ctx, SSL_OP_NO_SSLv2); /* Disable insecure SSLv2 Protocol */ SSL_CTX_set_options(pThis->ctx, SSL_OP_NO_SSLv3); /* Disable insecure SSLv3 Protocol */ SSL_CTX_sess_set_cache_size(pThis->ctx, 1024); /* TODO: make configurable? */ /* Set default VERIFY Options for OpenSSL CTX - and CALLBACK */ if (pThis->authMode == OSSL_AUTH_CERTANON) { dbgprintf("osslCtxInit: SSL_VERIFY_NONE\n"); net_ossl_set_ctx_verify_callback(pThis->ctx, SSL_VERIFY_NONE); } else { dbgprintf("osslCtxInit: SSL_VERIFY_PEER\n"); net_ossl_set_ctx_verify_callback(pThis->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); } SSL_CTX_set_timeout(pThis->ctx, 30); /* Default Session Timeout, TODO: Make configureable */ SSL_CTX_set_mode(pThis->ctx, SSL_MODE_AUTO_RETRY); #if OPENSSL_VERSION_NUMBER >= 0x10100000L /* Enable Support for automatic ephemeral/temporary DH parameter selection. */ SSL_CTX_set_dh_auto(pThis->ctx, 1); #endif #if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER <= 0x101010FFL /* Enable Support for automatic EC temporary key parameter selection. */ SSL_CTX_set_ecdh_auto(pThis->ctx, 1); #else /* * SSL_CTX_set_ecdh_auto and SSL_CTX_set_tmp_ecdh are depreceated in higher * OpenSSL Versions, so we no more need them - see for more: * https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ecdh_auto.html */ #endif #else dbgprintf( "osslCtxInit: openssl to old, cannot use SSL_CTX_set_ecdh_auto." "Using SSL_CTX_set_tmp_ecdh with NID_X9_62_prime256v1/() instead.\n"); SSL_CTX_set_tmp_ecdh(pThis->ctx, EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); #endif finalize_it: RETiRet; } /* Helper function to print usefull OpenSSL errors */ void net_ossl_lastOpenSSLErrorMsg( uchar *fromHost, int ret, SSL *ssl, int severity, const char *pszCallSource, const char *pszOsslApi) { unsigned long un_error = 0; int iSSLErr = 0; if (ssl == NULL) { /* Output Error Info*/ DBGPRINTF("lastOpenSSLErrorMsg: Error in '%s' with ret=%d\n", pszCallSource, ret); } else { /* if object is set, get error code */ iSSLErr = SSL_get_error(ssl, ret); /* Output Debug as well */ DBGPRINTF( "lastOpenSSLErrorMsg: %s Error in '%s': '%s(%d)' with ret=%d, errno=%d(%s), sslapi='%s'\n", (iSSLErr == SSL_ERROR_SSL ? "SSL_ERROR_SSL" : (iSSLErr == SSL_ERROR_SYSCALL ? "SSL_ERROR_SYSCALL" : "SSL_ERROR_UNKNOWN")), pszCallSource, ERR_error_string(iSSLErr, NULL), iSSLErr, ret, errno, strerror(errno), pszOsslApi); /* Output error message */ LogMsg(0, RS_RET_NO_ERRCODE, severity, "%s Error in '%s': '%s(%d)' with ret=%d, errno=%d(%s), sslapi='%s'\n", (iSSLErr == SSL_ERROR_SSL ? "SSL_ERROR_SSL" : (iSSLErr == SSL_ERROR_SYSCALL ? "SSL_ERROR_SYSCALL" : "SSL_ERROR_UNKNOWN")), pszCallSource, ERR_error_string(iSSLErr, NULL), iSSLErr, ret, errno, strerror(errno), pszOsslApi); } /* Loop through ERR_get_error */ while ((un_error = ERR_get_error()) > 0) { LogMsg(0, RS_RET_NO_ERRCODE, severity, "net_ossl:remote '%s' OpenSSL Error Stack: %s", fromHost, ERR_error_string(un_error, NULL)); } } #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) /* initialize tls config commands in openssl context */ rsRetVal net_ossl_apply_tlscgfcmd(net_ossl_t *pThis, uchar *tlscfgcmd) { DEFiRet; char *pCurrentPos; char *pNextPos; char *pszCmd; char *pszValue; int iConfErr; if (tlscfgcmd == NULL) { FINALIZE; } dbgprintf("net_ossl_apply_tlscgfcmd: Apply tlscfgcmd: '%s'\n", tlscfgcmd); /* Set working pointer */ pCurrentPos = (char *)tlscfgcmd; if (pCurrentPos != NULL && strlen(pCurrentPos) > 0) { // Create CTX Config Helper SSL_CONF_CTX *cctx; cctx = SSL_CONF_CTX_new(); if (pThis->sslState == osslServer) { SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); } else { SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); } SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS); SSL_CONF_CTX_set_ssl_ctx(cctx, pThis->ctx); do { pNextPos = index(pCurrentPos, '='); if (pNextPos != NULL) { while (*pCurrentPos != '\0' && (*pCurrentPos == ' ' || *pCurrentPos == '\t')) pCurrentPos++; pszCmd = strndup(pCurrentPos, pNextPos - pCurrentPos); pCurrentPos = pNextPos + 1; pNextPos = index(pCurrentPos, '\n'); pNextPos = (pNextPos == NULL ? index(pCurrentPos, ';') : pNextPos); pszValue = (pNextPos == NULL ? strdup(pCurrentPos) : strndup(pCurrentPos, pNextPos - pCurrentPos)); pCurrentPos = (pNextPos == NULL ? NULL : pNextPos + 1); /* Add SSL Conf Command */ iConfErr = SSL_CONF_cmd(cctx, pszCmd, pszValue); if (iConfErr > 0) { dbgprintf( "net_ossl_apply_tlscgfcmd: Successfully added Command " "'%s':'%s'\n", pszCmd, pszValue); } else { LogError(0, RS_RET_SYS_ERR, "Failed to added Command: %s:'%s' " "in net_ossl_apply_tlscgfcmd with error '%d'", pszCmd, pszValue, iConfErr); } free(pszCmd); free(pszValue); } else { /* Abort further parsing */ pCurrentPos = NULL; } } while (pCurrentPos != NULL); /* Finalize SSL Conf */ iConfErr = SSL_CONF_CTX_finish(cctx); if (!iConfErr) { LogError(0, RS_RET_SYS_ERR, "Error: setting openssl command parameters: %s" "OpenSSL error info may follow in next messages", tlscfgcmd); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "net_ossl_apply_tlscgfcmd", "SSL_CONF_CTX_finish"); } SSL_CONF_CTX_free(cctx); } finalize_it: RETiRet; } #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L /* Convert a fingerprint to printable data. The conversion is carried out * according IETF I-D syslog-transport-tls-12. The fingerprint string is * returned in a new cstr object. It is the caller's responsibility to * destruct that object. * rgerhards, 2008-05-08 */ static rsRetVal net_ossl_genfingerprintstr(uchar *pFingerprint, size_t sizeFingerprint, cstr_t **ppStr, const char *prefix) { cstr_t *pStr = NULL; uchar buf[4]; size_t i; DEFiRet; CHKiRet(rsCStrConstruct(&pStr)); CHKiRet(rsCStrAppendStrWithLen(pStr, (uchar *)prefix, strlen(prefix))); for (i = 0; i < sizeFingerprint; ++i) { snprintf((char *)buf, sizeof(buf), ":%2.2X", pFingerprint[i]); CHKiRet(rsCStrAppendStrWithLen(pStr, buf, 3)); } cstrFinalize(pStr); *ppStr = pStr; finalize_it: if (iRet != RS_RET_OK) { if (pStr != NULL) rsCStrDestruct(&pStr); } RETiRet; } /* Perform a match on ONE peer name obtained from the certificate. This name * is checked against the set of configured credentials. *pbFoundPositiveMatch is * set to 1 if the ID matches. *pbFoundPositiveMatch must have been initialized * to 0 by the caller (this is a performance enhancement as we expect to be * called multiple times). * TODO: implemet wildcards? * rgerhards, 2008-05-26 */ static rsRetVal net_ossl_chkonepeername(net_ossl_t *pThis, X509 *certpeer, uchar *pszPeerID, int *pbFoundPositiveMatch) { permittedPeers_t *pPeer; #if OPENSSL_VERSION_NUMBER >= 0x10002000L int osslRet; unsigned int x509flags = 0; #endif char *x509name = NULL; DEFiRet; if (certpeer == NULL) { ABORT_FINALIZE(RS_RET_TLS_NO_CERT); } ISOBJ_TYPE_assert(pThis, net_ossl); assert(pszPeerID != NULL); assert(pbFoundPositiveMatch != NULL); /* Obtain Namex509 name from subject */ x509name = X509_NAME_oneline(RSYSLOG_X509_NAME_oneline(certpeer), NULL, 0); if (pThis->pPermPeers) { /* do we have configured peer IDs? */ pPeer = pThis->pPermPeers; while (pPeer != NULL) { CHKiRet(net.PermittedPeerWildcardMatch(pPeer, pszPeerID, pbFoundPositiveMatch)); if (*pbFoundPositiveMatch) break; #if OPENSSL_VERSION_NUMBER >= 0x10002000L /* if we did not succeed so far, try ossl X509_check_host * ( Includes check against SubjectAlternativeName ) * if prioritizeSAN set, only check against SAN */ if (pThis->bSANpriority == 1) { #if OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER) x509flags = X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; #else dbgprintf("net_ossl_chkonepeername: PrioritizeSAN not supported before OpenSSL 1.1.0\n"); #endif // OPENSSL_VERSION_NUMBER >= 0x10100004L } osslRet = X509_check_host(certpeer, (const char *)pPeer->pszID, strlen((const char *)pPeer->pszID), x509flags, NULL); if (osslRet == 1) { /* Found Peer cert in allowed Peerslist */ dbgprintf("net_ossl_chkonepeername: Client ('%s') is allowed (X509_check_host)\n", x509name); *pbFoundPositiveMatch = 1; break; } else if (osslRet < 0) { net_ossl_lastOpenSSLErrorMsg(NULL, osslRet, NULL, LOG_ERR, "net_ossl_chkonepeername", "X509_check_host"); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } #endif /* Check next peer */ pPeer = pPeer->pNext; } } else { LogMsg(0, RS_RET_TLS_NO_CERT, LOG_WARNING, "net_ossl_chkonepeername: Peername check could not be done: " "no peernames configured."); } finalize_it: if (x509name != NULL) { OPENSSL_free(x509name); } RETiRet; } /* Check the peer's ID in fingerprint auth mode. * rgerhards, 2008-05-22 */ rsRetVal net_ossl_peerfingerprint(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP) { DEFiRet; unsigned int n; uchar fingerprint[20 /*EVP_MAX_MD_SIZE**/]; uchar fingerprintSha256[32 /*EVP_MAX_MD_SIZE**/]; size_t size; size_t sizeSha256; cstr_t *pstrFingerprint = NULL; cstr_t *pstrFingerprintSha256 = NULL; int bFoundPositiveMatch; permittedPeers_t *pPeer; const EVP_MD *fdig = EVP_sha1(); const EVP_MD *fdigSha256 = EVP_sha256(); ISOBJ_TYPE_assert(pThis, net_ossl); if (certpeer == NULL) { ABORT_FINALIZE(RS_RET_TLS_NO_CERT); } /* obtain the SHA1 fingerprint */ size = sizeof(fingerprint); if (!X509_digest(certpeer, fdig, fingerprint, &n)) { dbgprintf("net_ossl_peerfingerprint: error X509cert is not valid!\n"); ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } sizeSha256 = sizeof(fingerprintSha256); if (!X509_digest(certpeer, fdigSha256, fingerprintSha256, &n)) { dbgprintf("net_ossl_peerfingerprint: error X509cert is not valid!\n"); ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } CHKiRet(net_ossl_genfingerprintstr(fingerprint, size, &pstrFingerprint, "SHA1")); dbgprintf("net_ossl_peerfingerprint: peer's certificate SHA1 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprint)); CHKiRet(net_ossl_genfingerprintstr(fingerprintSha256, sizeSha256, &pstrFingerprintSha256, "SHA256")); dbgprintf("net_ossl_peerfingerprint: peer's certificate SHA256 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprintSha256)); /* now search through the permitted peers to see if we can find a permitted one */ bFoundPositiveMatch = 0; pPeer = pThis->pPermPeers; while (pPeer != NULL && !bFoundPositiveMatch) { if (!rsCStrSzStrCmp(pstrFingerprint, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("net_ossl_peerfingerprint: peer's certificate SHA1 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else if (!rsCStrSzStrCmp(pstrFingerprintSha256, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("net_ossl_peerfingerprint: peer's certificate SHA256 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else { dbgprintf("net_ossl_peerfingerprint: NOMATCH peer certificate: %s\n", pPeer->pszID); pPeer = pPeer->pNext; } } if (!bFoundPositiveMatch) { dbgprintf("net_ossl_peerfingerprint: invalid peer fingerprint, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { errno = 0; LogMsg(0, RS_RET_INVALID_FINGERPRINT, LOG_WARNING, "net_ossl:TLS session terminated with remote syslog server '%s': " "Fingerprint check failed, not permitted to talk to %s", fromHostIP, cstrGetSzStrNoNULL(pstrFingerprint)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } finalize_it: if (pstrFingerprint != NULL) cstrDestruct(&pstrFingerprint); if (pstrFingerprintSha256 != NULL) cstrDestruct(&pstrFingerprintSha256); RETiRet; } /* Check the peer's ID in name auth mode. */ rsRetVal net_ossl_chkpeername(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP) { DEFiRet; uchar lnBuf[256]; int bFoundPositiveMatch; cstr_t *pStr = NULL; char *x509name = NULL; ISOBJ_TYPE_assert(pThis, net_ossl); bFoundPositiveMatch = 0; CHKiRet(rsCStrConstruct(&pStr)); /* Obtain Namex509 name from subject */ x509name = X509_NAME_oneline(RSYSLOG_X509_NAME_oneline(certpeer), NULL, 0); dbgprintf("net_ossl_chkpeername: checking - peername '%s' on server '%s'\n", x509name, fromHostIP); snprintf((char *)lnBuf, sizeof(lnBuf), "name: %s; ", x509name); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(net_ossl_chkonepeername(pThis, certpeer, (uchar *)x509name, &bFoundPositiveMatch)); if (!bFoundPositiveMatch) { dbgprintf("net_ossl_chkpeername: invalid peername, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { cstrFinalize(pStr); errno = 0; LogMsg(0, RS_RET_INVALID_FINGERPRINT, LOG_WARNING, "net_ossl:TLS session terminated with remote syslog server: " "peer name not authorized, not permitted to talk to %s", cstrGetSzStrNoNULL(pStr)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } else { dbgprintf("net_ossl_chkpeername: permitted to talk!\n"); } finalize_it: if (x509name != NULL) { OPENSSL_free(x509name); } if (pStr != NULL) rsCStrDestruct(&pStr); RETiRet; } /* check the ID of the remote peer - used for both fingerprint and * name authentication. */ X509 *net_ossl_getpeercert(net_ossl_t *pThis, SSL *ssl, uchar *fromHostIP) { X509 *certpeer; ISOBJ_TYPE_assert(pThis, net_ossl); /* Get peer certificate from SSL */ certpeer = SSL_get_peer_certificate(ssl); if (certpeer == NULL) { if (pThis->bReportAuthErr == 1 && 1) { errno = 0; pThis->bReportAuthErr = 0; LogMsg(0, RS_RET_TLS_NO_CERT, LOG_WARNING, "net_ossl:TLS session terminated with remote syslog server '%s': " "Peer check failed, peer did not provide a certificate.", fromHostIP); } } return certpeer; } /* Verify the validity of the remote peer's certificate. */ rsRetVal net_ossl_chkpeercertvalidity(net_ossl_t __attribute__((unused)) * pThis, SSL *ssl, uchar *fromHostIP) { DEFiRet; int iVerErr = X509_V_OK; ISOBJ_TYPE_assert(pThis, net_ossl); PermitExpiredCerts *pPermitExpiredCerts = (PermitExpiredCerts *)SSL_get_ex_data(ssl, 1); iVerErr = SSL_get_verify_result(ssl); if (iVerErr != X509_V_OK) { if (iVerErr == X509_V_ERR_CERT_HAS_EXPIRED) { if (pPermitExpiredCerts != NULL && *pPermitExpiredCerts == OSSL_EXPIRED_DENY) { LogMsg(0, RS_RET_CERT_EXPIRED, LOG_INFO, "net_ossl:TLS session terminated with remote syslog server '%s': " "not permitted to talk to peer, certificate invalid: " "Certificate expired: %s", fromHostIP, X509_verify_cert_error_string(iVerErr)); ABORT_FINALIZE(RS_RET_CERT_EXPIRED); } else if (pPermitExpiredCerts != NULL && *pPermitExpiredCerts == OSSL_EXPIRED_WARN) { LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "net_ossl:CertValidity check - warning talking to peer '%s': " "certificate expired: %s", fromHostIP, X509_verify_cert_error_string(iVerErr)); } else { dbgprintf( "net_ossl_chkpeercertvalidity: talking to peer '%s': " "certificate expired: %s\n", fromHostIP, X509_verify_cert_error_string(iVerErr)); } /* Else do nothing */ } else if (iVerErr == X509_V_ERR_CERT_REVOKED) { LogMsg(0, RS_RET_CERT_REVOKED, LOG_INFO, "net_ossl:TLS session terminated with remote syslog server '%s': " "not permitted to talk to peer, certificate invalid: " "certificate revoked '%s'", fromHostIP, X509_verify_cert_error_string(iVerErr)); ABORT_FINALIZE(RS_RET_CERT_EXPIRED); } else { LogMsg(0, RS_RET_CERT_INVALID, LOG_INFO, "net_ossl:TLS session terminated with remote syslog server '%s': " "not permitted to talk to peer, certificate validation failed: %s", fromHostIP, X509_verify_cert_error_string(iVerErr)); ABORT_FINALIZE(RS_RET_CERT_INVALID); } } else { dbgprintf("net_ossl_chkpeercertvalidity: client certificate validation success: %s\n", X509_verify_cert_error_string(iVerErr)); } finalize_it: RETiRet; } /* Verify Callback for X509 Certificate validation. Force visibility as this function is not called anywhere but * only used as callback! */ int net_ossl_verify_callback(int status, X509_STORE_CTX *store) { char szdbgdata1[256]; char szdbgdata2[256]; dbgprintf("verify_callback: status %d\n", status); if (status == 0) { /* Retrieve all needed pointers */ X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); SSL *ssl = X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()); int iVerifyMode = SSL_get_verify_mode(ssl); nsd_t *pNsdTcp = (nsd_t *)SSL_get_ex_data(ssl, 0); PermitExpiredCerts *pPermitExpiredCerts = (PermitExpiredCerts *)SSL_get_ex_data(ssl, 1); dbgprintf("verify_callback: Certificate validation failed, Mode (%d)!\n", iVerifyMode); X509_NAME_oneline(X509_get_issuer_name(cert), szdbgdata1, sizeof(szdbgdata1)); X509_NAME_oneline(RSYSLOG_X509_NAME_oneline(cert), szdbgdata2, sizeof(szdbgdata2)); uchar *fromHost = NULL; if (pNsdTcp != NULL) { nsd_ptcp.GetRemoteHName(pNsdTcp, &fromHost); } if (iVerifyMode != SSL_VERIFY_NONE) { /* Handle expired Certificates **/ if (err == X509_V_OK || err == X509_V_ERR_CERT_HAS_EXPIRED) { if (pPermitExpiredCerts != NULL && *pPermitExpiredCerts == OSSL_EXPIRED_PERMIT) { dbgprintf( "verify_callback: EXPIRED cert but PERMITTED at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err)); /* Set Status to OK*/ status = 1; } else if (pPermitExpiredCerts != NULL && *pPermitExpiredCerts == OSSL_EXPIRED_WARN) { LogMsg(0, RS_RET_CERT_EXPIRED, LOG_WARNING, "Certificate EXPIRED warning at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s peer '%s'", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err), fromHost); /* Set Status to OK*/ status = 1; } else /* also default - if (pPermitExpiredCerts == OSSL_EXPIRED_DENY)*/ { LogMsg(0, RS_RET_CERT_EXPIRED, LOG_ERR, "Certificate EXPIRED at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n\t" "not permitted to talk to peer '%s', certificate invalid: " "certificate expired", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err), fromHost); } } else if (err == X509_V_ERR_CERT_REVOKED) { LogMsg(0, RS_RET_CERT_REVOKED, LOG_ERR, "Certificate REVOKED at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n\t" "not permitted to talk to peer '%s', certificate invalid: " "certificate revoked", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err), fromHost); } else { /* all other error codes cause failure */ LogMsg(0, RS_RET_NO_ERRCODE, LOG_ERR, "Certificate error at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s - peer '%s'", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err), fromHost); } } else { /* do not verify certs in ANON mode, just log into debug */ dbgprintf( "verify_callback: Certificate validation DISABLED but Error at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err)); /* Set Status to OK*/ status = 1; } free(fromHost); } return status; } #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) static long RSYSLOG_BIO_debug_callback_ex(BIO *bio, int cmd, const char __attribute__((unused)) * argp, size_t __attribute__((unused)) len, int argi, long __attribute__((unused)) argl, int ret, size_t __attribute__((unused)) * processed) #else static long RSYSLOG_BIO_debug_callback( BIO *bio, int cmd, const char __attribute__((unused)) * argp, int argi, long __attribute__((unused)) argl, long ret) #endif { long ret2 = ret; long r = 1; if (BIO_CB_RETURN & cmd) r = ret; dbgprintf("openssl debugmsg: BIO[%p]: ", (void *)bio); switch (cmd) { case BIO_CB_FREE: dbgprintf("Free - %s\n", RSYSLOG_BIO_method_name(bio)); break; /* Disabled due API changes for OpenSSL 1.1.0+ */ #if OPENSSL_VERSION_NUMBER < 0x10100000L case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) dbgprintf("read(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_read(bio)); else dbgprintf("read(%d,%lu) - %s\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) dbgprintf("write(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_written(bio)); else dbgprintf("write(%d,%lu) - %s\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; #else case BIO_CB_READ: dbgprintf("read %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_WRITE: dbgprintf("write %s\n", RSYSLOG_BIO_method_name(bio)); break; #endif case BIO_CB_PUTS: dbgprintf("puts() - %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_GETS: dbgprintf("gets(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_CTRL: dbgprintf("ctrl(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_RETURN | BIO_CB_READ: dbgprintf("read return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_WRITE: dbgprintf("write return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_GETS: dbgprintf("gets return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_PUTS: dbgprintf("puts return %ld\n", ret2); break; case BIO_CB_RETURN | BIO_CB_CTRL: dbgprintf("ctrl return %ld\n", ret2); break; default: dbgprintf("bio callback - unknown type (%d)\n", cmd); break; } return (r); } #if OPENSSL_VERSION_NUMBER >= 0x10100000L // Requires at least OpenSSL v1.1.1 PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wunused_parameter static int net_ossl_generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) { unsigned char result[EVP_MAX_MD_SIZE]; unsigned int resultlength; unsigned char *sslHello; unsigned int length; sslHello = (unsigned char *)"rsyslog"; length = strlen((char *)sslHello); // Generate the cookie using SHA256 hash if (!EVP_Digest(sslHello, length, result, &resultlength, EVP_sha256(), NULL)) { return 0; } memcpy(cookie, result, resultlength); *cookie_len = resultlength; dbgprintf("net_ossl_generate_cookie: generate cookie SUCCESS\n"); return 1; } PRAGMA_DIAGNOSTIC_POP static int net_ossl_verify_cookie(SSL *ssl, const unsigned char *cookie, unsigned int cookie_len) { unsigned char cookie_gen[EVP_MAX_MD_SIZE]; unsigned int cookie_gen_len; // Generate a cookie using the same method as in net_ossl_generate_cookie if (!net_ossl_generate_cookie(ssl, cookie_gen, &cookie_gen_len)) { dbgprintf("net_ossl_verify_cookie: generate cookie FAILED\n"); return 0; } // Check if the generated cookie matches the cookie received if (cookie_len == cookie_gen_len && memcmp(cookie, cookie_gen, cookie_len) == 0) { dbgprintf("net_ossl_verify_cookie: compare cookie SUCCESS\n"); return 1; } dbgprintf("net_ossl_verify_cookie: compare cookie FAILED\n"); return 0; } static rsRetVal net_ossl_init_engine(__attribute__((unused)) net_ossl_t *pThis) { // OpenSSL Engine Support feature relies on an outdated version of OpenSSL and is // strictly experimental. No support or guarantees are provided. Use at your own risk. DEFiRet; #ifndef OPENSSL_NO_ENGINE const char *engine_id = NULL; const char *engine_name = NULL; PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wdeprecated_declarations // Get the default RSA engine ENGINE *default_engine = ENGINE_get_default_RSA(); if (default_engine) { engine_id = ENGINE_get_id(default_engine); engine_name = ENGINE_get_name(default_engine); DBGPRINTF("net_ossl_init_engine: Default RSA Engine: ID = %s, Name = %s\n", engine_id, engine_name); // Free the engine reference when done ENGINE_free(default_engine); } else { DBGPRINTF("net_ossl_init_engine: No default RSA Engine set.\n"); } /* Setting specific Engine */ if (runConf != NULL && glbl.GetDfltOpensslEngine(runConf) != NULL) { default_engine = ENGINE_by_id((char *)glbl.GetDfltOpensslEngine(runConf)); if (default_engine && ENGINE_init(default_engine)) { /* engine initialised */ ENGINE_set_default_DSA(default_engine); ENGINE_set_default_ciphers(default_engine); /* Switch to Engine */ DBGPRINTF("net_ossl_init_engine: Changed default Engine to %s\n", glbl.GetDfltOpensslEngine(runConf)); /* Release the functional reference from ENGINE_init() */ ENGINE_finish(default_engine); } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: ENGINE_init failed to load Engine '%s'" "ossl netstream driver", glbl.GetDfltOpensslEngine(runConf)); net_ossl_lastOpenSSLErrorMsg(NULL, 0, NULL, LOG_ERR, "net_ossl_init_engine", "ENGINE_init"); } // Free the engine reference when done ENGINE_free(default_engine); } else { DBGPRINTF("net_ossl_init_engine: use openssl default Engine"); } PRAGMA_DIAGNOSTIC_POP #else DBGPRINTF("net_ossl_init_engine: OpenSSL compiled without ENGINE support - ENGINE support disabled\n"); #endif /* OPENSSL_NO_ENGINE */ RETiRet; } static rsRetVal net_ossl_ctx_init_cookie(net_ossl_t *pThis) { DEFiRet; // Set our cookie generation and verification callbacks SSL_CTX_set_options(pThis->ctx, SSL_OP_COOKIE_EXCHANGE); SSL_CTX_set_cookie_generate_cb(pThis->ctx, net_ossl_generate_cookie); SSL_CTX_set_cookie_verify_cb(pThis->ctx, net_ossl_verify_cookie); RETiRet; } #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L /* ------------------------------ end OpenSSL helpers ------------------------------------------*/ /* ------------------------------ OpenSSL Callback set helpers ---------------------------------*/ void net_ossl_set_ssl_verify_callback(SSL *pSsl, int flags) { /* Enable certificate valid checking */ SSL_set_verify(pSsl, flags, net_ossl_verify_callback); } void net_ossl_set_ctx_verify_callback(SSL_CTX *pCtx, int flags) { /* Enable certificate valid checking */ SSL_CTX_set_verify(pCtx, flags, net_ossl_verify_callback); } void net_ossl_set_bio_callback(BIO *conn) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) BIO_set_callback_ex(conn, RSYSLOG_BIO_debug_callback_ex); #else BIO_set_callback(conn, RSYSLOG_BIO_debug_callback); #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L } /* ------------------------------ End OpenSSL Callback set helpers -----------------------------*/ /* Standard-Constructor */ BEGINobjConstruct(net_ossl) /* be sure to specify the object type also in END macro! */ DBGPRINTF("net_ossl_construct: [%p]\n", pThis); pThis->bReportAuthErr = 1; pThis->bSANpriority = 0; #if OPENSSL_VERSION_NUMBER >= 0x10100000L CHKiRet(net_ossl_init_engine(pThis)); finalize_it: #endif ENDobjConstruct(net_ossl) /* destructor for the net_ossl object */ BEGINobjDestruct(net_ossl) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(net_ossl); DBGPRINTF("net_ossl_destruct: [%p]\n", pThis); /* Free SSL obj also if we do not have a session - or are NOT in TLS mode! */ if (pThis->ssl != NULL) { DBGPRINTF("net_ossl_destruct: [%p] FREE pThis->ssl \n", pThis); SSL_free(pThis->ssl); pThis->ssl = NULL; } if (pThis->ctx != NULL && !pThis->ctx_is_copy) { SSL_CTX_free(pThis->ctx); } free((void *)pThis->pszCAFile); free((void *)pThis->pszCRLFile); free((void *)pThis->pszKeyFile); free((void *)pThis->pszCertFile); free((void *)pThis->pszExtraCAFiles); ENDobjDestruct(net_ossl) /* queryInterface function */ BEGINobjQueryInterface(net_ossl) CODESTARTobjQueryInterface(net_ossl); DBGPRINTF("netosslQueryInterface\n"); if (pIf->ifVersion != net_osslCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } pIf->Construct = (rsRetVal(*)(net_ossl_t **))net_osslConstruct; pIf->Destruct = (rsRetVal(*)(net_ossl_t **))net_osslDestruct; pIf->osslCtxInit = net_ossl_osslCtxInit; pIf->osslChkpeername = net_ossl_chkpeername; pIf->osslPeerfingerprint = net_ossl_peerfingerprint; pIf->osslGetpeercert = net_ossl_getpeercert; pIf->osslChkpeercertvalidity = net_ossl_chkpeercertvalidity; #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) pIf->osslApplyTlscgfcmd = net_ossl_apply_tlscgfcmd; #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L pIf->osslSetBioCallback = net_ossl_set_bio_callback; pIf->osslSetCtxVerifyCallback = net_ossl_set_ctx_verify_callback; pIf->osslSetSslVerifyCallback = net_ossl_set_ssl_verify_callback; pIf->osslLastOpenSSLErrorMsg = net_ossl_lastOpenSSLErrorMsg; #if OPENSSL_VERSION_NUMBER >= 0x10100000L pIf->osslCtxInitCookie = net_ossl_ctx_init_cookie; pIf->osslInitEngine = net_ossl_init_engine; #endif finalize_it: ENDobjQueryInterface(net_ossl) /* exit our class */ BEGINObjClassExit(net_ossl, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(net_ossl); DBGPRINTF("netosslClassExit\n"); /* release objects we no longer need */ objRelease(nsd_ptcp, LM_NSD_PTCP_FILENAME); objRelease(net, LM_NET_FILENAME); objRelease(glbl, CORE_COMPONENT); /* shut down OpenSSL */ osslGlblExit(); ENDObjClassExit(net_ossl) /* Initialize the net_ossl class. Must be called as the very first method * before anything else is called inside this class. */ BEGINObjClassInit(net_ossl, 1, OBJ_IS_CORE_MODULE) /* class, version */ DBGPRINTF("net_osslClassInit\n"); // request objects we use CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(nsd_ptcp, LM_NSD_PTCP_FILENAME)); // Do global TLS init stuff osslGlblInit(); ENDObjClassInit(net_ossl) /* --------------- here now comes the plumbing that makes as a library module --------------- */ /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/var.c0000644000000000000000000000013215055605325015156 xustar0030 mtime=1756826325.654800759 30 atime=1764930993.383901352 30 ctime=1764935923.239577438 rsyslog-8.2512.0/runtime/var.c0000664000175000017500000001013315055605325014620 0ustar00rgerrger/* var.c - a typeless variable class * * This class is used to represent variable values, which may have any type. * Among others, it will be used inside rsyslog's expression system, but * also internally at any place where a typeless variable is needed. * * Module begun 2008-02-20 by Rainer Gerhards, with some code taken * from the obj.c/.h files. * * Copyright 2007-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "obj.h" #include "srUtils.h" #include "var.h" /* static data */ DEFobjStaticHelpers; /* Standard-Constructor */ BEGINobjConstruct(var) /* be sure to specify the object type also in END macro! */ ENDobjConstruct(var) /* ConstructionFinalizer * rgerhards, 2008-01-09 */ static rsRetVal varConstructFinalize(var_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, var); RETiRet; } /* destructor for the var object */ BEGINobjDestruct(var) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(var); if (pThis->pcsName != NULL) rsCStrDestruct(&pThis->pcsName); if (pThis->varType == VARTYPE_STR) { if (pThis->val.pStr != NULL) rsCStrDestruct(&pThis->val.pStr); } ENDobjDestruct(var) /* DebugPrint support for the var object */ BEGINobjDebugPrint(var) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(var); switch (pThis->varType) { case VARTYPE_STR: dbgoprint((obj_t*)pThis, "type: cstr, val '%s'\n", rsCStrGetSzStrNoNULL(pThis->val.pStr)); break; case VARTYPE_NUMBER: dbgoprint((obj_t*)pThis, "type: number, val %lld\n", pThis->val.num); break; case VARTYPE_SYSLOGTIME: case VARTYPE_NONE: default: dbgoprint((obj_t*)pThis, "type %d currently not supported in debug output\n", pThis->varType); break; } ENDobjDebugPrint(var) /* queryInterface function * rgerhards, 2008-02-21 */ BEGINobjQueryInterface(var) CODESTARTobjQueryInterface(var); if (pIf->ifVersion != varCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = varConstruct; pIf->ConstructFinalize = varConstructFinalize; pIf->Destruct = varDestruct; pIf->DebugPrint = varDebugPrint; finalize_it: ENDobjQueryInterface(var) /* Initialize the var class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(var, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ /* now set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, varDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, varConstructFinalize); ENDObjClassInit(var) /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/regexp.h0000644000000000000000000000013115055605325015664 xustar0030 mtime=1756826325.651800713 29 atime=1764930980.03067839 30 ctime=1764935923.384579658 rsyslog-8.2512.0/runtime/regexp.h0000664000175000017500000000316115055605325015332 0ustar00rgerrger/* The regexp object. It encapsulates the C regexp functionality. The primary * purpose of this wrapper class is to enable rsyslogd core to be build without * regexp libraries. * * Copyright 2008-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_REGEXP_H #define INCLUDED_REGEXP_H #include /* interfaces */ BEGINinterface(regexp) /* name must also be changed in ENDinterface macro! */ int (*regcomp)(regex_t *preg, const char *regex, int cflags); int (*regexec)(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); size_t (*regerror)(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); void (*regfree)(regex_t *preg); ENDinterface(regexp) #define regexpCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(regexp); /* the name of our library binary */ #define LM_REGEXP_FILENAME "lmregexp" #endif /* #ifndef INCLUDED_REGEXP_H */ rsyslog-8.2512.0/runtime/PaxHeaders/syslogd-types.h0000644000000000000000000000013215055605325017221 xustar0030 mtime=1756826325.653800744 30 atime=1764930979.976677487 30 ctime=1764935923.113575509 rsyslog-8.2512.0/runtime/syslogd-types.h0000664000175000017500000000774015055605325016675 0ustar00rgerrger/* syslogd-type.h * This file contains type defintions used by syslogd and its modules. * It is a required input for any module. * * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c) * * Copyright 2007-2018 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SYSLOGD_TYPES_INCLUDED #define SYSLOGD_TYPES_INCLUDED 1 #include "stringbuf.h" #include /* we use RSTRUE/FALSE to prevent name claches with other packages */ #define RSFALSE 0 #define RSTRUE 1 #define MAXFNAME 4096 /* max file pathname length */ #define _DB_MAXCONNINFOLEN 2048 /* maximum length connection string */ #define _DB_MAXDBLEN 128 /* maximum number of db */ #define _DB_MAXUNAMELEN 128 /* maximum number of user name */ #define _DB_MAXPWDLEN 128 /* maximum number of user's pass */ #define _DB_DELAYTIMEONERROR 20 /* If an error occur we stop logging until a delayed time is over */ /* we define features of the syslog code. This features can be used * to check if modules are compatible with them - and possible other * applications I do not yet envision. -- rgerhards, 2007-07-24 */ typedef enum _syslogFeature { sFEATURERepeatedMsgReduction = 1, /* for output modules */ sFEATURENonCancelInputTermination = 2, /* for input modules */ sFEATUREAutomaticSanitazion = 3, /* for parser modules */ sFEATUREAutomaticPRIParsing = 4 /* for parser modules */ } syslogFeature; /* we define our own facility and severities */ /* facility and severity codes */ typedef struct _syslogCode { char *c_name; int c_val; } syslogCODE; /* values for host comparisons specified with host selector blocks * (+host, -host). rgerhards 2005-10-18. */ enum _EHostnameCmpMode { HN_NO_COMP = 0, /* do not compare hostname */ HN_COMP_MATCH = 1, /* hostname must match */ HN_COMP_NOMATCH = 2 /* hostname must NOT match */ }; typedef enum _EHostnameCmpMode EHostnameCmpMode; /* time type numerical values for structure below */ #define TIME_TYPE_UNINIT 0 #define TIME_TYPE_RFC3164 1 #define TIME_TYPE_RFC5424 2 /* rgerhards 2004-11-11: the following structure represents * a time as it is used in syslog. * rgerhards, 2009-06-23: packed structure for better cache performance * (but left ultimate decision about packing to compiler) */ struct syslogTime { intTiny timeType; /* 0 - unitinialized , 1 - RFC 3164, 2 - syslog-protocol */ intTiny month; intTiny day; intTiny wday; intTiny hour; /* 24 hour clock */ intTiny minute; intTiny second; intTiny secfracPrecision; intTiny OffsetMinute; /* UTC offset in minutes */ intTiny OffsetHour; /* UTC offset in hours * full UTC offset minutes = OffsetHours*60 + OffsetMinute. Then use * OffsetMode to know the direction. */ char OffsetMode; /* UTC offset + or - */ short year; int secfrac; /* fractional seconds (must be 32 bit!) */ intTiny inUTC; /* forced UTC? */ }; typedef struct syslogTime syslogTime_t; struct tzinfo { char *id; char offsMode; int8_t offsHour; int8_t offsMin; }; typedef struct tzinfo tzinfo_t; typedef enum { ACT_STRING_PASSING = 0, ACT_ARRAY_PASSING = 1, ACT_MSG_PASSING = 2, ACT_JSON_PASSING = 3 } paramPassing_t; #endif /* #ifndef SYSLOGD_TYPES_INCLUDED */ /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/modules.c0000644000000000000000000000013215055605325016036 xustar0030 mtime=1756826325.647800653 30 atime=1764930989.898843237 30 ctime=1764935923.210576994 rsyslog-8.2512.0/runtime/modules.c0000664000175000017500000014725415055605325015517 0ustar00rgerrger/* modules.c * This is the implementation of syslogd modules object. * This object handles plug-ins and build-in modules of all kind. * * Modules are reference-counted. Anyone who access a module must call * Use() before any function is accessed and Release() when he is done. * When the reference count reaches 0, rsyslog unloads the module (that * may be changed in the future to cache modules). Rsyslog does NOT * unload modules with a reference count > 0, even if the unload * method is called! * * File begun on 2007-07-22 by RGerhards * * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #ifdef OS_BSD #include "libgen.h" #endif #include /* TODO: replace this with the libtools equivalent! */ #include #include #include "rsyslog.h" #include "rainerscript.h" #include "cfsysline.h" #include "rsconf.h" #include "modules.h" #include "errmsg.h" #include "parser.h" #include "strgen.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(strgen) static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */ static modInfo_t *pLoadedModulesLast = NULL; /* tail-pointer */ /* already dlopen()-ed libs */ static struct dlhandle_s *pHandles = NULL; static uchar *pModDir; /* directory where loadable modules are found */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"load", eCmdHdlrGetWord, 1}}; static struct cnfparamblk pblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; typedef rsRetVal (*pModInit_t)(int, int *, rsRetVal (**)(), rsRetVal (*)(), modInfo_t *); /* we provide a set of dummy functions for modules that do not support the * some interfaces. * On the commit feature: As the modules do not support it, they commit each message they * receive, and as such the dummies can always return RS_RET_OK without causing * harm. This simplifies things as in action processing we do not need to check * if the transactional entry points exist. */ static rsRetVal dummyBeginTransaction(__attribute__((unused)) void *dummy) { return RS_RET_OK; } static rsRetVal dummyEndTransaction(__attribute__((unused)) void *dummy) { return RS_RET_OK; } static rsRetVal dummyIsCompatibleWithFeature(__attribute__((unused)) syslogFeature eFeat) { return RS_RET_INCOMPATIBLE; } static rsRetVal dummynewActInst(uchar *modName, struct nvlst __attribute__((unused)) * dummy1, void __attribute__((unused)) * *dummy2, omodStringRequest_t __attribute__((unused)) * *dummy3) { LogError(0, RS_RET_CONFOBJ_UNSUPPORTED, "config objects are not " "supported by module '%s' -- legacy config options " "MUST be used instead", modName); return RS_RET_CONFOBJ_UNSUPPORTED; } #ifdef DEBUG /* we add some home-grown support to track our users (and detect who does not free us). In * the long term, this should probably be migrated into debug.c (TODO). -- rgerhards, 2008-03-11 */ /* add a user to the current list of users (always at the root) */ static void modUsrAdd(modInfo_t *pThis, const char *pszUsr) { modUsr_t *pUsr; if ((pUsr = calloc(1, sizeof(modUsr_t))) == NULL) goto finalize_it; if ((pUsr->pszFile = strdup(pszUsr)) == NULL) { free(pUsr); goto finalize_it; } if (pThis->pModUsrRoot != NULL) { pUsr->pNext = pThis->pModUsrRoot; } pThis->pModUsrRoot = pUsr; finalize_it: return; } /* remove a user from the current user list * rgerhards, 2008-03-11 */ static void modUsrDel(modInfo_t *pThis, const char *pszUsr) { modUsr_t *pUsr; modUsr_t *pPrev = NULL; for (pUsr = pThis->pModUsrRoot; pUsr != NULL; pUsr = pUsr->pNext) { if (!strcmp(pUsr->pszFile, pszUsr)) break; else pPrev = pUsr; } if (pUsr == NULL) { dbgprintf("oops - tried to delete user %s from module %s and it wasn't registered as one...\n", pszUsr, pThis->pszName); } else { if (pPrev == NULL) { /* This was at the root! */ pThis->pModUsrRoot = pUsr->pNext; } else { pPrev->pNext = pUsr->pNext; } /* free ressources */ free(pUsr->pszFile); free(pUsr); pUsr = NULL; /* just to make sure... */ } } /* print a short list all all source files using the module in question * rgerhards, 2008-03-11 */ static void modUsrPrint(modInfo_t *pThis) { modUsr_t *pUsr; for (pUsr = pThis->pModUsrRoot; pUsr != NULL; pUsr = pUsr->pNext) { dbgprintf("\tmodule %s is currently in use by file %s\n", pThis->pszName, pUsr->pszFile); } } /* print all loaded modules and who is accessing them. This is primarily intended * to be called at end of run to detect "module leaks" and who is causing them. * rgerhards, 2008-03-11 */ static void modUsrPrintAll(void) { modInfo_t *pMod; for (pMod = pLoadedModules; pMod != NULL; pMod = pMod->pNext) { dbgprintf("printing users of loadable module %s, refcount %u, ptr %p, type %d\n", pMod->pszName, pMod->uRefCnt, pMod, pMod->eType); modUsrPrint(pMod); } } #endif /* #ifdef DEBUG */ /* Construct a new module object */ static rsRetVal moduleConstruct(modInfo_t **pThis) { modInfo_t *pNew; if ((pNew = calloc(1, sizeof(modInfo_t))) == NULL) return RS_RET_OUT_OF_MEMORY; /* OK, we got the element, now initialize members that should * not be zero-filled. */ *pThis = pNew; return RS_RET_OK; } /* Destructs a module object. The object must not be linked to the * linked list of modules. Please note that all other dependencies on this * modules must have been removed before (e.g. CfSysLineHandlers!) */ static void moduleDestruct(modInfo_t *pThis) { assert(pThis != NULL); free(pThis->pszName); free(pThis->cnfName); if (pThis->pModHdlr != NULL) { #ifdef VALGRIND DBGPRINTF( "moduleDestruct: compiled with valgrind, do " "not unload module\n"); #else if (glblUnloadModules) { if (pThis->eKeepType == eMOD_NOKEEP) { dlclose(pThis->pModHdlr); } } else { DBGPRINTF( "moduleDestruct: not unloading module " "due to user configuration\n"); } #endif } free(pThis); } /* This enables a module to query the core for specific features. * rgerhards, 2009-04-22 */ static rsRetVal queryCoreFeatureSupport(int *pBool, unsigned uFeat) { DEFiRet; if (pBool == NULL) ABORT_FINALIZE(RS_RET_PARAM_ERROR); *pBool = (uFeat & CORE_FEATURE_BATCHING) ? 1 : 0; finalize_it: RETiRet; } /* The following function is the queryEntryPoint for host-based entry points. * Modules may call it to get access to core interface functions. Please note * that utility functions can be accessed via shared libraries - at least this * is my current shool of thinking. * Please note that the implementation as a query interface allows one to take * care of plug-in interface version differences. -- rgerhards, 2007-07-31 * ... but often it better not to use a new interface. So we now add core * functions here that a plugin may request. -- rgerhards, 2009-04-22 */ static rsRetVal queryHostEtryPt(uchar *name, rsRetVal (**pEtryPoint)()) { DEFiRet; if ((name == NULL) || (pEtryPoint == NULL)) ABORT_FINALIZE(RS_RET_PARAM_ERROR); if (!strcmp((char *)name, "regCfSysLineHdlr")) { *pEtryPoint = regCfSysLineHdlr; } else if (!strcmp((char *)name, "objGetObjInterface")) { *pEtryPoint = objGetObjInterface; } else if (!strcmp((char *)name, "OMSRgetSupportedTplOpts")) { *pEtryPoint = OMSRgetSupportedTplOpts; } else if (!strcmp((char *)name, "queryCoreFeatureSupport")) { *pEtryPoint = queryCoreFeatureSupport; } else { *pEtryPoint = NULL; /* to be on the safe side */ ABORT_FINALIZE(RS_RET_ENTRY_POINT_NOT_FOUND); } finalize_it: RETiRet; } /* get the name of a module */ uchar *modGetName(modInfo_t *pThis) { return ((pThis->pszName == NULL) ? (uchar *)"" : pThis->pszName); } /* get the state-name of a module. The state name is its name * together with a short description of the module state (which * is pulled from the module itself. * rgerhards, 2007-07-24 * TODO: the actual state name is not yet pulled */ static uchar *modGetStateName(modInfo_t *pThis) { return (modGetName(pThis)); } /* Add a module to the loaded module linked list */ static void ATTR_NONNULL() addModToGlblList(modInfo_t *const pThis) { assert(pThis != NULL); if (pLoadedModules == NULL) { pLoadedModules = pLoadedModulesLast = pThis; } else { /* there already exist entries */ pThis->pPrev = pLoadedModulesLast; pLoadedModulesLast->pNext = pThis; pLoadedModulesLast = pThis; } } /* ready module for config processing. this includes checking if the module * is already in the config, so this function may return errors. Returns a * pointer to the last module inthe current config. That pointer needs to * be passed to addModToCnfLst() when it is called later in the process. */ rsRetVal readyModForCnf(modInfo_t *pThis, cfgmodules_etry_t **ppNew, cfgmodules_etry_t **ppLast) { cfgmodules_etry_t *pNew = NULL; cfgmodules_etry_t *pLast; DEFiRet; assert(pThis != NULL); if (loadConf == NULL) { FINALIZE; /* we are in an early init state */ } /* check for duplicates and, as a side-activity, identify last node */ pLast = loadConf->modules.root; if (pLast != NULL) { while (1) { /* loop broken inside */ if (pLast->pMod == pThis) { DBGPRINTF("module '%s' already in this config\n", modGetName(pThis)); if (strncmp((char *)modGetName(pThis), "builtin:", sizeof("builtin:") - 1)) { LogError(0, RS_RET_MODULE_ALREADY_IN_CONF, "module '%s' already in this config, cannot be added\n", modGetName(pThis)); ABORT_FINALIZE(RS_RET_MODULE_ALREADY_IN_CONF); } FINALIZE; } if (pLast->next == NULL) break; pLast = pLast->next; } } /* if we reach this point, pLast is the tail pointer and this module is new * inside the currently loaded config. So, iff it is an input module, let's * pass it a pointer which it can populate with a pointer to its module conf. */ CHKmalloc(pNew = malloc(sizeof(cfgmodules_etry_t))); pNew->canActivate = 1; pNew->next = NULL; pNew->pMod = pThis; if (pThis->beginCnfLoad != NULL) { CHKiRet(pThis->beginCnfLoad(&pNew->modCnf, loadConf)); } *ppLast = pLast; *ppNew = pNew; finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) free(pNew); } RETiRet; } /* abort the creation of a module entry without adding it to the * module list. Needed to prevent mem leaks. */ static inline void abortCnfUse(cfgmodules_etry_t **pNew) { if (pNew != NULL) { free(*pNew); *pNew = NULL; } } /* Add a module to the config module list for current loadConf. * Requires last pointer obtained by readyModForCnf(). * The module pointer is handed over to this function. It is no * longer available to caller one we are called. */ rsRetVal ATTR_NONNULL(1) addModToCnfList(cfgmodules_etry_t **const pNew, cfgmodules_etry_t *const pLast) { DEFiRet; assert(*pNew != NULL); if (loadConf == NULL) { abortCnfUse(pNew); FINALIZE; /* we are in an early init state */ } if (pLast == NULL) { loadConf->modules.root = *pNew; } else { /* there already exist entries */ pLast->next = *pNew; } finalize_it: *pNew = NULL; RETiRet; } /* Get the next module pointer - this is used to traverse the list. * The function returns the next pointer or NULL, if there is no next one. * The last object must be provided to the function. If NULL is provided, * it starts at the root of the list. Even in this case, NULL may be * returned - then, the list is empty. * rgerhards, 2007-07-23 */ static modInfo_t *GetNxt(modInfo_t *pThis) { modInfo_t *pNew; if (pThis == NULL) pNew = pLoadedModules; else pNew = pThis->pNext; return (pNew); } /* this function is like GetNxt(), but it returns pointers to * the configmodules entry, which than can be used to obtain the * actual module pointer. Note that it returns those for * modules of specific type only. Only modules from the provided * config are returned. Note that processing speed could be improved, * but this is really not relevant, as config file loading is not really * something we are concerned about in regard to runtime. */ static cfgmodules_etry_t *GetNxtCnfType(rsconf_t *cnf, cfgmodules_etry_t *node, eModType_t rqtdType) { if (node == NULL) { /* start at beginning of module list */ node = cnf->modules.root; } else { node = node->next; } if (rqtdType != eMOD_ANY) { /* if any, we already have the right one! */ while (node != NULL && node->pMod->eType != rqtdType) { node = node->next; } } return node; } /* Find a module with the given conf name and type. Returns NULL if none * can be found, otherwise module found. */ static modInfo_t *FindWithCnfName(rsconf_t *cnf, uchar *name, eModType_t rqtdType) { cfgmodules_etry_t *node; ; for (node = cnf->modules.root; node != NULL; node = node->next) { if (node->pMod->eType != rqtdType || node->pMod->cnfName == NULL) continue; if (!strcasecmp((char *)node->pMod->cnfName, (char *)name)) break; } return node == NULL ? NULL : node->pMod; } /* Prepare a module for unloading. * This is currently a dummy, to be filled when we have a plug-in * interface - rgerhards, 2007-08-09 * rgerhards, 2007-11-21: * When this function is called, all instance-data must already have * been destroyed. In the case of output modules, this happens when the * rule set is being destroyed. When we implement other module types, we * need to think how we handle it there (and if we have any instance data). * rgerhards, 2008-03-10: reject unload request if the module has a reference * count > 0. */ static rsRetVal modPrepareUnload(modInfo_t *pThis) { DEFiRet; void *pModCookie; assert(pThis != NULL); if (pThis->uRefCnt > 0) { dbgprintf("rejecting unload of module '%s' because it has a refcount of %d\n", pThis->pszName, pThis->uRefCnt); ABORT_FINALIZE(RS_RET_MODULE_STILL_REFERENCED); } CHKiRet(pThis->modGetID(&pModCookie)); pThis->modExit(); /* tell the module to get ready for unload */ CHKiRet(unregCfSysLineHdlrs4Owner(pModCookie)); finalize_it: RETiRet; } /* Add an already-loaded module to the module linked list. This function does * everything needed to fully initialize the module. */ static rsRetVal doModInit(pModInit_t modInit, uchar *name, void *pModHdlr, modInfo_t **pNewModule) { rsRetVal localRet; modInfo_t *pNew = NULL; uchar *pName; strgen_t *pStrgen; /* used for strgen modules */ rsRetVal (*GetName)(uchar **); rsRetVal (*modGetType)(eModType_t *pType); rsRetVal (*modGetKeepType)(eModKeepType_t *pKeepType); struct dlhandle_s *pHandle = NULL; rsRetVal (*getModCnfName)(uchar **cnfName); uchar *cnfName; DEFiRet; assert(modInit != NULL); if ((iRet = moduleConstruct(&pNew)) != RS_RET_OK) { pNew = NULL; FINALIZE; } CHKiRet((*modInit)(CURR_MOD_IF_VERSION, &pNew->iIFVers, &pNew->modQueryEtryPt, queryHostEtryPt, pNew)); if (pNew->iIFVers != CURR_MOD_IF_VERSION) { ABORT_FINALIZE(RS_RET_MISSING_INTERFACE); } /* We now poll the module to see what type it is. We do this only once as this * can never change in the lifetime of an module. -- rgerhards, 2007-12-14 */ CHKiRet((*pNew->modQueryEtryPt)((uchar *)"getType", &modGetType)); CHKiRet((*modGetType)(&pNew->eType)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"getKeepType", &modGetKeepType)); CHKiRet((*modGetKeepType)(&pNew->eKeepType)); dbgprintf("module %s of type %d being loaded (keepType=%d).\n", name, pNew->eType, pNew->eKeepType); /* OK, we know we can successfully work with the module. So we now fill the * rest of the data elements. First we load the interfaces common to all * module types. */ CHKiRet((*pNew->modQueryEtryPt)((uchar *)"modGetID", &pNew->modGetID)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"modExit", &pNew->modExit)); localRet = (*pNew->modQueryEtryPt)((uchar *)"isCompatibleWithFeature", &pNew->isCompatibleWithFeature); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) pNew->isCompatibleWithFeature = dummyIsCompatibleWithFeature; else if (localRet != RS_RET_OK) ABORT_FINALIZE(localRet); localRet = (*pNew->modQueryEtryPt)((uchar *)"setModCnf", &pNew->setModCnf); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) pNew->setModCnf = NULL; else if (localRet != RS_RET_OK) ABORT_FINALIZE(localRet); /* optional calls for new config system */ localRet = (*pNew->modQueryEtryPt)((uchar *)"getModCnfName", &getModCnfName); if (localRet == RS_RET_OK) { if (getModCnfName(&cnfName) == RS_RET_OK) pNew->cnfName = (uchar *)strdup((char *)cnfName); /**< we do not care if strdup() fails, we can accept that */ else pNew->cnfName = NULL; dbgprintf("module config name is '%s'\n", cnfName); } localRet = (*pNew->modQueryEtryPt)((uchar *)"beginCnfLoad", &pNew->beginCnfLoad); if (localRet == RS_RET_OK) { dbgprintf("module %s supports rsyslog v6 config interface\n", name); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"endCnfLoad", &pNew->endCnfLoad)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"freeCnf", &pNew->freeCnf)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"checkCnf", &pNew->checkCnf)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"activateCnf", &pNew->activateCnf)); localRet = (*pNew->modQueryEtryPt)((uchar *)"activateCnfPrePrivDrop", &pNew->activateCnfPrePrivDrop); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->activateCnfPrePrivDrop = NULL; } else { CHKiRet(localRet); } } else if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->beginCnfLoad = NULL; /* flag as non-present */ } else { ABORT_FINALIZE(localRet); } /* ... and now the module-specific interfaces */ switch (pNew->eType) { case eMOD_IN: CHKiRet((*pNew->modQueryEtryPt)((uchar *)"runInput", &pNew->mod.im.runInput)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"willRun", &pNew->mod.im.willRun)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"afterRun", &pNew->mod.im.afterRun)); pNew->mod.im.bCanRun = 0; localRet = (*pNew->modQueryEtryPt)((uchar *)"newInpInst", &pNew->mod.im.newInpInst); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.im.newInpInst = NULL; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } localRet = (*pNew->modQueryEtryPt)((uchar *)"doHUP", &pNew->doHUP); if (localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) ABORT_FINALIZE(localRet); break; case eMOD_OUT: CHKiRet((*pNew->modQueryEtryPt)((uchar *)"freeInstance", &pNew->freeInstance)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"dbgPrintInstInfo", &pNew->dbgPrintInstInfo)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"parseSelectorAct", &pNew->mod.om.parseSelectorAct)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"tryResume", &pNew->tryResume)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"createWrkrInstance", &pNew->mod.om.createWrkrInstance)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"freeWrkrInstance", &pNew->mod.om.freeWrkrInstance)); /* try load optional interfaces */ localRet = (*pNew->modQueryEtryPt)((uchar *)"doHUP", &pNew->doHUP); if (localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) ABORT_FINALIZE(localRet); localRet = (*pNew->modQueryEtryPt)((uchar *)"doHUPWrkr", &pNew->doHUPWrkr); if (localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) ABORT_FINALIZE(localRet); localRet = (*pNew->modQueryEtryPt)((uchar *)"SetShutdownImmdtPtr", &pNew->mod.om.SetShutdownImmdtPtr); if (localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) ABORT_FINALIZE(localRet); pNew->mod.om.supportsTX = 1; localRet = (*pNew->modQueryEtryPt)((uchar *)"beginTransaction", &pNew->mod.om.beginTransaction); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.beginTransaction = dummyBeginTransaction; pNew->mod.om.supportsTX = 0; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } localRet = (*pNew->modQueryEtryPt)((uchar *)"doAction", &pNew->mod.om.doAction); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.doAction = NULL; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } localRet = (*pNew->modQueryEtryPt)((uchar *)"commitTransaction", &pNew->mod.om.commitTransaction); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.commitTransaction = NULL; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } if (pNew->mod.om.doAction == NULL && pNew->mod.om.commitTransaction == NULL) { LogError(0, RS_RET_INVLD_OMOD, "module %s does neither provide doAction() " "nor commitTransaction() interface - cannot " "load", name); ABORT_FINALIZE(RS_RET_INVLD_OMOD); } if (pNew->mod.om.commitTransaction != NULL) { if (pNew->mod.om.doAction != NULL) { LogError(0, RS_RET_INVLD_OMOD, "module %s provides both doAction() " "and commitTransaction() interface, using " "commitTransaction()", name); pNew->mod.om.doAction = NULL; } if (pNew->mod.om.beginTransaction == NULL) { LogError(0, RS_RET_INVLD_OMOD, "module %s provides both commitTransaction() " "but does not provide beginTransaction() - " "cannot load", name); ABORT_FINALIZE(RS_RET_INVLD_OMOD); } } localRet = (*pNew->modQueryEtryPt)((uchar *)"endTransaction", &pNew->mod.om.endTransaction); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.endTransaction = dummyEndTransaction; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } localRet = (*pNew->modQueryEtryPt)((uchar *)"newActInst", &pNew->mod.om.newActInst); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.newActInst = dummynewActInst; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } break; case eMOD_LIB: break; case eMOD_PARSER: localRet = (*pNew->modQueryEtryPt)((uchar *)"parse2", &pNew->mod.pm.parse2); if (localRet == RS_RET_OK) { pNew->mod.pm.parse = NULL; CHKiRet((*pNew->modQueryEtryPt)((uchar *)"newParserInst", &pNew->mod.pm.newParserInst)); localRet = (*pNew->modQueryEtryPt)((uchar *)"checkParserInst", &pNew->mod.pm.checkParserInst); if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.pm.checkParserInst = NULL; } else { CHKiRet(localRet); } CHKiRet((*pNew->modQueryEtryPt)((uchar *)"freeParserInst", &pNew->mod.pm.freeParserInst)); } else if (localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.pm.parse2 = NULL; pNew->mod.pm.newParserInst = NULL; pNew->mod.pm.checkParserInst = NULL; pNew->mod.pm.freeParserInst = NULL; CHKiRet((*pNew->modQueryEtryPt)((uchar *)"parse", &pNew->mod.pm.parse)); } else { ABORT_FINALIZE(localRet); } CHKiRet((*pNew->modQueryEtryPt)((uchar *)"GetParserName", &GetName)); CHKiRet(GetName(&pName)); CHKiRet(parserConstructViaModAndName(pNew, pName, NULL)); break; case eMOD_STRGEN: /* first, we need to obtain the strgen object. We could not do that during * init as that would have caused class bootstrap issues which are not * absolutely necessary. Note that we can call objUse() multiple times, it * handles that. */ CHKiRet(objUse(strgen, CORE_COMPONENT)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"strgen", &pNew->mod.sm.strgen)); CHKiRet((*pNew->modQueryEtryPt)((uchar *)"GetName", &GetName)); CHKiRet(GetName(&pName)); CHKiRet(strgen.Construct(&pStrgen)); CHKiRet(strgen.SetName(pStrgen, pName)); CHKiRet(strgen.SetModPtr(pStrgen, pNew)); CHKiRet(strgen.ConstructFinalize(pStrgen)); break; case eMOD_FUNCTION: CHKiRet((*pNew->modQueryEtryPt)((uchar *)"getFunctArray", &pNew->mod.fm.getFunctArray)); int version; struct scriptFunct *functArray; pNew->mod.fm.getFunctArray(&version, &functArray); dbgprintf("LLL: %s\n", functArray[0].fname); addMod2List(version, functArray); break; case eMOD_ANY: /* this is mostly to keep the compiler happy! */ DBGPRINTF("PROGRAM ERROR: eMOD_ANY set as module type\n"); assert(0); break; default: // No action needed for other cases break; } pNew->pszName = (uchar *)strdup((char *)name); /* we do not care if strdup() fails, we can accept that */ pNew->pModHdlr = pModHdlr; if (pModHdlr == NULL) { pNew->eLinkType = eMOD_LINK_STATIC; } else { pNew->eLinkType = eMOD_LINK_DYNAMIC_LOADED; /* if we need to keep the linked module, save it */ if (pNew->eKeepType == eMOD_KEEP) { /* see if we have this one already */ for (pHandle = pHandles; pHandle; pHandle = pHandle->next) { if (!strcmp((char *)name, (char *)pHandle->pszName)) break; } /* not found, create it */ if (!pHandle) { if ((pHandle = malloc(sizeof(*pHandle))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } if ((pHandle->pszName = (uchar *)strdup((char *)name)) == NULL) { free(pHandle); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pHandle->pModHdlr = pModHdlr; pHandle->next = pHandles; pHandles = pHandle; } } } /* we initialized the structure, now let's add it to the linked list of modules */ addModToGlblList(pNew); *pNewModule = pNew; finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) moduleDestruct(pNew); *pNewModule = NULL; } RETiRet; } /* Print loaded modules. This is more or less a * debug or test aid, but anyhow I think it's worth it... * This only works if the dbgprintf() subsystem is initialized. * TODO: update for new input modules! */ static void modPrintList(void) { modInfo_t *pMod; pMod = GetNxt(NULL); while (pMod != NULL) { dbgprintf("Loaded Module: Name='%s', IFVersion=%d, ", (char *)modGetName(pMod), pMod->iIFVers); dbgprintf("type="); switch (pMod->eType) { case eMOD_OUT: dbgprintf("output"); break; case eMOD_IN: dbgprintf("input"); break; case eMOD_LIB: dbgprintf("library"); break; case eMOD_PARSER: dbgprintf("parser"); break; case eMOD_STRGEN: dbgprintf("strgen"); break; case eMOD_FUNCTION: dbgprintf("function"); break; case eMOD_ANY: /* this is mostly to keep the compiler happy! */ DBGPRINTF("PROGRAM ERROR: eMOD_ANY set as module type\n"); assert(0); break; default: // No action needed for other cases break; } dbgprintf(" module.\n"); dbgprintf("Entry points:\n"); dbgprintf("\tqueryEtryPt: 0x%lx\n", (unsigned long)pMod->modQueryEtryPt); dbgprintf("\tdbgPrintInstInfo: 0x%lx\n", (unsigned long)pMod->dbgPrintInstInfo); dbgprintf("\tfreeInstance: 0x%lx\n", (unsigned long)pMod->freeInstance); dbgprintf("\tbeginCnfLoad: 0x%lx\n", (unsigned long)pMod->beginCnfLoad); dbgprintf("\tSetModCnf: 0x%lx\n", (unsigned long)pMod->setModCnf); dbgprintf("\tcheckCnf: 0x%lx\n", (unsigned long)pMod->checkCnf); dbgprintf("\tactivateCnfPrePrivDrop: 0x%lx\n", (unsigned long)pMod->activateCnfPrePrivDrop); dbgprintf("\tactivateCnf: 0x%lx\n", (unsigned long)pMod->activateCnf); dbgprintf("\tfreeCnf: 0x%lx\n", (unsigned long)pMod->freeCnf); switch (pMod->eType) { case eMOD_OUT: dbgprintf("Output Module Entry Points:\n"); dbgprintf("\tdoAction: %p\n", pMod->mod.om.doAction); dbgprintf("\tparseSelectorAct: %p\n", pMod->mod.om.parseSelectorAct); dbgprintf("\tnewActInst: %p\n", (pMod->mod.om.newActInst == dummynewActInst) ? NULL : pMod->mod.om.newActInst); dbgprintf("\ttryResume: %p\n", pMod->tryResume); dbgprintf("\tdoHUP: %p\n", pMod->doHUP); dbgprintf( "\tBeginTransaction: %p\n", ((pMod->mod.om.beginTransaction == dummyBeginTransaction) ? NULL : pMod->mod.om.beginTransaction)); dbgprintf("\tEndTransaction: %p\n", ((pMod->mod.om.endTransaction == dummyEndTransaction) ? NULL : pMod->mod.om.endTransaction)); break; case eMOD_IN: dbgprintf("Input Module Entry Points\n"); dbgprintf("\trunInput: 0x%lx\n", (unsigned long)pMod->mod.im.runInput); dbgprintf("\twillRun: 0x%lx\n", (unsigned long)pMod->mod.im.willRun); dbgprintf("\tafterRun: 0x%lx\n", (unsigned long)pMod->mod.im.afterRun); break; case eMOD_LIB: break; case eMOD_PARSER: dbgprintf("Parser Module Entry Points\n"); dbgprintf("\tparse: 0x%lx\n", (unsigned long)pMod->mod.pm.parse); dbgprintf("\tparse2: %p\n", pMod->mod.pm.parse2); dbgprintf("\tnewParserInst: %p\n", pMod->mod.pm.newParserInst); dbgprintf("\tcheckParserInst: %p\n", pMod->mod.pm.checkParserInst); dbgprintf("\tfreeParserInst: %p\n", pMod->mod.pm.freeParserInst); break; case eMOD_STRGEN: dbgprintf("Strgen Module Entry Points\n"); dbgprintf("\tstrgen: 0x%lx\n", (unsigned long)pMod->mod.sm.strgen); break; case eMOD_FUNCTION: dbgprintf("Function Module Entry Points\n"); dbgprintf("\tgetFunctArray: 0x%lx\n", (unsigned long)pMod->mod.fm.getFunctArray); break; case eMOD_ANY: /* this is mostly to keep the compiler happy! */ break; default: // No action needed for other cases break; } dbgprintf("\n"); pMod = GetNxt(pMod); /* done, go next */ } } /* HUP all modules that support it - except for actions, which * need (and have) specialised HUP handling. */ void modDoHUP(void) { modInfo_t *pMod; pthread_mutex_lock(&mutObjGlobalOp); pMod = GetNxt(NULL); while (pMod != NULL) { if (pMod->eType != eMOD_OUT && pMod->doHUP != NULL) { DBGPRINTF("HUPing module %s\n", (char *)modGetName(pMod)); pMod->doHUP(NULL); } pMod = GetNxt(pMod); /* done, go next */ } pthread_mutex_unlock(&mutObjGlobalOp); } /* unlink and destroy a module. The caller must provide a pointer to the module * itself as well as one to its immediate predecessor. * rgerhards, 2008-02-26 */ static rsRetVal modUnlinkAndDestroy(modInfo_t **ppThis) { DEFiRet; modInfo_t *pThis; assert(ppThis != NULL); pThis = *ppThis; assert(pThis != NULL); pthread_mutex_lock(&mutObjGlobalOp); /* first check if we are permitted to unload */ if (pThis->eType == eMOD_LIB) { if (pThis->uRefCnt > 0) { dbgprintf("module %s NOT unloaded because it still has a refcount of %u\n", pThis->pszName, pThis->uRefCnt); ABORT_FINALIZE(RS_RET_MODULE_STILL_REFERENCED); } } /* we need to unlink the module before we can destruct it -- rgerhards, 2008-02-26 */ if (pThis->pPrev == NULL) { /* module is root, so we need to set a new root */ pLoadedModules = pThis->pNext; } else { pThis->pPrev->pNext = pThis->pNext; } if (pThis->pNext == NULL) { pLoadedModulesLast = pThis->pPrev; } else { pThis->pNext->pPrev = pThis->pPrev; } /* finally, we are ready for the module to go away... */ dbgprintf("Unloading module %s\n", modGetName(pThis)); CHKiRet(modPrepareUnload(pThis)); *ppThis = pThis->pNext; moduleDestruct(pThis); finalize_it: pthread_mutex_unlock(&mutObjGlobalOp); RETiRet; } /* unload all loaded modules of a specific type (use eMOD_ALL if you want to * unload all module types). The unload happens only if the module is no longer * referenced. So some modules may survive this call. * rgerhards, 2008-03-11 */ static rsRetVal modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload) { DEFiRet; modInfo_t *pModCurr; /* module currently being processed */ pModCurr = GetNxt(NULL); while (pModCurr != NULL) { if (modLinkTypesToUnload == eMOD_LINK_ALL || pModCurr->eLinkType == modLinkTypesToUnload) { if (modUnlinkAndDestroy(&pModCurr) == RS_RET_MODULE_STILL_REFERENCED) { pModCurr = GetNxt(pModCurr); } else { /* Note: if the module was successfully unloaded, it has updated the * pModCurr pointer to the next module. However, the unload process may * still have indirectly referenced the pointer list in a way that the * unloaded module is not aware of. So we restart the unload process * to make sure we do not fall into a trap (what we did ;)). The * performance toll is minimal. -- rgerhards, 2008-04-28 */ pModCurr = GetNxt(NULL); } } else { pModCurr = GetNxt(pModCurr); } } RETiRet; } /* find module with given name in global list */ static rsRetVal findModule(uchar *pModName, int iModNameLen, modInfo_t **pMod) { modInfo_t *pModInfo; uchar *pModNameCmp; DEFiRet; pModInfo = GetNxt(NULL); while (pModInfo != NULL) { if (!strncmp((char *)pModName, (char *)(pModNameCmp = modGetName(pModInfo)), iModNameLen) && (!*(pModNameCmp + iModNameLen) || !strcmp((char *)pModNameCmp + iModNameLen, ".so"))) { dbgprintf("Module '%s' found\n", pModName); break; } pModInfo = GetNxt(pModInfo); } *pMod = pModInfo; RETiRet; } /* load a module and initialize it, based on doModLoad() from conf.c * rgerhards, 2008-03-05 * varmojfekoj added support for dynamically loadable modules on 2007-08-13 * rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is * called below. This is ok because modules are currently only loaded during * configuration file processing, which is executed on a single thread. Should we * change that design at any stage (what is unlikely), we need to find a * replacement. * rgerhards, 2011-04-27: * Parameter "bConfLoad" tells us if the load was triggered by a config handler, in * which case we need to tie the loaded module to the current config. If bConfLoad == 0, * the system loads a module for internal reasons, this is not directly tied to a * configuration. We could also think if it would be useful to add only certain types * of modules, but the current implementation at least looks simpler. * Note: pvals = NULL means legacy config system */ static rsRetVal ATTR_NONNULL(1) Load(uchar *const pModName, const sbool bConfLoad, struct nvlst *const lst) { size_t iPathLen, iModNameLen; int bHasExtension; void *pModHdlr; pModInit_t pModInit; modInfo_t *pModInfo; cfgmodules_etry_t *pNew = NULL; cfgmodules_etry_t *pLast = NULL; uchar *pModDirCurr, *pModDirNext; struct dlhandle_s *pHandle = NULL; uchar pathBuf[PATH_MAX + 1]; uchar *pPathBuf = pathBuf; size_t lenPathBuf = sizeof(pathBuf); rsRetVal localRet; cstr_t *load_err_msg = NULL; DEFiRet; assert(pModName != NULL); DBGPRINTF("Requested to load module '%s'\n", pModName); iModNameLen = strlen((char *)pModName); /* overhead for a full path is potentially 1 byte for a slash, * three bytes for ".so" and one byte for '\0'. */ #define PATHBUF_OVERHEAD 1 + iModNameLen + 3 + 1 pthread_mutex_lock(&mutObjGlobalOp); if (iModNameLen > 3 && !strcmp((char *)pModName + iModNameLen - 3, ".so")) { iModNameLen -= 3; bHasExtension = RSTRUE; } else bHasExtension = RSFALSE; CHKiRet(findModule(pModName, iModNameLen, &pModInfo)); if (pModInfo != NULL) { DBGPRINTF("Module '%s' already loaded\n", pModName); if (bConfLoad) { localRet = readyModForCnf(pModInfo, &pNew, &pLast); if (pModInfo->setModCnf != NULL && localRet == RS_RET_OK) { if (!strncmp((char *)pModName, "builtin:", sizeof("builtin:") - 1)) { if (pModInfo->bSetModCnfCalled) { LogError(0, RS_RET_DUP_PARAM, "parameters for built-in module %s already set - ignored\n", pModName); ABORT_FINALIZE(RS_RET_DUP_PARAM); } else { /* for built-in moules, we need to call setModConf, * because there is no way to set parameters at load * time for obvious reasons... */ if (lst != NULL) pModInfo->setModCnf(lst); pModInfo->bSetModCnfCalled = 1; } } else { /* regular modules need to be added to conf list (for * builtins, this happend during initial load). */ addModToCnfList(&pNew, pLast); } } } FINALIZE; } pModDirCurr = (uchar *)((pModDir == NULL) ? _PATH_MODDIR : (char *)pModDir); pModDirNext = NULL; pModHdlr = NULL; do { /* now build our load module name */ if (*pModName == '/' || *pModName == '.') { if (lenPathBuf < PATHBUF_OVERHEAD) { if (pPathBuf != pathBuf) /* already malloc()ed memory? */ free(pPathBuf); /* we always alloc enough memory for everything we potentiall need to add */ lenPathBuf = PATHBUF_OVERHEAD; CHKmalloc(pPathBuf = malloc(lenPathBuf)); } *pPathBuf = '\0'; /* we do not need to append the path - its already in the module name */ iPathLen = 0; } else { *pPathBuf = '\0'; iPathLen = strlen((char *)pModDirCurr); pModDirNext = (uchar *)strchr((char *)pModDirCurr, ':'); if (pModDirNext) iPathLen = (size_t)(pModDirNext - pModDirCurr); if (iPathLen == 0) { if (pModDirNext) { pModDirCurr = pModDirNext + 1; continue; } break; } else if (iPathLen > lenPathBuf - PATHBUF_OVERHEAD) { if (pPathBuf != pathBuf) /* already malloc()ed memory? */ free(pPathBuf); /* we always alloc enough memory for everything we potentiall need to add */ lenPathBuf = iPathLen + PATHBUF_OVERHEAD; CHKmalloc(pPathBuf = malloc(lenPathBuf)); } memcpy((char *)pPathBuf, (char *)pModDirCurr, iPathLen); if ((pPathBuf[iPathLen - 1] != '/')) { /* we have space, made sure in previous check */ pPathBuf[iPathLen++] = '/'; } pPathBuf[iPathLen] = '\0'; if (pModDirNext) pModDirCurr = pModDirNext + 1; } /* ... add actual name ... */ strncat((char *)pPathBuf, (char *)pModName, lenPathBuf - iPathLen - 1); /* now see if we have an extension and, if not, append ".so" */ if (!bHasExtension) { /* we do not have an extension and so need to add ".so" * TODO: I guess this is highly importable, so we should change the * algo over time... -- rgerhards, 2008-03-05 */ strncat((char *)pPathBuf, ".so", lenPathBuf - strlen((char *)pPathBuf) - 1); } /* complete load path constructed, so ... GO! */ dbgprintf("loading module '%s'\n", pPathBuf); /* see if we have this one already */ for (pHandle = pHandles; pHandle; pHandle = pHandle->next) { if (!strcmp((char *)pModName, (char *)pHandle->pszName)) { pModHdlr = pHandle->pModHdlr; break; } } /* not found, try to dynamically link it */ if (!pModHdlr) { pModHdlr = dlopen((char *)pPathBuf, RTLD_NOW); } if (pModHdlr == NULL) { char errmsg[4096]; snprintf(errmsg, sizeof(errmsg), "%strying to load module %s: %s", (load_err_msg == NULL) ? "" : " //////// ", pPathBuf, dlerror()); if (load_err_msg == NULL) { rsCStrConstructFromszStr(&load_err_msg, (uchar *)errmsg); } else { rsCStrAppendStr(load_err_msg, (uchar *)errmsg); } } } while (pModHdlr == NULL && *pModName != '/' && pModDirNext); if (load_err_msg != NULL) { cstrFinalize(load_err_msg); } if (!pModHdlr) { LogError(0, RS_RET_MODULE_LOAD_ERR_DLOPEN, "could not load module '%s', errors: %s", pModName, (load_err_msg == NULL) ? "NONE SEEN???" : (const char *)cstrGetSzStrNoNULL(load_err_msg)); ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_DLOPEN); } if (!(pModInit = (pModInit_t)dlsym(pModHdlr, "modInit"))) { LogError(0, RS_RET_MODULE_LOAD_ERR_NO_INIT, "could not load module '%s', dlsym: %s\n", pPathBuf, dlerror()); dlclose(pModHdlr); ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_NO_INIT); } if ((iRet = doModInit(pModInit, (uchar *)pModName, pModHdlr, &pModInfo)) != RS_RET_OK) { LogError(0, RS_RET_MODULE_LOAD_ERR_INIT_FAILED, "could not load module '%s', rsyslog error %d\n", pPathBuf, iRet); dlclose(pModHdlr); ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED); } if (bConfLoad) { readyModForCnf(pModInfo, &pNew, &pLast); if (pModInfo->setModCnf != NULL) { if (lst != NULL) { localRet = pModInfo->setModCnf(lst); if (localRet != RS_RET_OK) { LogError(0, localRet, "module '%s', failed processing config parameters", pPathBuf); ABORT_FINALIZE(localRet); } } pModInfo->bSetModCnfCalled = 1; } addModToCnfList(&pNew, pLast); } finalize_it: if (load_err_msg != NULL) { cstrDestruct(&load_err_msg); } if (pPathBuf != pathBuf) /* used malloc()ed memory? */ free(pPathBuf); if (iRet != RS_RET_OK) abortCnfUse(&pNew); free(pNew); /* is NULL again if properly consumed, else clean up */ pthread_mutex_unlock(&mutObjGlobalOp); RETiRet; } /* the v6+ way of loading modules: process a "module(...)" directive. * rgerhards, 2012-06-20 */ rsRetVal modulesProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; uchar *cnfModName = NULL; int typeIdx; DEFiRet; pvals = nvlstGetParams(o->nvlst, &pblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("modulesProcessCnf params:\n"); cnfparamsPrint(&pblk, pvals); typeIdx = cnfparamGetIdx(&pblk, "load"); if (pvals[typeIdx].bUsed == 0) { LogError(0, RS_RET_CONF_RQRD_PARAM_MISSING, "module type missing"); ABORT_FINALIZE(RS_RET_CONF_RQRD_PARAM_MISSING); } cnfModName = (uchar *)es_str2cstr(pvals[typeIdx].val.d.estr, NULL); iRet = Load(cnfModName, 1, o->nvlst); finalize_it: free(cnfModName); cnfparamvalsDestruct(pvals, &pblk); RETiRet; } /* set the default module load directory. A NULL value may be provided, in * which case any previous value is deleted but no new one set. The caller-provided * string is duplicated. If it needs to be freed, that's the caller's duty. * rgerhards, 2008-03-07 */ static rsRetVal SetModDir(uchar *pszModDir) { DEFiRet; dbgprintf("setting default module load directory '%s'\n", pszModDir); if (pModDir != NULL) { free(pModDir); } pModDir = (uchar *)strdup((char *)pszModDir); RETiRet; } /* Reference-Counting object access: add 1 to the current reference count. Must be * called by anyone interested in using a module. -- rgerhards, 20080-03-10 */ static rsRetVal Use(const char *srcFile, modInfo_t *pThis) { DEFiRet; assert(pThis != NULL); pThis->uRefCnt++; dbgprintf("source file %s requested reference for module '%s', reference count now %u\n", srcFile, pThis->pszName, pThis->uRefCnt); #ifdef DEBUG modUsrAdd(pThis, srcFile); #endif RETiRet; } /* Reference-Counting object access: subract one from the current refcount. Must * by called by anyone who no longer needs a module. If count reaches 0, the * module is unloaded. -- rgerhards, 20080-03-10 */ static rsRetVal Release(const char *srcFile, modInfo_t **ppThis) { DEFiRet; modInfo_t *pThis; assert(ppThis != NULL); pThis = *ppThis; assert(pThis != NULL); if (pThis->uRefCnt == 0) { /* oops, we are already at 0? */ dbgprintf("internal error: module '%s' already has a refcount of 0 (released by %s)!\n", pThis->pszName, srcFile); } else { --pThis->uRefCnt; dbgprintf("file %s released module '%s', reference count now %u\n", srcFile, pThis->pszName, pThis->uRefCnt); #ifdef DEBUG modUsrDel(pThis, srcFile); modUsrPrint(pThis); #endif } if (pThis->uRefCnt == 0) { /* we have a zero refcount, so we must unload the module */ dbgprintf("module '%s' has zero reference count, unloading...\n", pThis->pszName); modUnlinkAndDestroy(&pThis); /* we must NOT do a *ppThis = NULL, because ppThis now points into freed memory! * If in doubt, see obj.c::ReleaseObj() for how we are called. */ } RETiRet; } /* exit our class * rgerhards, 2008-03-11 */ BEGINObjClassExit(module, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(module); /* release objects we no longer need */ free(pModDir); #ifdef DEBUG modUsrPrintAll(); /* debug aid - TODO: integrate with debug.c, at least the settings! */ #endif ENDObjClassExit(module) /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(module) CODESTARTobjQueryInterface(module); if (pIf->ifVersion != moduleCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->GetNxt = GetNxt; pIf->GetNxtCnfType = GetNxtCnfType; pIf->GetName = modGetName; pIf->GetStateName = modGetStateName; pIf->PrintList = modPrintList; pIf->FindWithCnfName = FindWithCnfName; pIf->UnloadAndDestructAll = modUnloadAndDestructAll; pIf->doModInit = doModInit; pIf->SetModDir = SetModDir; pIf->Load = Load; pIf->Use = Use; pIf->Release = Release; finalize_it: ENDobjQueryInterface(module) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-03-05 */ BEGINAbstractObjClassInit(module, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */ uchar *pModPath; /* use any module load path specified in the environment */ if ((pModPath = (uchar *)getenv("RSYSLOG_MODDIR")) != NULL) { SetModDir(pModPath); } /* now check if another module path was set via the command line (-M) * if so, that overrides the environment. Please note that we must use * a global setting here because the command line parser can NOT call * into the module object, because it is not initialized at that point. So * instead a global setting is changed and we pick it up as soon as we * initialize -- rgerhards, 2008-04-04 */ if (glblModPath != NULL) { SetModDir(glblModPath); } /* request objects we use */ ENDObjClassInit(module) /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/tcpsrv.c0000644000000000000000000000013115114522477015710 xustar0029 mtime=1764926783.04263203 30 atime=1764926784.239661412 30 ctime=1764935923.410580056 rsyslog-8.2512.0/runtime/tcpsrv.c0000664000175000017500000024311415114522477015362 0ustar00rgerrger/* tcpsrv.c * * Common code for plain TCP syslog based servers. This is currently being * utilized by imtcp and imgssapi. * * NOTE: this is *not* a generic TCP server, but one for syslog servers. For * generic stream servers, please use ./runtime/strmsrv.c! * * There are actually two classes within the tcpserver code: one is * the tcpsrv itself, the other one is its sessions. This is a helper * class to tcpsrv. * * The common code here calls upon specific functionality by using * callbacks. The specialised input modules need to set the proper * callbacks before the code is run. The tcpsrv then calls back * into the specific input modules at the appropriate time. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2007-12-21 by RGerhards (extracted from syslogd.c[which was * licensed under BSD at the time of the rsyslog fork]) * * Copyright 2007-2025 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_FCNTL_H #include #endif #if !defined(ENABLE_IMTCP_EPOLL) #include #endif #include "rsyslog.h" #include "dirty.h" #include "cfsysline.h" #include "module-template.h" #include "net.h" #include "srUtils.h" #include "conf.h" #include "tcpsrv.h" #include "obj.h" #include "glbl.h" #include "netstrms.h" #include "netstrm.h" #include "errmsg.h" #include "ruleset.h" #include "ratelimit.h" #include "unicode-helper.h" #include "nsd_ptcp.h" PRAGMA_IGNORE_Wswitch_enum MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* defines */ #define TCPSESS_MAX_DEFAULT 200 /* default for nbr of tcp sessions if no number is given */ #define TCPLSTN_MAX_DEFAULT 20 /* default for nbr of listeners */ /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(conf); DEFobjCurrIf(glbl); DEFobjCurrIf(ruleset); DEFobjCurrIf(tcps_sess); DEFobjCurrIf(net); DEFobjCurrIf(netstrms); DEFobjCurrIf(netstrm); DEFobjCurrIf(prop); DEFobjCurrIf(statsobj); #define NSPOLL_MAX_EVENTS_PER_WAIT 128 static void enqueueWork(tcpsrv_io_descr_t *const pioDescr); /* We check which event notification mechanism we have and use the best available one. * We switch back from library-specific drivers, because event notification always works * at the socket layer and is conceptually the same. As such, we can reduce code, code * complexity, and a bit of runtime overhead by using a compile time selection and * abstraction of the event notification mechanism. * rgerhards, 2025-01-16 */ #if defined(ENABLE_IMTCP_EPOLL) static rsRetVal ATTR_NONNULL() eventNotify_init(tcpsrv_t *const pThis) { DEFiRet; #if defined(ENABLE_IMTCP_EPOLL) && defined(EPOLL_CLOEXEC) && defined(HAVE_EPOLL_CREATE1) DBGPRINTF("tcpsrv uses epoll_create1()\n"); pThis->evtdata.epoll.efd = epoll_create1(EPOLL_CLOEXEC); if (pThis->evtdata.epoll.efd < 0 && errno == ENOSYS) #endif { DBGPRINTF("tcpsrv uses epoll_create()\n"); pThis->evtdata.epoll.efd = epoll_create(100); /* size is ignored in newer kernels, but 100 is not bad... */ } if (pThis->evtdata.epoll.efd < 0) { DBGPRINTF("epoll_create1() could not create fd\n"); ABORT_FINALIZE(RS_RET_IO_ERROR); } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL() eventNotify_exit(tcpsrv_t *const pThis) { DEFiRet; close(pThis->evtdata.epoll.efd); RETiRet; } /* Modify socket set */ static rsRetVal ATTR_NONNULL() epoll_Ctl(tcpsrv_t *const pThis, tcpsrv_io_descr_t *const pioDescr, const int isLstn, const int op) { DEFiRet; const int id = pioDescr->id; const int sock = pioDescr->sock; assert(sock >= 0); if (op == EPOLL_CTL_ADD) { dbgprintf("adding epoll entry %d, socket %d\n", id, sock); pioDescr->event.events = EPOLLIN | EPOLLET | EPOLLONESHOT; pioDescr->event.data.ptr = (void *)pioDescr; if (epoll_ctl(pThis->evtdata.epoll.efd, EPOLL_CTL_ADD, sock, &pioDescr->event) < 0) { LogError(errno, RS_RET_ERR_EPOLL_CTL, "epoll_ctl failed on fd %d, isLstn %d\n", sock, isLstn); } } else if (op == EPOLL_CTL_DEL) { dbgprintf("removing epoll entry %d, socket %d\n", id, sock); if (epoll_ctl(pThis->evtdata.epoll.efd, EPOLL_CTL_DEL, sock, NULL) < 0) { if (errno == EBADF || errno == ENOENT) { /* already gone-away, everything is well */ DBGPRINTF("epoll_ctl: fd %d already removed, isLstn %d", sock, isLstn); } else { LogError(errno, RS_RET_ERR_EPOLL_CTL, "epoll_ctl failed on fd %d, isLstn %d\n", sock, isLstn); ABORT_FINALIZE(RS_RET_ERR_EPOLL_CTL); } } } else { dbgprintf("program error: invalid NSDPOLL_mode %d - ignoring request\n", op); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: DBGPRINTF("Done processing epoll entry %d, iRet %d\n", id, iRet); RETiRet; } /* Wait for io to become ready. After the successful call, idRdy contains the * id set by the caller for that i/o event, ppUsr is a pointer to a location * where the user pointer shall be stored. * numEntries contains the maximum number of entries on entry and the actual * number of entries actually read on exit. * rgerhards, 2009-11-18 */ static rsRetVal ATTR_NONNULL() epoll_Wait(tcpsrv_t *const pThis, const int timeout, int *const numEntries, tcpsrv_io_descr_t *pWorkset[]) { struct epoll_event event[NSPOLL_MAX_EVENTS_PER_WAIT]; int nfds; int i; DEFiRet; assert(pWorkset != NULL); if (*numEntries > NSPOLL_MAX_EVENTS_PER_WAIT) *numEntries = NSPOLL_MAX_EVENTS_PER_WAIT; DBGPRINTF("doing epoll_wait for max %d events\n", *numEntries); nfds = epoll_wait(pThis->evtdata.epoll.efd, event, *numEntries, timeout); if (nfds == -1) { if (errno == EINTR) { ABORT_FINALIZE(RS_RET_EINTR); } else { DBGPRINTF("epoll_wait() returned with error code %d\n", errno); ABORT_FINALIZE(RS_RET_ERR_EPOLL); } } else if (nfds == 0) { ABORT_FINALIZE(RS_RET_TIMEOUT); } /* we got valid events, so tell the caller... */ DBGPRINTF("epoll_wait returned %d entries\n", nfds); for (i = 0; i < nfds; ++i) { pWorkset[i] = event[i].data.ptr; /* default is no error, on error we terminate, so we need only to set in error case! */ if (event[i].events & EPOLLERR) { ATOMIC_STORE_1_TO_INT(&pWorkset[i]->isInError, &pWorkset[i]->mut_isInError); } } *numEntries = nfds; finalize_it: RETiRet; } #else /* no epoll, let's use poll() ------------------------------------------------------------ */ #define FDSET_INCREMENT 1024 /* increment for struct pollfds array allocation */ static rsRetVal ATTR_NONNULL() eventNotify_init(tcpsrv_t *const pThis ATTR_UNUSED) { return RS_RET_OK; } static rsRetVal ATTR_NONNULL() eventNotify_exit(tcpsrv_t *const pThis) { DEFiRet; free(pThis->evtdata.poll.fds); RETiRet; } /* Add a socket to the poll set */ static rsRetVal ATTR_NONNULL() poll_Add(tcpsrv_t *const pThis, netstrm_t *const pStrm, const nsdsel_waitOp_t waitOp) { DEFiRet; int sock; CHKiRet(netstrm.GetSock(pStrm, &sock)); if (pThis->evtdata.poll.currfds == pThis->evtdata.poll.maxfds) { struct pollfd *newfds; CHKmalloc(newfds = realloc(pThis->evtdata.poll.fds, sizeof(struct pollfd) * (pThis->evtdata.poll.maxfds + FDSET_INCREMENT))); pThis->evtdata.poll.maxfds += FDSET_INCREMENT; pThis->evtdata.poll.fds = newfds; } switch (waitOp) { case NSDSEL_RD: pThis->evtdata.poll.fds[pThis->evtdata.poll.currfds].events = POLLIN; break; case NSDSEL_WR: pThis->evtdata.poll.fds[pThis->evtdata.poll.currfds].events = POLLOUT; break; case NSDSEL_RDWR: pThis->evtdata.poll.fds[pThis->evtdata.poll.currfds].events = POLLIN | POLLOUT; break; default: break; } pThis->evtdata.poll.fds[pThis->evtdata.poll.currfds].fd = sock; ++pThis->evtdata.poll.currfds; finalize_it: RETiRet; } /* perform the poll() piNumReady returns how many descriptors are ready for IO */ static rsRetVal ATTR_NONNULL() poll_Poll(tcpsrv_t *const pThis, int *const piNumReady) { DEFiRet; assert(piNumReady != NULL); /* Output debug first*/ if (Debug) { dbgprintf("calling poll, active fds (%d): ", pThis->evtdata.poll.currfds); for (uint32_t i = 0; i <= pThis->evtdata.poll.currfds; ++i) dbgprintf("%d ", pThis->evtdata.poll.fds[i].fd); dbgprintf("\n"); } assert(pThis->evtdata.poll.currfds >= 1); /* now do the select */ *piNumReady = poll(pThis->evtdata.poll.fds, pThis->evtdata.poll.currfds, -1); if (*piNumReady < 0) { if (errno == EINTR) { DBGPRINTF("tcpsrv received EINTR\n"); } else { LogMsg(errno, RS_RET_POLL_ERR, LOG_WARNING, "ndssel_ptcp: poll system call failed, may cause further troubles"); } *piNumReady = 0; } RETiRet; } /* check if a socket is ready for IO */ static rsRetVal ATTR_NONNULL() poll_IsReady(tcpsrv_t *const pThis, netstrm_t *const pStrm, const nsdsel_waitOp_t waitOp, int *const pbIsReady) { DEFiRet; int sock; CHKiRet(netstrm.GetSock(pStrm, &sock)); uint32_t idx; for (idx = 0; idx < pThis->evtdata.poll.currfds; ++idx) { if (pThis->evtdata.poll.fds[idx].fd == sock) break; } if (idx >= pThis->evtdata.poll.currfds) { LogMsg(0, RS_RET_INTERNAL_ERROR, LOG_ERR, "ndssel_ptcp: could not find socket %d which should be present", sock); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } const short revent = pThis->evtdata.poll.fds[idx].revents; if (revent & POLLNVAL) { DBGPRINTF("ndssel_ptcp: revent & POLLNVAL is TRUE, we had a race, ignoring, revent = %d", revent); *pbIsReady = 0; } switch (waitOp) { case NSDSEL_RD: *pbIsReady = revent & POLLIN; break; case NSDSEL_WR: *pbIsReady = revent & POLLOUT; break; case NSDSEL_RDWR: *pbIsReady = revent & (POLLIN | POLLOUT); break; default: break; } finalize_it: RETiRet; } #endif /* event notification compile time selection */ /* add new listener port to listener port list * rgerhards, 2009-05-21 */ static rsRetVal ATTR_NONNULL() addNewLstnPort(tcpsrv_t *const pThis, tcpLstnParams_t *const cnf_params) { tcpLstnPortList_t *pEntry; uchar statname[64]; DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); /* create entry */ CHKmalloc(pEntry = (tcpLstnPortList_t *)calloc(1, sizeof(tcpLstnPortList_t))); pEntry->cnf_params = cnf_params; strcpy((char *)pEntry->cnf_params->dfltTZ, (char *)pThis->dfltTZ); pEntry->cnf_params->bSPFramingFix = pThis->bSPFramingFix; pEntry->cnf_params->bPreserveCase = pThis->bPreserveCase; pEntry->pSrv = pThis; /* support statistics gathering */ CHKiRet(ratelimitNew(&pEntry->ratelimiter, "tcperver", NULL)); ratelimitSetLinuxLike(pEntry->ratelimiter, pThis->ratelimitInterval, pThis->ratelimitBurst); ratelimitSetThreadSafe(pEntry->ratelimiter); CHKiRet(statsobj.Construct(&(pEntry->stats))); snprintf((char *)statname, sizeof(statname), "%s(%s)", cnf_params->pszInputName, cnf_params->pszPort); statname[sizeof(statname) - 1] = '\0'; /* just to be on the save side... */ CHKiRet(statsobj.SetName(pEntry->stats, statname)); CHKiRet(statsobj.SetOrigin(pEntry->stats, pThis->pszOrigin)); STATSCOUNTER_INIT(pEntry->ctrSubmit, pEntry->mutCtrSubmit); CHKiRet(statsobj.AddCounter(pEntry->stats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pEntry->ctrSubmit))); CHKiRet(statsobj.ConstructFinalize(pEntry->stats)); /* all OK - add to list */ pEntry->pNext = pThis->pLstnPorts; pThis->pLstnPorts = pEntry; finalize_it: if (iRet != RS_RET_OK) { if (pEntry != NULL) { if (pEntry->cnf_params->pInputName != NULL) { prop.Destruct(&pEntry->cnf_params->pInputName); } if (pEntry->ratelimiter != NULL) { ratelimitDestruct(pEntry->ratelimiter); } if (pEntry->stats != NULL) { statsobj.Destruct(&pEntry->stats); } free(pEntry); } } RETiRet; } /* configure TCP listener settings. * Note: pszPort is handed over to us - the caller MUST NOT free it! * rgerhards, 2008-03-20 */ static rsRetVal ATTR_NONNULL() configureTCPListen(tcpsrv_t *const pThis, tcpLstnParams_t *const cnf_params) { assert(cnf_params->pszPort != NULL); int i; DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); /* extract port */ const uchar *pPort = cnf_params->pszPort; i = 0; while (isdigit((int)*pPort)) { i = i * 10 + *pPort++ - '0'; } if (i >= 0 && i <= 65535) { CHKiRet(addNewLstnPort(pThis, cnf_params)); } else { LogError(0, NO_ERRCODE, "Invalid TCP listen port %s - ignored.\n", cnf_params->pszPort); } finalize_it: RETiRet; } /* Initialize the session table * returns 0 if OK, somewhat else otherwise */ static rsRetVal ATTR_NONNULL() TCPSessTblInit(tcpsrv_t *const pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); assert(pThis->pSessions == NULL); DBGPRINTF("Allocating buffer for %d TCP sessions.\n", pThis->iSessMax); if ((pThis->pSessions = (tcps_sess_t **)calloc(pThis->iSessMax, sizeof(tcps_sess_t *))) == NULL) { DBGPRINTF("Error: TCPSessInit() could not alloc memory for TCP session table.\n"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } finalize_it: RETiRet; } /* find a free spot in the session table. If the table * is full, -1 is returned, else the index of the free * entry (0 or higher). */ static int ATTR_NONNULL() TCPSessTblFindFreeSpot(tcpsrv_t *const pThis) { register int i; ISOBJ_TYPE_assert(pThis, tcpsrv); for (i = 0; i < pThis->iSessMax; ++i) { if (pThis->pSessions[i] == NULL) break; } return ((i < pThis->iSessMax) ? i : -1); } #if !defined(ENABLE_IMTCP_EPOLL) /* Get the next session index. Free session tables entries are * skipped. This function is provided the index of the last * session entry, or -1 if no previous entry was obtained. It * returns the index of the next session or -1, if there is no * further entry in the table. Please note that the initial call * might as well return -1, if there is no session at all in the * session table. */ static int ATTR_NONNULL() TCPSessGetNxtSess(tcpsrv_t *pThis, const int iCurr) { register int i; ISOBJ_TYPE_assert(pThis, tcpsrv); assert(pThis->pSessions != NULL); for (i = iCurr + 1; i < pThis->iSessMax; ++i) { if (pThis->pSessions[i] != NULL) break; } return ((i < pThis->iSessMax) ? i : -1); } #endif /* De-Initialize TCP listner sockets. * This function deinitializes everything, including freeing the * session table. No TCP listen receive operations are permitted * unless the subsystem is reinitialized. * rgerhards, 2007-06-21 */ static void ATTR_NONNULL() deinit_tcp_listener(tcpsrv_t *const pThis) { int i; tcpLstnPortList_t *pEntry; tcpLstnPortList_t *pDel; ISOBJ_TYPE_assert(pThis, tcpsrv); if (pThis->pSessions != NULL) { #if !defined(ENABLE_IMTCP_EPOLL) /* close all TCP connections! */ i = TCPSessGetNxtSess(pThis, -1); while (i != -1) { tcps_sess.Destruct(&pThis->pSessions[i]); /* now get next... */ i = TCPSessGetNxtSess(pThis, i); } #endif /* we are done with the session table - so get rid of it... */ free(pThis->pSessions); pThis->pSessions = NULL; /* just to make sure... */ } /* free list of tcp listen ports */ pEntry = pThis->pLstnPorts; while (pEntry != NULL) { prop.Destruct(&pEntry->cnf_params->pInputName); free((void *)pEntry->cnf_params->pszInputName); free((void *)pEntry->cnf_params->pszPort); free((void *)pEntry->cnf_params->pszAddr); free((void *)pEntry->cnf_params->pszLstnPortFileName); free((void *)pEntry->cnf_params->pszNetworkNamespace); free((void *)pEntry->cnf_params); ratelimitDestruct(pEntry->ratelimiter); statsobj.Destruct(&(pEntry->stats)); pDel = pEntry; pEntry = pEntry->pNext; free(pDel); } /* finally close our listen streams */ for (i = 0; i < pThis->iLstnCurr; ++i) { netstrm.Destruct(pThis->ppLstn + i); } } /* add a listen socket to our listen socket array. This is a callback * invoked from the netstrm class. -- rgerhards, 2008-04-23 */ static rsRetVal ATTR_NONNULL() addTcpLstn(void *pUsr, netstrm_t *const pLstn) { tcpLstnPortList_t *pPortList = (tcpLstnPortList_t *)pUsr; tcpsrv_t *pThis = pPortList->pSrv; DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); ISOBJ_TYPE_assert(pLstn, netstrm); if (pThis->iLstnCurr >= pThis->iLstnMax) ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED); pThis->ppLstn[pThis->iLstnCurr] = pLstn; pThis->ppLstnPort[pThis->iLstnCurr] = pPortList; ++pThis->iLstnCurr; finalize_it: RETiRet; } /* Initialize TCP listener socket for a single port * Note: at this point, TLS vs. non-TLS does not matter; TLS params are * set on connect! * rgerhards, 2009-05-21 */ static rsRetVal ATTR_NONNULL() initTCPListener(tcpsrv_t *pThis, tcpLstnPortList_t *pPortEntry) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); assert(pPortEntry != NULL); CHKiRet(netstrm.LstnInit(pThis->pNS, (void *)pPortEntry, addTcpLstn, pThis->iSessMax, pPortEntry->cnf_params)); finalize_it: RETiRet; } /* Initialize TCP sockets (for listener) and listens on them */ static rsRetVal ATTR_NONNULL() create_tcp_socket(tcpsrv_t *const pThis) { DEFiRet; rsRetVal localRet; tcpLstnPortList_t *pEntry; ISOBJ_TYPE_assert(pThis, tcpsrv); /* init all configured ports */ pEntry = pThis->pLstnPorts; while (pEntry != NULL) { localRet = initTCPListener(pThis, pEntry); if (localRet != RS_RET_OK) { char *ns = pEntry->cnf_params->pszNetworkNamespace; LogError( 0, localRet, "Could not create tcp listener, ignoring port " "%s bind-address %s%s%s.", (pEntry->cnf_params->pszPort == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszPort, (pEntry->cnf_params->pszAddr == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszAddr, (ns == NULL) ? "" : " namespace ", (ns == NULL) ? "" : ns); } pEntry = pEntry->pNext; } /* OK, we had success. Now it is also time to * initialize our connections */ if (TCPSessTblInit(pThis) != 0) { /* OK, we are in some trouble - we could not initialize the * session table, so we can not continue. We need to free all * we have assigned so far, because we can not really use it... */ LogError(0, RS_RET_ERR, "Could not initialize TCP session table, suspending TCP " "message reception."); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: RETiRet; } /* Accept new TCP connection; make entry in session table. If there * is no more space left in the connection table, the new TCP * connection is immediately dropped. * ppSess has a pointer to the newly created session, if it succeeds. * If it does not succeed, no session is created and ppSess is * undefined. If the user has provided an OnSessAccept Callback, * this one is executed immediately after creation of the * session object, so that it can do its own initialization. * rgerhards, 2008-03-02 */ static ATTR_NONNULL() rsRetVal SessAccept(tcpsrv_t *const pThis, tcpLstnPortList_t *const pLstnInfo, tcps_sess_t **ppSess, netstrm_t *pStrm, char *const connInfo) { DEFiRet; tcps_sess_t *pSess = NULL; netstrm_t *pNewStrm = NULL; const tcpLstnParams_t *const cnf_params = pLstnInfo->cnf_params; int iSess = -1; struct sockaddr_storage *addr; uchar *fromHostFQDN = NULL; prop_t *fromHostIP = NULL; prop_t *fromHostPort = NULL; const char *fromHostNameStr = "(hostname unknown)"; const char *fromHostIPStr = "(IP unknown)"; const char *fromHostPortStr = "(port unknown)"; ISOBJ_TYPE_assert(pThis, tcpsrv); assert(pLstnInfo != NULL); CHKiRet(netstrm.AcceptConnReq(pStrm, &pNewStrm, connInfo)); /* Add to session list */ iSess = TCPSessTblFindFreeSpot(pThis); if (iSess == -1) { errno = 0; LogError(0, RS_RET_MAX_SESS_REACHED, "too many tcp sessions - dropping incoming request"); ABORT_FINALIZE(RS_RET_MAX_SESS_REACHED); } if (pThis->bUseKeepAlive) { CHKiRet(netstrm.SetKeepAliveProbes(pNewStrm, pThis->iKeepAliveProbes)); CHKiRet(netstrm.SetKeepAliveTime(pNewStrm, pThis->iKeepAliveTime)); CHKiRet(netstrm.SetKeepAliveIntvl(pNewStrm, pThis->iKeepAliveIntvl)); CHKiRet(netstrm.EnableKeepAlive(pNewStrm)); } /* we found a free spot and can construct our session object */ if (pThis->gnutlsPriorityString != NULL) { CHKiRet(netstrm.SetGnutlsPriorityString(pNewStrm, pThis->gnutlsPriorityString)); } CHKiRet(tcps_sess.Construct(&pSess)); CHKiRet(tcps_sess.SetTcpsrv(pSess, pThis)); CHKiRet(tcps_sess.SetLstnInfo(pSess, pLstnInfo)); if (pThis->OnMsgReceive != NULL) CHKiRet(tcps_sess.SetOnMsgReceive(pSess, pThis->OnMsgReceive)); /* get the host name */ CHKiRet(netstrm.GetRemoteHName(pNewStrm, &fromHostFQDN)); fromHostNameStr = szStrOrDefault(fromHostFQDN, "(hostname unknown)"); if (!cnf_params->bPreserveCase) { /* preserve_case = off */ uchar *p; for (p = fromHostFQDN; *p; p++) { if (isupper((int)*p)) { *p = tolower((int)*p); } } } CHKiRet(netstrm.GetRemoteIP(pNewStrm, &fromHostIP)); fromHostIPStr = propGetSzStrOrDefault(fromHostIP, "(IP unknown)"); CHKiRet(netstrm.GetRemAddr(pNewStrm, &addr)); char portbuf[8]; uint16_t port; if (addr->ss_family == AF_INET) port = ntohs(((struct sockaddr_in *)addr)->sin_port); else if (addr->ss_family == AF_INET6) port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); else port = 0; snprintf(portbuf, sizeof(portbuf), "%u", port); CHKiRet(prop.Construct(&fromHostPort)); CHKiRet(prop.SetString(fromHostPort, (uchar *)portbuf, strlen(portbuf))); CHKiRet(prop.ConstructFinalize(fromHostPort)); fromHostPortStr = propGetSzStrOrDefault(fromHostPort, "(port unknown)"); /* Here we check if a host is permitted to send us messages. If it isn't, we do not further * process the message but log a warning (if we are configured to do this). * rgerhards, 2005-09-26 */ if (!pThis->pIsPermittedHost((struct sockaddr *)addr, (char *)fromHostFQDN, pThis->pUsr, pSess->pUsr)) { DBGPRINTF("%s is not an allowed sender\n", fromHostFQDN); if (glbl.GetOptionDisallowWarning(runConf)) { errno = 0; LogError(0, RS_RET_HOST_NOT_PERMITTED, "connection request from disallowed " "sender %s (%s:%s) discarded", fromHostNameStr, fromHostIPStr, fromHostPortStr); } ABORT_FINALIZE(RS_RET_HOST_NOT_PERMITTED); } /* OK, we have an allowed sender, so let's continue, what * means we can finally fill in the session object. */ CHKiRet(tcps_sess.SetHost(pSess, fromHostFQDN)); fromHostFQDN = NULL; /* we handed this string over */ fromHostNameStr = propGetSzStrOrDefault(pSess->fromHost, "(hostname unknown)"); CHKiRet(tcps_sess.SetHostIP(pSess, fromHostIP)); fromHostIPStr = propGetSzStrOrDefault(pSess->fromHostIP, "(IP unknown)"); fromHostIP = NULL; CHKiRet(tcps_sess.SetHostPort(pSess, fromHostPort)); fromHostPortStr = propGetSzStrOrDefault(pSess->fromHostPort, "(port unknown)"); fromHostPort = NULL; CHKiRet(tcps_sess.SetStrm(pSess, pNewStrm)); pNewStrm = NULL; /* prevent it from being freed in error handler, now done in tcps_sess! */ CHKiRet(tcps_sess.SetMsgIdx(pSess, 0)); CHKiRet(tcps_sess.ConstructFinalize(pSess)); /* check if we need to call our callback */ if (pThis->pOnSessAccept != NULL) { CHKiRet(pThis->pOnSessAccept(pThis, pSess, connInfo)); } *ppSess = pSess; #if !defined(ENABLE_IMTCP_EPOLL) pThis->pSessions[iSess] = pSess; #endif pSess = NULL; /* this is now also handed over */ if (pThis->bEmitMsgOnOpen) { LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "imtcp: connection established with host: %s (%s:%s)", fromHostNameStr, fromHostIPStr, fromHostPortStr); } finalize_it: if (iRet != RS_RET_OK) { if (iRet != RS_RET_HOST_NOT_PERMITTED && pThis->bEmitMsgOnOpen) { LogError(0, NO_ERRCODE, "imtcp: connection could not be " "established with host: %s (%s:%s)", fromHostNameStr, fromHostIPStr, fromHostPortStr); } if (pSess != NULL) tcps_sess.Destruct(&pSess); if (pNewStrm != NULL) netstrm.Destruct(&pNewStrm); if (fromHostIP != NULL) prop.Destruct(&fromHostIP); if (fromHostPort != NULL) prop.Destruct(&fromHostPort); free(fromHostFQDN); } RETiRet; } /** * \brief Close a TCP session and release associated resources. * * Closes the session referenced by \p pioDescr, runs the module-specific * close hook, and updates the event notification set. On EPOLL builds the * I/O descriptor is heap-allocated and is freed here after best-effort * removal from the epoll set. * * No locking is performed; callers are responsible for any required * mutex handling before/after this call. * * \param[in] pThis Server instance. * \param[in] pioDescr I/O descriptor for the session to close * (pioDescr->ptrType == NSD_PTR_TYPE_SESS). * * \pre \p pioDescr and its \c pSess are valid. * \post The session object is destroyed. On EPOLL builds, \p pioDescr is * freed; on non-EPOLL builds, the session table entry is cleared. * \post Callers must not access \p pioDescr or \c pSess after return. * * \note epoll removal is performed on a best-effort basis; teardown proceeds * regardless of epoll_ctl outcome. * * \retval RS_RET_OK */ static ATTR_NONNULL() rsRetVal closeSess(tcpsrv_t *const pThis, tcpsrv_io_descr_t *const pioDescr) { DEFiRet; assert(pioDescr->ptrType == NSD_PTR_TYPE_SESS); tcps_sess_t *pSess = pioDescr->ptr.pSess; #if defined(ENABLE_IMTCP_EPOLL) /* note: we do not check the result of epoll_Ctl because we cannot do * anything against a failure BUT we need to do the cleanup in any case. */ epoll_Ctl(pThis, pioDescr, 0, EPOLL_CTL_DEL); #endif assert(pThis->pOnRegularClose != NULL); pThis->pOnRegularClose(pSess); tcps_sess.Destruct(&pSess); #if defined(ENABLE_IMTCP_EPOLL) /* in epoll mode, pioDescr is dynamically allocated */ DESTROY_ATOMIC_HELPER_MUT(pioDescr->mut_isInError); free(pioDescr); #else pThis->pSessions[pioDescr->id] = NULL; #endif RETiRet; } /** * @brief Re-arm EPOLLONESHOT for this session’s descriptor. * * Uses EPOLL_CTL_MOD to (re)register the descriptor for the next I/O event, * selecting EPOLLIN or EPOLLOUT from `pioDescr->ioDirection` and always * enabling `EPOLLET | EPOLLONESHOT`. The epoll user data is set to the * given `pioDescr` so the same descriptor is delivered on the next event. * * @pre `pioDescr` is valid; `pioDescr->sock` and * `pioDescr->pSrv->evtdata.epoll.efd` refer to open fds. * @pre `pioDescr->ioDirection` ∈ { `NSDSEL_RD`, `NSDSEL_WR` }. * @pre Called by the thread that owns the descriptor (no concurrent epoll_ctl). * * @post On success, the descriptor is armed for the next edge-triggered event. * On failure, the previous epoll registration remains unchanged. * * @param[in] pioDescr I/O descriptor to (re)arm. * @retval RS_RET_OK on success. * @retval RS_RET_ERR_EPOLL_CTL on epoll_ctl failure (error is logged). * * @note Compiled only when ENABLE_IMTCP_EPOLL is defined. */ #if defined(ENABLE_IMTCP_EPOLL) static ATTR_NONNULL() rsRetVal rearmIoEvent(tcpsrv_io_descr_t *const pioDescr) { DEFiRet; /* Debug-only invariants */ assert(pioDescr->ioDirection == NSDSEL_RD || pioDescr->ioDirection == NSDSEL_WR); assert(pioDescr->pSrv != NULL && pioDescr->pSrv->evtdata.epoll.efd >= 0); assert(pioDescr->sock >= 0); const uint32_t waitIOEvent = (pioDescr->ioDirection == NSDSEL_WR) ? EPOLLOUT : EPOLLIN; struct epoll_event event = {.events = waitIOEvent | EPOLLET | EPOLLONESHOT, .data = {.ptr = pioDescr}}; if (epoll_ctl(pioDescr->pSrv->evtdata.epoll.efd, EPOLL_CTL_MOD, pioDescr->sock, &event) < 0) { LogError(errno, RS_RET_ERR_EPOLL_CTL, "epoll_ctl failed re-arm socket %d", pioDescr->sock); ABORT_FINALIZE(RS_RET_ERR_EPOLL_CTL); } finalize_it: RETiRet; } #endif /** * @brief Receive and dispatch data for a TCP session with starvation control and EPOLL re-arm. * * Flow: * - Read via pThis->pRcvData(), forward to tcps_sess.DataRcvd(). * - Starvation: after `starvationMaxReads`, enqueue `pioDescr` (handoff) and return (no re-arm). * - Would-block (RS_RET_RETRY): re-arm EPOLLONESHOT and return. * - Close/error: exit the loop and close the session after unlocking. * * Locking: * - If workQueue.numWrkr > 1, this function locks `pSess->mut` on entry and always unlocks * before return (including close/error and starvation/handoff paths). * - **Re-arm timing:** on the would-block path, `rearmIoEvent(pioDescr)` is called *before* * unlocking `pSess->mut` to keep ownership until the EPOLL_CTL_MOD completes. * - `closeSess()` is called *after* unlocking. * * Starvation accounting: * - `read_calls` counts only successful reads (RS_RET_OK), so the cap reflects actual data * consumption, not retries/closures/errors. * * @pre `pioDescr`, `pioDescr->ptr.pSess`, and `pioDescr->pSrv` are valid; I/O is non-blocking. * @post On close paths, both `pioDescr` and `pSess` are invalid on return. */ static rsRetVal ATTR_NONNULL(1) doReceive(tcpsrv_io_descr_t *const pioDescr, tcpsrvWrkrData_t *const wrkrData ATTR_UNUSED) { char buf[128 * 1024]; /* reception buffer - may hold a partial or multiple messages */ ssize_t iRcvd; rsRetVal localRet; DEFiRet; int oserr = 0; unsigned read_calls = 0; tcps_sess_t *const pSess = pioDescr->ptr.pSess; tcpsrv_t *const pThis = pioDescr->pSrv; const unsigned maxReads = pThis->starvationMaxReads; ISOBJ_TYPE_assert(pThis, tcpsrv); const char *const peerIP = propGetSzStrOrDefault(pSess->fromHostIP, "(IP unknown)"); const char *const peerPort = propGetSzStrOrDefault(pSess->fromHostPort, "(port unknown)"); DBGPRINTF("netstream %p with new data from remote peer %s:%s\n", (pSess)->pStrm, peerIP, peerPort); if (pThis->workQueue.numWrkr > 1) { pthread_mutex_lock(&pSess->mut); } /* explicit state machine */ enum RecvState { RS_READING, RS_STARVATION, RS_DONE_REARM, RS_DONECLOSE, RS_DONE_HANDOFF }; enum RecvState state = RS_READING; #if defined(ENABLE_IMTCP_EPOLL) /* If we had EPOLLERR, log additional info; processing continues. */ if (ATOMIC_FETCH_32BIT(&pioDescr->isInError, &pioDescr->mut_isInError)) { ATOMIC_STORE_0_TO_INT(&pioDescr->isInError, &pioDescr->mut_isInError); int error = 0; socklen_t len = sizeof(error); const int sock = pioDescr->sock; if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) == 0) { LogError(error, RS_RET_IO_ERROR, "epoll subsystem signaled EPOLLERR for stream %p, peer %s:%s", (pSess)->pStrm, peerIP, peerPort); } } #endif /* Sanity (debug builds): I/O direction must be valid. */ assert(pioDescr->ioDirection == NSDSEL_RD || pioDescr->ioDirection == NSDSEL_WR); /* Loop while in non-terminal states (positive check for readability). */ while (state == RS_READING || state == RS_STARVATION) { switch (state) { case RS_READING: while (state == RS_READING && (maxReads == 0 || read_calls < maxReads)) { iRet = pThis->pRcvData(pSess, buf, sizeof(buf), &iRcvd, &oserr, &pioDescr->ioDirection); switch (iRet) { case RS_RET_CLOSED: if (pThis->bEmitMsgOnClose) { errno = 0; LogError(0, RS_RET_PEER_CLOSED_CONN, "Netstream session %p closed by remote peer %s:%s.", (pSess)->pStrm, peerIP, peerPort); } state = RS_DONECLOSE; break; case RS_RET_RETRY: #if defined(ENABLE_IMTCP_EPOLL) if (pThis->workQueue.numWrkr > 1 && read_calls == 0) { STATSCOUNTER_ADD(wrkrData->ctrEmptyRead, wrkrData->mutCtrEmptyRead, 1); } #endif state = RS_DONE_REARM; /* would block → exit and re-arm */ break; case RS_RET_OK: /* Successful read counts toward starvation cap */ if (pThis->workQueue.numWrkr > 1) { ++read_calls; } localRet = tcps_sess.DataRcvd(pSess, buf, iRcvd); if (localRet != RS_RET_OK && localRet != RS_RET_QUEUE_FULL) { LogError(oserr, localRet, "Tearing down TCP Session from %s:%s", peerIP, peerPort); state = RS_DONECLOSE; } break; default: LogError(oserr, iRet, "netstream session %p from %s:%s will be closed due to error", pSess->pStrm, peerIP, peerPort); state = RS_DONECLOSE; break; } } if (state == RS_READING) { state = RS_STARVATION; /* hit the read cap */ } break; case RS_STARVATION: dbgprintf("starvation avoidance triggered, ctr=%u, maxReads=%u\n", read_calls, maxReads); assert(pThis->workQueue.numWrkr > 1); #if defined(ENABLE_IMTCP_EPOLL) STATSCOUNTER_INC(wrkrData->ctrStarvation, wrkrData->mutCtrStarvation); #endif enqueueWork(pioDescr); state = RS_DONE_HANDOFF; /* queued behind existing work → exit, no re-arm */ break; default: assert(0 && "unhandled RecvState inside doReceive loop"); state = RS_DONECLOSE; break; } } /* Postcondition: we must have transitioned to a terminal state. */ assert(state == RS_DONE_REARM || state == RS_DONECLOSE || state == RS_DONE_HANDOFF); #if defined(ENABLE_IMTCP_EPOLL) if (pThis->workQueue.numWrkr > 1) { STATSCOUNTER_ADD(wrkrData->ctrRead, wrkrData->mutCtrRead, read_calls); } if (state == RS_DONE_REARM) { rearmIoEvent(pioDescr); /* re-arm while still holding pSess->mut */ } #endif if (pThis->workQueue.numWrkr > 1) { pthread_mutex_unlock(&pSess->mut); } if (state == RS_DONECLOSE) { closeSess(pThis, pioDescr); /* also frees pioDescr in epoll builds */ } RETiRet; } /* This function processes a single incoming connection */ static rsRetVal ATTR_NONNULL(1) doSingleAccept(tcpsrv_io_descr_t *const pioDescr) { tcps_sess_t *pNewSess = NULL; tcpsrv_io_descr_t *pDescrNew = NULL; const int idx = pioDescr->id; tcpsrv_t *const pThis = pioDescr->pSrv; char connInfo[TCPSRV_CONNINFO_SIZE] = "\0"; DEFiRet; DBGPRINTF("New connect on NSD %p.\n", pThis->ppLstn[idx]); iRet = SessAccept(pThis, pThis->ppLstnPort[idx], &pNewSess, pThis->ppLstn[idx], connInfo); if (iRet == RS_RET_NO_MORE_DATA) { goto no_more_data; } if (iRet == RS_RET_OK) { #if defined(ENABLE_IMTCP_EPOLL) /* pDescrNew is only dyn allocated in epoll mode! */ CHKmalloc(pDescrNew = (tcpsrv_io_descr_t *)calloc(1, sizeof(tcpsrv_io_descr_t))); pDescrNew->pSrv = pThis; pDescrNew->id = idx; pDescrNew->isInError = 0; INIT_ATOMIC_HELPER_MUT(pDescrNew->mut_isInError); pDescrNew->ptrType = NSD_PTR_TYPE_SESS; pDescrNew->ioDirection = NSDSEL_RD; CHKiRet(netstrm.GetSock(pNewSess->pStrm, &pDescrNew->sock)); pDescrNew->ptr.pSess = pNewSess; CHKiRet(epoll_Ctl(pThis, pDescrNew, 0, EPOLL_CTL_ADD)); #endif DBGPRINTF("New session created with NSD %p.\n", pNewSess); } else { DBGPRINTF("tcpsrv: error %d during accept\n", iRet); } #if defined(ENABLE_IMTCP_EPOLL) finalize_it: #endif if (iRet != RS_RET_OK) { const tcpLstnParams_t *cnf_params = pThis->ppLstnPort[idx]->cnf_params; LogError(0, iRet, "tcpsrv listener (inputname: '%s') failed " "to process incoming connection %s with error %d", (cnf_params->pszInputName == NULL) ? (uchar *)"*UNSET*" : cnf_params->pszInputName, connInfo, iRet); if (pDescrNew != NULL) { DESTROY_ATOMIC_HELPER_MUT(pDescrNew->mut_isInError); free(pDescrNew); } srSleep(0, 20000); /* Sleep 20ms */ } no_more_data: RETiRet; } /* This function processes all pending accepts on this fd */ static rsRetVal ATTR_NONNULL(1) doAccept(tcpsrv_io_descr_t *const pioDescr, tcpsrvWrkrData_t *const wrkrData ATTR_UNUSED) { DEFiRet; int bRun = 1; int nAccept = 0; while (bRun) { iRet = doSingleAccept(pioDescr); if (iRet != RS_RET_OK) { bRun = 0; } ++nAccept; } #if defined(ENABLE_IMTCP_EPOLL) if (pioDescr->pSrv->workQueue.numWrkr > 1) { STATSCOUNTER_ADD(wrkrData->ctrAccept, wrkrData->mutCtrAccept, nAccept); } rearmIoEvent(pioDescr); /* listeners must ALWAYS be re-armed */ #endif RETiRet; } /* process a single workset item */ static rsRetVal ATTR_NONNULL(1) processWorksetItem(tcpsrv_io_descr_t *const pioDescr, tcpsrvWrkrData_t *const wrkrData ATTR_UNUSED) { DEFiRet; DBGPRINTF("tcpsrv: processing item %d, socket %d\n", pioDescr->id, pioDescr->sock); if (pioDescr->ptrType == NSD_PTR_TYPE_LSTN) { iRet = doAccept(pioDescr, wrkrData); } else { iRet = doReceive(pioDescr, wrkrData); } RETiRet; } /* work queue functions */ static void ATTR_NONNULL() * wrkr(void *arg); /* forward-def of wrkr */ /** * @brief Start the worker thread pool for tcpsrv (best-effort, single-path cleanup). * * @details * This function allocates worker arrays, initializes synchronization primitives, * and spawns `workQueue.numWrkr` threads running `wrkr()`. * * ### Why all cleanup happens in `finalize_it` * This routine runs during initialization. If we fail here, the process is very * likely unable to run successfully anyway. To keep the code robust and * maintainable as more CHKiRet checks are added over time, we centralize **all** * rollback into the single `finalize_it` block: * * - guarantees a single, well-tested teardown path * - avoids fragile “partial cleanups†spread across multiple branches * - tolerates partial initialization (some threads created, some not; mutex/cond * initialized or not), destroying only what actually succeeded * - ignores secondary errors from pthread_*destroy/cancel/join — this is an * extreme error path and best-effort cleanup is sufficient * * ### Thread cancellation model * If any threads were created before failure, we call `pthread_cancel()` and then * `pthread_join()` on each. Worker threads block in `pthread_cond_wait()` which is * a POSIX cancellation point, so cancellation is reliable here. * * @param pThis Server instance (must have `workQueue.numWrkr > 1`). * @retval RS_RET_OK on success; error code on failure (resources cleaned up). */ static rsRetVal ATTR_NONNULL() startWrkrPool(tcpsrv_t *const pThis) { DEFiRet; workQueue_t *const queue = &pThis->workQueue; int mut_initialized = 0; int cond_initialized = 0; unsigned created = 0; assert(queue->numWrkr > 1); /* Initialize queue state first. */ queue->head = NULL; queue->tail = NULL; /* Allocate arrays. */ CHKmalloc(queue->wrkr_tids = calloc(queue->numWrkr, sizeof(pthread_t))); CHKmalloc(queue->wrkr_data = calloc(queue->numWrkr, sizeof(tcpsrvWrkrData_t))); /* Init sync primitives. */ if (pthread_mutex_init(&queue->mut, NULL) != 0) { ABORT_FINALIZE(RS_RET_ERR); } mut_initialized = 1; if (pthread_cond_init(&queue->workRdy, NULL) != 0) { ABORT_FINALIZE(RS_RET_ERR); } cond_initialized = 1; /* Spawn workers. */ pThis->currWrkrs = 0; for (unsigned i = 0; i < queue->numWrkr; ++i) { if (pthread_create(&queue->wrkr_tids[i], NULL, wrkr, pThis) != 0) { iRet = RS_RET_ERR; break; } ++created; } finalize_it: if (iRet != RS_RET_OK) { /* Best-effort rollback in strict reverse order of construction. */ /* If any threads were created, cancel and join them. */ if (created > 0) { for (unsigned i = 0; i < created; ++i) { (void)pthread_cancel(queue->wrkr_tids[i]); /* cond_wait is a cancellation point */ } for (unsigned i = 0; i < created; ++i) { (void)pthread_join(queue->wrkr_tids[i], NULL); } } /* Destroy sync primitives IFF they were successfully initialized. */ if (cond_initialized) { (void)pthread_cond_destroy(&queue->workRdy); } if (mut_initialized) { (void)pthread_mutex_destroy(&queue->mut); } /* Free arrays (they might be NULL if allocation failed early). */ free(queue->wrkr_tids); free(queue->wrkr_data); queue->wrkr_tids = NULL; queue->wrkr_data = NULL; } RETiRet; } /** * @brief Safely stops the worker thread pool. * * This function can be called multiple times or in partial-init states. * It checks preconditions and only performs cleanup operations that are safe. */ static void ATTR_NONNULL() stopWrkrPool(tcpsrv_t *const pThis) { workQueue_t *const queue = &pThis->workQueue; /* Guard against being called when pool was never started or already stopped. */ if (queue->numWrkr <= 1 || queue->wrkr_tids == NULL) { return; } /* Signal all workers to wake and exit. */ pthread_mutex_lock(&queue->mut); pthread_cond_broadcast(&queue->workRdy); pthread_mutex_unlock(&queue->mut); /* Wait for all worker threads to finish. */ for (unsigned i = 0; i < queue->numWrkr; i++) { pthread_join(queue->wrkr_tids[i], NULL); } /* Free allocated resources. */ free(queue->wrkr_tids); free(queue->wrkr_data); /* Destroy synchronization primitives. */ pthread_mutex_destroy(&queue->mut); pthread_cond_destroy(&queue->workRdy); queue->wrkr_tids = NULL; queue->wrkr_data = NULL; } static tcpsrv_io_descr_t ATTR_NONNULL() * dequeueWork(tcpsrv_t *pSrv) { workQueue_t *const queue = &pSrv->workQueue; tcpsrv_io_descr_t *pioDescr; pthread_mutex_lock(&queue->mut); while ((queue->head == NULL) && !glbl.GetGlobalInputTermState()) { pthread_cond_wait(&queue->workRdy, &queue->mut); } if (queue->head == NULL) { pioDescr = NULL; goto finalize_it; } pioDescr = queue->head; queue->head = pioDescr->next; if (queue->head == NULL) { queue->tail = NULL; } finalize_it: pthread_mutex_unlock(&queue->mut); return pioDescr; } /** * @brief Queue a ready I/O descriptor for worker processing (best-effort). * * Appends @p pioDescr to the work FIFO and signals one worker. Performs its * own locking; callers must not hold workQueue::mut. No epoll re-arm is done here. * * Intent: * - File-local helper for starvation/handoff paths. * - Best-effort, side-effect only; no return value. In debug builds you may assert * on obvious misuse, but callers do not recover here. * * Threading & Ownership: * - Thread-safe; may be called from the event loop or a worker. * - Stores a non-owning pointer; @p pioDescr must remain valid until a worker * dequeues it. * * Preconditions: * - @p pioDescr != NULL and @p pioDescr->pSrv != NULL. * - Multi-thread mode active (workQueue.numWrkr > 1). * * Postconditions: * - @p pioDescr is placed at the queue tail and one worker is signaled. */ static void ATTR_NONNULL() enqueueWork(tcpsrv_io_descr_t *const pioDescr) { workQueue_t *const queue = &pioDescr->pSrv->workQueue; pthread_mutex_lock(&queue->mut); pioDescr->next = NULL; if (queue->tail == NULL) { assert(queue->head == NULL); queue->head = pioDescr; } else { queue->tail->next = pioDescr; } queue->tail = pioDescr; pthread_cond_signal(&queue->workRdy); pthread_mutex_unlock(&queue->mut); } /* Worker thread function */ static void ATTR_NONNULL() * wrkr(void *arg) { tcpsrv_t *const pThis = (tcpsrv_t *)arg; workQueue_t *const queue = &pThis->workQueue; tcpsrv_io_descr_t *pioDescr; pthread_mutex_lock(&queue->mut); const int wrkrIdx = pThis->currWrkrs++; pthread_mutex_unlock(&queue->mut); int deinit_stats = 0; rsRetVal localRet; tcpsrvWrkrData_t *const wrkrData = &(queue->wrkr_data[wrkrIdx]); uchar shortThrdName[16]; snprintf((char *)shortThrdName, sizeof(shortThrdName), "w%d/%s", wrkrIdx, (pThis->pszInputName == NULL) ? (uchar *)"tcpsrv" : pThis->pszInputName); uchar thrdName[32]; snprintf((char *)thrdName, sizeof(thrdName), "w%d/%s", wrkrIdx, (pThis->pszInputName == NULL) ? (uchar *)"tcpsrv" : pThis->pszInputName); dbgSetThrdName(thrdName); /* set thread name - we ignore if it fails, has no harsh consequences... */ #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) if (prctl(PR_SET_NAME, thrdName, 0, 0, 0) != 0) { DBGPRINTF("prctl failed, not setting thread name for '%s'\n", thrdName); } #elif defined(HAVE_PTHREAD_SETNAME_NP) #if defined(__APPLE__) /* The macOS variant takes only the thread name and returns an int. */ int r = pthread_setname_np((char *)shortThrdName); if (r != 0) { DBGPRINTF("pthread_setname_np failed, not setting thread name for '%s'\n", shortThrdName); } #elif defined(__FreeBSD__) /* FreeBSD variant has a void return type. */ pthread_setname_np(pthread_self(), (char *)shortThrdName); #elif defined(__NetBSD__) /* NetBSD variant takes a format string and returns an int. */ int r = pthread_setname_np(pthread_self(), "%s", (void *)shortThrdName); if (r != 0) { DBGPRINTF("pthread_setname_np failed, not setting thread name for '%s'\n", shortThrdName); } #else /* The glibc variant takes thread ID and name, and returns an int. */ int r = pthread_setname_np(pthread_self(), (char *)shortThrdName); if (r != 0) { DBGPRINTF("pthread_setname_np failed, not setting thread name for '%s'\n", shortThrdName); } #endif #endif if ((localRet = statsobj.Construct(&wrkrData->stats)) == RS_RET_OK) { statsobj.SetName(wrkrData->stats, thrdName); statsobj.SetOrigin(wrkrData->stats, (uchar *)"imtcp"); STATSCOUNTER_INIT(wrkrData->ctrRuns, wrkrData->mutCtrRuns); statsobj.AddCounter(wrkrData->stats, UCHAR_CONSTANT("runs"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(wrkrData->ctrRuns)); STATSCOUNTER_INIT(wrkrData->ctrRead, wrkrData->mutCtrRead); statsobj.AddCounter(wrkrData->stats, UCHAR_CONSTANT("read"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(wrkrData->ctrRead)); STATSCOUNTER_INIT(wrkrData->ctrEmptyRead, wrkrData->mutCtrEmptyRead); statsobj.AddCounter(wrkrData->stats, UCHAR_CONSTANT("emptyread"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(wrkrData->ctrEmptyRead)); STATSCOUNTER_INIT(wrkrData->ctrStarvation, wrkrData->mutCtrStarvation); statsobj.AddCounter(wrkrData->stats, UCHAR_CONSTANT("starvation_protect"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(wrkrData->ctrStarvation)); STATSCOUNTER_INIT(wrkrData->ctrAccept, wrkrData->mutCtrAccept); statsobj.AddCounter(wrkrData->stats, UCHAR_CONSTANT("accept"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(wrkrData->ctrAccept)); statsobj.ConstructFinalize(wrkrData->stats); deinit_stats = 1; } else { LogMsg(errno, localRet, LOG_WARNING, "tcpsrv worker %s could not create statistics " "counter. Thus, this worker does not provide them. Processing " "is otherwise unaffected", thrdName); } /**** main loop ****/ while (1) { pioDescr = dequeueWork(pThis); if (pioDescr == NULL) { break; } /* note: we ignore the result as we cannot do anything against errors in any * case. Also, errors are reported inside processWorksetItem(). */ processWorksetItem(pioDescr, wrkrData); STATSCOUNTER_ADD(wrkrData->ctrRuns, wrkrData->mutCtrRuns, 1); } /**** de-init ****/ if (deinit_stats) { statsobj.Destruct(&wrkrData->stats); } return NULL; } /* Process a workset, that is handle io. We become activated * from either poll or epoll handler. We split the workload * out to a pool of threads, but try to avoid context switches * as much as possible. */ static rsRetVal ATTR_NONNULL() processWorkset(const int numEntries, tcpsrv_io_descr_t *const pioDescr[]) { int i; assert(numEntries > 0); const unsigned numWrkr = pioDescr[0]->pSrv->workQueue.numWrkr; /* pSrv is always the same! */ DEFiRet; DBGPRINTF("tcpsrv: ready to process %d event entries\n", numEntries); for (i = 0; i < numEntries; ++i) { if (numWrkr == 1) { /* we process all on this thread, no need for context switch */ processWorksetItem(pioDescr[i], NULL); } else { enqueueWork(pioDescr[i]); } } RETiRet; } #if !defined(ENABLE_IMTCP_EPOLL) /* This function is called to gather input. */ PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wempty_body static ATTR_NONNULL() rsRetVal RunPoll(tcpsrv_t *const pThis) { DEFiRet; int nfds; int i; int iWorkset; int iTCPSess; int bIsReady; tcpsrv_io_descr_t *pWorkset[NSPOLL_MAX_EVENTS_PER_WAIT]; tcpsrv_io_descr_t workset[NSPOLL_MAX_EVENTS_PER_WAIT]; const int sizeWorkset = sizeof(workset) / sizeof(tcpsrv_io_descr_t); rsRetVal localRet; ISOBJ_TYPE_assert(pThis, tcpsrv); DBGPRINTF("tcpsrv uses poll() [ex-select()] interface\n"); /* init the workset pointers, they will remain fixed */ for (i = 0; i < sizeWorkset; ++i) { pWorkset[i] = workset + i; } /* we init the fd set with "constant" data and only later on add the sessions. * Note: further optimization would be to keep the sessions as long as possible, * but this is currently not considered worth the effort as non-epoll platforms * become really rare. 2025-02-25 RGerhards */ pThis->evtdata.poll.maxfds = FDSET_INCREMENT; /* we need to alloc one pollfd more, because the list must be 0-terminated! */ CHKmalloc(pThis->evtdata.poll.fds = calloc(FDSET_INCREMENT + 1, sizeof(struct pollfd))); /* Add the TCP listen sockets to the list of read descriptors. */ for (i = 0; i < pThis->iLstnCurr; ++i) { CHKiRet(poll_Add(pThis, pThis->ppLstn[i], NSDSEL_RD)); } while (1) { pThis->evtdata.poll.currfds = pThis->iLstnCurr; /* listeners are "fixed" */ /* do the sessions */ iTCPSess = TCPSessGetNxtSess(pThis, -1); while (iTCPSess != -1) { /* TODO: access to pNsd is NOT really CLEAN, use method... */ CHKiRet(poll_Add(pThis, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD)); DBGPRINTF("tcpsrv process session %d:\n", iTCPSess); /* now get next... */ iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess); } /* zero-out the last fd - space for it is always reserved! */ assert(pThis->evtdata.poll.maxfds != pThis->evtdata.poll.currfds); pThis->evtdata.poll.fds[pThis->evtdata.poll.currfds].fd = 0; /* wait for io to become ready */ CHKiRet(poll_Poll(pThis, &nfds)); if (glbl.GetGlobalInputTermState() == 1) break; /* terminate input! */ iWorkset = 0; for (i = 0; i < pThis->iLstnCurr && nfds; ++i) { if (glbl.GetGlobalInputTermState() == 1) ABORT_FINALIZE(RS_RET_FORCE_TERM); CHKiRet(poll_IsReady(pThis, pThis->ppLstn[i], NSDSEL_RD, &bIsReady)); if (bIsReady) { workset[iWorkset].pSrv = pThis; workset[iWorkset].ptrType = NSD_PTR_TYPE_LSTN; workset[iWorkset].id = i; workset[iWorkset].isInError = 0; workset[iWorkset].ioDirection = NSDSEL_RD; /* non-epoll: ensure sane default */ CHKiRet(netstrm.GetSock(pThis->ppLstn[i], &(workset[iWorkset].sock))); workset[iWorkset].ptr.ppLstn = pThis->ppLstn; /* this is a flag to indicate listen sock */ ++iWorkset; if (iWorkset >= (int)sizeWorkset) { processWorkset(iWorkset, pWorkset); iWorkset = 0; } --nfds; /* indicate we have processed one */ } } /* now check the sessions */ iTCPSess = TCPSessGetNxtSess(pThis, -1); while (nfds && iTCPSess != -1) { if (glbl.GetGlobalInputTermState() == 1) ABORT_FINALIZE(RS_RET_FORCE_TERM); localRet = poll_IsReady(pThis, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD, &bIsReady); if (bIsReady || localRet != RS_RET_OK) { workset[iWorkset].pSrv = pThis; workset[iWorkset].ptrType = NSD_PTR_TYPE_SESS; workset[iWorkset].id = iTCPSess; workset[iWorkset].isInError = 0; workset[iWorkset].ioDirection = NSDSEL_RD; /* non-epoll: ensure sane default */ CHKiRet(netstrm.GetSock(pThis->pSessions[iTCPSess]->pStrm, &(workset[iWorkset].sock))); workset[iWorkset].ptr.pSess = pThis->pSessions[iTCPSess]; ++iWorkset; if (iWorkset >= (int)sizeWorkset) { processWorkset(iWorkset, pWorkset); iWorkset = 0; } if (bIsReady) --nfds; /* indicate we have processed one */ } iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess); } if (iWorkset > 0) { processWorkset(iWorkset, pWorkset); } /* we need to copy back close descriptors */ finalize_it: /* this is a very special case - this time only we do not exit the function, * because that would not help us either. So we simply retry it. Let's see * if that actually is a better idea. Exiting the loop wasn't we always * crashed, which made sense (the rest of the engine was not prepared for * that) -- rgerhards, 2008-05-19 */ continue; /* keep compiler happy, block end after label is non-standard */ } RETiRet; } PRAGMA_DIAGNOSTIC_POP #endif /* conditional exclude when epoll is available */ #if defined(ENABLE_IMTCP_EPOLL) static rsRetVal ATTR_NONNULL() RunEpoll(tcpsrv_t *const pThis) { DEFiRet; int i; tcpsrv_io_descr_t *workset[NSPOLL_MAX_EVENTS_PER_WAIT]; int numEntries; rsRetVal localRet; DBGPRINTF("tcpsrv uses epoll() interface\n"); /* Add the TCP listen sockets to the list of sockets to monitor */ for (i = 0; i < pThis->iLstnCurr; ++i) { DBGPRINTF("Trying to add listener %d, pUsr=%p\n", i, pThis->ppLstn); CHKmalloc(pThis->ppioDescrPtr[i] = (tcpsrv_io_descr_t *)calloc(1, sizeof(tcpsrv_io_descr_t))); pThis->ppioDescrPtr[i]->pSrv = pThis; pThis->ppioDescrPtr[i]->id = i; pThis->ppioDescrPtr[i]->isInError = 0; pThis->ppioDescrPtr[i]->ioDirection = NSDSEL_RD; INIT_ATOMIC_HELPER_MUT(pThis->ppioDescrPtr[i]->mut_isInError); CHKiRet(netstrm.GetSock(pThis->ppLstn[i], &(pThis->ppioDescrPtr[i]->sock))); pThis->ppioDescrPtr[i]->ptrType = NSD_PTR_TYPE_LSTN; pThis->ppioDescrPtr[i]->ptr.ppLstn = pThis->ppLstn; CHKiRet(epoll_Ctl(pThis, pThis->ppioDescrPtr[i], 1, EPOLL_CTL_ADD)); DBGPRINTF("Added listener %d\n", i); } while (glbl.GetGlobalInputTermState() == 0) { numEntries = sizeof(workset) / sizeof(tcpsrv_io_descr_t *); localRet = epoll_Wait(pThis, -1, &numEntries, workset); if (glbl.GetGlobalInputTermState() == 1) { break; /* terminate input! */ } /* check if we need to ignore the i/o ready state. We do this if we got an invalid * return state. Validly, this can happen for RS_RET_EINTR, for other cases it may * not be the right thing, but what is the right thing is really hard at this point... * Note: numEntries can be validly 0 in some rare cases (eg spurios wakeup). */ if (localRet != RS_RET_OK || numEntries == 0) { continue; } processWorkset(numEntries, workset); } /* remove the tcp listen sockets from the epoll set */ for (i = 0; i < pThis->iLstnCurr; ++i) { CHKiRet(epoll_Ctl(pThis, pThis->ppioDescrPtr[i], 1, EPOLL_CTL_DEL)); DESTROY_ATOMIC_HELPER_MUT(pThis->ppioDescrPtr[i]->mut_isInError); free(pThis->ppioDescrPtr[i]); } finalize_it: RETiRet; } #endif /* This function is called to gather input. It tries doing that via the epoll() * interface. If the driver does not support that, it falls back to calling its * select() equivalent. * rgerhards, 2009-11-18 */ static rsRetVal ATTR_NONNULL() Run(tcpsrv_t *const pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (pThis->iLstnCurr == 0) { dbgprintf("tcpsrv: no listeneres at all (probably init error), terminating\n"); FINALIZE; } #if !defined(ENABLE_IMTCP_EPOLL) /* if we do not have epoll(), we need to run single-threaded */ pThis->workQueue.numWrkr = 1; #endif eventNotify_init(pThis); if (pThis->workQueue.numWrkr > 1) { iRet = startWrkrPool(pThis); if (iRet != RS_RET_OK) { LogError(errno, iRet, "tcpsrv could not start worker pool " "- now running single threaded '%s')", (pThis->pszInputName == NULL) ? (uchar *)"*UNSET*" : pThis->pszInputName); pThis->workQueue.numWrkr = 1; } } #if defined(ENABLE_IMTCP_EPOLL) iRet = RunEpoll(pThis); #else /* fall back to select */ iRet = RunPoll(pThis); #endif stopWrkrPool(pThis); eventNotify_exit(pThis); finalize_it: RETiRet; } /* Standard-Constructor */ BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macro! */ pThis->iSessMax = TCPSESS_MAX_DEFAULT; pThis->iLstnMax = TCPLSTN_MAX_DEFAULT; pThis->addtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER; pThis->maxFrameSize = 200000; pThis->bDisableLFDelim = 0; pThis->discardTruncatedMsg = 0; pThis->OnMsgReceive = NULL; pThis->dfltTZ[0] = '\0'; pThis->bSPFramingFix = 0; pThis->ratelimitInterval = 0; pThis->ratelimitBurst = 10000; pThis->bUseFlowControl = 1; pThis->pszDrvrName = NULL; pThis->bPreserveCase = 1; /* preserve case in fromhost; default to true. */ pThis->iSynBacklog = 0; /* default: unset */ pThis->DrvrTlsVerifyDepth = 0; ENDobjConstruct(tcpsrv) /* ConstructionFinalizer */ static rsRetVal ATTR_NONNULL() tcpsrvConstructFinalize(tcpsrv_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); /* prepare network stream subsystem */ CHKiRet(netstrms.Construct(&pThis->pNS)); CHKiRet(netstrms.SetSynBacklog(pThis->pNS, pThis->iSynBacklog)); if (pThis->pszDrvrName != NULL) CHKiRet(netstrms.SetDrvrName(pThis->pNS, pThis->pszDrvrName)); CHKiRet(netstrms.SetDrvrMode(pThis->pNS, pThis->iDrvrMode)); CHKiRet(netstrms.SetDrvrCheckExtendedKeyUsage(pThis->pNS, pThis->DrvrChkExtendedKeyUsage)); CHKiRet(netstrms.SetDrvrPrioritizeSAN(pThis->pNS, pThis->DrvrPrioritizeSan)); CHKiRet(netstrms.SetDrvrTlsVerifyDepth(pThis->pNS, pThis->DrvrTlsVerifyDepth)); if (pThis->pszDrvrAuthMode != NULL) CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode)); /* Call SetDrvrPermitExpiredCerts required * when param is NULL default handling for ExpiredCerts is set! */ CHKiRet(netstrms.SetDrvrPermitExpiredCerts(pThis->pNS, pThis->pszDrvrPermitExpiredCerts)); CHKiRet(netstrms.SetDrvrTlsCAFile(pThis->pNS, pThis->pszDrvrCAFile)); CHKiRet(netstrms.SetDrvrTlsCRLFile(pThis->pNS, pThis->pszDrvrCRLFile)); CHKiRet(netstrms.SetDrvrTlsKeyFile(pThis->pNS, pThis->pszDrvrKeyFile)); CHKiRet(netstrms.SetDrvrTlsCertFile(pThis->pNS, pThis->pszDrvrCertFile)); if (pThis->pPermPeers != NULL) CHKiRet(netstrms.SetDrvrPermPeers(pThis->pNS, pThis->pPermPeers)); if (pThis->gnutlsPriorityString != NULL) CHKiRet(netstrms.SetDrvrGnutlsPriorityString(pThis->pNS, pThis->gnutlsPriorityString)); CHKiRet(netstrms.ConstructFinalize(pThis->pNS)); /* set up listeners */ CHKmalloc(pThis->ppLstn = calloc(pThis->iLstnMax, sizeof(netstrm_t *))); CHKmalloc(pThis->ppLstnPort = calloc(pThis->iLstnMax, sizeof(tcpLstnPortList_t *))); CHKmalloc(pThis->ppioDescrPtr = calloc(pThis->iLstnMax, sizeof(tcpsrv_io_descr_t *))); iRet = pThis->OpenLstnSocks(pThis); finalize_it: if (iRet != RS_RET_OK) { if (pThis->pNS != NULL) netstrms.Destruct(&pThis->pNS); free(pThis->ppLstn); pThis->ppLstn = NULL; free(pThis->ppLstnPort); pThis->ppLstnPort = NULL; free(pThis->ppioDescrPtr); pThis->ppioDescrPtr = NULL; LogError(0, iRet, "tcpsrv could not create listener (inputname: '%s')", (pThis->pszInputName == NULL) ? (uchar *)"*UNSET*" : pThis->pszInputName); } RETiRet; } /* destructor for the tcpsrv object */ BEGINobjDestruct(tcpsrv) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(tcpsrv); if (pThis->OnDestruct != NULL) pThis->OnDestruct(pThis->pUsr); stopWrkrPool(pThis); deinit_tcp_listener(pThis); if (pThis->pNS != NULL) netstrms.Destruct(&pThis->pNS); free(pThis->pszDrvrName); free(pThis->pszDrvrAuthMode); free(pThis->pszDrvrPermitExpiredCerts); free(pThis->pszDrvrCAFile); free(pThis->pszDrvrCRLFile); free(pThis->pszDrvrKeyFile); free(pThis->pszDrvrCertFile); free(pThis->ppLstn); free(pThis->ppLstnPort); free(pThis->ppioDescrPtr); free(pThis->pszOrigin); ENDobjDestruct(tcpsrv) /* debugprint for the tcpsrv object */ BEGINobjDebugPrint(tcpsrv) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(tcpsrv); ENDobjDebugPrint(tcpsrv) /* set functions */ static rsRetVal ATTR_NONNULL(1) SetCBIsPermittedHost(tcpsrv_t *pThis, int (*pCB)(struct sockaddr *addr, char *fromHostFQDN, void *, void *)) { DEFiRet; pThis->pIsPermittedHost = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBRcvData(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t *, char *, size_t, ssize_t *, int *, unsigned *)) { DEFiRet; pThis->pRcvData = pRcvData; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnListenDeinit(tcpsrv_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->pOnListenDeinit = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnSessAccept(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t *, tcps_sess_t *, char *)) { DEFiRet; pThis->pOnSessAccept = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnDestruct(tcpsrv_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->OnDestruct = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnSessConstructFinalize(tcpsrv_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->OnSessConstructFinalize = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnSessDestruct(tcpsrv_t *pThis, rsRetVal (*pCB)(void *)) { DEFiRet; pThis->pOnSessDestruct = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnRegularClose(tcpsrv_t *pThis, rsRetVal (*pCB)(tcps_sess_t *)) { DEFiRet; pThis->pOnRegularClose = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOnErrClose(tcpsrv_t *pThis, rsRetVal (*pCB)(tcps_sess_t *)) { DEFiRet; pThis->pOnErrClose = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetCBOpenLstnSocks(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t *)) { DEFiRet; pThis->OpenLstnSocks = pCB; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetUsrP(tcpsrv_t *pThis, void *pUsr) { DEFiRet; pThis->pUsr = pUsr; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetKeepAlive(tcpsrv_t *pThis, const int iVal) { DEFiRet; DBGPRINTF("tcpsrv: keep-alive set to %d\n", iVal); pThis->bUseKeepAlive = iVal; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetKeepAliveIntvl(tcpsrv_t *pThis, const int iVal) { DEFiRet; DBGPRINTF("tcpsrv: keep-alive interval set to %d\n", iVal); pThis->iKeepAliveIntvl = iVal; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetKeepAliveProbes(tcpsrv_t *pThis, int iVal) { DEFiRet; DBGPRINTF("tcpsrv: keep-alive probes set to %d\n", iVal); pThis->iKeepAliveProbes = iVal; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetKeepAliveTime(tcpsrv_t *pThis, int iVal) { DEFiRet; DBGPRINTF("tcpsrv: keep-alive timeout set to %d\n", iVal); pThis->iKeepAliveTime = iVal; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetGnutlsPriorityString(tcpsrv_t *pThis, uchar *iVal) { DEFiRet; DBGPRINTF("tcpsrv: gnutlsPriorityString set to %s\n", (iVal == NULL) ? "(null)" : (const char *)iVal); pThis->gnutlsPriorityString = iVal; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetOnMsgReceive(tcpsrv_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t *, uchar *, int)) { DEFiRet; assert(OnMsgReceive != NULL); pThis->OnMsgReceive = OnMsgReceive; RETiRet; } /* set enable/disable standard LF frame delimiter (use with care!) * -- rgerhards, 2010-01-03 */ static rsRetVal ATTR_NONNULL(1) SetbDisableLFDelim(tcpsrv_t *pThis, int bVal) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->bDisableLFDelim = bVal; RETiRet; } /* discard the truncated msg part * -- PascalWithopf, 2017-04-20 */ static rsRetVal ATTR_NONNULL(1) SetDiscardTruncatedMsg(tcpsrv_t *pThis, int discard) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->discardTruncatedMsg = discard; RETiRet; } /* Set additional framing to use (if any) -- rgerhards, 2008-12-10 */ static rsRetVal ATTR_NONNULL(1) SetAddtlFrameDelim(tcpsrv_t *pThis, int iDelim) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->addtlFrameDelim = iDelim; RETiRet; } /* Set max frame size for octet counted -- PascalWithopf, 2017-04-20*/ static rsRetVal ATTR_NONNULL(1) SetMaxFrameSize(tcpsrv_t *pThis, int maxFrameSize) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->maxFrameSize = maxFrameSize; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDfltTZ(tcpsrv_t *const pThis, uchar *const tz) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); strncpy((char *)pThis->dfltTZ, (char *)tz, sizeof(pThis->dfltTZ)); pThis->dfltTZ[sizeof(pThis->dfltTZ) - 1] = '\0'; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetbSPFramingFix(tcpsrv_t *pThis, const sbool val) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->bSPFramingFix = val; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetOrigin(tcpsrv_t *pThis, uchar *origin) { DEFiRet; free(pThis->pszOrigin); pThis->pszOrigin = (origin == NULL) ? NULL : ustrdup(origin); RETiRet; } /* Set the input name to use -- rgerhards, 2008-12-10 */ static rsRetVal ATTR_NONNULL(1) SetInputName(tcpsrv_t *const pThis, tcpLstnParams_t *const cnf_params, const uchar *const name) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (name == NULL) { cnf_params->pszInputName = NULL; } else { CHKmalloc(cnf_params->pszInputName = ustrdup(name)); pThis->pszInputName = cnf_params->pszInputName; } /* we need to create a property */ CHKiRet(prop.Construct(&cnf_params->pInputName)); CHKiRet(prop.SetString(cnf_params->pInputName, cnf_params->pszInputName, ustrlen(cnf_params->pszInputName))); CHKiRet(prop.ConstructFinalize(cnf_params->pInputName)); finalize_it: RETiRet; } static rsRetVal SetNetworkNamespace(tcpsrv_t *pThis __attribute__((unused)), tcpLstnParams_t *const cnf_params, const char *const networkNamespace) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); free(cnf_params->pszNetworkNamespace); if (!networkNamespace || !*networkNamespace) { cnf_params->pszNetworkNamespace = NULL; } else { #ifdef HAVE_SETNS CHKmalloc(cnf_params->pszNetworkNamespace = strdup(networkNamespace)); #else // ndef HAVE_SETNS LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "Namespaces are not supported"); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); #endif // #else ndef HAVE_SETNS } finalize_it: RETiRet; } /* Set the linux-like ratelimiter settings */ static rsRetVal ATTR_NONNULL(1) SetLinuxLikeRatelimiters(tcpsrv_t *pThis, unsigned int ratelimitInterval, unsigned int ratelimitBurst) { DEFiRet; pThis->ratelimitInterval = ratelimitInterval; pThis->ratelimitBurst = ratelimitBurst; RETiRet; } /* Set connection open notification */ static rsRetVal ATTR_NONNULL(1) SetNotificationOnRemoteOpen(tcpsrv_t *pThis, const int bNewVal) { pThis->bEmitMsgOnOpen = bNewVal; return RS_RET_OK; } /* Set connection close notification */ static rsRetVal ATTR_NONNULL(1) SetNotificationOnRemoteClose(tcpsrv_t *pThis, const int bNewVal) { DEFiRet; pThis->bEmitMsgOnClose = bNewVal; RETiRet; } /* here follows a number of methods that shuffle authentication settings down * to the drivers. Drivers not supporting these settings may return an error * state. * -------------------------------------------------------------------------- */ /* set the driver mode -- rgerhards, 2008-04-30 */ static rsRetVal ATTR_NONNULL(1) SetDrvrMode(tcpsrv_t *pThis, const int iMode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->iDrvrMode = iMode; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDrvrName(tcpsrv_t *pThis, uchar *const name) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); free(pThis->pszDrvrName); CHKmalloc(pThis->pszDrvrName = ustrdup(name)); finalize_it: RETiRet; } /* set the driver authentication mode -- rgerhards, 2008-05-19 */ static rsRetVal ATTR_NONNULL(1) SetDrvrAuthMode(tcpsrv_t *pThis, uchar *const mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); CHKmalloc(pThis->pszDrvrAuthMode = ustrdup(mode)); finalize_it: RETiRet; } /* set the driver permitexpiredcerts mode -- alorbach, 2018-12-20 */ static rsRetVal ATTR_NONNULL(1) SetDrvrPermitExpiredCerts(tcpsrv_t *pThis, uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (mode != NULL) { CHKmalloc(pThis->pszDrvrPermitExpiredCerts = ustrdup(mode)); } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDrvrCAFile(tcpsrv_t *const pThis, uchar *const mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCAFile = ustrdup(mode)); } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDrvrCRLFile(tcpsrv_t *const pThis, uchar *const mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCRLFile = ustrdup(mode)); } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDrvrKeyFile(tcpsrv_t *pThis, uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (mode != NULL) { CHKmalloc(pThis->pszDrvrKeyFile = ustrdup(mode)); } finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) SetDrvrCertFile(tcpsrv_t *pThis, uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCertFile = ustrdup(mode)); } finalize_it: RETiRet; } /* set the driver's permitted peers -- rgerhards, 2008-05-19 */ static rsRetVal ATTR_NONNULL(1) SetDrvrPermPeers(tcpsrv_t *pThis, permittedPeers_t *pPermPeers) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->pPermPeers = pPermPeers; RETiRet; } /* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */ static rsRetVal ATTR_NONNULL(1) SetDrvrCheckExtendedKeyUsage(tcpsrv_t *pThis, int ChkExtendedKeyUsage) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage; RETiRet; } /* set the driver name checking policy -- jvymazal, 2019-08-16 */ static rsRetVal ATTR_NONNULL(1) SetDrvrPrioritizeSAN(tcpsrv_t *pThis, int prioritizeSan) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->DrvrPrioritizeSan = prioritizeSan; RETiRet; } /* set the driver Set the driver tls verifyDepth -- alorbach, 2019-12-20 */ static rsRetVal ATTR_NONNULL(1) SetDrvrTlsVerifyDepth(tcpsrv_t *pThis, int verifyDepth) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->DrvrTlsVerifyDepth = verifyDepth; RETiRet; } /* End of methods to shuffle autentication settings to the driver.; * -------------------------------------------------------------------------- */ /* set max number of listeners * this must be called before ConstructFinalize, or it will have no effect! * rgerhards, 2009-08-17 */ static rsRetVal ATTR_NONNULL(1) SetLstnMax(tcpsrv_t *pThis, int iMax) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->iLstnMax = iMax; RETiRet; } /* set if flow control shall be supported */ static rsRetVal ATTR_NONNULL(1) SetUseFlowControl(tcpsrv_t *pThis, int bUseFlowControl) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->bUseFlowControl = bUseFlowControl; RETiRet; } /* set max number of sessions * this must be called before ConstructFinalize, or it will have no effect! * rgerhards, 2009-04-09 */ static rsRetVal ATTR_NONNULL(1) SetSessMax(tcpsrv_t *pThis, int iMax) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->iSessMax = iMax; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetPreserveCase(tcpsrv_t *pThis, int bPreserveCase) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcpsrv); pThis->bPreserveCase = bPreserveCase; RETiRet; } static rsRetVal ATTR_NONNULL(1) SetSynBacklog(tcpsrv_t *pThis, const int iSynBacklog) { pThis->iSynBacklog = iSynBacklog; return RS_RET_OK; } static rsRetVal ATTR_NONNULL(1) SetStarvationMaxReads(tcpsrv_t *pThis, const unsigned int maxReads) { pThis->starvationMaxReads = maxReads; return RS_RET_OK; } static rsRetVal ATTR_NONNULL(1) SetNumWrkr(tcpsrv_t *pThis, const int numWrkr) { pThis->workQueue.numWrkr = numWrkr; return RS_RET_OK; } /* queryInterface function * rgerhards, 2008-02-29 */ BEGINobjQueryInterface(tcpsrv) CODESTARTobjQueryInterface(tcpsrv); if (pIf->ifVersion != tcpsrvCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->DebugPrint = tcpsrvDebugPrint; pIf->Construct = tcpsrvConstruct; pIf->ConstructFinalize = tcpsrvConstructFinalize; pIf->Destruct = tcpsrvDestruct; pIf->configureTCPListen = configureTCPListen; pIf->create_tcp_socket = create_tcp_socket; pIf->Run = Run; pIf->SetNetworkNamespace = SetNetworkNamespace; pIf->SetKeepAlive = SetKeepAlive; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetUsrP = SetUsrP; pIf->SetInputName = SetInputName; pIf->SetOrigin = SetOrigin; pIf->SetDfltTZ = SetDfltTZ; pIf->SetbSPFramingFix = SetbSPFramingFix; pIf->SetAddtlFrameDelim = SetAddtlFrameDelim; pIf->SetMaxFrameSize = SetMaxFrameSize; pIf->SetbDisableLFDelim = SetbDisableLFDelim; pIf->SetDiscardTruncatedMsg = SetDiscardTruncatedMsg; pIf->SetSessMax = SetSessMax; pIf->SetUseFlowControl = SetUseFlowControl; pIf->SetLstnMax = SetLstnMax; pIf->SetDrvrMode = SetDrvrMode; pIf->SetDrvrAuthMode = SetDrvrAuthMode; pIf->SetDrvrPermitExpiredCerts = SetDrvrPermitExpiredCerts; pIf->SetDrvrCAFile = SetDrvrCAFile; pIf->SetDrvrCRLFile = SetDrvrCRLFile; pIf->SetDrvrKeyFile = SetDrvrKeyFile; pIf->SetDrvrCertFile = SetDrvrCertFile; pIf->SetDrvrName = SetDrvrName; pIf->SetDrvrPermPeers = SetDrvrPermPeers; pIf->SetCBIsPermittedHost = SetCBIsPermittedHost; pIf->SetCBOpenLstnSocks = SetCBOpenLstnSocks; pIf->SetCBRcvData = SetCBRcvData; pIf->SetCBOnListenDeinit = SetCBOnListenDeinit; pIf->SetCBOnSessAccept = SetCBOnSessAccept; pIf->SetCBOnSessConstructFinalize = SetCBOnSessConstructFinalize; pIf->SetCBOnSessDestruct = SetCBOnSessDestruct; pIf->SetCBOnDestruct = SetCBOnDestruct; pIf->SetCBOnRegularClose = SetCBOnRegularClose; pIf->SetCBOnErrClose = SetCBOnErrClose; pIf->SetOnMsgReceive = SetOnMsgReceive; pIf->SetLinuxLikeRatelimiters = SetLinuxLikeRatelimiters; pIf->SetNotificationOnRemoteClose = SetNotificationOnRemoteClose; pIf->SetNotificationOnRemoteOpen = SetNotificationOnRemoteOpen; pIf->SetPreserveCase = SetPreserveCase; pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage; pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN; pIf->SetDrvrTlsVerifyDepth = SetDrvrTlsVerifyDepth; pIf->SetSynBacklog = SetSynBacklog; pIf->SetNumWrkr = SetNumWrkr; pIf->SetStarvationMaxReads = SetStarvationMaxReads; finalize_it: ENDobjQueryInterface(tcpsrv) /* exit our class * rgerhards, 2008-03-10 */ BEGINObjClassExit(tcpsrv, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(tcpsrv); /* release objects we no longer need */ objRelease(tcps_sess, DONT_LOAD_LIB); objRelease(conf, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(statsobj, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(netstrms, DONT_LOAD_LIB); objRelease(netstrm, LM_NETSTRMS_FILENAME); objRelease(net, LM_NET_FILENAME); ENDObjClassExit(tcpsrv) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-29 */ BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */ /* request objects we use */ CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(netstrm, DONT_LOAD_LIB)); CHKiRet(objUse(tcps_sess, DONT_LOAD_LIB)); CHKiRet(objUse(conf, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); /* set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, tcpsrvDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, tcpsrvConstructFinalize); ENDObjClassInit(tcpsrv) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; /* de-init in reverse order! */ tcpsrvClassExit(); tcps_sessClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(tcps_sessClassInit(pModInfo)); CHKiRet(tcpsrvClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/wti.h0000644000000000000000000000013215073421710015170 xustar0030 mtime=1760437192.757710634 30 atime=1764930980.028678357 30 ctime=1764935923.251577622 rsyslog-8.2512.0/runtime/wti.h0000664000175000017500000001473315073421710014644 0ustar00rgerrger/* Definition of the worker thread instance (wti) class. * * Copyright 2008-2017 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef WTI_H_INCLUDED #define WTI_H_INCLUDED #include #include #include "wtp.h" #include "obj.h" #include "batch.h" #include "action.h" #define ACT_STATE_RDY 0 /* action ready, waiting for new transaction */ #define ACT_STATE_ITX 1 /* transaction active, waiting for new data or commit */ /* 2 currently not being used */ #define ACT_STATE_RTRY 3 /* failure occurred, trying to restablish ready state */ #define ACT_STATE_SUSP 4 /* suspended due to failure (return fail until timeout expired) */ #define ACT_STATE_DATAFAIL \ 5 /* suspended due to failure in data, which means the message in \ questions needs to be dropped as it will always fail. The \ action must still do a "normal" retry in order to bring \ it back to regular state. */ /* note: 3 bit bit field --> highest value is 7! */ typedef struct actWrkrInfo { action_t *pAction; void *actWrkrData; uint16_t uResumeOKinRow; /* number of times in a row that resume said OK with an immediate failure following */ int iNbrResRtry; /* number of retries since last suspend */ sbool bHadAutoCommit; /* did an auto-commit happen during doAction()? */ struct { unsigned actState : 3; } flags; union { struct { actWrkrIParams_t *iparams; /* dynamically sized array for transactional outputs */ int currIParam; int maxIParams; /* current max */ } tx; struct { actWrkrIParams_t actParams[CONF_OMOD_NUMSTRINGS_MAXSIZE]; } nontx; } p; /* short name for "parameters" */ } actWrkrInfo_t; /* the worker thread instance class */ struct wti_s { BEGINobjInstance ; pthread_t thrdID; /* thread ID */ int bIsRunning; /* is this thread currently running? (must be int for atomic op!) */ sbool bAlwaysRunning; /* should this thread always run? */ int *pbShutdownImmediate; /* end processing of this batch immediately if set to 1 */ wtp_t *pWtp; /* my worker thread pool (important if only the work thread instance is passed! */ batch_t batch; /* pointer to an object array meaningful for current user pointer (e.g. queue pUsr data elemt) */ uchar *pszDbgHdr; /* header string for debug messages */ actWrkrInfo_t *actWrkrInfo; /* *array* of action wrkr infos for all actions (sized for max nbr of actions in config!) */ pthread_cond_t pcondBusy; /* condition to wake up the worker, protected by pmutUsr in wtp */ DEF_ATOMIC_HELPER_MUT(mutIsRunning); struct { uint8_t script_errno; /* errno-type interface for RainerScript functions */ uint8_t bPrevWasSuspended; uint8_t bDoAutoCommit; /* do a commit after each message * this is usually set for batches with 0 element, but may * also be added as a user-selectable option (not implemented yet) */ } execState; /* state for the execution engine */ }; /* prototypes */ rsRetVal wtiConstruct(wti_t **ppThis); rsRetVal wtiConstructFinalize(wti_t *const pThis); rsRetVal wtiDestruct(wti_t **ppThis); rsRetVal wtiWorker(wti_t *const pThis); rsRetVal wtiSetDbgHdr(wti_t *const pThis, uchar *pszMsg, size_t lenMsg); uchar *ATTR_NONNULL() wtiGetDbgHdr(const wti_t *const pThis); rsRetVal wtiCancelThrd(wti_t *const pThis, const uchar *const cancelobj); void ATTR_NONNULL() wtiJoinThrd(wti_t *const pThis); rsRetVal wtiSetAlwaysRunning(wti_t *const pThis); rsRetVal wtiSetState(wti_t *const pThis, int bNew); rsRetVal wtiWakeupThrd(wti_t *const pThis); int wtiGetState(wti_t *const pThis); wti_t *wtiGetDummy(void); int ATTR_NONNULL() wtiWaitNonEmpty(wti_t *const pThis, const struct timespec timeout); PROTOTYPEObjClassInit(wti); PROTOTYPEObjClassExit(wti); PROTOTYPEpropSetMeth(wti, pszDbgHdr, uchar *); PROTOTYPEpropSetMeth(wti, pWtp, wtp_t *); #define getActionStateByNbr(pWti, iActNbr) ((uint8_t)((pWti)->actWrkrInfo[(iActNbr)].flags.actState)) #define getActionState(pWti, pAction) (((uint8_t)(pWti)->actWrkrInfo[(pAction)->iActionNbr].flags.actState)) #define setActionState(pWti, pAction, newState) ((pWti)->actWrkrInfo[(pAction)->iActionNbr].flags.actState = (newState)) #define getActionResumeInRow(pWti, pAction) (((pWti)->actWrkrInfo[(pAction)->iActionNbr].uResumeOKinRow)) #define setActionResumeInRow(pWti, pAction, val) ((pWti)->actWrkrInfo[(pAction)->iActionNbr].uResumeOKinRow = (val)) #define incActionResumeInRow(pWti, pAction) ((pWti)->actWrkrInfo[(pAction)->iActionNbr].uResumeOKinRow++) #define getActionNbrResRtry(pWti, pAction) (((pWti)->actWrkrInfo[(pAction)->iActionNbr].iNbrResRtry)) #define setActionNbrResRtry(pWti, pAction, val) ((pWti)->actWrkrInfo[(pAction)->iActionNbr].iNbrResRtry = (val)) #define incActionNbrResRtry(pWti, pAction) ((pWti)->actWrkrInfo[(pAction)->iActionNbr].iNbrResRtry++) #define wtiInitIParam(piparams) (memset((piparams), 0, sizeof(actWrkrIParams_t))) #define wtiGetScriptErrno(pWti) ((pWti)->execState.script_errno) #define wtiSetScriptErrno(pWti, newval) (pWti)->execState.script_errno = (newval) static inline uint8_t ATTR_UNUSED ATTR_NONNULL(1) wtiGetPrevWasSuspended(const wti_t *const pWti) { assert(pWti != NULL); return pWti->execState.bPrevWasSuspended; } static inline void __attribute__((unused)) wtiResetExecState(wti_t *const pWti, batch_t *const pBatch) { wtiSetScriptErrno(pWti, 0); pWti->execState.bPrevWasSuspended = 0; pWti->execState.bDoAutoCommit = (batchNumMsgs(pBatch) == 1); } rsRetVal wtiNewIParam(wti_t *const pWti, action_t *const pAction, actWrkrIParams_t **piparams); #endif /* #ifndef WTI_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/strgen.h0000644000000000000000000000013215055605325015675 xustar0030 mtime=1756826325.653800744 30 atime=1764930980.052678758 30 ctime=1764935923.156576167 rsyslog-8.2512.0/runtime/strgen.h0000664000175000017500000000440315055605325015342 0ustar00rgerrger/* header for strgen.c * * Copyright 2010 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_STRGEN_H #define INCLUDED_STRGEN_H /* we create a small helper object, a list of strgens, that we can use to * build a chain of them whereever this is needed. */ struct strgenList_s { strgen_t *pStrgen; strgenList_t *pNext; }; /* the strgen object, a dummy because we have only static methods */ struct strgen_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ uchar *pName; /* name of this strgen */ modInfo_t *pModule; /* pointer to strgen's module */ }; /* interfaces */ BEGINinterface(strgen) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(strgen_t **ppThis); rsRetVal (*ConstructFinalize)(strgen_t *pThis); rsRetVal (*Destruct)(strgen_t **ppThis); rsRetVal (*SetName)(strgen_t *pThis, uchar *name); rsRetVal (*SetModPtr)(strgen_t *pThis, modInfo_t *pMod); rsRetVal (*FindStrgen)(strgen_t **ppThis, uchar *name); rsRetVal (*InitStrgenList)(strgenList_t **pListRoot); rsRetVal (*DestructStrgenList)(strgenList_t **pListRoot); rsRetVal (*AddStrgenToList)(strgenList_t **pListRoot, strgen_t *pStrgen); ENDinterface(strgen) #define strgenCURR_IF_VERSION 1 /* increment whenever you change the interface above! */ /* prototypes */ PROTOTYPEObj(strgen); #endif /* #ifndef INCLUDED_STRGEN_H */ rsyslog-8.2512.0/runtime/PaxHeaders/dnscache.c0000644000000000000000000000013215055605325016136 xustar0030 mtime=1756826325.644800608 30 atime=1764930980.466685682 30 ctime=1764935923.101575325 rsyslog-8.2512.0/runtime/dnscache.c0000664000175000017500000003770715055605325015620 0ustar00rgerrger/* dnscache.c * Implementation of a real DNS cache * * File begun on 2011-06-06 by RGerhards * The initial implementation is far from being optimal. The idea is to * first get somethting that'S functionally OK, and then evolve the algorithm. * In any case, even the initial implementaton is far faster than what we had * before. -- rgerhards, 2011-06-06 * * Copyright 2011-2019 by Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include "syslogd-types.h" #include "glbl.h" #include "errmsg.h" #include "obj.h" #include "unicode-helper.h" #include "net.h" #include "hashtable.h" #include "prop.h" #include "dnscache.h" #include "rsconf.h" /* module data structures */ struct dnscache_entry_s { struct sockaddr_storage addr; prop_t *fqdn; prop_t *fqdnLowerCase; prop_t *localName; /* only local name, without domain part (if configured so) */ prop_t *ip; time_t validUntil; struct dnscache_entry_s *next; unsigned nUsed; }; typedef struct dnscache_entry_s dnscache_entry_t; struct dnscache_s { pthread_rwlock_t rwlock; struct hashtable *ht; unsigned nEntries; }; typedef struct dnscache_s dnscache_t; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) static dnscache_t dnsCache; static prop_t *staticErrValue; /* Our hash function. */ static unsigned int hash_from_key_fn(void *k) { int len = 0; uchar *rkey; /* we treat this as opaque bytes */ unsigned hashval = 1; switch (((struct sockaddr *)k)->sa_family) { case AF_INET: len = sizeof(struct in_addr); rkey = (uchar *)&(((struct sockaddr_in *)k)->sin_addr); break; case AF_INET6: len = sizeof(struct in6_addr); rkey = (uchar *)&(((struct sockaddr_in6 *)k)->sin6_addr); break; default: dbgprintf("hash_from_key_fn: unknown address family!\n"); len = 0; rkey = NULL; } while (len--) { /* the casts are done in order to prevent undefined behavior sanitizer * from triggering warnings. Actually, it would be OK if we have just * "random" truncation. */ hashval = (unsigned)(hashval * (unsigned long long)33) + *rkey++; } return hashval; } static int key_equals_fn(void *key1, void *key2) { int RetVal = 0; if (((struct sockaddr *)key1)->sa_family != ((struct sockaddr *)key2)->sa_family) { return 0; } switch (((struct sockaddr *)key1)->sa_family) { case AF_INET: RetVal = !memcmp(&((struct sockaddr_in *)key1)->sin_addr, &((struct sockaddr_in *)key2)->sin_addr, sizeof(struct in_addr)); break; case AF_INET6: RetVal = !memcmp(&((struct sockaddr_in6 *)key1)->sin6_addr, &((struct sockaddr_in6 *)key2)->sin6_addr, sizeof(struct in6_addr)); break; default: // No action needed for other cases break; } return RetVal; } /* destruct a cache entry. * Precondition: entry must already be unlinked from list */ static void ATTR_NONNULL() entryDestruct(dnscache_entry_t *const etry) { if (etry->fqdn != NULL) prop.Destruct(&etry->fqdn); if (etry->fqdnLowerCase != NULL) prop.Destruct(&etry->fqdnLowerCase); if (etry->localName != NULL) prop.Destruct(&etry->localName); if (etry->ip != NULL) prop.Destruct(&etry->ip); free(etry); } /* init function (must be called once) */ rsRetVal dnscacheInit(void) { DEFiRet; if ((dnsCache.ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, (void (*)(void *))entryDestruct)) == NULL) { DBGPRINTF("dnscache: error creating hash table!\n"); ABORT_FINALIZE(RS_RET_ERR); // TODO: make this degrade, but run! } dnsCache.nEntries = 0; pthread_rwlock_init(&dnsCache.rwlock, NULL); CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); prop.Construct(&staticErrValue); prop.SetString(staticErrValue, (uchar *)"???", 3); prop.ConstructFinalize(staticErrValue); finalize_it: RETiRet; } /* deinit function (must be called once) */ rsRetVal dnscacheDeinit(void) { DEFiRet; prop.Destruct(&staticErrValue); hashtable_destroy(dnsCache.ht, 1); /* 1 => free all values automatically */ pthread_rwlock_destroy(&dnsCache.rwlock); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); RETiRet; } /* This is a cancel-safe getnameinfo() version, because we learned * (via drd/valgrind) that getnameinfo() seems to have some issues * when being cancelled, at least if the module was dlloaded. * rgerhards, 2008-09-30 */ static int mygetnameinfo( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { int iCancelStateSave; int i; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); i = getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); pthread_setcancelstate(iCancelStateSave, NULL); return i; } /* get only the local part of the hostname and set it in cache entry */ static void setLocalHostName(dnscache_entry_t *etry) { uchar *fqdnLower; uchar *p; int i; uchar hostbuf[NI_MAXHOST]; if (glbl.GetPreserveFQDN()) { prop.AddRef(etry->fqdnLowerCase); etry->localName = etry->fqdnLowerCase; goto done; } /* strip domain, if configured for this entry */ fqdnLower = propGetSzStr(etry->fqdnLowerCase); p = (uchar *)strchr((char *)fqdnLower, '.'); /* find start of domain name "machine.example.com" */ if (p == NULL) { /* do we have a domain part? */ prop.AddRef(etry->fqdnLowerCase); /* no! */ etry->localName = etry->fqdnLowerCase; goto done; } i = p - fqdnLower; /* length of hostname */ memcpy(hostbuf, fqdnLower, i); hostbuf[i] = '\0'; /* at this point, we have not found anything, so we again use the * already-created complete full name property. */ prop.AddRef(etry->fqdnLowerCase); etry->localName = etry->fqdnLowerCase; done: return; } /* resolve an address. * * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats) * for some explanation of the code found below. We do by default not * discard message where we detected malicouos DNS PTR records. However, * there is a user-configurabel option that will tell us if * we should abort. For this, the return value tells the caller if the * message should be processed (1) or discarded (0). */ static rsRetVal ATTR_NONNULL() resolveAddr(struct sockaddr_storage *addr, dnscache_entry_t *etry) { DEFiRet; int error; sigset_t omask, nmask; struct addrinfo hints, *res; char szIP[80]; /* large enough for IPv6 */ char fqdnBuf[NI_MAXHOST]; rs_size_t fqdnLen; rs_size_t i; error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *)addr), (char *)szIP, sizeof(szIP), NULL, 0, NI_NUMERICHOST); if (error) { dbgprintf("Malformed from address %s\n", gai_strerror(error)); ABORT_FINALIZE(RS_RET_INVALID_SOURCE); } if (!glbl.GetDisableDNS(runConf)) { sigemptyset(&nmask); sigaddset(&nmask, SIGHUP); pthread_sigmask(SIG_BLOCK, &nmask, &omask); error = mygetnameinfo((struct sockaddr *)addr, SALEN((struct sockaddr *)addr), fqdnBuf, NI_MAXHOST, NULL, 0, NI_NAMEREQD); if (error == 0) { memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; /* we now do a lookup once again. This one should fail, * because we should not have obtained a non-numeric address. If * we got a numeric one, someone messed with DNS! */ if (getaddrinfo(fqdnBuf, NULL, &hints, &res) == 0) { freeaddrinfo(res); /* OK, we know we have evil. The question now is what to do about * it. One the one hand, the message might probably be intended * to harm us. On the other hand, losing the message may also harm us. * Thus, the behaviour is controlled by the $DropMsgsWithMaliciousDnsPTRRecords * option. If it tells us we should discard, we do so, else we proceed, * but log an error message together with it. * time being, we simply drop the name we obtained and use the IP - that one * is OK in any way. We do also log the error message. rgerhards, 2007-07-16 */ if (glbl.GetDropMalPTRMsgs(runConf) == 1) { LogError(0, RS_RET_MALICIOUS_ENTITY, "Malicious PTR record, message dropped " "IP = \"%s\" HOST = \"%s\"", szIP, fqdnBuf); pthread_sigmask(SIG_SETMASK, &omask, NULL); ABORT_FINALIZE(RS_RET_MALICIOUS_ENTITY); } /* Please note: we deal with a malicous entry. Thus, we have crafted * the snprintf() below so that all text is in front of the entry - maybe * it contains characters that make the message unreadable * (OK, I admit this is more or less impossible, but I am paranoid...) * rgerhards, 2007-07-16 */ LogError(0, NO_ERRCODE, "Malicious PTR record (message accepted, but used IP " "instead of PTR name: IP = \"%s\" HOST = \"%s\"", szIP, fqdnBuf); error = 1; /* that will trigger using IP address below. */ } else { /* we have a valid entry, so let's create the respective properties */ fqdnLen = strlen(fqdnBuf); prop.CreateStringProp(&etry->fqdn, (uchar *)fqdnBuf, fqdnLen); for (i = 0; i < fqdnLen; ++i) fqdnBuf[i] = tolower(fqdnBuf[i]); prop.CreateStringProp(&etry->fqdnLowerCase, (uchar *)fqdnBuf, fqdnLen); } } pthread_sigmask(SIG_SETMASK, &omask, NULL); } finalize_it: if (iRet != RS_RET_OK) { strcpy(szIP, "?error.obtaining.ip?"); error = 1; /* trigger hostname copies below! */ } prop.CreateStringProp(&etry->ip, (uchar *)szIP, strlen(szIP)); if (error || glbl.GetDisableDNS(runConf)) { dbgprintf("Host name for your address (%s) unknown\n", szIP); prop.AddRef(etry->ip); etry->fqdn = etry->ip; prop.AddRef(etry->ip); etry->fqdnLowerCase = etry->ip; } setLocalHostName(etry); RETiRet; } static rsRetVal ATTR_NONNULL() addEntry(struct sockaddr_storage *const addr, dnscache_entry_t **const pEtry) { int r; dnscache_entry_t *etry = NULL; DEFiRet; /* entry still does not exist, so add it */ struct sockaddr_storage *const keybuf = malloc(sizeof(struct sockaddr_storage)); CHKmalloc(keybuf); CHKmalloc(etry = malloc(sizeof(dnscache_entry_t))); resolveAddr(addr, etry); assert(etry != NULL); memcpy(&etry->addr, addr, SALEN((struct sockaddr *)addr)); etry->nUsed = 0; if (runConf->globals.dnscacheEnableTTL) { etry->validUntil = time(NULL) + runConf->globals.dnscacheDefaultTTL; } memcpy(keybuf, addr, sizeof(struct sockaddr_storage)); r = hashtable_insert(dnsCache.ht, keybuf, etry); if (r == 0) { DBGPRINTF("dnscache: inserting element failed\n"); } *pEtry = etry; finalize_it: if (iRet != RS_RET_OK) { free(keybuf); } RETiRet; } static rsRetVal ATTR_NONNULL(1, 5) findEntry(struct sockaddr_storage *const addr, prop_t **const fqdn, prop_t **const fqdnLowerCase, prop_t **const localName, prop_t **const ip) { DEFiRet; pthread_rwlock_rdlock(&dnsCache.rwlock); dnscache_entry_t *etry = hashtable_search(dnsCache.ht, addr); DBGPRINTF("findEntry: 1st lookup found %p\n", etry); if (etry == NULL || (runConf->globals.dnscacheEnableTTL && (etry->validUntil <= time(NULL)))) { pthread_rwlock_unlock(&dnsCache.rwlock); pthread_rwlock_wrlock(&dnsCache.rwlock); etry = hashtable_search(dnsCache.ht, addr); /* re-query, might have changed */ DBGPRINTF("findEntry: 2nd lookup found %p\n", etry); if (etry == NULL || (runConf->globals.dnscacheEnableTTL && (etry->validUntil <= time(NULL)))) { if (etry != NULL) { DBGPRINTF( "hashtable: entry timed out, discarding it; " "valid until %lld, now %lld\n", (long long)etry->validUntil, (long long)time(NULL)); dnscache_entry_t *const deleted = hashtable_remove(dnsCache.ht, addr); if (deleted != etry) { LogError(0, RS_RET_INTERNAL_ERROR, "dnscache %d: removed different " "hashtable entry than expected - please report issue; " "rsyslog version is %s", __LINE__, VERSION); } entryDestruct(etry); } /* now entry doesn't exist in any case, so let's (re)create it */ CHKiRet(addEntry(addr, &etry)); } } prop.AddRef(etry->ip); *ip = etry->ip; if (fqdn != NULL) { prop.AddRef(etry->fqdn); *fqdn = etry->fqdn; } if (fqdnLowerCase != NULL) { prop.AddRef(etry->fqdnLowerCase); *fqdnLowerCase = etry->fqdnLowerCase; } if (localName != NULL) { prop.AddRef(etry->localName); *localName = etry->localName; } finalize_it: pthread_rwlock_unlock(&dnsCache.rwlock); RETiRet; } /* This is the main function: it looks up an entry and returns it's name * and IP address. If the entry is not yet inside the cache, it is added. * If the entry can not be resolved, an error is reported back. If fqdn * or fqdnLowerCase are NULL, they are not set. */ rsRetVal ATTR_NONNULL(1, 5) dnscacheLookup(struct sockaddr_storage *const addr, prop_t **const fqdn, prop_t **const fqdnLowerCase, prop_t **const localName, prop_t **const ip) { DEFiRet; iRet = findEntry(addr, fqdn, fqdnLowerCase, localName, ip); if (iRet != RS_RET_OK) { DBGPRINTF("dnscacheLookup failed with iRet %d\n", iRet); prop.AddRef(staticErrValue); *ip = staticErrValue; if (fqdn != NULL) { prop.AddRef(staticErrValue); *fqdn = staticErrValue; } if (fqdnLowerCase != NULL) { prop.AddRef(staticErrValue); *fqdnLowerCase = staticErrValue; } if (localName != NULL) { prop.AddRef(staticErrValue); *localName = staticErrValue; } } RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/var.h0000644000000000000000000000013215055605325015163 xustar0030 mtime=1756826325.654800759 30 atime=1764930980.013678105 30 ctime=1764935923.242577484 rsyslog-8.2512.0/runtime/var.h0000664000175000017500000000350615055605325014633 0ustar00rgerrger/* The var object. * * Copyright 2008-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_VAR_H #define INCLUDED_VAR_H #include "stringbuf.h" /* data types */ typedef enum { VARTYPE_NONE = 0, /* currently no value set */ VARTYPE_STR = 1, VARTYPE_NUMBER = 2, VARTYPE_SYSLOGTIME = 3 } varType_t; /* the var object */ typedef struct var_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ cstr_t *pcsName; varType_t varType; union { number_t num; es_str_t *str; cstr_t *pStr; syslogTime_t vSyslogTime; } val; } var_t; /* interfaces */ BEGINinterface(var) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(var); rsRetVal (*Construct)(var_t **ppThis); rsRetVal (*ConstructFinalize)(var_t __attribute__((unused)) * pThis); rsRetVal (*Destruct)(var_t **ppThis); ENDinterface(var) #define varCURR_IF_VERSION 2 /* increment whenever you change the interface above! */ /* v2 - 2011-07-15/rger: on the way to remove var */ /* prototypes */ PROTOTYPEObj(var); #endif /* #ifndef INCLUDED_VAR_H */ rsyslog-8.2512.0/runtime/PaxHeaders/zstdw.h0000644000000000000000000000013215055605325015546 xustar0030 mtime=1756826325.655800774 30 atime=1764930992.733890517 30 ctime=1764935923.422580239 rsyslog-8.2512.0/runtime/zstdw.h0000664000175000017500000000317415055605325015217 0ustar00rgerrger/* The zstdw object. It encapsulates the zstd functionality. The primary * purpose of this wrapper class is to enable rsyslogd core to be build without * zstd libraries. * * Copyright 2022 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_ZSTDW_H #define INCLUDED_ZSTDW_H /* interfaces */ BEGINinterface(zstdw) /* name must also be changed in ENDinterface macro! */ rsRetVal (*doStrmWrite)(strm_t *pThis, uchar *const pBuf, const size_t lenBuf, const int bFlush, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)); rsRetVal (*doCompressFinish)(strm_t *pThis, rsRetVal (*Destruct)(strm_t *pThis, uchar *pBuf, size_t lenBuf)); rsRetVal (*Destruct)(strm_t *pThis); ENDinterface(zstdw) #define zstdwCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(zstdw); /* the name of our library binary */ #define LM_ZSTDW_FILENAME "lmzstdw" #endif /* #ifndef INCLUDED_ZSTDW_H */ rsyslog-8.2512.0/runtime/PaxHeaders/lmcry_ossl.c0000644000000000000000000000013215055605325016554 xustar0030 mtime=1756826325.646800638 30 atime=1764931130.883155224 30 ctime=1764935923.329578816 rsyslog-8.2512.0/runtime/lmcry_ossl.c0000664000175000017500000002207715055605325016230 0ustar00rgerrger/* lmcry_ossl.c * * An implementation of the cryprov interface for openssl. * * Copyright 2013-2017 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "cryprov.h" #include "parserif.h" #include "libossl.h" #include "lmcry_ossl.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfpdescrRegular[] = {{"cry.key", eCmdHdlrGetWord, 0}, {"cry.keyfile", eCmdHdlrGetWord, 0}, {"cry.mode", eCmdHdlrGetWord, 0}, {"cry.algo", eCmdHdlrGetWord, 0}}; static struct cnfparamblk pblkRegular = {CNFPARAMBLK_VERSION, sizeof(cnfpdescrRegular) / sizeof(struct cnfparamdescr), cnfpdescrRegular}; static struct cnfparamdescr cnfpdescrQueue[] = {{"queue.cry.key", eCmdHdlrGetWord, 0}, {"queue.cry.keyfile", eCmdHdlrGetWord, 0}, {"queue.cry.mode", eCmdHdlrGetWord, 0}, {"queue.cry.algo", eCmdHdlrGetWord, 0}}; static struct cnfparamblk pblkQueue = {CNFPARAMBLK_VERSION, sizeof(cnfpdescrQueue) / sizeof(struct cnfparamdescr), cnfpdescrQueue}; /* Standard-Constructor */ BEGINobjConstruct(lmcry_ossl) CHKmalloc(pThis->ctx = osslCtxNew()); finalize_it: ENDobjConstruct(lmcry_ossl) /* destructor for the lmcry_ossl object */ BEGINobjDestruct(lmcry_ossl) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(lmcry_ossl); rsosslCtxDel(pThis->ctx); ENDobjDestruct(lmcry_ossl) /* apply all params from param block to us. This must be called * after construction, but before the OnFileOpen() entry point. * Defaults are expected to have been set during construction. */ static rsRetVal SetCnfParam(void *pT, struct nvlst *lst, int paramType) { lmcry_ossl_t *pThis = (lmcry_ossl_t *)pT; int i, r; unsigned keylen = 0; uchar *key = NULL; uchar *keyfile = NULL; uchar *algomode = NULL; int nKeys; /* number of keys (actually methods) specified */ struct cnfparamvals *pvals; struct cnfparamblk *pblk; DEFiRet; pblk = (paramType == CRYPROV_PARAMTYPE_REGULAR) ? &pblkRegular : &pblkQueue; nKeys = 0; pvals = nvlstGetParams(lst, pblk, NULL); if (pvals == NULL) { parser_errmsg("error crypto provider ossl config parameters"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("param blk in lmcry_ossl:\n"); cnfparamsPrint(pblk, pvals); } for (i = 0; i < pblk->nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblk->descr[i].name, "cry.key") || !strcmp(pblk->descr[i].name, "queue.cry.key")) { key = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); ++nKeys; } else if (!strcmp(pblk->descr[i].name, "cry.keyfile") || !strcmp(pblk->descr[i].name, "queue.cry.keyfile")) { keyfile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); ++nKeys; } else if (!strcmp(pblk->descr[i].name, "cry.algo") || !strcmp(pblk->descr[i].name, "queue.cry.algo")) { algomode = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { DBGPRINTF( "lmcry_ossl: program error, non-handled " "param '%s'\n", pblk->descr[i].name); } } if (algomode != NULL) { iRet = rsosslSetAlgoMode(pThis->ctx, algomode); if (iRet != RS_RET_OK) { LogError(0, iRet, "cry.algo '%s' is not know/supported", algomode); FINALIZE; } } /* note: key must be set AFTER algo/mode is set (as it depends on them) */ if (nKeys != 1) { LogError(0, RS_RET_INVALID_PARAMS, "excactly one of the following " "parameters can be specified: cry.key, cry.keyfile\n"); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } if (key != NULL) { LogError(0, RS_RET_ERR, "Note: specifying an actual key directly from the " "config file is highly insecure - DO NOT USE FOR PRODUCTION"); keylen = strlen((char *)key); } if (keyfile != NULL) { r = osslGetKeyFromFile((char *)keyfile, (char **)&key, &keylen); if (r != 0) { LogError(errno, RS_RET_ERR, "error reading keyfile %s", keyfile); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } } /* if we reach this point, we have a valid key */ r = rsosslSetKey(pThis->ctx, key, keylen); if (r > 0) { LogError(0, RS_RET_INVALID_PARAMS, "Key length %d expected, but " "key of length %d given", r, keylen); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } finalize_it: free(key); free(keyfile); free(algomode); if (pvals != NULL) cnfparamvalsDestruct(pvals, pblk); RETiRet; } static void SetDeleteOnClose(void *pF, int val) { osslfileSetDeleteOnClose(pF, val); } static rsRetVal GetBytesLeftInBlock(void *pF, ssize_t *left) { return osslfileGetBytesLeftInBlock((osslfile)pF, left); } static rsRetVal DeleteStateFiles(uchar *logfn) { return osslfileDeleteState(logfn); } static rsRetVal OnFileOpen(void *pT, uchar *fn, void *pGF, char openMode) { lmcry_ossl_t *pThis = (lmcry_ossl_t *)pT; osslfile *pgf = (osslfile *)pGF; DEFiRet; DBGPRINTF("lmcry_ossl: open file '%s', mode '%c'\n", fn, openMode); iRet = rsosslInitCrypt(pThis->ctx, pgf, fn, openMode); if (iRet != RS_RET_OK) { LogError(0, iRet, "Encryption Provider" "Error: cannot open .encinfo file - disabling log file"); } RETiRet; } static rsRetVal Decrypt(void *pF, uchar *rec, size_t *lenRec) { DEFiRet; iRet = rsosslDecrypt(pF, rec, lenRec); RETiRet; } static rsRetVal Encrypt(void *pF, uchar *rec, size_t *lenRec) { DEFiRet; iRet = rsosslEncrypt(pF, rec, lenRec); RETiRet; } static rsRetVal OnFileClose(void *pF, off64_t offsLogfile) { DEFiRet; osslfileDestruct(pF, offsLogfile); RETiRet; } BEGINobjQueryInterface(lmcry_ossl) CODESTARTobjQueryInterface(lmcry_ossl); if (pIf->ifVersion != cryprovCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } pIf->Construct = (rsRetVal(*)(void *))lmcry_osslConstruct; pIf->SetCnfParam = SetCnfParam; pIf->SetDeleteOnClose = SetDeleteOnClose; pIf->Destruct = (rsRetVal(*)(void *))lmcry_osslDestruct; pIf->OnFileOpen = OnFileOpen; pIf->Encrypt = Encrypt; pIf->Decrypt = Decrypt; pIf->OnFileClose = OnFileClose; pIf->DeleteStateFiles = DeleteStateFiles; pIf->GetBytesLeftInBlock = GetBytesLeftInBlock; finalize_it: ENDobjQueryInterface(lmcry_ossl) BEGINObjClassExit(lmcry_ossl, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(lmcry_ossl); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); rsosslExit(); ENDObjClassExit(lmcry_ossl) BEGINObjClassInit(lmcry_ossl, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); if (rsosslInit() != 0) { LogError(0, RS_RET_CRYPROV_ERR, "error initializing " "ossl crypto provider - cannot encrypt"); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } ENDObjClassInit(lmcry_ossl) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; lmcry_osslClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(lmcry_osslClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/dynstats.c0000644000000000000000000000013115055605325016236 xustar0030 mtime=1756826325.644800608 29 atime=1764930991.00986177 30 ctime=1764935923.220577147 rsyslog-8.2512.0/runtime/dynstats.c0000664000175000017500000005173215055605325015713 0ustar00rgerrger/* * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "errmsg.h" #include "rsconf.h" #include "unicode-helper.h" /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(statsobj) #define DYNSTATS_PARAM_NAME "name" #define DYNSTATS_PARAM_RESETTABLE "resettable" #define DYNSTATS_PARAM_MAX_CARDINALITY "maxCardinality" #define DYNSTATS_PARAM_UNUSED_METRIC_LIFE "unusedMetricLife" /* in seconds */ #define DYNSTATS_DEFAULT_RESETTABILITY 1 #define DYNSTATS_DEFAULT_MAX_CARDINALITY 2000 #define DYNSTATS_DEFAULT_UNUSED_METRIC_LIFE 3600 /* seconds */ #define DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH 100 #define DYNSTATS_METRIC_NAME_SEPARATOR '.' #define DYNSTATS_HASHTABLE_SIZE_OVERPROVISIONING 1.25 static struct cnfparamdescr modpdescr[] = { {DYNSTATS_PARAM_NAME, eCmdHdlrString, CNFPARAM_REQUIRED}, {DYNSTATS_PARAM_RESETTABLE, eCmdHdlrBinary, 0}, {DYNSTATS_PARAM_MAX_CARDINALITY, eCmdHdlrPositiveInt, 0}, {DYNSTATS_PARAM_UNUSED_METRIC_LIFE, eCmdHdlrPositiveInt, 0} /* in minutes */ }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; rsRetVal dynstatsClassInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); finalize_it: RETiRet; } static void dynstats_destroyCtr(dynstats_ctr_t *ctr) { statsobj.DestructUnlinkedCounter(ctr->pCtr); free(ctr->metric); free(ctr); } static void /* assumes exclusive access to bucket */ dynstats_destroyCountersIn(dynstats_bucket_t *b, htable *table, dynstats_ctr_t *ctrs) { dynstats_ctr_t *ctr; int ctrs_purged = 0; hashtable_destroy(table, 0); while (ctrs != NULL) { ctr = ctrs; ctrs = ctrs->next; dynstats_destroyCtr(ctr); ctrs_purged++; } STATSCOUNTER_ADD(b->ctrMetricsPurged, b->mutCtrMetricsPurged, ctrs_purged); ATOMIC_SUB_unsigned(&b->metricCount, ctrs_purged, &b->mutMetricCount); } static void /* assumes exclusive access to bucket */ dynstats_destroyCounters(dynstats_bucket_t *b) { statsobj.UnlinkAllCounters(b->stats); dynstats_destroyCountersIn(b, b->table, b->ctrs); } static void dynstats_destroyBucket(dynstats_buckets_t *bkts, dynstats_bucket_t *b) { pthread_rwlock_wrlock(&b->lock); dynstats_destroyCounters(b); dynstats_destroyCountersIn(b, b->survivor_table, b->survivor_ctrs); statsobj.Destruct(&b->stats); free(b->name); pthread_rwlock_unlock(&b->lock); pthread_rwlock_destroy(&b->lock); pthread_mutex_destroy(&b->mutMetricCount); statsobj.DestructCounter(bkts->global_stats, b->pOpsOverflowCtr); statsobj.DestructCounter(bkts->global_stats, b->pNewMetricAddCtr); statsobj.DestructCounter(bkts->global_stats, b->pNoMetricCtr); statsobj.DestructCounter(bkts->global_stats, b->pMetricsPurgedCtr); statsobj.DestructCounter(bkts->global_stats, b->pOpsIgnoredCtr); statsobj.DestructCounter(bkts->global_stats, b->pPurgeTriggeredCtr); free(b); } static rsRetVal dynstats_addBucketMetrics(dynstats_buckets_t *bkts, dynstats_bucket_t *b, const uchar *name) { uchar *metric_name_buff, *metric_suffix; const uchar *suffix_litteral; int name_len; DEFiRet; name_len = ustrlen(name); CHKmalloc(metric_name_buff = malloc((name_len + DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH + 1) * sizeof(uchar))); strcpy((char *)metric_name_buff, (char *)name); metric_suffix = metric_name_buff + name_len; *metric_suffix = DYNSTATS_METRIC_NAME_SEPARATOR; metric_suffix++; suffix_litteral = UCHAR_CONSTANT("ops_overflow"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrOpsOverflow, b->mutCtrOpsOverflow); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrOpsOverflow), &b->pOpsOverflowCtr, 1)); suffix_litteral = UCHAR_CONSTANT("new_metric_add"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrNewMetricAdd, b->mutCtrNewMetricAdd); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrNewMetricAdd), &b->pNewMetricAddCtr, 1)); suffix_litteral = UCHAR_CONSTANT("no_metric"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrNoMetric, b->mutCtrNoMetric); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrNoMetric), &b->pNoMetricCtr, 1)); suffix_litteral = UCHAR_CONSTANT("metrics_purged"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrMetricsPurged, b->mutCtrMetricsPurged); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrMetricsPurged), &b->pMetricsPurgedCtr, 1)); suffix_litteral = UCHAR_CONSTANT("ops_ignored"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrOpsIgnored, b->mutCtrOpsIgnored); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrOpsIgnored), &b->pOpsIgnoredCtr, 1)); suffix_litteral = UCHAR_CONSTANT("purge_triggered"); ustrncpy(metric_suffix, suffix_litteral, DYNSTATS_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrPurgeTriggered, b->mutCtrPurgeTriggered); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrPurgeTriggered), &b->pPurgeTriggeredCtr, 1)); finalize_it: free(metric_name_buff); if (iRet != RS_RET_OK) { if (b->pOpsOverflowCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pOpsOverflowCtr); } if (b->pNewMetricAddCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pNewMetricAddCtr); } if (b->pNoMetricCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pNoMetricCtr); } if (b->pMetricsPurgedCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pMetricsPurgedCtr); } if (b->pOpsIgnoredCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pOpsIgnoredCtr); } if (b->pPurgeTriggeredCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pPurgeTriggeredCtr); } } RETiRet; } static void no_op_free(void __attribute__((unused)) * ignore) {} static rsRetVal /* assumes exclusive access to bucket */ dynstats_rebuildSurvivorTable(dynstats_bucket_t *b) { htable *survivor_table = NULL; htable *new_table = NULL; size_t htab_sz; DEFiRet; htab_sz = (size_t)(DYNSTATS_HASHTABLE_SIZE_OVERPROVISIONING * b->maxCardinality + 1); if (b->table == NULL) { CHKmalloc(survivor_table = create_hashtable(htab_sz, hash_from_string, key_equals_string, no_op_free)); } CHKmalloc(new_table = create_hashtable(htab_sz, hash_from_string, key_equals_string, no_op_free)); statsobj.UnlinkAllCounters(b->stats); if (b->survivor_table != NULL) { dynstats_destroyCountersIn(b, b->survivor_table, b->survivor_ctrs); } b->survivor_table = (b->table == NULL) ? survivor_table : b->table; b->survivor_ctrs = b->ctrs; b->table = new_table; b->ctrs = NULL; finalize_it: if (iRet != RS_RET_OK) { LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to evict " "TTL-expired metrics of dyn-stats bucket named: %s", b->name); if (new_table == NULL) { LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to " "initialize hash-table for dyn-stats bucket named: %s", b->name); } else { assert(0); /* "can" not happen -- triggers Coverity CID 184307: hashtable_destroy(new_table, 0); We keep this as guard should code above change in the future */ } if (b->table == NULL) { if (survivor_table == NULL) { LogError(errno, RS_RET_INTERNAL_ERROR, "error trying to initialize " "ttl-survivor hash-table for dyn-stats bucket named: %s", b->name); } else { hashtable_destroy(survivor_table, 0); } } } RETiRet; } static rsRetVal dynstats_resetBucket(dynstats_bucket_t *b) { DEFiRet; pthread_rwlock_wrlock(&b->lock); CHKiRet(dynstats_rebuildSurvivorTable(b)); STATSCOUNTER_INC(b->ctrPurgeTriggered, b->mutCtrPurgeTriggered); timeoutComp(&b->metricCleanupTimeout, b->unusedMetricLife); finalize_it: pthread_rwlock_unlock(&b->lock); RETiRet; } static void dynstats_resetIfExpired(dynstats_bucket_t *b) { long timeout; pthread_rwlock_rdlock(&b->lock); timeout = timeoutVal(&b->metricCleanupTimeout); pthread_rwlock_unlock(&b->lock); if (timeout == 0) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "dynstats: bucket '%s' is being reset", b->name); dynstats_resetBucket(b); } } static void dynstats_readCallback(statsobj_t __attribute__((unused)) * ignore, void *b) { dynstats_buckets_t *bkts; bkts = &runConf->dynstats_buckets; pthread_rwlock_rdlock(&bkts->lock); dynstats_resetIfExpired((dynstats_bucket_t *)b); pthread_rwlock_unlock(&bkts->lock); } static rsRetVal dynstats_initNewBucketStats(dynstats_bucket_t *b) { DEFiRet; CHKiRet(statsobj.Construct(&b->stats)); CHKiRet(statsobj.SetOrigin(b->stats, UCHAR_CONSTANT("dynstats.bucket"))); CHKiRet(statsobj.SetName(b->stats, b->name)); CHKiRet(statsobj.SetReportingNamespace(b->stats, UCHAR_CONSTANT("values"))); statsobj.SetReadNotifier(b->stats, dynstats_readCallback, b); CHKiRet(statsobj.ConstructFinalize(b->stats)); finalize_it: RETiRet; } static rsRetVal dynstats_newBucket(const uchar *name, uint8_t resettable, uint32_t maxCardinality, uint32_t unusedMetricLife) { dynstats_bucket_t *b; dynstats_buckets_t *bkts; uint8_t lock_initialized, metric_count_mutex_initialized; pthread_rwlockattr_t bucket_lock_attr; DEFiRet; lock_initialized = metric_count_mutex_initialized = 0; b = NULL; bkts = &loadConf->dynstats_buckets; if (bkts->initialized) { CHKmalloc(b = calloc(1, sizeof(dynstats_bucket_t))); b->resettable = resettable; b->maxCardinality = maxCardinality; b->unusedMetricLife = 1000 * unusedMetricLife; CHKmalloc(b->name = ustrdup(name)); pthread_rwlockattr_init(&bucket_lock_attr); #ifdef HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP pthread_rwlockattr_setkind_np(&bucket_lock_attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); #endif pthread_rwlock_init(&b->lock, &bucket_lock_attr); lock_initialized = 1; pthread_mutex_init(&b->mutMetricCount, NULL); metric_count_mutex_initialized = 1; CHKiRet(dynstats_initNewBucketStats(b)); CHKiRet(dynstats_resetBucket(b)); CHKiRet(dynstats_addBucketMetrics(bkts, b, name)); pthread_rwlock_wrlock(&bkts->lock); if (bkts->list == NULL) { bkts->list = b; } else { b->next = bkts->list; bkts->list = b; } pthread_rwlock_unlock(&bkts->lock); } else { LogError(0, RS_RET_INTERNAL_ERROR, "dynstats: bucket creation failed, as " "global-initialization of buckets was unsuccessful"); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } finalize_it: if (iRet != RS_RET_OK) { if (metric_count_mutex_initialized) { pthread_mutex_destroy(&b->mutMetricCount); } if (lock_initialized) { pthread_rwlock_destroy(&b->lock); } if (b != NULL) { dynstats_destroyBucket(bkts, b); } } RETiRet; } rsRetVal dynstats_processCnf(struct cnfobj *o) { struct cnfparamvals *pvals; short i; uchar *name = NULL; uint8_t resettable = DYNSTATS_DEFAULT_RESETTABILITY; uint32_t maxCardinality = DYNSTATS_DEFAULT_MAX_CARDINALITY; uint32_t unusedMetricLife = DYNSTATS_DEFAULT_UNUSED_METRIC_LIFE; DEFiRet; pvals = nvlstGetParams(o->nvlst, &modpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, DYNSTATS_PARAM_NAME)) { CHKmalloc(name = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(modpblk.descr[i].name, DYNSTATS_PARAM_RESETTABLE)) { resettable = (pvals[i].val.d.n != 0); } else if (!strcmp(modpblk.descr[i].name, DYNSTATS_PARAM_MAX_CARDINALITY)) { maxCardinality = (uint32_t)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, DYNSTATS_PARAM_UNUSED_METRIC_LIFE)) { unusedMetricLife = (uint32_t)pvals[i].val.d.n; } else { dbgprintf( "dyn_stats: program error, non-handled " "param '%s'\n", modpblk.descr[i].name); } } if (name != NULL) { CHKiRet(dynstats_newBucket(name, resettable, maxCardinality, unusedMetricLife)); } finalize_it: free(name); cnfparamvalsDestruct(pvals, &modpblk); RETiRet; } rsRetVal dynstats_initCnf(dynstats_buckets_t *bkts) { DEFiRet; bkts->initialized = 0; bkts->list = NULL; CHKiRet(statsobj.Construct(&bkts->global_stats)); CHKiRet(statsobj.SetOrigin(bkts->global_stats, UCHAR_CONSTANT("dynstats"))); CHKiRet(statsobj.SetName(bkts->global_stats, UCHAR_CONSTANT("global"))); CHKiRet(statsobj.SetReportingNamespace(bkts->global_stats, UCHAR_CONSTANT("values"))); CHKiRet(statsobj.ConstructFinalize(bkts->global_stats)); pthread_rwlock_init(&bkts->lock, NULL); bkts->initialized = 1; finalize_it: if (iRet != RS_RET_OK) { statsobj.Destruct(&bkts->global_stats); } RETiRet; } void dynstats_destroyAllBuckets(void) { dynstats_buckets_t *bkts; dynstats_bucket_t *b; bkts = &runConf->dynstats_buckets; if (bkts->initialized) { pthread_rwlock_wrlock(&bkts->lock); while (1) { b = bkts->list; if (b == NULL) { break; } else { bkts->list = b->next; dynstats_destroyBucket(bkts, b); } } statsobj.Destruct(&bkts->global_stats); pthread_rwlock_unlock(&bkts->lock); pthread_rwlock_destroy(&bkts->lock); } } dynstats_bucket_t *dynstats_findBucket(const uchar *name) { dynstats_buckets_t *bkts; dynstats_bucket_t *b; bkts = &loadConf->dynstats_buckets; if (bkts->initialized) { pthread_rwlock_rdlock(&bkts->lock); b = bkts->list; while (b != NULL) { if (!ustrcmp(name, b->name)) { break; } b = b->next; } pthread_rwlock_unlock(&bkts->lock); } else { b = NULL; LogError(0, RS_RET_INTERNAL_ERROR, "dynstats: bucket lookup failed, as global-initialization " "of buckets was unsuccessful"); } return b; } static rsRetVal dynstats_createCtr(dynstats_bucket_t *b, const uchar *metric, dynstats_ctr_t **ctr) { DEFiRet; CHKmalloc(*ctr = calloc(1, sizeof(dynstats_ctr_t))); CHKmalloc((*ctr)->metric = ustrdup(metric)); STATSCOUNTER_INIT((*ctr)->ctr, (*ctr)->mutCtr); CHKiRet(statsobj.AddManagedCounter(b->stats, metric, ctrType_IntCtr, b->resettable ? CTR_FLAG_MUST_RESET : CTR_FLAG_NONE, &(*ctr)->ctr, &(*ctr)->pCtr, 0)); finalize_it: if (iRet != RS_RET_OK) { if ((*ctr) != NULL) { free((*ctr)->metric); free(*ctr); *ctr = NULL; } } RETiRet; } #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" /* TODO: how can we fix these warnings? */ #endif static rsRetVal dynstats_addNewCtr(dynstats_bucket_t *b, const uchar *metric, uint8_t doInitialIncrement) { dynstats_ctr_t *ctr; dynstats_ctr_t *found_ctr, *survivor_ctr, *effective_ctr; int created; uchar *copy_of_key = NULL; DEFiRet; created = 0; ctr = NULL; if ((unsigned)ATOMIC_FETCH_32BIT_unsigned(&b->metricCount, &b->mutMetricCount) >= b->maxCardinality) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } CHKiRet(dynstats_createCtr(b, metric, &ctr)); pthread_rwlock_wrlock(&b->lock); found_ctr = (dynstats_ctr_t *)hashtable_search(b->table, ctr->metric); if (found_ctr != NULL) { if (doInitialIncrement) { STATSCOUNTER_INC(found_ctr->ctr, found_ctr->mutCtr); } } else { copy_of_key = ustrdup(ctr->metric); if (copy_of_key != NULL) { survivor_ctr = (dynstats_ctr_t *)hashtable_search(b->survivor_table, ctr->metric); if (survivor_ctr == NULL) { effective_ctr = ctr; } else { effective_ctr = survivor_ctr; if (survivor_ctr->prev != NULL) { survivor_ctr->prev->next = survivor_ctr->next; } if (survivor_ctr->next != NULL) { survivor_ctr->next->prev = survivor_ctr->prev; } if (survivor_ctr == b->survivor_ctrs) { b->survivor_ctrs = survivor_ctr->next; } } if ((created = hashtable_insert(b->table, copy_of_key, effective_ctr))) { statsobj.AddPreCreatedCtr(b->stats, effective_ctr->pCtr); } } if (created) { if (b->ctrs != NULL) { b->ctrs->prev = effective_ctr; } effective_ctr->prev = NULL; effective_ctr->next = b->ctrs; b->ctrs = effective_ctr; if (doInitialIncrement) { STATSCOUNTER_INC(effective_ctr->ctr, effective_ctr->mutCtr); } } } pthread_rwlock_unlock(&b->lock); if (found_ctr != NULL) { // ignore } else if (created && (effective_ctr != survivor_ctr)) { ATOMIC_INC(&b->metricCount, &b->mutMetricCount); STATSCOUNTER_INC(b->ctrNewMetricAdd, b->mutCtrNewMetricAdd); } else if (!created) { if (copy_of_key != NULL) { free(copy_of_key); } ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } finalize_it: if (((!created) || (effective_ctr != ctr)) && (ctr != NULL)) { dynstats_destroyCtr(ctr); } RETiRet; } #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif rsRetVal dynstats_inc(dynstats_bucket_t *b, uchar *metric) { dynstats_ctr_t *ctr; DEFiRet; if (!GatherStats) { FINALIZE; } if (ustrlen(metric) == 0) { STATSCOUNTER_INC(b->ctrNoMetric, b->mutCtrNoMetric); FINALIZE; } if (pthread_rwlock_tryrdlock(&b->lock) == 0) { ctr = (dynstats_ctr_t *)hashtable_search(b->table, metric); if (ctr != NULL) { STATSCOUNTER_INC(ctr->ctr, ctr->mutCtr); } pthread_rwlock_unlock(&b->lock); } else { ABORT_FINALIZE(RS_RET_NOENTRY); } if (ctr == NULL) { CHKiRet(dynstats_addNewCtr(b, metric, 1)); } finalize_it: if (iRet != RS_RET_OK) { if (iRet == RS_RET_NOENTRY) { /* NOTE: this is not tested (because it requires very strong orchestration to guarantee contended lock for testing) */ STATSCOUNTER_INC(b->ctrOpsIgnored, b->mutCtrOpsIgnored); } else { STATSCOUNTER_INC(b->ctrOpsOverflow, b->mutCtrOpsOverflow); } } RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/nsd_mbedtls.c0000644000000000000000000000013215114522477016666 xustar0030 mtime=1764926783.041632005 30 atime=1764926783.489643004 30 ctime=1764935923.362579321 rsyslog-8.2512.0/runtime/nsd_mbedtls.c0000664000175000017500000013374115114522477016343 0ustar00rgerrger/* nsd_mbedtls.c * * An implementation of the nsd interface for Mbed TLS. * * Copyright (C) 2007-2023 Rainer Gerhards and Adiscon GmbH. * Copyright (C) 2023 CS Group. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "obj.h" #include "nsd_ptcp.h" #include "nsd_mbedtls.h" #include "rsconf.h" #include "net.h" MODULE_TYPE_LIB MODULE_TYPE_KEEP /* static data */ DEFobjStaticHelpers DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(nsd_ptcp) /* Mbed TLS debug level (0..5) * 5 is the most logs. */ #define MBEDTLS_DEBUG_LEVEL 0 #define DEFAULT_MAX_DEPTH 5 #if MBEDTLS_DEBUG_LEVEL > 0 static void debug(void __attribute__((unused)) * ctx, int __attribute__((unused)) level, const char *file, int line, const char *str) { dbgprintf("%s:%04d: %s", file, line, str); } #endif #define logMbedtlsError(err, mbedtls_err) \ do { \ char error_buf[128]; \ int aux = (mbedtls_err < 0 ? -mbedtls_err : mbedtls_err); \ const char *sig = (mbedtls_err < 0 ? "-" : ""); \ mbedtls_strerror(mbedtls_err, error_buf, 100); \ LogError(0, err, "Mbed TLS Error: %s0x%04X - %s", sig, aux, error_buf); \ } while (0) /* initialize Mbed TLS credential structure */ static rsRetVal mbedtlsInitCred(nsd_mbedtls_t *const pThis) { DEFiRet; const uchar *cafile; const uchar *crlfile; const uchar *keyFile; const uchar *certFile; int r; keyFile = (pThis->pszKeyFile == NULL) ? glbl.GetDfltNetstrmDrvrKeyFile(runConf) : pThis->pszKeyFile; if (keyFile != NULL) { mbedtls_pk_free(&(pThis->pkey)); mbedtls_pk_init(&(pThis->pkey)); #if MBEDTLS_VERSION_MAJOR >= 3 if ((r = mbedtls_pk_parse_keyfile(&(pThis->pkey), (const char *)keyFile, NULL, mbedtls_ctr_drbg_random, &(pThis->ctr_drbg))) != 0) { #else if ((r = mbedtls_pk_parse_keyfile(&(pThis->pkey), (const char *)keyFile, NULL)) != 0) { #endif logMbedtlsError(RS_RET_NO_ERRCODE, r); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } pThis->bHaveKey = 1; } certFile = (pThis->pszCertFile == NULL) ? glbl.GetDfltNetstrmDrvrCertFile(runConf) : pThis->pszCertFile; if (certFile != NULL) { mbedtls_x509_crt_free(&(pThis->srvcert)); mbedtls_x509_crt_init(&(pThis->srvcert)); if ((r = mbedtls_x509_crt_parse_file(&(pThis->srvcert), (const char *)certFile)) != 0) { logMbedtlsError(RS_RET_NO_ERRCODE, r); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } pThis->bHaveCert = 1; } cafile = (pThis->pszCAFile == NULL) ? glbl.GetDfltNetstrmDrvrCAF(runConf) : pThis->pszCAFile; if (cafile != NULL) { mbedtls_x509_crt_free(&(pThis->cacert)); mbedtls_x509_crt_init(&(pThis->cacert)); if ((r = mbedtls_x509_crt_parse_file(&(pThis->cacert), (const char *)cafile)) != 0) { logMbedtlsError(RS_RET_NO_ERRCODE, r); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } pThis->bHaveCaCert = 1; } crlfile = (pThis->pszCRLFile == NULL) ? glbl.GetDfltNetstrmDrvrCRLF(runConf) : pThis->pszCRLFile; if (crlfile != NULL) { mbedtls_x509_crl_free(&(pThis->crl)); mbedtls_x509_crl_init(&(pThis->crl)); if ((r = mbedtls_x509_crl_parse_file(&(pThis->crl), (const char *)crlfile)) != 0) { logMbedtlsError(RS_RET_NO_ERRCODE, r); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } pThis->bHaveCrl = 1; } finalize_it: if (iRet) { LogMsg(0, RS_RET_ERR, LOG_ERR, "nsd mbedtls: error parsing crypto config"); } RETiRet; } /* globally initialize Mbed TLS */ static rsRetVal mbedtlsGlblInit(void) { DEFiRet; dbgprintf("mbedtlsGlblInit: Running Version: '%#010x'\n", MBEDTLS_VERSION_NUMBER); RETiRet; } static rsRetVal get_custom_string(char **out) { DEFiRet; struct timeval tv; struct tm tm; CHKiRet(gettimeofday(&tv, NULL)); if (localtime_r(&(tv.tv_sec), &tm) == NULL) { ABORT_FINALIZE(RS_RET_NO_ERRCODE); } if (asprintf(out, "nsd_mbedtls-%04d-%02d-%02d %02d:%02d:%02d:%08ld", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec) == -1) { *out = NULL; ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } finalize_it: RETiRet; } static rsRetVal mbedtlsInitSession(nsd_mbedtls_t *pThis) { DEFiRet; char *cust = NULL; CHKiRet(get_custom_string(&cust)); CHKiRet(mbedtls_ctr_drbg_seed(&(pThis->ctr_drbg), mbedtls_entropy_func, &(pThis->entropy), (const unsigned char *)cust, strlen(cust))); finalize_it: if (iRet != RS_RET_OK) { LogError(0, iRet, "mbedtlsInitSession failed to INIT Session"); } free(cust); RETiRet; } /* globally de-initialize Mbed TLS */ static rsRetVal mbedtlsGlblExit(void) { DEFiRet; RETiRet; } /* end a Mbed TLS session * The function checks if we have a session and ends it only if so. So it can * always be called, even if there currently is no session. */ static rsRetVal mbedtlsEndSess(nsd_mbedtls_t *pThis) { DEFiRet; int mbedtlsRet; if (pThis->bHaveSess) { while ((mbedtlsRet = mbedtls_ssl_close_notify(&(pThis->ssl))) != 0) { if (mbedtlsRet != MBEDTLS_ERR_SSL_WANT_READ && mbedtlsRet != MBEDTLS_ERR_SSL_WANT_WRITE) break; } pThis->bHaveSess = 0; } RETiRet; } /* Standard-Constructor */ BEGINobjConstruct(nsd_mbedtls) /* be sure to specify the object type also in END macro! */ iRet = nsd_ptcp.Construct(&pThis->pTcp); mbedtls_ssl_init(&(pThis->ssl)); mbedtls_ssl_config_init(&(pThis->conf)); mbedtls_x509_crt_init(&(pThis->cacert)); mbedtls_x509_crl_init(&(pThis->crl)); mbedtls_pk_init(&(pThis->pkey)); mbedtls_x509_crt_init(&(pThis->srvcert)); mbedtls_ctr_drbg_init(&(pThis->ctr_drbg)); mbedtls_entropy_init(&(pThis->entropy)); pThis->bReportAuthErr = 1; #if MBEDTLS_DEBUG_LEVEL > 0 mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); #endif ENDobjConstruct(nsd_mbedtls) /* destructor for the nsd_mbedtls object */ PROTOTYPEobjDestruct(nsd_mbedtls); BEGINobjDestruct(nsd_mbedtls) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(nsd_mbedtls) if (pThis->iMode == 1) { mbedtlsEndSess(pThis); } if (pThis->pTcp != NULL) { nsd_ptcp.Destruct(&pThis->pTcp); } free((void *)pThis->pszCAFile); free((void *)pThis->pszCRLFile); free((void *)pThis->pszKeyFile); free((void *)pThis->pszCertFile); free((void *)pThis->anzCipherSuites); free((void *)pThis->pszConnectHost); mbedtls_entropy_free(&(pThis->entropy)); mbedtls_ctr_drbg_free(&(pThis->ctr_drbg)); mbedtls_x509_crt_free(&(pThis->srvcert)); mbedtls_pk_free(&(pThis->pkey)); mbedtls_x509_crl_free(&(pThis->crl)); mbedtls_x509_crt_free(&(pThis->cacert)); mbedtls_ssl_config_free(&(pThis->conf)); mbedtls_ssl_free(&(pThis->ssl)); ENDobjDestruct(nsd_mbedtls) /* Set the driver mode. For us, this has the following meaning: * 0 - work in plain tcp mode, without tls (e.g. before a STARTTLS) * 1 - work in TLS mode * rgerhards, 2008-04-28 */ static rsRetVal SetMode(nsd_t *const pNsd, const int mode) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); dbgprintf("(tls) mode: %d\n", mode); if (mode != 0 && mode != 1) { LogError(0, RS_RET_INVALID_DRVR_MODE, "error: driver mode %d not supported by " "mbedtls netstream driver", mode); ABORT_FINALIZE(RS_RET_INVALID_DRVR_MODE); } pThis->iMode = mode; finalize_it: RETiRet; } /* Set the authentication mode. For us, the following is supported: * anon - no certificate checks whatsoever (discouraged, but supported) * x509/certvalid - (just) check certificate validity * x509/fingerprint - certificate fingerprint * x509/name - cerfificate name check * mode == NULL is valid and defaults to x509/name * rgerhards, 2008-05-16 */ static rsRetVal SetAuthMode(nsd_t *pNsd, uchar *mode) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (mode == NULL || !strcasecmp((char *)mode, "x509/name")) { pThis->authMode = MBEDTLS_AUTH_CERTNAME; } else if (!strcasecmp((char *)mode, "x509/fingerprint")) { pThis->authMode = MBEDTLS_AUTH_CERTFINGERPRINT; } else if (!strcasecmp((char *)mode, "x509/certvalid")) { pThis->authMode = MBEDTLS_AUTH_CERTVALID; } else if (!strcasecmp((char *)mode, "anon")) { pThis->authMode = MBEDTLS_AUTH_CERTANON; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: authentication mode '%s' not supported by " "mbedtls netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetAuthMode to %s\n", (mode != NULL ? (char *)mode : "NULL")); finalize_it: RETiRet; } /* Set the PermitExpiredCerts mode. For us, the following is supported: * on - fail if certificate is expired * off - ignore expired certificates * warn - warn if certificate is expired * alorbach, 2018-12-20 */ static rsRetVal SetPermitExpiredCerts(nsd_t *pNsd, uchar *mode) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); /* default is set to off! */ if (mode == NULL || !strcasecmp((char *)mode, "off")) { pThis->permitExpiredCerts = MBEDTLS_EXPIRED_DENY; } else if (!strcasecmp((char *)mode, "warn")) { pThis->permitExpiredCerts = MBEDTLS_EXPIRED_WARN; } else if (!strcasecmp((char *)mode, "on")) { pThis->permitExpiredCerts = MBEDTLS_EXPIRED_PERMIT; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: permitexpiredcerts mode '%s' not supported by " "mbedtls netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetPermitExpiredCerts: Set Mode %s/%d\n", (mode != NULL ? (char *)mode : "NULL"), pThis->permitExpiredCerts); /* TODO: clear stored IDs! */ finalize_it: RETiRet; } /* Set permitted peers. It is depending on the auth mode if this are * fingerprints or names. -- rgerhards, 2008-05-19 */ static rsRetVal SetPermPeers(nsd_t *pNsd, permittedPeers_t *pPermPeers) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (pPermPeers == NULL) FINALIZE; if (pThis->authMode != MBEDTLS_AUTH_CERTFINGERPRINT && pThis->authMode != MBEDTLS_AUTH_CERTNAME) { LogError(0, RS_RET_VALUE_NOT_IN_THIS_MODE, "authentication not supported by " "mbedtls netstream driver in the configured authentication mode - ignored"); ABORT_FINALIZE(RS_RET_VALUE_NOT_IN_THIS_MODE); } pThis->pPermPeers = pPermPeers; finalize_it: RETiRet; } /* Set the priority string, aka the cipher suite list in * decreasing priority order (most important priority first) */ static rsRetVal SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; int nCipherSuiteId; char *pCurrentPos; char *pSave; int count = 0; char *str = NULL; int *tmp; const char *separators = ",; \n"; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (gnutlsPriorityString != NULL) { CHKmalloc(str = strdup((const char *)gnutlsPriorityString)); for (pCurrentPos = strtok_r(str, separators, &pSave); pCurrentPos != NULL; pCurrentPos = strtok_r(NULL, separators, &pSave)) { if (*pCurrentPos == '\0') { continue; } nCipherSuiteId = mbedtls_ssl_get_ciphersuite_id(pCurrentPos); if (nCipherSuiteId == 0) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "SetGnutlsPriorityString: %s " "is not supported", pCurrentPos); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } CHKmalloc(tmp = realloc(pThis->anzCipherSuites, (count + 2) * sizeof(int))); pThis->anzCipherSuites = tmp; pThis->anzCipherSuites[count] = nCipherSuiteId; pThis->anzCipherSuites[count + 1] = 0; ++count; } } finalize_it: free(str); RETiRet; } /* Set the driver cert extended key usage check setting * 0 - ignore contents of extended key usage * 1 - verify that cert contents is compatible with appropriate OID * jvymazal, 2019-08-16 */ static rsRetVal SetCheckExtendedKeyUsage(nsd_t *pNsd, int ChkExtendedKeyUsage) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (ChkExtendedKeyUsage != 0 && ChkExtendedKeyUsage != 1) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d " "not supported by mbedtls netstream driver", ChkExtendedKeyUsage); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetCheckExtendedKeyUsage: %d\n", ChkExtendedKeyUsage); pThis->dataTypeCheck = ChkExtendedKeyUsage; finalize_it: RETiRet; } /* Set the driver name checking strictness * 0 - less strict per RFC 5280, section 4.1.2.6 - either SAN or CN match is good * 1 - more strict per RFC 6125 - if any SAN present it must match (CN is ignored) * jvymazal, 2019-08-16 */ static rsRetVal SetPrioritizeSAN(nsd_t *pNsd, int prioritizeSan) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (prioritizeSan != 0 && prioritizeSan != 1) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d " "not supported by mbedtls netstream driver", prioritizeSan); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } pThis->bSANpriority = prioritizeSan; finalize_it: RETiRet; } /* Set the driver tls verifyDepth * alorbach, 2019-12-20 */ static rsRetVal SetTlsVerifyDepth(nsd_t *pNsd, int verifyDepth) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); pThis->DrvrVerifyDepth = verifyDepth; dbgprintf("SetTlsVerifyDepth: %d\n", pThis->DrvrVerifyDepth); RETiRet; } static rsRetVal SetTlsCAFile(nsd_t *pNsd, const uchar *const caFile) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); free((void *)pThis->pszCAFile); if (caFile == NULL) { pThis->pszCAFile = NULL; } else { CHKmalloc(pThis->pszCAFile = (const uchar *)strdup((const char *)caFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCRLFile(nsd_t *pNsd, const uchar *const crlFile) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); free((void *)pThis->pszCRLFile); if (crlFile == NULL) { pThis->pszCRLFile = NULL; } else { CHKmalloc(pThis->pszCRLFile = (const uchar *)strdup((const char *)crlFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsKeyFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); free((void *)pThis->pszKeyFile); if (pszFile == NULL) { pThis->pszKeyFile = NULL; } else { CHKmalloc(pThis->pszKeyFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCertFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); free((void *)pThis->pszCertFile); if (pszFile == NULL) { pThis->pszCertFile = NULL; } else { CHKmalloc(pThis->pszCertFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_mbedtls) who utilize ourselfs * for some of their functionality. -- rgerhards, 2008-04-18 */ static rsRetVal SetSock(nsd_t *pNsd, int sock) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); DBGPRINTF("SetSock for [%p]: Setting sock %d\n", pNsd, sock); nsd_ptcp.SetSock(pThis->pTcp, sock); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveIntvl(nsd_t *pNsd, int keepAliveIntvl) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); assert(keepAliveIntvl >= 0); nsd_ptcp.SetKeepAliveIntvl(pThis->pTcp, keepAliveIntvl); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveProbes(nsd_t *pNsd, int keepAliveProbes) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); assert(keepAliveProbes >= 0); nsd_ptcp.SetKeepAliveProbes(pThis->pTcp, keepAliveProbes); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveTime(nsd_t *pNsd, int keepAliveTime) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); assert(keepAliveTime >= 0); nsd_ptcp.SetKeepAliveTime(pThis->pTcp, keepAliveTime); RETiRet; } /* abort a connection. This is meant to be called immediately * before the Destruct call. -- rgerhards, 2008-03-24 */ static rsRetVal Abort(nsd_t *pNsd) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_mbedtls); if (pThis->iMode == 0) { nsd_ptcp.Abort(pThis->pTcp); } RETiRet; } /* Allow Mbed TLS to read data from the network. */ static int mbedtlsNetRecv(void *ctx, unsigned char *buf, size_t len) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)ctx; ssize_t slen = len; int oserr; DEFiRet; slen = recv(pThis->sock, buf, len, 0); oserr = errno; if (slen < 0) { switch (oserr) { case EAGAIN: #if EAGAIN != EWOULDBLOCK case EWOULDBLOCK: #endif case EINTR: ABORT_FINALIZE(MBEDTLS_ERR_SSL_WANT_READ); case EPIPE: case ECONNRESET: ABORT_FINALIZE(MBEDTLS_ERR_NET_CONN_RESET); default: ABORT_FINALIZE(MBEDTLS_ERR_NET_RECV_FAILED); } } iRet = slen; finalize_it: RETiRet; } /* Allow Mbed TLS to write data to the network. */ static int mbedtlsNetSend(void *ctx, const unsigned char *buf, size_t len) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)ctx; ssize_t slen = len; DEFiRet; iRet = nsd_ptcp.Send(pThis->pTcp, (unsigned char *)buf, &slen); if (iRet < RS_RET_OK) { ABORT_FINALIZE(MBEDTLS_ERR_NET_SEND_FAILED); } iRet = slen; finalize_it: RETiRet; } static int mbedtlsAuthMode(nsd_mbedtls_t *const pThis) { int mode; switch (pThis->authMode) { case MBEDTLS_AUTH_CERTNAME: case MBEDTLS_AUTH_CERTVALID: case MBEDTLS_AUTH_CERTFINGERPRINT: if (pThis->dataTypeCheck == MBEDTLS_NONE) mode = MBEDTLS_SSL_VERIFY_OPTIONAL; else mode = MBEDTLS_SSL_VERIFY_REQUIRED; break; case MBEDTLS_AUTH_CERTANON: mode = MBEDTLS_SSL_VERIFY_NONE; break; default: assert(0); /* this shall not happen! */ dbgprintf("ERROR: pThis->authMode %d invalid in nsd_mbedtls.c:%d\n", pThis->authMode, __LINE__); mode = MBEDTLS_SSL_VERIFY_REQUIRED; break; } return mode; } /* Obtain fingerprint of crt in buf of size *len. * *len will be filled with actual fingerprint length on output. */ static rsRetVal mbedtlsCertFingerprint(const mbedtls_x509_crt *crt, mbedtls_md_type_t mdType, uchar *buf, size_t *len) { const mbedtls_md_info_t *mdInfo; size_t mdLen = 0; DEFiRet; mdInfo = mbedtls_md_info_from_type(mdType); if (mdInfo == NULL) ABORT_FINALIZE(RS_RET_CODE_ERR); mdLen = mbedtls_md_get_size(mdInfo); if (*len < mdLen) ABORT_FINALIZE(RS_RET_PROVIDED_BUFFER_TOO_SMALL); if (crt == NULL || buf == NULL) ABORT_FINALIZE(RS_RET_CODE_ERR); if (mbedtls_md(mdInfo, crt->raw.p, crt->raw.len, buf) != 0) ABORT_FINALIZE(RS_RET_CODE_ERR); finalize_it: *len = mdLen; RETiRet; } /* Convert a fingerprint to printable data. The conversion is carried out * according IETF I-D syslog-transport-tls-12. The fingerprint string is * returned in a new cstr object. It is the caller's responsibility to * destruct that object. * rgerhards, 2008-05-08 */ static rsRetVal GenFingerprintStr(uchar *pFingerprint, size_t sizeFingerprint, cstr_t **ppStr, const char *prefix) { cstr_t *pStr = NULL; uchar buf[4]; size_t i; DEFiRet; CHKiRet(rsCStrConstruct(&pStr)); CHKiRet(rsCStrAppendStrWithLen(pStr, (uchar *)prefix, strlen(prefix))); for (i = 0; i < sizeFingerprint; ++i) { snprintf((char *)buf, sizeof(buf), ":%2.2X", pFingerprint[i]); CHKiRet(rsCStrAppendStrWithLen(pStr, buf, 3)); } cstrFinalize(pStr); *ppStr = pStr; finalize_it: if (iRet != RS_RET_OK) { if (pStr != NULL) rsCStrDestruct(&pStr); } RETiRet; } static rsRetVal mbedtlsChkPeerFingerprint(nsd_mbedtls_t *pThis, mbedtls_x509_crt *crt) { uchar fingerprint[20]; uchar fingerprintSha256[32]; size_t size; size_t sizeSha256; cstr_t *pstrFingerprint = NULL; cstr_t *pstrFingerprintSha256 = NULL; int bFoundPositiveMatch; permittedPeers_t *pPeer; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); /* obtain the SHA1 fingerprint */ size = sizeof(fingerprint); sizeSha256 = sizeof(fingerprintSha256); CHKiRet(mbedtlsCertFingerprint(crt, MBEDTLS_MD_SHA1, fingerprint, &size)); CHKiRet(mbedtlsCertFingerprint(crt, MBEDTLS_MD_SHA256, fingerprintSha256, &sizeSha256)); CHKiRet(GenFingerprintStr(fingerprint, size, &pstrFingerprint, "SHA1")); CHKiRet(GenFingerprintStr(fingerprintSha256, sizeSha256, &pstrFingerprintSha256, "SHA256")); dbgprintf("peer's certificate SHA1 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprint)); dbgprintf("peer's certificate SHA256 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprintSha256)); /* now search through the permitted peers to see if we can find a permitted one */ bFoundPositiveMatch = 0; pPeer = pThis->pPermPeers; while (pPeer != NULL && !bFoundPositiveMatch) { if (!rsCStrSzStrCmp(pstrFingerprint, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("mbedtlsChkPeerFingerprint: peer's certificate SHA1 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else if (!rsCStrSzStrCmp(pstrFingerprintSha256, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("mbedtlsChkPeerFingerprint: peer's certificate SHA256 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else { pPeer = pPeer->pNext; } } if (!bFoundPositiveMatch) { dbgprintf("invalid peer fingerprint, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { errno = 0; LogError(0, RS_RET_INVALID_FINGERPRINT, "error: peer fingerprint '%s' unknown - we are " "not permitted to talk to it", cstrGetSzStrNoNULL(pstrFingerprint)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } finalize_it: if (pstrFingerprint != NULL) cstrDestruct(&pstrFingerprint); if (pstrFingerprintSha256 != NULL) cstrDestruct(&pstrFingerprintSha256); RETiRet; } /* Perform a match on ONE peer name obtained from the certificate. This name * is checked against the set of configured credentials. *pbFoundPositiveMatch is * set to 1 if the ID matches. *pbFoundPositiveMatch must have been initialized * to 0 by the caller (this is a performance enhancement as we expect to be * called multiple times). * TODO: implemet wildcards? * rgerhards, 2008-05-26 */ static rsRetVal mbedtlsChkOnePeerName(nsd_mbedtls_t *pThis, uchar *pszPeerID, int *pbFoundPositiveMatch) { permittedPeers_t *pPeer; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); assert(pszPeerID != NULL); assert(pbFoundPositiveMatch != NULL); if (pThis->pPermPeers) { /* do we have configured peer IDs? */ pPeer = pThis->pPermPeers; while (pPeer != NULL) { CHKiRet(net.PermittedPeerWildcardMatch(pPeer, pszPeerID, pbFoundPositiveMatch)); if (*pbFoundPositiveMatch) break; pPeer = pPeer->pNext; } } else { /* we do not have configured peer IDs, so we use defaults */ if (pThis->pszConnectHost && !strcmp((char *)pszPeerID, (char *)pThis->pszConnectHost)) { *pbFoundPositiveMatch = 1; } } finalize_it: RETiRet; } /* Get the common name (CN) from a certificate * Caller must free() the returned string */ static char *mbedtlsCnFromCrt(const mbedtls_x509_crt *crt) { const mbedtls_x509_name *name; for (name = &crt->subject; name != NULL; name = name->next) { if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0) { return strndup((const char *)(name->val.p), name->val.len); } } return NULL; } static rsRetVal mbedtlsChkPeerName(nsd_mbedtls_t *pThis, mbedtls_x509_crt *crt) { uchar lnBuf[256]; const mbedtls_x509_sequence *san; int bFoundPositiveMatch; char *str = NULL; int bHaveSAN = 0; cstr_t *pStr = NULL; DEFiRet; bFoundPositiveMatch = 0; CHKiRet(rsCStrConstruct(&pStr)); /* Check SANs */ for (san = &crt->subject_alt_names; !bFoundPositiveMatch && san != NULL && san->buf.p != NULL; san = san->next) { if (san->buf.tag == (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME)) { CHKmalloc(str = strndup((const char *)(san->buf.p), san->buf.len)); bHaveSAN = 1; dbgprintf("subject alt dnsName: '%s'\n", str); snprintf((char *)lnBuf, sizeof(lnBuf), "DNSname: %s; ", str); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(mbedtlsChkOnePeerName(pThis, (uchar *)str, &bFoundPositiveMatch)); free(str); str = NULL; } } /* Check also CN only if not configured per stricter RFC 6125 or no SAN present*/ if (!bFoundPositiveMatch && (!pThis->bSANpriority || !bHaveSAN)) { str = mbedtlsCnFromCrt(crt); if (str != NULL) { /* NULL if there was no CN present */ dbgprintf("mbedtls now checking auth for CN '%s'\n", str); snprintf((char *)lnBuf, sizeof(lnBuf), "CN: %s; ", str); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(mbedtlsChkOnePeerName(pThis, (uchar *)str, &bFoundPositiveMatch)); } } if (!bFoundPositiveMatch) { dbgprintf("invalid peer name, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { cstrFinalize(pStr); errno = 0; LogError(0, RS_RET_INVALID_FINGERPRINT, "error: peer name not authorized - " "not permitted to talk to it. Names: %s", cstrGetSzStrNoNULL(pStr)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } finalize_it: if (pStr != NULL) rsCStrDestruct(&pStr); free(str); RETiRet; } /* This is a callback fonction to allow extra checks * in addition to default verifications already done by Mbed TLS's * default processing. */ static int verify(void *ctx, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)ctx; DEFiRet; if (depth > (pThis->DrvrVerifyDepth != 0 ? pThis->DrvrVerifyDepth : DEFAULT_MAX_DEPTH)) ABORT_FINALIZE(MBEDTLS_ERR_X509_FATAL_ERROR); if (depth > 0) FINALIZE; /* Nothing more to be done with issuer's certificates */ /* Mbed TLS API states that if any of the following checks fails, * the verify callback should set the corresponding flag (or * clear it if the check is not cared about) and return 0. * (see mbedtls_x509_crt_verify() documentation) */ if ((*flags) & MBEDTLS_X509_BADCERT_EXPIRED) { if (pThis->permitExpiredCerts == MBEDTLS_EXPIRED_DENY) { FINALIZE; } if (pThis->permitExpiredCerts == MBEDTLS_EXPIRED_WARN) { LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "Warning, certificate expired but expired certs are permitted"); } else { dbgprintf( "Mbed TLS gives MBEDTLS_X509_BADCERT_EXPIRED" ", but expired certs are permitted.\n"); } *flags &= ~MBEDTLS_X509_BADCERT_EXPIRED; } if (pThis->authMode == MBEDTLS_AUTH_CERTFINGERPRINT) { if (mbedtlsChkPeerFingerprint(pThis, crt) != RS_RET_OK) { *flags |= MBEDTLS_X509_BADCERT_OTHER; } } else if (pThis->authMode == MBEDTLS_AUTH_CERTNAME) { if (mbedtlsChkPeerName(pThis, crt) != RS_RET_OK) { *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; } } /* Other auth modes have already been handled by default processing */ finalize_it: RETiRet; } static rsRetVal CheckVerifyResult(nsd_mbedtls_t *pThis) { DEFiRet; uint32_t flags; flags = mbedtls_ssl_get_verify_result(&(pThis->ssl)); if (mbedtlsAuthMode(pThis) != MBEDTLS_SSL_VERIFY_OPTIONAL) FINALIZE; if (pThis->dataTypeCheck == MBEDTLS_NONE && (flags & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE)) { dbgprintf("Mbed TLS gives MBEDTLS_X509_BADCERT_EXT_KEY_USAGE but check disabled\n"); flags &= ~MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; } if (flags != 0) { logMbedtlsError(RS_RET_CERT_INVALID, MBEDTLS_ERR_X509_CERT_VERIFY_FAILED); ABORT_FINALIZE(RS_RET_CERT_INVALID); } finalize_it: if (flags != 0) { char vrfy_buf[512]; if (mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "Mbed TLS verify info : ", flags) < 0) LogError(0, RS_RET_PROVIDED_BUFFER_TOO_SMALL, "Can't get Mbed TLS verify info"); else LogError(0, RS_RET_CERT_INVALID, "%s", vrfy_buf); } RETiRet; } static rsRetVal zeroTermIntArrayDup(int *array, int **copy) { int c, i; int *p = NULL; DEFiRet; c = 0; while (array[c] != 0) ++c; CHKmalloc(p = malloc((c + 1) * sizeof(int))); for (i = 0; i <= c; ++i) p[i] = array[i]; finalize_it: *copy = p; RETiRet; } /* accept an incoming connection request - here, we do the usual accept * handling. TLS specific handling is done thereafter (and if we run in TLS * mode at this time). * rgerhards, 2008-04-25 */ static rsRetVal AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew, char *const connInfo) { DEFiRet; nsd_mbedtls_t *pNew = NULL; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; int mbedtlsRet; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); CHKiRet(nsd_mbedtlsConstruct(&pNew)); // TODO: prevent construct/destruct! CHKiRet(nsd_ptcp.Destruct(&pNew->pTcp)); CHKiRet(nsd_ptcp.AcceptConnReq(pThis->pTcp, &pNew->pTcp, connInfo)); if (pThis->iMode == 0) { /* we are in non-TLS mode, so we are done */ *ppNew = (nsd_t *)pNew; FINALIZE; } /* copy Properties to pnew first */ pNew->authMode = pThis->authMode; pNew->bSANpriority = pThis->bSANpriority; pNew->pPermPeers = pThis->pPermPeers; pNew->DrvrVerifyDepth = pThis->DrvrVerifyDepth; pNew->dataTypeCheck = pThis->dataTypeCheck; pNew->permitExpiredCerts = pThis->permitExpiredCerts; if (pThis->anzCipherSuites) CHKiRet(zeroTermIntArrayDup(pThis->anzCipherSuites, &(pNew->anzCipherSuites))); if (pThis->pszCertFile) CHKmalloc(pNew->pszCertFile = (const uchar *)strdup((const char *)(pThis->pszCertFile))); if (pThis->pszKeyFile) CHKmalloc(pNew->pszKeyFile = (const uchar *)strdup((const char *)(pThis->pszKeyFile))); if (pThis->pszCAFile) CHKmalloc(pNew->pszCAFile = (const uchar *)strdup((const char *)(pThis->pszCAFile))); if (pThis->pszCRLFile) CHKmalloc(pNew->pszCRLFile = (const uchar *)strdup((const char *)(pThis->pszCRLFile))); pNew->iMode = pThis->iMode; /* if we reach this point, we are in TLS mode */ CHKiRet(mbedtlsInitSession(pNew)); CHKiRet(mbedtlsInitCred(pNew)); CHKiRet(mbedtls_ssl_config_defaults(&(pNew->conf), MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)); mbedtls_ssl_conf_rng(&(pNew->conf), mbedtls_ctr_drbg_random, &(pNew->ctr_drbg)); mbedtls_ssl_conf_authmode(&(pNew->conf), mbedtlsAuthMode(pNew)); mbedtls_ssl_conf_ca_chain(&(pNew->conf), pNew->bHaveCaCert ? &(pNew->cacert) : NULL, pNew->bHaveCrl ? &(pNew->crl) : NULL); mbedtls_ssl_conf_verify(&(pNew->conf), verify, pNew); if (pNew->bHaveKey && pNew->bHaveCert) CHKiRet(mbedtls_ssl_conf_own_cert(&(pNew->conf), &(pNew->srvcert), &(pNew->pkey))); #if MBEDTLS_DEBUG_LEVEL > 0 mbedtls_ssl_conf_dbg(&(pNew->conf), debug, stdout); #endif if (pNew->anzCipherSuites != NULL) mbedtls_ssl_conf_ciphersuites(&(pNew->conf), pNew->anzCipherSuites); CHKiRet(mbedtls_ssl_setup(&(pNew->ssl), &(pNew->conf))); // peer id will be checked in verify() callback CHKiRet(mbedtls_ssl_set_hostname(&(pNew->ssl), NULL)); CHKiRet(nsd_ptcp.GetSock(pNew->pTcp, &(pNew->sock))); mbedtls_ssl_set_bio(&(pNew->ssl), pNew, mbedtlsNetSend, mbedtlsNetRecv, NULL); mbedtlsRet = mbedtls_ssl_handshake(&(pNew->ssl)); if (mbedtlsRet != 0 && mbedtlsRet != MBEDTLS_ERR_SSL_WANT_READ && mbedtlsRet != MBEDTLS_ERR_SSL_WANT_WRITE) { logMbedtlsError(RS_RET_TLS_HANDSHAKE_ERR, mbedtlsRet); ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR); } CHKiRet(CheckVerifyResult(pNew)); pNew->bHaveSess = 1; *ppNew = (nsd_t *)pNew; finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) nsd_mbedtlsDestruct(&pNew); } RETiRet; } /* receive data from a tcp socket * The lenBuf parameter must contain the max buffer size on entry and contains * the number of octets read on exit. This function * never blocks, not even when called on a blocking socket. That is important * for client sockets, which are set to block during send, but should not * block when trying to read data. -- rgerhards, 2008-03-17 */ static rsRetVal Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf, int *const oserr, unsigned *const nextIODirection) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); int n = 0; if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf, oserr, nextIODirection)); FINALIZE; } /* --- in TLS mode now --- */ n = mbedtls_ssl_read(&(pThis->ssl), pBuf, *pLenBuf); if (n == MBEDTLS_ERR_SSL_WANT_READ || n == MBEDTLS_ERR_SSL_WANT_WRITE) ABORT_FINALIZE(RS_RET_RETRY); if (n == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ABORT_FINALIZE(RS_RET_CLOSED); if (n < 0) { logMbedtlsError(RS_RET_RCV_ERR, n); ABORT_FINALIZE(RS_RET_RCV_ERR); } if (n == 0) ABORT_FINALIZE(RS_RET_RETRY); CHKiRet(CheckVerifyResult(pThis)); *pLenBuf = n; finalize_it: dbgprintf("mbedtlsRcv return. nsd %p, iRet %d, lenRcvBuf %ld\n", pThis, iRet, (long)(*pLenBuf)); if (iRet != RS_RET_OK && iRet != RS_RET_RETRY) *pLenBuf = 0; RETiRet; } /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has * been written. * rgerhards, 2008-03-19 */ static rsRetVal Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) { int iSent; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Send(pThis->pTcp, pBuf, pLenBuf)); FINALIZE; } /* in TLS mode now */ iSent = mbedtls_ssl_write(&(pThis->ssl), pBuf, *pLenBuf); if (iSent == MBEDTLS_ERR_SSL_WANT_READ || iSent == MBEDTLS_ERR_SSL_WANT_WRITE) { ABORT_FINALIZE(RS_RET_RETRY); } else if (iSent <= 0) { logMbedtlsError(RS_RET_NO_ERRCODE, iSent); ABORT_FINALIZE(RS_RET_IO_ERROR); } CHKiRet(CheckVerifyResult(pThis)); *pLenBuf = iSent; finalize_it: RETiRet; } /* Enable KEEPALIVE handling on the socket. * rgerhards, 2009-06-02 */ static rsRetVal EnableKeepAlive(nsd_t *pNsd) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); return nsd_ptcp.EnableKeepAlive(pThis->pTcp); } /* open a connection to a remote host (server). */ static rsRetVal Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; int mbedtlsRet; dbgprintf("Connect to %s:%s\n", host, port); ISOBJ_TYPE_assert(pThis, nsd_mbedtls); assert(port != NULL); assert(host != NULL); CHKiRet(mbedtlsInitSession(pThis)); CHKiRet(mbedtlsInitCred(pThis)); CHKiRet(nsd_ptcp.Connect(pThis->pTcp, family, port, host, device)); if (pThis->iMode == 0) FINALIZE; /* we reach this point if in TLS mode */ CHKiRet(mbedtls_ssl_config_defaults(&(pThis->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)); mbedtls_ssl_conf_rng(&(pThis->conf), mbedtls_ctr_drbg_random, &(pThis->ctr_drbg)); mbedtls_ssl_conf_authmode(&(pThis->conf), mbedtlsAuthMode(pThis)); mbedtls_ssl_conf_ca_chain(&(pThis->conf), pThis->bHaveCaCert ? &(pThis->cacert) : NULL, pThis->bHaveCrl ? &(pThis->crl) : NULL); mbedtls_ssl_conf_verify(&(pThis->conf), verify, pThis); if (pThis->bHaveKey && pThis->bHaveCert) CHKiRet(mbedtls_ssl_conf_own_cert(&(pThis->conf), &(pThis->srvcert), &(pThis->pkey))); #if MBEDTLS_DEBUG_LEVEL > 0 mbedtls_ssl_conf_dbg(&(pThis->conf), debug, stdout); #endif if (pThis->anzCipherSuites != NULL) mbedtls_ssl_conf_ciphersuites(&(pThis->conf), pThis->anzCipherSuites); CHKiRet(mbedtls_ssl_setup(&(pThis->ssl), &(pThis->conf))); // peer id will be checked in verify() callback CHKiRet(mbedtls_ssl_set_hostname(&(pThis->ssl), NULL)); CHKmalloc(pThis->pszConnectHost = (uchar *)strdup((char *)host)); CHKiRet(nsd_ptcp.GetSock(pThis->pTcp, &(pThis->sock))); mbedtls_ssl_set_bio(&(pThis->ssl), pThis, mbedtlsNetSend, mbedtlsNetRecv, NULL); mbedtlsRet = mbedtls_ssl_handshake(&(pThis->ssl)); if (mbedtlsRet != 0 && mbedtlsRet != MBEDTLS_ERR_SSL_WANT_READ && mbedtlsRet != MBEDTLS_ERR_SSL_WANT_WRITE) { logMbedtlsError(RS_RET_TLS_HANDSHAKE_ERR, mbedtlsRet); ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR); } CHKiRet(CheckVerifyResult(pThis)); pThis->bHaveSess = 1; finalize_it: if (iRet != RS_RET_OK) { free(pThis->pszConnectHost); pThis->pszConnectHost = NULL; } RETiRet; } static rsRetVal ATTR_NONNULL(1, 3, 5) LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal (*fAddLstn)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *cnf_params) { DEFiRet; iRet = nsd_ptcp.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params); RETiRet; } /* This function checks if the connection is still alive - well, kind of... * This is a dummy here. For details, check function common in ptcp driver. * rgerhards, 2008-06-09 */ static rsRetVal CheckConnection(nsd_t *pNsd) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); dbgprintf("CheckConnection for %p\n", pNsd); return nsd_ptcp.CheckConnection(pThis->pTcp); } /* Provide access to the underlying OS socket. */ static rsRetVal GetSock(nsd_t *pNsd, int *pSock) { nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); return nsd_ptcp.GetSock(pThis->pTcp, pSock); } /* get the remote hostname. The returned hostname must be freed by the caller. * rgerhards, 2008-04-25 */ static rsRetVal GetRemoteHName(nsd_t *pNsd, uchar **ppszHName) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); iRet = nsd_ptcp.GetRemoteHName(pThis->pTcp, ppszHName); RETiRet; } /* Provide access to the sockaddr_storage of the remote peer. This * is needed by the legacy ACL system. --- gerhards, 2008-12-01 */ static rsRetVal GetRemAddr(nsd_t *pNsd, struct sockaddr_storage **ppAddr) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); iRet = nsd_ptcp.GetRemAddr(pThis->pTcp, ppAddr); RETiRet; } /* get the remote host's IP address. Caller must Destruct the object. */ static rsRetVal GetRemoteIP(nsd_t *pNsd, prop_t **ip) { DEFiRet; nsd_mbedtls_t *pThis = (nsd_mbedtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_mbedtls); iRet = nsd_ptcp.GetRemoteIP(pThis->pTcp, ip); RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(nsd_mbedtls) CODESTARTobjQueryInterface( nsd_mbedtls) if (pIf->ifVersion != nsdCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = (rsRetVal(*)(nsd_t **))nsd_mbedtlsConstruct; pIf->Destruct = (rsRetVal(*)(nsd_t **))nsd_mbedtlsDestruct; pIf->Abort = Abort; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->Rcv = Rcv; pIf->Send = Send; pIf->Connect = Connect; pIf->GetSock = GetSock; pIf->SetSock = SetSock; pIf->SetMode = SetMode; pIf->SetAuthMode = SetAuthMode; pIf->SetPermitExpiredCerts = SetPermitExpiredCerts; pIf->SetPermPeers = SetPermPeers; pIf->CheckConnection = CheckConnection; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->GetRemAddr = GetRemAddr; pIf->EnableKeepAlive = EnableKeepAlive; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; pIf->SetPrioritizeSAN = SetPrioritizeSAN; pIf->SetTlsVerifyDepth = SetTlsVerifyDepth; pIf->SetTlsCAFile = SetTlsCAFile; pIf->SetTlsCRLFile = SetTlsCRLFile; pIf->SetTlsKeyFile = SetTlsKeyFile; pIf->SetTlsCertFile = SetTlsCertFile; finalize_it: ENDobjQueryInterface(nsd_mbedtls) /* exit our class */ BEGINObjClassExit(nsd_mbedtls, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(nsd_mbedtls) mbedtlsGlblExit(); /* shut down Mbed TLS */ /* release objects we no longer need */ objRelease(nsd_ptcp, LM_NSD_PTCP_FILENAME); objRelease(net, LM_NET_FILENAME); objRelease(glbl, CORE_COMPONENT); ENDObjClassExit(nsd_mbedtls) /* Initialize the nsd_mbedtls class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(nsd_mbedtls, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(nsd_ptcp, LM_NSD_PTCP_FILENAME)); CHKiRet(objUse(net, LM_NET_FILENAME)); /* now do global TLS init stuff */ CHKiRet(mbedtlsGlblInit()); ENDObjClassInit(nsd_mbedtls) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit nsd_mbedtlsClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_LIB_QUERIES ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(nsd_mbedtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/strgen.c0000644000000000000000000000013215114522477015672 xustar0030 mtime=1764926783.041632005 30 atime=1764926784.239661412 30 ctime=1764935923.159576213 rsyslog-8.2512.0/runtime/strgen.c0000664000175000017500000001750715114522477015350 0ustar00rgerrger/* strgen.c * Module to handle string generators. These are C modules that receive * the message object and return a custom-built string. The primary purpose * for their existence is performance -- they do the same as template strings, but * potentially faster (if well implmented). * * Module begun 2010-06-01 by Rainer Gerhards * * Copyright 2010 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "msg.h" #include "obj.h" #include "errmsg.h" #include "strgen.h" #include "ruleset.h" #include "unicode-helper.h" #include "cfsysline.h" /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(ruleset) /* static data */ /* config data */ /* This is the list of all strgens known to us. * This is also used to unload all modules on shutdown. */ strgenList_t *pStrgenLstRoot = NULL; /* initialize (but NOT allocate) a strgen list. Primarily meant as a hook * which can be used to extend the list in the future. So far, just sets * it to NULL. */ static rsRetVal InitStrgenList(strgenList_t **pListRoot) { *pListRoot = NULL; return RS_RET_OK; } /* destruct a strgen list. The list elements are destroyed, but the strgen objects * themselves are not modified. (That is done at a late stage during rsyslogd * shutdown and need not be considered here.) */ static rsRetVal DestructStrgenList(strgenList_t **ppListRoot) { strgenList_t *pStrgenLst; strgenList_t *pStrgenLstDel; pStrgenLst = *ppListRoot; while (pStrgenLst != NULL) { pStrgenLstDel = pStrgenLst; pStrgenLst = pStrgenLst->pNext; free(pStrgenLstDel); } *ppListRoot = NULL; return RS_RET_OK; } /* Add a strgen to the list. We use a VERY simple and ineffcient algorithm, * but it is employed only for a few milliseconds during config processing. So * I prefer to keep it very simple and with simple data structures. Unfortunately, * we need to preserve the order, but I don't like to add a tail pointer as that * would require a container object. So I do the extra work to skip to the tail * when adding elements... */ static rsRetVal AddStrgenToList(strgenList_t **ppListRoot, strgen_t *pStrgen) { strgenList_t *pThis; strgenList_t *pTail; DEFiRet; CHKmalloc(pThis = malloc(sizeof(strgenList_t))); pThis->pStrgen = pStrgen; pThis->pNext = NULL; if (*ppListRoot == NULL) { pThis->pNext = *ppListRoot; *ppListRoot = pThis; } else { /* find tail first */ for (pTail = *ppListRoot; pTail->pNext != NULL; pTail = pTail->pNext) /* just search, do nothing else */ ; /* add at tail */ pTail->pNext = pThis; } finalize_it: RETiRet; } /* find a strgen based on the provided name */ static rsRetVal FindStrgen(strgen_t **ppStrgen, uchar *pName) { strgenList_t *pThis; DEFiRet; for (pThis = pStrgenLstRoot; pThis != NULL; pThis = pThis->pNext) { if (ustrcmp(pThis->pStrgen->pName, pName) == 0) { *ppStrgen = pThis->pStrgen; FINALIZE; /* found it, iRet still eq. OK! */ } } iRet = RS_RET_PARSER_NOT_FOUND; finalize_it: RETiRet; } /* --- END helper functions for strgen list handling --- */ BEGINobjConstruct(strgen) /* be sure to specify the object type also in END macro! */ ENDobjConstruct(strgen) /* ConstructionFinalizer. The most important chore is to add the strgen object * to our global list of available strgens. * rgerhards, 2009-11-03 */ static rsRetVal strgenConstructFinalize(strgen_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, strgen); CHKiRet(AddStrgenToList(&pStrgenLstRoot, pThis)); DBGPRINTF("Strgen '%s' added to list of available strgens.\n", pThis->pName); finalize_it: RETiRet; } PROTOTYPEobjDestruct(strgen); BEGINobjDestruct(strgen) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(strgen); dbgprintf("destructing strgen '%s'\n", pThis->pName); free(pThis->pName); ENDobjDestruct(strgen) /* set the strgen name - string is copied over, call can continue to use it, * but must free it if desired. */ static rsRetVal SetName(strgen_t *pThis, uchar *name) { DEFiRet; ISOBJ_TYPE_assert(pThis, strgen); assert(name != NULL); if (pThis->pName != NULL) { free(pThis->pName); pThis->pName = NULL; } CHKmalloc(pThis->pName = ustrdup(name)); finalize_it: RETiRet; } /* set a pointer to "our" module. Note that no module * pointer must already be set. */ static rsRetVal SetModPtr(strgen_t *pThis, modInfo_t *pMod) { ISOBJ_TYPE_assert(pThis, strgen); assert(pMod != NULL); assert(pThis->pModule == NULL); pThis->pModule = pMod; return RS_RET_OK; } /* queryInterface function-- rgerhards, 2009-11-03 */ BEGINobjQueryInterface(strgen) CODESTARTobjQueryInterface(strgen); if (pIf->ifVersion != strgenCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = strgenConstruct; pIf->ConstructFinalize = strgenConstructFinalize; pIf->Destruct = strgenDestruct; pIf->SetName = SetName; pIf->SetModPtr = SetModPtr; pIf->InitStrgenList = InitStrgenList; pIf->DestructStrgenList = DestructStrgenList; pIf->AddStrgenToList = AddStrgenToList; pIf->FindStrgen = FindStrgen; finalize_it: ENDobjQueryInterface(strgen) /* This destroys the master strgenlist and all of its strgen entries. MUST only be * done when the module is shut down. Strgen modules are NOT unloaded, rsyslog * does that at a later stage for all dynamically loaded modules. */ static void destroyMasterStrgenList(void) { strgenList_t *pStrgenLst; strgenList_t *pStrgenLstDel; pStrgenLst = pStrgenLstRoot; while (pStrgenLst != NULL) { strgenDestruct(&pStrgenLst->pStrgen); pStrgenLstDel = pStrgenLst; pStrgenLst = pStrgenLst->pNext; free(pStrgenLstDel); } } /* Exit our class. * rgerhards, 2009-11-04 */ BEGINObjClassExit(strgen, OBJ_IS_CORE_MODULE) /* class, version */ destroyMasterStrgenList(); objRelease(glbl, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDObjClassExit(strgen) /* Initialize the strgen class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2009-11-02 */ BEGINObjClassInit(strgen, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); InitStrgenList(&pStrgenLstRoot); ENDObjClassInit(strgen) rsyslog-8.2512.0/runtime/PaxHeaders/netstrms.h0000644000000000000000000000013215055605325016252 xustar0030 mtime=1756826325.649800683 30 atime=1764931008.708156258 30 ctime=1764935923.350579137 rsyslog-8.2512.0/runtime/netstrms.h0000664000175000017500000001124315055605325015717 0ustar00rgerrger/* Definitions for the stream-based netstrm sworking class. * * Copyright 2007-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_NETSTRMS_H #define INCLUDED_NETSTRMS_H #include "nsd.h" /* we need our driver interface to be defined */ /* the netstrms object */ struct netstrms_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ uchar *pBaseDrvrName; /**< nsd base driver name to use, or NULL if system default */ uchar *pDrvrName; /**< full base driver name (set when driver is loaded) */ int iDrvrMode; /**< current default driver mode */ uchar *pszDrvrAuthMode; /**< current driver authentication mode */ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */ int DrvrVerifyDepth; /**< Verify Depth for certificate chains */ uchar *pszDrvrPermitExpiredCerts; const uchar *pszDrvrCAFile; const uchar *pszDrvrCRLFile; const uchar *pszDrvrKeyFile; const uchar *pszDrvrCertFile; uchar *gnutlsPriorityString; /**< priorityString for connection */ int iSynBacklog; /**< socket layer syn backlog for listen() */ permittedPeers_t *pPermPeers; /**< current driver's permitted peers */ rsRetVal (*fLstnInitDrvr)(netstrm_t *); /**< "late" driver-specific lstn init function NULL if none */ nsd_if_t Drvr; /**< our stream driver */ }; /* interface */ BEGINinterface(netstrms) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(netstrms_t **ppThis); rsRetVal (*ConstructFinalize)(netstrms_t *pThis); rsRetVal (*Destruct)(netstrms_t **ppThis); rsRetVal (*CreateStrm)(netstrms_t *pThis, netstrm_t **ppStrm); rsRetVal (*SetDrvrName)(netstrms_t *pThis, uchar *pszName); rsRetVal (*SetDrvrMode)(netstrms_t *pThis, int iMode); rsRetVal (*SetDrvrAuthMode)(netstrms_t *pThis, uchar *); rsRetVal (*SetDrvrPermitExpiredCerts)(netstrms_t *pThis, uchar *); rsRetVal (*SetDrvrPermPeers)(netstrms_t *pThis, permittedPeers_t *); int (*GetDrvrMode)(netstrms_t *pThis); uchar *(*GetDrvrAuthMode)(netstrms_t *pThis); uchar *(*GetDrvrPermitExpiredCerts)(netstrms_t *pThis); permittedPeers_t *(*GetDrvrPermPeers)(netstrms_t *pThis); rsRetVal (*SetDrvrGnutlsPriorityString)(netstrms_t *pThis, uchar *); uchar *(*GetDrvrGnutlsPriorityString)(netstrms_t *pThis); rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis, int ChkExtendedKeyUsage); int (*GetDrvrCheckExtendedKeyUsage)(netstrms_t *pThis); rsRetVal (*SetDrvrPrioritizeSAN)(netstrms_t *pThis, int prioritizeSan); int (*GetDrvrPrioritizeSAN)(netstrms_t *pThis); rsRetVal (*SetDrvrTlsVerifyDepth)(netstrms_t *pThis, int verifyDepth); int (*GetDrvrTlsVerifyDepth)(netstrms_t *pThis); /* v2 */ rsRetVal (*SetDrvrTlsCAFile)(netstrms_t *pThis, const uchar *); const uchar *(*GetDrvrTlsCAFile)(netstrms_t *pThis); rsRetVal (*SetDrvrTlsKeyFile)(netstrms_t *pThis, const uchar *); const uchar *(*GetDrvrTlsKeyFile)(netstrms_t *pThis); rsRetVal (*SetDrvrTlsCertFile)(netstrms_t *pThis, const uchar *); const uchar *(*GetDrvrTlsCertFile)(netstrms_t *pThis); /* v3 */ rsRetVal (*SetDrvrTlsCRLFile)(netstrms_t *pThis, const uchar *); const uchar *(*GetDrvrTlsCRLFile)(netstrms_t *pThis); /* v4 */ rsRetVal (*SetSynBacklog)(netstrms_t *pThis, const int); ENDinterface(netstrms) #define netstrmsCURR_IF_VERSION 4 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(netstrms); /* the name of our library binary */ #define LM_NETSTRMS_FILENAME "lmnetstrms" #endif /* #ifndef INCLUDED_NETSTRMS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/tcps_sess.c0000644000000000000000000000013215071746523016400 xustar0030 mtime=1760021843.877421601 30 atime=1764931016.183280232 30 ctime=1764935923.405579979 rsyslog-8.2512.0/runtime/tcps_sess.c0000664000175000017500000006011615071746523016050 0ustar00rgerrger/* tcps_sess.c * * This implements a session of the tcpsrv object. For general * comments, see header of tcpsrv.c. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2008-03-01 by RGerhards (extracted from tcpsrv.c, which * based on the BSD-licensed syslogd.c) * * Copyright 2007-2025 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "dirty.h" #include "unicode-helper.h" #include "module-template.h" #include "net.h" #include "tcpsrv.h" #include "tcps_sess.h" #include "obj.h" #include "errmsg.h" #include "netstrm.h" #include "msg.h" #include "datetime.h" #include "prop.h" #include "ratelimit.h" #include "debug.h" #include "rsconf.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(netstrm) DEFobjCurrIf(prop) DEFobjCurrIf(datetime) /* forward definitions */ static rsRetVal Close(tcps_sess_t *pThis); /* Standard-Constructor */ BEGINobjConstruct(tcps_sess) /* be sure to specify the object type also in END macro! */ pThis->iMsg = 0; /* just make sure... */ pThis->iMaxLine = glbl.GetMaxLine(runConf); pThis->inputState = eAtStrtFram; /* indicate frame header expected */ pThis->eFraming = TCP_FRAMING_OCTET_STUFFING; /* just make sure... */ pthread_mutex_init(&pThis->mut, NULL); pThis->fromHost = NULL; pThis->fromHostIP = NULL; pThis->fromHostPort = NULL; pThis->tlsProbeBytes = 0; pThis->tlsProbeDone = 0; pThis->tlsMismatchWarned = 0; memset(pThis->tlsProbeBuf, 0, sizeof(pThis->tlsProbeBuf)); /* now allocate the message reception buffer */ CHKmalloc(pThis->pMsg = (uchar *)malloc(pThis->iMaxLine + 1)); finalize_it: ENDobjConstruct(tcps_sess) /* ConstructionFinalizer */ static rsRetVal tcps_sessConstructFinalize(tcps_sess_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->pSrv->OnSessConstructFinalize != NULL) { CHKiRet(pThis->pSrv->OnSessConstructFinalize(&pThis->pUsr)); } finalize_it: RETiRet; } /* destructor for the tcps_sess object */ BEGINobjDestruct(tcps_sess) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(tcps_sess); if (pThis->pStrm != NULL) netstrm.Destruct(&pThis->pStrm); if (pThis->pSrv->pOnSessDestruct != NULL) { pThis->pSrv->pOnSessDestruct(&pThis->pUsr); } pthread_mutex_destroy(&pThis->mut); /* now destruct our own properties */ if (pThis->fromHost != NULL) CHKiRet(prop.Destruct(&pThis->fromHost)); if (pThis->fromHostIP != NULL) CHKiRet(prop.Destruct(&pThis->fromHostIP)); if (pThis->fromHostPort != NULL) CHKiRet(prop.Destruct(&pThis->fromHostPort)); free(pThis->pMsg); ENDobjDestruct(tcps_sess) /* debugprint for the tcps_sess object */ BEGINobjDebugPrint(tcps_sess) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(tcps_sess); ENDobjDebugPrint(tcps_sess) /* set property functions */ /* set the hostname. Note that the caller *hands over* the string. That is, * the caller no longer controls it once SetHost() has received it. Most importantly, * the caller must not free it. -- rgerhards, 2008-04-24 */ static rsRetVal SetHost(tcps_sess_t *pThis, uchar *pszHost) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->fromHost == NULL) CHKiRet(prop.Construct(&pThis->fromHost)); CHKiRet(prop.SetString(pThis->fromHost, pszHost, ustrlen(pszHost))); finalize_it: free(pszHost); /* we must free according to our (old) calling conventions */ RETiRet; } /* set the remote host's IP. Note that the caller *hands over* the property. That is, * the caller no longer controls it once SetHostIP() has received it. Most importantly, * the caller must not destruct it. -- rgerhards, 2008-05-16 */ static rsRetVal SetHostIP(tcps_sess_t *pThis, prop_t *ip) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->fromHostIP != NULL) { prop.Destruct(&pThis->fromHostIP); } pThis->fromHostIP = ip; RETiRet; } static rsRetVal SetHostPort(tcps_sess_t *pThis, prop_t *port) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->fromHostPort != NULL) { prop.Destruct(&pThis->fromHostPort); } pThis->fromHostPort = port; RETiRet; } static rsRetVal SetStrm(tcps_sess_t *pThis, netstrm_t *pStrm) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); pThis->pStrm = pStrm; RETiRet; } static inline int isLikelyTlsClientHello(const uchar buf[5]) { if (buf[0] != 0x16) return 0; /* handshake record */ if (buf[1] != 0x03) return 0; /* TLS major version */ if (buf[2] > 0x04) return 0; /* accept TLS 1.0 - 1.3 */ const unsigned recordLen = ((unsigned)buf[3] << 8) | buf[4]; if (recordLen < 40 || recordLen > 16384) return 0; /* sanity */ return 1; } static ATTR_NONNULL() rsRetVal maybeDetectTlsClientHello(tcps_sess_t *pThis, const char *data, size_t len) { DEFiRet; if (pThis->tlsProbeDone) FINALIZE; if (pThis->pSrv->pszOrigin == NULL || strcmp((const char *)pThis->pSrv->pszOrigin, "imtcp") != 0) { pThis->tlsProbeDone = 1; FINALIZE; } if (pThis->pSrv->iDrvrMode != 0) { pThis->tlsProbeDone = 1; FINALIZE; } while (len > 0 && pThis->tlsProbeBytes < sizeof(pThis->tlsProbeBuf)) { pThis->tlsProbeBuf[pThis->tlsProbeBytes++] = (uchar)*data++; --len; } if (pThis->tlsProbeBytes >= sizeof(pThis->tlsProbeBuf)) { if (!pThis->tlsMismatchWarned && isLikelyTlsClientHello(pThis->tlsProbeBuf)) { const char *const host = propGetSzStrOrDefault(pThis->fromHost, "(host unknown)"); const char *const ip = propGetSzStrOrDefault(pThis->fromHostIP, "(IP unknown)"); const char *const port = propGetSzStrOrDefault(pThis->fromHostPort, "(port unknown)"); LogError(0, RS_RET_SERVER_NO_TLS, "imtcp: TLS handshake detected from %s (%s:%s) but listener is not TLS-enabled. " "Enable TLS on this listener or disable TLS on the client. " "See https://www.rsyslog.com/doc/faq/imtcp-tls-gibberish.html for troubleshooting.", host, ip, port); pThis->tlsMismatchWarned = 1; ABORT_FINALIZE(RS_RET_SERVER_NO_TLS); } pThis->tlsProbeDone = 1; } finalize_it: RETiRet; } static rsRetVal SetMsgIdx(tcps_sess_t *pThis, int idx) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); pThis->iMsg = idx; RETiRet; } /* set our parent, the tcpsrv object */ static rsRetVal SetTcpsrv(tcps_sess_t *pThis, tcpsrv_t *pSrv) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); ISOBJ_TYPE_assert(pSrv, tcpsrv); pThis->pSrv = pSrv; RETiRet; } /* set our parent listener info*/ static rsRetVal SetLstnInfo(tcps_sess_t *pThis, tcpLstnPortList_t *pLstnInfo) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); assert(pLstnInfo != NULL); pThis->pLstnInfo = pLstnInfo; /* set cached elements */ pThis->bSuppOctetFram = pLstnInfo->cnf_params->bSuppOctetFram; pThis->bSPFramingFix = pLstnInfo->cnf_params->bSPFramingFix; RETiRet; } static rsRetVal SetUsrP(tcps_sess_t *pThis, void *pUsr) { DEFiRet; pThis->pUsr = pUsr; RETiRet; } static rsRetVal SetOnMsgReceive(tcps_sess_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t *, uchar *, int)) { DEFiRet; pThis->DoSubmitMessage = OnMsgReceive; RETiRet; } /* This is a helper for submitting the message to the rsyslog core. * It does some common processing, including resetting the various * state variables to a "processed" state. * Note that this function is also called if we had a buffer overflow * due to a too-long message. So far, there is no indication this * happened and it may be worth thinking about different handling * of this case (what obviously would require a change to this * function or some related code). * rgerhards, 2009-04-23 */ static rsRetVal defaultDoSubmitMessage(tcps_sess_t *pThis, struct syslogTime *stTime, time_t ttGenTime, multi_submit_t *pMultiSub) { smsg_t *pMsg; DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); const tcpLstnParams_t *const cnf_params = pThis->pLstnInfo->cnf_params; if (pThis->iMsg == 0) { DBGPRINTF("discarding zero-sized message\n"); FINALIZE; } if (pThis->DoSubmitMessage != NULL) { pThis->DoSubmitMessage(pThis, pThis->pMsg, pThis->iMsg); FINALIZE; } /* we now create our own message object and submit it to the queue */ CHKiRet(msgConstructWithTime(&pMsg, stTime, ttGenTime)); MsgSetRawMsg(pMsg, (char *)pThis->pMsg, pThis->iMsg); MsgSetInputName(pMsg, cnf_params->pInputName); if (cnf_params->dfltTZ[0] != '\0') MsgSetDfltTZ(pMsg, (char *)cnf_params->dfltTZ); MsgSetFlowControlType(pMsg, pThis->pSrv->bUseFlowControl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; MsgSetRcvFrom(pMsg, pThis->fromHost); CHKiRet(MsgSetRcvFromIP(pMsg, pThis->fromHostIP)); CHKiRet(MsgSetRcvFromPort(pMsg, pThis->fromHostPort)); MsgSetRuleset(pMsg, cnf_params->pRuleset); STATSCOUNTER_INC(pThis->pLstnInfo->ctrSubmit, pThis->pLstnInfo->mutCtrSubmit); ratelimitAddMsg(pThis->pLstnInfo->ratelimiter, pMultiSub, pMsg); finalize_it: /* reset status variables */ pThis->iMsg = 0; RETiRet; } /* This should be called before a normal (non forced) close * of a TCP session. This function checks if there is any unprocessed * message left in the TCP stream. Such a message is probably a * fragement. If evrything goes well, we must be right at the * beginnig of a new frame without any data received from it. If * not, there is some kind of a framing error. I think I remember that * some legacy syslog/TCP implementations have non-LF terminated * messages at the end of the stream. For now, we allow this behaviour. * Later, it should probably become a configuration option. * rgerhards, 2006-12-07 */ static rsRetVal PrepareClose(tcps_sess_t *pThis) { struct syslogTime stTime; time_t ttGenTime; DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->inputState == eAtStrtFram) { /* this is how it should be. There is no unprocessed * data left and such we have nothing to do. For simplicity * reasons, we immediately return in that case. */ FINALIZE; } /* we have some data left! */ if (pThis->eFraming == TCP_FRAMING_OCTET_COUNTING) { /* In this case, we have an invalid frame count and thus * generate an error message and discard the frame. */ LogError(0, NO_ERRCODE, "Incomplete frame at end of stream in session %p - " "ignoring extra data (a message may be lost).", pThis->pStrm); /* nothing more to do */ } else { /* here, we have traditional framing. Missing LF at the end * of message may occur. As such, we process the message in * this case. */ DBGPRINTF("Extra data at end of stream in legacy syslog/tcp message - processing\n"); datetime.getCurrTime(&stTime, &ttGenTime, TIME_IN_LOCALTIME); defaultDoSubmitMessage(pThis, &stTime, ttGenTime, NULL); } finalize_it: RETiRet; } /* Closes a TCP session * No attention is paid to the return code * of close, so potential-double closes are not detected. */ static rsRetVal Close(tcps_sess_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); netstrm.Destruct(&pThis->pStrm); if (pThis->fromHost != NULL) { prop.Destruct(&pThis->fromHost); } if (pThis->fromHostIP != NULL) prop.Destruct(&pThis->fromHostIP); RETiRet; } /* process the data received. As TCP is stream based, we need to process the * data inside a state machine. The actual data received is passed in byte-by-byte * from DataRcvd, and this function here compiles messages from them and submits * the end result to the queue. Introducing this function fixes a long-term bug ;) * rgerhards, 2008-03-14 */ static rsRetVal ATTR_NONNULL(1) processDataRcvd(tcps_sess_t *pThis, const char c, struct syslogTime *stTime, const time_t ttGenTime, multi_submit_t *pMultiSub, unsigned *const __restrict__ pnMsgs) { DEFiRet; const tcpLstnParams_t *const cnf_params = pThis->pLstnInfo->cnf_params; ISOBJ_TYPE_assert(pThis, tcps_sess); if (pThis->inputState == eAtStrtFram) { if (c >= '0' && c <= '9' && pThis->bSuppOctetFram) { pThis->inputState = eInOctetCnt; pThis->iOctetsRemain = 0; pThis->eFraming = TCP_FRAMING_OCTET_COUNTING; } else if (c == ' ' && pThis->bSPFramingFix) { /* Cisco ASA very occasionally sends a SP after a LF, which * thrashes framing if not taken special care of. Here, * we permit space *in front of the next frame* and * ignore it. */ FINALIZE; } else { pThis->inputState = eInMsg; pThis->eFraming = TCP_FRAMING_OCTET_STUFFING; } } if (pThis->inputState == eInMsg) { #if 0 // set to 1 for ultra-verbose DBGPRINTF("DEBUG: processDataRcvd c=%c remain=%d\n", c, pThis->iOctetsRemain); #endif if ((((c == '\n') && !pThis->pSrv->bDisableLFDelim) || ((pThis->pSrv->addtlFrameDelim != TCPSRV_NO_ADDTL_DELIMITER) && (c == pThis->pSrv->addtlFrameDelim))) && pThis->eFraming == TCP_FRAMING_OCTET_STUFFING) { /* record delimiter? */ defaultDoSubmitMessage(pThis, stTime, ttGenTime, pMultiSub); ++(*pnMsgs); pThis->inputState = eAtStrtFram; } else { /* IMPORTANT: here we copy the actual frame content to the message - for BOTH framing modes! * If we have a message that is larger than the max msg size, we truncate it. This is the best * we can do in light of what the engine supports. -- rgerhards, 2008-03-14 */ if (pThis->iMsg < pThis->iMaxLine) { *(pThis->pMsg + pThis->iMsg++) = c; } else { /* emergency, we now need to flush, no matter if we are at end of message or not... */ DBGPRINTF("error: message received is larger than max msg size, we %s it - c=%x\n", pThis->pSrv->discardTruncatedMsg == 1 ? "truncate" : "split", c); defaultDoSubmitMessage(pThis, stTime, ttGenTime, pMultiSub); ++(*pnMsgs); if (pThis->pSrv->discardTruncatedMsg == 1) { if (pThis->eFraming == TCP_FRAMING_OCTET_COUNTING) { pThis->iOctetsRemain--; if (pThis->iOctetsRemain == 0) { pThis->inputState = eAtStrtFram; FINALIZE; } } pThis->inputState = eInMsgTruncating; FINALIZE; } } } if (pThis->eFraming == TCP_FRAMING_OCTET_COUNTING) { /* do we need to find end-of-frame via octet counting? */ pThis->iOctetsRemain--; if (pThis->iOctetsRemain < 1) { /* we have end of frame! */ defaultDoSubmitMessage(pThis, stTime, ttGenTime, pMultiSub); ++(*pnMsgs); pThis->inputState = eAtStrtFram; } } } else if (pThis->inputState == eInMsgTruncating) { if (pThis->eFraming == TCP_FRAMING_OCTET_COUNTING) { DBGPRINTF("DEBUG: TCP_FRAMING_OCTET_COUNTING eInMsgTruncating c=%c remain=%d\n", c, pThis->iOctetsRemain); pThis->iOctetsRemain--; if (pThis->iOctetsRemain < 1) { pThis->inputState = eAtStrtFram; } } else { if (((c == '\n') && !pThis->pSrv->bDisableLFDelim) || ((pThis->pSrv->addtlFrameDelim != TCPSRV_NO_ADDTL_DELIMITER) && (c == pThis->pSrv->addtlFrameDelim))) { pThis->inputState = eAtStrtFram; } } } else { assert(pThis->inputState == eInOctetCnt); if (c >= '0' && c <= '9') { /* isdigit() the faster way */ if (pThis->iOctetsRemain <= 200000000) { pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0'; } if (pThis->iMsg < pThis->iMaxLine) { *(pThis->pMsg + pThis->iMsg++) = c; } } else { /* done with the octet count, so this must be the SP terminator */ DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain); const char *const peerName = propGetSzStrOrDefault(pThis->fromHost, "(hostname unknown)"); const char *const peerIP = propGetSzStrOrDefault(pThis->fromHostIP, "(IP unknown)"); const char *const peerPort = propGetSzStrOrDefault(pThis->fromHostPort, "(port unknown)"); if (c != ' ') { LogError(0, NO_ERRCODE, "imtcp %s: Framing Error in received TCP message from " "peer: (hostname) %s, (ip) %s, (port) %s: delimiter is not SP but has " "ASCII value %d.", cnf_params->pszInputName, peerName, peerIP, peerPort, c); } if (pThis->iOctetsRemain < 1) { /* TODO: handle the case where the octet count is 0! */ LogError(0, NO_ERRCODE, "imtcp %s: Framing Error in received TCP message from " "peer: (hostname) %s, (ip) %s, (port) %s: invalid octet count %d.", cnf_params->pszInputName, peerName, peerIP, peerPort, pThis->iOctetsRemain); pThis->eFraming = TCP_FRAMING_OCTET_STUFFING; } else if (pThis->iOctetsRemain > pThis->iMaxLine) { /* while we can not do anything against it, we can at least log an indication * that something went wrong) -- rgerhards, 2008-03-14 */ LogError(0, NO_ERRCODE, "imtcp %s: received oversize message from peer: " "(hostname) %s, (ip) %s, (port) %s: size is %d bytes, max msg size " "is %d, truncating...", cnf_params->pszInputName, peerName, peerIP, peerPort, pThis->iOctetsRemain, pThis->iMaxLine); } if (pThis->iOctetsRemain > pThis->pSrv->maxFrameSize) { LogError(0, NO_ERRCODE, "imtcp %s: Framing Error in received TCP message from " "peer: (hostname) %s, (ip) %s, (port) %s: frame too large: %d, change " "to octet stuffing", cnf_params->pszInputName, peerName, peerIP, peerPort, pThis->iOctetsRemain); pThis->eFraming = TCP_FRAMING_OCTET_STUFFING; } else { pThis->iMsg = 0; } pThis->inputState = eInMsg; } } finalize_it: RETiRet; } /* Processes the data received via a TCP session. If there * is no other way to handle it, data is discarded. * Input parameter data is the data received, iLen is its * len as returned from recv(). iLen must be 1 or more (that * is errors must be handled by caller!). iTCPSess must be * the index of the TCP session that received the data. * rgerhards 2005-07-04 * And another change while generalizing. We now return either * RS_RET_OK, which means the session should be kept open * or anything else, which means it must be closed. * rgerhards, 2008-03-01 * As a performance optimization, we pick up the timestamp here. Acutally, * this *is* the *correct* reception step for all the data we received, because * we have just received a bunch of data! -- rgerhards, 2009-06-16 */ #define NUM_MULTISUB 1024 static rsRetVal DataRcvd(tcps_sess_t *pThis, char *pData, const size_t iLen) { multi_submit_t multiSub; smsg_t *pMsgs[NUM_MULTISUB]; struct syslogTime stTime; time_t ttGenTime; char *pEnd; unsigned nMsgs = 0; DEFiRet; ISOBJ_TYPE_assert(pThis, tcps_sess); assert(pData != NULL); assert(iLen > 0); CHKiRet(maybeDetectTlsClientHello(pThis, pData, iLen)); datetime.getCurrTime(&stTime, &ttGenTime, TIME_IN_LOCALTIME); multiSub.ppMsgs = pMsgs; multiSub.maxElem = NUM_MULTISUB; multiSub.nElem = 0; /* We now copy the message to the session buffer. */ pEnd = pData + iLen; /* this is one off, which is intensional */ while (pData < pEnd) { CHKiRet(processDataRcvd(pThis, *pData++, &stTime, ttGenTime, &multiSub, &nMsgs)); } iRet = multiSubmitFlush(&multiSub); if (runConf->globals.senderKeepTrack) statsRecordSender(propGetSzStr(pThis->fromHost), nMsgs, ttGenTime); finalize_it: RETiRet; } #undef NUM_MULTISUB /* queryInterface function * rgerhards, 2008-02-29 */ BEGINobjQueryInterface(tcps_sess) CODESTARTobjQueryInterface(tcps_sess); if (pIf->ifVersion != tcps_sessCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->DebugPrint = tcps_sessDebugPrint; pIf->Construct = tcps_sessConstruct; pIf->ConstructFinalize = tcps_sessConstructFinalize; pIf->Destruct = tcps_sessDestruct; pIf->PrepareClose = PrepareClose; pIf->Close = Close; pIf->DataRcvd = DataRcvd; pIf->SetUsrP = SetUsrP; pIf->SetTcpsrv = SetTcpsrv; pIf->SetLstnInfo = SetLstnInfo; pIf->SetHost = SetHost; pIf->SetHostIP = SetHostIP; pIf->SetHostPort = SetHostPort; pIf->SetStrm = SetStrm; pIf->SetMsgIdx = SetMsgIdx; pIf->SetOnMsgReceive = SetOnMsgReceive; finalize_it: ENDobjQueryInterface(tcps_sess) /* exit our class * rgerhards, 2008-03-10 */ BEGINObjClassExit(tcps_sess, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(tcps_sess); /* release objects we no longer need */ objRelease(netstrm, LM_NETSTRMS_FILENAME); objRelease(datetime, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); ENDObjClassExit(tcps_sess) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-29 */ BEGINObjClassInit(tcps_sess, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */ /* request objects we use */ CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); objRelease(glbl, CORE_COMPONENT); /* set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, tcps_sessDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, tcps_sessConstructFinalize); ENDObjClassInit(tcps_sess) /* vim:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/net.h0000644000000000000000000000013215071746523015165 xustar0030 mtime=1760021843.866421427 30 atime=1764930980.499686234 30 ctime=1764935923.340578984 rsyslog-8.2512.0/runtime/net.h0000664000175000017500000002445015071746523014636 0ustar00rgerrger/* Definitions for network-related stuff. * * Copyright 2007-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_NET_H #define INCLUDED_NET_H #include #include #include /* this is needed on HP UX -- rgerhards, 2008-03-04 */ #include "netns_socket.h" typedef enum _TCPFRAMINGMODE { TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */ TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */ } TCPFRAMINGMODE; #define F_SET(where, flag) ((where) |= (flag)) #define F_ISSET(where, flag) (((where) & (flag)) == (flag)) #define F_UNSET(where, flag) ((where) &= ~(flag)) #define ADDR_NAME 0x01 /* address is hostname wildcard) */ #define ADDR_PRI6 0x02 /* use IPv6 address prior to IPv4 when resolving */ /* portability: incase IP_FREEBIND is not defined */ #ifndef IP_FREEBIND #define IP_FREEBIND 0 #endif /* defines for IP_FREEBIND, currently being used in imudp */ #define IPFREEBIND_DISABLED 0x00 /* don't enable IP_FREEBIND in sock option */ #define IPFREEBIND_ENABLED_NO_LOG 0x01 /* enable IP_FREEBIND but no warn on success */ #define IPFREEBIND_ENABLED_WITH_LOG 0x02 /* enable IP_FREEBIND and warn on success */ #ifdef OS_BSD #ifndef _KERNEL #define s6_addr32 __u6_addr.__u6_addr32 #endif #endif struct NetAddr { uint8_t flags; union { struct sockaddr *NetAddr; char *HostWildcard; } addr; }; #ifndef SO_BSDCOMPAT /* this shall prevent compiler errors due to undefined name */ #define SO_BSDCOMPAT 0 #endif /* IPv6 compatibility layer for older platforms * We need to handle a few things different if we are running * on an older platform which does not support all the glory * of IPv6. We try to limit toll on features and reliability, * but obviously it is better to run rsyslog on a platform that * supports everything... * rgerhards, 2007-06-22 */ #ifndef AI_NUMERICSERV #define AI_NUMERICSERV 0 #endif #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN #define SALEN(sa) ((sa)->sa_len) #else static inline size_t __attribute__((unused)) SALEN(struct sockaddr *sa) { switch (sa->sa_family) { case AF_INET: return (sizeof(struct sockaddr_in)); case AF_INET6: return (sizeof(struct sockaddr_in6)); default: return 0; } } #endif struct AllowedSenders { struct NetAddr allowedSender; /* ip address allowed */ uint8_t SignificantBits; /* defines how many bits should be discarded (eqiv to mask) */ struct AllowedSenders *pNext; }; /* this structure is a helper to implement wildcards in permittedPeers_t. It specifies * the domain component and the matching mode. * rgerhards, 2008-05-27 */ struct permittedPeerWildcard_s { uchar *pszDomainPart; size_t lenDomainPart; enum { PEER_WILDCARD_NONE = 0, /**< no wildcard in this entry */ PEER_WILDCARD_AT_START = 1, /**< wildcard at start of entry (*name) */ PEER_WILDCARD_AT_END = 2, /**< wildcard at end of entry (name*) */ PEER_WILDCARD_MATCH_ALL = 3, /**< only * wildcard, matches all values */ PEER_WILDCARD_EMPTY_COMPONENT = 4 /**< special case: domain component empty (e.g. "..") */ } wildcardType; permittedPeerWildcard_t *pNext; }; /* for fingerprints and hostnames, we need to have a temporary linked list of * permitted values. Unforutnately, we must also duplicate this in the netstream * drivers. However, this is the best interim solution (with the least effort). * A clean implementation requires that we have more capable variables and the * full-fledged scripting engine available. So we have opted to do the interim * solution so that our users can begin to enjoy authenticated TLS. The next step * (hopefully) is to enhance RainerScript. -- rgerhards, 2008-05-19 */ struct permittedPeers_s { uchar *pszID; enum { PERM_PEER_TYPE_UNDECIDED = 0, /**< we have not yet decided the type (fine in some auth modes) */ PERM_PEER_TYPE_PLAIN = 1, /**< just plain text contained */ PERM_PEER_TYPE_WILDCARD = 2, /**< wildcards are contained, wildcard struture is filled */ } etryType; permittedPeers_t *pNext; permittedPeerWildcard_t *pWildcardRoot; /**< root of the wildcard, NULL if not initialized */ permittedPeerWildcard_t *pWildcardLast; /**< end of the wildcard list, NULL if not initialized */ }; /* interfaces */ BEGINinterface(net) /* name must also be changed in ENDinterface macro! */ rsRetVal (*cvthname)(struct sockaddr_storage *f, prop_t **localName, prop_t **fqdn, prop_t **ip); /* things to go away after proper modularization */ rsRetVal (*addAllowedSenderLine)(char *pName, uchar **ppRestOfConfLine); void (*PrintAllowedSenders)(int iListToPrint); void (*clearAllowedSenders)(uchar *); void (*debugListenInfo)(int fd, char *type); int *(*create_udp_socket)(uchar *hostname, uchar *LogPort, int bIsServer, int rcvbuf, int sndbuf, int ipfreebind, char *device); void (*closeUDPListenSockets)(int *finet); int (*isAllowedSender)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost); /* deprecated! */ rsRetVal (*getLocalHostname)(rsconf_t *const, uchar **); int (*should_use_so_bsdcompat)(void); /* permitted peer handling should be replaced by something better (see comments above) */ rsRetVal (*AddPermittedPeer)(permittedPeers_t **ppRootPeer, uchar *pszID); rsRetVal (*DestructPermittedPeers)(permittedPeers_t **ppRootPeer); rsRetVal (*PermittedPeerWildcardMatch)(permittedPeers_t *pPeer, const uchar *pszNameToMatch, int *pbIsMatching); /* v5 interface additions */ int (*CmpHost)(struct sockaddr_storage *, struct sockaddr_storage *, size_t); /* v6 interface additions - 2009-11-16 */ rsRetVal (*HasRestrictions)(uchar *, int *bHasRestrictions); int (*isAllowedSender2)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS); /* v7 interface additions - 2012-03-06 */ rsRetVal (*GetIFIPAddr)(uchar *szif, int family, uchar *pszbuf, int lenBuf); /* v8 cvthname() signature change -- rgerhards, 2013-01-18 */ /* v9 create_udp_socket() signature change -- dsahern, 2016-11-11 */ /* v10 moved data members to rsconf_t -- alakatos, 2021-12-29 */ /* v11 netns functions -- balsup, 2025-09-11 */ /* * @brief Open a socket on the given namespace * @param fdp A place to store the descriptor. This must not be NULL. * A failure will store -1 here. * @param domain The communication domain argument to the underlying socket call * @param type The type argument to the underlying socket call * @param protocol The protocol argument to the underlying socket call * @param ns The desired namespace. This may be NULL or the empty string if * the current namespace is desired. * @return RS_RET_OK on success, otherwise a failure code. * @details This is a wrapper to socket, allowing one to open a socket in * a given namespace. For platforms that do not support network * namespaces, an error will be returned if the ns parameter * is not NULL or the empty string. */ rsRetVal (*netns_socket)(int *fdp, int domain, int type, int protocol, const char *ns); /* * @brief Switch to the given network namespace * @param ns The desired namespace. If this is NULL or the empty string, then * this function is a no-op. * @return RS_RET_OK on success, otherwise a failure code. * @details For platforms that do not support network namespaces, an error will * be returned if the ns parameter is not NULL or the empty string. */ rsRetVal (*netns_switch)(const char *ns); /* * @brief Save a descriptor to the current network namespace * @param fd The location to store the descriptor for the current * namespace. This must not not be NULL, and the * descriptor must be pre-initialized to -1, i.e. *fd == -1 * is a precondition. This style is to prevent inadvertent * descriptor leaks that might arise by overwriting a valid * descriptor. * @return RS_RET_OK on success, otherwise a failure code. * @details For platforms that do not support network namespaces, this * function is a no-op and will always return RS_RET_OK. */ rsRetVal (*netns_save)(int *fd); /* * @brief Restore the original network namespace * @param fd A pointer to a descriptor associated with the original * namespace. This must not not be NULL. If the descriptor * is -1, then this function is a no-op. A valid descriptor * is always closed as a side-effect of this function, * with the descriptor being updated to -1. * @return RS_RET_OK on success, otherwise a failure code. * @details For platforms that do not support network namespaces, this * function cannot change the network namespace. However, if * presented with an fd that is not -1, it will still close * that fd and reset the value to -1. */ rsRetVal (*netns_restore)(int *fd); ENDinterface(net) #define netCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(net); /* the name of our library binary */ #define LM_NET_FILENAME "lmnet" #endif /* #ifndef INCLUDED_NET_H */ rsyslog-8.2512.0/runtime/PaxHeaders/obj.c0000644000000000000000000000013115060224612015127 xustar0029 mtime=1757489546.16638391 30 atime=1764930989.355834177 30 ctime=1764935923.205576917 rsyslog-8.2512.0/runtime/obj.c0000664000175000017500000012506515060224612014605 0ustar00rgerrger/* obj.c * * This file implements a generic object "class". All other classes can * use the service of this base class here to include auto-destruction and * other capabilities in a generic manner. * * As of 2008-02-29, I (rgerhards) am adding support for dynamically loadable * objects. In essence, each object will soon be available via its interface, * only. Before any object's code is accessed (including global static methods), * the caller needs to obtain an object interface. To do so, it needs to provide * the object name and the file where the object is expected to reside in. A * file may not be given, in which case the object is expected to reside in * the rsyslog core. The caller than receives an interface pointer which can * be utilized to access all the object's methods. This method enables rsyslog * to load library modules on demand. In order to keep overhead low, callers * should request object interface only once in the object Init function and * free them when they exit. The only exception is when a caller needs to * access an object only conditional, in which case a pointer to its interface * shall be acquired as need first arises but still be released only on exit * or when there definitely is no further need. The whole idea is to limit * the very performance-intense act of dynamically loading an objects library. * Of course, it is possible to violate this suggestion, but than you should * have very good reasoning to do so. * * Please note that there is one trick we need to do. Each object queries * the object interfaces and it does so via objUse(). objUse, however, is * part of the obj object's interface (implemented via the file you are * just reading). So in order to obtain a pointer to objUse, we need to * call it - obviously not possible. One solution would be that objUse is * hardcoded into all callers. That, however, would bring us into slight * trouble with actually dynamically loaded modules, as we should NOT * rely on the OS loader to resolve symbols back to the caller (this * is a feature not universally available and highly importable). Of course, * we can solve this with a pHostQueryEtryPoint() call. It still sounds * somewhat unnatural to call a regular interface function via a special * method. So what we do instead is define a special function called * objGetObjInterface() which delivers our own interface. That function * than will be defined global and be queriable via pHostQueryEtryPoint(). * I agree, technically this is much the same, but from an architecture * point of view it looks cleaner (at least to me). * * Please note that there is another egg-hen problem: we use a linked list, * which is provided by the linkedList object. However, we need to * initialize the linked list before we can provide the UseObj() * functionality. That, in turn, would probably be required by the * linkedList object. So the solution is to use a backdoor just to * init the linked list and from then on use the usual interfaces. * * File begun on 2008-01-04 by RGerhards * * Copyright 2008-2024 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #define DEV_DEBUG 0 /* set to 1 to enable very verbose developer debugging messages */ /* how many objects are supported by rsyslogd? */ #define OBJ_NUM_IDS 100 #include "rsyslog.h" #include "syslogd-types.h" #include "srUtils.h" #include "obj.h" #include "stream.h" #include "modules.h" #include "errmsg.h" #include "cfsysline.h" #include "unicode-helper.h" #include "datetime.h" /* static data */ DEFobjCurrIf(obj) /* we define our own interface, as this is expected by some macros! */ DEFobjCurrIf(var) DEFobjCurrIf(module) DEFobjCurrIf(strm) static objInfo_t *arrObjInfo[OBJ_NUM_IDS]; /* array with object information pointers */ pthread_mutex_t mutObjGlobalOp; /* mutex to guard global operations of the object system */ /* cookies for serialized lines */ #define COOKIE_OBJLINE '<' #define COOKIE_PROPLINE '+' #define COOKIE_ENDLINE '>' #define COOKIE_BLANKLINE '.' /* forward definitions */ static rsRetVal FindObjInfo(const char *szObjName, objInfo_t **ppInfo); /* methods */ /* This is a dummy method to be used when a standard method has not been * implemented by an object. Having it allows us to simply call via the * jump table without any NULL pointer checks - which gains quite * some performance. -- rgerhards, 2008-01-04 */ static rsRetVal objInfoNotImplementedDummy(void __attribute__((unused)) * pThis) { return RS_RET_NOT_IMPLEMENTED; } /* and now the macro to check if something is not implemented * must be provided an objInfo_t pointer. */ #define objInfoIsImplemented(pThis, method) \ (pThis->objMethods[method] != (rsRetVal(*)(void *, ...))objInfoNotImplementedDummy) /* construct an object Info object. Each class shall do this on init. The * resulting object shall be cached during the lifetime of the class and each * object shall receive a reference. A constructor and destructor MUST be provided for all * objects, thus they are in the parameter list. * pszID is the identifying object name and must point to constant pool memory. It is never freed. */ static rsRetVal InfoConstruct(objInfo_t **ppThis, uchar *pszID, int iObjVers, rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *), rsRetVal (*pQueryIF)(interface_t *), modInfo_t *pModInfo) { DEFiRet; int i; objInfo_t *pThis; assert(ppThis != NULL); if ((pThis = calloc(1, sizeof(objInfo_t))) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pThis->pszID = pszID; pThis->lenID = ustrlen(pszID); pThis->pszName = ustrdup(pszID); /* it's OK if we have NULL ptr, GetName() will deal with that! */ pThis->iObjVers = iObjVers; pThis->QueryIF = pQueryIF; pThis->pModInfo = pModInfo; pThis->objMethods[0] = (rsRetVal(*)(void *, ...))pConstruct; pThis->objMethods[1] = (rsRetVal(*)(void *, ...))pDestruct; for (i = 2; i < OBJ_NUM_METHODS; ++i) { pThis->objMethods[i] = (rsRetVal(*)(void *, ...))objInfoNotImplementedDummy; } *ppThis = pThis; finalize_it: RETiRet; } /* destruct the objInfo object - must be done only when no more instances exist. * rgerhards, 2008-03-10 */ static rsRetVal InfoDestruct(objInfo_t **ppThis) { DEFiRet; objInfo_t *pThis; assert(ppThis != NULL); pThis = *ppThis; assert(pThis != NULL); free(pThis->pszName); free(pThis); *ppThis = NULL; RETiRet; } /* set a method handler */ static rsRetVal InfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void *)) { pThis->objMethods[objMethod] = (rsRetVal(*)(void *, ...))pHandler; return RS_RET_OK; } /* destruct the base object properties. * rgerhards, 2008-01-29 */ static rsRetVal DestructObjSelf(obj_t *pThis) { DEFiRet; ISOBJ_assert(pThis); free(pThis->pszName); RETiRet; } /* --------------- object serializiation / deserialization support --------------- */ /* serialize the header of an object * pszRecType must be either "Obj" (Object) or "OPB" (Object Property Bag) */ static rsRetVal objSerializeHeader(strm_t *pStrm, obj_t *pObj, uchar *pszRecType) { DEFiRet; ISOBJ_TYPE_assert(pStrm, strm); ISOBJ_assert(pObj); assert(!strcmp((char *)pszRecType, "Obj") || !strcmp((char *)pszRecType, "OPB")); /* object cookie and serializer version (so far always 1) */ CHKiRet(strm.WriteChar(pStrm, COOKIE_OBJLINE)); CHKiRet(strm.Write(pStrm, (uchar *)pszRecType, 3)); /* record types are always 3 octets */ CHKiRet(strm.WriteChar(pStrm, ':')); CHKiRet(strm.WriteChar(pStrm, '1')); /* object type, version and string length */ CHKiRet(strm.WriteChar(pStrm, ':')); CHKiRet(strm.Write(pStrm, pObj->pObjInfo->pszID, pObj->pObjInfo->lenID)); CHKiRet(strm.WriteChar(pStrm, ':')); CHKiRet(strm.WriteLong(pStrm, objGetVersion(pObj))); /* record trailer */ CHKiRet(strm.WriteChar(pStrm, ':')); CHKiRet(strm.WriteChar(pStrm, '\n')); finalize_it: RETiRet; } /* begin serialization of an object * rgerhards, 2008-01-06 */ static rsRetVal BeginSerialize(strm_t *pStrm, obj_t *pObj) { DEFiRet; ISOBJ_TYPE_assert(pStrm, strm); ISOBJ_assert(pObj); CHKiRet(strm.RecordBegin(pStrm)); CHKiRet(objSerializeHeader(pStrm, pObj, (uchar *)"Obj")); finalize_it: RETiRet; } /* begin serialization of an object's property bag * Note: a property bag is used to serialize some of an objects * properties, but not necessarily all. A good example is the queue * object, which at some stage needs to serialize a number of its * properties, but not the queue data itself. From the object point * of view, a property bag can not be used to re-instantiate an object. * Otherwise, the serialization is exactly the same. * rgerhards, 2008-01-11 */ static rsRetVal BeginSerializePropBag(strm_t *pStrm, obj_t *pObj) { DEFiRet; ISOBJ_TYPE_assert(pStrm, strm); ISOBJ_assert(pObj); CHKiRet(strm.RecordBegin(pStrm)); CHKiRet(objSerializeHeader(pStrm, pObj, (uchar *)"OPB")); finalize_it: RETiRet; } /* append a property */ static rsRetVal SerializeProp(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr) { DEFiRet; uchar *pszBuf = NULL; size_t lenBuf = 0; uchar szBuf[64]; varType_t vType = VARTYPE_NONE; ISOBJ_TYPE_assert(pStrm, strm); assert(pszPropName != NULL); /*dbgprintf("objSerializeProp: strm %p, propName '%s', type %d, pUsr %p\n", pStrm, pszPropName, propType, pUsr);*/ /* if we have no user pointer, there is no need to write this property. * TODO: think if that's the righ point of view * rgerhards, 2008-01-06 */ if (pUsr == NULL) { ABORT_FINALIZE(RS_RET_OK); } /* TODO: use the stream functions for data conversion here - should be quicker */ switch (propType) { case PROPTYPE_PSZ: pszBuf = (uchar *)pUsr; lenBuf = ustrlen(pszBuf); vType = VARTYPE_STR; break; case PROPTYPE_SHORT: CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), (long)*((short *)pUsr))); pszBuf = szBuf; lenBuf = ustrlen(szBuf); vType = VARTYPE_NUMBER; break; case PROPTYPE_INT: CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), (long)*((int *)pUsr))); pszBuf = szBuf; lenBuf = ustrlen(szBuf); vType = VARTYPE_NUMBER; break; case PROPTYPE_LONG: CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), *((long *)pUsr))); pszBuf = szBuf; lenBuf = ustrlen(szBuf); vType = VARTYPE_NUMBER; break; case PROPTYPE_INT64: CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), *((int64 *)pUsr))); pszBuf = szBuf; lenBuf = ustrlen(szBuf); vType = VARTYPE_NUMBER; break; case PROPTYPE_CSTR: pszBuf = rsCStrGetSzStrNoNULL((cstr_t *)pUsr); lenBuf = rsCStrLen((cstr_t *)pUsr); vType = VARTYPE_STR; break; case PROPTYPE_SYSLOGTIME: lenBuf = snprintf((char *)szBuf, sizeof(szBuf), "%d:%d:%d:%d:%d:%d:%d:%d:%d:%c:%d:%d", ((syslogTime_t *)pUsr)->timeType, ((syslogTime_t *)pUsr)->year, ((syslogTime_t *)pUsr)->month, ((syslogTime_t *)pUsr)->day, ((syslogTime_t *)pUsr)->hour, ((syslogTime_t *)pUsr)->minute, ((syslogTime_t *)pUsr)->second, ((syslogTime_t *)pUsr)->secfrac, ((syslogTime_t *)pUsr)->secfracPrecision, ((syslogTime_t *)pUsr)->OffsetMode, ((syslogTime_t *)pUsr)->OffsetHour, ((syslogTime_t *)pUsr)->OffsetMinute); if (lenBuf > sizeof(szBuf) - 1) ABORT_FINALIZE(RS_RET_PROVIDED_BUFFER_TOO_SMALL); vType = VARTYPE_SYSLOGTIME; pszBuf = szBuf; break; case PROPTYPE_NONE: default: dbgprintf("invalid PROPTYPE %d\n", propType); break; } /* cookie */ CHKiRet(strm.WriteChar(pStrm, COOKIE_PROPLINE)); /* name */ CHKiRet(strm.Write(pStrm, pszPropName, ustrlen(pszPropName))); CHKiRet(strm.WriteChar(pStrm, ':')); /* type */ CHKiRet(strm.WriteLong(pStrm, (int)vType)); CHKiRet(strm.WriteChar(pStrm, ':')); /* length */ CHKiRet(strm.WriteLong(pStrm, lenBuf)); CHKiRet(strm.WriteChar(pStrm, ':')); /* data */ CHKiRet(strm.Write(pStrm, (uchar *)pszBuf, lenBuf)); /* trailer */ CHKiRet(strm.WriteChar(pStrm, ':')); CHKiRet(strm.WriteChar(pStrm, '\n')); finalize_it: RETiRet; } /* end serialization of an object. The caller receives a * standard C string, which he must free when no longer needed. */ static rsRetVal EndSerialize(strm_t *pStrm) { DEFiRet; assert(pStrm != NULL); CHKiRet(strm.WriteChar(pStrm, COOKIE_ENDLINE)); CHKiRet(strm.Write(pStrm, (uchar *)"End\n", sizeof("END\n") - 1)); CHKiRet(strm.WriteChar(pStrm, COOKIE_BLANKLINE)); CHKiRet(strm.WriteChar(pStrm, '\n')); CHKiRet(strm.RecordEnd(pStrm)); finalize_it: RETiRet; } /* define a helper to make code below a bit cleaner (and quicker to write) */ #define NEXTC CHKiRet(strm.ReadChar(pStrm, &c)) /*;dbgprintf("c: %c\n", c)*/ /* de-serialize an embedded, non-octect-counted string. This is useful * for deserializing the object name inside the header. The string is * terminated by the first occurrence of the ':' character. * rgerhards, 2008-02-29 */ static rsRetVal objDeserializeEmbedStr(cstr_t **ppStr, strm_t *pStrm) { DEFiRet; uchar c; cstr_t *pStr = NULL; assert(ppStr != NULL); CHKiRet(cstrConstruct(&pStr)); NEXTC; while (c != ':') { CHKiRet(cstrAppendChar(pStr, c)); NEXTC; } cstrFinalize(pStr); *ppStr = pStr; finalize_it: if (iRet != RS_RET_OK && pStr != NULL) cstrDestruct(&pStr); RETiRet; } /* de-serialize a number */ static rsRetVal objDeserializeNumber(number_t *pNum, strm_t *pStrm) { DEFiRet; number_t i; int bIsNegative; uchar c; assert(pNum != NULL); NEXTC; if (c == '-') { bIsNegative = 1; NEXTC; } else { bIsNegative = 0; } /* we check this so that we get more meaningful error codes */ if (!isdigit(c)) ABORT_FINALIZE(RS_RET_INVALID_NUMBER); i = 0; while (isdigit(c)) { i = i * 10 + c - '0'; NEXTC; } if (c != ':') ABORT_FINALIZE(RS_RET_INVALID_DELIMITER); if (bIsNegative) i *= -1; *pNum = i; finalize_it: RETiRet; } /* de-serialize a string, length must be provided but may be 0 */ static rsRetVal objDeserializeStr(cstr_t **ppCStr, int iLen, strm_t *pStrm) { DEFiRet; int i; uchar c; cstr_t *pCStr = NULL; assert(ppCStr != NULL); assert(iLen >= 0); CHKiRet(cstrConstruct(&pCStr)); NEXTC; for (i = 0; i < iLen; ++i) { CHKiRet(cstrAppendChar(pCStr, c)); NEXTC; } cstrFinalize(pCStr); /* check terminator */ if (c != ':') { /* Initialized to NULL */ *ppCStr = NULL; ABORT_FINALIZE(RS_RET_INVALID_DELIMITER); } *ppCStr = pCStr; finalize_it: if (iRet != RS_RET_OK && pCStr != NULL) cstrDestruct(&pCStr); RETiRet; } /* de-serialize a syslogTime -- rgerhards,2008-01-08 */ #define GETVAL(var) \ CHKiRet(objDeserializeNumber(&l, pStrm)); \ pTime->var = l; static rsRetVal objDeserializeSyslogTime(syslogTime_t *pTime, strm_t *pStrm) { DEFiRet; number_t l; uchar c; assert(pTime != NULL); GETVAL(timeType); GETVAL(year); GETVAL(month); GETVAL(day); GETVAL(hour); GETVAL(minute); GETVAL(second); GETVAL(secfrac); GETVAL(secfracPrecision); /* OffsetMode is a single character! */ NEXTC; pTime->OffsetMode = c; NEXTC; if (c != ':') ABORT_FINALIZE(RS_RET_INVALID_DELIMITER); GETVAL(OffsetHour); GETVAL(OffsetMinute); finalize_it: RETiRet; } #undef GETVAL /* de-serialize an object header * rgerhards, 2008-01-07 */ static rsRetVal objDeserializeHeader(uchar *pszRecType, cstr_t **ppstrID, int *poVers, strm_t *pStrm) { DEFiRet; number_t oVers; uchar c; assert(ppstrID != NULL); assert(poVers != NULL); assert(!strcmp((char *)pszRecType, "Obj") || !strcmp((char *)pszRecType, "OPB")); /* check header cookie */ NEXTC; if (c != COOKIE_OBJLINE) ABORT_FINALIZE(RS_RET_INVALID_HEADER); NEXTC; if (c != pszRecType[0]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); NEXTC; if (c != pszRecType[1]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); NEXTC; if (c != pszRecType[2]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); NEXTC; if (c != ':') ABORT_FINALIZE(RS_RET_INVALID_HEADER); NEXTC; if (c != '1') ABORT_FINALIZE(RS_RET_INVALID_HEADER_VERS); NEXTC; if (c != ':') ABORT_FINALIZE(RS_RET_INVALID_HEADER_VERS); /* object type and version */ CHKiRet(objDeserializeEmbedStr(ppstrID, pStrm)); CHKiRet(objDeserializeNumber(&oVers, pStrm)); /* and now we skip over the rest until the delemiting \n */ NEXTC; while (c != '\n') { NEXTC; } *poVers = oVers; finalize_it: RETiRet; } /* Deserialize a single property. Pointer must be positioned at begin of line. Whole line * up until the \n is read. */ rsRetVal objDeserializeProperty(var_t *pProp, strm_t *pStrm) { DEFiRet; number_t i; number_t iLen; uchar c; int step = 0; /* which step was successful? */ int64 offs; assert(pProp != NULL); /* check cookie */ NEXTC; if (c != COOKIE_PROPLINE) { /* oops, we've read one char that does not belong to use - unget it first */ CHKiRet(strm.UnreadChar(pStrm, c)); ABORT_FINALIZE(RS_RET_NO_PROPLINE); } /* get the property name first */ CHKiRet(cstrConstruct(&pProp->pcsName)); NEXTC; while (c != ':') { CHKiRet(cstrAppendChar(pProp->pcsName, c)); NEXTC; } cstrFinalize(pProp->pcsName); step = 1; /* property type */ CHKiRet(objDeserializeNumber(&i, pStrm)); pProp->varType = i; step = 2; /* size (needed for strings) */ CHKiRet(objDeserializeNumber(&iLen, pStrm)); step = 3; /* we now need to deserialize the value */ switch (pProp->varType) { case VARTYPE_STR: CHKiRet(objDeserializeStr(&pProp->val.pStr, iLen, pStrm)); break; case VARTYPE_NUMBER: CHKiRet(objDeserializeNumber(&pProp->val.num, pStrm)); break; case VARTYPE_SYSLOGTIME: CHKiRet(objDeserializeSyslogTime(&pProp->val.vSyslogTime, pStrm)); break; case VARTYPE_NONE: default: dbgprintf("invalid VARTYPE %d\n", pProp->varType); break; } step = 4; /* we should now be at the end of the line. So the next char must be \n */ NEXTC; if (c != '\n') ABORT_FINALIZE(RS_RET_INVALID_PROPFRAME); finalize_it: /* ensure the type of var is reset back to VARTYPE_NONE since * the deconstruct method of var might free unallocated memory */ if (iRet != RS_RET_OK && iRet != RS_RET_NO_PROPLINE) { if (step <= 2) { pProp->varType = VARTYPE_NONE; } } if (Debug && iRet != RS_RET_OK && iRet != RS_RET_NO_PROPLINE) { strm.GetCurrOffset(pStrm, &offs); dbgprintf("error %d deserializing property name, offset %lld, step %d\n", iRet, offs, step); strmDebugOutBuf(pStrm); if (step >= 1) { dbgprintf("error property name: '%s'\n", rsCStrGetSzStrNoNULL(pProp->pcsName)); } if (step >= 2) { dbgprintf("error var type: '%d'\n", pProp->varType); } if (step >= 3) { dbgprintf("error len: '%d'\n", (int)iLen); } if (step >= 4) { switch (pProp->varType) { case VARTYPE_STR: dbgprintf("error data string: '%s'\n", rsCStrGetSzStrNoNULL(pProp->val.pStr)); break; case VARTYPE_NUMBER: dbgprintf("error number: %d\n", (int)pProp->val.num); break; case VARTYPE_SYSLOGTIME: dbgprintf( "syslog time was successfully parsed (but " "is not displayed\n"); break; case VARTYPE_NONE: default: break; } } } RETiRet; } /* de-serialize an object trailer. This does not get any data but checks if the * format is ok. * rgerhards, 2008-01-07 */ static rsRetVal objDeserializeTrailer(strm_t *pStrm) { DEFiRet; uchar c; /* check header cookie */ NEXTC; if (c != COOKIE_ENDLINE) ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != 'E') ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != 'n') ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != 'd') ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != '\n') ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != COOKIE_BLANKLINE) ABORT_FINALIZE(RS_RET_INVALID_TRAILER); NEXTC; if (c != '\n') ABORT_FINALIZE(RS_RET_INVALID_TRAILER); finalize_it: if (Debug && iRet != RS_RET_OK) { dbgprintf("objDeserializeTrailer fails with %d\n", iRet); } RETiRet; } /* This method tries to recover a serial store if it got out of sync. * To do so, it scans the line beginning cookies and waits for the object * cookie. If that is found, control is returned. If the store is exhausted, * we will receive an RS_RET_EOF error as part of NEXTC, which will also * terminate this function. So we may either return with somehting that * looks like a valid object or end of store. * rgerhards, 2008-01-07 */ static rsRetVal objDeserializeTryRecover(strm_t *pStrm) { DEFiRet; uchar c; int bWasNL; int bRun; assert(pStrm != NULL); bRun = 1; bWasNL = 0; while (bRun) { NEXTC; if (c == '\n') bWasNL = 1; else { if (bWasNL == 1 && c == COOKIE_OBJLINE) bRun = 0; /* we found it! */ else bWasNL = 0; } } CHKiRet(strm.UnreadChar(pStrm, c)); finalize_it: dbgprintf("deserializer has possibly been able to re-sync and recover, state %d\n", iRet); RETiRet; } /* De-serialize the properties of an object. This includes processing * of the trailer. Header must already have been processed. * rgerhards, 2008-01-11 */ static rsRetVal objDeserializeProperties(obj_t *pObj, rsRetVal (*objSetProperty)(void *, ...), strm_t *pStrm) { DEFiRet; var_t *pVar = NULL; ISOBJ_assert(pObj); ISOBJ_TYPE_assert(pStrm, strm); CHKiRet(var.Construct(&pVar)); CHKiRet(var.ConstructFinalize(pVar)); iRet = objDeserializeProperty(pVar, pStrm); while (iRet == RS_RET_OK) { CHKiRet(objSetProperty(pObj, pVar)); /* re-init var object - TODO: method of var! */ rsCStrDestruct(&pVar->pcsName); /* no longer needed */ if (pVar->varType == VARTYPE_STR) { if (pVar->val.pStr != NULL) rsCStrDestruct(&pVar->val.pStr); } iRet = objDeserializeProperty(pVar, pStrm); } if (iRet != RS_RET_NO_PROPLINE) FINALIZE; CHKiRet(objDeserializeTrailer(pStrm)); /* do trailer checks */ finalize_it: if (pVar != NULL) var.Destruct(&pVar); RETiRet; } /* De-Serialize an object. * Params: Pointer to object Pointer (pObj) (like a obj_t**, but can not do that due to compiler warning) * expected object ID (to check against), a fixup function that can modify the object before it is finalized * and a user pointer that is to be passed to that function in addition to the object. The fixup function * pointer may be NULL, in which case none is called. * The caller must destruct the created object. * rgerhards, 2008-01-07 */ static rsRetVal Deserialize( void *ppObj, uchar *pszTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t *, void *), void *pUsr) { DEFiRet; rsRetVal iRetLocal; obj_t *pObj = NULL; int oVers = 0; /* keep compiler happy, but it is totally useless but takes up some execution time... */ cstr_t *pstrID = NULL; objInfo_t *pObjInfo; assert(ppObj != NULL); assert(pszTypeExpected != NULL); ISOBJ_TYPE_assert(pStrm, strm); /* we de-serialize the header. if all goes well, we are happy. However, if * we experience a problem, we try to recover. We do this by skipping to * the next object header. This is defined via the line-start cookies. In * worst case, we exhaust the queue, but then we receive EOF return state, * from objDeserializeTryRecover(), what will cause us to ultimately give up. * rgerhards, 2008-07-08 */ do { iRetLocal = objDeserializeHeader((uchar *)"Obj", &pstrID, &oVers, pStrm); if (iRetLocal != RS_RET_OK) { dbgprintf("objDeserialize error %d during header processing - trying to recover\n", iRetLocal); CHKiRet(objDeserializeTryRecover(pStrm)); } } while (iRetLocal != RS_RET_OK); if (rsCStrSzStrCmp(pstrID, pszTypeExpected, ustrlen(pszTypeExpected))) ABORT_FINALIZE(RS_RET_INVALID_OID); CHKiRet(FindObjInfo((char *)cstrGetSzStrNoNULL(pstrID), &pObjInfo)); CHKiRet(pObjInfo->objMethods[objMethod_CONSTRUCT](&pObj)); /* we got the object, now we need to fill the properties */ CHKiRet( objDeserializeProperties(pObj, (rsRetVal(*)(void *, ...))pObjInfo->objMethods[objMethod_SETPROPERTY], pStrm)); /* check if we need to call a fixup function that modifies the object * before it is finalized. -- rgerhards, 2008-01-13 */ if (fFixup != NULL) CHKiRet(fFixup(pObj, pUsr)); /* we have a valid object, let's finalize our work and return */ if (objInfoIsImplemented(pObjInfo, objMethod_CONSTRUCTION_FINALIZER)) CHKiRet(pObjInfo->objMethods[objMethod_CONSTRUCTION_FINALIZER](pObj)); *((obj_t **)ppObj) = pObj; finalize_it: if (iRet != RS_RET_OK && pObj != NULL) free(pObj); /* TODO: check if we can call destructor 2008-01-13 rger */ if (pstrID != NULL) rsCStrDestruct(&pstrID); RETiRet; } /* De-Serialize an object, with known constructur and destructor. Params like Deserialize(). * Note: this is for the queue subsystem, and optimized for its use. * rgerhards, 2012-11-03 */ rsRetVal objDeserializeWithMethods(void *ppObj, uchar *pszTypeExpected, int lenTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t *, void *), void *pUsr, rsRetVal (*objConstruct)(void **), rsRetVal (*objConstructFinalize)(void *), rsRetVal (*objDeserialize)(void *, strm_t *)) { DEFiRet; rsRetVal iRetLocal; obj_t *pObj = NULL; int oVers = 0; /* keep compiler happy, but it is totally useless but takes up some execution time... */ cstr_t *pstrID = NULL; assert(ppObj != NULL); assert(pszTypeExpected != NULL); ISOBJ_TYPE_assert(pStrm, strm); /* we de-serialize the header. if all goes well, we are happy. However, if * we experience a problem, we try to recover. We do this by skipping to * the next object header. This is defined via the line-start cookies. In * worst case, we exhaust the queue, but then we receive EOF return state, * from objDeserializeTryRecover(), what will cause us to ultimately give up. * rgerhards, 2008-07-08 */ do { iRetLocal = objDeserializeHeader((uchar *)"Obj", &pstrID, &oVers, pStrm); if (iRetLocal != RS_RET_OK) { dbgprintf( "objDeserialize error %d during header processing - " "trying to recover\n", iRetLocal); CHKiRet(objDeserializeTryRecover(pStrm)); } } while (iRetLocal != RS_RET_OK); if (rsCStrSzStrCmp(pstrID, pszTypeExpected, lenTypeExpected)) ABORT_FINALIZE(RS_RET_INVALID_OID); CHKiRet(objConstruct((void **)&pObj)); /* we got the object, now we need to fill the properties */ CHKiRet(objDeserialize(pObj, pStrm)); CHKiRet(objDeserializeTrailer(pStrm)); /* do trailer checks */ /* check if we need to call a fixup function that modifies the object * before it is finalized. -- rgerhards, 2008-01-13 */ if (fFixup != NULL) CHKiRet(fFixup(pObj, pUsr)); /* we have a valid object, let's finalize our work and return */ if (objConstructFinalize != NULL) { CHKiRet(objConstructFinalize(pObj)); } *((obj_t **)ppObj) = pObj; finalize_it: if (iRet != RS_RET_OK && pObj != NULL) free(pObj); /* TODO: check if we can call destructor 2008-01-13 rger */ if (pstrID != NULL) rsCStrDestruct(&pstrID); if (Debug && iRet != RS_RET_OK) { dbgprintf("objDeserializeWithMethods fails with %d, stream state:\n", iRet); strmDebugOutBuf(pStrm); } RETiRet; } /* De-Serialize an object property bag. As a property bag contains only partial properties, * it is not instanciable. Thus, the caller must provide a pointer of an already-instanciated * object of the correct type. * Params: Pointer to object (pObj) * Pointer to be passed to the function * The caller must destruct the created object. * rgerhards, 2008-01-07 */ static rsRetVal DeserializePropBag(obj_t *pObj, strm_t *pStrm) { DEFiRet; rsRetVal iRetLocal; cstr_t *pstrID = NULL; int oVers; objInfo_t *pObjInfo; ISOBJ_assert(pObj); ISOBJ_TYPE_assert(pStrm, strm); /* we de-serialize the header. if all goes well, we are happy. However, if * we experience a problem, we try to recover. We do this by skipping to * the next object header. This is defined via the line-start cookies. In * worst case, we exhaust the queue, but then we receive EOF return state * from objDeserializeTryRecover(), what will cause us to ultimately give up. * rgerhards, 2008-07-08 */ do { iRetLocal = objDeserializeHeader((uchar *)"OPB", &pstrID, &oVers, pStrm); if (iRetLocal != RS_RET_OK) { dbgprintf("objDeserializePropBag error %d during header - trying to recover\n", iRetLocal); CHKiRet(objDeserializeTryRecover(pStrm)); } } while (iRetLocal != RS_RET_OK); if (rsCStrSzStrCmp(pstrID, pObj->pObjInfo->pszID, pObj->pObjInfo->lenID)) ABORT_FINALIZE(RS_RET_INVALID_OID); CHKiRet(FindObjInfo((char *)cstrGetSzStrNoNULL(pstrID), &pObjInfo)); /* we got the object, now we need to fill the properties */ CHKiRet( objDeserializeProperties(pObj, (rsRetVal(*)(void *, ...))pObjInfo->objMethods[objMethod_SETPROPERTY], pStrm)); finalize_it: if (pstrID != NULL) rsCStrDestruct(&pstrID); RETiRet; } #undef NEXTC /* undef helper macro */ /* --------------- end object serializiation / deserialization support --------------- */ /* set the object (instance) name * rgerhards, 2008-01-29 * TODO: change the naming to a rsCStr obj! (faster) */ static rsRetVal SetName(obj_t *pThis, uchar *pszName) { DEFiRet; free(pThis->pszName); CHKmalloc(pThis->pszName = ustrdup(pszName)); finalize_it: RETiRet; } /* get the object (instance) name * Note that we use a non-standard calling convention. Thus function must never * fail, else we run into real big problems. So it must make sure that at least someting * is returned. * rgerhards, 2008-01-30 */ uchar *ATTR_NONNULL() objGetName(obj_t *const pThis) { uchar *ret; uchar szName[128]; ISOBJ_assert(pThis); if (pThis->pszName == NULL) { snprintf((char *)szName, sizeof(szName), "%s %p", objGetClassName(pThis), pThis); SetName(pThis, szName); /* looks strange, but we NEED to re-check because if there was an * error in objSetName(), the pointer may still be NULL */ if (pThis->pszName == NULL) { ret = objGetClassName(pThis); } else { ret = pThis->pszName; } } else { ret = pThis->pszName; } return ret; } /* Find the objInfo object for the current object * rgerhards, 2008-02-29 */ static rsRetVal FindObjInfo(const char *const __restrict__ strOID, objInfo_t **ppInfo) { DEFiRet; int bFound; int i; bFound = 0; i = 0; while (!bFound && i < OBJ_NUM_IDS) { if (arrObjInfo[i] != NULL && !strcmp(strOID, (const char *)arrObjInfo[i]->pszID)) { bFound = 1; break; } ++i; } if (!bFound) ABORT_FINALIZE(RS_RET_NOT_FOUND); *ppInfo = arrObjInfo[i]; finalize_it: if (iRet != RS_RET_OK) { dbgprintf("caller requested object '%s', not found (iRet %d)\n", strOID, iRet); } RETiRet; } /* register a classes' info pointer, so that we can reference it later, if needed to * (e.g. for de-serialization support). * rgerhards, 2008-01-07 * In this function, we look for a free space in the object table. While we do so, we * also detect if the same object has already been registered, which is not valid. * rgerhards, 2008-02-29 */ static rsRetVal RegisterObj(uchar *pszObjName, objInfo_t *pInfo) { DEFiRet; int bFound; int i; assert(pszObjName != NULL); assert(pInfo != NULL); bFound = 0; i = 0; while (!bFound && i < OBJ_NUM_IDS && arrObjInfo[i] != NULL) { if (arrObjInfo[i] != NULL && !ustrcmp(arrObjInfo[i]->pszID, pszObjName)) { bFound = 1; break; } ++i; } if (bFound) ABORT_FINALIZE(RS_RET_OBJ_ALREADY_REGISTERED); if (i >= OBJ_NUM_IDS) ABORT_FINALIZE(RS_RET_OBJ_REGISTRY_OUT_OF_SPACE); arrObjInfo[i] = pInfo; #if DEV_DEBUG == 1 dbgprintf( "object '%s' successfully registered with " "index %d, qIF %p\n", pszObjName, i, pInfo->QueryIF); #endif finalize_it: if (iRet != RS_RET_OK) { LogError(0, NO_ERRCODE, "registering object '%s' failed with error code %d", pszObjName, iRet); } RETiRet; } /* deregister a classes' info pointer, usually called because the class is unloaded. * After deregistration, the class can no longer be accessed, except if it is reloaded. * rgerhards, 2008-03-10 */ static rsRetVal UnregisterObj(uchar *pszObjName) { DEFiRet; int bFound; int i; assert(pszObjName != NULL); bFound = 0; i = 0; while (!bFound && i < OBJ_NUM_IDS) { if (arrObjInfo[i] != NULL && !ustrcmp(arrObjInfo[i]->pszID, pszObjName)) { bFound = 1; break; } ++i; } if (!bFound) ABORT_FINALIZE(RS_RET_OBJ_NOT_REGISTERED); InfoDestruct(&arrObjInfo[i]); #if DEV_DEBUG == 1 dbgprintf("object '%s' successfully unregistered with index %d\n", pszObjName, i); #endif finalize_it: if (iRet != RS_RET_OK) { dbgprintf("unregistering object '%s' failed with error code %d\n", pszObjName, iRet); } RETiRet; } /* This function shall be called by anyone who would like to use an object. It will * try to locate the object, load it into memory if not already present and return * a pointer to the objects interface. * rgerhards, 2008-02-29 */ static rsRetVal UseObj(const char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf) { DEFiRet; objInfo_t *pObjInfo; #if DEV_DEBUG == 1 dbgprintf( "source file %s requests object '%s', " " ifIsLoaded %d\n", srcFile, pObjName, pIf->ifIsLoaded); #endif pthread_mutex_lock(&mutObjGlobalOp); if (pIf->ifIsLoaded == 1) { ABORT_FINALIZE(RS_RET_OK); /* we are already set */ } if (pIf->ifIsLoaded == 2) { ABORT_FINALIZE(RS_RET_LOAD_ERROR); /* we had a load error and can not continue */ } /* we must be careful that we do not enter in infinite loop if an error occurs during * loading a module. ModLoad emits an error message in such cases and that potentially * can trigger the same code here. So we initially set the module state to "load error" * and set it to "fully initialized" when the load succeeded. It's a bit hackish, but * looks like a good solution. -- rgerhards, 2008-03-07 */ pIf->ifIsLoaded = 2; iRet = FindObjInfo((const char *)pObjName, &pObjInfo); if (iRet == RS_RET_NOT_FOUND) { /* in this case, we need to see if we can dynamically load the object */ if (pObjFile == NULL) { FINALIZE; /* no chance, we have lost... */ } else { CHKiRet(module.Load(pObjFile, 0, NULL)); /* NOW, we must find it or we have a problem... */ CHKiRet(FindObjInfo((const char *)pObjName, &pObjInfo)); } } else if (iRet != RS_RET_OK) { FINALIZE; /* give up */ } /* if we reach this point, we have a valid pObjInfo */ if (pObjFile != NULL) { /* NULL means core module */ module.Use(srcFile, pObjInfo->pModInfo); /* increase refcount */ } CHKiRet(pObjInfo->QueryIF(pIf)); pIf->ifIsLoaded = 1; /* we are happy */ finalize_it: pthread_mutex_unlock(&mutObjGlobalOp); RETiRet; } /* This function shall be called when a caller is done with an object. Its primary * purpose is to keep the reference count correct, which is highly important for * modules residing in loadable modules. * rgerhards, 2008-03-10 */ static rsRetVal ReleaseObj(const char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf) { DEFiRet; objInfo_t *pObjInfo; /* dev debug only dbgprintf("source file %s releasing object '%s', ifIsLoaded %d\n", srcFile, pObjName, pIf->ifIsLoaded); */ pthread_mutex_lock(&mutObjGlobalOp); if (pObjFile == NULL) FINALIZE; /* if it is not a lodable module, we do not need to do anything... */ if (pIf->ifIsLoaded == 0) { FINALIZE; /* we are not loaded - this is perfectly OK... */ } else if (pIf->ifIsLoaded == 2) { pIf->ifIsLoaded = 0; /* clean up */ FINALIZE; /* we had a load error and can not/must not continue */ } CHKiRet(FindObjInfo((const char *)pObjName, &pObjInfo)); /* if we reach this point, we have a valid pObjInfo */ module.Release(srcFile, &pObjInfo->pModInfo); /* decrease refcount */ pIf->ifIsLoaded = 0; /* indicated "no longer valid" */ finalize_it: pthread_mutex_unlock(&mutObjGlobalOp); RETiRet; } /* queryInterface function * rgerhards, 2008-02-29 */ PROTOTYPEObjQueryInterface(obj); BEGINobjQueryInterface(obj) CODESTARTobjQueryInterface(obj); if (pIf->ifVersion != objCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->UseObj = UseObj; pIf->ReleaseObj = ReleaseObj; pIf->InfoConstruct = InfoConstruct; pIf->DestructObjSelf = DestructObjSelf; pIf->BeginSerializePropBag = BeginSerializePropBag; pIf->InfoSetMethod = InfoSetMethod; pIf->BeginSerialize = BeginSerialize; pIf->SerializeProp = SerializeProp; pIf->EndSerialize = EndSerialize; pIf->RegisterObj = RegisterObj; pIf->UnregisterObj = UnregisterObj; pIf->Deserialize = Deserialize; pIf->DeserializePropBag = DeserializePropBag; pIf->SetName = SetName; pIf->GetName = objGetName; finalize_it: ENDobjQueryInterface(obj) /* This function returns a pointer to our own interface. It is used as the * hook that every object (including dynamically loaded ones) can use to * obtain a pointer to our interface which than can be used to obtain * pointers to any other interface in the system. This function must be * externally visible because of its special nature. * rgerhards, 2008-02-29 [nice - will have that date the next time in 4 years ;)] */ rsRetVal objGetObjInterface(obj_if_t *pIf) { DEFiRet; assert(pIf != NULL); objQueryInterface(pIf); RETiRet; } /* exit our class * rgerhards, 2008-03-11 */ rsRetVal objClassExit(void) { DEFiRet; /* release objects we no longer need */ objRelease(strm, CORE_COMPONENT); objRelease(var, CORE_COMPONENT); objRelease(module, CORE_COMPONENT); /* TODO: implement the class exits! */ #if 0 cfsyslineExit(pModInfo); varClassExit(pModInfo); #endif moduleClassExit(); RETiRet; } /* initialize our own class * Please note that this also initializes those classes that we rely on. * Though this is a bit dirty, we need to do it - otherwise we can't get * around that bootstrap problem. We need to face the fact the the obj * class is a little different from the rest of the system, as it provides * the core class loader functionality. * rgerhards, 2008-02-29 */ rsRetVal objClassInit(modInfo_t *pModInfo) { pthread_mutexattr_t mutAttr; int i; DEFiRet; /* first, initialize the object system itself. This must be done * before any other object is created. */ for (i = 0; i < OBJ_NUM_IDS; ++i) { arrObjInfo[i] = NULL; } /* the mutex must be recursive, because objects may call into other * object identifiers recursively. */ pthread_mutexattr_init(&mutAttr); pthread_mutexattr_settype(&mutAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&mutObjGlobalOp, &mutAttr); /* request objects we use */ CHKiRet(objGetObjInterface(&obj)); /* get ourselves ;) */ /* init classes we use (limit to as few as possible!) */ CHKiRet(datetimeClassInit(pModInfo)); CHKiRet(cfsyslineInit()); CHKiRet(varClassInit(pModInfo)); CHKiRet(moduleClassInit(pModInfo)); CHKiRet(strmClassInit(pModInfo)); CHKiRet(objUse(var, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); CHKiRet(objUse(strm, CORE_COMPONENT)); finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/cryprov.h0000644000000000000000000000013215055605325016077 xustar0030 mtime=1756826325.643800593 30 atime=1764930980.026678323 30 ctime=1764935923.125575693 rsyslog-8.2512.0/runtime/cryprov.h0000664000175000017500000000412215055605325015542 0ustar00rgerrger/* The interface definition for (file) crypto providers. * * This is just an abstract driver interface, which needs to be * implemented by concrete classes. * * Copyright 2013 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_CRYPROV_H #define INCLUDED_CRYPROV_H /* we unfortunately need to have two different param names depending on the * context in which parameters are set. Other than (re/over)engineering the core * interface, we just define some values to keep track of that. */ #define CRYPROV_PARAMTYPE_REGULAR 0 #define CRYPROV_PARAMTYPE_DISK 1 /* interface */ BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(void *ppThis); rsRetVal (*SetCnfParam)(void *ppThis, struct nvlst *lst, int paramType); rsRetVal (*Destruct)(void *ppThis); rsRetVal (*OnFileOpen)(void *pThis, uchar *fn, void *pFileInstData, char openMode); rsRetVal (*Encrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf); rsRetVal (*Decrypt)(void *pFileInstData, uchar *buf, size_t *lenBuf); rsRetVal (*OnFileClose)(void *pFileInstData, off64_t offsLogfile); rsRetVal (*DeleteStateFiles)(uchar *logfn); rsRetVal (*GetBytesLeftInBlock)(void *pFileInstData, ssize_t *left); void (*SetDeleteOnClose)(void *pFileInstData, int val); ENDinterface(cryprov) #define cryprovCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */ #endif /* #ifndef INCLUDED_CRYPROV_H */ rsyslog-8.2512.0/runtime/PaxHeaders/netns_socket.h0000644000000000000000000000013215071746523017076 xustar0030 mtime=1760021843.867421443 30 atime=1764930980.500686251 30 ctime=1764935923.345579061 rsyslog-8.2512.0/runtime/netns_socket.h0000664000175000017500000000227715071746523016552 0ustar00rgerrger/* Definitions for netns_socket API * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NETNS_SOCKET_H #define INCLUDED_NETNS_SOCKET_H #include "rsyslog.h" /* * Open a socket in the named network namespace */ rsRetVal netns_socket(int *fdp, int domain, int type, int protocol, const char *ns); /* * Switch to the named networknamespace */ rsRetVal netns_switch(const char *ns); /* * Save and restore our current network namespace */ rsRetVal ATTR_NONNULL() netns_save(int *fd); rsRetVal ATTR_NONNULL() netns_restore(int *fd); #endif /* #ifndef INCLUDED_NETNS_SOCKET_H */ rsyslog-8.2512.0/runtime/PaxHeaders/lib_ksils12.h0000644000000000000000000000013215055605325016511 xustar0030 mtime=1756826325.646800638 30 atime=1764931131.091158582 30 ctime=1764935923.393579796 rsyslog-8.2512.0/runtime/lib_ksils12.h0000664000175000017500000002453415055605325016165 0ustar00rgerrger/* lib_ksils12.h - rsyslog's KSI-LS12 support library * * Copyright 2013-2017 Adiscon GmbH and Guardtime, Inc. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_KSILS12_H #define INCLUDED_KSILS12_H #include #include "lib_ksi_queue.h" #define MAX_ROOTS 64 /* Flags and record types for TLV handling */ #define RSGT_FLAG_NONCRIT 0x20 #define RSGT_FLAG_FORWARD 0x40 #define RSGT_TYPE_MASK 0x1f #define RSGT_FLAG_TLV16 0x80 /* check return state of operation and abort, if non-OK */ #define CHKr(code) \ if ((r = code) != 0) goto done /* check the return value of a ksi api call and log a message in case of error */ #define CHECK_KSI_API(code, context, msg) \ if ((res = code) != 0) do { \ reportKSIAPIErr(context, NULL, msg, res); \ goto cleanup; \ } while (0) typedef enum LOGSIG_SyncMode_en { /** The block hashes and ksi signatures in one file */ LOGSIG_ASYNCHRONOUS = 0x00, /** The block hashes and ksi signatures split into separate files */ LOGSIG_SYNCHRONOUS = 0x01 } LOGSIG_SyncMode; enum { /* Signer state assigned before the signer thread is initialized. State remains * until thread initialization begins. In case of system failure to create new * thread state remains the same. */ SIGNER_IDLE = 0x01, /* Signer state assigned while signer thread initialization is in progress. */ SIGNER_INIT = 0x02, /* Signer state assigned when signer thread is initialized and ready to work. */ SIGNER_STARTED = 0x04, /* Thread state assigned when signer thread is being closed (signer thread returns). */ SIGNER_STOPPED = 0x08 }; /* Max number of roots inside the forest. This permits blocks of up to * 2^MAX_ROOTS records. We assume that 64 is sufficient for all use * cases ;) [and 64 is not really a waste of memory, so we do not even * try to work with reallocs and such...] */ typedef struct rsksictx_s *rsksictx; typedef struct ksifile_s *ksifile; typedef struct ksierrctx_s ksierrctx_t; /* context for gt calls. This primarily serves as a container for the * config settings. The actual file-specific data is kept in ksifile. */ struct rsksictx_s { KSI_CTX *ksi_ctx; /* libksi's context object */ KSI_DataHasher *hasher; KSI_HashAlgorithm hashAlg; KSI_HashAlgorithm hmacAlg; uint8_t bKeepRecordHashes; uint8_t bKeepTreeHashes; uint64_t confInterval; time_t tConfRequested; uint64_t blockLevelLimit; uint32_t blockTimeLimit; uint32_t blockSigTimeout; uint32_t effectiveBlockLevelLimit; /* level limit adjusted by gateway settings */ uint32_t threadSleepms; uint8_t syncMode; uid_t fileUID; /* IDs for creation */ uid_t dirUID; gid_t fileGID; gid_t dirGID; int fCreateMode; /* mode to use when creating files */ int fDirCreateMode; /* mode to use when creating files */ char *aggregatorUri; char *aggregatorId; char *aggregatorKey; char *aggregatorEndpoints[KSI_CTX_HA_MAX_SUBSERVICES]; int aggregatorEndpointCount; char *random_source; pthread_mutex_t module_lock; pthread_t signer_thread; ProtectedQueue *signer_queue; #if KSI_SDK_VER_MAJOR == 3 && KSI_SDK_VER_MINOR < 22 size_t roundCount; /* Count of signing requests in round. */ uint8_t bRoundLock; /* A lock for async. signer. */ #endif int signer_state; uint8_t disabled; /* permits to disable the plugin --> set to 1 */ ksifile *ksi; /* List of signature files for keeping track of block timeouts. */ size_t ksiCapacity; size_t ksiCount; char *debugFileName; int debugLevel; FILE *debugFile; uint64_t max_requests; void (*errFunc)(void *, unsigned char *); void (*logFunc)(void *, unsigned char *); void *usrptr; /* for error function */ }; /* this describes a file, as far as librsksi is concerned */ struct ksifile_s { /* the following data items are mirrored from rsksictx to * increase cache hit ratio (they are frequently accesed). */ KSI_HashAlgorithm hashAlg; uint8_t bKeepRecordHashes; uint8_t bKeepTreeHashes; uint64_t blockSizeLimit; uint32_t blockTimeLimit; /* end mirrored properties */ uint8_t disabled; /* permits to disable this file --> set to 1 */ uint8_t *IV; /* initial value for blinding masks */ unsigned char lastLeaf[KSI_MAX_IMPRINT_LEN]; /* last leaf hash (maybe of previous block) --> preserve on term */ unsigned char *blockfilename; unsigned char *ksifilename; unsigned char *statefilename; uint64_t nRecords; /* current number of records in current block */ uint64_t bInBlk; /* are we currently inside a blk --> need to finish on close */ time_t blockStarted; int8_t nRoots; /* algo engineering: roots structure is split into two arrays * in order to improve cache hits. */ KSI_DataHash *roots[MAX_ROOTS]; /* data members for the associated TLV file */ FILE *blockFile; FILE *sigFile; /* Note that this may only be closed by signer thread or when signer thread has terminated. */ rsksictx ctx; }; /* the following defines the ksistate file record. Currently, this record * is fixed, we may change that over time. */ struct rsksistatefile { char hdr[9]; /* must be "KSISTAT10" */ uint8_t hashID; uint8_t lenHash; /* after that, the hash value is contained within the file */ }; /* error states */ #define RSGTE_SUCCESS 0 /* Success state */ #define RSGTE_IO 1 /* any kind of io error */ #define RSGTE_FMT 2 /* data fromat error */ #define RSGTE_INVLTYP 3 /* invalid TLV type record (unexcpected at this point) */ #define RSGTE_OOM 4 /* ran out of memory */ #define RSGTE_LEN 5 /* error related to length records */ #define RSGTE_SIG_EXTEND 6 /* error extending signature */ #define RSGTE_INVLD_RECCNT \ 7 /* mismatch between actual records and records \ given in block-sig record */ #define RSGTE_INVLHDR 8 /* invalid file header */ #define RSGTE_EOF 9 /* specific EOF */ #define RSGTE_MISS_REC_HASH 10 /* record hash missing when expected */ #define RSGTE_MISS_TREE_HASH 11 /* tree hash missing when expected */ #define RSGTE_INVLD_REC_HASH 12 /* invalid record hash (failed verification) */ #define RSGTE_INVLD_TREE_HASH 13 /* invalid tree hash (failed verification) */ #define RSGTE_INVLD_REC_HASHID 14 /* invalid record hash ID (failed verification) */ #define RSGTE_INVLD_TREE_HASHID 15 /* invalid tree hash ID (failed verification) */ #define RSGTE_MISS_BLOCKSIG 16 /* block signature record missing when expected */ #define RSGTE_INVLD_SIGNATURE 17 /* Signature is invalid (KSI_Signature_verifyDataHash)*/ #define RSGTE_TS_CREATEHASH 18 /* error creating HASH (KSI_DataHash_create) */ #define RSGTE_TS_DERENCODE 19 /* error DER-Encoding a timestamp */ #define RSGTE_HASH_CREATE 20 /* error creating a hash */ #define RSGTE_END_OF_SIG 21 /* unexpected end of signature - more log line exist */ #define RSGTE_END_OF_LOG 22 /* unexpected end of log file - more signatures exist */ #define RSGTE_EXTRACT_HASH 23 /* error extracting hashes for record */ #define RSGTE_CONFIG_ERROR 24 /* Configuration error */ #define RSGTE_NETWORK_ERROR 25 /* Network error */ #define RSGTE_MISS_KSISIG 26 /* KSI signature missing */ #define RSGTE_INTERNAL 27 /* Internal error */ #define getIVLenKSI(bh) (hashOutputLengthOctetsKSI((bh)->hashID)) #define rsksiSetBlockLevelLimit(ctx, limit) ((ctx)->blockLevelLimit = (ctx)->effectiveBlockLevelLimit = limit) #define rsksiSetBlockTimeLimit(ctx, limit) ((ctx)->blockTimeLimit = limit) #define rsksiSetBlockSigTimeout(ctx, val) ((ctx)->blockSigTimeout = val) #define rsksiSetConfInterval(ctx, val) ((ctx)->confInterval = val) #define rsksiSetKeepRecordHashes(ctx, val) ((ctx)->bKeepRecordHashes = val) #define rsksiSetKeepTreeHashes(ctx, val) ((ctx)->bKeepTreeHashes = val) #define rsksiSetFileFormat(ctx, val) ((ctx)->fileFormat = val) #define rsksiSetSyncMode(ctx, val) ((ctx)->syncMode = val) #define rsksiSetRandomSource(ctx, val) ((ctx)->random_source = strdup(val)) #define rsksiSetFileUID(ctx, val) ((ctx)->fileUID = val) /* IDs for creation */ #define rsksiSetDirUID(ctx, val) ((ctx)->dirUID = val) #define rsksiSetFileGID(ctx, val) ((ctx)->fileGID = val) #define rsksiSetDirGID(ctx, val) ((ctx)->dirGID = val) #define rsksiSetCreateMode(ctx, val) ((ctx)->fCreateMode = val) #define rsksiSetDirCreateMode(ctx, val) ((ctx)->fDirCreateMode = val) #define rsksiSetDebugLevel(ctx, val) ((ctx)->debugLevel = val) int rsksiSetDebugFile(rsksictx ctx, char *val); int rsksiSetAggregator(rsksictx ctx, char *uri, char *loginid, char *key); int rsksiSetHashFunction(rsksictx ctx, char *algName); int rsksiSetHmacFunction(rsksictx ctx, char *algName); int rsksiInitModule(rsksictx ctx); rsksictx rsksiCtxNew(void); void rsksisetErrFunc(rsksictx ctx, void (*func)(void *, unsigned char *), void *usrptr); void rsksisetLogFunc(rsksictx ctx, void (*func)(void *, unsigned char *), void *usrptr); void reportKSIAPIErr(rsksictx ctx, ksifile ksi, const char *apiname, int ecode); ksifile rsksiCtxOpenFile(rsksictx ctx, unsigned char *logfn); int rsksifileDestruct(ksifile ksi); void rsksiCtxDel(rsksictx ctx); void sigblkInitKSI(ksifile ksi); int sigblkAddRecordKSI(ksifile ksi, const unsigned char *rec, const size_t len); int sigblkAddLeaf(ksifile ksi, const unsigned char *rec, const size_t len, bool metadata); unsigned sigblkCalcLevel(unsigned leaves); int sigblkFinishKSI(ksifile ksi); int sigblkAddMetadata(ksifile ksi, const char *key, const char *value); int sigblkCreateMask(ksifile ksi, KSI_DataHash **m); int sigblkCreateHash(ksifile ksi, KSI_DataHash **r, const unsigned char *rec, const size_t len); int sigblkHashTwoNodes(ksifile ksi, KSI_DataHash **node, KSI_DataHash *m, KSI_DataHash *r, uint8_t level); #endif /* #ifndef INCLUDED_KSILS12_H */ rsyslog-8.2512.0/runtime/PaxHeaders/hashtable_itr.h0000644000000000000000000000013215055605325017204 xustar0030 mtime=1756826325.645800623 30 atime=1764930990.565854364 30 ctime=1764935923.304578433 rsyslog-8.2512.0/runtime/hashtable_itr.h0000664000175000017500000000767015055605325016662 0ustar00rgerrger/* Copyright (C) 2002, 2004 Christopher Clark */ #ifndef __HASHTABLE_ITR_CWC22__ #define __HASHTABLE_ITR_CWC22__ #include "hashtable_private.h" /* needed to enable inlining */ /*****************************************************************************/ /* This struct is only concrete here to allow the inlining of two of the * accessor functions. */ struct hashtable_itr { struct hashtable *h; struct entry *e; struct entry *parent; unsigned int index; }; /*****************************************************************************/ /* hashtable_iterator */ struct hashtable_itr *hashtable_iterator(struct hashtable *h); /*****************************************************************************/ /* hashtable_iterator_key * - return the value of the (key,value) pair at the current position */ #define hashtable_iterator_key(i) ((i)->e->k) /*****************************************************************************/ /* value - return the value of the (key,value) pair at the current position */ #define hashtable_iterator_value(i) ((i)->e->v) /*****************************************************************************/ /* advance - advance the iterator to the next element * returns zero if advanced to end of table */ int hashtable_iterator_advance(struct hashtable_itr *itr); /*****************************************************************************/ /* remove - remove current element and advance the iterator to the next element * NB: if you need the value to free it, read it before * removing. ie: beware memory leaks! * returns zero if advanced to end of table */ int hashtable_iterator_remove(struct hashtable_itr *itr); /*****************************************************************************/ /* search - overwrite the supplied iterator, to point to the entry * matching the supplied key. * h points to the hashtable to be searched. * returns zero if not found. */ int hashtable_iterator_search(struct hashtable_itr *itr, struct hashtable *h, void *k); #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \ int fnname(struct hashtable_itr *i, struct hashtable *h, keytype *k) { \ return (hashtable_iterator_search(i, h, k)); \ } #endif /* __HASHTABLE_ITR_CWC22__*/ /* * Copyright (c) 2002, 2004, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ rsyslog-8.2512.0/runtime/PaxHeaders/lib_ksils12.c0000644000000000000000000000013215055605325016504 xustar0030 mtime=1756826325.645800623 30 atime=1764931131.083158454 30 ctime=1764935923.391579765 rsyslog-8.2512.0/runtime/lib_ksils12.c0000664000175000017500000017635615055605325016172 0ustar00rgerrger/* lib_ksils12.c - rsyslog's KSI-LS12 support library * * Regarding the online algorithm for Merkle tree signing. Expected * calling sequence is: * * sigblkConstruct * for each signature block: * sigblkInitKSI * for each record: * sigblkAddRecordKSI * sigblkFinishKSI * sigblkDestruct * * Obviously, the next call after sigblkFinsh must either be to * sigblkInitKSI or sigblkDestruct (if no more signature blocks are * to be emitted, e.g. on file close). sigblkDestruct saves state * information (most importantly last block hash) and sigblkConstruct * reads (or initilizes if not present) it. * * Copyright 2013-2018 Adiscon GmbH and Guardtime, Inc. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "errmsg.h" #include "lib_ksils12.h" #include "lib_ksi_queue.h" #ifndef VERSION #define VERSION "no-version" #endif #define KSI_BUF_SIZE 4096 static const char *blockFileSuffix = ".logsig.parts/blocks.dat"; static const char *sigFileSuffix = ".logsig.parts/block-signatures.dat"; static const char *ls12FileSuffix = ".logsig"; static const char *blockCloseReason = "com.guardtime.blockCloseReason"; #define LS12_FILE_HEADER "LOGSIG12" #define LS12_BLOCKFILE_HEADER "LOG12BLK" #define LS12_SIGFILE_HEADER "LOG12SIG" #define LS12_SIGNATURE_TIMEOUT 60 /* Worker queue item type identifier */ typedef enum QITEM_type_en { QITEM_SIGNATURE_REQUEST = 0x00, QITEM_CLOSE_FILE, QITEM_NEW_FILE, QITEM_QUIT } QITEM_type; /* Worker queue item status identifier */ typedef enum QITEM_status_en { /* State assigned to any item added to queue (initial state). */ QITEM_WAITING = 0x00, /* State assigned to #QITEM_SIGNATURE_REQUEST item when it is sent out. */ QITEM_SENT, /* State assigned to #QITEM_SIGNATURE_REQUEST item when request failed or succeeded. */ QITEM_DONE } QITEM_status; /* Worker queue job item */ typedef struct QueueItem_st { QITEM_type type; QITEM_status status; KSI_DataHash *root; FILE *file; /* To keep track of the target signature file. */ uint64_t intarg1; /* Block time limit or record count or not used. */ uint64_t intarg2; /* Level of the sign request or not used. */ KSI_AsyncHandle *respHandle; int ksi_status; time_t request_time; } QueueItem; static bool queueAddCloseFile(rsksictx ctx, ksifile kf); static bool queueAddNewFile(rsksictx ctx, ksifile kf); static bool queueAddQuit(rsksictx ctx); static bool queueAddSignRequest(rsksictx ctx, ksifile kf, KSI_DataHash *root, unsigned level); static int sigblkFinishKSINoSignature(ksifile ksi, const char *reason); void *signer_thread(void *arg); static void __attribute__((format(printf, 2, 3))) report(rsksictx ctx, const char *errmsg, ...) { char buf[1024]; int r; va_list args; va_start(args, errmsg); r = vsnprintf(buf, sizeof(buf), errmsg, args); buf[sizeof(buf) - 1] = '\0'; va_end(args); if (ctx->logFunc == NULL) return; if (r > 0 && r < (int)sizeof(buf)) ctx->logFunc(ctx->usrptr, (uchar *)buf); else ctx->logFunc(ctx->usrptr, (uchar *)errmsg); } static void reportErr(rsksictx ctx, const char *const errmsg) { if (ctx->errFunc == NULL) goto done; ctx->errFunc(ctx->usrptr, (uchar *)errmsg); done: return; } static const char *level2str(int level) { switch (level) { case KSI_LOG_DEBUG: return "DEBUG"; case KSI_LOG_INFO: return "INFO"; case KSI_LOG_NOTICE: return "NOTICE"; case KSI_LOG_WARN: return "WARN"; case KSI_LOG_ERROR: return "ERROR"; default: return "UNKNOWN LOG LEVEL"; } } void reportKSIAPIErr(rsksictx ctx, ksifile ksi, const char *apiname, int ecode) { char errbuf[4096]; char ksi_errbuf[4096]; KSI_ERR_getBaseErrorMessage(ctx->ksi_ctx, ksi_errbuf, sizeof(ksi_errbuf), NULL, NULL); snprintf(errbuf, sizeof(errbuf), "%s[%s:%d]: %s (%s)", (ksi == NULL) ? (uchar *)"" : ksi->blockfilename, apiname, ecode, KSI_getErrorString(ecode), ksi_errbuf); errbuf[sizeof(errbuf) - 1] = '\0'; reportErr(ctx, errbuf); } void rsksisetErrFunc(rsksictx ctx, void (*func)(void *, uchar *), void *usrptr) { ctx->usrptr = usrptr; ctx->errFunc = func; } void rsksisetLogFunc(rsksictx ctx, void (*func)(void *, uchar *), void *usrptr) { ctx->usrptr = usrptr; ctx->logFunc = func; } static ksifile rsksifileConstruct(rsksictx ctx) { ksifile ksi = NULL; if ((ksi = calloc(1, sizeof(struct ksifile_s))) == NULL) goto done; ksi->ctx = ctx; ksi->hashAlg = ctx->hashAlg; ksi->blockTimeLimit = ctx->blockTimeLimit; ksi->blockSizeLimit = 1 << (ctx->effectiveBlockLevelLimit - 1); ksi->bKeepRecordHashes = ctx->bKeepRecordHashes; ksi->bKeepTreeHashes = ctx->bKeepTreeHashes; ksi->lastLeaf[0] = ctx->hashAlg; done: return ksi; } /* return the actual length in to-be-written octets of an integer */ static uint8_t tlvGetIntSize(uint64_t val) { uint8_t n = 0; while (val != 0) { val >>= 8; n++; } return n; } static int tlvWriteOctetString(FILE *f, const uint8_t *data, uint16_t len) { if (fwrite(data, len, 1, f) != 1) return RSGTE_IO; return 0; } static int tlvWriteHeader8(FILE *f, int flags, uint8_t tlvtype, int len) { unsigned char buf[2]; assert((flags & RSGT_TYPE_MASK) == 0); assert((tlvtype & RSGT_TYPE_MASK) == tlvtype); buf[0] = (flags & ~RSGT_FLAG_TLV16) | tlvtype; buf[1] = len & 0xff; return tlvWriteOctetString(f, buf, 2); } static int tlvWriteHeader16(FILE *f, int flags, uint16_t tlvtype, uint16_t len) { uint16_t typ; unsigned char buf[4]; assert((flags & RSGT_TYPE_MASK) == 0); assert((tlvtype >> 8 & RSGT_TYPE_MASK) == (tlvtype >> 8)); typ = ((flags | RSGT_FLAG_TLV16) << 8) | tlvtype; buf[0] = typ >> 8; buf[1] = typ & 0xff; buf[2] = (len >> 8) & 0xff; buf[3] = len & 0xff; return tlvWriteOctetString(f, buf, 4); } static int tlvGetHeaderSize(uint16_t tag, size_t size) { if (tag <= RSGT_TYPE_MASK && size <= 0xff) return 2; if ((tag >> 8) <= RSGT_TYPE_MASK && size <= 0xffff) return 4; return 0; } static int tlvWriteHeader(FILE *f, int flags, uint16_t tlvtype, uint16_t len) { int headersize = tlvGetHeaderSize(tlvtype, flags); if (headersize == 2) return tlvWriteHeader8(f, flags, tlvtype, len); else if (headersize == 4) return tlvWriteHeader16(f, flags, tlvtype, len); else return 0; } static int tlvWriteOctetStringTLV(FILE *f, int flags, uint16_t tlvtype, const uint8_t *data, uint16_t len) { if (tlvWriteHeader(f, flags, tlvtype, len) != 0) return RSGTE_IO; if (fwrite(data, len, 1, f) != 1) return RSGTE_IO; return 0; } static int tlvWriteInt64TLV(FILE *f, int flags, uint16_t tlvtype, uint64_t val) { unsigned char buf[8]; uint8_t count = tlvGetIntSize(val); uint64_t nTmp; if (tlvWriteHeader(f, flags, tlvtype, count) != 0) return RSGTE_IO; nTmp = val; for (int i = count - 1; i >= 0; i--) { buf[i] = 0xFF & nTmp; nTmp = nTmp >> 8; } if (fwrite(buf, count, 1, f) != 1) return RSGTE_IO; return 0; } static int tlvWriteHashKSI(ksifile ksi, uint16_t tlvtype, KSI_DataHash *rec) { int r; const unsigned char *imprint; size_t imprint_len; r = KSI_DataHash_getImprint(rec, &imprint, &imprint_len); if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_DataHash_getImprint", r); return r; } return tlvWriteOctetStringTLV(ksi->blockFile, 0, tlvtype, imprint, imprint_len); } static int tlvWriteBlockHdrKSI(ksifile ksi) { unsigned tlvlen; uint8_t hash_algo = ksi->hashAlg; int r; tlvlen = 2 + 1 /* hash algo TLV */ + 2 + KSI_getHashLength(ksi->hashAlg) /* iv */ + 2 + KSI_getHashLength(ksi->lastLeaf[0]) + 1; /* last hash */; /* write top-level TLV object block-hdr */ CHKr(tlvWriteHeader(ksi->blockFile, 0x00, 0x0901, tlvlen)); /* hash-algo */ CHKr(tlvWriteOctetStringTLV(ksi->blockFile, 0x00, 0x01, &hash_algo, 1)); /* block-iv */ CHKr(tlvWriteOctetStringTLV(ksi->blockFile, 0x00, 0x02, ksi->IV, KSI_getHashLength(ksi->hashAlg))); /* last-hash */ CHKr(tlvWriteOctetStringTLV(ksi->blockFile, 0x00, 0x03, ksi->lastLeaf, KSI_getHashLength(ksi->lastLeaf[0]) + 1)); done: return r; } static int tlvWriteKSISigLS12(FILE *outfile, size_t record_count, uchar *der, uint16_t lenDer) { int r = 0; int totalSize = 2 + tlvGetIntSize(record_count) + 4 + lenDer; CHKr(tlvWriteHeader(outfile, 0x00, 0x0904, totalSize)); CHKr(tlvWriteInt64TLV(outfile, 0x00, 0x01, record_count)); CHKr(tlvWriteOctetStringTLV(outfile, 0x00, 0x0905, der, lenDer)); done: return r; } static int tlvWriteNoSigLS12(FILE *outfile, size_t record_count, const KSI_DataHash *hash, const char *errorText) { int r = 0; int totalSize = 0; int noSigSize = 0; const unsigned char *imprint = NULL; size_t imprintLen = 0; KSI_DataHash_getImprint(hash, &imprint, &imprintLen); noSigSize = 2 + imprintLen + (errorText ? (2 + strlen(errorText) + 1) : 0); totalSize = 2 + tlvGetIntSize(record_count) + 2 + noSigSize; CHKr(tlvWriteHeader(outfile, 0x00, 0x0904, totalSize)); CHKr(tlvWriteInt64TLV(outfile, 0x00, 0x01, record_count)); CHKr(tlvWriteHeader(outfile, 0x00, 0x02, noSigSize)); CHKr(tlvWriteOctetStringTLV(outfile, 0x00, 0x01, imprint, imprintLen)); if (errorText) CHKr(tlvWriteOctetStringTLV(outfile, 0x00, 0x02, (uint8_t *)errorText, strlen(errorText) + 1)); done: return r; } static int tlvCreateMetadata( ksifile ksi, uint64_t record_index, const char *key, const char *value, unsigned char *buffer, size_t *len) { int r = 0; KSI_TlvElement *metadata = NULL, *attrib_tlv = NULL; KSI_Utf8String *key_tlv = NULL, *value_tlv = NULL; KSI_Integer *index_tlv = NULL; CHKr(KSI_TlvElement_new(&metadata)); metadata->ftlv.tag = 0x0911; CHKr(KSI_Integer_new(ksi->ctx->ksi_ctx, record_index, &index_tlv)); CHKr(KSI_TlvElement_setInteger(metadata, 0x01, index_tlv)); CHKr(KSI_TlvElement_new(&attrib_tlv)); attrib_tlv->ftlv.tag = 0x02; CHKr(KSI_Utf8String_new(ksi->ctx->ksi_ctx, key, strlen(key) + 1, &key_tlv)); CHKr(KSI_TlvElement_setUtf8String(attrib_tlv, 0x01, key_tlv)); CHKr(KSI_Utf8String_new(ksi->ctx->ksi_ctx, value, strlen(value) + 1, &value_tlv)); CHKr(KSI_TlvElement_setUtf8String(attrib_tlv, 0x02, value_tlv)); CHKr(KSI_TlvElement_setElement(metadata, attrib_tlv)); CHKr(KSI_TlvElement_serialize(metadata, buffer, 0xFFFF, len, 0)); done: if (metadata) KSI_TlvElement_free(metadata); if (attrib_tlv) KSI_TlvElement_free(attrib_tlv); if (key_tlv) KSI_Utf8String_free(key_tlv); if (value_tlv) KSI_Utf8String_free(value_tlv); if (index_tlv) KSI_Integer_free(index_tlv); return r; } #define KSI_FILE_AMOUNT_INC 32 static int rsksiExpandRegisterIfNeeded(rsksictx ctx, size_t inc) { int ret = RSGTE_INTERNAL; ksifile *tmp = NULL; if (ctx == NULL || inc == 0) { return RSGTE_INTERNAL; } if (ctx->ksiCount < ctx->ksiCapacity) { return RSGTE_SUCCESS; } /* If needed allocate memory for the buffer. */ tmp = (ksifile *)realloc(ctx->ksi, sizeof(ksifile) * (ctx->ksiCapacity + inc)); if (tmp == NULL) { ret = RSGTE_OOM; goto done; } /* Make sure that allocated pointers are all set to NULL. */ memset(tmp + ctx->ksiCapacity, 0, sizeof(ksifile) * inc); /* Update buffer capacity. */ ctx->ksiCapacity += inc; ctx->ksi = tmp; tmp = NULL; ret = RSGTE_SUCCESS; done: free(tmp); return ret; } static int rsksiRegisterKsiFile(rsksictx ctx, ksifile ksi) { int ret = RSGTE_INTERNAL; if (ctx == NULL || ksi == NULL) { return RSGTE_INTERNAL; } /* To be extra sure that ksifile buffer is initialized correctly, clear variables. */ if (ctx->ksi == NULL) { ctx->ksiCount = 0; ctx->ksiCapacity = 0; } ret = rsksiExpandRegisterIfNeeded(ctx, KSI_FILE_AMOUNT_INC); if (ret != RSGTE_SUCCESS) goto done; ctx->ksi[ctx->ksiCount] = ksi; ctx->ksiCount++; ret = RSGTE_SUCCESS; done: return ret; } static int rsksiDeregisterKsiFile(rsksictx ctx, ksifile ksi) { int ret = RSGTE_INTERNAL; size_t i = 0; if (ctx == NULL || ksi == NULL) { return RSGTE_INTERNAL; } for (i = 0; i < ctx->ksiCount; i++) { if (ctx->ksi[i] != NULL && ctx->ksi[i] == ksi) { size_t lastElement = ctx->ksiCount - 1; if (i != lastElement) { ctx->ksi[i] = ctx->ksi[lastElement]; } ctx->ksi[lastElement] = NULL; ctx->ksiCount--; ret = RSGTE_SUCCESS; goto done; } } done: return ret; } /* support for old platforms - graceful degrade */ #ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif /* read rsyslog log state file; if we cannot access it or the * contents looks invalid, we flag it as non-present (and thus * begin a new hash chain). * The context is initialized accordingly. */ static bool ksiReadStateFile(ksifile ksi) { int fd = -1; struct rsksistatefile sf; bool ret = false; fd = open((char *)ksi->statefilename, O_RDONLY | O_NOCTTY | O_CLOEXEC, 0600); if (fd == -1) goto done; if (read(fd, &sf, sizeof(sf)) != sizeof(sf)) goto done; if (strncmp(sf.hdr, "KSISTAT10", 9)) goto done; if (KSI_getHashLength(sf.hashID) != sf.lenHash || KSI_getHashLength(sf.hashID) > KSI_MAX_IMPRINT_LEN - 1) goto done; if (read(fd, ksi->lastLeaf + 1, sf.lenHash) != sf.lenHash) goto done; ksi->lastLeaf[0] = sf.hashID; ret = true; done: if (!ret) { memset(ksi->lastLeaf, 0, sizeof(ksi->lastLeaf)); ksi->lastLeaf[0] = ksi->hashAlg; } if (fd != -1) close(fd); return ret; } /* persist all information that we need to re-open and append * to a log signature file. */ static void ksiWwriteStateFile(ksifile ksi) { int fd; struct rsksistatefile sf; fd = open((char *)ksi->statefilename, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY | O_CLOEXEC, ksi->ctx->fCreateMode); if (fd == -1) goto done; if (ksi->ctx->fileUID != (uid_t)-1 || ksi->ctx->fileGID != (gid_t)-1) { /* we need to set owner/group */ if (fchown(fd, ksi->ctx->fileUID, ksi->ctx->fileGID) != 0) { report(ksi->ctx, "lmsig_ksi: chown for file '%s' failed: %s", ksi->statefilename, strerror(errno)); } } memcpy(sf.hdr, "KSISTAT10", 9); sf.hashID = ksi->hashAlg; sf.lenHash = KSI_getHashLength(ksi->lastLeaf[0]); /* if the write fails, we cannot do anything against that. We check * the condition just to keep the compiler happy. */ if (write(fd, &sf, sizeof(sf))) { }; if (write(fd, ksi->lastLeaf + 1, sf.lenHash)) { }; close(fd); done: return; } static int ksiCloseSigFile(ksifile ksi) { fclose(ksi->blockFile); ksi->blockFile = NULL; if (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS) queueAddCloseFile(ksi->ctx, ksi); ksiWwriteStateFile(ksi); return 0; } static int mkpath(char *path, mode_t mode, uid_t uid, gid_t gid) { if (path == NULL) return 1; for (char *p = strchr(path + 1, '/'); p; p = strchr(p + 1, '/')) { *p = '\0'; if (mkdir(path, mode) == 0) { if (uid != (uid_t)-1 || gid != (uid_t)-1) { if (chown(path, uid, gid)) { LogError(errno, RS_RET_IO_ERROR, "ksils12 signatures: could not change to " "configured owner - files may be unaccessible"); } } } else if (errno != EEXIST) { *p = '/'; return -1; } *p = '/'; } return 0; } static FILE *ksiCreateFile( rsksictx ctx, const char *path, uid_t uid, gid_t gid, int mode, bool lockit, const char *header) { int fd = -1; struct stat stat_st; FILE *f = NULL; struct flock lock = {F_WRLCK, SEEK_SET, 0, 0, 0}; if (path == NULL) return NULL; if (mkpath((char *)path, ctx->fDirCreateMode, ctx->dirUID, ctx->dirGID) != 0) { report(ctx, "ksiCreateFile: mkpath failed for %s", path); goto done; } fd = open(path, O_RDWR | O_APPEND | O_NOCTTY | O_CLOEXEC, 0600); if (fd == -1) { fd = open(path, O_RDWR | O_CREAT | O_NOCTTY | O_CLOEXEC, mode); if (fd == -1) { report(ctx, "creating file '%s' failed: %s", path, strerror(errno)); goto done; } if (uid != (uid_t)-1 || gid != (gid_t)-1) { if (fchown(fd, uid, gid) != 0) { report(ctx, "lmsig_ksi: chown for file '%s' failed: %s", path, strerror(errno)); } } } if (lockit && fcntl(fd, F_SETLK, &lock) != 0) report(ctx, "fcntl error: %s", strerror(errno)); f = fdopen(fd, "a"); if (f == NULL) { report(ctx, "fdopen for '%s' failed: %s", path, strerror(errno)); goto done; } setvbuf(f, NULL, _IOFBF, KSI_BUF_SIZE); if (fstat(fd, &stat_st) == -1) { reportErr(ctx, "ksiOpenSigFile: can not stat file"); goto done; } if (stat_st.st_size == 0 && header != NULL) { if (fwrite(header, strlen(header), 1, f) != 1) { report(ctx, "ksiOpenSigFile: fwrite for file %s failed: %s", path, strerror(errno)); goto done; } } /* Write header immediately as when using dynafile it is possible that the same * file is opened 2x in sequence (caused by small dynafile cache where files are * frequently closed and reopened). If the header already exists double header is * not written. The content of the file is ordered by signer thread. */ fflush(f); done: return f; } static void handle_ksi_config(rsksictx ctx, KSI_AsyncService *as, KSI_Config *config) { int res = KSI_UNKNOWN_ERROR; KSI_Integer *intValue = NULL; if (KSI_Config_getMaxRequests(config, &intValue) == KSI_OK && intValue != NULL) { ctx->max_requests = KSI_Integer_getUInt64(intValue); report(ctx, "KSI gateway has reported a max requests value of %llu", (long long unsigned)ctx->max_requests); if (as) { /* libksi expects size_t. */ size_t optValue = 0; optValue = ctx->max_requests; res = KSI_AsyncService_setOption(as, KSI_ASYNC_OPT_MAX_REQUEST_COUNT, (void *)optValue); if (res != KSI_OK) reportKSIAPIErr(ctx, NULL, "KSI_AsyncService_setOption(max_request)", res); optValue = 3 * ctx->max_requests * ctx->blockSigTimeout; KSI_AsyncService_setOption(as, KSI_ASYNC_OPT_REQUEST_CACHE_SIZE, (void *)optValue); } } intValue = NULL; if (KSI_Config_getMaxLevel(config, &intValue) == KSI_OK && intValue != NULL) { uint64_t newLevel = 0; newLevel = KSI_Integer_getUInt64(intValue); report(ctx, "KSI gateway has reported a max level value of %llu", (long long unsigned)newLevel); newLevel = MIN(newLevel, ctx->blockLevelLimit); if (ctx->effectiveBlockLevelLimit != newLevel) { report(ctx, "Changing the configured block level limit from %llu to %llu", (long long unsigned)ctx->effectiveBlockLevelLimit, (long long unsigned)newLevel); ctx->effectiveBlockLevelLimit = newLevel; } else if (newLevel < 2) { report(ctx, "KSI gateway has reported an invalid level limit value (%llu), " "plugin disabled", (long long unsigned)newLevel); ctx->disabled = true; } } intValue = NULL; if (KSI_Config_getAggrPeriod(config, &intValue) == KSI_OK && intValue != NULL) { uint64_t newThreadSleep = 0; newThreadSleep = KSI_Integer_getUInt64(intValue); report(ctx, "KSI gateway has reported an aggregation period value of %llu", (long long unsigned)newThreadSleep); newThreadSleep = MIN(newThreadSleep, ctx->threadSleepms); if (ctx->threadSleepms != newThreadSleep) { report(ctx, "Changing async signer thread sleep from %llu to %llu", (long long unsigned)ctx->threadSleepms, (long long unsigned)newThreadSleep); ctx->threadSleepms = newThreadSleep; } } } static int isAggrConfNeeded(rsksictx ctx) { time_t now = 0; now = time(NULL); if ((uint64_t)ctx->tConfRequested + ctx->confInterval <= (uint64_t)now || ctx->tConfRequested == 0) { ctx->tConfRequested = now; return 1; } return 0; } /* note: if file exists, the last hash for chaining must * be read from file. */ static int ksiOpenSigFile(ksifile ksi) { int r = 0, tmpRes = 0; const char *header; FILE *signatureFile = NULL; if (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS) header = LS12_BLOCKFILE_HEADER; else header = LS12_FILE_HEADER; ksi->blockFile = ksiCreateFile(ksi->ctx, (char *)ksi->blockfilename, ksi->ctx->fileUID, ksi->ctx->fileGID, ksi->ctx->fCreateMode, true, header); if (ksi->blockFile == NULL) { r = RSGTE_IO; goto done; } /* create the file for ksi signatures if needed */ if (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS) { signatureFile = ksiCreateFile(ksi->ctx, (char *)ksi->ksifilename, ksi->ctx->fileUID, ksi->ctx->fileGID, ksi->ctx->fCreateMode, true, LS12_SIGFILE_HEADER); if (signatureFile == NULL) { r = RSGTE_IO; goto done; } ksi->sigFile = signatureFile; queueAddNewFile(ksi->ctx, ksi); } /* we now need to obtain the last previous hash, so that * we can continue the hash chain. We do not check for error * as a state file error can be recovered by graceful degredation. */ ksiReadStateFile(ksi); if (ksi->ctx->syncMode == LOGSIG_SYNCHRONOUS) { if (isAggrConfNeeded(ksi->ctx)) { KSI_Config *config = NULL; tmpRes = KSI_receiveAggregatorConfig(ksi->ctx->ksi_ctx, &config); if (tmpRes == KSI_OK) { handle_ksi_config(ksi->ctx, NULL, config); } else { reportKSIAPIErr(ksi->ctx, NULL, "KSI_receiveAggregatorConfig", tmpRes); } KSI_Config_free(config); } } done: return r; } /* * As of some Linux and security expert I spoke to, /dev/urandom * provides very strong random numbers, even if it runs out of * entropy. As far as he knew, this is save for all applications * (and he had good proof that I currently am not permitted to * reproduce). -- rgerhards, 2013-03-04 */ static void seedIVKSI(ksifile ksi) { int hashlen; int fd; const char *rnd_device = ksi->ctx->random_source ? ksi->ctx->random_source : "/dev/urandom"; hashlen = KSI_getHashLength(ksi->hashAlg); ksi->IV = malloc(hashlen); /* do NOT zero-out! */ /* * If /dev/urandom is unavailable, the current memory content is used as a * weak fallback for random data. This is a theoretical case, as this * library only supports Linux, where /dev/urandom is expected to be * reliably available. */ if ((fd = open(rnd_device, O_RDONLY)) >= 0) { if (read(fd, ksi->IV, hashlen) == hashlen) { }; /* keep compiler happy */ close(fd); } } static int create_signer_thread(rsksictx ctx) { int r; if (ctx->signer_state != SIGNER_STARTED) { if ((r = pthread_mutex_init(&ctx->module_lock, 0))) report(ctx, "pthread_mutex_init: %s", strerror(r)); ctx->signer_queue = ProtectedQueue_new(10); ctx->signer_state = SIGNER_INIT; if ((r = pthread_create(&ctx->signer_thread, NULL, signer_thread, ctx))) { report(ctx, "pthread_create: %s", strerror(r)); ctx->signer_state = SIGNER_IDLE; return RSGTE_INTERNAL; } /* Lock until init. */ while (*((volatile int *)&ctx->signer_state) & SIGNER_INIT); if (ctx->signer_state != SIGNER_STARTED) { return RSGTE_INTERNAL; } } return RSGTE_SUCCESS; } rsksictx rsksiCtxNew(void) { rsksictx ctx; ctx = calloc(1, sizeof(struct rsksictx_s)); KSI_CTX_new(&ctx->ksi_ctx); // TODO: error check (probably via a generic macro?) ctx->hasher = NULL; ctx->hashAlg = KSI_getHashAlgorithmByName("default"); ctx->blockTimeLimit = 0; ctx->bKeepTreeHashes = false; ctx->bKeepRecordHashes = true; ctx->max_requests = (1 << 8); ctx->blockSigTimeout = 10; ctx->confInterval = 3600; ctx->tConfRequested = 0; ctx->threadSleepms = 1000; ctx->errFunc = NULL; ctx->usrptr = NULL; ctx->fileUID = -1; ctx->fileGID = -1; ctx->dirUID = -1; ctx->dirGID = -1; ctx->fCreateMode = 0644; ctx->fDirCreateMode = 0700; #if KSI_SDK_VER_MAJOR == 3 && KSI_SDK_VER_MINOR < 22 ctx->roundCount = 0; ctx->bRoundLock = 0; #endif ctx->syncMode = LOGSIG_SYNCHRONOUS; ctx->signer_state = SIGNER_IDLE; ctx->disabled = false; ctx->ksi = NULL; /*if (pthread_mutex_init(&ctx->module_lock, 0)) report(ctx, "pthread_mutex_init: %s", strerror(errno)); ctx->signer_queue = ProtectedQueue_new(10);*/ /* Creating a thread this way works only in daemon mode but not when being run interactively when not forked */ /*ret = pthread_atfork(NULL, NULL, create_signer_thread); if (ret != 0) report(ctx, "pthread_atfork error: %s", strerror(ret));*/ return ctx; } static int rsksiStreamLogger(void *logCtx, int logLevel, const char *message) { char time_buf[32]; struct tm *tm_info; time_t timer; FILE *f = (FILE *)logCtx; timer = time(NULL); tm_info = localtime(&timer); if (tm_info == NULL) { return KSI_UNKNOWN_ERROR; } if (f != NULL) { flockfile(f); /* for thread safety */ if (strftime(time_buf, sizeof(time_buf), "%d.%m.%Y %H:%M:%S", tm_info)) { if (fprintf(f, "%s [%s] %lu - %s\n", level2str(logLevel), time_buf, pthread_self(), message) > 0) { } } funlockfile(f); } return KSI_OK; } int rsksiInitModule(rsksictx ctx) { int res = 0; if (ctx->debugFileName != NULL) { ctx->debugFile = fopen(ctx->debugFileName, "w"); if (ctx->debugFile) { res = KSI_CTX_setLoggerCallback(ctx->ksi_ctx, rsksiStreamLogger, ctx->debugFile); if (res != KSI_OK) reportKSIAPIErr(ctx, NULL, "Unable to set logger callback", res); res = KSI_CTX_setLogLevel(ctx->ksi_ctx, ctx->debugLevel); if (res != KSI_OK) reportKSIAPIErr(ctx, NULL, "Unable to set log level", res); } else { report(ctx, "Could not open logfile %s: %s", ctx->debugFileName, strerror(errno)); } } KSI_CTX_setOption(ctx->ksi_ctx, KSI_OPT_AGGR_HMAC_ALGORITHM, (void *)((size_t)ctx->hmacAlg)); return create_signer_thread(ctx); } /* either returns ksifile object or NULL if something went wrong */ ksifile rsksiCtxOpenFile(rsksictx ctx, unsigned char *logfn) { int ret = RSGTE_INTERNAL; ksifile ksi; char fn[MAXFNAME + 1]; if (ctx->disabled) return NULL; pthread_mutex_lock(&ctx->module_lock); /* The thread cannot be be created in rsksiCtxNew because in daemon mode the process forks after rsksiCtxNew and the thread disappears */ if (ctx->signer_state != SIGNER_STARTED) { ret = rsksiInitModule(ctx); if (ret != RSGTE_SUCCESS) { report(ctx, "Unable to init. KSI module, signing service disabled"); ctx->disabled = true; pthread_mutex_unlock(&ctx->module_lock); return NULL; } } if ((ksi = rsksifileConstruct(ctx)) == NULL) goto done; snprintf(fn, sizeof(fn), "%s.ksistate", logfn); fn[MAXFNAME] = '\0'; /* be on safe side */ ksi->statefilename = (uchar *)strdup(fn); if (ctx->syncMode == LOGSIG_ASYNCHRONOUS) { /* filename for blocks of hashes*/ snprintf(fn, sizeof(fn), "%s%s", logfn, blockFileSuffix); fn[MAXFNAME] = '\0'; /* be on safe side */ ksi->blockfilename = (uchar *)strdup(fn); /* filename for KSI signatures*/ snprintf(fn, sizeof(fn), "%s%s", logfn, sigFileSuffix); fn[MAXFNAME] = '\0'; /* be on safe side */ ksi->ksifilename = (uchar *)strdup(fn); } else if (ctx->syncMode == LOGSIG_SYNCHRONOUS) { snprintf(fn, sizeof(fn), "%s%s", logfn, ls12FileSuffix); fn[MAXFNAME] = '\0'; /* be on safe side */ ksi->blockfilename = (uchar *)strdup(fn); } if (ksiOpenSigFile(ksi) != 0) { reportErr(ctx, "signature file open failed"); /* Free memory */ free(ksi); ksi = NULL; } done: /* Register ksi file in rsksictx for keeping track of block timeouts. */ rsksiRegisterKsiFile(ctx, ksi); pthread_mutex_unlock(&ctx->module_lock); return ksi; } /* Returns RSGTE_SUCCESS on success, error code otherwise. If algo is unknown or * is not trusted, default hash function is used. */ int rsksiSetHashFunction(rsksictx ctx, char *algName) { if (ctx == NULL || algName == NULL) { return RSGTE_INTERNAL; } int r, id = KSI_getHashAlgorithmByName(algName); if (!KSI_isHashAlgorithmSupported(id)) { report(ctx, "Hash function '%s' is not supported - using default", algName); ctx->hashAlg = KSI_getHashAlgorithmByName("default"); } else { if (!KSI_isHashAlgorithmTrusted(id)) { report(ctx, "Hash function '%s' is not trusted - using default", algName); ctx->hashAlg = KSI_getHashAlgorithmByName("default"); } else ctx->hashAlg = id; } if ((r = KSI_DataHasher_open(ctx->ksi_ctx, ctx->hashAlg, &ctx->hasher)) != KSI_OK) { reportKSIAPIErr(ctx, NULL, "KSI_DataHasher_open", r); ctx->disabled = true; return r; } return RSGTE_SUCCESS; } int rsksiSetHmacFunction(rsksictx ctx, char *algName) { int id = KSI_getHashAlgorithmByName(algName); if (!KSI_isHashAlgorithmSupported(id)) { report(ctx, "HMAC function '%s' is not supported - using default", algName); ctx->hmacAlg = KSI_getHashAlgorithmByName("default"); } else { if (!KSI_isHashAlgorithmTrusted(id)) { report(ctx, "HMAC function '%s' is not trusted - using default", algName); ctx->hmacAlg = KSI_getHashAlgorithmByName("default"); } else ctx->hmacAlg = id; } return 0; } int rsksifileDestruct(ksifile ksi) { int r = 0; rsksictx ctx = NULL; if (ksi == NULL) return RSGTE_INTERNAL; pthread_mutex_lock(&ksi->ctx->module_lock); ctx = ksi->ctx; /* Deregister ksifile so it is not used by signer thread anymore. Note that files are not closed yet! */ rsksiDeregisterKsiFile(ctx, ksi); if (!ksi->disabled && ksi->bInBlk) { sigblkAddMetadata(ksi, blockCloseReason, "Block closed due to file closure."); r = sigblkFinishKSI(ksi); } /* Note that block file is closed immediately but signature file will be closed * by the signer thread scheduled by signer thread work queue. */ if (!ksi->disabled) r = ksiCloseSigFile(ksi); free(ksi->blockfilename); free(ksi->statefilename); free(ksi->ksifilename); free(ksi); pthread_mutex_unlock(&ctx->module_lock); return r; } /* This can only be used when signer thread has terminated or within the thread. */ static void rsksifileForceFree(ksifile ksi) { if (ksi == NULL) return; if (ksi->sigFile != NULL) fclose(ksi->sigFile); if (ksi->blockFile != NULL) fclose(ksi->blockFile); free(ksi->blockfilename); free(ksi->statefilename); free(ksi->ksifilename); free(ksi); return; } /* This can only be used when signer thread has terminated or within the thread. */ static void rsksictxForceFreeSignatures(rsksictx ctx) { size_t i = 0; if (ctx == NULL || ctx->ksi == NULL) return; for (i = 0; i < ctx->ksiCount; i++) { if (ctx->ksi[i] != NULL) { rsksifileForceFree(ctx->ksi[i]); ctx->ksi[i] = NULL; } } ctx->ksiCount = 0; return; } /* This can only be used when signer thread has terminated or within the thread. */ static int rsksictxForceCloseWithoutSig(rsksictx ctx, const char *reason) { size_t i = 0; if (ctx == NULL || ctx->ksi == NULL) return RSGTE_INTERNAL; for (i = 0; i < ctx->ksiCount; i++) { if (ctx->ksi[i] != NULL) { int ret = RSGTE_INTERNAL; /* Only if block contains records, create metadata, close the block and add * no signature marker. Closing block without record will produce redundant * blocks that needs to be signed afterward. */ if (ctx->ksi[i]->nRecords > 0) { ret = sigblkFinishKSINoSignature(ctx->ksi[i], reason); if (ret != RSGTE_SUCCESS) return ret; } /* Free files and remove object from the list. */ rsksifileForceFree(ctx->ksi[i]); ctx->ksi[i] = NULL; } } ctx->ksiCount = 0; return RSGTE_SUCCESS; } void rsksiCtxDel(rsksictx ctx) { if (ctx == NULL) return; /* Note that even in sync. mode signer thread is created and needs to be closed * correctly. */ if (ctx->signer_state == SIGNER_STARTED) { queueAddQuit(ctx); /* Wait until thread closes to be able to safely free the resources. */ pthread_join(ctx->signer_thread, NULL); ProtectedQueue_free(ctx->signer_queue); pthread_mutex_destroy(&ctx->module_lock); } free(ctx->aggregatorUri); free(ctx->aggregatorId); free(ctx->aggregatorKey); free(ctx->debugFileName); if (ctx->random_source) free(ctx->random_source); KSI_DataHasher_free(ctx->hasher); KSI_CTX_free(ctx->ksi_ctx); if (ctx->debugFile != NULL) fclose(ctx->debugFile); /* After signer thread is terminated there should be no open signature files, * but to be extra sure that all files are closed, recheck the list of opened * signature files. */ rsksictxForceFreeSignatures(ctx); free(ctx->ksi); free(ctx); } /* new sigblk is initialized, but maybe in existing ctx */ void sigblkInitKSI(ksifile ksi) { if (ksi == NULL) goto done; seedIVKSI(ksi); memset(ksi->roots, 0, sizeof(ksi->roots)); ksi->nRoots = 0; ksi->nRecords = 0; ksi->bInBlk = 1; ksi->blockStarted = time(NULL); ksi->blockSizeLimit = 1 << (ksi->ctx->effectiveBlockLevelLimit - 1); /* flush the optional debug file when starting a new block */ if (ksi->ctx->debugFile != NULL) fflush(ksi->ctx->debugFile); done: return; } int sigblkCreateMask(ksifile ksi, KSI_DataHash **m) { int r = 0; CHKr(KSI_DataHasher_reset(ksi->ctx->hasher)); CHKr(KSI_DataHasher_add(ksi->ctx->hasher, ksi->lastLeaf, KSI_getHashLength(ksi->lastLeaf[0]) + 1)); CHKr(KSI_DataHasher_add(ksi->ctx->hasher, ksi->IV, KSI_getHashLength(ksi->hashAlg))); CHKr(KSI_DataHasher_close(ksi->ctx->hasher, m)); done: if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_DataHasher", r); r = RSGTE_HASH_CREATE; } return r; } int sigblkCreateHash(ksifile ksi, KSI_DataHash **out, const uchar *rec, const size_t len) { int r = 0; CHKr(KSI_DataHasher_reset(ksi->ctx->hasher)); CHKr(KSI_DataHasher_add(ksi->ctx->hasher, rec, len)); CHKr(KSI_DataHasher_close(ksi->ctx->hasher, out)); done: if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_DataHasher", r); r = RSGTE_HASH_CREATE; } return r; } int sigblkHashTwoNodes(ksifile ksi, KSI_DataHash **out, KSI_DataHash *left, KSI_DataHash *right, uint8_t level) { int r = 0; CHKr(KSI_DataHasher_reset(ksi->ctx->hasher)); CHKr(KSI_DataHasher_addImprint(ksi->ctx->hasher, left)); CHKr(KSI_DataHasher_addImprint(ksi->ctx->hasher, right)); CHKr(KSI_DataHasher_add(ksi->ctx->hasher, &level, 1)); CHKr(KSI_DataHasher_close(ksi->ctx->hasher, out)); done: if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_DataHash_create", r); r = RSGTE_HASH_CREATE; } return r; } int sigblkAddMetadata(ksifile ksi, const char *key, const char *value) { unsigned char buffer[0xFFFF]; size_t encoded_size = 0; int ret = 0; tlvCreateMetadata(ksi, ksi->nRecords, key, value, buffer, &encoded_size); sigblkAddLeaf(ksi, buffer, encoded_size, true); return ret; } int sigblkAddRecordKSI(ksifile ksi, const uchar *rec, const size_t len) { int ret = 0; if (ksi == NULL || ksi->disabled) return 0; pthread_mutex_lock(&ksi->ctx->module_lock); if ((ret = sigblkAddLeaf(ksi, rec, len, false)) != 0) goto done; if (ksi->nRecords == ksi->blockSizeLimit) { sigblkFinishKSI(ksi); sigblkInitKSI(ksi); } done: pthread_mutex_unlock(&ksi->ctx->module_lock); return ret; } int sigblkAddLeaf(ksifile ksi, const uchar *leafData, const size_t leafLength, bool metadata) { KSI_DataHash *mask, *leafHash, *treeNode, *tmpTreeNode; uint8_t j; const unsigned char *pTmp; size_t len; int r = 0; if (ksi == NULL || ksi->disabled) goto done; CHKr(sigblkCreateMask(ksi, &mask)); CHKr(sigblkCreateHash(ksi, &leafHash, leafData, leafLength)); if (ksi->nRecords == 0) tlvWriteBlockHdrKSI(ksi); /* metadata record has to be written into the block file too*/ if (metadata) tlvWriteOctetString(ksi->blockFile, leafData, leafLength); if (ksi->bKeepRecordHashes) tlvWriteHashKSI(ksi, 0x0902, leafHash); /* normal leaf and metadata record are hashed in different order */ if (!metadata) { /* hash leaf */ if ((r = sigblkHashTwoNodes(ksi, &treeNode, mask, leafHash, 1)) != 0) goto done; } else { if ((r = sigblkHashTwoNodes(ksi, &treeNode, leafHash, mask, 1)) != 0) goto done; } /* persists x here if Merkle tree needs to be persisted! */ if (ksi->bKeepTreeHashes) tlvWriteHashKSI(ksi, 0x0903, treeNode); KSI_DataHash_getImprint(treeNode, &pTmp, &len); memcpy(ksi->lastLeaf, pTmp, len); for (j = 0; j < ksi->nRoots; ++j) { if (ksi->roots[j] == NULL) { ksi->roots[j] = treeNode; treeNode = NULL; break; } else if (treeNode != NULL) { /* hash interim node */ tmpTreeNode = treeNode; r = sigblkHashTwoNodes(ksi, &treeNode, ksi->roots[j], tmpTreeNode, j + 2); KSI_DataHash_free(ksi->roots[j]); ksi->roots[j] = NULL; KSI_DataHash_free(tmpTreeNode); if (r != 0) goto done; if (ksi->bKeepTreeHashes) tlvWriteHashKSI(ksi, 0x0903, treeNode); } } if (treeNode != NULL) { /* new level, append "at the top" */ ksi->roots[ksi->nRoots] = treeNode; ++ksi->nRoots; assert(ksi->nRoots < MAX_ROOTS); treeNode = NULL; } ++ksi->nRecords; /* cleanup (x is cleared as part of the roots array) */ KSI_DataHash_free(mask); KSI_DataHash_free(leafHash); done: return r; } static int sigblkCheckTimeOut(rsksictx ctx) { int ret = RSGTE_INTERNAL; time_t now; char buf[KSI_BUF_SIZE]; size_t i = 0; if (ctx == NULL) { return RSGTE_INTERNAL; } pthread_mutex_lock(&ctx->module_lock); if (ctx->ksi == NULL || ctx->disabled || !ctx->blockTimeLimit) { ret = RSGTE_SUCCESS; goto done; } now = time(NULL); for (i = 0; i < ctx->ksiCount; i++) { ksifile ksi = ctx->ksi[i]; if (ksi == NULL) continue; /* To avoide unexpected crash. */ if (!ksi->bInBlk) continue; /* Not inside a block, nothing to close nor sign. */ if ((time_t)(ksi->blockStarted + ctx->blockTimeLimit) > now) continue; snprintf(buf, KSI_BUF_SIZE, "Block closed due to reaching time limit %d", ctx->blockTimeLimit); sigblkAddMetadata(ksi, blockCloseReason, buf); sigblkFinishKSI(ksi); sigblkInitKSI(ksi); } done: pthread_mutex_unlock(&ctx->module_lock); return ret; } static int sigblkSign(ksifile ksi, KSI_DataHash *hash, int level) { unsigned char *der = NULL; size_t lenDer = 0; int r = KSI_OK; int ret = 0; KSI_Signature *sig = NULL; /* Sign the root hash. */ r = KSI_Signature_signAggregated(ksi->ctx->ksi_ctx, hash, level, &sig); if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_Signature_createAggregated", r); ret = 1; goto signing_done; } /* Serialize Signature. */ r = KSI_Signature_serialize(sig, &der, &lenDer); if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "KSI_Signature_serialize", r); ret = 1; lenDer = 0; goto signing_done; } signing_done: /* if signing failed the signature will be written as zero size */ if (r == KSI_OK) { r = tlvWriteKSISigLS12(ksi->blockFile, ksi->nRecords, der, lenDer); if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "tlvWriteKSISigLS12", r); ret = 1; } } else r = tlvWriteNoSigLS12(ksi->blockFile, ksi->nRecords, hash, KSI_getErrorString(r)); if (r != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "tlvWriteBlockSigKSI", r); ret = 1; } if (sig != NULL) KSI_Signature_free(sig); if (der != NULL) KSI_free(der); return ret; } unsigned sigblkCalcLevel(unsigned leaves) { unsigned level = 0; unsigned c = leaves; while (c > 1) { level++; c >>= 1; } if (1 << level < (int)leaves) level++; return level; } static int sigblkFinishTree(ksifile ksi, KSI_DataHash **hsh) { int ret = RSGTE_INTERNAL; KSI_DataHash *root = NULL; KSI_DataHash *rootDel = NULL; int8_t j = 0; if (ksi == NULL || hsh == NULL) { goto done; } if (ksi->nRecords == 0) { ret = RSGTE_SUCCESS; goto done; } root = NULL; for (j = 0; j < ksi->nRoots; ++j) { if (root == NULL) { root = ksi->roots[j]; ksi->roots[j] = NULL; } else if (ksi->roots[j] != NULL) { rootDel = root; root = NULL; ret = sigblkHashTwoNodes(ksi, &root, ksi->roots[j], rootDel, j + 2); KSI_DataHash_free(ksi->roots[j]); ksi->roots[j] = NULL; KSI_DataHash_free(rootDel); rootDel = NULL; if (ksi->bKeepTreeHashes) { tlvWriteHashKSI(ksi, 0x0903, root); } if (ret != KSI_OK) goto done; /* checks sigblkHashTwoNodes() result! */ } } *hsh = root; root = NULL; ret = RSGTE_SUCCESS; done: KSI_DataHash_free(root); KSI_DataHash_free(rootDel); return ret; } int sigblkFinishKSI(ksifile ksi) { KSI_DataHash *root = NULL; int ret = RSGTE_INTERNAL; unsigned level = 0; if (ksi == NULL) { goto done; } if (ksi->nRecords == 0) { ret = RSGTE_SUCCESS; goto done; } ret = sigblkFinishTree(ksi, &root); if (ret != RSGTE_SUCCESS) goto done; // Multiplying leaves count by 2 to account for blinding masks level = sigblkCalcLevel(2 * ksi->nRecords); // in case of async mode we append the root hash to signer queue if (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS) { ret = tlvWriteNoSigLS12(ksi->blockFile, ksi->nRecords, root, NULL); if (ret != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "tlvWriteNoSigLS12", ret); goto done; } queueAddSignRequest(ksi->ctx, ksi, root, level); root = NULL; } else { sigblkSign(ksi, root, level); } ret = RSGTE_SUCCESS; done: KSI_DataHash_free(root); free(ksi->IV); ksi->IV = NULL; ksi->bInBlk = 0; return ret; } static int sigblkFinishKSINoSignature(ksifile ksi, const char *reason) { KSI_DataHash *root = NULL; int ret = RSGTE_INTERNAL; if (ksi == NULL || ksi->ctx == NULL || (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS && ksi->sigFile == NULL) || ksi->blockFile == NULL || reason == NULL) { goto done; } ret = sigblkAddMetadata(ksi, blockCloseReason, reason); if (ret != RSGTE_SUCCESS) goto done; ret = sigblkFinishTree(ksi, &root); if (ret != RSGTE_SUCCESS) goto done; ret = tlvWriteNoSigLS12(ksi->blockFile, ksi->nRecords, root, reason); if (ret != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "tlvWriteNoSigLS12", ret); goto done; } if (ksi->ctx->syncMode == LOGSIG_ASYNCHRONOUS) { ret = tlvWriteNoSigLS12(ksi->sigFile, ksi->nRecords, root, reason); if (ret != KSI_OK) { reportKSIAPIErr(ksi->ctx, ksi, "tlvWriteNoSigLS12", ret); goto done; } } ret = RSGTE_SUCCESS; done: KSI_DataHash_free(root); free(ksi->IV); ksi->IV = NULL; ksi->bInBlk = 0; return ret; } int rsksiSetAggregator(rsksictx ctx, char *uri, char *loginid, char *key) { int r; char *strTmp, *strTmpUri; /* only use the strings if they are not empty */ ctx->aggregatorUri = (uri != NULL && strlen(uri) != 0) ? strdup(uri) : NULL; ctx->aggregatorId = (loginid != NULL && strlen(loginid) != 0) ? strdup(loginid) : NULL; ctx->aggregatorKey = (key != NULL && strlen(key) != 0) ? strdup(key) : NULL; /* split the URI string up for possible HA endpoints */ strTmp = ctx->aggregatorUri; while ((strTmpUri = strsep(&strTmp, "|")) != NULL) { if (ctx->aggregatorEndpointCount >= KSI_CTX_HA_MAX_SUBSERVICES) { report(ctx, "Maximum number (%d) of service endoints reached, ignoring endpoint: %s", KSI_CTX_HA_MAX_SUBSERVICES, strTmpUri); } else { ctx->aggregatorEndpoints[ctx->aggregatorEndpointCount] = strTmpUri; ctx->aggregatorEndpointCount++; } } r = KSI_CTX_setAggregator(ctx->ksi_ctx, ctx->aggregatorUri, ctx->aggregatorId, ctx->aggregatorKey); if (r != KSI_OK) { ctx->disabled = true; reportKSIAPIErr(ctx, NULL, "KSI_CTX_setAggregator", r); return KSI_INVALID_ARGUMENT; } return r; } int rsksiSetDebugFile(rsksictx ctx, char *val) { if (!val) return KSI_INVALID_ARGUMENT; ctx->debugFileName = strdup(val); return KSI_OK; } static bool add_queue_item( rsksictx ctx, QITEM_type type, KSI_DataHash *root, FILE *sigFile, uint64_t intarg1, uint64_t intarg2) { QueueItem *qi = (QueueItem *)malloc(sizeof(QueueItem)); if (!qi) { ctx->disabled = true; return false; } qi->root = root; qi->file = sigFile; qi->type = type; qi->status = QITEM_WAITING; qi->intarg1 = intarg1; qi->intarg2 = intarg2; qi->respHandle = NULL; qi->ksi_status = KSI_UNKNOWN_ERROR; qi->request_time = time(NULL); if (ProtectedQueue_addItem(ctx->signer_queue, qi) == false) { ctx->disabled = true; free(qi); return false; } return true; } static bool queueAddCloseFile(rsksictx ctx, ksifile ksi) { return add_queue_item(ctx, QITEM_CLOSE_FILE, NULL, ksi->sigFile, 0, 0); } static bool queueAddNewFile(rsksictx ctx, ksifile ksi) { return add_queue_item(ctx, QITEM_NEW_FILE, NULL, ksi->sigFile, time(NULL) + ctx->blockTimeLimit, 0); } static bool queueAddQuit(rsksictx ctx) { return add_queue_item(ctx, QITEM_QUIT, NULL, NULL, 0, 0); } static bool queueAddSignRequest(rsksictx ctx, ksifile ksi, KSI_DataHash *root, unsigned level) { return add_queue_item(ctx, QITEM_SIGNATURE_REQUEST, root, ksi->sigFile, ksi->nRecords, level); } static bool save_response(rsksictx ctx, FILE *outfile, QueueItem *item) { bool ret = false; KSI_Signature *sig = NULL; unsigned char *raw = NULL; size_t raw_len; int res = KSI_OK; if (item->respHandle != NULL && item->ksi_status == KSI_OK) { CHECK_KSI_API(KSI_AsyncHandle_getSignature(item->respHandle, &sig), ctx, "KSI_AsyncHandle_getSignature"); CHECK_KSI_API(KSI_Signature_serialize(sig, &raw, &raw_len), ctx, "KSI_Signature_serialize"); tlvWriteKSISigLS12(outfile, item->intarg1, raw, raw_len); KSI_free(raw); } else { tlvWriteNoSigLS12(outfile, item->intarg1, item->root, KSI_getErrorString(item->ksi_status)); } ret = true; cleanup: if (res != KSI_OK) tlvWriteNoSigLS12(outfile, item->intarg1, item->root, KSI_getErrorString(res)); KSI_Signature_free(sig); return ret; } static KSI_DataHash *clone_hash(KSI_CTX *ksi_ctx, const KSI_DataHash *hash) { int res = KSI_UNKNOWN_ERROR; const unsigned char *imprint = NULL; size_t imprint_len = 0; KSI_DataHash *tmp = NULL; if (hash == NULL) return NULL; res = KSI_DataHash_getImprint(hash, &imprint, &imprint_len); if (res != KSI_OK) return NULL; res = KSI_DataHash_fromImprint(ksi_ctx, imprint, imprint_len, &tmp); if (res != KSI_OK) return NULL; return tmp; } static bool process_requests_async(rsksictx ctx, KSI_CTX *ksi_ctx, KSI_AsyncService *as) { bool ret = false; QueueItem *item = NULL; int res = KSI_OK, tmpRes; KSI_AsyncHandle *reqHandle = NULL; KSI_AsyncHandle *respHandle = NULL; KSI_DataHash *clonedHash = NULL; KSI_AggregationReq *req = NULL; KSI_Config *config = NULL; KSI_Integer *level; long extError; KSI_Utf8String *errorMsg; int state, ksi_status; unsigned i; size_t p; KSI_AsyncService_getPendingCount(as, &p); /* Check if there are pending/available responses and associate them with the request items */ while (true) { respHandle = NULL; item = NULL; tmpRes = KSI_AsyncService_run(as, &respHandle, &p); if (tmpRes != KSI_OK) reportKSIAPIErr(ctx, NULL, "KSI_AsyncService_run", tmpRes); if (respHandle == NULL) { /* nothing received */ break; } #if KSI_SDK_VER_MAJOR == 3 && KSI_SDK_VER_MINOR < 22 if (p != 0 && ctx->roundCount > 0) { ctx->roundCount--; } else { ctx->bRoundLock = 0; ctx->roundCount = 0; } #endif state = KSI_ASYNC_STATE_UNDEFINED; CHECK_KSI_API(KSI_AsyncHandle_getState(respHandle, &state), ctx, "KSI_AsyncHandle_getState"); if (state == KSI_ASYNC_STATE_PUSH_CONFIG_RECEIVED) { res = KSI_AsyncHandle_getConfig(respHandle, &config); if (res == KSI_OK) { handle_ksi_config(ctx, as, config); KSI_AsyncHandle_free(respHandle); } else reportKSIAPIErr(ctx, NULL, "KSI_AsyncHandle_getConfig", res); } else if (state == KSI_ASYNC_STATE_RESPONSE_RECEIVED) { CHECK_KSI_API(KSI_AsyncHandle_getRequestCtx(respHandle, (const void **)&item), ctx, "KSI_AsyncHandle_getRequestCtx"); item->respHandle = respHandle; item->ksi_status = KSI_OK; } else if (state == KSI_ASYNC_STATE_ERROR) { CHECK_KSI_API(KSI_AsyncHandle_getRequestCtx(respHandle, (const void **)&item), ctx, "KSI_AsyncHandle_getRequestCtx"); errorMsg = NULL; KSI_AsyncHandle_getError(respHandle, &ksi_status); KSI_AsyncHandle_getExtError(respHandle, &extError); KSI_AsyncHandle_getErrorMessage(respHandle, &errorMsg); report(ctx, "Asynchronous request returned error %s (%d), %lu %s", KSI_getErrorString(ksi_status), ksi_status, extError, errorMsg ? KSI_Utf8String_cstr(errorMsg) : ""); KSI_AsyncHandle_free(respHandle); if (item) item->ksi_status = ksi_status; } if (item) item->status = QITEM_DONE; } KSI_AsyncService_getPendingCount(as, &p); /* Send all the new requests in the back of the queue to the server */ for (i = 0; i < ProtectedQueue_count(ctx->signer_queue); i++) { item = NULL; if (!ProtectedQueue_getItem(ctx->signer_queue, i, (void **)&item) || !item) continue; /* ingore non request queue items */ if (item->type != QITEM_SIGNATURE_REQUEST) continue; /* stop at first processed item */ if (item->status != QITEM_WAITING) continue; /* Due to a bug in libksi it is possible that async signer may send out * more signing requests than permitted by the gateway. Workaround is to * keep track of signing requests here. */ #if KSI_SDK_VER_MAJOR == 3 && KSI_SDK_VER_MINOR < 22 if (ctx->roundCount >= ctx->max_requests) ctx->bRoundLock = 1; if (ctx->bRoundLock) break; #endif /* The data hash is produced in another thread by another KSI_CTX and * libksi internal uses KSI_DataHash cache to reduce the amount of * memory allocations by recycling old objects. Lets clone the hash * value with current KSI_CTX as we can not be sure that this thread is * not affecting the data hash cache operated by another thread. */ clonedHash = clone_hash(ksi_ctx, item->root); CHECK_KSI_API(KSI_AggregationReq_new(ksi_ctx, &req), ctx, "KSI_AggregationReq_new"); CHECK_KSI_API(KSI_AggregationReq_setRequestHash((KSI_AggregationReq *)req, clonedHash), ctx, "KSI_AggregationReq_setRequestHash"); clonedHash = NULL; CHECK_KSI_API(KSI_Integer_new(ksi_ctx, item->intarg2, &level), ctx, "KSI_Integer_new"); CHECK_KSI_API(KSI_AggregationReq_setRequestLevel(req, level), ctx, "KSI_AggregationReq_setRequestLevel"); CHECK_KSI_API(KSI_AsyncAggregationHandle_new(ksi_ctx, req, &reqHandle), ctx, "KSI_AsyncAggregationHandle_new"); CHECK_KSI_API(KSI_AsyncHandle_setRequestCtx(reqHandle, (void *)item, NULL), ctx, "KSI_AsyncRequest_setRequestContext"); res = KSI_AsyncService_addRequest(as, reqHandle); /* this can fail because of throttling */ if (res == KSI_OK) { item->status = QITEM_SENT; #if KSI_SDK_VER_MAJOR == 3 && KSI_SDK_VER_MINOR < 22 ctx->roundCount++; #endif } else { reportKSIAPIErr(ctx, NULL, "KSI_AsyncService_addRequest", res); KSI_AsyncHandle_free(reqHandle); item->status = QITEM_DONE; item->ksi_status = res; break; } if (i != 0 && i % ctx->max_requests == 0) { CHECK_KSI_API(KSI_AsyncService_run(as, NULL, NULL), ctx, "KSI_AsyncService_run"); } } CHECK_KSI_API(KSI_AsyncService_run(as, NULL, NULL), ctx, "KSI_AsyncService_run"); /* Save all consequent fulfilled responses in the front of the queue to the signature file */ while (ProtectedQueue_count(ctx->signer_queue)) { item = NULL; if (!ProtectedQueue_getItem(ctx->signer_queue, 0, (void **)&item)) break; if (!item) { ProtectedQueue_popFront(ctx->signer_queue, (void **)&item); continue; } /* stop at first non request queue item (maybe file close/open, quit) */ if (item->type != QITEM_SIGNATURE_REQUEST) break; /* stop at first unfinished queue item because the signatures need to be ordered */ if (item->status != QITEM_DONE) break; ProtectedQueue_popFront(ctx->signer_queue, (void **)&item); save_response(ctx, item->file, item); fflush(item->file); /* the main thread has to be locked when the hash is freed to avoid a race condition */ pthread_mutex_lock(&ctx->module_lock); KSI_DataHash_free(item->root); KSI_AsyncHandle_free(item->respHandle); free(item); pthread_mutex_unlock(&ctx->module_lock); } ret = true; cleanup: KSI_DataHash_free(clonedHash); KSI_AsyncService_getPendingCount(as, &p); return ret; } /* This can only be used when signer thread has terminated or within the thread. */ static bool rsksictxCloseAllPendingBlocksWithoutSignature(rsksictx ctx, const char *reason) { bool ret = false; QueueItem *item = NULL; int res = KSI_OK; /* Save all consequent fulfilled responses in the front of the queue to the signature file */ while (ProtectedQueue_count(ctx->signer_queue)) { item = NULL; ProtectedQueue_popFront(ctx->signer_queue, (void **)&item); if (item == NULL) { continue; } /* Skip non request queue item. */ if (item->type == QITEM_SIGNATURE_REQUEST) { res = tlvWriteNoSigLS12(item->file, item->intarg1, item->root, reason); if (res != KSI_OK) { reportKSIAPIErr(ctx, NULL, "tlvWriteNoSigLS12", res); ret = false; goto cleanup; } fflush(item->file); } KSI_DataHash_free(item->root); KSI_AsyncHandle_free(item->respHandle); free(item); } ret = true; cleanup: return ret; } static void request_async_config(rsksictx ctx, KSI_CTX *ksi_ctx, KSI_AsyncService *as) { KSI_Config *cfg = NULL; KSI_AsyncHandle *cfgHandle = NULL; KSI_AggregationReq *cfgReq = NULL; int res; bool bSuccess = false; CHECK_KSI_API(KSI_AggregationReq_new(ksi_ctx, &cfgReq), ctx, "KSI_AggregationReq_new"); CHECK_KSI_API(KSI_Config_new(ksi_ctx, &cfg), ctx, "KSI_Config_new"); CHECK_KSI_API(KSI_AggregationReq_setConfig(cfgReq, cfg), ctx, "KSI_AggregationReq_setConfig"); CHECK_KSI_API(KSI_AsyncAggregationHandle_new(ksi_ctx, cfgReq, &cfgHandle), ctx, "KSI_AsyncAggregationHandle_new"); CHECK_KSI_API(KSI_AsyncService_addRequest(as, cfgHandle), ctx, "KSI_AsyncService_addRequest"); bSuccess = true; cleanup: if (!bSuccess) { if (cfgHandle) KSI_AsyncHandle_free(cfgHandle); else if (cfgReq) KSI_AggregationReq_free(cfgReq); else if (cfg) KSI_Config_free(cfg); } } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" void *signer_thread(void *arg) { int res = KSI_UNKNOWN_ERROR; rsksictx ctx = (rsksictx)arg; KSI_CTX *ksi_ctx = NULL; KSI_AsyncService *as = NULL; size_t size_t_value = 0; size_t ksiFileCount = 0; int endpoints = 0; bool bSleep = true; CHECK_KSI_API(KSI_CTX_new(&ksi_ctx), ctx, "KSI_CTX_new"); CHECK_KSI_API(KSI_CTX_setAggregator(ksi_ctx, ctx->aggregatorUri, ctx->aggregatorId, ctx->aggregatorKey), ctx, "KSI_CTX_setAggregator"); if (ctx->debugFile) { res = KSI_CTX_setLoggerCallback(ksi_ctx, rsksiStreamLogger, ctx->debugFile); if (res != KSI_OK) reportKSIAPIErr(ctx, NULL, "Unable to set logger callback", res); res = KSI_CTX_setLogLevel(ksi_ctx, ctx->debugLevel); if (res != KSI_OK) reportKSIAPIErr(ctx, NULL, "Unable to set log level", res); } CHECK_KSI_API(KSI_CTX_setOption(ksi_ctx, KSI_OPT_AGGR_HMAC_ALGORITHM, (void *)((size_t)ctx->hmacAlg)), ctx, "KSI_CTX_setOption"); res = KSI_SigningHighAvailabilityService_new(ksi_ctx, &as); if (res != KSI_OK) { reportKSIAPIErr(ctx, NULL, "KSI_SigningAsyncService_new", res); } else { int i = 0; for (i = 0; i < ctx->aggregatorEndpointCount; i++) { res = KSI_AsyncService_addEndpoint(as, ctx->aggregatorEndpoints[i], ctx->aggregatorId, ctx->aggregatorKey); if (res != KSI_OK) { // This can fail if the protocol is not supported by async api. reportKSIAPIErr(ctx, NULL, "KSI_AsyncService_addEndpoint", res); continue; } endpoints++; } } if (endpoints == 0) { /* no endpoint accepted, deleting the service */ report(ctx, "No endpoints added, signing service disabled"); ctx->disabled = true; KSI_AsyncService_free(as); as = NULL; goto cleanup; } /* Lets use buffer value, as libksi requires size_t. */ size_t_value = ctx->max_requests; KSI_AsyncService_setOption(as, KSI_ASYNC_OPT_REQUEST_CACHE_SIZE, (void *)size_t_value); size_t_value = ctx->blockSigTimeout; KSI_AsyncService_setOption(as, KSI_ASYNC_OPT_SND_TIMEOUT, (void *)size_t_value); ctx->signer_state = SIGNER_STARTED; while (true) { QueueItem *item = NULL; if (isAggrConfNeeded(ctx)) { request_async_config(ctx, ksi_ctx, as); } /* Wait for a work item or timeout*/ if (bSleep) { ProtectedQueue_waitForItem(ctx->signer_queue, NULL, ctx->threadSleepms); } bSleep = true; /* Check for block time limit. */ sigblkCheckTimeOut(ctx); /* in case there are no items go around*/ if (ProtectedQueue_count(ctx->signer_queue) == 0) { process_requests_async(ctx, ksi_ctx, as); continue; } /* process signing requests only if there is an open signature file */ if (ksiFileCount > 0) { /* check for pending/unsent requests in asynchronous service */ if (!process_requests_async(ctx, ksi_ctx, as)) { // probably fatal error, disable signing, error should be already reported ctx->disabled = true; goto cleanup; } } /* if there are sig. requests still in the front, then we have to start over*/ if (ProtectedQueue_peekFront(ctx->signer_queue, (void **)&item) && item->type == QITEM_SIGNATURE_REQUEST) continue; /* Handle other types of work items */ if (ProtectedQueue_popFront(ctx->signer_queue, (void **)&item) != 0) { /* There is no point to sleep after processing non request type item * as there is great possibility that next item can already be * processed. */ bSleep = false; if (item->type == QITEM_CLOSE_FILE) { if (item->file) { fclose(item->file); item->file = NULL; } if (ksiFileCount > 0) ksiFileCount--; } else if (item->type == QITEM_NEW_FILE) { ksiFileCount++; } else if (item->type == QITEM_QUIT) { free(item); /* Will look into work queue for pending KSI signatures and will output * unsigned block marker instead of actual KSI signature to finalize this * thread quickly. */ rsksictxCloseAllPendingBlocksWithoutSignature( ctx, "Signing not finished due to sudden closure of lmsig_ksi-ls12 module."); rsksictxForceCloseWithoutSig(ctx, "Block closed due to sudden closure of lmsig_ksi-ls12 module."); goto cleanup; } free(item); } } cleanup: KSI_AsyncService_free(as); KSI_CTX_free(ksi_ctx); ctx->signer_state = SIGNER_STOPPED; return NULL; } #pragma GCC diagnostic push rsyslog-8.2512.0/runtime/PaxHeaders/hashtable_private.h0000644000000000000000000000013115055605325020057 xustar0030 mtime=1756826325.645800623 29 atime=1764930990.56685438 30 ctime=1764935923.306578464 rsyslog-8.2512.0/runtime/hashtable_private.h0000664000175000017500000000535315055605325017532 0ustar00rgerrger/* Copyright (C) 2002, 2004 Christopher Clark */ #ifndef __HASHTABLE_PRIVATE_CWC22_H__ #define __HASHTABLE_PRIVATE_CWC22_H__ #include "hashtable.h" /*****************************************************************************/ struct entry { void *k, *v; unsigned int h; struct entry *next; }; struct hashtable { unsigned int tablelength; struct entry **table; unsigned int entrycount; unsigned int loadlimit; unsigned int primeindex; unsigned int (*hashfn)(void *k); int (*eqfn)(void *k1, void *k2); void (*dest)(void *v); /* destructor for values, if NULL use free() */ }; /*****************************************************************************/ unsigned int hash(struct hashtable *h, void *k); /*****************************************************************************/ /* indexFor */ #define indexFor(tablelength, hashvalue) ((hashvalue) % (tablelength)) /*****************************************************************************/ #define freekey(X) free(X) /*****************************************************************************/ #endif /* __HASHTABLE_PRIVATE_CWC22_H__*/ /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ rsyslog-8.2512.0/runtime/PaxHeaders/rsconf.c0000644000000000000000000000013215114522477015662 xustar0030 mtime=1764926783.041632005 30 atime=1764926784.239661412 30 ctime=1764935923.147576029 rsyslog-8.2512.0/runtime/rsconf.c0000664000175000017500000016655615114522477015351 0ustar00rgerrger/* rsconf.c - the rsyslog configuration system. * * Module begun 2011-04-19 by Rainer Gerhards * * Copyright 2011-2023 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "obj.h" #include "srUtils.h" #include "ruleset.h" #include "modules.h" #include "conf.h" #include "queue.h" #include "rsconf.h" #include "cfsysline.h" #include "errmsg.h" #include "action.h" #include "glbl.h" #include "unicode-helper.h" #include "omshell.h" #include "omusrmsg.h" #include "omfwd.h" #include "omfile.h" #include "ompipe.h" #include "omdiscard.h" #include "pmrfc5424.h" #include "pmrfc3164.h" #include "smfile.h" #include "smtradfile.h" #include "smfwd.h" #include "smtradfwd.h" #include "parser.h" #include "outchannel.h" #include "threads.h" #include "datetime.h" #include "parserif.h" #include "modules.h" #include "dirty.h" #include "template.h" #include "timezones.h" extern char *yytext; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(ruleset) DEFobjCurrIf(module) DEFobjCurrIf(conf) DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* exported static data */ rsconf_t *runConf = NULL; /* the currently running config */ rsconf_t *loadConf = NULL; /* the config currently being loaded (no concurrent config load supported!) */ /* hardcoded standard templates (used for defaults) */ static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: " "'%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', " "APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', " "STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\ninputname: %inputname% " "rawmsg: '%rawmsg%'\n$!:%$!%\n$.:%$.%\n$/:%$/%\n\n\""; static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% " "%PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\""; static uchar template_SyslogRFC5424Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% " "%PROCID% %MSGID% %STRUCTURED-DATA% %msg%\""; static uchar template_TraditionalFileFormat[] = "=RSYSLOG_TraditionalFileFormat"; static uchar template_FileFormat[] = "=RSYSLOG_FileFormat"; static uchar template_ForwardFormat[] = "=RSYSLOG_ForwardFormat"; static uchar template_TraditionalForwardFormat[] = "=RSYSLOG_TraditionalForwardFormat"; static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n " "%syslogtag%%msg%\n\r\""; static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, " "DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, " "'%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, " "'%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, " "DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, " "'%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, " "'%syslogtag%')\",STDSQL"; static uchar template_spoofadr[] = "\"%fromhost-ip%\""; static uchar template_SysklogdFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n\""; static uchar template_StdJSONFmt[] = "\"{\\\"message\\\":\\\"%msg:::json%\\\",\\\"fromhost\\\":\\\"" "%HOSTNAME:::json%\\\",\\\"facility\\\":\\\"%syslogfacility-text%\\\",\\\"priority\\\":\\\"" "%syslogpriority-text%\\\",\\\"timereported\\\":\\\"%timereported:::date-rfc3339%\\\",\\\"timegenerated\\\":\\\"" "%timegenerated:::date-rfc3339%\\\"}\""; static uchar template_FullJSONFmt[] = "\"{\\\"message\\\":\\\"%msg:::json%\\\"," "\\\"fromhost\\\":\\\"%HOSTNAME:::json%\\\"," "\\\"programname\\\":\\\"%programname%\\\"," "\\\"procid\\\":\\\"%PROCID%\\\"," "\\\"msgid\\\":\\\"%MSGID%\\\"," "\\\"facility\\\":\\\"%syslogfacility-text%\\\"," "\\\"priority\\\":\\\"%syslogpriority-text%\\\"," "\\\"timereported\\\":\\\"%timereported:::date-rfc3339%\\\"," "\\\"timegenerated\\\":\\\"%timegenerated:::date-rfc3339%\\\"}\""; static uchar template_StdClickHouseFmt[] = "\"INSERT INTO rsyslog.SystemEvents (severity, facility, " "timestamp, hostname, tag, message) VALUES (%syslogseverity%, %syslogfacility%, " "'%timereported:::date-unixtimestamp%', '%hostname%', '%syslogtag%', '%msg%')\",STDSQL"; static uchar template_StdOmSenderTrack_senderid[] = "\"%fromhost-ip%\""; /* default template for omsendertrack "senderid" parameter*/ /* end templates */ /* tables for interfacing with the v6 config system (as far as we need to) */ static struct cnfparamdescr inppdescr[] = {{"type", eCmdHdlrString, CNFPARAM_REQUIRED}}; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; static struct cnfparamdescr parserpdescr[] = {{"type", eCmdHdlrString, CNFPARAM_REQUIRED}, {"name", eCmdHdlrString, CNFPARAM_REQUIRED}}; static struct cnfparamblk parserpblk = {CNFPARAMBLK_VERSION, sizeof(parserpdescr) / sizeof(struct cnfparamdescr), parserpdescr}; /* forward-definitions */ void cnfDoCfsysline(char *ln); int rsconfNeedDropPriv(rsconf_t *const cnf) { return ((cnf->globals.gidDropPriv != 0) || (cnf->globals.uidDropPriv != 0)); } static void cnfSetDefaults(rsconf_t *pThis) { #ifdef ENABLE_LIBCAPNG pThis->globals.bAbortOnFailedLibcapngSetup = 1; pThis->globals.bCapabilityDropEnabled = 1; #endif pThis->globals.bAbortOnUncleanConfig = 0; pThis->globals.bAbortOnFailedQueueStartup = 0; pThis->globals.bReduceRepeatMsgs = 0; pThis->globals.bDebugPrintTemplateList = 1; pThis->globals.bDebugPrintModuleList = 0; pThis->globals.bDebugPrintCfSysLineHandlerList = 0; pThis->globals.bLogStatusMsgs = DFLT_bLogStatusMsgs; pThis->globals.bAllMsgToStderr = 0; pThis->globals.bErrMsgToStderr = 1; pThis->globals.maxErrMsgToStderr = -1; pThis->globals.umask = -1; pThis->globals.gidDropPrivKeepSupplemental = 0; pThis->globals.abortOnIDResolutionFail = 1; pThis->templates.root = NULL; pThis->templates.last = NULL; pThis->templates.lastStatic = NULL; pThis->actions.nbrActions = 0; pThis->actions.iActionNbr = 0; pThis->globals.pszWorkDir = NULL; pThis->globals.bDropMalPTRMsgs = 0; pThis->globals.operatingStateFile = NULL; pThis->globals.iGnuTLSLoglevel = 0; pThis->globals.debugOnShutdown = 0; pThis->globals.pszDfltNetstrmDrvrCAF = NULL; pThis->globals.pszDfltNetstrmDrvrCRLF = NULL; pThis->globals.pszDfltNetstrmDrvrCertFile = NULL; pThis->globals.pszDfltNetstrmDrvrKeyFile = NULL; pThis->globals.pszDfltNetstrmDrvr = NULL; pThis->globals.oversizeMsgErrorFile = NULL; pThis->globals.reportOversizeMsg = 1; pThis->globals.oversizeMsgInputMode = 0; pThis->globals.reportChildProcessExits = REPORT_CHILD_PROCESS_EXITS_ERRORS; pThis->globals.bActionReportSuspension = 1; pThis->globals.bActionReportSuspensionCont = 0; pThis->globals.janitorInterval = 10; pThis->globals.reportNewSenders = 0; pThis->globals.reportGoneAwaySenders = 0; pThis->globals.senderStatsTimeout = 12 * 60 * 60; /* 12 hr timeout for senders */ pThis->globals.senderKeepTrack = 0; pThis->globals.inputTimeoutShutdown = 1000; pThis->globals.iDefPFFamily = PF_UNSPEC; pThis->globals.ACLAddHostnameOnFail = 0; pThis->globals.ACLDontResolve = 0; pThis->globals.bDisableDNS = 0; pThis->globals.bProcessInternalMessages = 0; const char *const log_dflt = getenv("RSYSLOG_DFLT_LOG_INTERNAL"); if (log_dflt != NULL && !strcmp(log_dflt, "1")) pThis->globals.bProcessInternalMessages = 1; pThis->globals.glblDevOptions = 0; pThis->globals.intMsgRateLimitItv = 5; pThis->globals.intMsgRateLimitBurst = 500; pThis->globals.intMsgsSeverityFilter = DFLT_INT_MSGS_SEV_FILTER; pThis->globals.permitCtlC = glblPermitCtlC; pThis->globals.actq_dflt_toQShutdown = 10; pThis->globals.actq_dflt_toActShutdown = 1000; pThis->globals.actq_dflt_toEnq = 2000; pThis->globals.actq_dflt_toWrkShutdown = 60000; pThis->globals.ruleset_dflt_toQShutdown = 1500; pThis->globals.ruleset_dflt_toActShutdown = 1000; pThis->globals.ruleset_dflt_toEnq = 2000; pThis->globals.ruleset_dflt_toWrkShutdown = 60000; pThis->globals.dnscacheDefaultTTL = 24 * 60 * 60; pThis->globals.dnscacheEnableTTL = 0; pThis->globals.shutdownQueueDoubleSize = 0; pThis->globals.optionDisallowWarning = 1; pThis->globals.bSupportCompressionExtension = 1; #ifdef ENABLE_LIBLOGGING_STDLOG pThis->globals.stdlog_hdl = stdlog_open("rsyslogd", 0, STDLOG_SYSLOG, NULL); pThis->globals.stdlog_chanspec = NULL; #endif pThis->globals.iMaxLine = 8096; /* timezone specific*/ pThis->timezones.tzinfos = NULL; pThis->timezones.ntzinfos = 0; /* queue params */ pThis->globals.mainQ.iMainMsgQueueSize = 100000; pThis->globals.mainQ.iMainMsgQHighWtrMark = 80000; pThis->globals.mainQ.iMainMsgQLowWtrMark = 20000; pThis->globals.mainQ.iMainMsgQDiscardMark = -1; pThis->globals.mainQ.iMainMsgQDiscardSeverity = 8; pThis->globals.mainQ.iMainMsgQueueNumWorkers = 2; pThis->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; pThis->globals.mainQ.pszMainMsgQFName = NULL; pThis->globals.mainQ.iMainMsgQueMaxFileSize = 1024 * 1024; pThis->globals.mainQ.iMainMsgQPersistUpdCnt = 0; pThis->globals.mainQ.bMainMsgQSyncQeueFiles = 0; pThis->globals.mainQ.iMainMsgQtoQShutdown = 1500; pThis->globals.mainQ.iMainMsgQtoActShutdown = 1000; pThis->globals.mainQ.iMainMsgQtoEnq = 2000; pThis->globals.mainQ.iMainMsgQtoWrkShutdown = 60000; pThis->globals.mainQ.iMainMsgQWrkMinMsgs = 40000; pThis->globals.mainQ.iMainMsgQDeqSlowdown = 0; pThis->globals.mainQ.iMainMsgQueMaxDiskSpace = 0; pThis->globals.mainQ.iMainMsgQueDeqBatchSize = 256; pThis->globals.mainQ.bMainMsgQSaveOnShutdown = 1; pThis->globals.mainQ.iMainMsgQueueDeqtWinFromHr = 0; pThis->globals.mainQ.iMainMsgQueueDeqtWinToHr = 25; pThis->pMsgQueue = NULL; pThis->globals.parser.cCCEscapeChar = '#'; pThis->globals.parser.bDropTrailingLF = 1; pThis->globals.parser.bEscapeCCOnRcv = 1; pThis->globals.parser.bSpaceLFOnRcv = 0; pThis->globals.parser.bEscape8BitChars = 0; pThis->globals.parser.bEscapeTab = 1; pThis->globals.parser.bParserEscapeCCCStyle = 0; pThis->globals.parser.bPermitSlashInProgramname = 0; pThis->globals.parser.bParseHOSTNAMEandTAG = 1; pThis->parsers.pDfltParsLst = NULL; pThis->parsers.pParsLstRoot = NULL; } /* Standard-Constructor */ BEGINobjConstruct(rsconf) /* be sure to specify the object type also in END macro! */ cnfSetDefaults(pThis); lookupInitCnf(&pThis->lu_tabs); CHKiRet(dynstats_initCnf(&pThis->dynstats_buckets)); CHKiRet(perctile_initCnf(&pThis->perctile_buckets)); CHKiRet(llInit(&pThis->rulesets.llRulesets, rulesetDestructForLinkedList, rulesetKeyDestruct, (int (*)(void *, void *))strcasecmp)); finalize_it: ENDobjConstruct(rsconf) /* ConstructionFinalizer */ static rsRetVal rsconfConstructFinalize(rsconf_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, rsconf); RETiRet; } /* call freeCnf() module entry points AND free the module entries themselfes. */ static void freeCnf(rsconf_t *pThis) { cfgmodules_etry_t *etry, *del; etry = pThis->modules.root; while (etry != NULL) { if (etry->pMod->beginCnfLoad != NULL) { dbgprintf("calling freeCnf(%p) for module '%s'\n", etry->modCnf, (char *)module.GetName(etry->pMod)); etry->pMod->freeCnf(etry->modCnf); } del = etry; etry = etry->next; free(del); } } /* destructor for the rsconf object */ PROTOTYPEobjDestruct(rsconf); BEGINobjDestruct(rsconf) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(rsconf); freeCnf(pThis); tplDeleteAll(pThis); dynstats_destroyAllBuckets(); perctileBucketsDestruct(); ochDeleteAll(); freeTimezones(pThis); parser.DestructParserList(&pThis->parsers.pDfltParsLst); parser.destroyMasterParserList(pThis->parsers.pParsLstRoot); free(pThis->globals.mainQ.pszMainMsgQFName); free(pThis->globals.pszConfDAGFile); free(pThis->globals.pszWorkDir); free(pThis->globals.operatingStateFile); free(pThis->globals.pszDfltNetstrmDrvrCAF); free(pThis->globals.pszDfltNetstrmDrvrCRLF); free(pThis->globals.pszDfltNetstrmDrvrCertFile); free(pThis->globals.pszDfltNetstrmDrvrKeyFile); free(pThis->globals.pszDfltNetstrmDrvr); free(pThis->globals.oversizeMsgErrorFile); #ifdef ENABLE_LIBLOGGING_STDLOG stdlog_close(pThis->globals.stdlog_hdl); free(pThis->globals.stdlog_chanspec); #endif lookupDestroyCnf(); llDestroy(&(pThis->rulesets.llRulesets)); ENDobjDestruct(rsconf) /* DebugPrint support for the rsconf object */ PROTOTYPEObjDebugPrint(rsconf); BEGINobjDebugPrint(rsconf) /* be sure to specify the object type also in END and CODESTART macros! */ cfgmodules_etry_t *modNode; dbgprintf("configuration object %p\n", pThis); dbgprintf("Global Settings:\n"); dbgprintf(" bDebugPrintTemplateList.............: %d\n", pThis->globals.bDebugPrintTemplateList); dbgprintf(" bDebugPrintModuleList : %d\n", pThis->globals.bDebugPrintModuleList); dbgprintf(" bDebugPrintCfSysLineHandlerList.....: %d\n", pThis->globals.bDebugPrintCfSysLineHandlerList); dbgprintf(" bLogStatusMsgs : %d\n", pThis->globals.bLogStatusMsgs); dbgprintf(" bErrMsgToStderr.....................: %d\n", pThis->globals.bErrMsgToStderr); dbgprintf(" drop Msgs with malicious PTR Record : %d\n", glbl.GetDropMalPTRMsgs(pThis)); ruleset.DebugPrintAll(pThis); dbgprintf("\n"); if (pThis->globals.bDebugPrintTemplateList) tplPrintList(pThis); if (pThis->globals.bDebugPrintModuleList) module.PrintList(); if (pThis->globals.bDebugPrintCfSysLineHandlerList) dbgPrintCfSysLineHandlers(); /* we use the now traditional messages, albeit they originally were expected to become * "streamlined". Also we do not add any more, as the config system ouputs this data in * any case and we have seen no need for more info in the past 10+ years. */ dbgprintf("Main queue size %d messages.\n", pThis->globals.mainQ.iMainMsgQueueSize); dbgprintf("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n", pThis->globals.mainQ.iMainMsgQueueNumWorkers, pThis->globals.mainQ.iMainMsgQtoWrkShutdown, pThis->globals.mainQ.iMainMsgQPersistUpdCnt); dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n", pThis->globals.mainQ.iMainMsgQtoQShutdown, pThis->globals.mainQ.iMainMsgQtoActShutdown, pThis->globals.mainQ.iMainMsgQtoEnq); dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n", pThis->globals.mainQ.iMainMsgQHighWtrMark, pThis->globals.mainQ.iMainMsgQLowWtrMark, pThis->globals.mainQ.iMainMsgQDiscardMark, pThis->globals.mainQ.iMainMsgQDiscardSeverity); dbgprintf("Main queue save on shutdown %d, max disk space allowed %lld\n", pThis->globals.mainQ.bMainMsgQSaveOnShutdown, pThis->globals.mainQ.iMainMsgQueMaxDiskSpace); dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir(pThis)); ochPrintList(pThis); dbgprintf("Modules used in this configuration:\n"); for (modNode = pThis->modules.root; modNode != NULL; modNode = modNode->next) { dbgprintf(" %s\n", module.GetName(modNode->pMod)); } CODESTARTobjDebugPrint(rsconf); ENDobjDebugPrint(rsconf) static rsRetVal parserProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; modInfo_t *pMod; uchar *cnfModName = NULL; uchar *parserName = NULL; int paramIdx; void *parserInst; parser_t *myparser; DEFiRet; pvals = nvlstGetParams(o->nvlst, &parserpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } DBGPRINTF("input param blk after parserProcessCnf:\n"); cnfparamsPrint(&parserpblk, pvals); paramIdx = cnfparamGetIdx(&parserpblk, "name"); parserName = (uchar *)es_str2cstr(pvals[paramIdx].val.d.estr, NULL); if (parser.FindParser(loadConf->parsers.pParsLstRoot, &myparser, parserName) != RS_RET_PARSER_NOT_FOUND) { LogError(0, RS_RET_PARSER_NAME_EXISTS, "parser module name '%s' already exists", parserName); ABORT_FINALIZE(RS_RET_PARSER_NAME_EXISTS); } paramIdx = cnfparamGetIdx(&parserpblk, "type"); cnfModName = (uchar *)es_str2cstr(pvals[paramIdx].val.d.estr, NULL); if ((pMod = module.FindWithCnfName(loadConf, cnfModName, eMOD_PARSER)) == NULL) { LogError(0, RS_RET_MOD_UNKNOWN, "parser module name '%s' is unknown", cnfModName); ABORT_FINALIZE(RS_RET_MOD_UNKNOWN); } if (pMod->mod.pm.newParserInst == NULL) { LogError(0, RS_RET_MOD_NO_PARSER_STMT, "parser module '%s' does not support parser() statement", cnfModName); ABORT_FINALIZE(RS_RET_MOD_NO_INPUT_STMT); } CHKiRet(pMod->mod.pm.newParserInst(o->nvlst, &parserInst)); /* all well, so let's (try) to add parser to config */ CHKiRet(parserConstructViaModAndName(pMod, parserName, parserInst)); finalize_it: free(cnfModName); free(parserName); cnfparamvalsDestruct(pvals, &parserpblk); RETiRet; } /* Process input() objects */ static rsRetVal inputProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; modInfo_t *pMod; uchar *cnfModName = NULL; int typeIdx; DEFiRet; pvals = nvlstGetParams(o->nvlst, &inppblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } DBGPRINTF("input param blk after inputProcessCnf:\n"); cnfparamsPrint(&inppblk, pvals); typeIdx = cnfparamGetIdx(&inppblk, "type"); cnfModName = (uchar *)es_str2cstr(pvals[typeIdx].val.d.estr, NULL); if ((pMod = module.FindWithCnfName(loadConf, cnfModName, eMOD_IN)) == NULL) { LogError(0, RS_RET_MOD_UNKNOWN, "input module name '%s' is unknown", cnfModName); ABORT_FINALIZE(RS_RET_MOD_UNKNOWN); } if (pMod->mod.im.newInpInst == NULL) { LogError(0, RS_RET_MOD_NO_INPUT_STMT, "input module '%s' does not support input() statement", cnfModName); ABORT_FINALIZE(RS_RET_MOD_NO_INPUT_STMT); } iRet = pMod->mod.im.newInpInst(o->nvlst); finalize_it: free(cnfModName); cnfparamvalsDestruct(pvals, &inppblk); RETiRet; } /*------------------------------ interface to flex/bison parser ------------------------------*/ extern int yylineno; void parser_warnmsg(const char *fmt, ...) { va_list ap; char errBuf[1024]; va_start(ap, fmt); if (vsnprintf(errBuf, sizeof(errBuf), fmt, ap) == sizeof(errBuf)) errBuf[sizeof(errBuf) - 1] = '\0'; LogMsg(0, RS_RET_CONF_PARSE_WARNING, LOG_WARNING, "warning during parsing file %s, on or before line %d: %s", cnfcurrfn, yylineno, errBuf); va_end(ap); } void parser_errmsg(const char *fmt, ...) { va_list ap; char errBuf[1024]; va_start(ap, fmt); if (vsnprintf(errBuf, sizeof(errBuf), fmt, ap) == sizeof(errBuf)) errBuf[sizeof(errBuf) - 1] = '\0'; if (cnfcurrfn == NULL) { LogError(0, RS_RET_CONF_PARSE_ERROR, "error during config processing: %s", errBuf); } else { LogError(0, RS_RET_CONF_PARSE_ERROR, "error during parsing file %s, on or before line %d: %s", cnfcurrfn, yylineno, errBuf); } va_end(ap); } int yyerror(const char *s); /* we need this prototype to make compiler happy */ int yyerror(const char *s) { parser_errmsg("%s on token '%s'", s, yytext); return 0; } void ATTR_NONNULL() cnfDoObj(struct cnfobj *const o) { int bDestructObj = 1; int bChkUnuse = 1; assert(o != NULL); dbgprintf("cnf:global:obj: "); cnfobjPrint(o); /* We need to check for object disabling as early as here to cover most * of them at once and avoid needless initializations * - jvymazal 2020-02-12 */ if (nvlstChkDisabled(o->nvlst)) { dbgprintf("object disabled by configuration\n"); return; } switch (o->objType) { case CNFOBJ_GLOBAL: glblProcessCnf(o); break; case CNFOBJ_TIMEZONE: glblProcessTimezone(o); break; case CNFOBJ_MAINQ: glblProcessMainQCnf(o); bDestructObj = 0; break; case CNFOBJ_MODULE: modulesProcessCnf(o); break; case CNFOBJ_INPUT: inputProcessCnf(o); break; case CNFOBJ_LOOKUP_TABLE: lookupTableDefProcessCnf(o); break; case CNFOBJ_DYN_STATS: dynstats_processCnf(o); break; case CNFOBJ_PERCTILE_STATS: perctile_processCnf(o); break; case CNFOBJ_PARSER: parserProcessCnf(o); break; case CNFOBJ_TPL: if (tplProcessCnf(o) != RS_RET_OK) parser_errmsg("error processing template object"); break; case CNFOBJ_RULESET: rulesetProcessCnf(o); break; case CNFOBJ_PROPERTY: case CNFOBJ_CONSTANT: /* these types are processed at a later stage */ bChkUnuse = 0; break; case CNFOBJ_ACTION: default: dbgprintf("cnfDoObj program error: unexpected object type %u\n", o->objType); break; } if (bDestructObj) { if (bChkUnuse) nvlstChkUnused(o->nvlst); cnfobjDestruct(o); } } void cnfDoScript(struct cnfstmt *script) { dbgprintf("cnf:global:script\n"); ruleset.AddScript(ruleset.GetCurrent(loadConf), script); } void cnfDoCfsysline(char *ln) { DBGPRINTF("cnf:global:cfsysline: %s\n", ln); /* the legacy system needs the "$" stripped */ conf.cfsysline((uchar *)ln + 1); free(ln); } void cnfDoBSDTag(char *ln) { DBGPRINTF("cnf:global:BSD tag: %s\n", ln); LogError(0, RS_RET_BSD_BLOCKS_UNSUPPORTED, "BSD-style blocks are no longer supported in rsyslog, " "see https://www.rsyslog.com/g/BSD for details and a " "solution (Block '%s')", ln); free(ln); } void cnfDoBSDHost(char *ln) { DBGPRINTF("cnf:global:BSD host: %s\n", ln); LogError(0, RS_RET_BSD_BLOCKS_UNSUPPORTED, "BSD-style blocks are no longer supported in rsyslog, " "see https://www.rsyslog.com/g/BSD for details and a " "solution (Block '%s')", ln); free(ln); } /*------------------------------ end interface to flex/bison parser ------------------------------*/ /* drop to specified group * if something goes wrong, the function never returns */ static rsRetVal doDropPrivGid(rsconf_t *cnf) { int res; uchar szBuf[1024]; DEFiRet; if (!cnf->globals.gidDropPrivKeepSupplemental) { res = setgroups(0, NULL); /* remove all supplemental group IDs */ if (res) { LogError(errno, RS_RET_ERR_DROP_PRIV, "could not remove supplemental group IDs"); ABORT_FINALIZE(RS_RET_ERR_DROP_PRIV); } DBGPRINTF("setgroups(0, NULL): %d\n", res); } res = setgid(cnf->globals.gidDropPriv); if (res) { LogError(errno, RS_RET_ERR_DROP_PRIV, "could not set requested group id %d via setgid()", cnf->globals.gidDropPriv); ABORT_FINALIZE(RS_RET_ERR_DROP_PRIV); } DBGPRINTF("setgid(%d): %d\n", cnf->globals.gidDropPriv, res); snprintf((char *)szBuf, sizeof(szBuf), "rsyslogd's groupid changed to %d", cnf->globals.gidDropPriv); logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, szBuf, 0); finalize_it: RETiRet; } /* drop to specified user * if something goes wrong, the function never returns * Note that such an abort can cause damage to on-disk structures, so we should * re-design the "interface" in the long term. -- rgerhards, 2008-11-19 */ static void doDropPrivUid(rsconf_t *cnf) { int res; uchar szBuf[1024]; struct passwd *pw; gid_t gid; /* Try to set appropriate supplementary groups for this user. * Failure is not fatal. */ pw = getpwuid(cnf->globals.uidDropPriv); if (pw) { gid = getgid(); res = initgroups(pw->pw_name, gid); DBGPRINTF("initgroups(%s, %ld): %d\n", pw->pw_name, (long)gid, res); } else { LogError(errno, NO_ERRCODE, "could not get username for userid '%d'", cnf->globals.uidDropPriv); } res = setuid(cnf->globals.uidDropPriv); if (res) { /* if we can not set the userid, this is fatal, so let's unconditionally abort */ perror("could not set requested userid"); exit(1); } DBGPRINTF("setuid(%d): %d\n", cnf->globals.uidDropPriv, res); snprintf((char *)szBuf, sizeof(szBuf), "rsyslogd's userid changed to %d", cnf->globals.uidDropPriv); logmsgInternal(NO_ERRCODE, LOG_SYSLOG | LOG_INFO, szBuf, 0); } /* drop privileges. This will drop to the configured privileges, if * set by the user. After this method has been executed, the previous * privileges can no be re-gained. */ static rsRetVal dropPrivileges(rsconf_t *cnf) { DEFiRet; if (cnf->globals.gidDropPriv != 0) { CHKiRet(doDropPrivGid(cnf)); DBGPRINTF("group privileges have been dropped to gid %u\n", (unsigned)cnf->globals.gidDropPriv); } if (cnf->globals.uidDropPriv != 0) { doDropPrivUid(cnf); DBGPRINTF("user privileges have been dropped to uid %u\n", (unsigned)cnf->globals.uidDropPriv); } finalize_it: RETiRet; } /* tell the rsysog core (including ourselfs) that the config load is done and * we need to prepare to move over to activate mode. */ static inline rsRetVal tellCoreConfigLoadDone(void) { DBGPRINTF("telling rsyslog core that config load for %p is done\n", loadConf); return glblDoneLoadCnf(); } /* Tell input modules that the config parsing stage is over. */ static rsRetVal tellModulesConfigLoadDone(void) { cfgmodules_etry_t *node; DBGPRINTF("telling modules that config load for %p is done\n", loadConf); node = module.GetNxtCnfType(loadConf, NULL, eMOD_ANY); while (node != NULL) { DBGPRINTF("beginCnfLoad(%p) for module '%s'\n", node->pMod->beginCnfLoad, node->pMod->pszName); if (node->pMod->beginCnfLoad != NULL) { DBGPRINTF("calling endCnfLoad() for module '%s'\n", node->pMod->pszName); node->pMod->endCnfLoad(node->modCnf); } node = module.GetNxtCnfType(loadConf, node, eMOD_ANY); // loadConf -> runConf } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* Tell input modules to verify config object */ static rsRetVal tellModulesCheckConfig(void) { cfgmodules_etry_t *node; rsRetVal localRet; DBGPRINTF("telling modules to check config %p\n", loadConf); node = module.GetNxtCnfType(loadConf, NULL, eMOD_ANY); while (node != NULL) { if (node->pMod->beginCnfLoad != NULL) { localRet = node->pMod->checkCnf(node->modCnf); DBGPRINTF("module %s tells us config can %sbe activated\n", node->pMod->pszName, (localRet == RS_RET_OK) ? "" : "NOT "); if (localRet == RS_RET_OK) { node->canActivate = 1; } else { node->canActivate = 0; } } node = module.GetNxtCnfType(loadConf, node, eMOD_ANY); // runConf -> loadConf } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* verify parser instances after full config load */ static rsRetVal checkParserInstances(void) { parserList_t *node; rsRetVal localRet; DEFiRet; node = loadConf->parsers.pParsLstRoot; while (node != NULL) { if (node->pParser->pModule->mod.pm.checkParserInst != NULL) { localRet = node->pParser->pModule->mod.pm.checkParserInst(node->pParser->pInst); if (localRet != RS_RET_OK) { iRet = localRet; break; } } node = node->pNext; } RETiRet; } /* Tell modules to activate current running config (pre privilege drop) */ static rsRetVal tellModulesActivateConfigPrePrivDrop(void) { cfgmodules_etry_t *node; rsRetVal localRet; DBGPRINTF("telling modules to activate config (before dropping privs) %p\n", runConf); node = module.GetNxtCnfType(runConf, NULL, eMOD_ANY); while (node != NULL) { if (node->pMod->beginCnfLoad != NULL && node->pMod->activateCnfPrePrivDrop != NULL && node->canActivate) { DBGPRINTF("pre priv drop activating config %p for module %s\n", runConf, node->pMod->pszName); localRet = node->pMod->activateCnfPrePrivDrop(node->modCnf); if (localRet != RS_RET_OK) { LogError(0, localRet, "activation of module %s failed", node->pMod->pszName); node->canActivate = 0; /* in a sense, could not activate... */ } } node = module.GetNxtCnfType(runConf, node, eMOD_ANY); } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* Tell modules to activate current running config */ static rsRetVal tellModulesActivateConfig(void) { cfgmodules_etry_t *node; rsRetVal localRet; DBGPRINTF("telling modules to activate config %p\n", runConf); node = module.GetNxtCnfType(runConf, NULL, eMOD_ANY); while (node != NULL) { if (node->pMod->beginCnfLoad != NULL && node->canActivate) { DBGPRINTF("activating config %p for module %s\n", runConf, node->pMod->pszName); localRet = node->pMod->activateCnf(node->modCnf); if (localRet != RS_RET_OK) { LogError(0, localRet, "activation of module %s failed", node->pMod->pszName); node->canActivate = 0; /* in a sense, could not activate... */ } } node = module.GetNxtCnfType(runConf, node, eMOD_ANY); } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* Actually run the input modules. This happens after privileges are dropped, * if that is requested. */ static rsRetVal runInputModules(void) { cfgmodules_etry_t *node; int bNeedsCancel; node = module.GetNxtCnfType(runConf, NULL, eMOD_IN); while (node != NULL) { if (node->canRun) { bNeedsCancel = (node->pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? 0 : 1; DBGPRINTF("running module %s with config %p, term mode: %s\n", node->pMod->pszName, node, bNeedsCancel ? "cancel" : "cooperative/SIGTTIN"); thrdCreate(node->pMod->mod.im.runInput, node->pMod->mod.im.afterRun, bNeedsCancel, (node->pMod->cnfName == NULL) ? node->pMod->pszName : node->pMod->cnfName); } node = module.GetNxtCnfType(runConf, node, eMOD_IN); } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* Make the modules check if they are ready to start. */ static rsRetVal startInputModules(void) { DEFiRet; cfgmodules_etry_t *node; node = module.GetNxtCnfType(runConf, NULL, eMOD_IN); while (node != NULL) { if (node->canActivate) { iRet = node->pMod->mod.im.willRun(); node->canRun = (iRet == RS_RET_OK); if (!node->canRun) { DBGPRINTF("module %s will not run, iRet %d\n", node->pMod->pszName, iRet); } } else { node->canRun = 0; } node = module.GetNxtCnfType(runConf, node, eMOD_IN); } return RS_RET_OK; /* intentional: we do not care about module errors */ } /* load the main queue */ static rsRetVal loadMainQueue(void) { DEFiRet; struct cnfobj *mainqCnfObj; mainqCnfObj = glbl.GetmainqCnfObj(); DBGPRINTF("loadMainQueue: mainq cnf obj ptr is %p\n", mainqCnfObj); /* create message queue */ iRet = createMainQueue(&loadConf->pMsgQueue, UCHAR_CONSTANT("main Q"), (mainqCnfObj == NULL) ? NULL : mainqCnfObj->nvlst); if (iRet == RS_RET_OK) { if (runConf != NULL) { /* dynamic config reload */ int areEqual = queuesEqual(loadConf->pMsgQueue, runConf->pMsgQueue); DBGPRINTF("Comparison of old and new main queues: %d\n", areEqual); if (areEqual) { /* content of the new main queue is the same as it was in previous conf */ qqueueDestruct(&loadConf->pMsgQueue); loadConf->pMsgQueue = runConf->pMsgQueue; } } } if (iRet != RS_RET_OK) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); FINALIZE; } finalize_it: glblDestructMainqCnfObj(); RETiRet; } /* activate the main queue */ static rsRetVal activateMainQueue(void) { DEFiRet; DBGPRINTF("activateMainQueue: will try to activate main queue %p\n", runConf->pMsgQueue); iRet = startMainQueue(runConf, runConf->pMsgQueue); if (iRet != RS_RET_OK) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); FINALIZE; } if (runConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT) { PREFER_STORE_0_TO_INT(&bHaveMainQueue); } else { PREFER_STORE_1_TO_INT(&bHaveMainQueue); } DBGPRINTF("Main processing queue is initialized and running\n"); finalize_it: RETiRet; } /* set the processes umask (upon configuration request) */ static inline rsRetVal setUmask(int iUmask) { if (iUmask != -1) { umask(iUmask); DBGPRINTF("umask set to 0%3.3o.\n", iUmask); } return RS_RET_OK; } /* Remove resources from previous config */ static void cleanupOldCnf(rsconf_t *cnf) { if (cnf == NULL) FINALIZE; if (runConf->pMsgQueue != cnf->pMsgQueue) qqueueDestruct(&cnf->pMsgQueue); finalize_it: return; } /* Activate an already-loaded configuration. The configuration will become * the new running conf (if successful). Note that in theory this method may * be called when there already is a running conf. In practice, the current * version of rsyslog does not support this. Future versions probably will. * Begun 2011-04-20, rgerhards */ static rsRetVal activate(rsconf_t *cnf) { DEFiRet; rsconf_t *runCnfOld = runConf; /* at this point, we "switch" over to the running conf */ runConf = cnf; loadConf = NULL; #if 0 /* currently the DAG is not supported -- code missing! */ /* TODO: re-enable this functionality some time later! */ /* check if we need to generate a config DAG and, if so, do that */ if(ourConf->globals.pszConfDAGFile != NULL) generateConfigDAG(ourConf->globals.pszConfDAGFile); #endif setUmask(cnf->globals.umask); /* the output part and the queue is now ready to run. So it is a good time * to initialize the inputs. Please note that the net code above should be * shuffled to down here once we have everything in input modules. * rgerhards, 2007-12-14 * NOTE: as of 2009-06-29, the input modules are initialized, but not yet run. * Keep in mind. though, that the outputs already run if the queue was * persisted to disk. -- rgerhards */ tellModulesActivateConfigPrePrivDrop(); CHKiRet(dropPrivileges(cnf)); lookupActivateConf(); tellModulesActivateConfig(); startInputModules(); CHKiRet(activateActions()); CHKiRet(activateRulesetQueues()); CHKiRet(activateMainQueue()); /* finally let the inputs run... */ runInputModules(); qqueueDoneLoadCnf(); /* we no longer need config-load-only data structures */ dbgprintf("configuration %p activated\n", cnf); cleanupOldCnf(runCnfOld); finalize_it: RETiRet; } /* -------------------- some legacy config handlers -------------------- * TODO: move to conf.c? */ /* legacy config system: set the action resume interval */ static rsRetVal setActionResumeInterval(void __attribute__((unused)) * pVal, int iNewVal) { return actionSetGlobalResumeInterval(iNewVal); } /* Switch the default ruleset (that, what servcies bind to if nothing specific * is specified). * rgerhards, 2009-06-12 */ static rsRetVal setDefaultRuleset(void __attribute__((unused)) * pVal, uchar *pszName) { DEFiRet; CHKiRet(ruleset.SetDefaultRuleset(ourConf, pszName)); finalize_it: free(pszName); /* no longer needed */ RETiRet; } /* Switch to either an already existing rule set or start a new one. The * named rule set becomes the new "current" rule set (what means that new * actions are added to it). * rgerhards, 2009-06-12 */ static rsRetVal setCurrRuleset(void __attribute__((unused)) * pVal, uchar *pszName) { ruleset_t *pRuleset; rsRetVal localRet; DEFiRet; localRet = ruleset.SetCurrRuleset(ourConf, pszName); if (localRet == RS_RET_NOT_FOUND) { DBGPRINTF("begin new current rule set '%s'\n", pszName); CHKiRet(ruleset.Construct(&pRuleset)); CHKiRet(ruleset.SetName(pRuleset, pszName)); CHKiRet(ruleset.ConstructFinalize(ourConf, pRuleset)); rulesetSetCurrRulesetPtr(pRuleset); } else { ABORT_FINALIZE(localRet); } finalize_it: free(pszName); /* no longer needed */ RETiRet; } /* set the main message queue mode * rgerhards, 2008-01-03 */ static rsRetVal setMainMsgQueType(void __attribute__((unused)) * pVal, uchar *pszType) { DEFiRet; if (!strcasecmp((char *)pszType, "fixedarray")) { loadConf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; DBGPRINTF("main message queue type set to FIXED_ARRAY\n"); } else if (!strcasecmp((char *)pszType, "linkedlist")) { loadConf->globals.mainQ.MainMsgQueType = QUEUETYPE_LINKEDLIST; DBGPRINTF("main message queue type set to LINKEDLIST\n"); } else if (!strcasecmp((char *)pszType, "disk")) { loadConf->globals.mainQ.MainMsgQueType = QUEUETYPE_DISK; DBGPRINTF("main message queue type set to DISK\n"); } else if (!strcasecmp((char *)pszType, "direct")) { loadConf->globals.mainQ.MainMsgQueType = QUEUETYPE_DIRECT; DBGPRINTF("main message queue type set to DIRECT (no queueing at all)\n"); } else { LogError(0, RS_RET_INVALID_PARAMS, "unknown mainmessagequeuetype parameter: %s", (char *)pszType); iRet = RS_RET_INVALID_PARAMS; } free(pszType); /* no longer needed */ RETiRet; } /* -------------------- end legacy config handlers -------------------- */ /* set the processes max number ob files (upon configuration request) * 2009-04-14 rgerhards */ static rsRetVal setMaxFiles(void __attribute__((unused)) * pVal, int iFiles) { // TODO this must use a local var, then carry out action during activate! struct rlimit maxFiles; char errStr[1024]; DEFiRet; maxFiles.rlim_cur = iFiles; maxFiles.rlim_max = iFiles; if (setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { /* NOTE: under valgrind, we seem to be unable to extend the size! */ rs_strerror_r(errno, errStr, sizeof(errStr)); LogError(0, RS_RET_ERR_RLIM_NOFILE, "could not set process file limit to %d: %s " "[kernel max %ld]", iFiles, errStr, (long)maxFiles.rlim_max); ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); } #ifdef USE_UNLIMITED_SELECT glbl.SetFdSetSize(howmany(iFiles, __NFDBITS) * sizeof(fd_mask)); #endif DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long)maxFiles.rlim_max); finalize_it: RETiRet; } /* legacy config system: reset config variables to default values. */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { free(loadConf->globals.mainQ.pszMainMsgQFName); cnfSetDefaults(loadConf); return RS_RET_OK; } /* legacy config system: set the action resume interval */ static rsRetVal setModDir(void __attribute__((unused)) * pVal, uchar *pszNewVal) { DEFiRet; iRet = module.SetModDir(pszNewVal); free(pszNewVal); RETiRet; } /* "load" a build in module and register it for the current load config */ static rsRetVal regBuildInModule(rsRetVal (*modInit)(), uchar *name, void *pModHdlr) { cfgmodules_etry_t *pNew; cfgmodules_etry_t *pLast; modInfo_t *pMod; DEFiRet; CHKiRet(module.doModInit(modInit, name, pModHdlr, &pMod)); readyModForCnf(pMod, &pNew, &pLast); addModToCnfList(&pNew, pLast); finalize_it: RETiRet; } /* load build-in modules * very first version begun on 2007-07-23 by rgerhards */ static rsRetVal loadBuildInModules(void) { DEFiRet; CHKiRet(regBuildInModule(modInitFile, UCHAR_CONSTANT("builtin:omfile"), NULL)); CHKiRet(regBuildInModule(modInitPipe, UCHAR_CONSTANT("builtin:ompipe"), NULL)); CHKiRet(regBuildInModule(modInitShell, UCHAR_CONSTANT("builtin-shell"), NULL)); CHKiRet(regBuildInModule(modInitDiscard, UCHAR_CONSTANT("builtin:omdiscard"), NULL)); #ifdef SYSLOG_INET CHKiRet(regBuildInModule(modInitFwd, UCHAR_CONSTANT("builtin:omfwd"), NULL)); #endif /* dirty, but this must be for the time being: the usrmsg module must always be * loaded as last module. This is because it processes any type of action selector. * If we load it before other modules, these others will never have a chance of * working with the config file. We may change that implementation so that a user name * must start with an alnum, that would definitely help (but would it break backwards * compatibility?). * rgerhards, 2007-07-23 * User names now must begin with: * [a-zA-Z0-9_.] */ CHKiRet(regBuildInModule(modInitUsrMsg, (uchar *)"builtin:omusrmsg", NULL)); /* load build-in parser modules */ CHKiRet(regBuildInModule(modInitpmrfc5424, UCHAR_CONSTANT("builtin:pmrfc5424"), NULL)); CHKiRet(regBuildInModule(modInitpmrfc3164, UCHAR_CONSTANT("builtin:pmrfc3164"), NULL)); /* and set default parser modules. Order is *very* important, legacy * (3164) parser needs to go last! */ CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc5424"))); CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164"))); /* load build-in strgen modules */ CHKiRet(regBuildInModule(modInitsmfile, UCHAR_CONSTANT("builtin:smfile"), NULL)); CHKiRet(regBuildInModule(modInitsmtradfile, UCHAR_CONSTANT("builtin:smtradfile"), NULL)); CHKiRet(regBuildInModule(modInitsmfwd, UCHAR_CONSTANT("builtin:smfwd"), NULL)); CHKiRet(regBuildInModule(modInitsmtradfwd, UCHAR_CONSTANT("builtin:smtradfwd"), NULL)); finalize_it: if (iRet != RS_RET_OK) { /* we need to do fprintf, as we do not yet have an error reporting system * in place. */ fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", iRet); } RETiRet; } /* initialize the legacy config system */ static rsRetVal initLegacyConf(void) { DEFiRet; uchar *pTmp; ruleset_t *pRuleset; DBGPRINTF("doing legacy config system init\n"); /* construct the default ruleset */ ruleset.Construct(&pRuleset); ruleset.SetName(pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); ruleset.ConstructFinalize(loadConf, pRuleset); rulesetSetCurrRulesetPtr(pRuleset); /* now register config handlers */ CHKiRet(regCfSysLineHdlr((uchar *)"sleep", 0, eCmdHdlrGoneAway, NULL, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &loadConf->globals.bLogStatusMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &loadConf->globals.bErrMsgToStderr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"abortonuncleanconfig", 0, eCmdHdlrBinary, NULL, &loadConf->globals.bAbortOnUncleanConfig, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &loadConf->globals.bReduceRepeatMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &(loadConf->globals.bDebugPrintTemplateList), NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &(loadConf->globals.bDebugPrintModuleList), NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, NULL, &(loadConf->globals.bDebugPrintCfSysLineHandlerList), NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouser", 0, eCmdHdlrUID, NULL, &loadConf->globals.uidDropPriv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptouserid", 0, eCmdHdlrInt, NULL, &loadConf->globals.uidDropPriv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroup", 0, eCmdHdlrGID, NULL, &loadConf->globals.gidDropPriv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"privdroptogroupid", 0, eCmdHdlrInt, NULL, &loadConf->globals.gidDropPriv, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"generateconfiggraph", 0, eCmdHdlrGetWord, NULL, &loadConf->globals.pszConfDAGFile, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, NULL, &loadConf->globals.umask, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL)); /* handler for "larger" config statements (tie into legacy conf system) */ CHKiRet( regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void *)DIR_TEMPLATE, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void *)DIR_OUTCHANNEL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void *)DIR_ALLOWEDSENDER, NULL)); /* the following are parameters for the main message queue. I have the * strong feeling that this needs to go to a different space, but that * feeling may be wrong - we'll see how things evolve. * rgerhards, 2011-04-21 */ CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &loadConf->globals.mainQ.pszMainMsgQFName, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQueueSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuehighwatermark", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQHighWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuelowwatermark", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQLowWtrMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardmark", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQDiscardMark, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuediscardseverity", 0, eCmdHdlrSeverity, NULL, &loadConf->globals.mainQ.iMainMsgQDiscardSeverity, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuecheckpointinterval", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQPersistUpdCnt, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesyncqueuefiles", 0, eCmdHdlrBinary, NULL, &loadConf->globals.mainQ.bMainMsgQSyncQeueFiles, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetype", 0, eCmdHdlrGetWord, setMainMsgQueType, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreads", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQueueNumWorkers, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutshutdown", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQtoQShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutactioncompletion", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQtoActShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuetimeoutenqueue", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQtoEnq, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkertimeoutthreadshutdown", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQtoWrkShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQDeqSlowdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueueworkerthreadminimummessages", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQWrkMinMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &loadConf->globals.mainQ.iMainMsgQueMaxFileSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuebatchsize", 0, eCmdHdlrSize, NULL, &loadConf->globals.mainQ.iMainMsgQueDeqBatchSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &loadConf->globals.mainQ.iMainMsgQueMaxDiskSpace, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &loadConf->globals.mainQ.bMainMsgQSaveOnShutdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &loadConf->globals.mainQ.iMainMsgQueueDeqtWinToHr, NULL)); /* moddir is a bit hard problem -- because it actually needs to * modify a setting that is specific to module.c. The important point * is that this action MUST actually be carried out during config load, * because we must load modules in order to get their config extensions * (no way around). * TODO: think about a clean solution */ CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, setModDir, NULL, NULL)); /* finally, the reset handler */ CHKiRet( regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); /* initialize the build-in templates */ pTmp = template_DebugFormat; tplAddLine(ourConf, "RSYSLOG_DebugFormat", &pTmp); pTmp = template_SyslogProtocol23Format; tplAddLine(ourConf, "RSYSLOG_SyslogProtocol23Format", &pTmp); pTmp = template_SyslogRFC5424Format; tplAddLine(ourConf, "RSYSLOG_SyslogRFC5424Format", &pTmp); pTmp = template_FileFormat; /* new format for files with high-precision stamp */ tplAddLine(ourConf, "RSYSLOG_FileFormat", &pTmp); pTmp = template_TraditionalFileFormat; tplAddLine(ourConf, "RSYSLOG_TraditionalFileFormat", &pTmp); pTmp = template_WallFmt; tplAddLine(ourConf, " WallFmt", &pTmp); pTmp = template_ForwardFormat; tplAddLine(ourConf, "RSYSLOG_ForwardFormat", &pTmp); pTmp = template_TraditionalForwardFormat; tplAddLine(ourConf, "RSYSLOG_TraditionalForwardFormat", &pTmp); pTmp = template_StdUsrMsgFmt; tplAddLine(ourConf, " StdUsrMsgFmt", &pTmp); pTmp = template_StdDBFmt; tplAddLine(ourConf, " StdDBFmt", &pTmp); pTmp = template_SysklogdFileFormat; tplAddLine(ourConf, "RSYSLOG_SysklogdFileFormat", &pTmp); pTmp = template_StdPgSQLFmt; tplAddLine(ourConf, " StdPgSQLFmt", &pTmp); pTmp = template_StdJSONFmt; tplAddLine(ourConf, " StdJSONFmt", &pTmp); pTmp = template_FullJSONFmt; tplAddLine(ourConf, " FullJSONFmt", &pTmp); pTmp = template_StdClickHouseFmt; tplAddLine(ourConf, " StdClickHouseFmt", &pTmp); pTmp = template_StdOmSenderTrack_senderid; tplAddLine(ourConf, " StdOmSenderTrack-senderid", &pTmp); pTmp = template_spoofadr; tplLastStaticInit(ourConf, tplAddLine(ourConf, "RSYSLOG_omudpspoofDfltSourceTpl", &pTmp)); finalize_it: RETiRet; } /* validate the configuration pointed by conf, generate error messages, do * optimizations, etc, etc,... */ static rsRetVal validateConf(rsconf_t *cnf) { DEFiRet; /* some checks */ if (cnf->globals.mainQ.iMainMsgQueueNumWorkers < 1) { LogError(0, NO_ERRCODE, "$MainMsgQueueNumWorkers must be at least 1! Set to 1.\n"); cnf->globals.mainQ.iMainMsgQueueNumWorkers = 1; } if (cnf->globals.mainQ.MainMsgQueType == QUEUETYPE_DISK) { errno = 0; /* for logerror! */ if (glbl.GetWorkDir(cnf) == NULL) { LogError(0, NO_ERRCODE, "No $WorkDirectory specified - can not run main " "message queue in 'disk' mode. Using 'FixedArray' instead.\n"); cnf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } if (cnf->globals.mainQ.pszMainMsgQFName == NULL) { LogError(0, NO_ERRCODE, "No $MainMsgQueueFileName specified - can not run main " "message queue in 'disk' mode. Using 'FixedArray' instead.\n"); cnf->globals.mainQ.MainMsgQueType = QUEUETYPE_FIXED_ARRAY; } } RETiRet; } /* Load a configuration. This will do all necessary steps to create * the in-memory representation of the configuration, including support * for multiple configuration languages. * Note that to support the legacy language we must provide some global * object that holds the currently-being-loaded config ptr. * Begun 2011-04-20, rgerhards */ static rsRetVal load(rsconf_t **cnf, uchar *confFile) { int iNbrActions = 0; int r; rsRetVal delayed_iRet = RS_RET_OK; DEFiRet; CHKiRet(rsconfConstruct(&loadConf)); ourConf = loadConf; // TODO: remove, once ourConf is gone! CHKiRet(loadBuildInModules()); CHKiRet(initLegacyConf()); /* open the configuration file */ r = cnfSetLexFile((char *)confFile); if (r == 0) { r = yyparse(); conf.GetNbrActActions(loadConf, &iNbrActions); } /* we run the optimizer even if we have an error, as it may spit out * additional error messages and we want to see these even if we abort. */ rulesetOptimizeAll(loadConf); if (r == 1) { LogError(0, RS_RET_CONF_PARSE_ERROR, "could not interpret master " "config file '%s'.", confFile); /* we usually keep running with the failure, so we need to continue for now */ delayed_iRet = RS_RET_CONF_PARSE_ERROR; } else if (r == 2) { /* file not found? */ LogError(errno, RS_RET_CONF_FILE_NOT_FOUND, "could not open config file '%s'", confFile); ABORT_FINALIZE(RS_RET_CONF_FILE_NOT_FOUND); } else if ((iNbrActions == 0) && !(iConfigVerify & CONF_VERIFY_PARTIAL_CONF)) { LogError(0, RS_RET_NO_ACTIONS, "there are no active actions configured. " "Inputs would run, but no output whatsoever were created."); ABORT_FINALIZE(RS_RET_NO_ACTIONS); } tellLexEndParsing(); DBGPRINTF("Number of actions in this configuration: %d\n", loadConf->actions.iActionNbr); CHKiRet(tellCoreConfigLoadDone()); tellModulesConfigLoadDone(); tellModulesCheckConfig(); CHKiRet(checkParserInstances()); CHKiRet(validateConf(loadConf)); CHKiRet(loadMainQueue()); /* we are done checking the config - now validate if we should actually run or not. * If not, terminate. -- rgerhards, 2008-07-25 * TODO: iConfigVerify -- should it be pulled from the config, or leave as is (option)? */ if (iConfigVerify) { if (iRet == RS_RET_OK) iRet = RS_RET_VALIDATION_RUN; FINALIZE; } /* all OK, pass loaded conf to caller */ *cnf = loadConf; // TODO: enable this once all config code is moved to here! loadConf = NULL; dbgprintf("rsyslog finished loading master config %p\n", loadConf); rsconfDebugPrint(loadConf); finalize_it: if (iRet == RS_RET_OK && delayed_iRet != RS_RET_OK) { iRet = delayed_iRet; } RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(rsconf) CODESTARTobjQueryInterface(rsconf); if (pIf->ifVersion != rsconfCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Destruct = rsconfDestruct; pIf->DebugPrint = rsconfDebugPrint; pIf->Load = load; pIf->Activate = activate; finalize_it: ENDobjQueryInterface(rsconf) /* Initialize the rsconf class. Must be called as the very first method * before anything else is called inside this class. */ BEGINObjClassInit(rsconf, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); CHKiRet(objUse(conf, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); /* now set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, rsconfDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, rsconfConstructFinalize); ENDObjClassInit(rsconf) /* De-initialize the rsconf class. */ BEGINObjClassExit(rsconf, OBJ_IS_CORE_MODULE) /* class, version */ objRelease(ruleset, CORE_COMPONENT); objRelease(module, CORE_COMPONENT); objRelease(conf, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); ENDObjClassExit(rsconf) rsyslog-8.2512.0/runtime/PaxHeaders/zlibw.c0000644000000000000000000000013215055605325015515 xustar0030 mtime=1756826325.654800759 30 atime=1764931005.980110957 30 ctime=1764935923.415580133 rsyslog-8.2512.0/runtime/zlibw.c0000664000175000017500000001732015055605325015164 0ustar00rgerrger/* The zlibwrap object. * * This is an rsyslog object wrapper around zlib. * * Copyright 2009-2022 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "module-template.h" #include "obj.h" #include "stream.h" #include "zlibw.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; /* ------------------------------ methods ------------------------------ */ /* zlib make strong use of macros for its interface functions, so we can not simply * pass function pointers to them. Instead, we create very small wrappers which call * the relevant entry points. */ static int myDeflateInit(z_streamp strm, int level) { return deflateInit(strm, level); } static int myDeflateInit2(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy) { return deflateInit2(strm, level, method, windowBits, memLevel, strategy); } static int myDeflateEnd(z_streamp strm) { return deflateEnd(strm); } static int myDeflate(z_streamp strm, int flush) { return deflate(strm, flush); } /* finish zlib buffer */ static rsRetVal doCompressFinish(strm_t *pThis, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)) { int zRet; /* zlib return state */ DEFiRet; unsigned outavail; assert(pThis != NULL); assert(pThis->compressionDriver == STRM_COMPRESS_ZIP); if (!pThis->bzInitDone) goto done; pThis->zstrm.avail_in = 0; /* run deflate() on buffer until everything has been compressed */ do { DBGPRINTF("in deflate() loop, avail_in %d, total_in %ld\n", pThis->zstrm.avail_in, pThis->zstrm.total_in); pThis->zstrm.avail_out = pThis->sIOBufSize; pThis->zstrm.next_out = pThis->pZipBuf; zRet = deflate(&pThis->zstrm, Z_FINISH); /* no bad return value */ DBGPRINTF("after deflate, ret %d, avail_out %d\n", zRet, pThis->zstrm.avail_out); outavail = pThis->sIOBufSize - pThis->zstrm.avail_out; if (outavail != 0) { CHKiRet(strmPhysWrite(pThis, (uchar *)pThis->pZipBuf, outavail)); } } while (pThis->zstrm.avail_out == 0); finalize_it: zRet = deflateEnd(&pThis->zstrm); if (zRet != Z_OK) { LogError(0, RS_RET_ZLIB_ERR, "error %d returned from zlib/deflateEnd()", zRet); } pThis->bzInitDone = 0; done: RETiRet; } /* write the output buffer in zip mode * This means we compress it first and then do a physical write. * Note that we always do a full deflateInit ... deflate ... deflateEnd * sequence. While this is not optimal, we need to do it because we need * to ensure that the file is readable even when we are aborted. Doing the * full sequence brings us as far towards this goal as possible (and not * doing it would be a total failure). It may be worth considering to * add a config switch so that the user can decide the risk he is ready * to take, but so far this is not yet implemented (not even requested ;)). * rgerhards, 2009-06-04 */ static rsRetVal doStrmWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf, const int bFlush, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)) { int zRet; /* zlib return state */ DEFiRet; unsigned outavail = 0; assert(pThis != NULL); assert(pBuf != NULL); assert(pThis->compressionDriver == STRM_COMPRESS_ZIP); if (!pThis->bzInitDone) { /* allocate deflate state */ pThis->zstrm.zalloc = Z_NULL; pThis->zstrm.zfree = Z_NULL; pThis->zstrm.opaque = Z_NULL; /* see note in file header for the params we use with deflateInit2() */ zRet = deflateInit2(&pThis->zstrm, pThis->iZipLevel, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY); if (zRet != Z_OK) { LogError(0, RS_RET_ZLIB_ERR, "error %d returned from zlib/deflateInit2()", zRet); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } pThis->bzInitDone = RSTRUE; } /* now doing the compression */ pThis->zstrm.next_in = (Bytef *)pBuf; pThis->zstrm.avail_in = lenBuf; /* run deflate() on buffer until everything has been compressed */ do { DBGPRINTF("in deflate() loop, avail_in %d, total_in %ld, bFlush %d\n", pThis->zstrm.avail_in, pThis->zstrm.total_in, bFlush); pThis->zstrm.avail_out = pThis->sIOBufSize; pThis->zstrm.next_out = pThis->pZipBuf; zRet = deflate(&pThis->zstrm, bFlush ? Z_SYNC_FLUSH : Z_NO_FLUSH); /* no bad return value */ DBGPRINTF("after deflate, ret %d, avail_out %d, to write %d\n", zRet, pThis->zstrm.avail_out, outavail); if (zRet != Z_OK) { LogError(0, RS_RET_ZLIB_ERR, "error %d returned from zlib/Deflate()", zRet); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } outavail = pThis->sIOBufSize - pThis->zstrm.avail_out; if (outavail != 0) { CHKiRet(strmPhysWrite(pThis, (uchar *)pThis->pZipBuf, outavail)); } } while (pThis->zstrm.avail_out == 0); finalize_it: if (pThis->bzInitDone && pThis->bVeryReliableZip) { doCompressFinish(pThis, strmPhysWrite); } RETiRet; } /* destruction of caller's zlib ressources - a dummy for us */ static rsRetVal zlib_Destruct(ATTR_UNUSED strm_t *pThis) { return RS_RET_OK; } /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(zlibw) CODESTARTobjQueryInterface(zlibw); if (pIf->ifVersion != zlibwCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->DeflateInit = myDeflateInit; pIf->DeflateInit2 = myDeflateInit2; pIf->Deflate = myDeflate; pIf->DeflateEnd = myDeflateEnd; pIf->doStrmWrite = doStrmWrite; pIf->doCompressFinish = doCompressFinish; pIf->Destruct = zlib_Destruct; finalize_it: ENDobjQueryInterface(zlibw) /* Initialize the zlibw class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(zlibw, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ /* set our own handlers */ ENDObjClassInit(zlibw) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CHKiRet(zlibwClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ /* Initialize all classes that are in our module - this includes ourselfs */ ENDmodInit /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/objomsr.c0000644000000000000000000000013215055605325016041 xustar0030 mtime=1756826325.650800698 30 atime=1764930985.795774748 30 ctime=1764935923.171576397 rsyslog-8.2512.0/runtime/objomsr.c0000664000175000017500000001045715055605325015514 0ustar00rgerrger/* objomsr.c * Implementation of the omsr (omodStringRequest) object. * * File begun on 2007-07-27 by RGerhards * * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include "rsyslog.h" #include "objomsr.h" /* destructor */ rsRetVal OMSRdestruct(omodStringRequest_t *pThis) { int i; assert(pThis != NULL); /* free the strings */ if (pThis->ppTplName != NULL) { for (i = 0; i < pThis->iNumEntries; ++i) { free(pThis->ppTplName[i]); } free(pThis->ppTplName); } if (pThis->piTplOpts != NULL) free(pThis->piTplOpts); free(pThis); return RS_RET_OK; } /* constructor */ rsRetVal OMSRconstruct(omodStringRequest_t **ppThis, int iNumEntries) { omodStringRequest_t *pThis = NULL; DEFiRet; assert(ppThis != NULL); assert(iNumEntries >= 0); if (iNumEntries > CONF_OMOD_NUMSTRINGS_MAXSIZE) { ABORT_FINALIZE(RS_RET_MAX_OMSR_REACHED); } CHKmalloc(pThis = calloc(1, sizeof(omodStringRequest_t))); /* got the structure, so fill it */ if (iNumEntries > 0) { pThis->iNumEntries = iNumEntries; /* allocate string for template name array. The individual strings will be * allocated as the code progresses (we do not yet know the string sizes) */ CHKmalloc(pThis->ppTplName = calloc(iNumEntries, sizeof(uchar *))); /* allocate the template options array. */ CHKmalloc(pThis->piTplOpts = calloc(iNumEntries, sizeof(int))); } finalize_it: if (iRet != RS_RET_OK) { if (pThis != NULL) { OMSRdestruct(pThis); pThis = NULL; } } *ppThis = pThis; RETiRet; } /* set a template name and option to the object. Index must be given. The pTplName must be * pointing to memory that can be freed. If in doubt, the caller must strdup() the value. */ rsRetVal OMSRsetEntry(omodStringRequest_t *pThis, int iEntry, uchar *pTplName, int iTplOpts) { assert(pThis != NULL); assert(iEntry < pThis->iNumEntries); if (pThis->ppTplName[iEntry] != NULL) free(pThis->ppTplName[iEntry]); pThis->ppTplName[iEntry] = pTplName; pThis->piTplOpts[iEntry] = iTplOpts; return RS_RET_OK; } /* get number of entries for this object */ int OMSRgetEntryCount(omodStringRequest_t *pThis) { assert(pThis != NULL); return pThis->iNumEntries; } /* return data for a specific entry. All data returned is * read-only and lasts only as long as the object lives. If the caller * needs it for an extended period of time, the caller must copy the * strings. Please note that the string pointer may be NULL, which is the * case when it was never set. */ int OMSRgetEntry(omodStringRequest_t *pThis, int iEntry, uchar **ppTplName, int *piTplOpts) { assert(pThis != NULL); assert(ppTplName != NULL); assert(piTplOpts != NULL); assert(iEntry < pThis->iNumEntries); *ppTplName = pThis->ppTplName[iEntry]; *piTplOpts = pThis->piTplOpts[iEntry]; return RS_RET_OK; } /* return the full set of template options that are supported by this version of * OMSR. They are returned in an unsigned long value. The caller can mask that * value to check on the option he is interested in. * Note that this interface was added in 4.1.6, so a plugin must obtain a pointer * to this interface via queryHostEtryPt(). * rgerhards, 2009-04-03 */ rsRetVal OMSRgetSupportedTplOpts(unsigned long *pOpts) { DEFiRet; assert(pOpts != NULL); *pOpts = OMSR_RQD_TPL_OPT_SQL | OMSR_TPL_AS_ARRAY | OMSR_TPL_AS_MSG | OMSR_TPL_AS_JSON; RETiRet; } /* vim:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/wtp.c0000644000000000000000000000013215071746523015204 xustar0030 mtime=1760021843.878421617 30 atime=1764930993.861909319 30 ctime=1764935923.244577514 rsyslog-8.2512.0/runtime/wtp.c0000664000175000017500000005440515071746523014660 0ustar00rgerrger/* wtp.c * * This file implements the worker thread pool (wtp) class. * * File begun on 2008-01-20 by RGerhards * * There is some in-depth documentation available in doc/dev_queue.html * (and in the web doc set on https://www.rsyslog.com/doc/). Be sure to read it * if you are getting aquainted to the object. * * Copyright 2008-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_PRCTL_H #include #endif #include "rsyslog.h" #include "stringbuf.h" #include "srUtils.h" #include "wtp.h" #include "wti.h" #include "obj.h" #include "unicode-helper.h" #include "glbl.h" #include "errmsg.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) /* forward-definitions */ /* methods */ /* get the header for debug messages * The caller must NOT free or otherwise modify the returned string! */ static uchar *wtpGetDbgHdr(wtp_t *pThis) { ISOBJ_TYPE_assert(pThis, wtp); if (pThis->pszDbgHdr == NULL) return (uchar *)"wtp"; /* should not normally happen */ else return pThis->pszDbgHdr; } /* Not implemented dummy function for constructor */ static rsRetVal NotImplementedDummy_voidp_int(__attribute__((unused)) void *p1, __attribute__((unused)) int p2) { return RS_RET_NOT_IMPLEMENTED; } static rsRetVal NotImplementedDummy_voidp_intp(__attribute__((unused)) void *p1, __attribute__((unused)) int *p2) { return RS_RET_NOT_IMPLEMENTED; } static rsRetVal NotImplementedDummy_voidp_voidp(__attribute__((unused)) void *p1, __attribute__((unused)) void *p2) { return RS_RET_NOT_IMPLEMENTED; } static rsRetVal NotImplementedDummy_voidp_wti_tp(__attribute__((unused)) void *p1, __attribute__((unused)) wti_t *p2) { return RS_RET_NOT_IMPLEMENTED; } /* Standard-Constructor for the wtp object */ BEGINobjConstruct(wtp) /* be sure to specify the object type also in END macro! */ pthread_mutex_init(&pThis->mutWtp, NULL); pthread_cond_init(&pThis->condThrdInitDone, NULL); pthread_cond_init(&pThis->condThrdTrm, NULL); pthread_attr_init(&pThis->attrThrd); /* Set thread scheduling policy to default */ #ifdef HAVE_PTHREAD_SETSCHEDPARAM pthread_attr_setschedpolicy(&pThis->attrThrd, default_thr_sched_policy); pthread_attr_setschedparam(&pThis->attrThrd, &default_sched_param); pthread_attr_setinheritsched(&pThis->attrThrd, PTHREAD_EXPLICIT_SCHED); #endif /* set all function pointers to "not implemented" dummy so that we can safely call them */ pThis->pfChkStopWrkr = (rsRetVal(*)(void *, int))NotImplementedDummy_voidp_int; pThis->pfGetDeqBatchSize = (rsRetVal(*)(void *, int *))NotImplementedDummy_voidp_intp; pThis->pfDoWork = (rsRetVal(*)(void *, void *))NotImplementedDummy_voidp_voidp; pThis->pfObjProcessed = (rsRetVal(*)(void *, wti_t *))NotImplementedDummy_voidp_wti_tp; INIT_ATOMIC_HELPER_MUT(pThis->mutCurNumWrkThrd); INIT_ATOMIC_HELPER_MUT(pThis->mutWtpState); ENDobjConstruct(wtp) /* Construction finalizer * rgerhards, 2008-01-17 */ rsRetVal wtpConstructFinalize(wtp_t *pThis) { DEFiRet; int i; uchar pszBuf[64]; size_t lenBuf; wti_t *pWti; ISOBJ_TYPE_assert(pThis, wtp); DBGPRINTF("%s: finalizing construction of worker thread pool (numworkerThreads %d)\n", wtpGetDbgHdr(pThis), pThis->iNumWorkerThreads); /* alloc and construct workers - this can only be done in finalizer as we previously do * not know the max number of workers */ CHKmalloc(pThis->pWrkr = malloc(sizeof(wti_t *) * pThis->iNumWorkerThreads)); for (i = 0; i < pThis->iNumWorkerThreads; ++i) { CHKiRet(wtiConstruct(&pThis->pWrkr[i])); pWti = pThis->pWrkr[i]; lenBuf = snprintf((char *)pszBuf, sizeof(pszBuf), "%.*s/w%d", (int)(sizeof(pszBuf) - 6), /* leave 6 chars for \0, "/w" and number: */ wtpGetDbgHdr(pThis), i); if (lenBuf >= sizeof(pszBuf)) { LogError(0, RS_RET_INTERNAL_ERROR, "%s:%d debug header too long: %zd - in " "thory this cannot happen - truncating", __FILE__, __LINE__, lenBuf); lenBuf = sizeof(pszBuf) - 1; pszBuf[lenBuf] = '\0'; } CHKiRet(wtiSetDbgHdr(pWti, pszBuf, lenBuf)); CHKiRet(wtiSetpWtp(pWti, pThis)); CHKiRet(wtiConstructFinalize(pWti)); } finalize_it: RETiRet; } /* Destructor */ BEGINobjDestruct(wtp) /* be sure to specify the object type also in END and CODESTART macros! */ int i; CODESTARTobjDestruct(wtp); d_pthread_mutex_lock(&pThis->mutWtp); /* make sure nobody is still using the mutex */ assert(pThis->iCurNumWrkThrd == 0); /* destruct workers */ for (i = 0; i < pThis->iNumWorkerThreads; ++i) wtiDestruct(&pThis->pWrkr[i]); free(pThis->pWrkr); pThis->pWrkr = NULL; /* actual destruction */ d_pthread_mutex_unlock(&pThis->mutWtp); pthread_cond_destroy(&pThis->condThrdTrm); pthread_cond_destroy(&pThis->condThrdInitDone); pthread_mutex_destroy(&pThis->mutWtp); pthread_attr_destroy(&pThis->attrThrd); DESTROY_ATOMIC_HELPER_MUT(pThis->mutCurNumWrkThrd); DESTROY_ATOMIC_HELPER_MUT(pThis->mutWtpState); free(pThis->pszDbgHdr); ENDobjDestruct(wtp) /* Sent a specific state for the worker thread pool. -- rgerhards, 2008-01-21 * We do not need to do atomic instructions as set operations are only * called when terminating the pool, and then in strict sequence. So we * can never overwrite each other. On the other hand, it also doesn't * matter if the read operation obtains an older value, as we then simply * do one more iteration, what is perfectly legal (during shutdown * they are awoken in any case). -- rgerhards, 2009-07-20 */ rsRetVal wtpSetState(wtp_t *pThis, wtpState_t iNewState) { ISOBJ_TYPE_assert(pThis, wtp); pThis->wtpState = iNewState; // TODO: do we need a mutex here? 2010-04-26 return RS_RET_OK; } /* join terminated worker threads */ static void ATTR_NONNULL() wtpJoinTerminatedWrkr(wtp_t *const pThis) { int i; for (i = 0; i < pThis->iNumWorkerThreads; ++i) { wtiJoinThrd(pThis->pWrkr[i]); } } /* check if the worker shall shutdown (1 = yes, 0 = no) * Note: there may be two mutexes locked, the bLockUsrMutex is the one in our "user" * (e.g. the queue clas) * rgerhards, 2008-01-21 */ rsRetVal wtpChkStopWrkr(wtp_t *pThis, int bLockUsrMutex) { DEFiRet; wtpState_t wtpState; ISOBJ_TYPE_assert(pThis, wtp); /* we need a consistent value, but it doesn't really matter if it is changed * right after the fetch - then we simply do one more iteration in the worker */ wtpState = (wtpState_t)ATOMIC_FETCH_32BIT((int *)&pThis->wtpState, &pThis->mutWtpState); if (wtpState == wtpState_SHUTDOWN_IMMEDIATE) { ABORT_FINALIZE(RS_RET_TERMINATE_NOW); } else if (wtpState == wtpState_SHUTDOWN) { ABORT_FINALIZE(RS_RET_TERMINATE_WHEN_IDLE); } /* try customer handler if one was set and we do not yet have a definite result */ if (pThis->pfChkStopWrkr != NULL) { iRet = pThis->pfChkStopWrkr(pThis->pUsr, bLockUsrMutex); } finalize_it: RETiRet; } PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wempty_body /* Send a shutdown command to all workers and see if they terminate. * A timeout may be specified. This function may also be called with * the current number of workers being 0, in which case it does not * shut down any worker. * rgerhards, 2008-01-14 */ rsRetVal ATTR_NONNULL() wtpShutdownAll(wtp_t *pThis, wtpState_t tShutdownCmd, struct timespec *ptTimeout) { DEFiRet; int bTimedOut; int i; ISOBJ_TYPE_assert(pThis, wtp); /* lock mutex to prevent races (may otherwise happen during idle processing and such...) */ d_pthread_mutex_lock(pThis->pmutUsr); wtpSetState(pThis, tShutdownCmd); /* awake workers in retry loop */ for (i = 0; i < pThis->iNumWorkerThreads; ++i) { wtpJoinTerminatedWrkr(pThis); pthread_cond_signal(&pThis->pWrkr[i]->pcondBusy); wtiWakeupThrd(pThis->pWrkr[i]); } d_pthread_mutex_unlock(pThis->pmutUsr); /* wait for worker thread termination */ d_pthread_mutex_lock(&pThis->mutWtp); pthread_cleanup_push(mutexCancelCleanup, &pThis->mutWtp); bTimedOut = 0; while (pThis->iCurNumWrkThrd > 0 && !bTimedOut) { wtpJoinTerminatedWrkr(pThis); DBGPRINTF("%s: waiting %ldms on worker thread termination, %d still running\n", wtpGetDbgHdr(pThis), timeoutVal(ptTimeout), ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); if (d_pthread_cond_timedwait(&pThis->condThrdTrm, &pThis->mutWtp, ptTimeout) != 0) { DBGPRINTF("%s: timeout waiting on worker thread termination\n", wtpGetDbgHdr(pThis)); bTimedOut = 1; /* we exit the loop on timeout */ } /* awake workers in retry loop */ for (i = 0; i < pThis->iNumWorkerThreads; ++i) { wtiWakeupThrd(pThis->pWrkr[i]); } } pthread_cleanup_pop(1); if (bTimedOut) iRet = RS_RET_TIMED_OUT; RETiRet; } PRAGMA_DIAGNOSTIC_POP /* Unconditionally cancel all running worker threads. * rgerhards, 2008-01-14 */ rsRetVal ATTR_NONNULL() wtpCancelAll(wtp_t *pThis, const uchar *const cancelobj) { DEFiRet; int i; ISOBJ_TYPE_assert(pThis, wtp); /* go through all workers and cancel those that are active */ for (i = 0; i < pThis->iNumWorkerThreads; ++i) { wtiCancelThrd(pThis->pWrkr[i], cancelobj); } RETiRet; } /* this function contains shared code for both regular worker shutdown as * well as shutdown via cancellation. We can not simply use pthread_cleanup_pop(1) * as this introduces a race in the debug system (RETiRet system). * rgerhards, 2009-10-26 */ static void wtpWrkrExecCleanup(wti_t *pWti) { wtp_t *pThis; ISOBJ_TYPE_assert(pWti, wti); pThis = pWti->pWtp; ISOBJ_TYPE_assert(pThis, wtp); // TESTBENCH bughunt - remove when done! 2018-11-05 rgerhards if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: enter WrkrExecCleanup\n", wtiGetDbgHdr(pWti)); } /* the order of the next two statements is important! */ wtiSetState(pWti, WRKTHRD_WAIT_JOIN); ATOMIC_DEC(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd); /* note: numWorkersNow is only for message generation, so we do not try * hard to get it 100% accurate (as curently done, it is not). */ const int numWorkersNow = ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd); DBGPRINTF("%s: Worker thread %lx, terminated, num workers now %d\n", wtpGetDbgHdr(pThis), (unsigned long)pWti, numWorkersNow); if (numWorkersNow > 0) { // TODO: did the thread ID experiment (pthread_self) work out? rgerhards, 2024-07-25 LogMsg(0, RS_RET_OPERATION_STATUS, LOG_INFO, "%s: worker thread %lx (%" PRIuPTR ") terminated, now %d active worker threads", wtpGetDbgHdr(pThis), (unsigned long)pWti, (uintptr_t)pthread_self(), numWorkersNow); } } /* cancellation cleanup handler for executing worker decrements the worker counter. * rgerhards, 2009-07-20 */ static void wtpWrkrExecCancelCleanup(void *arg) { wti_t *pWti = (wti_t *)arg; wtp_t *pThis; ISOBJ_TYPE_assert(pWti, wti); pThis = pWti->pWtp; ISOBJ_TYPE_assert(pThis, wtp); DBGPRINTF("%s: Worker thread %lx requested to be cancelled.\n", wtpGetDbgHdr(pThis), (unsigned long)pWti); wtpWrkrExecCleanup(pWti); pthread_cond_broadcast(&pThis->condThrdTrm); /* activate anyone waiting on thread shutdown */ } /* wtp worker shell. This is started and calls into the actual * wti worker. * rgerhards, 2008-01-21 */ PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wempty_body static void *wtpWorker( void *arg) /* the arg is actually a wti object, even though we are in wtp! */ { wti_t *pWti = (wti_t *)arg; wtp_t *pThis; sigset_t sigSet; #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) uchar *pszDbgHdr; uchar thrdName[32] = "rs:"; #endif ISOBJ_TYPE_assert(pWti, wti); pThis = pWti->pWtp; ISOBJ_TYPE_assert(pThis, wtp); /* block all signals except SIGTTIN and SIGSEGV */ sigfillset(&sigSet); sigdelset(&sigSet, SIGTTIN); sigdelset(&sigSet, SIGSEGV); pthread_sigmask(SIG_BLOCK, &sigSet, NULL); #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) /* set thread name - we ignore if the call fails, has no harsh consequences... */ pszDbgHdr = wtpGetDbgHdr(pThis); ustrncpy(thrdName + 3, pszDbgHdr, 20); if (prctl(PR_SET_NAME, thrdName, 0, 0, 0) != 0) { DBGPRINTF("prctl failed, not setting thread name for '%s'\n", wtpGetDbgHdr(pThis)); } dbgOutputTID((char *)thrdName); #endif // TESTBENCH bughunt - remove when done! 2018-11-05 rgerhards if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: worker %p started\n", wtpGetDbgHdr(pThis), pThis); } /* let the parent know we're done with initialization */ d_pthread_mutex_lock(&pThis->mutWtp); wtiSetState(pWti, WRKTHRD_RUNNING); pthread_cond_broadcast(&pThis->condThrdInitDone); d_pthread_mutex_unlock(&pThis->mutWtp); pthread_cleanup_push(wtpWrkrExecCancelCleanup, pWti); wtiWorker(pWti); pthread_cleanup_pop(0); d_pthread_mutex_lock(&pThis->mutWtp); pthread_cleanup_push(mutexCancelCleanup, &pThis->mutWtp); wtpWrkrExecCleanup(pWti); pthread_cond_broadcast(&pThis->condThrdTrm); /* activate anyone waiting on thread shutdown */ pthread_cleanup_pop(1); /* unlock mutex */ if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %p: worker exiting\n", pWti); } pthread_exit(0); return NULL; /* To suppress warning */ } PRAGMA_DIAGNOSTIC_POP /* start a new worker */ static rsRetVal ATTR_NONNULL() wtpStartWrkr(wtp_t *const pThis, const int permit_during_shutdown) { wti_t *pWti; int i; int iState; DEFiRet; ISOBJ_TYPE_assert(pThis, wtp); // TESTBENCH bughunt - remove when done! 2018-11-05 rgerhards if (dbgTimeoutToStderr) { fprintf(stderr, "%s: worker start requested, num workers currently %d\n", wtpGetDbgHdr(pThis), ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); } const wtpState_t wtpState = (wtpState_t)ATOMIC_FETCH_32BIT((int *)&pThis->wtpState, &pThis->mutWtpState); if (wtpState != wtpState_RUNNING && !permit_during_shutdown) { DBGPRINTF("%s: worker start requested during shutdown - ignored\n", wtpGetDbgHdr(pThis)); if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: worker start requested during shutdown - ignored\n", wtpGetDbgHdr(pThis)); } return RS_RET_ERR; /* exceptional case, but really makes sense here! */ } d_pthread_mutex_lock(&pThis->mutWtp); wtpJoinTerminatedWrkr(pThis); /* find free spot in thread table. */ for (i = 0; i < pThis->iNumWorkerThreads; ++i) { if (wtiGetState(pThis->pWrkr[i]) == WRKTHRD_STOPPED) { break; } } if (i == pThis->iNumWorkerThreads) ABORT_FINALIZE(RS_RET_NO_MORE_THREADS); if (i == 0 || pThis->toWrkShutdown == -1) { wtiSetAlwaysRunning(pThis->pWrkr[i]); } pWti = pThis->pWrkr[i]; wtiSetState(pWti, WRKTHRD_INITIALIZING); iState = pthread_create(&(pWti->thrdID), &pThis->attrThrd, wtpWorker, (void *)pWti); ATOMIC_INC(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd); /* we got one more! */ // TESTBENCH bughunt - remove when done! 2018-11-05 rgerhards if (dbgTimeoutToStderr) { fprintf(stderr, "%s: wrkr start initiated with state %d, num workers now %d\n", wtpGetDbgHdr(pThis), iState, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); } DBGPRINTF("%s: started with state %d, num workers now %d\n", wtpGetDbgHdr(pThis), iState, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); /* wait for the new thread to initialize its signal mask and * cancellation cleanup handler before proceeding */ do { d_pthread_cond_wait(&pThis->condThrdInitDone, &pThis->mutWtp); } while ((iState = wtiGetState(pWti)) == WRKTHRD_INITIALIZING); DBGPRINTF("%s: new worker finished initialization with state %d, num workers now %d\n", wtpGetDbgHdr(pThis), iState, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); // TESTBENCH bughunt - remove when done! 2018-11-05 rgerhards if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslog debug: %s: started with state %d, num workers now %d\n", wtpGetDbgHdr(pThis), iState, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); } finalize_it: d_pthread_mutex_unlock(&pThis->mutWtp); RETiRet; } /* set the number of worker threads that should be running. If less than currently running, * a new worker may be started. Please note that there is no guarantee the number of workers * said will be running after we exit this function. It is just a hint. If the number is * higher than one, and no worker is started, the "busy" condition is signaled to awake a worker. * So the caller can assume that there is at least one worker re-checking if there is "work to do" * after this function call. * Parameter "permit_during_shutdown" if true, permits worker starts while the system is * in shutdown state. The prime use case for this is persisting disk queues in enqueue only * mode, which is activated during shutdown. */ rsRetVal ATTR_NONNULL() wtpAdviseMaxWorkers(wtp_t *const pThis, int nMaxWrkr, const int permit_during_shutdown) { DEFiRet; int nMissing; /* number workers missing to run */ int i, nRunning; ISOBJ_TYPE_assert(pThis, wtp); if (nMaxWrkr == 0) FINALIZE; if (nMaxWrkr > pThis->iNumWorkerThreads) /* limit to configured maximum */ nMaxWrkr = pThis->iNumWorkerThreads; nMissing = nMaxWrkr - ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd); if (nMissing > 0) { if (ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd) > 0) { LogMsg(0, RS_RET_OPERATION_STATUS, LOG_INFO, "%s: high activity - starting %d additional worker thread(s), " "currently %d active worker threads.", wtpGetDbgHdr(pThis), nMissing, ATOMIC_FETCH_32BIT(&pThis->iCurNumWrkThrd, &pThis->mutCurNumWrkThrd)); } /* start the rqtd nbr of workers */ for (i = 0; i < nMissing; ++i) { CHKiRet(wtpStartWrkr(pThis, permit_during_shutdown)); } } else { /* we have needed number of workers, but they may be sleeping */ for (i = 0, nRunning = 0; i < pThis->iNumWorkerThreads && nRunning < nMaxWrkr; ++i) { if (wtiGetState(pThis->pWrkr[i]) != WRKTHRD_STOPPED) { pthread_cond_signal(&pThis->pWrkr[i]->pcondBusy); nRunning++; } } } finalize_it: RETiRet; } /* some simple object access methods * Note: the semicolons behind the macros are actually empty declarations. This is * a work-around for clang-format's missing understanding of generative macros. * Some compilers may flag this empty declarations by a warning. If so, we need * to disable this warning. Alternatively, we could exclude this code from being * reformatted by clang-format; */ DEFpropSetMeth(wtp, toWrkShutdown, long); DEFpropSetMeth(wtp, wtpState, wtpState_t); DEFpropSetMeth(wtp, iNumWorkerThreads, int); DEFpropSetMeth(wtp, pUsr, void *); DEFpropSetMethPTR(wtp, pmutUsr, pthread_mutex_t); DEFpropSetMethFP(wtp, pfChkStopWrkr, rsRetVal (*pVal)(void *, int)); DEFpropSetMethFP(wtp, pfRateLimiter, rsRetVal (*pVal)(void *)); DEFpropSetMethFP(wtp, pfGetDeqBatchSize, rsRetVal (*pVal)(void *, int *)); DEFpropSetMethFP(wtp, pfDoWork, rsRetVal (*pVal)(void *, void *)); DEFpropSetMethFP(wtp, pfObjProcessed, rsRetVal (*pVal)(void *, wti_t *)); /* set the debug header message * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. Must be called only before object is finalized. * rgerhards, 2008-01-09 */ rsRetVal wtpSetDbgHdr(wtp_t *pThis, uchar *pszMsg, size_t lenMsg) { DEFiRet; ISOBJ_TYPE_assert(pThis, wtp); assert(pszMsg != NULL); if (lenMsg < 1) ABORT_FINALIZE(RS_RET_PARAM_ERROR); if (pThis->pszDbgHdr != NULL) { free(pThis->pszDbgHdr); pThis->pszDbgHdr = NULL; } if ((pThis->pszDbgHdr = malloc(lenMsg + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pszDbgHdr, pszMsg, lenMsg + 1); /* always think about the \0! */ finalize_it: RETiRet; } /* dummy */ static rsRetVal wtpQueryInterface(interface_t __attribute__((unused)) * i) { return RS_RET_NOT_IMPLEMENTED; } /* exit our class */ BEGINObjClassExit(wtp, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(wtp); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); ENDObjClassExit(wtp) /* Initialize the stream class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 */ BEGINObjClassInit(wtp, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDObjClassInit(wtp) rsyslog-8.2512.0/runtime/PaxHeaders/lookup.c0000644000000000000000000000013115055605325015676 xustar0030 mtime=1756826325.647800653 29 atime=1764930997.29096644 30 ctime=1764935923.273577958 rsyslog-8.2512.0/runtime/lookup.c0000664000175000017500000011704015055605325015346 0ustar00rgerrger/* lookup.c * Support for lookup tables in RainerScript. * * Copyright 2013-2023 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "errmsg.h" #include "lookup.h" #include "msg.h" #include "rsconf.h" #include "dirty.h" #include "unicode-helper.h" #include "regexp.h" PRAGMA_IGNORE_Wdeprecated_declarations /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) #ifdef FEATURE_REGEXP DEFobjCurrIf(regexp) #endif /* forward definitions */ static rsRetVal lookupReadFile(lookup_t *pThis, const uchar *name, const uchar *filename); static void lookupDestruct(lookup_t *pThis); /* static data */ /* tables for interfacing with the v6 config system (as far as we need to) */ static struct cnfparamdescr modpdescr[] = {{"name", eCmdHdlrString, CNFPARAM_REQUIRED}, {"file", eCmdHdlrString, CNFPARAM_REQUIRED}, {"reloadOnHUP", eCmdHdlrBinary, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* internal data-types */ typedef struct uint32_index_val_s { uint32_t index; uchar *val; } uint32_index_val_t; const char *reloader_prefix = "lkp_tbl_reloader:"; static void *lookupTableReloader(void *self); static void lookupStopReloader(lookup_ref_t *pThis); /* create a new lookup table object AND include it in our list of * lookup tables. */ static rsRetVal lookupNew(lookup_ref_t **ppThis) { lookup_ref_t *pThis = NULL; lookup_t *t = NULL; DEFiRet; CHKmalloc(pThis = calloc(1, sizeof(lookup_ref_t))); CHKmalloc(t = calloc(1, sizeof(lookup_t))); pThis->do_reload = pThis->do_stop = 0; pThis->reload_on_hup = 1; /*DO reload on HUP (default)*/ pThis->next = NULL; if (loadConf->lu_tabs.root == NULL) { loadConf->lu_tabs.root = pThis; } else { loadConf->lu_tabs.last->next = pThis; } loadConf->lu_tabs.last = pThis; pThis->self = t; *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK) { LogError(errno, iRet, "a lookup table could not be initialized"); free(t); free(pThis); } RETiRet; } /* activate a lookup table entry once rsyslog is ready to do so */ static rsRetVal lookupActivateTable(lookup_ref_t *pThis) { DEFiRet; int initialized = 0; DBGPRINTF("lookupActivateTable called\n"); CHKiConcCtrl(pthread_rwlock_init(&pThis->rwlock, NULL)); initialized++; /*1*/ CHKiConcCtrl(pthread_mutex_init(&pThis->reloader_mut, NULL)); initialized++; /*2*/ CHKiConcCtrl(pthread_cond_init(&pThis->run_reloader, NULL)); initialized++; /*3*/ CHKiConcCtrl(pthread_attr_init(&pThis->reloader_thd_attr)); initialized++; /*4*/ pThis->do_reload = pThis->do_stop = 0; CHKiConcCtrl(pthread_create(&pThis->reloader, &pThis->reloader_thd_attr, lookupTableReloader, pThis)); initialized++; /*5*/ finalize_it: if (iRet != RS_RET_OK) { LogError(errno, iRet, "a lookup table could not be activated: " "failed at init-step %d (please enable debug logs for details)", initialized); /* Can not happen with current code, but might occur in the future when * an error-condition as added after step 5. If we leave it in, Coverity * scan complains. So we comment it out but do not remove the code. * Triggered by CID 185426 if (initialized > 4) lookupStopReloader(pThis); */ if (initialized > 3) pthread_attr_destroy(&pThis->reloader_thd_attr); if (initialized > 2) pthread_cond_destroy(&pThis->run_reloader); if (initialized > 1) pthread_mutex_destroy(&pThis->reloader_mut); if (initialized > 0) pthread_rwlock_destroy(&pThis->rwlock); } RETiRet; } /*must be called with reloader_mut acquired*/ static void ATTR_NONNULL() freeStubValueForReloadFailure(lookup_ref_t *const pThis) { if (pThis->stub_value_for_reload_failure != NULL) { free(pThis->stub_value_for_reload_failure); pThis->stub_value_for_reload_failure = NULL; } } static void lookupStopReloader(lookup_ref_t *pThis) { pthread_mutex_lock(&pThis->reloader_mut); freeStubValueForReloadFailure(pThis); pThis->do_reload = 0; pThis->do_stop = 1; pthread_cond_signal(&pThis->run_reloader); pthread_mutex_unlock(&pThis->reloader_mut); pthread_join(pThis->reloader, NULL); } static void lookupRefDestruct(lookup_ref_t *pThis) { lookupStopReloader(pThis); pthread_mutex_destroy(&pThis->reloader_mut); pthread_cond_destroy(&pThis->run_reloader); pthread_attr_destroy(&pThis->reloader_thd_attr); pthread_rwlock_destroy(&pThis->rwlock); lookupDestruct(pThis->self); free(pThis->name); free(pThis->filename); free(pThis); } static void destructTable_str(lookup_t *pThis) { uint32_t i = 0; lookup_string_tab_entry_t *entries = pThis->table.str->entries; for (i = 0; i < pThis->nmemb; i++) { free(entries[i].key); } free(entries); free(pThis->table.str); } static void destructTable_arr(lookup_t *pThis) { free(pThis->table.arr->interned_val_refs); free(pThis->table.arr); } static void destructTable_sparseArr(lookup_t *pThis) { free(pThis->table.sprsArr->entries); free(pThis->table.sprsArr); } #ifdef FEATURE_REGEXP static void destructTable_regex(lookup_t *pThis) { uint32_t i; int regfree_available = 0; lookup_regex_tab_entry_t *entries; if (pThis == NULL || pThis->table.regex == NULL) return; entries = pThis->table.regex->entries; if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) regfree_available = 1; if (entries != NULL) { for (i = 0; i < pThis->nmemb; ++i) { if (entries[i].is_compiled) { if (regfree_available) { regexp.regfree(&entries[i].regex); } else { LogError(0, RS_RET_INTERNAL_ERROR, "regexp module missing; compiled regex cannot be freed"); } } free(entries[i].regex_str); entries[i].regex_str = NULL; } } free(entries); free(pThis->table.regex); } #endif static void lookupDestruct(lookup_t *pThis) { uint32_t i; if (pThis == NULL) return; if (pThis->type == STRING_LOOKUP_TABLE) { destructTable_str(pThis); } else if (pThis->type == ARRAY_LOOKUP_TABLE) { destructTable_arr(pThis); } else if (pThis->type == SPARSE_ARRAY_LOOKUP_TABLE) { destructTable_sparseArr(pThis); #ifdef FEATURE_REGEXP } else if (pThis->type == REGEX_LOOKUP_TABLE) { destructTable_regex(pThis); #endif } else if (pThis->type == STUBBED_LOOKUP_TABLE) { /*nothing to be done*/ } for (i = 0; i < pThis->interned_val_count; i++) { free(pThis->interned_vals[i]); } free(pThis->interned_vals); free(pThis->nomatch); free(pThis); } void lookupInitCnf(lookup_tables_t *lu_tabs) { lu_tabs->root = NULL; lu_tabs->last = NULL; } void lookupDestroyCnf(void) { lookup_ref_t *luref, *luref_next; for (luref = runConf->lu_tabs.root; luref != NULL;) { luref_next = luref->next; lookupRefDestruct(luref); luref = luref_next; } } /* comparison function for qsort() */ static int qs_arrcmp_strtab(const void *s1, const void *s2) { return ustrcmp(((lookup_string_tab_entry_t *)s1)->key, ((lookup_string_tab_entry_t *)s2)->key); } static int qs_arrcmp_ustrs(const void *s1, const void *s2) { return ustrcmp(*(uchar **)s1, *(uchar **)s2); } static int qs_arrcmp_uint32_index_val(const void *s1, const void *s2) { uint32_t first_value = ((uint32_index_val_t *)s1)->index; uint32_t second_value = ((uint32_index_val_t *)s2)->index; if (first_value < second_value) { return -1; } return first_value - second_value; } static int qs_arrcmp_sprsArrtab(const void *s1, const void *s2) { uint32_t first_value = ((lookup_sparseArray_tab_entry_t *)s1)->key; uint32_t second_value = ((lookup_sparseArray_tab_entry_t *)s2)->key; if (first_value < second_value) { return -1; } return first_value - second_value; } /* comparison function for bsearch() and string array compare * this is for the string lookup table type */ static int bs_arrcmp_strtab(const void *s1, const void *s2) { return strcmp((char *)s1, (char *)((lookup_string_tab_entry_t *)s2)->key); } static int bs_arrcmp_str(const void *s1, const void *s2) { return ustrcmp((uchar *)s1, *(uchar **)s2); } static int bs_arrcmp_sprsArrtab(const void *s1, const void *s2) { uint32_t key = *(uint32_t *)s1; uint32_t array_member_value = ((lookup_sparseArray_tab_entry_t *)s2)->key; if (key < array_member_value) { return -1; } return key - array_member_value; } static inline const char *defaultVal(lookup_t *pThis) { return (pThis->nomatch == NULL) ? "" : (const char *)pThis->nomatch; } /* lookup_fn for different types of tables */ static es_str_t *lookupKey_stub(lookup_t *pThis, lookup_key_t __attribute__((unused)) key) { return es_newStrFromCStr((char *)pThis->nomatch, ustrlen(pThis->nomatch)); } static es_str_t *lookupKey_str(lookup_t *pThis, lookup_key_t key) { lookup_string_tab_entry_t *entry; const char *r; if (pThis->nmemb == 0) { entry = NULL; } else { assert(pThis->table.str->entries); entry = bsearch(key.k_str, pThis->table.str->entries, pThis->nmemb, sizeof(lookup_string_tab_entry_t), bs_arrcmp_strtab); } if (entry == NULL) { r = defaultVal(pThis); } else { r = (const char *)entry->interned_val_ref; } return es_newStrFromCStr(r, strlen(r)); } static es_str_t *lookupKey_arr(lookup_t *pThis, lookup_key_t key) { const char *r; uint32_t uint_key = key.k_uint; if ((pThis->nmemb == 0) || (uint_key < pThis->table.arr->first_key)) { r = defaultVal(pThis); } else { uint32_t idx = uint_key - pThis->table.arr->first_key; if (idx >= pThis->nmemb) { r = defaultVal(pThis); } else { r = (char *)pThis->table.arr->interned_val_refs[idx]; } } return es_newStrFromCStr(r, strlen(r)); } typedef int(comp_fn_t)(const void *s1, const void *s2); static void *bsearch_lte(const void *key, const void *base, size_t nmemb, size_t size, comp_fn_t *comp_fn) { size_t l, u, idx; const void *p; int comparison; l = 0; u = nmemb; if (l == u) { return NULL; } while (l < u) { idx = (l + u) / 2; p = (void *)(((const char *)base) + (idx * size)); comparison = (*comp_fn)(key, p); if (comparison < 0) u = idx; else if (comparison > 0) l = idx + 1; else return (void *)p; } if (comparison < 0) { if (idx == 0) { return NULL; } idx--; } return (void *)(((const char *)base) + (idx * size)); } static es_str_t *lookupKey_sprsArr(lookup_t *pThis, lookup_key_t key) { lookup_sparseArray_tab_entry_t *entry; const char *r; if (pThis->nmemb == 0) { entry = NULL; } else { entry = bsearch_lte(&key.k_uint, pThis->table.sprsArr->entries, pThis->nmemb, sizeof(lookup_sparseArray_tab_entry_t), bs_arrcmp_sprsArrtab); } if (entry == NULL) { r = defaultVal(pThis); } else { r = (const char *)entry->interned_val_ref; } return es_newStrFromCStr(r, strlen(r)); } #ifdef FEATURE_REGEXP static es_str_t *lookupKey_regex(lookup_t *pThis, lookup_key_t key) { const char *r = defaultVal(pThis); for (uint32_t i = 0; i < pThis->nmemb; ++i) { if (regexp.regexec(&pThis->table.regex->entries[i].regex, (char *)key.k_str, 0, NULL, 0) == 0) { r = (const char *)pThis->table.regex->entries[i].interned_val_ref; break; } } return es_newStrFromCStr(r, strlen(r)); } #endif /* builders for different table-types */ #define NO_INDEX_ERROR(type, name) \ LogError(0, RS_RET_INVALID_VALUE, \ "'%s' lookup table named: '%s' has record(s) without 'index' " \ "field", \ type, name); \ ABORT_FINALIZE(RS_RET_INVALID_VALUE); static rsRetVal build_StringTable(lookup_t *pThis, struct json_object *jtab, const uchar *name) { uint32_t i; struct json_object *jrow, *jindex, *jvalue; uchar *value, *canonicalValueRef; DEFiRet; pThis->table.str = NULL; CHKmalloc(pThis->table.str = calloc(1, sizeof(lookup_string_tab_t))); if (pThis->nmemb > 0) { CHKmalloc(pThis->table.str->entries = calloc(pThis->nmemb, sizeof(lookup_string_tab_entry_t))); for (i = 0; i < pThis->nmemb; i++) { jrow = json_object_array_get_idx(jtab, i); fjson_object_object_get_ex(jrow, "index", &jindex); fjson_object_object_get_ex(jrow, "value", &jvalue); if (jindex == NULL || json_object_is_type(jindex, json_type_null)) { NO_INDEX_ERROR("string", name); } CHKmalloc(pThis->table.str->entries[i].key = ustrdup((uchar *)json_object_get_string(jindex))); value = (uchar *)json_object_get_string(jvalue); uchar **found = (uchar **)bsearch(value, pThis->interned_vals, pThis->interned_val_count, sizeof(uchar *), bs_arrcmp_str); if (found == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "lookup.c:build_StringTable(): " "internal error, bsearch returned NULL for '%s'", value); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } // I give up, I see no way to remove false positive -- rgerhards, 2017-10-24 #ifndef __clang_analyzer__ canonicalValueRef = *found; if (canonicalValueRef == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "lookup.c:build_StringTable(): " "internal error, canonicalValueRef returned from bsearch " "is NULL for '%s'", value); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } pThis->table.str->entries[i].interned_val_ref = canonicalValueRef; #endif } qsort(pThis->table.str->entries, pThis->nmemb, sizeof(lookup_string_tab_entry_t), qs_arrcmp_strtab); } pThis->lookup = lookupKey_str; pThis->key_type = LOOKUP_KEY_TYPE_STRING; finalize_it: RETiRet; } static rsRetVal build_ArrayTable(lookup_t *pThis, struct json_object *jtab, const uchar *name) { uint32_t i; struct json_object *jrow, *jindex, *jvalue; uchar *canonicalValueRef; uint32_t prev_index, _index; uint8_t prev_index_set; uint32_index_val_t *indexes = NULL; DEFiRet; prev_index_set = 0; pThis->table.arr = NULL; CHKmalloc(pThis->table.arr = calloc(1, sizeof(lookup_array_tab_t))); if (pThis->nmemb > 0) { CHKmalloc(indexes = calloc(pThis->nmemb, sizeof(uint32_index_val_t))); CHKmalloc(pThis->table.arr->interned_val_refs = calloc(pThis->nmemb, sizeof(uchar *))); for (i = 0; i < pThis->nmemb; i++) { jrow = json_object_array_get_idx(jtab, i); fjson_object_object_get_ex(jrow, "index", &jindex); fjson_object_object_get_ex(jrow, "value", &jvalue); if (jindex == NULL || json_object_is_type(jindex, json_type_null)) { NO_INDEX_ERROR("array", name); } indexes[i].index = (uint32_t)json_object_get_int(jindex); indexes[i].val = (uchar *)json_object_get_string(jvalue); } qsort(indexes, pThis->nmemb, sizeof(uint32_index_val_t), qs_arrcmp_uint32_index_val); for (i = 0; i < pThis->nmemb; i++) { _index = indexes[i].index; if (prev_index_set == 0) { prev_index = _index; prev_index_set = 1; pThis->table.arr->first_key = _index; } else { if (_index != ++prev_index) { LogError(0, RS_RET_INVALID_VALUE, "'array' lookup table name: '%s' " "has non-contiguous members between index '%d' and '%d'", name, prev_index, _index); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } } uchar *const *const canonicalValueRef_ptr = bsearch( indexes[i].val, pThis->interned_vals, pThis->interned_val_count, sizeof(uchar *), bs_arrcmp_str); if (canonicalValueRef_ptr == NULL) { LogError(0, RS_RET_ERR, "BUG: canonicalValueRef not found in " "build_ArrayTable(), %s:%d", __FILE__, __LINE__); ABORT_FINALIZE(RS_RET_ERR); } canonicalValueRef = *canonicalValueRef_ptr; assert(canonicalValueRef != NULL); pThis->table.arr->interned_val_refs[i] = canonicalValueRef; } } pThis->lookup = lookupKey_arr; pThis->key_type = LOOKUP_KEY_TYPE_UINT; finalize_it: free(indexes); RETiRet; } static rsRetVal build_SparseArrayTable(lookup_t *pThis, struct json_object *jtab, const uchar *name) { uint32_t i; struct json_object *jrow, *jindex, *jvalue; uchar *value, *canonicalValueRef; DEFiRet; pThis->table.str = NULL; CHKmalloc(pThis->table.sprsArr = calloc(1, sizeof(lookup_sparseArray_tab_t))); if (pThis->nmemb > 0) { CHKmalloc(pThis->table.sprsArr->entries = calloc(pThis->nmemb, sizeof(lookup_sparseArray_tab_entry_t))); for (i = 0; i < pThis->nmemb; i++) { jrow = json_object_array_get_idx(jtab, i); fjson_object_object_get_ex(jrow, "index", &jindex); fjson_object_object_get_ex(jrow, "value", &jvalue); if (jindex == NULL || json_object_is_type(jindex, json_type_null)) { NO_INDEX_ERROR("sparseArray", name); } pThis->table.sprsArr->entries[i].key = (uint32_t)json_object_get_int(jindex); value = (uchar *)json_object_get_string(jvalue); uchar *const *const canonicalValueRef_ptr = bsearch(value, pThis->interned_vals, pThis->interned_val_count, sizeof(uchar *), bs_arrcmp_str); if (canonicalValueRef_ptr == NULL) { LogError(0, RS_RET_ERR, "BUG: canonicalValueRef not found in " "build_SparseArrayTable(), %s:%d", __FILE__, __LINE__); ABORT_FINALIZE(RS_RET_ERR); } canonicalValueRef = *canonicalValueRef_ptr; assert(canonicalValueRef != NULL); pThis->table.sprsArr->entries[i].interned_val_ref = canonicalValueRef; } qsort(pThis->table.sprsArr->entries, pThis->nmemb, sizeof(lookup_sparseArray_tab_entry_t), qs_arrcmp_sprsArrtab); } pThis->lookup = lookupKey_sprsArr; pThis->key_type = LOOKUP_KEY_TYPE_UINT; finalize_it: RETiRet; } #ifdef FEATURE_REGEXP static rsRetVal build_RegexTable(lookup_t *pThis, struct json_object *jtab, const uchar *name) { uint32_t i; struct json_object *jrow, *jregex, *jtag; uchar *value, *canonicalValueRef; const char *regex_str; DEFiRet; pThis->table.regex = NULL; CHKmalloc(pThis->table.regex = calloc(1, sizeof(lookup_regex_tab_t))); if (pThis->nmemb > 0) { CHKmalloc(pThis->table.regex->entries = calloc(pThis->nmemb, sizeof(lookup_regex_tab_entry_t))); for (i = 0; i < pThis->nmemb; i++) { jrow = json_object_array_get_idx(jtab, i); fjson_object_object_get_ex(jrow, "regex", &jregex); fjson_object_object_get_ex(jrow, "tag", &jtag); if (jregex == NULL || jtag == NULL || json_object_is_type(jregex, json_type_null) || json_object_is_type(jtag, json_type_null)) { LogError(0, RS_RET_INVALID_VALUE, "'regex' lookup table named: '%s' has record(s) without required " "fields", name); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } regex_str = json_object_get_string(jregex); CHKmalloc(pThis->table.regex->entries[i].regex_str = ustrdup((const uchar *)regex_str)); value = (uchar *)json_object_get_string(jtag); uchar *const *const canonicalValueRef_ptr = bsearch(value, pThis->interned_vals, pThis->interned_val_count, sizeof(uchar *), bs_arrcmp_str); if (canonicalValueRef_ptr == NULL) { LogError(0, RS_RET_ERR, "BUG: canonicalValueRef not found in build_RegexTable(), %s:%d", __FILE__, __LINE__); ABORT_FINALIZE(RS_RET_ERR); } canonicalValueRef = *canonicalValueRef_ptr; assert(canonicalValueRef != NULL); pThis->table.regex->entries[i].interned_val_ref = canonicalValueRef; int err; if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { if ((err = regexp.regcomp(&pThis->table.regex->entries[i].regex, regex_str, REG_EXTENDED | REG_NOSUB)) != 0) { char errbuf[256]; regexp.regerror(err, &pThis->table.regex->entries[i].regex, errbuf, sizeof(errbuf)); LogError(0, RS_RET_INVALID_VALUE, "error compiling regex '%s' in lookup table '%s': %s", regex_str, name, errbuf); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } else { pThis->table.regex->entries[i].is_compiled = 1; } } else { LogError(0, RS_RET_INTERNAL_ERROR, "regex library could not be loaded"); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } } } pThis->lookup = lookupKey_regex; pThis->key_type = LOOKUP_KEY_TYPE_STRING; finalize_it: RETiRet; } #endif static rsRetVal lookupBuildStubbedTable(lookup_t *pThis, const uchar *stub_val) { DEFiRet; CHKmalloc(pThis->nomatch = ustrdup(stub_val)); pThis->lookup = lookupKey_stub; pThis->type = STUBBED_LOOKUP_TABLE; pThis->key_type = LOOKUP_KEY_TYPE_NONE; finalize_it: RETiRet; } static rsRetVal lookupBuildTable_v1(lookup_t *pThis, struct json_object *jroot, const uchar *name) { struct json_object *jnomatch, *jtype, *jtab; struct json_object *jrow, *jvalue; const char *table_type, *nomatch_value; const char *value_key; const uchar **all_values; const uchar *curr, *prev; uint32_t i, j; uint32_t uniq_values; DEFiRet; all_values = NULL; fjson_object_object_get_ex(jroot, "nomatch", &jnomatch); fjson_object_object_get_ex(jroot, "type", &jtype); fjson_object_object_get_ex(jroot, "table", &jtab); if (jtab == NULL || !json_object_is_type(jtab, json_type_array)) { LogError(0, RS_RET_INVALID_VALUE, "lookup table named: '%s' has invalid table definition", name); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } pThis->nmemb = json_object_array_length(jtab); table_type = json_object_get_string(jtype); if (table_type == NULL) { table_type = "string"; } value_key = (strcmp(table_type, "regex") == 0) ? "tag" : "value"; CHKmalloc(all_values = malloc(pThis->nmemb * sizeof(uchar *))); /* before actual table can be loaded, prepare all-value list and remove duplicates*/ for (i = 0; i < pThis->nmemb; i++) { jrow = json_object_array_get_idx(jtab, i); fjson_object_object_get_ex(jrow, value_key, &jvalue); if (jvalue == NULL || json_object_is_type(jvalue, json_type_null)) { LogError(0, RS_RET_INVALID_VALUE, "'%s' lookup table named: '%s' has record(s) " "without '%s' field", table_type, name, value_key); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } all_values[i] = (const uchar *)json_object_get_string(jvalue); } qsort(all_values, pThis->nmemb, sizeof(uchar *), qs_arrcmp_ustrs); uniq_values = 1; for (i = 1; i < pThis->nmemb; i++) { curr = all_values[i]; prev = all_values[i - 1]; if (ustrcmp(prev, curr) != 0) { uniq_values++; } } if (pThis->nmemb > 0) { CHKmalloc(pThis->interned_vals = malloc(uniq_values * sizeof(uchar *))); j = 0; CHKmalloc(pThis->interned_vals[j++] = ustrdup(all_values[0])); for (i = 1; i < pThis->nmemb; ++i) { curr = all_values[i]; prev = all_values[i - 1]; if (ustrcmp(prev, curr) != 0) { CHKmalloc(pThis->interned_vals[j++] = ustrdup(all_values[i])); } } pThis->interned_val_count = uniq_values; } /* uniq values captured (sorted) */ nomatch_value = json_object_get_string(jnomatch); if (nomatch_value != NULL) { CHKmalloc(pThis->nomatch = (uchar *)strdup(nomatch_value)); } if (strcmp(table_type, "array") == 0) { pThis->type = ARRAY_LOOKUP_TABLE; CHKiRet(build_ArrayTable(pThis, jtab, name)); } else if (strcmp(table_type, "sparseArray") == 0) { pThis->type = SPARSE_ARRAY_LOOKUP_TABLE; CHKiRet(build_SparseArrayTable(pThis, jtab, name)); #ifdef FEATURE_REGEXP } else if (strcmp(table_type, "regex") == 0) { pThis->type = REGEX_LOOKUP_TABLE; CHKiRet(build_RegexTable(pThis, jtab, name)); #endif } else if (strcmp(table_type, "string") == 0) { pThis->type = STRING_LOOKUP_TABLE; CHKiRet(build_StringTable(pThis, jtab, name)); } else { LogError(0, RS_RET_INVALID_VALUE, "lookup table named: '%s' uses unupported " "type: '%s'", name, table_type); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } finalize_it: if (all_values != NULL) free(all_values); RETiRet; } static rsRetVal lookupBuildTable(lookup_t *pThis, struct json_object *jroot, const uchar *name) { struct json_object *jversion; int version = 1; DEFiRet; fjson_object_object_get_ex(jroot, "version", &jversion); if (jversion != NULL && !json_object_is_type(jversion, json_type_null)) { version = json_object_get_int(jversion); } else { LogError(0, RS_RET_INVALID_VALUE, "lookup table named: '%s' doesn't specify version " "(will use default value: %d)", name, version); } if (version == 1) { CHKiRet(lookupBuildTable_v1(pThis, jroot, name)); } else { LogError(0, RS_RET_INVALID_VALUE, "lookup table named: '%s' uses unsupported " "version: %d", name, version); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } finalize_it: RETiRet; } /* find a lookup table. This is a naive O(n) algo, but this really * doesn't matter as it is called only a few times during config * load. The function returns either a pointer to the requested * table or NULL, if not found. */ lookup_ref_t *ATTR_NONNULL() lookupFindTable(uchar *name) { lookup_ref_t *curr; for (curr = loadConf->lu_tabs.root; curr != NULL; curr = curr->next) { if (!ustrcmp(curr->name, name)) break; } return curr; } /* this reloads a lookup table. This is done while the engine is running, * as such the function must ensure proper locking and proper order of * operations (so that nothing can interfere). If the table cannot be loaded, * the old table is continued to be used. */ static rsRetVal lookupReloadOrStub(lookup_ref_t *pThis, const uchar *stub_val) { lookup_t *newlu, *oldlu; /* dummy to be able to use support functions without affecting current settings. */ DEFiRet; oldlu = pThis->self; newlu = NULL; DBGPRINTF("reload requested for lookup table '%s'\n", pThis->name); CHKmalloc(newlu = calloc(1, sizeof(lookup_t))); if (stub_val == NULL) { CHKiRet(lookupReadFile(newlu, pThis->name, pThis->filename)); } else { CHKiRet(lookupBuildStubbedTable(newlu, stub_val)); } /* all went well, copy over data members */ pthread_rwlock_wrlock(&pThis->rwlock); pThis->self = newlu; pthread_rwlock_unlock(&pThis->rwlock); finalize_it: if (iRet != RS_RET_OK) { if (stub_val == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "lookup table '%s' could not be reloaded from file '%s'", pThis->name, pThis->filename); } else { LogError(0, RS_RET_INTERNAL_ERROR, "lookup table '%s' could not be stubbed with value '%s'", pThis->name, stub_val); } lookupDestruct(newlu); } else { if (stub_val == NULL) { LogMsg(0, RS_RET_OK, LOG_INFO, "lookup table '%s' reloaded from file '%s'", pThis->name, pThis->filename); } else { LogError(0, RS_RET_OK, "lookup table '%s' stubbed with value '%s'", pThis->name, stub_val); } lookupDestruct(oldlu); } RETiRet; } static rsRetVal lookupDoStub(lookup_ref_t *pThis, const uchar *stub_val) { int already_stubbed = 0; DEFiRet; pthread_rwlock_rdlock(&pThis->rwlock); if (pThis->self->type == STUBBED_LOOKUP_TABLE && ustrcmp(pThis->self->nomatch, stub_val) == 0) already_stubbed = 1; pthread_rwlock_unlock(&pThis->rwlock); if (!already_stubbed) { LogError(0, RS_RET_OK, "stubbing lookup table '%s' with value '%s'", pThis->name, stub_val); CHKiRet(lookupReloadOrStub(pThis, stub_val)); } else { LogError(0, RS_RET_OK, "lookup table '%s' is already stubbed with value '%s'", pThis->name, stub_val); } finalize_it: RETiRet; } static uint8_t lookupIsReloadPending(lookup_ref_t *pThis) { uint8_t reload_pending; pthread_mutex_lock(&pThis->reloader_mut); reload_pending = pThis->do_reload; pthread_mutex_unlock(&pThis->reloader_mut); return reload_pending; } /* note: stub_val_if_reload_fails may or may not be NULL */ rsRetVal ATTR_NONNULL(1) lookupReload(lookup_ref_t *const pThis, const uchar *const stub_val_if_reload_fails) { uint8_t locked = 0; int lock_errno = 0; DEFiRet; assert(pThis != NULL); if ((lock_errno = pthread_mutex_trylock(&pThis->reloader_mut)) == 0) { locked = 1; /*so it doesn't leak memory in situation where 2 reload requests are issued back to back*/ freeStubValueForReloadFailure(pThis); if (stub_val_if_reload_fails != NULL) { CHKmalloc(pThis->stub_value_for_reload_failure = ustrdup(stub_val_if_reload_fails)); } pThis->do_reload = 1; pthread_cond_signal(&pThis->run_reloader); } else { LogError(lock_errno, RS_RET_INTERNAL_ERROR, "attempt to trigger " "reload of lookup table '%s' failed (not stubbing)", pThis->name); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); /* we can choose to stub the table here, but it'll hurt because the table reloader may take time to complete the reload and stubbing because of a concurrent reload message may not be desirable (except in very tightly controled environments where reload-triggering messages pushed are timed accurately and an idempotency-filter is used to reject re-deliveries) */ } finalize_it: if (locked) { pthread_mutex_unlock(&pThis->reloader_mut); } RETiRet; } static rsRetVal ATTR_NONNULL() lookupDoReload(lookup_ref_t *pThis) { DEFiRet; iRet = lookupReloadOrStub(pThis, NULL); if ((iRet != RS_RET_OK) && (pThis->stub_value_for_reload_failure != NULL)) { iRet = lookupDoStub(pThis, pThis->stub_value_for_reload_failure); } freeStubValueForReloadFailure(pThis); RETiRet; } void *lookupTableReloader(void *self) { lookup_ref_t *pThis = (lookup_ref_t *)self; pthread_mutex_lock(&pThis->reloader_mut); while (1) { if (pThis->do_stop) { break; } else if (pThis->do_reload) { lookupDoReload(pThis); pThis->do_reload = 0; } else { pthread_cond_wait(&pThis->run_reloader, &pThis->reloader_mut); } } pthread_mutex_unlock(&pThis->reloader_mut); return NULL; } /* reload all lookup tables on HUP */ void lookupDoHUP(void) { lookup_ref_t *luref; for (luref = runConf->lu_tabs.root; luref != NULL; luref = luref->next) { if (luref->reload_on_hup) { lookupReload(luref, NULL); } } } /* activate lookup table system config * most importantly, this means tarting the lookup table reloader thread in the * right process space - it is a difference if we fork or not! */ void lookupActivateConf(void) { DBGPRINTF("lookup tables: activate config \n"); lookup_ref_t *luref; for (luref = runConf->lu_tabs.root; luref != NULL; luref = luref->next) { DBGPRINTF("lookup actiate: processing %p\n", luref); lookupActivateTable(luref); } DBGPRINTF("lookup tables: activate done\n"); } uint lookupPendingReloadCount(void) { uint pending_reload_count = 0; lookup_ref_t *luref; for (luref = runConf->lu_tabs.root; luref != NULL; luref = luref->next) { if (lookupIsReloadPending(luref)) { pending_reload_count++; } } return pending_reload_count; } /* returns either a pointer to the value (read only!) or NULL * if either the key could not be found or an error occurred. * Note that an estr_t object is returned. The caller is * responsible for freeing it. */ es_str_t *lookupKey(lookup_ref_t *pThis, lookup_key_t key) { es_str_t *estr; lookup_t *t; pthread_rwlock_rdlock(&pThis->rwlock); t = pThis->self; estr = t->lookup(t, key); pthread_rwlock_unlock(&pThis->rwlock); return estr; } /* note: widely-deployed json_c 0.9 does NOT support incremental * parsing. In order to keep compatible with e.g. Ubuntu 12.04LTS, * we read the file into one big memory buffer and parse it at once. * While this is not very elegant, it will not pose any real issue * for "reasonable" lookup tables (and "unreasonably" large ones * will probably have other issues as well...). */ static rsRetVal ATTR_NONNULL() lookupReadFile(lookup_t *const pThis, const uchar *const name, const uchar *const filename) { struct json_tokener *tokener = NULL; struct json_object *json = NULL; char *iobuf = NULL; int fd = -1; ssize_t nread; struct stat sb; DEFiRet; if ((fd = open((const char *)filename, O_RDONLY)) == -1) { LogError(errno, RS_RET_FILE_NOT_FOUND, "lookup table file '%s' could not be opened", filename); ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); } if (fstat(fd, &sb) == -1) { LogError(errno, RS_RET_FILE_NOT_FOUND, "lookup table file '%s' stat failed", filename); ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); } CHKmalloc(iobuf = malloc(sb.st_size)); tokener = json_tokener_new(); nread = read(fd, iobuf, sb.st_size); if (nread != (ssize_t)sb.st_size) { LogError(errno, RS_RET_READ_ERR, "lookup table file '%s' read error", filename); ABORT_FINALIZE(RS_RET_READ_ERR); } json = json_tokener_parse_ex(tokener, iobuf, sb.st_size); if (json == NULL) { LogError(0, RS_RET_JSON_PARSE_ERR, "lookup table file '%s' json parsing error", filename); ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); } free(iobuf); /* early free to sever resources*/ iobuf = NULL; /* make sure no double-free */ /* got json object, now populate our own in-memory structure */ CHKiRet(lookupBuildTable(pThis, json, name)); finalize_it: if (fd != -1) { close(fd); } free(iobuf); if (tokener != NULL) json_tokener_free(tokener); if (json != NULL) json_object_put(json); RETiRet; } rsRetVal lookupTableDefProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; lookup_ref_t *lu; short i; #ifdef HAVE_PTHREAD_SETNAME_NP char *reloader_thd_name = NULL; int thd_name_len = 0; #endif DEFiRet; lu = NULL; pvals = nvlstGetParams(o->nvlst, &modpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } DBGPRINTF("lookupTableDefProcessCnf params:\n"); cnfparamsPrint(&modpblk, pvals); CHKiRet(lookupNew(&lu)); for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "file")) { CHKmalloc(lu->filename = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(modpblk.descr[i].name, "name")) { CHKmalloc(lu->name = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(modpblk.descr[i].name, "reloadOnHUP")) { lu->reload_on_hup = (pvals[i].val.d.n != 0); } else { dbgprintf( "lookup_table: program error, non-handled " "param '%s'\n", modpblk.descr[i].name); } } const uchar *const lu_name = lu->name; /* we need a const to keep TSAN happy :-( */ const uchar *const lu_filename = lu->filename; /* we need a const to keep TSAN happy :-( */ if (lu_name == NULL || lu_filename == NULL) { iRet = RS_RET_INTERNAL_ERROR; LogError(0, iRet, "internal error: lookup table name not set albeit being mandatory"); ABORT_FINALIZE(iRet); } #ifdef HAVE_PTHREAD_SETNAME_NP thd_name_len = ustrlen(lu_name) + strlen(reloader_prefix) + 1; CHKmalloc(reloader_thd_name = malloc(thd_name_len)); strcpy(reloader_thd_name, reloader_prefix); strcpy(reloader_thd_name + strlen(reloader_prefix), (char *)lu_name); reloader_thd_name[thd_name_len - 1] = '\0'; #if defined(__NetBSD__) pthread_setname_np(lu->reloader, "%s", reloader_thd_name); #elif defined(__APPLE__) pthread_setname_np(reloader_thd_name); // must check #else pthread_setname_np(lu->reloader, reloader_thd_name); #endif #endif CHKiRet(lookupReadFile(lu->self, lu_name, lu_filename)); LogMsg(0, RS_RET_OK, LOG_INFO, "lookup table '%s' loaded from file '%s'", lu_name, lu->filename); finalize_it: #ifdef HAVE_PTHREAD_SETNAME_NP free(reloader_thd_name); #endif cnfparamvalsDestruct(pvals, &modpblk); if (iRet != RS_RET_OK) { if (lu != NULL) { lookupDestruct(lu->self); lu->self = NULL; } } RETiRet; } void lookupClassExit(void) { objRelease(glbl, CORE_COMPONENT); } rsRetVal lookupClassInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(glbl, CORE_COMPONENT)); finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/stringbuf.c0000644000000000000000000000013215055605325016371 xustar0030 mtime=1756826325.653800744 30 atime=1764930986.265782597 30 ctime=1764935923.176576474 rsyslog-8.2512.0/runtime/stringbuf.c0000664000175000017500000005573515055605325016054 0ustar00rgerrger/* This is the byte-counted string class for rsyslog. * This object has a lot of legacy. Among others, it was started to * support embedded \0 bytes, which looked like they were needed to * be supported by RFC developments at that time. Later, this was * no longer a requirement, and we refactored the class in 2016 * to some simpler internals which make use of the fact that no * NUL can ever occur in rsyslog strings (they are escaped at the * input side of rsyslog). * It now serves primarily to a) dynamic string creation, b) keep * old interfaces supported, and c) some special functionality, * e.g. search. Further refactoring and simplificytin may make * sense. * * Copyright (C) 2005-2025 Adiscon GmbH * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include "rsyslog.h" #include "stringbuf.h" #include "srUtils.h" #include "regexp.h" #include "errmsg.h" #include "unicode-helper.h" #define DEV_DEBUG 0 /* set to 1 to enable very verbose developer debugging messages */ /* ################################################################# * * private members * * ################################################################# */ /* static data */ DEFobjCurrIf(obj) DEFobjCurrIf(regexp) /* ################################################################# * * public members * * ################################################################# */ rsRetVal cstrConstruct(cstr_t **const ppThis) { DEFiRet; cstr_t *pThis; CHKmalloc(pThis = (cstr_t *)malloc(sizeof(cstr_t))); rsSETOBJTYPE(pThis, OIDrsCStr); #ifndef NDEBUG pThis->isFinalized = 0; #endif pThis->pBuf = NULL; pThis->iBufSize = 0; pThis->iStrLen = 0; *ppThis = pThis; finalize_it: RETiRet; } /* construct from sz string * rgerhards 2005-09-15 */ rsRetVal rsCStrConstructFromszStr(cstr_t **const ppThis, const uchar *const sz) { DEFiRet; cstr_t *pThis; CHKiRet(rsCStrConstruct(&pThis)); pThis->iStrLen = strlen((char *)sz); pThis->iBufSize = strlen((char *)sz) + 1; if ((pThis->pBuf = (uchar *)malloc(pThis->iBufSize)) == NULL) { RSFREEOBJ(pThis); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } /* we do NOT need to copy the \0! */ memcpy(pThis->pBuf, sz, pThis->iStrLen); *ppThis = pThis; finalize_it: RETiRet; } /* a helper function for rsCStr*Strf() */ static rsRetVal rsCStrConstructFromszStrv(cstr_t **ppThis, const char *fmt, va_list ap) __attribute__((format(printf, 2, 0))); static rsRetVal rsCStrConstructFromszStrv(cstr_t **const ppThis, const char *const fmt, va_list ap) { DEFiRet; cstr_t *pThis; va_list ap2; int len; va_copy(ap2, ap); len = vsnprintf(NULL, 0, (char *)fmt, ap2); va_end(ap2); if (len < 0) ABORT_FINALIZE(RS_RET_ERR); CHKiRet(rsCStrConstruct(&pThis)); pThis->iStrLen = len; pThis->iBufSize = len + 1; len++; /* account for the \0 written by vsnprintf */ if ((pThis->pBuf = (uchar *)malloc(pThis->iBufSize)) == NULL) { RSFREEOBJ(pThis); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } vsnprintf((char *)pThis->pBuf, len, (char *)fmt, ap); *ppThis = pThis; finalize_it: RETiRet; } /* construct from a printf-style formated string */ rsRetVal rsCStrConstructFromszStrf(cstr_t **ppThis, const char *fmt, ...) { DEFiRet; va_list ap; va_start(ap, fmt); iRet = rsCStrConstructFromszStrv(ppThis, fmt, ap); va_end(ap); RETiRet; } /* construct from es_str_t string * rgerhards 2010-12-03 */ rsRetVal cstrConstructFromESStr(cstr_t **const ppThis, es_str_t *const str) { DEFiRet; cstr_t *pThis; CHKiRet(rsCStrConstruct(&pThis)); pThis->iStrLen = es_strlen(str); pThis->iBufSize = pThis->iStrLen + 1; if ((pThis->pBuf = (uchar *)malloc(pThis->iBufSize)) == NULL) { RSFREEOBJ(pThis); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } /* we do NOT need to copy the \0! */ memcpy(pThis->pBuf, es_getBufAddr(str), pThis->iStrLen); *ppThis = pThis; finalize_it: RETiRet; } /* construct from CStr object. * rgerhards 2005-10-18 */ rsRetVal ATTR_NONNULL() rsCStrConstructFromCStr(cstr_t **const ppThis, const cstr_t *const pFrom) { DEFiRet; cstr_t *pThis; rsCHECKVALIDOBJECT(pFrom, OIDrsCStr); CHKiRet(rsCStrConstruct(&pThis)); if (pFrom->iStrLen > 0) { pThis->iStrLen = pFrom->iStrLen; pThis->iBufSize = pFrom->iStrLen + 1; if ((pThis->pBuf = (uchar *)malloc(pThis->iBufSize)) == NULL) { RSFREEOBJ(pThis); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } memcpy(pThis->pBuf, pFrom->pBuf, pThis->iStrLen); } *ppThis = pThis; finalize_it: RETiRet; } void rsCStrDestruct(cstr_t **const ppThis) { free((*ppThis)->pBuf); RSFREEOBJ(*ppThis); *ppThis = NULL; } /* extend the string buffer if its size is insufficient. * Param iMinNeeded is the minumum free space needed. If it is larger * than the default alloc increment, space for at least this amount is * allocated. In practice, a bit more is allocated because we envision that * some more characters may be added after these. * rgerhards, 2008-01-07 * changed to utilized realloc() -- rgerhards, 2009-06-16 */ static rsRetVal rsCStrExtendBuf(cstr_t *const __restrict__ pThis, const size_t iMinNeeded) { uchar *pNewBuf; size_t iNewSize; DEFiRet; /* first compute the new size needed */ if (iMinNeeded > RS_STRINGBUF_ALLOC_INCREMENT) { /* we allocate "n" ALLOC_INCREMENTs. Usually, that should * leave some room after the absolutely needed one. It also * reduces memory fragmentation. Note that all of this are * integer operations (very important to understand what is * going on)! Parenthesis are for better readibility. */ iNewSize = (iMinNeeded / RS_STRINGBUF_ALLOC_INCREMENT + 1) * RS_STRINGBUF_ALLOC_INCREMENT; } else { iNewSize = pThis->iBufSize + RS_STRINGBUF_ALLOC_INCREMENT; } iNewSize += pThis->iBufSize; /* add current size */ #if DEV_DEBUG == 1 dbgprintf("extending string buffer, old %d, new %d\n", pThis->iBufSize, iNewSize); #endif CHKmalloc(pNewBuf = (uchar *)realloc(pThis->pBuf, iNewSize)); pThis->iBufSize = iNewSize; pThis->pBuf = pNewBuf; finalize_it: RETiRet; } /* Append a character to the current string object. This may only be done until * cstrFinalize() is called. * rgerhards, 2009-06-16 */ rsRetVal cstrAppendChar(cstr_t *const __restrict__ pThis, const uchar c) { rsRetVal iRet = RS_RET_OK; if (pThis->iStrLen + 1 >= pThis->iBufSize) { CHKiRet(rsCStrExtendBuf(pThis, 1)); /* need more memory! */ } /* ok, when we reach this, we have sufficient memory */ *(pThis->pBuf + pThis->iStrLen++) = c; finalize_it: return iRet; } /* append a string of known length. In this case, we make sure we do at most * one additional memory allocation. */ rsRetVal rsCStrAppendStrWithLen(cstr_t *const pThis, const uchar *const psz, const size_t iStrLen) { DEFiRet; rsCHECKVALIDOBJECT(pThis, OIDrsCStr); assert(psz != NULL); /* does the string fit? */ if (pThis->iStrLen + iStrLen >= pThis->iBufSize) { CHKiRet(rsCStrExtendBuf(pThis, iStrLen)); /* need more memory! */ } /* ok, now we always have sufficient continues memory to do a memcpy() */ memcpy(pThis->pBuf + pThis->iStrLen, psz, iStrLen); pThis->iStrLen += iStrLen; finalize_it: RETiRet; } /* changed to be a wrapper to rsCStrAppendStrWithLen() so that * we can save some time when we have the length but do not * need to change existing code. * rgerhards, 2007-07-03 */ rsRetVal rsCStrAppendStr(cstr_t *const pThis, const uchar *const psz) { return rsCStrAppendStrWithLen(pThis, psz, strlen((char *)psz)); } /* append the contents of one cstr_t object to another * rgerhards, 2008-02-25 */ rsRetVal cstrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend) { return rsCStrAppendStrWithLen(pThis, pstrAppend->pBuf, pstrAppend->iStrLen); } /* append a printf-style formated string */ rsRetVal rsCStrAppendStrf(cstr_t *pThis, const char *fmt, ...) { DEFiRet; va_list ap; cstr_t *pStr = NULL; va_start(ap, fmt); iRet = rsCStrConstructFromszStrv(&pStr, (char *)fmt, ap); va_end(ap); if (iRet != RS_RET_OK) goto finalize_it; iRet = cstrAppendCStr(pThis, pStr); rsCStrDestruct(&pStr); finalize_it: RETiRet; } rsRetVal rsCStrAppendInt(cstr_t *pThis, long i) { DEFiRet; uchar szBuf[32]; rsCHECKVALIDOBJECT(pThis, OIDrsCStr); CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), i)); iRet = rsCStrAppendStr(pThis, szBuf); finalize_it: RETiRet; } /* Sets the string object to the classigal sz-string provided. * Any previously stored vlaue is discarded. If a NULL pointer * the the new value (pszNew) is provided, an empty string is * created (this is NOT an error!). * rgerhards, 2005-10-18 */ rsRetVal rsCStrSetSzStr(cstr_t *const __restrict__ pThis, uchar *const __restrict__ pszNew) { rsCHECKVALIDOBJECT(pThis, OIDrsCStr); if (pszNew == NULL) { free(pThis->pBuf); pThis->pBuf = NULL; pThis->iStrLen = 0; pThis->iBufSize = 0; } else { const size_t newlen = strlen((char *)pszNew); if (newlen > pThis->iBufSize) { uchar *const newbuf = (uchar *)realloc(pThis->pBuf, newlen + 1); if (newbuf == NULL) { /* we keep the old value, best we can do */ return RS_RET_OUT_OF_MEMORY; } pThis->pBuf = newbuf; pThis->iBufSize = newlen + 1; } pThis->iStrLen = newlen; memcpy(pThis->pBuf, pszNew, pThis->iStrLen); } return RS_RET_OK; } /* Converts the CStr object to a classical zero-terminated C string * and returns that string. The caller must not free it and must not * destroy the CStr object as long as the ascii string is used. */ uchar *cstrGetSzStrNoNULL(cstr_t *const __restrict__ pThis) { assert(pThis->isFinalized); return (pThis->pBuf == NULL) ? (uchar *)"" : pThis->pBuf; } /* Converts the CStr object to a classical zero-terminated C string, * returns that string and destroys the CStr object. The returned string * MUST be freed by the caller. The function might return NULL if * no memory can be allocated. * * This is the NEW replacement for rsCStrConvSzStrAndDestruct which does * no longer utilize a special buffer but soley works on pBuf (and also * assumes that cstrFinalize had been called). * * Parameters are as follows: * pointer to the object, pointer to string-pointer to receive string and * bRetNULL: 0 - must not return NULL on empty string, return "" in that * case, 1 - return NULL instead of an empty string. * PLEASE NOTE: the caller must free the memory returned in ppSz in any case * (except, of course, if it is NULL). */ rsRetVal cstrConvSzStrAndDestruct(cstr_t **ppThis, uchar **ppSz, int bRetNULL) { DEFiRet; uchar *pRetBuf; cstr_t *pThis; assert(ppThis != NULL); pThis = *ppThis; assert(pThis->isFinalized); rsCHECKVALIDOBJECT(pThis, OIDrsCStr); assert(ppSz != NULL); assert(bRetNULL == 0 || bRetNULL == 1); if (pThis->pBuf == NULL) { if (bRetNULL == 0) { CHKmalloc(pRetBuf = malloc(1)); *pRetBuf = '\0'; } else { pRetBuf = NULL; } } else { pThis->pBuf[pThis->iStrLen] = '\0'; /* space for this is reserved */ pRetBuf = pThis->pBuf; } *ppSz = pRetBuf; finalize_it: /* We got it, now free the object ourselfs. Please note * that we can NOT use the rsCStrDestruct function as it would * also free the sz String buffer, which we pass on to the user. */ RSFREEOBJ(pThis); *ppThis = NULL; RETiRet; } /* return the length of the current string * 2005-09-09 rgerhards * Please note: this is only a function in a debug build. * For release builds, it is a macro defined in stringbuf.h. * This is due to performance reasons. */ #ifndef NDEBUG size_t cstrLen(cstr_t *pThis) { rsCHECKVALIDOBJECT(pThis, OIDrsCStr); return (pThis->iStrLen); } #endif /* Truncate characters from the end of the string. * rgerhards 2005-09-15 */ rsRetVal rsCStrTruncate(cstr_t *pThis, size_t nTrunc) { rsCHECKVALIDOBJECT(pThis, OIDrsCStr); if (pThis->iStrLen < nTrunc) return RS_TRUNCAT_TOO_LARGE; pThis->iStrLen -= nTrunc; return RS_RET_OK; } /* Trim trailing whitespace from a given string */ void cstrTrimTrailingWhiteSpace(cstr_t *const __restrict__ pThis) { register int i; register uchar *pC; rsCHECKVALIDOBJECT(pThis, OIDrsCStr); if (pThis->iStrLen == 0) goto done; /* empty string -> nothing to trim ;) */ i = pThis->iStrLen; pC = pThis->pBuf + i - 1; while (i > 0 && isspace((int)*pC)) { --pC; --i; } /* i now is the new string length! */ if (i != (int)pThis->iStrLen) { pThis->iStrLen = i; pThis->pBuf[pThis->iStrLen] = '\0'; /* we always have this space */ // TODO: can we remove this? } done: return; } /* compare two string objects - works like strcmp(), but operates * on CStr objects. Please note that this version here is * faster in the majority of cases, simply because it can * rely on StrLen. * rgerhards 2005-09-19 * fixed bug, in which only the last byte was actually compared * in equal-size strings. * rgerhards, 2005-09-26 */ int rsCStrCStrCmp(cstr_t *const __restrict__ pCS1, cstr_t *const __restrict__ pCS2) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); rsCHECKVALIDOBJECT(pCS2, OIDrsCStr); if (pCS1->iStrLen == pCS2->iStrLen) if (pCS1->iStrLen == 0) return 0; /* zero-sized string are equal ;) */ else return memcmp(pCS1->pBuf, pCS2->pBuf, pCS1->iStrLen); else return pCS1->iStrLen - pCS2->iStrLen; } /* check if a sz-type string starts with a CStr object. This function * is initially written to support the "startswith" property-filter * comparison operation. Maybe it also has other needs. * This functions is modelled after the strcmp() series, thus a * return value of 0 indicates that the string starts with the * sequence while -1 indicates it does not! * rgerhards 2005-10-19 */ int rsCStrSzStrStartsWithCStr(cstr_t *const __restrict__ pCS1, uchar *const __restrict__ psz, const size_t iLenSz) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(psz != NULL); assert(iLenSz == strlen((char *)psz)); /* just make sure during debugging! */ if (iLenSz >= pCS1->iStrLen) { if (pCS1->iStrLen == 0) return 0; /* yes, it starts with a zero-sized string ;) */ else return memcmp(psz, pCS1->pBuf, pCS1->iStrLen); } else { return -1; /* pCS1 is less then psz */ } } /* check if a sz-type string ends with a CStr object. This helper mirrors * rsCStrSzStrStartsWithCStr and is primarily intended for the new * "endswith" property-filter operation. * returns 0 if the string ends with the pattern, -1 otherwise. */ int rsCStrSzStrEndsWithCStr(cstr_t *const __restrict__ pCS1, uchar *const __restrict__ psz, const size_t iLenSz) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(psz != NULL); assert(iLenSz == strlen((char *)psz)); if (iLenSz >= pCS1->iStrLen) { if (pCS1->iStrLen == 0) { return 0; /* yes, it ends with a zero-sized string ;) */ } else { return memcmp(psz + iLenSz - pCS1->iStrLen, pCS1->pBuf, pCS1->iStrLen); } } else { return -1; } } /* check if a CStr object matches a regex. * msamia@redhat.com 2007-07-12 * @return returns 0 if matched * bug: doesn't work for CStr containing \0 * rgerhards, 2007-07-16: bug is no real bug, because rsyslogd ensures there * never is a \0 *inside* a property string. * Note that the function returns -1 if regexp functionality is not available. * rgerhards: 2009-03-04: ERE support added, via parameter iType: 0 - BRE, 1 - ERE * Arnaud Cornet/rgerhards: 2009-04-02: performance improvement by caching compiled regex * If a caller does not need the cached version, it must still provide memory for it * and must call rsCStrRegexDestruct() afterwards. */ rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *rc) { regex_t **cache = (regex_t **)rc; int ret; DEFiRet; assert(pCS1 != NULL); assert(psz != NULL); assert(cache != NULL); if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { if (*cache == NULL) { *cache = calloc(1, sizeof(regex_t)); int errcode; if ((errcode = regexp.regcomp(*cache, (char *)rsCStrGetSzStrNoNULL(pCS1), (iType == 1 ? REG_EXTENDED : 0) | REG_NOSUB))) { char errbuff[512]; regexp.regerror(errcode, *cache, errbuff, sizeof(errbuff)); LogError(0, NO_ERRCODE, "Error in regular expression: %s\n", errbuff); ABORT_FINALIZE(RS_RET_NOT_FOUND); } } ret = regexp.regexec(*cache, (char *)psz, 0, NULL, 0); if (ret != 0) ABORT_FINALIZE(RS_RET_NOT_FOUND); } else { ABORT_FINALIZE(RS_RET_NOT_FOUND); } finalize_it: RETiRet; } /* free a cached compiled regex * Caller must provide a pointer to a buffer that was created by * rsCStrSzStrMatchRegexCache() */ void rsCStrRegexDestruct(void *rc) { regex_t **cache = rc; assert(cache != NULL); assert(*cache != NULL); if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { regexp.regfree(*cache); free(*cache); *cache = NULL; } } /* compare a rsCStr object with a classical sz string. This function * is almost identical to rsCStrZsStrCmp(), but it also takes an offset * to the CStr object from where the comparison is to start. * I have thought quite a while if it really makes sense to more or * less duplicate the code. After all, if you call it with an offset of * zero, the functionality is exactly the same. So it looks natural to * just have a single function. However, supporting the offset requires * some (few) additional integer operations. While they are few, they * happen at places in the code that is run very frequently. All in all, * I have opted for performance and thus duplicated the code. I hope * this is a good, or at least acceptable, compromise. * rgerhards, 2005-09-26 * This function also has an offset-pointer which allows one to * specify *where* the compare operation should begin in * the CStr. If everything is to be compared, it must be set * to 0. If some leading bytes are to be skipped, it must be set * to the first index that is to be compared. It must not be * set higher than the string length (this is considered a * program bug and will lead to unpredictable results and program aborts). * rgerhards 2005-09-26 */ int rsCStrOffsetSzStrCmp(cstr_t *pCS1, size_t iOffset, uchar *psz, size_t iLenSz) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(iOffset < pCS1->iStrLen); assert(iLenSz == strlen((char *)psz)); /* just make sure during debugging! */ if ((pCS1->iStrLen - iOffset) == iLenSz) { /* we are using iLenSz below, because the lengths * are equal and iLenSz is faster to access */ if (iLenSz == 0) { return 0; /* zero-sized strings are equal ;) */ } else { /* we now have two non-empty strings of equal * length, so we need to actually check if they * are equal. */ return memcmp(pCS1->pBuf + iOffset, psz, iLenSz); } } else { return pCS1->iStrLen - iOffset - iLenSz; } } /* compare a rsCStr object with a classical sz string. * Just like rsCStrCStrCmp, just for a different data type. * There must not only the sz string but also its length be * provided. If the caller does not know the length he can * call with * rsCstrSzStrCmp(pCS, psz, strlen((char*)psz)); * we are not doing the strlen((char*)) ourselfs as the caller might * already know the length and in such cases we can save the * overhead of doing it one more time (strelen() is costly!). * The bottom line is that the provided length MUST be correct! * The to sz string pointer must not be NULL! * rgerhards 2005-09-26 */ int rsCStrSzStrCmp(cstr_t *pCS1, uchar *psz, size_t iLenSz) { rsCHECKVALIDOBJECT(pCS1, OIDrsCStr); assert(psz != NULL); assert(iLenSz == strlen((char *)psz)); /* just make sure during debugging! */ if (pCS1->iStrLen == iLenSz) if (iLenSz == 0) return 0; /* zero-sized strings are equal ;) */ else return strncmp((char *)pCS1->pBuf, (char *)psz, iLenSz); else return (ssize_t)pCS1->iStrLen - (ssize_t)iLenSz; } /* Locate the first occurrence of this rsCStr object inside a standard sz string. * Returns the offset (0-bound) of this first occurrence. If not found, -1 is * returned. Both parameters MUST be given (NULL is not allowed). * rgerhards 2005-09-19 */ int ATTR_NONNULL(1, 2) rsCStrLocateInSzStr(cstr_t *const pThis, uchar *const sz) { size_t i; size_t iMax; size_t len_sz = ustrlen(sz); int bFound; rsCHECKVALIDOBJECT(pThis, OIDrsCStr); assert(sz != NULL); if (pThis->iStrLen == 0) return 0; /* compute the largest index where a match could occur - after all, * the to-be-located string must be able to be present in the * searched string (it needs its size ;)). */ iMax = (pThis->iStrLen >= len_sz) ? 0 : len_sz - pThis->iStrLen; bFound = 0; i = 0; while (i <= iMax && !bFound) { size_t iCheck; uchar *pComp = sz + i; for (iCheck = 0; iCheck < pThis->iStrLen; ++iCheck) if (*(pComp + iCheck) != *(pThis->pBuf + iCheck)) break; if (iCheck == pThis->iStrLen) bFound = 1; /* found! - else it wouldn't be equal */ else ++i; /* on to the next try */ } return (bFound ? (int)i : -1); } /* our exit function. TODO: remove once converted to a class * rgerhards, 2008-03-11 */ rsRetVal strExit(void) { DEFiRet; objRelease(regexp, LM_REGEXP_FILENAME); RETiRet; } /* our init function. TODO: remove once converted to a class */ rsRetVal strInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/wtp.h0000644000000000000000000000013215062756615015214 xustar0030 mtime=1758190989.231641545 30 atime=1764930980.028678357 30 ctime=1764935923.246577545 rsyslog-8.2512.0/runtime/wtp.h0000664000175000017500000001120115062756615014653 0ustar00rgerrger/* Definition of the worker thread pool (wtp) object. * * Copyright 2008-2018 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef WTP_H_INCLUDED #define WTP_H_INCLUDED #include #include "obj.h" #include "atomic.h" /* states for worker threads. * important: they need to be increasing with all previous state bits * set. That is because we can only atomically or a value! */ #define WRKTHRD_STOPPED 0 #define WRKTHRD_INITIALIZING 1 #define WRKTHRD_RUNNING 3 #define WRKTHRD_WAIT_JOIN 7 /* possible states of a worker thread pool */ typedef enum { wtpState_RUNNING = 0, /* runs in regular mode */ wtpState_SHUTDOWN = 1, /* worker threads shall shutdown when idle */ wtpState_SHUTDOWN_IMMEDIATE = 2 /* worker threads shall shutdown ASAP, even if not idle */ } wtpState_t; /* the worker thread pool (wtp) object */ struct wtp_s { BEGINobjInstance ; wtpState_t wtpState; int iNumWorkerThreads; /* number of worker threads to use */ int iCurNumWrkThrd; /* current number of active worker threads */ struct wti_s **pWrkr; /* array with control structure for the worker thread(s) associated with this wtp */ int toWrkShutdown; /* timeout for idle workers in ms, -1 means indefinite (0 is immediate) */ rsRetVal (*pConsumer)(void *); /* user-supplied consumer function for dewtpd messages */ /* synchronization variables */ pthread_mutex_t mutWtp; /* mutex for the wtp's thread management */ pthread_cond_t condThrdInitDone; /* signalled when a new thread is ready for work */ pthread_cond_t condThrdTrm; /* signalled when threads terminate */ /* end sync variables */ /* user objects */ void *pUsr; /* pointer to user object (in this case, the queue the wtp belongs to) */ pthread_attr_t attrThrd; /* attribute for new threads (created just once and cached here) */ pthread_mutex_t *pmutUsr; rsRetVal (*pfChkStopWrkr)(void *pUsr, int); rsRetVal (*pfGetDeqBatchSize)(void *pUsr, int *); /* obtains max dequeue count from queue config */ rsRetVal (*pfObjProcessed)(void *pUsr, wti_t *pWti); /* indicate user object is processed */ rsRetVal (*pfRateLimiter)(void *pUsr); rsRetVal (*pfDoWork)(void *pUsr, void *pWti); /* end user objects */ uchar *pszDbgHdr; /* header string for debug messages */ DEF_ATOMIC_HELPER_MUT(mutCurNumWrkThrd); DEF_ATOMIC_HELPER_MUT(mutWtpState); }; /* some symbolic constants for easier reference */ #define DENY_WORKER_START_DURING_SHUTDOWN 0 #define PERMIT_WORKER_START_DURING_SHUTDOWN 1 /* prototypes */ rsRetVal wtpConstruct(wtp_t **ppThis); rsRetVal wtpConstructFinalize(wtp_t *pThis); rsRetVal wtpDestruct(wtp_t **ppThis); rsRetVal wtpAdviseMaxWorkers(wtp_t *pThis, int nMaxWrkr, const int permit_during_shutdown); rsRetVal wtpProcessThrdChanges(wtp_t *pThis); rsRetVal wtpChkStopWrkr(wtp_t *pThis, int bLockUsrMutex); rsRetVal wtpSetState(wtp_t *pThis, wtpState_t iNewState); rsRetVal wtpWakeupAllWrkr(wtp_t *pThis); rsRetVal wtpCancelAll(wtp_t *pThis, const uchar *const cancelobj); rsRetVal wtpSetDbgHdr(wtp_t *pThis, uchar *pszMsg, size_t lenMsg); rsRetVal wtpShutdownAll(wtp_t *pThis, wtpState_t tShutdownCmd, struct timespec *ptTimeout); PROTOTYPEObjClassInit(wtp); PROTOTYPEObjClassExit(wtp); PROTOTYPEpropSetMethFP(wtp, pfChkStopWrkr, rsRetVal (*pVal)(void *, int)); PROTOTYPEpropSetMethFP(wtp, pfRateLimiter, rsRetVal (*pVal)(void *)); PROTOTYPEpropSetMethFP(wtp, pfGetDeqBatchSize, rsRetVal (*pVal)(void *, int *)); PROTOTYPEpropSetMethFP(wtp, pfDoWork, rsRetVal (*pVal)(void *, void *)); PROTOTYPEpropSetMethFP(wtp, pfObjProcessed, rsRetVal (*pVal)(void *, wti_t *)); PROTOTYPEpropSetMeth(wtp, toWrkShutdown, long); PROTOTYPEpropSetMeth(wtp, wtpState, wtpState_t); PROTOTYPEpropSetMeth(wtp, iMaxWorkerThreads, int); PROTOTYPEpropSetMeth(wtp, pUsr, void *); PROTOTYPEpropSetMeth(wtp, iNumWorkerThreads, int); PROTOTYPEpropSetMethPTR(wtp, pmutUsr, pthread_mutex_t); #endif /* #ifndef WTP_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/debug.c0000644000000000000000000000013215055605325015454 xustar0030 mtime=1756826325.644800608 30 atime=1764930988.853825801 30 ctime=1764935923.200576841 rsyslog-8.2512.0/runtime/debug.c0000664000175000017500000003607015055605325015126 0ustar00rgerrger/* debug.c * * This file proides debug support. * * File begun on 2008-01-22 by RGerhards * * Some functions are controlled by environment variables: * * RSYSLOG_DEBUGLOG if set, a debug log file is written to that location * RSYSLOG_DEBUG specific debug options * * For details, visit doc/debug.html * * Copyright 2008-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" /* autotools! */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SYSCALL_H #include #endif #if _POSIX_TIMERS <= 0 #include #endif #include "rsyslog.h" #include "debug.h" #include "cfsysline.h" #include "obj.h" /* static data (some time to be replaced) */ DEFobjCurrIf(obj) int Debug = DEBUG_OFF; /* debug flag - read-only after startup */ int debugging_on = 0; /* read-only, except on sig USR1 */ int dbgTimeoutToStderr = 0; static int bPrintTime = 1; /* print a timestamp together with debug message */ static int bOutputTidToStderr = 0; /* output TID to stderr on thread creation */ char *pszAltDbgFileName = NULL; /* if set, debug output is *also* sent to here */ int altdbg = -1; /* and the handle for alternate debug output */ int stddbg = 1; /* the handle for regular debug output, set to stdout if not forking, -1 otherwise */ static uint64_t dummy_errcount = 0; /* just to avoid some static analyzer complaints */ static pthread_key_t keyThrdName; /* output the current thread ID to "relevant" places * (what "relevant" means is determinded by various ways) */ void dbgOutputTID(char *name __attribute__((unused))) { #if defined(HAVE_SYSCALL) && defined(HAVE_SYS_gettid) if (bOutputTidToStderr) fprintf(stderr, "thread tid %u, name '%s'\n", (unsigned)syscall(SYS_gettid), name); DBGPRINTF("thread created, tid %u, name '%s'\n", (unsigned)syscall(SYS_gettid), name); #endif } /* build a string with the thread name. If none is set, the thread ID is * used instead. Caller must provide buffer space. */ static void ATTR_NONNULL() dbgGetThrdName(char *const pszBuf, const size_t lenBuf, const pthread_t thrdID) { assert(pszBuf != NULL); const char *const thrdName = pthread_getspecific(keyThrdName); if (thrdName == NULL) { snprintf(pszBuf, lenBuf, "%lx", (long)thrdID); } else { snprintf(pszBuf, lenBuf, "%-15s", thrdName); } } /* set a name for the current thread */ void ATTR_NONNULL() dbgSetThrdName(const uchar *const pszName) { (void)pthread_setspecific(keyThrdName, strdup((char *)pszName)); } /* destructor for thread name (called by pthreads!) */ static void dbgThrdNameDestruct(void *arg) { free(arg); } /* write the debug message. This is a helper to dbgprintf and dbgoprint which * contains common code. added 2008-09-26 rgerhards * Note: We need to split the function due to the bad nature of POSIX * cancel cleanup handlers. */ static void DBGL_UNUSED dbgprint(obj_t *pObj, char *pszMsg, const char *pszFileName, const size_t lenMsg) { uchar *pszObjName = NULL; static pthread_t ptLastThrdID = 0; static int bWasNL = 0; char pszThrdName[64]; /* 64 is to be on the safe side, anything over 20 is bad... */ char pszWriteBuf[32 * 1024]; size_t lenCopy; size_t offsWriteBuf = 0; size_t lenWriteBuf; struct timespec t; #if _POSIX_TIMERS <= 0 struct timeval tv; #endif if (pObj != NULL) { pszObjName = obj.GetName(pObj); } /* The bWasNL handler does not really work. It works if no thread * switching occurs during non-NL messages. Else, things are messed * up. Anyhow, it works well enough to provide useful help during * getting this up and running. It is questionable if the extra effort * is worth fixing it, giving the limited appliability. -- rgerhards, 2005-10-25 * I have decided that it is not worth fixing it - especially as it works * pretty well. -- rgerhards, 2007-06-15 */ if (ptLastThrdID != pthread_self()) { if (!bWasNL) { pszWriteBuf[0] = '\n'; offsWriteBuf = 1; bWasNL = 1; } ptLastThrdID = pthread_self(); } dbgGetThrdName(pszThrdName, sizeof(pszThrdName), ptLastThrdID); if (bWasNL) { if (bPrintTime) { #if _POSIX_TIMERS > 0 /* this is the "regular" code */ clock_gettime(CLOCK_REALTIME, &t); #else gettimeofday(&tv, NULL); t.tv_sec = tv.tv_sec; t.tv_nsec = tv.tv_usec * 1000; #endif lenWriteBuf = snprintf(pszWriteBuf + offsWriteBuf, sizeof(pszWriteBuf) - offsWriteBuf, "%4.4ld.%9.9ld:", (long)(t.tv_sec % 10000), t.tv_nsec); offsWriteBuf += lenWriteBuf; } lenWriteBuf = snprintf(pszWriteBuf + offsWriteBuf, sizeof(pszWriteBuf) - offsWriteBuf, "%s: ", pszThrdName); offsWriteBuf += lenWriteBuf; /* print object name header if we have an object */ if (pszObjName != NULL) { lenWriteBuf = snprintf(pszWriteBuf + offsWriteBuf, sizeof(pszWriteBuf) - offsWriteBuf, "%s: ", pszObjName); offsWriteBuf += lenWriteBuf; } lenWriteBuf = snprintf(pszWriteBuf + offsWriteBuf, sizeof(pszWriteBuf) - offsWriteBuf, "%s: ", pszFileName); offsWriteBuf += lenWriteBuf; } if (lenMsg > sizeof(pszWriteBuf) - offsWriteBuf) lenCopy = sizeof(pszWriteBuf) - offsWriteBuf; else lenCopy = lenMsg; memcpy(pszWriteBuf + offsWriteBuf, pszMsg, lenCopy); offsWriteBuf += lenCopy; /* the write is included in an "if" just to silence compiler * warnings. Here, we really don't care if the write fails, we * have no good response to that in any case... -- rgerhards, 2012-11-28 */ if (stddbg != -1) { if (write(stddbg, pszWriteBuf, offsWriteBuf)) { ++dummy_errcount; } } if (altdbg != -1) { if (write(altdbg, pszWriteBuf, offsWriteBuf)) { ++dummy_errcount; } } bWasNL = (pszMsg[lenMsg - 1] == '\n') ? 1 : 0; } static int DBGL_UNUSED checkDbgFile(const char *srcname) { if (glblDbgFilesNum == 0) { return 1; } if (glblDbgWhitelist) { if (bsearch(srcname, glblDbgFiles, glblDbgFilesNum, sizeof(char *), bs_arrcmp_glblDbgFiles) == NULL) { return 0; } else { return 1; } } else { if (bsearch(srcname, glblDbgFiles, glblDbgFilesNum, sizeof(char *), bs_arrcmp_glblDbgFiles) != NULL) { return 0; } else { return 1; } } } /* print some debug output when an object is given * This is mostly a copy of dbgprintf, but I do not know how to combine it * into a single function as we have variable arguments and I don't know how to call * from one vararg function into another. I don't dig in this, it is OK for the * time being. -- rgerhards, 2008-01-29 */ #ifndef DEBUGLESS void r_dbgoprint(const char *srcname, obj_t *pObj, const char *fmt, ...) { va_list ap; char pszWriteBuf[32 * 1024]; size_t lenWriteBuf; if (!(Debug && debugging_on)) return; if (!checkDbgFile(srcname)) { return; } va_start(ap, fmt); lenWriteBuf = vsnprintf(pszWriteBuf, sizeof(pszWriteBuf), fmt, ap); va_end(ap); if (lenWriteBuf >= sizeof(pszWriteBuf)) { /* prevent buffer overrruns and garbagge display */ pszWriteBuf[sizeof(pszWriteBuf) - 5] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 4] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 3] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 2] = '\n'; pszWriteBuf[sizeof(pszWriteBuf) - 1] = '\0'; lenWriteBuf = sizeof(pszWriteBuf); } dbgprint(pObj, pszWriteBuf, srcname, lenWriteBuf); } #endif /* print some debug output when no object is given * WARNING: duplicate code, see dbgoprint above! */ #ifndef DEBUGLESS void r_dbgprintf(const char *srcname, const char *fmt, ...) { va_list ap; char pszWriteBuf[32 * 1024]; size_t lenWriteBuf; if (!(Debug && debugging_on)) { return; } if (!checkDbgFile(srcname)) { return; } va_start(ap, fmt); lenWriteBuf = vsnprintf(pszWriteBuf, sizeof(pszWriteBuf), fmt, ap); va_end(ap); if (lenWriteBuf >= sizeof(pszWriteBuf)) { /* prevent buffer overrruns and garbagge display */ pszWriteBuf[sizeof(pszWriteBuf) - 5] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 4] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 3] = '.'; pszWriteBuf[sizeof(pszWriteBuf) - 2] = '\n'; pszWriteBuf[sizeof(pszWriteBuf) - 1] = '\0'; lenWriteBuf = sizeof(pszWriteBuf); } dbgprint(NULL, pszWriteBuf, srcname, lenWriteBuf); } #endif /* support system to set debug options at runtime */ /* parse a param/value pair from the current location of the * option string. Returns 1 if an option was found, 0 * otherwise. 0 means there are NO MORE options to be * processed. -- rgerhards, 2008-02-28 */ static int ATTR_NONNULL() dbgGetRTOptNamVal(const uchar **const ppszOpt, uchar **const ppOptName) { assert(ppszOpt != NULL); assert(*ppszOpt != NULL); int bRet = 0; const uchar *p = *ppszOpt; size_t i; static uchar optname[128] = ""; /* skip whitespace */ while (*p && isspace(*p)) ++p; /* name: up until whitespace */ i = 0; while (i < (sizeof(optname) - 1) && *p && !isspace(*p)) { optname[i++] = *p++; } if (i > 0) { bRet = 1; optname[i] = '\0'; } /* done */ *ppszOpt = p; *ppOptName = optname; return bRet; } /* report fd used for debug log. This is needed in case of * auto-backgrounding, where the debug log shall not be closed. */ int dbgGetDbglogFd(void) { return altdbg; } /* read in the runtime options * rgerhards, 2008-02-28 */ static void dbgGetRuntimeOptions(void) { const uchar *pszOpts; uchar *optname; /* set some defaults */ if ((pszOpts = (uchar *)getenv("RSYSLOG_DEBUG")) != NULL) { /* we have options set, so let's process them */ while (dbgGetRTOptNamVal(&pszOpts, &optname)) { if (!strcasecmp((char *)optname, "help")) { fprintf(stderr, "rsyslogd " VERSION " runtime debug support - help requested, " "rsyslog terminates\n\nenvironment variables:\n" "additional logfile: export RSYSLOG_DEBUGFILE=\"/path/to/file\"\n" "to set: export RSYSLOG_DEBUG=\"cmd cmd cmd\"\n\n" "Commands are (all case-insensitive):\n" "help (this list, terminates rsyslogd)\n" "NoLogTimestamp\n" "Nostdout\n" "OutputTidToStderr\n" "DebugOnDemand - enables debugging on USR1, but does not turn on output\n" "\nSee debug.html in your doc set or https://www.rsyslog.com for details\n"); exit(1); } else if (!strcasecmp((char *)optname, "debug")) { /* this is earlier in the process than the -d option, as such it * allows us to spit out debug messages from the very beginning. */ Debug = DEBUG_FULL; debugging_on = 1; } else if (!strcasecmp((char *)optname, "debugondemand")) { /* Enables debugging, but turns off debug output */ Debug = DEBUG_ONDEMAND; debugging_on = 1; dbgprintf( "Note: debug on demand turned on via configuration file, " "use USR1 signal to activate.\n"); debugging_on = 0; } else if (!strcasecmp((char *)optname, "nologtimestamp")) { bPrintTime = 0; } else if (!strcasecmp((char *)optname, "nostdout")) { stddbg = -1; } else if (!strcasecmp((char *)optname, "outputtidtostderr")) { bOutputTidToStderr = 1; } else { fprintf(stderr, "rsyslogd " VERSION " error: invalid debug option '%s' " "- ignored\n", optname); } } } } void dbgSetDebugLevel(int level) { Debug = level; debugging_on = (level == DEBUG_FULL) ? 1 : 0; } void dbgSetDebugFile(uchar *fn) { if (altdbg != -1) { dbgprintf("switching to debug file %s\n", fn); close(altdbg); } if ((altdbg = open((char *)fn, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { fprintf(stderr, "alternate debug file could not be opened, ignoring. Error: %s\n", strerror(errno)); } } /* end support system to set debug options at runtime */ rsRetVal dbgClassInit(void) { rsRetVal iRet; /* do not use DEFiRet, as this makes calls into the debug system! */ (void)pthread_key_create(&keyThrdName, dbgThrdNameDestruct); /* while we try not to use any of the real rsyslog code (to avoid infinite loops), we * need to have the ability to query object names. Thus, we need to obtain a pointer to * the object interface. -- rgerhards, 2008-02-29 */ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ const char *dbgto2stderr; dbgto2stderr = getenv("RSYSLOG_DEBUG_TIMEOUTS_TO_STDERR"); dbgTimeoutToStderr = (dbgto2stderr != NULL && !strcmp(dbgto2stderr, "on")) ? 1 : 0; if (dbgTimeoutToStderr) { fprintf(stderr, "rsyslogd: NOTE: RSYSLOG_DEBUG_TIMEOUTS_TO_STDERR activated\n"); } dbgGetRuntimeOptions(); /* init debug system from environment */ pszAltDbgFileName = getenv("RSYSLOG_DEBUGLOG"); if (pszAltDbgFileName != NULL) { /* we have a secondary file, so let's open it) */ if ((altdbg = open(pszAltDbgFileName, O_WRONLY | O_CREAT | O_TRUNC | O_NOCTTY | O_CLOEXEC, S_IRUSR | S_IWUSR)) == -1) { fprintf(stderr, "alternate debug file could not be opened, ignoring. Error: %s\n", strerror(errno)); } } dbgSetThrdName((uchar *)"main thread"); finalize_it: return (iRet); } rsRetVal dbgClassExit(void) { pthread_key_delete(keyThrdName); if (altdbg != -1) close(altdbg); return RS_RET_OK; } rsyslog-8.2512.0/runtime/PaxHeaders/statsobj.h0000644000000000000000000000013215062756615016233 xustar0030 mtime=1758190989.230641531 30 atime=1764930980.034678457 30 ctime=1764935923.217577101 rsyslog-8.2512.0/runtime/statsobj.h0000664000175000017500000002201515062756615015677 0ustar00rgerrger/* The statsobj object. * * Copyright 2010-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file statsobj.h * @brief Interface of the rsyslog statistics object * * A statistics object (statsobj_t) represents a set of counters that * describe activity within a subsystem. Each object keeps a doubly * linked list of counters and all objects are maintained in a global * list protected by a mutex. The counters are either 64 bit integers * (ctrType_IntCtr) or plain int values (ctrType_Int) and can be marked * resettable. Statistics are only gathered while the global * ::GatherStats flag is non-zero. * * Counters can be reported in multiple formats via the GetAllStatsLines() * interface: * - ::statsFmt_Legacy classic key=value pairs * - ::statsFmt_JSON valid JSON structures * - ::statsFmt_JSON_ES JSON with dot replacement for Elasticsearch * - ::statsFmt_CEE Project Lumberjack / CEE format * - ::statsFmt_Prometheus Prometheus text exposition format * * The caller supplies a callback that receives each generated line. * After emission counters flagged with CTR_FLAG_RESETTABLE may be * cleared if requested. */ #ifndef INCLUDED_STATSOBJ_H #define INCLUDED_STATSOBJ_H #include "atomic.h" /* The following data item is somewhat dirty, in that it does not follow * our usual object calling conventions. However, much like with "Debug", we * do this to gain speed. If we finally come to a platform that does not * provide resolution of names for dynamically loaded modules, we need to find * a work-around, but until then, we use the direct access. * If set to 0, statistics are not gathered, otherwise they are. */ extern int GatherStats; /* our basic counter type -- need 32 bit on 32 bit platform. * IMPORTANT: this type *MUST* be supported by atomic instructions! */ typedef uint64 intctr_t; /* counter types */ typedef enum statsCtrType_e { ctrType_IntCtr, ctrType_Int } statsCtrType_t; /* stats line format types */ typedef enum statsFmtType_e { statsFmt_Legacy, statsFmt_JSON, statsFmt_JSON_ES, statsFmt_CEE, /** * Prometheus textâ€exposition format: * For each counter, emit: * # HELP _ (optional generic text) * # TYPE _ counter * _ */ statsFmt_Prometheus } statsFmtType_t; /* counter flags */ #define CTR_FLAG_NONE 0 #define CTR_FLAG_RESETTABLE 1 #define CTR_FLAG_MUST_RESET 2 /* statsobj flags */ #define STATSOBJ_FLAG_NONE 0 #define STATSOBJ_FLAG_DO_PREPEND 1 /* helper entity, the counter */ typedef struct ctr_s { uchar *name; statsCtrType_t ctrType; union { intctr_t *pIntCtr; int *pInt; } val; int8_t flags; struct ctr_s *next, *prev; } ctr_t; /* the statsobj object */ struct statsobj_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ uchar *name; uchar *origin; uchar *reporting_ns; statsobj_read_notifier_t read_notifier; void *read_notifier_ctx; pthread_mutex_t mutCtr; /* to guard counter linked-list ops */ ctr_t *ctrRoot; /* doubly-linked list of statsobj counters */ ctr_t *ctrLast; int flags; /* used to link ourselves together */ statsobj_t *prev; statsobj_t *next; }; struct sender_stats { const uchar *sender; uint64_t nMsgs; time_t lastSeen; }; /* interfaces */ BEGINinterface(statsobj) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(statsobj); rsRetVal (*Construct)(statsobj_t **ppThis); rsRetVal (*ConstructFinalize)(statsobj_t *pThis); rsRetVal (*Destruct)(statsobj_t **ppThis); rsRetVal (*SetName)(statsobj_t *pThis, uchar *name); rsRetVal (*SetOrigin)(statsobj_t *pThis, uchar *name); /* added v12, 2014-09-08 */ rsRetVal (*SetReadNotifier)(statsobj_t *pThis, statsobj_read_notifier_t notifier, void *ctx); rsRetVal (*SetReportingNamespace)(statsobj_t *pThis, uchar *ns); void (*SetStatsObjFlags)(statsobj_t *pThis, int flags); rsRetVal (*GetAllStatsLines)(rsRetVal (*cb)(void *, const char *), void *usrptr, statsFmtType_t fmt, int8_t bResetCtr); rsRetVal (*AddCounter)(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr); rsRetVal (*AddManagedCounter)(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr, ctr_t **ref, int8_t linked); void (*AddPreCreatedCtr)(statsobj_t *pThis, ctr_t *ctr); void (*DestructCounter)(statsobj_t *pThis, ctr_t *ref); void (*DestructUnlinkedCounter)(ctr_t *ctr); ctr_t *(*UnlinkAllCounters)(statsobj_t *pThis); rsRetVal (*EnableStats)(void); ENDinterface(statsobj) #define statsobjCURR_IF_VERSION 13 /* increment whenever you change the interface structure! */ /* Changes * v2-v9 rserved for future use in "older" version branches * v10, 2012-04-01: GetAllStatsLines got fmt parameter * v11, 2013-09-07: - add "flags" to AddCounter API * - GetAllStatsLines got parameter telling if ctrs shall be reset * v13, 2016-05-19: GetAllStatsLines cb data type changed (char* instead of cstr) */ /* prototypes */ PROTOTYPEObj(statsobj); rsRetVal statsRecordSender(const uchar *sender, unsigned nMsgs, time_t lastSeen); /* checkGoneAwaySenders() is part of this module because all it needs is * done by this module, so even though it's own processing is not directly * related to stats, it makes sense to do it here... -- rgerhards, 2016-02-01 */ void checkGoneAwaySenders(time_t); /* macros to handle stats counters * These are to be used by "counter providers". Note that we MUST * specify the mutex name, even though at first it looks like it * could be automatically be generated via e.g. "mut##ctr". * Unfortunately, this does not work if counter is e.g. "pThis->ctr". * So we decided, for clarity, to always insist on specifying the mutex * name (after all, it's just a few more keystrokes...). * -------------------------------------------------------------------- * NOTE WELL * -------------------------------------------------------------------- * There are actually two types of stats counters: "regular" counters, * which are only used for stats purposes and "dual" counters, which * are primarily used for other purposes but can be included in stats * as well. ALL regular counters MUST be initialized with * STATSCOUNTER_INIT and only be modified by STATSCOUNTER_* functions. * They MUST NOT be used for any other purpose (if this seems to make * sense, consider changing it to a dual counter). * Dual counters are somewhat dangerous in that a single variable is * used for two purposes: the actual application need and stats * counting. However, this is supported for performance reasons, as it * provides insight into the inner engine workings without need for * additional counters (and their maintenance code). Dual counters * MUST NOT be modified by STATSCOUNTER_* functions. Most importantly, * it is expected that the actua application code provides proper * (enough) synchronized access to these counters. Most importantly, * this means they have NO stats-system mutex associated to them. * * The interface function AddCounter() is a read-only function. It * only provides the stats subsystem with a reference to a counter. * It is irrelevant if the counter is a regular or dual one. For that * reason, AddCounter() must not modify the counter contents, as in * the case of a dual counter application code may be broken. */ #define STATSCOUNTER_DEF(ctr, mut) \ intctr_t ctr; \ DEF_ATOMIC_HELPER_MUT64(mut); #define STATSCOUNTER_INIT(ctr, mut) \ INIT_ATOMIC_HELPER_MUT64(mut); \ ctr = 0; #define STATSCOUNTER_INC(ctr, mut) \ if (GatherStats) ATOMIC_INC_uint64(&ctr, &mut); #define STATSCOUNTER_ADD(ctr, mut, delta) \ if (GatherStats) ATOMIC_ADD_uint64(&ctr, &mut, delta); #define STATSCOUNTER_DEC(ctr, mut) \ if (GatherStats) ATOMIC_DEC_uint64(&ctr, &mut); /* the next macro works only if the variable is already guarded * by mutex (or the users risks a wrong result). It is assumed * that there are not concurrent operations that modify the counter. */ #define STATSCOUNTER_SETMAX_NOMUT(ctr, newmax) \ if (GatherStats && ((newmax) > (ctr))) ctr = newmax; #endif /* #ifndef INCLUDED_STATSOBJ_H */ rsyslog-8.2512.0/runtime/PaxHeaders/libossl.h0000644000000000000000000000013115055605325016041 xustar0030 mtime=1756826325.646800638 29 atime=1764931130.14814336 30 ctime=1764935923.091575172 rsyslog-8.2512.0/runtime/libossl.h0000664000175000017500000000526715055605325015520 0ustar00rgerrger/* libossl.h - rsyslog's ossl crypto provider support library * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LIBOSSL_H #define INCLUDED_LIBOSSL_H #include #include #include #include struct osslctx_s { uchar* key; size_t keyLen; const EVP_CIPHER* cipher; /* container for algorithm + mode */ }; typedef struct osslctx_s* osslctx; typedef struct osslfile_s* osslfile; /* this describes a file, as far as libgcry is concerned */ struct osslfile_s { // gcry_cipher_hd_t chd; /* cypher handle */ TODO EVP_CIPHER_CTX* chd; size_t blkLength; /* size of low-level crypto block */ uchar* eiName; /* name of .encinfo file */ int fd; /* descriptor of .encinfo file (-1 if not open) */ char openMode; /* 'r': read, 'w': write */ osslctx ctx; uchar* readBuf; int16_t readBufIdx; int16_t readBufMaxIdx; int8_t bDeleteOnClose; /* for queue support, similar to stream subsys */ ssize_t bytesToBlkEnd; /* number of bytes remaining in current crypto block -1 means -> no end (still being writen to, queue files), 0 means -> end of block, new one must be started. */ }; osslctx osslCtxNew(void); void rsosslCtxDel(osslctx ctx); rsRetVal rsosslSetAlgoMode(osslctx ctx, uchar* algorithm); int osslGetKeyFromFile(const char* const fn, char** const key, unsigned* const keylen); int rsosslSetKey(osslctx ctx, unsigned char* key, uint16_t keyLen); rsRetVal osslfileGetBytesLeftInBlock(osslfile gf, ssize_t* left); rsRetVal osslfileDeleteState(uchar* logfn); rsRetVal rsosslInitCrypt(osslctx ctx, osslfile* pgf, uchar* fname, char openMode); rsRetVal rsosslDecrypt(osslfile pF, uchar* buf, size_t* len); rsRetVal rsosslEncrypt(osslfile pF, uchar* buf, size_t* len); int osslfileDestruct(osslfile gf, off64_t offsLogfile); int rsosslInit(void); void rsosslExit(void); // FIXME refactor static inline void __attribute__((unused)) osslfileSetDeleteOnClose(osslfile gf, const int val) { if (gf != NULL) gf->bDeleteOnClose = val; } #endif /* #ifndef INCLUDED_LIBOSSL_H */ rsyslog-8.2512.0/runtime/PaxHeaders/unicode-helper.h0000644000000000000000000000013215055605325017276 xustar0030 mtime=1756826325.654800759 30 atime=1764930980.498686217 30 ctime=1764935923.106575402 rsyslog-8.2512.0/runtime/unicode-helper.h0000664000175000017500000000334615055605325016750 0ustar00rgerrger/* This is the header file for unicode support. * * Currently, this is a dummy module. * The following functions are wrappers which hopefully enable us to move * from 8-bit chars to unicode with relative ease when we finally attack this * * Begun 2009-05-21 RGerhards * * Copyright (C) 2009-2016 by Rainer Gerhards and Adiscon GmbH * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_UNICODE_HELPER_H #define INCLUDED_UNICODE_HELPER_H #include #define ustrncpy(psz1, psz2, len) strncpy((char*)(psz1), (char*)(psz2), (len)) #define ustrdup(psz) (uchar*)strdup((char*)(psz)) #define ustrcmp(psz1, psz2) (strcmp((const char*)(psz1), (const char*)(psz2))) #define ustrlen(psz) (strlen((const char*)(psz))) #define UCHAR_CONSTANT(x) ((uchar*)(x)) #define CHAR_CONVERT(x) ((char*)(x)) /* Compare values of two instances/configs/queues especially during dynamic config reload */ #define USTR_EQUALS(var) \ ((pOld->var == NULL) ? (pNew->var == NULL) : (pNew->var != NULL && !ustrcmp(pOld->var, pNew->var))) #define NUM_EQUALS(var) (pOld->var == pNew->var) #endif /* multi-include protection */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_ptcp.c0000644000000000000000000000013215062756615016207 xustar0030 mtime=1758190989.228641502 30 atime=1764931010.301182695 30 ctime=1764935923.376579536 rsyslog-8.2512.0/runtime/nsd_ptcp.c0000664000175000017500000011711215062756615015656 0ustar00rgerrger/* nsd_ptcp.c * * An implementation of the nsd interface for plain tcp sockets. * * Copyright 2007-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "parse.h" #include "srUtils.h" #include "obj.h" #include "errmsg.h" #include "net.h" #include "netstrms.h" #include "netstrm.h" #include "nsd_ptcp.h" #include "prop.h" #include "dnscache.h" #include "rsconf.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(netstrms) DEFobjCurrIf(netstrm) DEFobjCurrIf(prop) /* a few deinit helpers */ /* close socket if open (may always be called) */ static void sockClose(int *pSock) { if (*pSock >= 0) { close(*pSock); *pSock = -1; } } /* Standard-Constructor */ BEGINobjConstruct(nsd_ptcp) /* be sure to specify the object type also in END macro! */ pThis->sock = -1; ENDobjConstruct(nsd_ptcp) /* destructor for the nsd_ptcp object */ BEGINobjDestruct(nsd_ptcp) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(nsd_ptcp); sockClose(&pThis->sock); if (pThis->remoteIP != NULL) prop.Destruct(&pThis->remoteIP); free(pThis->pRemHostName); ENDobjDestruct(nsd_ptcp) /* Provide access to the sockaddr_storage of the remote peer. This * is needed by the legacy ACL system. --- gerhards, 2008-12-01 */ static rsRetVal GetRemAddr(nsd_t *pNsd, struct sockaddr_storage **ppAddr) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); assert(ppAddr != NULL); *ppAddr = &(pThis->remAddr); RETiRet; } /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_gtls) who utilize ourselfs * for some of their functionality. -- rgerhards, 2008-04-18 */ static rsRetVal GetSock(nsd_t *pNsd, int *pSock) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; NULL_CHECK(pSock); *pSock = pThis->sock; finalize_it: RETiRet; } /* Set the driver mode. We support no different modes, but allow mode * 0 to be set to be compatible with config file defaults and the other * drivers. * rgerhards, 2008-04-28 */ static rsRetVal SetMode(nsd_t __attribute__((unused)) * pNsd, int mode) { DEFiRet; if (mode != 0) { LogError(0, RS_RET_INVALID_DRVR_MODE, "error: driver mode %d not supported by " "ptcp netstream driver", mode); ABORT_FINALIZE(RS_RET_INVALID_DRVR_MODE); } finalize_it: RETiRet; } /* Set the driver cert extended key usage check setting, not supported in ptcp. * jvymazal, 2019-08-16 */ static rsRetVal SetCheckExtendedKeyUsage(nsd_t __attribute__((unused)) * pNsd, int ChkExtendedKeyUsage) { DEFiRet; if (ChkExtendedKeyUsage != 0) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d " "not supported by ptcp netstream driver", ChkExtendedKeyUsage); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set the driver name checking strictness, not supported in ptcp. * jvymazal, 2019-08-16 */ static rsRetVal SetPrioritizeSAN(nsd_t __attribute__((unused)) * pNsd, int prioritizeSan) { DEFiRet; if (prioritizeSan != 0) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d " "not supported by ptcp netstream driver", prioritizeSan); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set the tls verify depth, not supported in ptcp. * alorbach, 2019-12-20 */ static rsRetVal SetTlsVerifyDepth(nsd_t __attribute__((unused)) * pNsd, int verifyDepth) { nsd_ptcp_t __attribute__((unused)) *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); if (verifyDepth == 0) { FINALIZE; } finalize_it: RETiRet; } /* Set the authentication mode. For us, the following is supported: * anon - no certificate checks whatsoever (discouraged, but supported) * mode == NULL is valid and defaults to anon * Actually, we do not even record the mode right now, because we can * always work in anon mode, only. So there is no point in recording * something if that's the only choice. What the function does is * return an error if something is requested that we can not support. * rgerhards, 2008-05-17 */ static rsRetVal SetAuthMode(nsd_t __attribute__((unused)) * pNsd, uchar *mode) { DEFiRet; if (mode != NULL && strcasecmp((char *)mode, "anon")) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: authentication mode '%s' not supported by " "ptcp netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set the PermitExpiredCerts mode. not supported in ptcp * alorbach, 2018-12-20 */ static rsRetVal SetPermitExpiredCerts(nsd_t __attribute__((unused)) * pNsd, uchar *mode) { DEFiRet; if (mode != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: permitexpiredcerts setting not supported by " "ptcp netstream driver"); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } static rsRetVal SetTlsCAFile(nsd_t __attribute__((unused)) * pNsd, const uchar *const pszFile) { DEFiRet; if (pszFile != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: CA File setting not supported by " "ptcp netstream driver - value %s", pszFile); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } static rsRetVal SetTlsCRLFile(nsd_t __attribute__((unused)) * pNsd, const uchar *const pszFile) { DEFiRet; if (pszFile != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: CRL File setting not supported by " "ptcp netstream driver - value %s", pszFile); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } static rsRetVal SetTlsKeyFile(nsd_t __attribute__((unused)) * pNsd, const uchar *const pszFile) { DEFiRet; if (pszFile != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: TLS Key File setting not supported by " "ptcp netstream driver"); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } static rsRetVal SetTlsCertFile(nsd_t __attribute__((unused)) * pNsd, const uchar *const pszFile) { DEFiRet; if (pszFile != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: TLS Cert File setting not supported by " "ptcp netstream driver"); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set priorityString * PascalWithopf 2017-08-18 */ static rsRetVal SetGnutlsPriorityString(nsd_t __attribute__((unused)) * pNsd, uchar *iVal) { DEFiRet; if (iVal != NULL) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: " "gnutlsPriorityString '%s' not supported by ptcp netstream " "driver", iVal); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: RETiRet; } /* Set the permitted peers. This is a dummy, always returning an * error because we do not support fingerprint authentication. * rgerhards, 2008-05-17 */ static rsRetVal SetPermPeers(nsd_t __attribute__((unused)) * pNsd, permittedPeers_t __attribute__((unused)) * pPermPeers) { DEFiRet; if (pPermPeers != NULL) { LogError(0, RS_RET_VALUE_NOT_IN_THIS_MODE, "authentication not supported by ptcp netstream driver"); ABORT_FINALIZE(RS_RET_VALUE_NOT_IN_THIS_MODE); } finalize_it: RETiRet; } /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_gtls) who utilize ourselfs * for some of their functionality. * This function sets the socket -- rgerhards, 2008-04-25 */ static rsRetVal SetSock(nsd_t *pNsd, int sock) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); assert(sock >= 0); pThis->sock = sock; RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveIntvl(nsd_t *pNsd, int keepAliveIntvl) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); pThis->iKeepAliveIntvl = keepAliveIntvl; RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveProbes(nsd_t *pNsd, int keepAliveProbes) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); pThis->iKeepAliveProbes = keepAliveProbes; RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveTime(nsd_t *pNsd, int keepAliveTime) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); pThis->iKeepAliveTime = keepAliveTime; RETiRet; } /* abort a connection. This is meant to be called immediately * before the Destruct call. -- rgerhards, 2008-03-24 */ static rsRetVal Abort(nsd_t *pNsd) { struct linger ling; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_ptcp); if ((pThis)->sock != -1) { ling.l_onoff = 1; ling.l_linger = 0; if (setsockopt((pThis)->sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) < 0) { dbgprintf("could not set SO_LINGER, errno %d\n", errno); } } RETiRet; } /* Set pRemHost based on the address provided. This is to be called upon accept()ing * a connection request. It must be provided by the socket we received the * message on as well as a NI_MAXHOST size large character buffer for the FQDN. * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats) * for some explanation of the code found below. If we detect a malicious * hostname, we return RS_RET_MALICIOUS_HNAME and let the caller decide * on how to deal with that. * rgerhards, 2008-03-31 */ static rsRetVal FillRemHost(nsd_ptcp_t *pThis, struct sockaddr_storage *pAddr) { prop_t *fqdn; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_ptcp); assert(pAddr != NULL); CHKiRet(dnscacheLookup(pAddr, &fqdn, NULL, NULL, &pThis->remoteIP)); /* We now have the names, so now let's allocate memory and store them permanently. * (side note: we may hold on to these values for quite a while, thus we trim their * memory consumption) */ if ((pThis->pRemHostName = malloc(prop.GetStringLen(fqdn) + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pRemHostName, propGetSzStr(fqdn), prop.GetStringLen(fqdn) + 1); prop.Destruct(&fqdn); finalize_it: RETiRet; } /* obtain connection info as soon as we are connected */ static void get_socket_info(const int sockfd, char *const connInfo) { char local_ip_str[INET_ADDRSTRLEN]; // Buffer to hold the IP address string int local_port = -1; char local_port_str[8]; char remote_ip_str[INET_ADDRSTRLEN]; // Buffer to hold the IP address string int remote_port = -1; char remote_port_str[8]; struct sockaddr_in local_addr; socklen_t local_addr_len = sizeof(local_addr); struct sockaddr_in remote_addr; socklen_t remote_addr_len = sizeof(remote_addr); /* local system info */ local_addr.sin_port = 0; /* just to keep clang static analyzer happy */ if (getsockname(sockfd, (struct sockaddr *)&local_addr, &local_addr_len) == -1) { strcpy(local_ip_str, "?"); } else { if (inet_ntop(AF_INET, &local_addr.sin_addr, local_ip_str, INET_ADDRSTRLEN) == NULL) { strcpy(local_ip_str, "?"); } local_port = ntohs(local_addr.sin_port); } /* remote system info */ remote_addr.sin_port = 0; /* just to keep clang static analyzer happy */ if (getpeername(sockfd, (struct sockaddr *)&remote_addr, &remote_addr_len) == -1) { strcpy(remote_ip_str, "?"); } else { if (inet_ntop(AF_INET, &remote_addr.sin_addr, remote_ip_str, INET_ADDRSTRLEN) == NULL) { strcpy(remote_ip_str, "?"); } remote_port = ntohs(remote_addr.sin_port); } if (local_port == -1) { strcpy(local_port_str, "?"); } else { snprintf(local_port_str, 7, "%d", local_port); local_port_str[7] = '\0'; /* be on safe side */ } if (remote_port == -1) { strcpy(remote_port_str, "?"); } else { snprintf(remote_port_str, 7, "%d", remote_port); remote_port_str[7] = '\0'; /* be on safe side */ } snprintf(connInfo, TCPSRV_CONNINFO_SIZE, "from %s:%s to %s:%s", remote_ip_str, remote_port_str, local_ip_str, local_port_str); } /* accept an incoming connection request * rgerhards, 2008-04-22 */ static rsRetVal AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew, char *const connInfo) { int sockflags; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); nsd_ptcp_t *pNew = NULL; int iNewSock = -1; DEFiRet; assert(ppNew != NULL); ISOBJ_TYPE_assert(pThis, nsd_ptcp); iNewSock = accept(pThis->sock, (struct sockaddr *)&addr, &addrlen); if (iNewSock < 0) { if (errno == EINTR || errno == EAGAIN) { ABORT_FINALIZE(RS_RET_NO_MORE_DATA); } LogMsg(errno, RS_RET_ACCEPT_ERR, LOG_WARNING, "nds_ptcp: error accepting connection on socket %d", pThis->sock); ABORT_FINALIZE(RS_RET_ACCEPT_ERR); } get_socket_info(iNewSock, connInfo); /* construct our object so that we can use it... */ CHKiRet(nsd_ptcpConstruct(&pNew)); /* for the legacy ACL code, we need to preserve addr. While this is far from * begin perfect (from an abstract design perspective), we need this to prevent * breaking everything. */ memcpy(&pNew->remAddr, &addr, sizeof(struct sockaddr_storage)); CHKiRet(FillRemHost(pNew, &addr)); /* set the new socket to non-blocking IO -TODO:do we really need to do this here? Do we always want it? */ if ((sockflags = fcntl(iNewSock, F_GETFL)) != -1) { sockflags |= O_NONBLOCK; /* SETFL could fail too, so get it caught by the subsequent * error check. */ sockflags = fcntl(iNewSock, F_SETFL, sockflags); } if (sockflags == -1) { dbgprintf("error %d setting fcntl(O_NONBLOCK) on tcp socket %d", errno, iNewSock); ABORT_FINALIZE(RS_RET_IO_ERROR); } pNew->sock = iNewSock; *ppNew = (nsd_t *)pNew; finalize_it: if (iRet != RS_RET_OK) { if (pNew != NULL) nsd_ptcpDestruct(&pNew); /* the close may be redundant, but that doesn't hurt... */ sockClose(&iNewSock); } RETiRet; } /* initialize tcp sockets for a listner. The initialized sockets are passed to the * app-level caller via a callback. * pLstnPort must point to a port name or number. NULL is NOT permitted. pLstnIP * points to the port to listen to (NULL means "all"), iMaxSess has the maximum * number of sessions permitted. * rgerhards, 2008-04-22 */ static rsRetVal ATTR_NONNULL(1, 3, 5) LstnInit(netstrms_t *const pNS, void *pUsr, rsRetVal (*fAddLstn)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params) { DEFiRet; netstrm_t *pNewStrm = NULL; nsd_t *pNewNsd = NULL; int error, maxs, on = 1; int isIPv6 = 0; int sock = -1; int numSocks; int sockflags; int port_override = 0; /* if dyn port (0): use this for actually bound port */ struct addrinfo hints, *res = NULL, *r; union { struct sockaddr *sa; struct sockaddr_in *ipv4; struct sockaddr_in6 *ipv6; } savecast; ISOBJ_TYPE_assert(pNS, netstrms); assert(fAddLstn != NULL); assert(cnf_params->pszPort != NULL); assert(iSessMax >= 0); dbgprintf("creating tcp listen socket on port %s\n", cnf_params->pszPort); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = glbl.GetDefPFFamily(runConf); hints.ai_socktype = SOCK_STREAM; error = getaddrinfo((const char *)cnf_params->pszAddr, (const char *)cnf_params->pszPort, &hints, &res); if (error) { LogError(0, RS_RET_INVALID_PORT, "error querying port '%s': %s", (cnf_params->pszAddr == NULL) ? "**UNSPECIFIED**" : (const char *)cnf_params->pszAddr, gai_strerror(error)); ABORT_FINALIZE(RS_RET_INVALID_PORT); } /* Count max number of sockets we may open */ for (maxs = 0, r = res; r != NULL; r = r->ai_next, maxs++) /* EMPTY */ ; numSocks = 0; /* num of sockets counter at start of array */ for (r = res; r != NULL; r = r->ai_next) { if (port_override != 0) { savecast.sa = (struct sockaddr *)r->ai_addr; if (r->ai_family == AF_INET6) { savecast.ipv6->sin6_port = port_override; } else { savecast.ipv4->sin_port = port_override; } } sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol); if (sock < 0) { if (!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT)) { dbgprintf("error %d creating tcp listen socket", errno); /* it is debatable if PF_INET with EAFNOSUPPORT should * also be ignored... */ } continue; } #ifdef IPV6_V6ONLY if (r->ai_family == AF_INET6) { isIPv6 = 1; int iOn = 1; if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&iOn, sizeof(iOn)) < 0) { close(sock); sock = -1; continue; } } #endif if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { dbgprintf("error %d setting tcp socket option\n", errno); close(sock); sock = -1; continue; } /* We use non-blocking IO! */ if ((sockflags = fcntl(sock, F_GETFL)) != -1) { sockflags |= O_NONBLOCK; /* SETFL could fail too, so get it caught by the subsequent * error check. */ sockflags = fcntl(sock, F_SETFL, sockflags); } if (sockflags == -1) { dbgprintf("error %d setting fcntl(O_NONBLOCK) on tcp socket", errno); close(sock); sock = -1; continue; } /* We need to enable BSD compatibility. Otherwise an attacker * could flood our log files by sending us tons of ICMP errors. */ #if !defined(_AIX) && !defined(BSD) if (net.should_use_so_bsdcompat()) { if (setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT, (char *)&on, sizeof(on)) < 0) { LogError(errno, NO_ERRCODE, "TCP setsockopt(BSDCOMPAT)"); close(sock); sock = -1; continue; } } #endif if ((bind(sock, r->ai_addr, r->ai_addrlen) < 0) #ifndef IPV6_V6ONLY && (errno != EADDRINUSE) #endif ) { /* TODO: check if *we* bound the socket - else we *have* an error! */ LogError(errno, NO_ERRCODE, "Error while binding tcp socket"); close(sock); sock = -1; continue; } /* if we bind to dynamic port (port 0 given), we will do so consistently. Thus * once we got a dynamic port, we will keep it and use it for other protocols * as well. As of my understanding, this should always work as the OS does not * pick a port that is used by some protocol (well, at least this looks very * unlikely...). If our asusmption is wrong, we should iterate until we find a * combination that works - it is very unusual to have the same service listen * on differnt ports on IPv4 and IPv6. */ savecast.sa = (struct sockaddr *)r->ai_addr; const int currport = (isIPv6) ? savecast.ipv6->sin6_port : savecast.ipv4->sin_port; if (currport == 0) { socklen_t socklen_r = r->ai_addrlen; if (getsockname(sock, r->ai_addr, &socklen_r) == -1) { LogError(errno, NO_ERRCODE, "nsd_ptcp: ListenPortFileName: getsockname:" "error while trying to get socket"); } r->ai_addrlen = socklen_r; savecast.sa = (struct sockaddr *)r->ai_addr; port_override = (isIPv6) ? savecast.ipv6->sin6_port : savecast.ipv4->sin_port; if (cnf_params->pszLstnPortFileName != NULL) { FILE *fp; if ((fp = fopen((const char *)cnf_params->pszLstnPortFileName, "w+")) == NULL) { LogError(errno, RS_RET_IO_ERROR, "nsd_ptcp: ListenPortFileName: " "error while trying to open file"); ABORT_FINALIZE(RS_RET_IO_ERROR); } if (isIPv6) { fprintf(fp, "%d", ntohs(savecast.ipv6->sin6_port)); } else { fprintf(fp, "%d", ntohs(savecast.ipv4->sin_port)); } fclose(fp); } } const int iSynBacklog = (pNS->iSynBacklog == 0) ? iSessMax / 10 + 5 : pNS->iSynBacklog; if (listen(sock, iSynBacklog) < 0) { /* If the listen fails, it most probably fails because we ask * for a too-large backlog. So in this case we first set back * to a fixed, reasonable, limit that should work. Only if * that fails, too, we give up. */ dbgprintf("listen with a backlog of %d failed - retrying with default of 32.\n", iSessMax / 10 + 5); if (listen(sock, 32) < 0) { dbgprintf("tcp listen error %d, suspending\n", errno); close(sock); sock = -1; continue; } } /* if we reach this point, we were able to obtain a valid socket, so we can * construct a new netstrm obj and hand it over to the upper layers for inclusion * into their socket array. -- rgerhards, 2008-04-23 */ CHKiRet(pNS->Drvr.Construct(&pNewNsd)); CHKiRet(pNS->Drvr.SetSock(pNewNsd, sock)); CHKiRet(pNS->Drvr.SetMode(pNewNsd, netstrms.GetDrvrMode(pNS))); CHKiRet(pNS->Drvr.SetCheckExtendedKeyUsage(pNewNsd, netstrms.GetDrvrCheckExtendedKeyUsage(pNS))); CHKiRet(pNS->Drvr.SetPrioritizeSAN(pNewNsd, netstrms.GetDrvrPrioritizeSAN(pNS))); CHKiRet(pNS->Drvr.SetTlsCAFile(pNewNsd, netstrms.GetDrvrTlsCAFile(pNS))); CHKiRet(pNS->Drvr.SetTlsCRLFile(pNewNsd, netstrms.GetDrvrTlsCRLFile(pNS))); CHKiRet(pNS->Drvr.SetTlsKeyFile(pNewNsd, netstrms.GetDrvrTlsKeyFile(pNS))); CHKiRet(pNS->Drvr.SetTlsCertFile(pNewNsd, netstrms.GetDrvrTlsCertFile(pNS))); CHKiRet(pNS->Drvr.SetTlsVerifyDepth(pNewNsd, netstrms.GetDrvrTlsVerifyDepth(pNS))); CHKiRet(pNS->Drvr.SetAuthMode(pNewNsd, netstrms.GetDrvrAuthMode(pNS))); CHKiRet(pNS->Drvr.SetPermitExpiredCerts(pNewNsd, netstrms.GetDrvrPermitExpiredCerts(pNS))); CHKiRet(pNS->Drvr.SetPermPeers(pNewNsd, netstrms.GetDrvrPermPeers(pNS))); CHKiRet(pNS->Drvr.SetGnutlsPriorityString(pNewNsd, netstrms.GetDrvrGnutlsPriorityString(pNS))); CHKiRet(netstrms.CreateStrm(pNS, &pNewStrm)); pNewStrm->pDrvrData = (nsd_t *)pNewNsd; if (pNS->fLstnInitDrvr != NULL) { CHKiRet(pNS->fLstnInitDrvr(pNewStrm)); } CHKiRet(fAddLstn(pUsr, pNewStrm)); pNewStrm = NULL; /* sock has been handed over by SetSock() above, so invalidate it here * coverity scan falsely identifies this as ressource leak */ sock = -1; ++numSocks; } if (numSocks != maxs) dbgprintf( "We could initialize %d TCP listen sockets out of %d we received " "- this may or may not be an error indication.\n", numSocks, maxs); if (numSocks == 0) { dbgprintf("No TCP listen sockets could successfully be initialized\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_BIND); } finalize_it: if (sock != -1) { close(sock); } if (res != NULL) freeaddrinfo(res); if (iRet != RS_RET_OK) { if (pNewStrm != NULL) netstrm.Destruct(&pNewStrm); else if (pNewNsd != NULL) pNS->Drvr.Destruct(&pNewNsd); } RETiRet; } /* receive data from a tcp socket * The lenBuf parameter must contain the max buffer size on entry and contains * the number of octets read (or -1 in case of error) on exit. This function * never blocks, not even when called on a blocking socket. That is important * for client sockets, which are set to block during send, but should not * block when trying to read data. If *pLenBuf is -1, an error occurred and * oserr holds the exact error cause. * rgerhards, 2008-03-17 */ static rsRetVal Rcv(nsd_t *pNsd, uchar *pRcvBuf, ssize_t *pLenBuf, int *const oserr, unsigned *const nextIODirection) { char errStr[1024]; DEFiRet; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ptcp); assert(oserr != NULL); /* AIXPORT : MSG_DONTWAIT not supported */ #if defined(_AIX) #define MSG_DONTWAIT MSG_NONBLOCK #endif *pLenBuf = recv(pThis->sock, pRcvBuf, *pLenBuf, MSG_DONTWAIT); *oserr = errno; *nextIODirection = NSDSEL_RD; if (*pLenBuf == 0) { ABORT_FINALIZE(RS_RET_CLOSED); } else if (*pLenBuf < 0) { if (*oserr == EINTR || *oserr == EAGAIN) { ABORT_FINALIZE(RS_RET_RETRY); } else { rs_strerror_r(errno, errStr, sizeof(errStr)); dbgprintf("error during recv on NSD %p: %s\n", pNsd, errStr); ABORT_FINALIZE(RS_RET_RCV_ERR); } } finalize_it: RETiRet; } /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has * been written. * rgerhards, 2008-03-19 */ static rsRetVal Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; ssize_t written; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_ptcp); written = send(pThis->sock, pBuf, *pLenBuf, 0); if (written == -1) { switch (errno) { case EAGAIN: case EINTR: /* this is fine, just retry... */ written = 0; break; default: ABORT_FINALIZE(RS_RET_IO_ERROR); break; } } *pLenBuf = written; finalize_it: RETiRet; } /* Enable KEEPALIVE handling on the socket. * rgerhards, 2009-06-02 */ static rsRetVal EnableKeepAlive(nsd_t *pNsd) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; int ret; int optval; socklen_t optlen; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_ptcp); optval = 1; optlen = sizeof(optval); ret = setsockopt(pThis->sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen); if (ret < 0) { dbgprintf("EnableKeepAlive socket call returns error %d\n", ret); ABORT_FINALIZE(RS_RET_ERR); } #if defined(IPPROTO_TCP) && defined(TCP_KEEPCNT) if (pThis->iKeepAliveProbes > 0) { optval = pThis->iKeepAliveProbes; optlen = sizeof(optval); ret = setsockopt(pThis->sock, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen); } else { ret = 0; } #else ret = -1; #endif if (ret < 0) { LogError(ret, NO_ERRCODE, "nsd_ptcp cannot set keepalive probes - ignored"); } #if defined(IPPROTO_TCP) && defined(TCP_KEEPIDLE) if (pThis->iKeepAliveTime > 0) { optval = pThis->iKeepAliveTime; optlen = sizeof(optval); ret = setsockopt(pThis->sock, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen); } else { ret = 0; } #else ret = -1; #endif if (ret < 0) { LogError(ret, NO_ERRCODE, "nsd_ptcp cannot set keepalive time - ignored"); } #if defined(IPPROTO_TCP) && defined(TCP_KEEPCNT) if (pThis->iKeepAliveIntvl > 0) { optval = pThis->iKeepAliveIntvl; optlen = sizeof(optval); ret = setsockopt(pThis->sock, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen); } else { ret = 0; } #else ret = -1; #endif if (ret < 0) { LogError(errno, NO_ERRCODE, "nsd_ptcp cannot set keepalive intvl - ignored"); } dbgprintf("KEEPALIVE enabled for socket %d\n", pThis->sock); finalize_it: RETiRet; } /* open a connection to a remote host (server). * rgerhards, 2008-03-19 */ static rsRetVal Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) { nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; struct addrinfo *res = NULL; struct addrinfo hints; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_ptcp); assert(port != NULL); assert(host != NULL); assert(pThis->sock == -1); memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; if (getaddrinfo((char *)host, (char *)port, &hints, &res) != 0) { LogError(errno, RS_RET_IO_ERROR, "cannot resolve hostname '%s'", host); ABORT_FINALIZE(RS_RET_IO_ERROR); } /* We need to copy Remote Hostname here for error logging purposes */ if ((pThis->pRemHostName = malloc(strlen((char *)host) + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pRemHostName, host, strlen((char *)host) + 1); if ((pThis->sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { LogError(errno, RS_RET_IO_ERROR, "cannot bind socket for %s:%s", host, port); ABORT_FINALIZE(RS_RET_IO_ERROR); } if (device) { #if defined(SO_BINDTODEVICE) if (setsockopt(pThis->sock, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) < 0) #endif { dbgprintf("setsockopt(SO_BINDTODEVICE) failed\n"); ABORT_FINALIZE(RS_RET_IO_ERROR); } } struct timeval start, end; long seconds, useconds; gettimeofday(&start, NULL); if (connect(pThis->sock, res->ai_addr, res->ai_addrlen) != 0) { gettimeofday(&end, NULL); seconds = end.tv_sec - start.tv_sec; useconds = end.tv_usec - start.tv_usec; if (useconds < 0) { useconds += 1000000; seconds -= 1; } if (seconds < 0) { seconds = 0; useconds = 0; } LogError(errno, RS_RET_IO_ERROR, "cannot connect to %s:%s (took %ld.%02ld seconds)", host, port, seconds, useconds / 10000); ABORT_FINALIZE(RS_RET_IO_ERROR); } finalize_it: if (res != NULL) freeaddrinfo(res); if (iRet != RS_RET_OK) { sockClose(&pThis->sock); } RETiRet; } /* get the remote hostname. The returned hostname must be freed by the * caller. * rgerhards, 2008-04-24 */ static rsRetVal GetRemoteHName(nsd_t *pNsd, uchar **ppszHName) { DEFiRet; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ptcp); assert(ppszHName != NULL); // TODO: how can the RemHost be empty? CHKmalloc(*ppszHName = (uchar *)strdup(pThis->pRemHostName == NULL ? "" : (char *)pThis->pRemHostName)); finalize_it: RETiRet; } /** * getRemotePort - return peer TCP port number for improved diagnostics * @pThis: nsd_t object representing the network stream driver. * @port: Pointer to an integer where the port number will be stored. * It will be set to -1 on error or if no port information is available. * @return: standard rsRetVal error code */ static rsRetVal GetRemotePort(nsd_t *pNsd, int *port) { DEFiRet; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); assert(pThis != NULL); assert(port != NULL); *port = -1; /* Initialize port to -1, indicating no port found initially or on error */ memset(&addr, 0, sizeof(addr)); /* avoid potential garbage values */ if (getpeername(pThis->sock, (struct sockaddr *)&addr, &addrlen) == 0) { if (addr.ss_family == AF_INET6) { *port = ntohs(((struct sockaddr_in6 *)&addr)->sin6_port); } else if (addr.ss_family == AF_INET) { *port = ntohs(((struct sockaddr_in *)&addr)->sin_port); } else { /* Unsupported address family */ ABORT_FINALIZE(RS_RET_UNSUPP_SOCK_AF); } } else { /* getpeername failed */ ABORT_FINALIZE(RS_RET_IO_ERROR); } finalize_it: RETiRet; } static rsRetVal FmtRemotePortStr(const int port, uchar *const buf, const size_t len) { int r; if (len == 0) { return RS_RET_INVALID_PARAMS; /* can't do anything with zero-sized buffer */ } if (port == -1) { r = snprintf((char *)buf, len, "?"); } else { r = snprintf((char *)buf, len, "%d", port); } if (r < 0) { /* An encoding error occurred. */ return RS_RET_ERR; } else if ((size_t)r >= len) { /* The buffer was too small, truncation occurred. */ return RS_RET_PROVIDED_BUFFER_TOO_SMALL; } /* Ensure null termination, though snprintf usually does this unless truncated. */ buf[len - 1] = '\0'; return RS_RET_OK; } /* This function checks if the connection is still alive - well, kind of... It * is primarily being used for plain TCP syslog and it is quite a hack. However, * as it seems to work, it is worth supporting it. The bottom line is that it * should not be called by anything else but a plain tcp syslog sender. * In order for it to work, it must be called *immediately* *before* the send() * call. For details about what is done, see here: * http://blog.gerhards.net/2008/06/getting-bit-more-reliability-from-plain.html * rgerhards, 2008-06-09 */ static rsRetVal CheckConnection(nsd_t *pNsd) { DEFiRet; int rc; char msgbuf[1]; /* dummy */ nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ptcp); rc = recv(pThis->sock, msgbuf, 1, MSG_DONTWAIT | MSG_PEEK); if (rc == 0) { LogMsg(0, RS_RET_IO_ERROR, LOG_INFO, "ptcp network driver: CheckConnection detected that peer closed connection."); sockClose(&pThis->sock); ABORT_FINALIZE(RS_RET_PEER_CLOSED_CONN); } else if (rc < 0) { if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { LogMsg(errno, RS_RET_IO_ERROR, LOG_ERR, "ptcp network driver: CheckConnection detected broken connection"); sockClose(&pThis->sock); ABORT_FINALIZE(RS_RET_IO_ERROR); } } finalize_it: RETiRet; } /* get the remote host's IP address. Caller must Destruct the object. */ static rsRetVal GetRemoteIP(nsd_t *pNsd, prop_t **ip) { DEFiRet; nsd_ptcp_t *pThis = (nsd_ptcp_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_ptcp); prop.AddRef(pThis->remoteIP); *ip = pThis->remoteIP; RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(nsd_ptcp) CODESTARTobjQueryInterface(nsd_ptcp); if (pIf->ifVersion != nsdCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = (rsRetVal(*)(nsd_t **))nsd_ptcpConstruct; pIf->Destruct = (rsRetVal(*)(nsd_t **))nsd_ptcpDestruct; pIf->Abort = Abort; pIf->GetRemAddr = GetRemAddr; pIf->GetSock = GetSock; pIf->SetSock = SetSock; pIf->SetMode = SetMode; pIf->SetAuthMode = SetAuthMode; pIf->SetPermitExpiredCerts = SetPermitExpiredCerts; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetPermPeers = SetPermPeers; pIf->Rcv = Rcv; pIf->Send = Send; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->Connect = Connect; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->GetRemotePort = GetRemotePort; pIf->FmtRemotePortStr = FmtRemotePortStr; pIf->CheckConnection = CheckConnection; pIf->EnableKeepAlive = EnableKeepAlive; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; pIf->SetPrioritizeSAN = SetPrioritizeSAN; pIf->SetTlsVerifyDepth = SetTlsVerifyDepth; pIf->SetTlsCAFile = SetTlsCAFile; pIf->SetTlsCRLFile = SetTlsCRLFile; pIf->SetTlsKeyFile = SetTlsKeyFile; pIf->SetTlsCertFile = SetTlsCertFile; finalize_it: ENDobjQueryInterface(nsd_ptcp) /* exit our class */ BEGINObjClassExit(nsd_ptcp, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(nsd_ptcp); /* release objects we no longer need */ objRelease(net, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(netstrm, DONT_LOAD_LIB); objRelease(netstrms, LM_NETSTRMS_FILENAME); ENDObjClassExit(nsd_ptcp) /* Initialize the nsd_ptcp class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(nsd_ptcp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(net, CORE_COMPONENT)); CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME)); CHKiRet(objUse(netstrm, DONT_LOAD_LIB)); /* set our own handlers */ ENDObjClassInit(nsd_ptcp) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; nsd_ptcpClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(nsd_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/datetime.c0000644000000000000000000000013115055605325016161 xustar0030 mtime=1756826325.644800608 30 atime=1764930986.790791364 29 ctime=1764935923.18157655 rsyslog-8.2512.0/runtime/datetime.c0000664000175000017500000013443015055605325015633 0ustar00rgerrger/* The datetime object. It contains date and time related functions. * * Module begun 2008-03-05 by Rainer Gerhards, based on some code * from syslogd.c. The main intension was to move code out of syslogd.c * in a useful manner. It is still undecided if all functions will continue * to stay here or some will be moved into parser modules (once we have them). * * Copyright 2008-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include "rsyslog.h" #include "obj.h" #include "modules.h" #include "datetime.h" #include "srUtils.h" #include "stringbuf.h" #include "errmsg.h" #include "rsconf.h" #include "timezones.h" /* static data */ DEFobjStaticHelpers; /* the following table of ten powers saves us some computation */ static const int tenPowers[6] = {1, 10, 100, 1000, 10000, 100000}; /* the following table saves us from computing an additional date to get * the ordinal day of the year - at least from 1967-2099 * Note: non-2038+ compliant systems (Solaris) will generate compiler * warnings on the post 2038-rollover years. */ static const int yearInSec_startYear = 1967; /* for x in $(seq 1967 2099) ; do * printf %s', ' $(date --date="Dec 31 ${x} UTC 23:59:59" +%s) * done |fold -w 70 -s */ static const long long yearInSecs[] = { -63158401, -31536001, -1, 31535999, 63071999, 94694399, 126230399, 157766399, 189302399, 220924799, 252460799, 283996799, 315532799, 347155199, 378691199, 410227199, 441763199, 473385599, 504921599, 536457599, 567993599, 599615999, 631151999, 662687999, 694223999, 725846399, 757382399, 788918399, 820454399, 852076799, 883612799, 915148799, 946684799, 978307199, 1009843199, 1041379199, 1072915199, 1104537599, 1136073599, 1167609599, 1199145599, 1230767999, 1262303999, 1293839999, 1325375999, 1356998399, 1388534399, 1420070399, 1451606399, 1483228799, 1514764799, 1546300799, 1577836799, 1609459199, 1640995199, 1672531199, 1704067199, 1735689599, 1767225599, 1798761599, 1830297599, 1861919999, 1893455999, 1924991999, 1956527999, 1988150399, 2019686399, 2051222399, 2082758399, 2114380799, 2145916799, 2177452799, 2208988799, 2240611199, 2272147199, 2303683199, 2335219199, 2366841599, 2398377599, 2429913599, 2461449599, 2493071999, 2524607999, 2556143999, 2587679999, 2619302399, 2650838399, 2682374399, 2713910399, 2745532799, 2777068799, 2808604799, 2840140799, 2871763199, 2903299199, 2934835199, 2966371199, 2997993599, 3029529599, 3061065599, 3092601599, 3124223999, 3155759999, 3187295999, 3218831999, 3250454399, 3281990399, 3313526399, 3345062399, 3376684799, 3408220799, 3439756799, 3471292799, 3502915199, 3534451199, 3565987199, 3597523199, 3629145599, 3660681599, 3692217599, 3723753599, 3755375999, 3786911999, 3818447999, 3849983999, 3881606399, 3913142399, 3944678399, 3976214399, 4007836799, 4039372799, 4070908799, 4102444799}; /* note ramge is 1969 -> 2100 because it needs to access previous/next year */ /* for x in $(seq 1969 2100) ; do * printf %s', ' $(date --date="Dec 28 ${x} UTC 12:00:00" +%V) * done | fold -w 70 -s */ static const int weeksInYear[] = { 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 53, 52, }; static const char *monthNames[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; /* ------------------------------ methods ------------------------------ */ /** * Convert struct timeval to syslog_time */ static void timeval2syslogTime(struct timeval *tp, struct syslogTime *t, const int inUTC) { struct tm *tm; struct tm tmBuf; long lBias; time_t secs; #if defined(__hpux) struct timezone tz; #endif secs = tp->tv_sec; if (inUTC) tm = gmtime_r(&secs, &tmBuf); else tm = localtime_r(&secs, &tmBuf); t->year = tm->tm_year + 1900; t->month = tm->tm_mon + 1; t->day = tm->tm_mday; t->wday = tm->tm_wday; t->hour = tm->tm_hour; t->minute = tm->tm_min; t->second = tm->tm_sec; t->secfrac = tp->tv_usec; t->secfracPrecision = 6; if (inUTC) { t->OffsetMode = '+'; lBias = 0; } else { #if defined(__sun) /* Solaris uses a different method of exporting the time zone. * It is UTC - localtime, which is the opposite sign of mins east of GMT. */ lBias = -(tm->tm_isdst ? altzone : timezone); #elif defined(__hpux) lBias = tz.tz_dsttime ? -tz.tz_minuteswest : 0; #elif defined(_AIX) /* AIXPORT : IBM documentation notice that 'extern long timezone' * is setted after calling tzset. * Recent version of AIX, localtime_r call inside tzset. */ if (tm->tm_isdst) tzset(); lBias = -timezone; #else lBias = tm->tm_gmtoff; #endif if (lBias < 0) { t->OffsetMode = '-'; lBias *= -1; } else t->OffsetMode = '+'; } t->OffsetHour = lBias / 3600; t->OffsetMinute = (lBias % 3600) / 60; t->timeType = TIME_TYPE_RFC5424; /* we have a high precision timestamp */ t->inUTC = inUTC; } /** * Get the current date/time in the best resolution the operating * system has to offer (well, actually at most down to the milli- * second level. * * The date and time is returned in separate fields as this is * most portable and removes the need for additional structures * (but I have to admit it is somewhat "bulky";)). * * Obviously, *t must not be NULL... * * rgerhards, 2008-10-07: added ttSeconds to provide a way to * obtain the second-resolution UNIX timestamp. This is needed * in some situations to minimize time() calls (namely when doing * output processing). This can be left NULL if not needed. */ static void getCurrTime(struct syslogTime *t, time_t *ttSeconds, const int inUTC) { struct timeval tp; /* AIXPORT : fix build error : "tm_gmtoff" is not a member of "struct tm" * Choose the HPUX code path, only for this function. * This is achieved by adding a check to _AIX wherever _hpux is checked */ #if defined(__hpux) || defined(_AIX) struct timezone tz; #endif assert(t != NULL); #if defined(__hpux) || defined(_AIX) /* NOTE: under HP UX, the tz information might actually be * valid data. So we need to obtain and process it there. * As HP UX is not a supported platform, this is left to * explore by someone with interest in this platform. */ gettimeofday(&tp, &tz); #else gettimeofday(&tp, NULL); #endif if (ttSeconds != NULL) *ttSeconds = tp.tv_sec; timeval2syslogTime(&tp, t, inUTC); } /* A fast alternative to getCurrTime() and time() that only obtains * a timestamp like time() does. I was told that gettimeofday(), at * least under Linux, is much faster than time() and I could confirm * this testing. So I created that function as a replacement. * rgerhards, 2009-11-12 */ time_t getTime(time_t *ttSeconds) { struct timeval tp; if (gettimeofday(&tp, NULL) == -1) return -1; if (ttSeconds != NULL) *ttSeconds = tp.tv_sec; return tp.tv_sec; } dateTimeFormat_t getDateTimeFormatFromStr(const char *const __restrict__ s) { assert(s != NULL); if (strcmp(s, "date-rfc3164") == 0) return DATE_RFC3164; if (strcmp(s, "date-rfc3339") == 0) return DATE_RFC3339; if (strcmp(s, "date-unix") == 0) return DATE_UNIX; return DATE_INVALID; } /******************************************************************* * BEGIN CODE-LIBLOGGING * ******************************************************************* * Code in this section is borrowed from liblogging. This is an * interim solution. Once liblogging is fully integrated, this is * to be removed (see http://www.monitorware.com/liblogging for * more details. 2004-11-16 rgerhards * * Please note that the orginal liblogging code is modified so that * it fits into the context of the current version of syslogd.c. * * DO NOT PUT ANY OTHER CODE IN THIS BEGIN ... END BLOCK!!!! */ /** * Parse a 32 bit integer number from a string. We do not permit * integer overruns, this the guard against INT_MAX. * * \param ppsz Pointer to the Pointer to the string being parsed. It * must be positioned at the first digit. Will be updated * so that on return it points to the first character AFTER * the integer parsed. * \param pLenStr pointer to string length, decremented on exit by * characters processed * Note that if an empty string (len < 1) is passed in, * the method always returns zero. * \retval The number parsed. */ static int srSLMGParseInt32(uchar **ppsz, int *pLenStr) { register int i; i = 0; while (*pLenStr > 0 && **ppsz >= '0' && **ppsz <= '9' && i < INT_MAX / 10 - 1) { i = i * 10 + **ppsz - '0'; ++(*ppsz); --(*pLenStr); } return i; } /** * Parse a TIMESTAMP-3339. * updates the parse pointer position. The pTime parameter * is guranteed to be updated only if a new valid timestamp * could be obtained (restriction added 2008-09-16 by rgerhards). * This method now also checks the maximum string length it is passed. * If a *valid* timestamp is found, the string length is decremented * by the number of characters processed. If it is not a valid timestamp, * the length is kept unmodified. -- rgerhards, 2009-09-23 */ static rsRetVal ParseTIMESTAMP3339(struct syslogTime *pTime, uchar **ppszTS, int *pLenStr) { uchar *pszTS = *ppszTS; /* variables to temporarily hold time information while we parse */ int year; int month; int day; int hour; /* 24 hour clock */ int minute; int second; int secfrac; /* fractional seconds (must be 32 bit!) */ int secfracPrecision; char OffsetMode; /* UTC offset + or - */ int OffsetHour; /* UTC offset in hours */ int OffsetMinute; /* UTC offset in minutes */ int lenStr; /* end variables to temporarily hold time information while we parse */ DEFiRet; assert(pTime != NULL); assert(ppszTS != NULL); assert(pszTS != NULL); lenStr = *pLenStr; year = srSLMGParseInt32(&pszTS, &lenStr); /* We take the liberty to accept slightly malformed timestamps e.g. in * the format of 2003-9-1T1:0:0. This doesn't hurt on receiving. Of course, * with the current state of affairs, we would never run into this code * here because at postion 11, there is no "T" in such cases ;) */ if (lenStr == 0 || *pszTS++ != '-' || year < 0 || year >= 2100) { DBGPRINTF("ParseTIMESTAMP3339: invalid year: %d, pszTS: '%c'\n", year, *pszTS); ABORT_FINALIZE(RS_RET_INVLD_TIME); } --lenStr; month = srSLMGParseInt32(&pszTS, &lenStr); if (month < 1 || month > 12) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != '-') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; day = srSLMGParseInt32(&pszTS, &lenStr); if (day < 1 || day > 31) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != 'T') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; hour = srSLMGParseInt32(&pszTS, &lenStr); if (hour < 0 || hour > 23) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != ':') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; minute = srSLMGParseInt32(&pszTS, &lenStr); if (minute < 0 || minute > 59) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != ':') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; second = srSLMGParseInt32(&pszTS, &lenStr); if (second < 0 || second > 60) ABORT_FINALIZE(RS_RET_INVLD_TIME); /* Now let's see if we have secfrac */ if (lenStr > 0 && *pszTS == '.') { --lenStr; uchar *pszStart = ++pszTS; secfrac = srSLMGParseInt32(&pszTS, &lenStr); secfracPrecision = (int)(pszTS - pszStart); } else { secfracPrecision = 0; secfrac = 0; } /* check the timezone */ if (lenStr == 0) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (*pszTS == 'Z') { --lenStr; pszTS++; /* eat Z */ OffsetMode = 'Z'; OffsetHour = 0; OffsetMinute = 0; } else if ((*pszTS == '+') || (*pszTS == '-')) { OffsetMode = *pszTS; --lenStr; pszTS++; OffsetHour = srSLMGParseInt32(&pszTS, &lenStr); if (OffsetHour < 0 || OffsetHour > 23) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS != ':') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; pszTS++; OffsetMinute = srSLMGParseInt32(&pszTS, &lenStr); if (OffsetMinute < 0 || OffsetMinute > 59) ABORT_FINALIZE(RS_RET_INVLD_TIME); } else { /* there MUST be TZ information */ ABORT_FINALIZE(RS_RET_INVLD_TIME); } /* OK, we actually have a 3339 timestamp, so let's indicated this */ if (lenStr > 0) { if (*pszTS != ' ') /* if it is not a space, it can not be a "good" time - 2010-02-22 rgerhards */ ABORT_FINALIZE(RS_RET_INVLD_TIME); ++pszTS; /* just skip past it */ --lenStr; } /* we had success, so update parse pointer and caller-provided timestamp */ *ppszTS = pszTS; pTime->timeType = 2; pTime->year = year; pTime->month = month; pTime->day = day; pTime->hour = hour; pTime->minute = minute; pTime->second = second; pTime->secfrac = secfrac; pTime->secfracPrecision = secfracPrecision; pTime->OffsetMode = OffsetMode; pTime->OffsetHour = OffsetHour; pTime->OffsetMinute = OffsetMinute; *pLenStr = lenStr; finalize_it: RETiRet; } /** * Parse a TIMESTAMP-3164. The pTime parameter * is guranteed to be updated only if a new valid timestamp * could be obtained (restriction added 2008-09-16 by rgerhards). This * also means the caller *must* provide a valid (probably current) * timstamp in pTime when calling this function. a 3164 timestamp contains * only partial information and only that partial information is updated. * So the "output timestamp" is a valid timestamp only if the "input * timestamp" was valid, too. The is actually an optimization, as it * permits us to use a pre-acquired timestamp and thus avoids to do * a (costly) time() call. Thanks to David Lang for insisting on * time() call reduction ;). * This method now also checks the maximum string length it is passed. * If a *valid* timestamp is found, the string length is decremented * by the number of characters processed. If it is not a valid timestamp, * the length is kept unmodified. -- rgerhards, 2009-09-23 * * We support this format: * [yyyy] Mon mm [yyyy] hh:mm:ss[.subsec][ [yyyy ]/[TZSTRING:]] * Note that [yyyy] and [.subsec] are non-standard but frequently occur. * Also [yyyy] can only occur once -- if it occurs twice, we flag the * timestamp as invalid. if bParseTZ is true, we try to obtain a * TZSTRING. Note that in this case it MUST be terminated by a colon * (Cisco format). This option is a bit dangerous, as it could already * by the tag. So it MUST only be enabled in specialised parsers. * subsec, [yyyy] in front, TZSTRING was added in 2014-07-08 rgerhards * Similarly, we try to detect a year after the timestamp if * bDetectYearAfterTime is set. This is mutally exclusive with bParseTZ. * Note: bDetectYearAfterTime will misdetect hostnames in the range * 2000..2100 as years, so this option should explicitly be turned on * and is not meant for general consumption. */ static rsRetVal ParseTIMESTAMP3164( struct syslogTime *pTime, uchar **ppszTS, int *pLenStr, const int bParseTZ, const int bDetectYearAfterTime) { /* variables to temporarily hold time information while we parse */ int month; int day; int year = 0; /* 0 means no year provided */ int hour; /* 24 hour clock */ int minute; int second; int secfrac; /* fractional seconds (must be 32 bit!) */ int secfracPrecision; char tzstring[16]; char OffsetMode = '\0'; /* UTC offset: \0 -> indicate no update */ char OffsetHour = '\0'; /* UTC offset in hours */ int OffsetMinute = 0; /* UTC offset in minutes */ /* end variables to temporarily hold time information while we parse */ int lenStr; uchar *pszTS; DEFiRet; assert(ppszTS != NULL); pszTS = *ppszTS; assert(pszTS != NULL); assert(pTime != NULL); assert(pLenStr != NULL); lenStr = *pLenStr; if (lenStr < 3) ABORT_FINALIZE(RS_RET_INVLD_TIME); /* first check if we have a year in front of the timestamp. some devices (e.g. Brocade) * do this. As it is pretty straightforward to detect and chance of misinterpretation * is low, we try to parse it. */ if (*pszTS >= '0' && *pszTS <= '9') { /* OK, either we have a prepended year or an invalid format! */ year = srSLMGParseInt32(&pszTS, &lenStr); if (year < 1970 || year > 2100 || *pszTS != ' ') ABORT_FINALIZE(RS_RET_INVLD_TIME); ++pszTS; /* skip SP */ } /* If we look at the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec), * we may see the following character sequences occur: * * J(an/u(n/l)), Feb, Ma(r/y), A(pr/ug), Sep, Oct, Nov, Dec * * We will use this for parsing, as it probably is the * fastest way to parse it. * * 2009-08-17: we now do case-insensitive comparisons, as some devices obviously do not * obey to the RFC-specified case. As we need to guess in any case, we can ignore case * in the first place -- rgerhards * * 2005-07-18, well sometimes it pays to be a bit more verbose, even in C... * Fixed a bug that lead to invalid detection of the data. The issue was that * we had an if(++pszTS == 'x') inside of some of the consturcts below. However, * there were also some elseifs (doing the same ++), which than obviously did not * check the orginal character but the next one. Now removed the ++ and put it * into the statements below. Was a really nasty bug... I didn't detect it before * june, when it first manifested. This also lead to invalid parsing of the rest * of the message, as the time stamp was not detected to be correct. - rgerhards */ switch (*pszTS++) { case 'j': case 'J': if (*pszTS == 'a' || *pszTS == 'A') { ++pszTS; if (*pszTS == 'n' || *pszTS == 'N') { ++pszTS; month = 1; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else if (*pszTS == 'u' || *pszTS == 'U') { ++pszTS; if (*pszTS == 'n' || *pszTS == 'N') { ++pszTS; month = 6; } else if (*pszTS == 'l' || *pszTS == 'L') { ++pszTS; month = 7; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'f': case 'F': if (*pszTS == 'e' || *pszTS == 'E') { ++pszTS; if (*pszTS == 'b' || *pszTS == 'B') { ++pszTS; month = 2; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'm': case 'M': if (*pszTS == 'a' || *pszTS == 'A') { ++pszTS; if (*pszTS == 'r' || *pszTS == 'R') { ++pszTS; month = 3; } else if (*pszTS == 'y' || *pszTS == 'Y') { ++pszTS; month = 5; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'a': case 'A': if (*pszTS == 'p' || *pszTS == 'P') { ++pszTS; if (*pszTS == 'r' || *pszTS == 'R') { ++pszTS; month = 4; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else if (*pszTS == 'u' || *pszTS == 'U') { ++pszTS; if (*pszTS == 'g' || *pszTS == 'G') { ++pszTS; month = 8; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 's': case 'S': if (*pszTS == 'e' || *pszTS == 'E') { ++pszTS; if (*pszTS == 'p' || *pszTS == 'P') { ++pszTS; month = 9; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'o': case 'O': if (*pszTS == 'c' || *pszTS == 'C') { ++pszTS; if (*pszTS == 't' || *pszTS == 'T') { ++pszTS; month = 10; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'n': case 'N': if (*pszTS == 'o' || *pszTS == 'O') { ++pszTS; if (*pszTS == 'v' || *pszTS == 'V') { ++pszTS; month = 11; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; case 'd': case 'D': if (*pszTS == 'e' || *pszTS == 'E') { ++pszTS; if (*pszTS == 'c' || *pszTS == 'C') { ++pszTS; month = 12; } else ABORT_FINALIZE(RS_RET_INVLD_TIME); } else ABORT_FINALIZE(RS_RET_INVLD_TIME); break; default: ABORT_FINALIZE(RS_RET_INVLD_TIME); } lenStr -= 3; /* done month */ if (lenStr == 0 || *pszTS++ != ' ') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; /* we accept a slightly malformed timestamp when receiving. This is * we accept one-digit days */ if (*pszTS == ' ') { --lenStr; ++pszTS; } day = srSLMGParseInt32(&pszTS, &lenStr); if (day < 1 || day > 31) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != ' ') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; /* time part */ hour = srSLMGParseInt32(&pszTS, &lenStr); if (year == 0 && hour > 1970 && hour < 2100) { /* if so, we assume this actually is a year. This is a format found * e.g. in Cisco devices. * (if you read this 2100+ trying to fix a bug, congratulate me * to how long the code survived - me no longer ;)) -- rgerhards, 2008-11-18 */ year = hour; /* re-query the hour, this time it must be valid */ if (lenStr == 0 || *pszTS++ != ' ') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; hour = srSLMGParseInt32(&pszTS, &lenStr); } if (hour < 0 || hour > 23) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != ':') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; minute = srSLMGParseInt32(&pszTS, &lenStr); if (minute < 0 || minute > 59) ABORT_FINALIZE(RS_RET_INVLD_TIME); if (lenStr == 0 || *pszTS++ != ':') ABORT_FINALIZE(RS_RET_INVLD_TIME); --lenStr; second = srSLMGParseInt32(&pszTS, &lenStr); if (second < 0 || second > 60) ABORT_FINALIZE(RS_RET_INVLD_TIME); /* as an extension e.g. found in CISCO IOS, we support sub-second resultion. * It's presence is indicated by a dot immediately following the second. */ if (lenStr > 0 && *pszTS == '.') { --lenStr; uchar *pszStart = ++pszTS; secfrac = srSLMGParseInt32(&pszTS, &lenStr); secfracPrecision = (int)(pszTS - pszStart); } else { secfracPrecision = 0; secfrac = 0; } /* try to parse the TZSTRING if we are instructed to do so */ if (bParseTZ && lenStr > 2 && *pszTS == ' ') { int i; for (++pszTS, --lenStr, i = 0; lenStr > 0 && i < (int)sizeof(tzstring) - 1 && *pszTS != ':' && *pszTS != ' '; --lenStr) tzstring[i++] = *pszTS++; if (i > 0) { /* found TZ, apply it */ tzinfo_t *tzinfo; tzstring[i] = '\0'; if ((tzinfo = glblFindTimezone(runConf, (char *)tzstring)) == NULL) { DBGPRINTF("ParseTIMESTAMP3164: invalid TZ string '%s' -- ignored\n", tzstring); } else { OffsetMode = tzinfo->offsMode; OffsetHour = tzinfo->offsHour; OffsetMinute = tzinfo->offsMin; } } } if (bDetectYearAfterTime && year == 0 && lenStr > 5 && *pszTS == ' ') { int j; int y = 0; for (j = 1; j < 5; ++j) { if (pszTS[j] < '0' || pszTS[j] > '9') break; y = 10 * y + pszTS[j] - '0'; } if (lenStr > 6 && pszTS[5] != ' ') y = 0; /* no year! */ if (2000 <= y && y < 2100) { year = y; pszTS += 5; /* we need to preserve the SP, checked below */ lenStr -= 5; } } /* we provide support for an extra ":" after the date. While this is an * invalid format, it occurs frequently enough (e.g. with Cisco devices) * to permit it as a valid case. -- rgerhards, 2008-09-12 */ if (lenStr > 0 && *pszTS == ':') { ++pszTS; /* just skip past it */ --lenStr; } if (lenStr > 0) { if (*pszTS != ' ') /* if it is not a space, it can not be a "good" time - 2010-02-22 rgerhards */ ABORT_FINALIZE(RS_RET_INVLD_TIME); ++pszTS; /* just skip past it */ --lenStr; } /* we had success, so update parse pointer and caller-provided timestamp * fields we do not have are not updated in the caller's timestamp. This * is the reason why the caller must pass in a correct timestamp. */ *ppszTS = pszTS; /* provide updated parse position back to caller */ pTime->timeType = 1; pTime->month = month; if (year > 0) pTime->year = year; /* persist year if detected */ pTime->day = day; pTime->hour = hour; pTime->minute = minute; pTime->second = second; pTime->secfrac = secfrac; pTime->secfracPrecision = secfracPrecision; if (OffsetMode != '\0') { /* need to update TZ info? */ pTime->OffsetMode = OffsetMode; pTime->OffsetHour = OffsetHour; pTime->OffsetMinute = OffsetMinute; } *pLenStr = lenStr; finalize_it: RETiRet; } void applyDfltTZ(struct syslogTime *pTime, char *tz) { pTime->OffsetMode = tz[0]; pTime->OffsetHour = (tz[1] - '0') * 10 + (tz[2] - '0'); pTime->OffsetMinute = (tz[4] - '0') * 10 + (tz[5] - '0'); } /******************************************************************* * END CODE-LIBLOGGING * *******************************************************************/ /** * Format a syslogTimestamp into format required by MySQL. * We are using the 14 digits format. For example 20041111122600 * is interpreted as '2004-11-11 12:26:00'. * The caller must provide the timestamp as well as a character * buffer that will receive the resulting string. The function * returns the size of the timestamp written in bytes (without * the string terminator). If 0 is returend, an error occurred. */ static int formatTimestampToMySQL(struct syslogTime *ts, char *pBuf) { /* currently we do not consider localtime/utc. This may later be * added. If so, I recommend using a property replacer option * and/or a global configuration option. However, we should wait * on user requests for this feature before doing anything. * rgerhards, 2007-06-26 */ assert(ts != NULL); assert(pBuf != NULL); pBuf[0] = (ts->year / 1000) % 10 + '0'; pBuf[1] = (ts->year / 100) % 10 + '0'; pBuf[2] = (ts->year / 10) % 10 + '0'; pBuf[3] = ts->year % 10 + '0'; pBuf[4] = (ts->month / 10) % 10 + '0'; pBuf[5] = ts->month % 10 + '0'; pBuf[6] = (ts->day / 10) % 10 + '0'; pBuf[7] = ts->day % 10 + '0'; pBuf[8] = (ts->hour / 10) % 10 + '0'; pBuf[9] = ts->hour % 10 + '0'; pBuf[10] = (ts->minute / 10) % 10 + '0'; pBuf[11] = ts->minute % 10 + '0'; pBuf[12] = (ts->second / 10) % 10 + '0'; pBuf[13] = ts->second % 10 + '0'; pBuf[14] = '\0'; return 15; } static int formatTimestampToPgSQL(struct syslogTime *ts, char *pBuf) { /* see note in formatTimestampToMySQL, applies here as well */ assert(ts != NULL); assert(pBuf != NULL); pBuf[0] = (ts->year / 1000) % 10 + '0'; pBuf[1] = (ts->year / 100) % 10 + '0'; pBuf[2] = (ts->year / 10) % 10 + '0'; pBuf[3] = ts->year % 10 + '0'; pBuf[4] = '-'; pBuf[5] = (ts->month / 10) % 10 + '0'; pBuf[6] = ts->month % 10 + '0'; pBuf[7] = '-'; pBuf[8] = (ts->day / 10) % 10 + '0'; pBuf[9] = ts->day % 10 + '0'; pBuf[10] = ' '; pBuf[11] = (ts->hour / 10) % 10 + '0'; pBuf[12] = ts->hour % 10 + '0'; pBuf[13] = ':'; pBuf[14] = (ts->minute / 10) % 10 + '0'; pBuf[15] = ts->minute % 10 + '0'; pBuf[16] = ':'; pBuf[17] = (ts->second / 10) % 10 + '0'; pBuf[18] = ts->second % 10 + '0'; pBuf[19] = '\0'; return 19; } /** * Format a syslogTimestamp to just the fractional seconds. * The caller must provide the timestamp as well as a character * buffer that will receive the resulting string. The function * returns the size of the timestamp written in bytes (without * the string terminator). If 0 is returend, an error occurred. * The buffer must be at least 7 bytes large. * rgerhards, 2008-06-06 */ static int formatTimestampSecFrac(struct syslogTime *ts, char *pBuf) { int iBuf; int power; int secfrac; short digit; assert(ts != NULL); assert(pBuf != NULL); iBuf = 0; if (ts->secfracPrecision > 0) { power = tenPowers[(ts->secfracPrecision - 1) % 6]; secfrac = ts->secfrac; while (power > 0) { digit = secfrac / power; secfrac -= digit * power; power /= 10; pBuf[iBuf++] = digit + '0'; } } else { pBuf[iBuf++] = '0'; } pBuf[iBuf] = '\0'; return iBuf; } /** * Format a syslogTimestamp to a RFC3339 timestamp string (as * specified in syslog-protocol). * The caller must provide the timestamp as well as a character * buffer that will receive the resulting string. The function * returns the size of the timestamp written in bytes (without * the string terminator). If 0 is returend, an error occurred. */ static int formatTimestamp3339(struct syslogTime *ts, char *pBuf) { int iBuf; int power; int secfrac; short digit; assert(ts != NULL); assert(pBuf != NULL); /* start with fixed parts */ /* year yyyy */ pBuf[0] = (ts->year / 1000) % 10 + '0'; pBuf[1] = (ts->year / 100) % 10 + '0'; pBuf[2] = (ts->year / 10) % 10 + '0'; pBuf[3] = ts->year % 10 + '0'; pBuf[4] = '-'; /* month */ pBuf[5] = (ts->month / 10) % 10 + '0'; pBuf[6] = ts->month % 10 + '0'; pBuf[7] = '-'; /* day */ pBuf[8] = (ts->day / 10) % 10 + '0'; pBuf[9] = ts->day % 10 + '0'; pBuf[10] = 'T'; /* hour */ pBuf[11] = (ts->hour / 10) % 10 + '0'; pBuf[12] = ts->hour % 10 + '0'; pBuf[13] = ':'; /* minute */ pBuf[14] = (ts->minute / 10) % 10 + '0'; pBuf[15] = ts->minute % 10 + '0'; pBuf[16] = ':'; /* second */ pBuf[17] = (ts->second / 10) % 10 + '0'; pBuf[18] = ts->second % 10 + '0'; iBuf = 19; /* points to next free entry, now it becomes dynamic! */ if (ts->secfracPrecision > 0) { pBuf[iBuf++] = '.'; power = tenPowers[(ts->secfracPrecision - 1) % 6]; secfrac = ts->secfrac; while (power > 0) { digit = secfrac / power; secfrac -= digit * power; power /= 10; pBuf[iBuf++] = digit + '0'; } } if (ts->OffsetMode == 'Z') { pBuf[iBuf++] = 'Z'; } else { pBuf[iBuf++] = ts->OffsetMode; pBuf[iBuf++] = (ts->OffsetHour / 10) % 10 + '0'; pBuf[iBuf++] = ts->OffsetHour % 10 + '0'; pBuf[iBuf++] = ':'; pBuf[iBuf++] = (ts->OffsetMinute / 10) % 10 + '0'; pBuf[iBuf++] = ts->OffsetMinute % 10 + '0'; } pBuf[iBuf] = '\0'; return iBuf; } /** * Format a syslogTimestamp to a RFC3164 timestamp sring. * The caller must provide the timestamp as well as a character * buffer that will receive the resulting string. The function * returns the size of the timestamp written in bytes (without * the string termnator). If 0 is returend, an error occurred. * rgerhards, 2010-03-05: Added support to for buggy 3164 dates, * where a zero-digit is written instead of a space for the first * day character if day < 10. syslog-ng seems to do that, and some * parsing scripts (in migration cases) rely on that. */ static int formatTimestamp3164(struct syslogTime *ts, char *pBuf, int bBuggyDay) { int iDay; assert(ts != NULL); assert(pBuf != NULL); pBuf[0] = monthNames[(ts->month - 1) % 12][0]; pBuf[1] = monthNames[(ts->month - 1) % 12][1]; pBuf[2] = monthNames[(ts->month - 1) % 12][2]; pBuf[3] = ' '; iDay = (ts->day / 10) % 10; /* we need to write a space if the first digit is 0 */ pBuf[4] = (bBuggyDay || iDay > 0) ? iDay + '0' : ' '; pBuf[5] = ts->day % 10 + '0'; pBuf[6] = ' '; pBuf[7] = (ts->hour / 10) % 10 + '0'; pBuf[8] = ts->hour % 10 + '0'; pBuf[9] = ':'; pBuf[10] = (ts->minute / 10) % 10 + '0'; pBuf[11] = ts->minute % 10 + '0'; pBuf[12] = ':'; pBuf[13] = (ts->second / 10) % 10 + '0'; pBuf[14] = ts->second % 10 + '0'; pBuf[15] = '\0'; return 16; /* traditional: number of bytes written */ } /** * convert syslog timestamp to time_t * Note: it would be better to use something similar to mktime() here. * Unfortunately, mktime() semantics are problematic: first of all, it * works on local time, on the machine's time zone. In syslog, we have * to deal with multiple time zones at once, so we cannot plainly rely * on the local zone, and so we cannot rely on mktime(). One solution would * be to refactor all time-related functions so that they are all guarded * by a mutex to ensure TZ consistency (which would also enable us to * change the TZ at will for specific function calls). But that would * potentially mean a lot of overhead. * Also, mktime() has some side effects, at least setting of tzname. With * a refactoring as described above that should probably not be a problem, * but would also need more work. For some more thoughts on this topic, * have a look here: * http://stackoverflow.com/questions/18355101/is-standard-c-mktime-thread-safe-on-linux * In conclusion, we keep our own code for generating the unix timestamp. * rgerhards, 2016-03-02 */ static time_t syslogTime2time_t(const struct syslogTime *ts) { long MonthInDays, NumberOfYears, NumberOfDays; int utcOffset; time_t TimeInUnixFormat; if (ts->year < 1970 || ts->year > 2100) { TimeInUnixFormat = 0; LogError(0, RS_RET_ERR, "syslogTime2time_t: invalid year %d " "in timestamp - returning 1970-01-01 instead", ts->year); goto done; } /* Counting how many Days have passed since the 01.01 of the * selected Year (Month level), according to the selected Month*/ switch (ts->month) { case 1: MonthInDays = 0; // until 01 of January break; case 2: MonthInDays = 31; // until 01 of February - leap year handling down below! break; case 3: MonthInDays = 59; // until 01 of March break; case 4: MonthInDays = 90; // until 01 of April break; case 5: MonthInDays = 120; // until 01 of Mai break; case 6: MonthInDays = 151; // until 01 of June break; case 7: MonthInDays = 181; // until 01 of July break; case 8: MonthInDays = 212; // until 01 of August break; case 9: MonthInDays = 243; // until 01 of September break; case 10: MonthInDays = 273; // until 01 of Oktober break; case 11: MonthInDays = 304; // until 01 of November break; case 12: MonthInDays = 334; // until 01 of December break; default: /* this cannot happen (and would be a program error) * but we need the code to keep the compiler silent. */ MonthInDays = 0; /* any value fits ;) */ break; } /* adjust for leap years */ if ((ts->year % 100 != 0 && ts->year % 4 == 0) || (ts->year == 2000)) { if (ts->month > 2) MonthInDays++; } /* 1) Counting how many Years have passed since 1970 2) Counting how many Days have passed since the 01.01 of the selected Year (Day level) according to the Selected Month and Day. Last day doesn't count, it should be until last day 3) Calculating this period (NumberOfDays) in seconds*/ NumberOfYears = ts->year - yearInSec_startYear - 1; NumberOfDays = MonthInDays + ts->day - 1; TimeInUnixFormat = (time_t)(yearInSecs[NumberOfYears] + 1) + NumberOfDays * 86400; /*Add Hours, minutes and seconds */ TimeInUnixFormat += ts->hour * 60 * 60; TimeInUnixFormat += ts->minute * 60; TimeInUnixFormat += ts->second; /* do UTC offset */ utcOffset = ts->OffsetHour * 3600 + ts->OffsetMinute * 60; if (ts->OffsetMode == '+') utcOffset *= -1; /* if timestamp is ahead, we need to "go back" to UTC */ TimeInUnixFormat += utcOffset; done: return TimeInUnixFormat; } /** * format a timestamp as a UNIX timestamp; subsecond resolution is * discarded. * Note that this code can use some refactoring. I decided to use it * because mktime() requires an upfront TZ update as it works on local * time. In any case, it is worth reconsidering to move to mktime() or * some other method. * Important: pBuf must point to a buffer of at least 11 bytes. * rgerhards, 2012-03-29 */ static int formatTimestampUnix(struct syslogTime *ts, char *pBuf) { snprintf(pBuf, 11, "%u", (unsigned)syslogTime2time_t(ts)); return 11; } /* 0 - Sunday, 1, Monday, ... * Note that we cannot use strftime() and helpers as they rely on the TZ * variable (again, arghhhh). So we need to do it ourselves... * Note: in the year 2100, this algorithm does not work correctly (due to * leap time rules. To fix it then (*IF* this code really still exists then), * just use 2100 as new anchor year and adapt the initial day number. */ int getWeekdayNbr(struct syslogTime *ts) { int wday; int g, f; g = ts->year; if (ts->month < 3) { g--; f = ts->month + 13; } else { f = ts->month + 1; } wday = ((36525 * g) / 100) + ((306 * f) / 10) + ts->day - 621049; wday %= 7; return wday; } /* getOrdinal - 1-366 day of the year * I've given little thought to leap seconds here. */ int getOrdinal(struct syslogTime *ts) { int yday; time_t thistime; time_t previousyears; int utcOffset; time_t seconds_into_year; if (ts->year < 1970 || ts->year > 2100) { yday = 0; LogError(0, RS_RET_ERR, "getOrdinal: invalid year %d " "in timestamp - returning 1970-01-01 instead", ts->year); goto done; } thistime = syslogTime2time_t(ts); previousyears = (time_t)yearInSecs[ts->year - yearInSec_startYear - 1]; /* adjust previous years to match UTC offset */ utcOffset = ts->OffsetHour * 3600 + ts->OffsetMinute * 60; if (ts->OffsetMode == '+') utcOffset += -1; /* if timestamp is ahead, we need to "go back" to UTC */ previousyears += utcOffset; /* subtract seconds from previous years */ seconds_into_year = thistime - previousyears; /* divide by seconds in a day and truncate to int */ yday = seconds_into_year / 86400; done: return yday; } /* getWeek - 1-52 week of the year */ int getWeek(struct syslogTime *ts) { int weekNum; struct syslogTime yt; int curDow; int jan1Dow; int curYearDay; /* initialize a timestamp for january 1st of the current year */ yt.year = ts->year; yt.month = 1; yt.day = 1; yt.hour = 0; yt.minute = 0; yt.second = 0; yt.secfracPrecision = 0; yt.secfrac = 0; yt.OffsetMinute = ts->OffsetMinute; yt.OffsetHour = ts->OffsetHour; yt.OffsetMode = ts->OffsetMode; yt.timeType = TIME_TYPE_RFC3164; /* low-res time */ /* get current day in year, current day of week * and the day of week of 1/1 */ curYearDay = getOrdinal(ts); curDow = getWeekdayNbr(ts); jan1Dow = getWeekdayNbr(&yt); /* calculate week of year for given date by pinning 1/1 as start * of year, then going back and adjusting for the actual week day. */ weekNum = ((curYearDay + 6) / 7); if (curDow < jan1Dow) { ++weekNum; } return weekNum; } /* getISOWeek - 1-53 week of the year */ int getISOWeek(struct syslogTime *ts, int *year) { int weekNum; int curDow; int curYearDay; /* get current day in year, current day of week * and the day of week of 1/1 */ curYearDay = getOrdinal(ts); curDow = getWeekdayNbr(ts); /* map from 0 - Sunday, 1, Monday to 1, Monday, 7 - Sunday */ if (curDow == 0) { curDow = 7; } /* make ordinal in range 1-366 */ curYearDay++; weekNum = (10 + curYearDay - curDow) / 7; *year = ts->year; if (weekNum == 0) { /* this is actually W52 or W53 of previous year */ weekNum = weeksInYear[ts->year - 1 - 1969]; *year = ts->year - 1; } else if (weekNum > weeksInYear[ts->year - 1969]) { /* this is actually W01 of next year */ weekNum = 1; *year = ts->year + 1; } return weekNum; } void timeConvertToUTC(const struct syslogTime *const __restrict__ local, struct syslogTime *const __restrict__ utc) { struct timeval tp; tp.tv_sec = syslogTime2time_t(local); tp.tv_usec = local->secfrac; timeval2syslogTime(&tp, utc, 1); } /** * Format a UNIX timestamp. */ static int formatUnixTimeFromTime_t(time_t unixtime, const char *format, char *pBuf, __attribute__((unused)) uint pBufMax) { struct tm lt; assert(format != NULL); assert(pBuf != NULL); // Convert to struct tm if (gmtime_r(&unixtime, <) == NULL) { DBGPRINTF("Unexpected error calling gmtime_r().\n"); return -1; } // Do our conversions if (strcmp(format, "date-rfc3164") == 0) { assert(pBufMax >= 16); // Unlikely to run into this situation, but you never know... if (lt.tm_mon < 0 || lt.tm_mon > 11) { DBGPRINTF("lt.tm_mon is out of range. Value: %d\n", lt.tm_mon); return -1; } // MMM dd HH:mm:ss sprintf(pBuf, "%s %2d %.2d:%.2d:%.2d", monthNames[lt.tm_mon], lt.tm_mday, lt.tm_hour, lt.tm_min, lt.tm_sec); } else if (strcmp(format, "date-rfc3339") == 0) { assert(pBufMax >= 26); // YYYY-MM-DDTHH:mm:ss+00:00 sprintf(pBuf, "%d-%.2d-%.2dT%.2d:%.2d:%.2dZ", lt.tm_year + 1900, lt.tm_mon + 1, lt.tm_mday, lt.tm_hour, lt.tm_min, lt.tm_sec); } return strlen(pBuf); } /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(datetime) CODESTARTobjQueryInterface(datetime); if (pIf->ifVersion != datetimeCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->getCurrTime = getCurrTime; pIf->GetTime = getTime; pIf->timeval2syslogTime = timeval2syslogTime; pIf->ParseTIMESTAMP3339 = ParseTIMESTAMP3339; pIf->ParseTIMESTAMP3164 = ParseTIMESTAMP3164; pIf->formatTimestampToMySQL = formatTimestampToMySQL; pIf->formatTimestampToPgSQL = formatTimestampToPgSQL; pIf->formatTimestampSecFrac = formatTimestampSecFrac; pIf->formatTimestamp3339 = formatTimestamp3339; pIf->formatTimestamp3164 = formatTimestamp3164; pIf->formatTimestampUnix = formatTimestampUnix; pIf->syslogTime2time_t = syslogTime2time_t; pIf->formatUnixTimeFromTime_t = formatUnixTimeFromTime_t; finalize_it: ENDobjQueryInterface(datetime) /* Initialize the datetime class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(datetime, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ ENDObjClassInit(datetime) /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/queue.h0000644000000000000000000000013115062756615015525 xustar0030 mtime=1758190989.229641517 29 atime=1764930980.03367844 30 ctime=1764935923.256577698 rsyslog-8.2512.0/runtime/queue.h0000664000175000017500000003322315062756615015175 0ustar00rgerrger/* Definition of the queue support module. * * Copyright 2008-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ /** * @file queue.h * @brief Public interface and data structures for the rsyslog queue subsystem. * * This header defines the primary functions and data structures needed to * interact with rsyslog queues (in-memory, disk, and disk-assisted). It serves * as the main entry point for developers looking to understand how to use and * interact with the queueing mechanism. * * For a detailed discussion of the architectural principles, especially * concerning disk queues, their "Limited Duplication" guarantee, and a * comparison to Write-Ahead Logs (WALs), please see the extensive header * comment in queue.c. * * @see queue.c */ #ifndef QUEUE_H_INCLUDED #define QUEUE_H_INCLUDED #include #include "obj.h" #include "wtp.h" #include "batch.h" #include "stream.h" #include "statsobj.h" #include "cryprov.h" /* support for the toDelete list */ typedef struct toDeleteLst_s toDeleteLst_t; struct toDeleteLst_s { qDeqID deqID; int nElemDeq; /* numbe of elements that were dequeued and as such must now be discarded */ struct toDeleteLst_s *pNext; }; /* queue types */ typedef enum { QUEUETYPE_FIXED_ARRAY = 0, /* a simple queue made out of a fixed (initially malloced) array fast but memoryhog */ QUEUETYPE_LINKEDLIST = 1, /* linked list used as buffer, lower fixed memory overhead but slower */ QUEUETYPE_DISK = 2, /* disk files used as buffer */ QUEUETYPE_DIRECT = 3 /* no queuing happens, consumer is directly called */ } queueType_t; /* list member definition for linked list types of queues: */ typedef struct qLinkedList_S { struct qLinkedList_S *pNext; smsg_t *pMsg; } qLinkedList_t; /** * @brief The "queue object for the queueing subsystem". * * This structure holds the runtime state for a queue instance, especially a * disk-based one. It contains the core pointers that define the Bounded Queue. * * Note on naming: This is named `qqueue` due to historical symbol clashes with * system libraries on some platforms (e.g., AIX). See queue.c for details. */ struct queue_s { BEGINobjInstance ; queueType_t qType; int nLogDeq; /* number of elements currently logically dequeued */ int bShutdownImmediate; /* should all workers cease processing messages? */ sbool bEnqOnly; /* does queue run in enqueue-only mode (1) or not (0)? */ sbool bSaveOnShutdown; /* persists everthing on shutdown (if DA!)? 1-yes, 0-no */ sbool bQueueStarted; /* has queueStart() been called on this queue? 1-yes, 0-no */ sbool takeFlowCtlFromMsg; /* override enq flow ctl by message property? */ int iQueueSize; /* Current number of elements in the queue */ int iMaxQueueSize; /* how large can the queue grow? */ int iNumWorkerThreads; /* number of worker threads to use */ int iCurNumWrkThrd; /* current number of active worker threads */ int iMinMsgsPerWrkr; /* minimum nbr of msgs per worker thread, if more, a new worker is started until max wrkrs */ wtp_t *pWtpDA; wtp_t *pWtpReg; action_t *pAction; /* for action queues, ptr to action object; for main queues unused */ int iUpdsSincePersist; /* nbr of queue updates since the last persist call */ int iPersistUpdCnt; /* persits queue info after this nbr of updates - 0 -> persist only on shutdown */ sbool bSyncQueueFiles; /* if working with files, sync them after each write? */ int iHighWtrMrk; /* high water mark for disk-assisted memory queues */ int iLowWtrMrk; /* low water mark for disk-assisted memory queues */ int iDiscardMrk; /* if the queue is above this mark, low-severity messages are discarded */ int iFullDlyMrk; /* if the queue is above this mark, FULL_DELAYable message are put on hold */ int iLightDlyMrk; /* if the queue is above this mark, LIGHT_DELAYable message are put on hold */ int iDiscardSeverity; /* messages of this severity above are discarded on too-full queue */ sbool bNeedDelQIF; /* does the QIF file need to be deleted when queue becomes empty? */ int toQShutdown; /* timeout for regular queue shutdown in ms */ int toActShutdown; /* timeout for long-running action shutdown in ms */ int toWrkShutdown; /* timeout for idle workers in ms, -1 means indefinite (0 is immediate) */ toDeleteLst_t *toDeleteLst; /* this queue's to-delete list */ int toEnq; /* enqueue timeout */ int iDeqBatchSize; /* max number of elements that shall be dequeued at once */ int iMinDeqBatchSize; /* min number of elements that shall be dequeued at once */ int toMinDeqBatchSize; /* timeout for MinDeqBatchSize, in ms */ /* rate limiting settings (will be expanded) */ int iDeqSlowdown; /* slow down dequeue by specified nbr of microseconds */ /* end rate limiting */ /* dequeue time window settings (may also be expanded) */ int iDeqtWinFromHr; /* begin of dequeue time window (hour only) */ int iDeqtWinToHr; /* end of dequeue time window (hour only), set to 25 to disable deq window! */ /* note that begin and end have specific semantics. It is a big difference if we have * begin 4, end 22 or begin 22, end 4. In the later case, dequeuing will run from 10p, * throughout the night and stop at 4 in the morning. In the first case, it will start * at 4am, run throughout the day, and stop at 10 in the evening! So far, not logic is * applied to detect user configuration errors (and tell me how should we detect what * the user really wanted...). -- rgerhards, 2008-04-02 */ /* end dequeue time window */ rsRetVal (*pConsumer)(void *, batch_t *, wti_t *); /* user-supplied consumer function for dequeued messages */ /* calling interface for pConsumer: arg1 is the global user pointer from this structure, arg2 is the * user pointer array that was dequeued (actual sample: for actions, arg1 is the pAction and arg2 * is pointer to an array of message message pointers) */ /* type-specific handlers (set during construction) */ rsRetVal (*qConstruct)(struct queue_s *pThis); rsRetVal (*qDestruct)(struct queue_s *pThis); rsRetVal (*qAdd)(struct queue_s *pThis, smsg_t *pMsg); rsRetVal (*qDeq)(struct queue_s *pThis, smsg_t **ppMsg); rsRetVal (*qDel)(struct queue_s *pThis); /* end type-specific handler */ /* public entry points (set during construction, permit to set best algorithm for params selected) */ rsRetVal (*MultiEnq)(qqueue_t *pThis, multi_submit_t *pMultiSub); /* end public entry points */ /* synchronization variables */ pthread_mutex_t mutThrdMgmt; /* mutex for the queue's thread management */ pthread_mutex_t *mut; /* mutex for enqueing and dequeueing messages */ pthread_cond_t notFull; pthread_cond_t belowFullDlyWtrMrk; /* below eFLOWCTL_FULL_DELAY watermark */ pthread_cond_t belowLightDlyWtrMrk; /* below eFLOWCTL_FULL_DELAY watermark */ int bThrdStateChanged; /* at least one thread state has changed if 1 */ /* end sync variables */ /* the following variables are always present, because they * are not only used for the "disk" queueing mode but also for * any other queueing mode if it is set to "disk assisted". * rgerhards, 2008-01-09 */ uchar *pszSpoolDir; size_t lenSpoolDir; uchar *pszFilePrefix; size_t lenFilePrefix; uchar *pszQIFNam; /* full .qi file name, based on parts above */ size_t lenQIFNam; int iNumberFiles; /* how many files make up the queue? */ int64 iMaxFileSize; /* max size for a single queue file */ int64 sizeOnDiskMax; /* maximum size on disk allowed */ qDeqID deqIDAdd; /* next dequeue ID to use during add to queue store */ qDeqID deqIDDel; /* queue store delete position */ int bIsDA; /* is this queue disk assisted? */ struct queue_s *pqDA; /* queue for disk-assisted modes */ struct queue_s *pqParent; /* pointer to the parent (if this is a child queue) */ int bDAEnqOnly; /* EnqOnly setting for DA queue */ /* now follow queueing mode specific data elements */ // union { /* different data elements based on queue type (qType) */ struct { /* different data elements based on queue type (qType) */ struct { long deqhead, head, tail; void **pBuf; /* the queued user data structure */ } farray; struct { qLinkedList_t *pDeqRoot; qLinkedList_t *pDelRoot; qLinkedList_t *pLast; } linklist; struct { int64 sizeOnDisk; /* current amount of disk space used */ int64 deqOffs; /* offset after dequeue batch - used for file deleter */ int deqFileNumIn; /* same for the circular file numbers, mainly for */ int deqFileNumOut; /* deleting finished files */ strm_t *pWrite; /* current file to be written */ strm_t *pReadDeq; /* current file for dequeueing */ strm_t *pReadDel; /* current file for deleting */ int nForcePersist; /* force persist of .qi file the next "n" times */ } disk; } tVars; sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ uchar *cryprovName; /* crypto provider to use */ cryprov_if_t cryprov; /* ptr to crypto provider interface */ void *cryprovData; /* opaque data ptr for provider use */ uchar *cryprovNameFull; /* full internal crypto provider name */ DEF_ATOMIC_HELPER_MUT(mutQueueSize); DEF_ATOMIC_HELPER_MUT(mutLogDeq); /* for statistics subsystem */ statsobj_t *statsobj; STATSCOUNTER_DEF(ctrEnqueued, mutCtrEnqueued) STATSCOUNTER_DEF(ctrFull, mutCtrFull) STATSCOUNTER_DEF(ctrFDscrd, mutCtrFDscrd) STATSCOUNTER_DEF(ctrNFDscrd, mutCtrNFDscrd) int ctrMaxqsize; /* NOT guarded by a mutex */ int iSmpInterval; /* line interval of sampling logs */ int isRunning; }; /* the define below is an "eternal" timeout for the timeout settings which require a value. * It is one day, which is not really eternal, but comes close to it if we think about * rsyslog (e.g.: do you want to wait on shutdown for more than a day? ;)) * rgerhards, 2008-01-17 */ #define QUEUE_TIMEOUT_ETERNAL 24 * 60 * 60 * 1000 /* prototypes */ rsRetVal qqueueDestruct(qqueue_t **ppThis); rsRetVal qqueueEnqMsg(qqueue_t *pThis, flowControl_t flwCtlType, smsg_t *pMsg); rsRetVal qqueueStart(rsconf_t *cnf, qqueue_t *pThis); rsRetVal qqueueSetMaxFileSize(qqueue_t *pThis, size_t iMaxFileSize); rsRetVal qqueueSetFilePrefix(qqueue_t *pThis, uchar *pszPrefix, size_t iLenPrefix); rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThreads, int iMaxQueueSize, rsRetVal (*pConsumer)(void *, batch_t *, wti_t *)); int queueCnfParamsSet(struct nvlst *lst); rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst); void qqueueSetDefaultsRulesetQueue(qqueue_t *pThis); void qqueueSetDefaultsActionQueue(qqueue_t *pThis); void qqueueDbgPrint(qqueue_t *pThis); rsRetVal qqueueShutdownWorkers(qqueue_t *pThis); void qqueueDoneLoadCnf(void); int queuesEqual(qqueue_t *pOld, qqueue_t *pNew); void qqueueCorrectParams(qqueue_t *pThis); PROTOTYPEObjClassInit(qqueue); PROTOTYPEpropSetMeth(qqueue, iPersistUpdCnt, int); PROTOTYPEpropSetMeth(qqueue, bSyncQueueFiles, int); PROTOTYPEpropSetMeth(qqueue, iDeqtWinFromHr, int); PROTOTYPEpropSetMeth(qqueue, iDeqtWinToHr, int); PROTOTYPEpropSetMeth(qqueue, toQShutdown, long); PROTOTYPEpropSetMeth(qqueue, toActShutdown, long); PROTOTYPEpropSetMeth(qqueue, toWrkShutdown, long); PROTOTYPEpropSetMeth(qqueue, toEnq, long); PROTOTYPEpropSetMeth(qqueue, iLightDlyMrk, int); PROTOTYPEpropSetMeth(qqueue, iHighWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iLowWtrMrk, int); PROTOTYPEpropSetMeth(qqueue, iDiscardMrk, int); PROTOTYPEpropSetMeth(qqueue, iDiscardSeverity, int); PROTOTYPEpropSetMeth(qqueue, iMinMsgsPerWrkr, int); PROTOTYPEpropSetMeth(qqueue, iNumWorkerThreads, int); PROTOTYPEpropSetMeth(qqueue, bSaveOnShutdown, int); PROTOTYPEpropSetMeth(qqueue, pAction, action_t *); PROTOTYPEpropSetMeth(qqueue, iDeqSlowdown, int); PROTOTYPEpropSetMeth(qqueue, sizeOnDiskMax, int64); PROTOTYPEpropSetMeth(qqueue, iDeqBatchSize, int); #define qqueueGetID(pThis) ((unsigned long)pThis) #ifdef ENABLE_IMDIAG extern unsigned int iOverallQueueSize; #endif #endif /* #ifndef QUEUE_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/janitor.c0000644000000000000000000000013115055605325016033 xustar0030 mtime=1756826325.645800623 29 atime=1764930982.11771329 30 ctime=1764935923.141575938 rsyslog-8.2512.0/runtime/janitor.c0000664000175000017500000000574315055605325015511 0ustar00rgerrger/* janitor.c - rsyslog's janitor * * The rsyslog janitor can be used to periodically clean out * resources. It was initially developed to close files that * were not written to for some time (omfile plugin), but has * a generic interface that can be used for all similar tasks. * * Module begun 2014-05-15 by Rainer Gerhards * * Copyright (C) 2014-2015 by Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include "rsyslog.h" #include "janitor.h" static struct janitorEtry *janitorRoot = NULL; static pthread_mutex_t janitorMut = PTHREAD_MUTEX_INITIALIZER; rsRetVal janitorAddEtry(void (*cb)(void *), const char *id, void *pUsr) { struct janitorEtry *etry = NULL; DEFiRet; CHKmalloc(etry = malloc(sizeof(struct janitorEtry))); CHKmalloc(etry->id = strdup(id)); etry->pUsr = pUsr; etry->cb = cb; etry->next = janitorRoot; pthread_mutex_lock(&janitorMut); janitorRoot = etry; pthread_mutex_unlock(&janitorMut); DBGPRINTF("janitor: entry %p, id '%s' added\n", etry, id); finalize_it: if (iRet != RS_RET_OK && etry != NULL) free(etry); RETiRet; } rsRetVal janitorDelEtry(const char *__restrict__ const id) { struct janitorEtry *curr, *prev = NULL; DEFiRet; pthread_mutex_lock(&janitorMut); for (curr = janitorRoot; curr != NULL; curr = curr->next) { if (!strcmp(curr->id, id)) { if (prev == NULL) { janitorRoot = curr->next; } else { prev->next = curr->next; } free(curr->id); free(curr); DBGPRINTF("janitor: deleted entry '%s'\n", id); ABORT_FINALIZE(RS_RET_OK); } prev = curr; } DBGPRINTF("janitor: to be deleted entry '%s' not found\n", id); iRet = RS_RET_NOT_FOUND; finalize_it: pthread_mutex_unlock(&janitorMut); RETiRet; } /* run the janitor; all entries are processed */ void janitorRun(void) { struct janitorEtry *curr; dbgprintf("janitorRun() called\n"); pthread_mutex_lock(&janitorMut); for (curr = janitorRoot; curr != NULL; curr = curr->next) { DBGPRINTF("janitor: processing entry %p, id '%s'\n", curr, curr->id); curr->cb(curr->pUsr); } pthread_mutex_unlock(&janitorMut); } rsyslog-8.2512.0/runtime/PaxHeaders/datetime.h0000644000000000000000000000013015055605325016165 xustar0030 mtime=1756826325.644800608 29 atime=1764930980.03667849 29 ctime=1764935923.18357658 rsyslog-8.2512.0/runtime/datetime.h0000664000175000017500000000773715055605325015651 0ustar00rgerrger/* The datetime object. Contains time-related functions. * * Copyright 2008-2015 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_DATETIME_H #define INCLUDED_DATETIME_H /* TODO: define error codes */ #define NO_ERRCODE -1 /* the datetime object */ typedef struct datetime_s { char dummy; } datetime_t; typedef enum { DATE_INVALID = -1, DATE_RFC3164 = 0, DATE_RFC3339 = 1, DATE_UNIX = 2, } dateTimeFormat_t; /* interfaces */ BEGINinterface(datetime) /* name must also be changed in ENDinterface macro! */ void (*getCurrTime)(struct syslogTime *t, time_t *ttSeconds, const int inUTC); rsRetVal (*ParseTIMESTAMP3339)(struct syslogTime *pTime, uchar **ppszTS, int *); rsRetVal (*ParseTIMESTAMP3164)(struct syslogTime *pTime, uchar **pszTS, int *, const int bParseTZ, const int bDetectYearAfterTime); int (*formatTimestampToMySQL)(struct syslogTime *ts, char *pDst); int (*formatTimestampToPgSQL)(struct syslogTime *ts, char *pDst); int (*formatTimestamp3339)(struct syslogTime *ts, char *pBuf); int (*formatTimestamp3164)(struct syslogTime *ts, char *pBuf, int); int (*formatTimestampSecFrac)(struct syslogTime *ts, char *pBuf); /* v3, 2009-11-12 */ time_t (*GetTime)(time_t *ttSeconds); /* v6, 2011-06-20 , v10, 2016-01-12*/ void (*timeval2syslogTime)(struct timeval *tp, struct syslogTime *t, const int inUTC); /* v7, 2012-03-29 */ int (*formatTimestampUnix)(struct syslogTime *ts, char *pBuf); time_t (*syslogTime2time_t)(const struct syslogTime *ts); /* v11, 2017-10-05 */ int (*formatUnixTimeFromTime_t)(time_t time, const char *format, char *pBuf, uint pBufMax); ENDinterface(datetime) #define datetimeCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */ /* interface changes: * 1 - initial version * 2 - not compatible to 1 - bugfix required ParseTIMESTAMP3164 to accept char ** as * last parameter. Did not try to remain compatible as this is not something any * third-party module should call. -- rgerhards, 2008.-09-12 * 3 - taken by v5 branch! * 4 - formatTimestamp3164 takes a third int parameter * 5 - merge of versions 3 + 4 (2010-03-09) * 6 - see above * 8 - ParseTIMESTAMP3164 has addtl parameter to permit TZ string parsing * 9 - ParseTIMESTAMP3164 has addtl parameter to permit year parsing * 10 - functions having addtl paramater inUTC to emit time in UTC: * timeval2syslogTime, getCurrtime * 11 - Add formatUnixTimeFromTime_t */ #define PARSE3164_TZSTRING 1 #define NO_PARSE3164_TZSTRING 0 #define PERMIT_YEAR_AFTER_TIME 1 #define NO_PERMIT_YEAR_AFTER_TIME 0 /* two defines for functions that create timestamps either in local * time or UTC. */ #define TIME_IN_UTC 1 #define TIME_IN_LOCALTIME 0 /* prototypes */ PROTOTYPEObj(datetime); void applyDfltTZ(struct syslogTime *pTime, char *tz); int getWeekdayNbr(struct syslogTime *ts); int getOrdinal(struct syslogTime *ts); int getWeek(struct syslogTime *ts); int getISOWeek(struct syslogTime *ts, int *year); void timeConvertToUTC(const struct syslogTime *const __restrict__ local, struct syslogTime *const __restrict__ utc); time_t getTime(time_t *ttSeconds); dateTimeFormat_t getDateTimeFormatFromStr(const char *const __restrict__ s); #endif /* #ifndef INCLUDED_DATETIME_H */ rsyslog-8.2512.0/runtime/PaxHeaders/janitor.h0000644000000000000000000000013215055605325016041 xustar0030 mtime=1756826325.645800623 30 atime=1764930982.208714811 30 ctime=1764935923.144575983 rsyslog-8.2512.0/runtime/janitor.h0000664000175000017500000000227715055605325015515 0ustar00rgerrger/* rsyslog's janitor * * Copyright (C) 2014 by Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_JANITOR_H #define INCLUDED_JANITOR_H struct janitorEtry { struct janitorEtry *next; char *id; /* ID used to remove entry */ void (*cb)(void *pUsr); void *pUsr; /* user-settable pointer (passed to callback) */ }; rsRetVal janitorAddEtry(void (*cb)(void *), const char *id, void *pUsr); rsRetVal janitorDelEtry(const char *__restrict__ const id); void janitorRun(void); #endif /* #ifndef INCLUDED_JANITOR_H */ rsyslog-8.2512.0/runtime/PaxHeaders/srutils.c0000644000000000000000000000013115055605325016072 xustar0030 mtime=1756826325.652800728 29 atime=1764930987.35180073 30 ctime=1764935923.186576627 rsyslog-8.2512.0/runtime/srutils.c0000664000175000017500000006444115055605325015550 0ustar00rgerrger/**\file srUtils.c * \brief General utilties that fit nowhere else. * * The namespace for this file is "srUtil". * * \author Rainer Gerhards * \date 2003-09-09 * Coding begun. * * Copyright 2003-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "obj.h" #include "errmsg.h" #include "glbl.h" #include "rsconf.h" #if _POSIX_TIMERS <= 0 #include #endif /* here we host some syslog specific names. There currently is no better place * to do it, but over here is also not ideal... -- rgerhards, 2008-02-14 * rgerhards, 2008-04-16: note in LGPL move: the code tables below exist in * the same way in BSD, so it is not a problem to move them from GPLv3 to LGPL. * And nobody modified them since it was under LGPL, so we can also move it * to ASL 2.0. */ syslogName_t syslogPriNames[] = { {"alert", LOG_ALERT}, {"crit", LOG_CRIT}, {"debug", LOG_DEBUG}, {"emerg", LOG_EMERG}, {"err", LOG_ERR}, {"error", LOG_ERR}, /* DEPRECATED */ {"info", LOG_INFO}, {"none", INTERNAL_NOPRI}, /* INTERNAL */ {"notice", LOG_NOTICE}, {"panic", LOG_EMERG}, /* DEPRECATED */ {"warn", LOG_WARNING}, /* DEPRECATED */ {"warning", LOG_WARNING}, {"*", TABLE_ALLPRI}, {NULL, -1}}; #ifndef LOG_AUTHPRIV #define LOG_AUTHPRIV LOG_AUTH #endif syslogName_t syslogFacNames[] = { {"auth", LOG_AUTH}, {"authpriv", LOG_AUTHPRIV}, {"cron", LOG_CRON}, {"daemon", LOG_DAEMON}, {"kern", LOG_KERN}, {"lpr", LOG_LPR}, {"mail", LOG_MAIL}, {"mark", LOG_MARK}, /* INTERNAL */ {"news", LOG_NEWS}, {"ntp", (12 << 3)}, /* NTP, perhaps BSD-specific? */ {"security", LOG_AUTH}, /* DEPRECATED */ {"bsd_security", (13 << 3)}, /* BSD-specific, unfortunatly with duplicate name... */ {"syslog", LOG_SYSLOG}, {"user", LOG_USER}, {"uucp", LOG_UUCP}, #if defined(_AIX) /* AIXPORT : These are necessary for AIX */ {"caa", LOG_CAA}, {"aso", LOG_ASO}, #endif #if defined(LOG_FTP) {"ftp", LOG_FTP}, #endif #if defined(LOG_AUDIT) {"audit", LOG_AUDIT}, #endif {"console", (14 << 3)}, /* BSD-specific priority */ {"local0", LOG_LOCAL0}, {"local1", LOG_LOCAL1}, {"local2", LOG_LOCAL2}, {"local3", LOG_LOCAL3}, {"local4", LOG_LOCAL4}, {"local5", LOG_LOCAL5}, {"local6", LOG_LOCAL6}, {"local7", LOG_LOCAL7}, {"invld", LOG_INVLD}, {NULL, -1}, }; /* ################################################################# * * private members * * ################################################################# */ /* As this is not a "real" object, there won't be any private * members in this file. */ /* ################################################################# * * public members * * ################################################################# */ rsRetVal srUtilItoA(char *pBuf, int iLenBuf, number_t iToConv) { int i; int bIsNegative; char szBuf[64]; /* sufficiently large for my lifespan and those of my children... ;) */ assert(pBuf != NULL); assert(iLenBuf > 1); /* This is actually an app error and as thus checked for... */ if (iToConv < 0) { bIsNegative = RSTRUE; iToConv *= -1; } else bIsNegative = RSFALSE; /* first generate a string with the digits in the reverse direction */ i = 0; do { szBuf[i++] = iToConv % 10 + '0'; iToConv /= 10; } while (iToConv > 0); /* warning: do...while()! */ --i; /* undo last increment - we were pointing at NEXT location */ /* make sure we are within bounds... */ if (i + 2 > iLenBuf) /* +2 because: a) i starts at zero! b) the \0 byte */ return RS_RET_PROVIDED_BUFFER_TOO_SMALL; /* then move it to the right direction... */ if (bIsNegative == RSTRUE) *pBuf++ = '-'; while (i >= 0) *pBuf++ = szBuf[i--]; *pBuf = '\0'; /* terminate it!!! */ return RS_RET_OK; } uchar *srUtilStrDup(uchar *pOld, size_t len) { uchar *pNew; assert(pOld != NULL); if ((pNew = malloc(len + 1)) != NULL) memcpy(pNew, pOld, len + 1); return pNew; } /* creates a path recursively * Return 0 on success, -1 otherwise. On failure, errno * hold the last OS error. * Param "mode" holds the mode that all non-existing directories are to be * created with. * Note that we have a potential race inside that code, a race that even exists * outside of the rsyslog process (if multiple instances run, or other programs * generate directories): If the directory does not exist, a context switch happens, * at that moment another process creates it, then our creation on the context * switch back fails. This actually happened in practice, and depending on the * configuration it is even likely to happen. We can not solve this situation * with a mutex, as that works only within out process space. So the solution * is that we take the optimistic approach, try the creation, and if it fails * with "already exists" we go back and do one retry of the check/create * sequence. That should then succeed. If the directory is still not found but * the creation fails in the similar way, we return an error on that second * try because otherwise we would potentially run into an endless loop. * loop. -- rgerhards, 2010-03-25 * The likeliest scenario for a prolonged contest of creating the parent directiories * is within our process space. This can happen with a high probability when two * threads, that want to start logging to files within same directory tree, are * started close to each other. We should fix what we can. -- nipakoo, 2017-11-25 */ static int real_makeFileParentDirs(const uchar *const szFile, const size_t lenFile, const mode_t mode, const uid_t uid, const gid_t gid, const int bFailOnChownFail) { uchar *p; uchar *pszWork; size_t len; assert(szFile != NULL); assert(lenFile > 0); len = lenFile + 1; /* add one for '\0'-byte */ if ((pszWork = malloc(len)) == NULL) return -1; memcpy(pszWork, szFile, len); for (p = pszWork + 1; *p; p++) if (*p == '/') { /* temporarily terminate string, create dir and go on */ *p = '\0'; int bErr = 0; if (mkdir((char *)pszWork, mode) == 0) { if (uid != (uid_t)-1 || gid != (gid_t)-1) { /* we need to set owner/group */ if (chown((char *)pszWork, uid, gid) != 0) { LogError(errno, RS_RET_DIR_CHOWN_ERROR, "chown for directory '%s' failed", pszWork); if (bFailOnChownFail) { /* ignore if configured to do so */ bErr = 1; } } } } else if (errno != EEXIST) { /* EEXIST is ok, means this component exists */ bErr = 1; } if (bErr) { int eSave = errno; free(pszWork); errno = eSave; return -1; } *p = '/'; } free(pszWork); return 0; } /* note: this small function is the stub for the brain-dead POSIX cancel handling */ int makeFileParentDirs(const uchar *const szFile, const size_t lenFile, const mode_t mode, const uid_t uid, const gid_t gid, const int bFailOnChownFail) { static pthread_mutex_t mutParentDir = PTHREAD_MUTEX_INITIALIZER; int r; /* needs to be declared OUTSIDE of pthread_cleanup... macros! */ pthread_mutex_lock(&mutParentDir); pthread_cleanup_push(mutexCancelCleanup, &mutParentDir); r = real_makeFileParentDirs(szFile, lenFile, mode, uid, gid, bFailOnChownFail); pthread_mutex_unlock(&mutParentDir); pthread_cleanup_pop(0); return r; } /* execute a program with a single argument * returns child pid if everything ok, 0 on failure. if * it fails, errno is set. if it fails after the fork(), the caller * can not be notfied for obvious reasons. if bwait is set to 1, * the code waits until the child terminates - that potentially takes * a lot of time. * implemented 2007-07-20 rgerhards */ int execProg(uchar *program, int bWait, uchar *arg) { int pid; int sig; struct sigaction sigAct; dbgprintf("exec program '%s' with param '%s'\n", program, arg); pid = fork(); if (pid < 0) { return 0; } if (pid) { /* Parent */ if (bWait) { /* waitpid will fail with errno == ECHILD if the child process has already been reaped by the rsyslogd main loop (see rsyslogd.c) */ int status; if (waitpid(pid, &status, 0) == pid) { glblReportChildProcessExit(runConf, program, pid, status); } else if (errno != ECHILD) { /* we do not use logerror(), because * that might bring us into an endless * loop. At some time, we may * reconsider this behaviour. */ dbgprintf("could not wait on child after executing '%s'", (char *)program); } } return pid; } /* Child */ alarm(0); /* create a clean environment before we exec the real child */ memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = SIG_DFL; for (sig = 1; sig < NSIG; ++sig) sigaction(sig, &sigAct, NULL); execlp((char *)program, (char *)program, (char *)arg, NULL); /* In the long term, it's a good idea to implement some enhanced error * checking here. However, it can not easily be done. For starters, we * may run into endless loops if we log to syslog. The next problem is * that output is typically not seen by the user. For the time being, * we use no error reporting, which is quite consitent with the old * system() way of doing things. rgerhards, 2007-07-20 */ perror("exec"); fprintf(stderr, "exec program was '%s' with param '%s'\n", program, arg); exit(1); /* not much we can do in this case */ } /* skip over whitespace in a standard C string. The * provided pointer is advanced to the first non-whitespace * charater or the \0 byte, if there is none. It is never * moved past the \0. */ void skipWhiteSpace(uchar **pp) { register uchar *p; assert(pp != NULL); assert(*pp != NULL); p = *pp; while (*p && isspace((int)*p)) ++p; *pp = p; } /* generate a file name from four parts: * /. * If number is negative, it is not used. If any of the strings is * NULL, an empty string is used instead. Length must be provided. * lNumDigits is the minimum number of digits that lNum should have. This * is to pretty-print the file name, e.g. lNum = 3, lNumDigits= 4 will * result in "0003" being used inside the file name. Set lNumDigits to 0 * to use as few space as possible. * rgerhards, 2008-01-03 */ PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wformat_nonliteral rsRetVal genFileName( uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName, size_t lenFName, int64_t lNum, int lNumDigits) { DEFiRet; uchar *pName; uchar *pNameWork; size_t lenName; uchar szBuf[128]; /* buffer for number */ char szFmtBuf[32]; /* buffer for snprintf format */ size_t lenBuf; if (lNum < 0) { szBuf[0] = '\0'; lenBuf = 0; } else { if (lNumDigits > 0) { snprintf(szFmtBuf, sizeof(szFmtBuf), ".%%0%d" PRId64, lNumDigits); lenBuf = snprintf((char *)szBuf, sizeof(szBuf), szFmtBuf, lNum); } else lenBuf = snprintf((char *)szBuf, sizeof(szBuf), ".%" PRId64, lNum); } lenName = lenDirName + 1 + lenFName + lenBuf + 1; /* last +1 for \0 char! */ if ((pName = malloc(lenName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); /* got memory, now construct string */ memcpy(pName, pDirName, lenDirName); pNameWork = pName + lenDirName; *pNameWork++ = '/'; memcpy(pNameWork, pFName, lenFName); pNameWork += lenFName; if (lenBuf > 0) { memcpy(pNameWork, szBuf, lenBuf); pNameWork += lenBuf; } *pNameWork = '\0'; *ppName = pName; finalize_it: RETiRet; } PRAGMA_DIAGNOSTIC_POP /* get the number of digits required to represent a given number. We use an * iterative approach as we do not like to draw in the floating point * library just for log(). -- rgerhards, 2008-01-10 */ int getNumberDigits(long lNum) { int iDig; if (lNum == 0) iDig = 1; else for (iDig = 0; lNum != 0; ++iDig) lNum /= 10; return iDig; } /* compute an absolute time timeout suitable for calls to pthread_cond_timedwait() * iTimeout is in milliseconds * rgerhards, 2008-01-14 */ rsRetVal timeoutComp(struct timespec *pt, long iTimeout) { #if _POSIX_TIMERS <= 0 struct timeval tv; #endif assert(pt != NULL); /* compute timeout */ #if _POSIX_TIMERS > 0 /* this is the "regular" code */ clock_gettime(CLOCK_REALTIME, pt); #else gettimeofday(&tv, NULL); pt->tv_sec = tv.tv_sec; pt->tv_nsec = tv.tv_usec * 1000; #endif pt->tv_sec += iTimeout / 1000; pt->tv_nsec += (iTimeout % 1000) * 1000000; /* think INTEGER arithmetic! */ if (pt->tv_nsec > 999999999) { /* overrun? */ pt->tv_nsec -= 1000000000; ++pt->tv_sec; } return RS_RET_OK; /* so far, this is static... */ } long long currentTimeMills(void) { struct timespec tm; #if _POSIX_TIMERS <= 0 struct timeval tv; #endif #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &tm); #else gettimeofday(&tv, NULL); tm.tv_sec = tv.tv_sec; tm.tv_nsec = tv.tv_usec * 1000; #endif return ((long long)tm.tv_sec) * 1000 + (tm.tv_nsec / 1000000); } /* This function is kind of the reverse of timeoutComp() - it takes an absolute * timeout value and computes how far this is in the future. If the value is already * in the past, 0 is returned. The return value is in ms. * rgerhards, 2008-01-25 */ long timeoutVal(struct timespec *pt) { struct timespec t; long iTimeout; #if _POSIX_TIMERS <= 0 struct timeval tv; #endif assert(pt != NULL); /* compute timeout */ #if _POSIX_TIMERS > 0 /* this is the "regular" code */ clock_gettime(CLOCK_REALTIME, &t); #else gettimeofday(&tv, NULL); t.tv_sec = tv.tv_sec; t.tv_nsec = tv.tv_usec * 1000; #endif iTimeout = (pt->tv_nsec - t.tv_nsec) / 1000000; iTimeout += (pt->tv_sec - t.tv_sec) * 1000; if (iTimeout < 0) iTimeout = 0; return iTimeout; } /* cancellation cleanup handler - frees provided mutex * rgerhards, 2008-01-14 */ void mutexCancelCleanup(void *arg) { assert(arg != NULL); d_pthread_mutex_unlock((pthread_mutex_t *)arg); } /* rsSleep() - a fairly portable way to to sleep. It * will wake up when * a) the wake-time is over * rgerhards, 2008-01-28 */ void srSleep(int iSeconds, int iuSeconds) { struct timeval tvSelectTimeout; tvSelectTimeout.tv_sec = iSeconds; tvSelectTimeout.tv_usec = iuSeconds; /* micro seconds */ select(0, NULL, NULL, NULL, &tvSelectTimeout); } /* From varmojfekoj's mail on why he provided rs_strerror_r(): * There are two problems with strerror_r(): * I see you've rewritten some of the code which calls it to use only * the supplied buffer; unfortunately the GNU implementation sometimes * doesn't use the buffer at all and returns a pointer to some * immutable string instead, as noted in the man page. * * The other problem is that on some systems strerror_r() has a return * type of int. * * So I've written a wrapper function rs_strerror_r(), which should * take care of all this and be used instead. * * Added 2008-01-30 */ char *rs_strerror_r(int errnum, char *buf, size_t buflen) { #ifndef HAVE_STRERROR_R char *pszErr; pszErr = strerror(errnum); snprintf(buf, buflen, "%s", pszErr); #else #ifdef STRERROR_R_CHAR_P char *p = strerror_r(errnum, buf, buflen); if (p != buf) { strncpy(buf, p, buflen); buf[buflen - 1] = '\0'; } #else strerror_r(errnum, buf, buflen); #endif #endif /* #ifdef __hpux */ return buf; } /* Decode a symbolic name to a numeric value */ int decodeSyslogName(uchar *name, syslogName_t *codetab) { register syslogName_t *c; register uchar *p; uchar buf[80]; assert(name != NULL); assert(codetab != NULL); DBGPRINTF("symbolic name: %s", name); if (isdigit((int)*name)) { DBGPRINTF("\n"); return (atoi((char *)name)); } strncpy((char *)buf, (char *)name, 79); for (p = buf; *p; p++) { if (isupper((int)*p)) *p = tolower((int)*p); } for (c = codetab; c->c_name; c++) { if (!strcmp((char *)buf, (char *)c->c_name)) { DBGPRINTF(" ==> %d\n", c->c_val); return (c->c_val); } } DBGPRINTF("\n"); return (-1); } /** * getSubString * * Copy a string byte by byte until the occurrence * of a given separator. * * \param ppSrc Pointer to a pointer of the source array of characters. If a separator detected the Pointer points to the next char after the separator. Except if the end of the string is dedected ('\n'). Then it points to the terminator char. * \param pDst Pointer to the destination array of characters. Here the substing will be stored. * \param DstSize Maximum numbers of characters to store. * \param cSep Separator char. * \ret int Returns 0 if no error occurred. * * rgerhards, 2008-02-12: some notes are due... I will once again fix this function, this time * so that it treats ' ' as a request for whitespace. But in general, the function and its callers * should be changed over time, this is not really very good code... */ int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep) { uchar *pSrc = *ppSrc; int iErr = 0; /* 0 = no error, >0 = error */ while ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0' && DstSize > 1) { *pDst++ = *(pSrc)++; DstSize--; } /* check if the Dst buffer was to small */ if ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0') { dbgprintf("in getSubString, error Src buffer > Dst buffer\n"); iErr = 1; } if (*pSrc == '\0' || *pSrc == '\n') /* this line was missing, causing ppSrc to be invalid when it * was returned in case of end-of-string. rgerhards 2005-07-29 */ *ppSrc = pSrc; else *ppSrc = pSrc + 1; *pDst = '\0'; return iErr; } /* get the size of a file or return appropriate error code. If an error is returned, * *pSize content is undefined. * rgerhards, 2009-06-12 */ rsRetVal getFileSize(uchar *pszName, off_t *pSize) { int ret; struct stat statBuf; DEFiRet; ret = stat((char *)pszName, &statBuf); if (ret == -1) { switch (errno) { case EACCES: ABORT_FINALIZE(RS_RET_NO_FILE_ACCESS); case ENOTDIR: case ENOENT: ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); default: ABORT_FINALIZE(RS_RET_FILE_NO_STAT); } } *pSize = statBuf.st_size; finalize_it: RETiRet; } /* Returns 1 if the given string contains a non-escaped glob(3) * wildcard character and 0 otherwise (or if the string is empty). */ int containsGlobWildcard(char *str) { char *p; if (!str) { return 0; } /* From Linux Programmer's Guide: * "A string is a wildcard pattern if it contains one of the characters '?', '*', '{' or '['" * "One can remove the special meaning of '?', '*', '{' and '[' by preceding them by a backslash" */ for (p = str; *p != '\0'; p++) { if ((*p == '?' || *p == '*' || *p == '[' || *p == '{') && (p == str || *(p - 1) != '\\')) { return 1; } } return 0; } static void seedRandomInsecureNumber(void) { struct timespec t; timeoutComp(&t, 0); long long x = t.tv_sec * 3 + t.tv_nsec * 2; srandom((unsigned int)x); } static long int randomInsecureNumber(void) { return random(); } #ifdef OS_LINUX static int fdURandom = -1; void seedRandomNumber(void) { if (fdURandom >= 0) { /* Already opened. */ return; } fdURandom = open("/dev/urandom", O_RDONLY); if (fdURandom == -1) { LogError(errno, RS_RET_IO_ERROR, "failed to seed random number generation," " will use fallback (open urandom failed)"); seedRandomInsecureNumber(); } } void seedRandomNumberForChild(void) { /* The file descriptor inherited from our parent will have been closed after * the fork. Discard this and call seedRandomNumber() to open /dev/urandom * again. */ fdURandom = -1; seedRandomNumber(); } long int randomNumber(void) { long int ret; if (fdURandom >= 0) { if (read(fdURandom, &ret, sizeof(long int)) == -1) { LogError(errno, RS_RET_IO_ERROR, "failed to generate random number, will" " use fallback (read urandom failed)"); ret = randomInsecureNumber(); } } else { ret = randomInsecureNumber(); } return ret; } #else void seedRandomNumber(void) { seedRandomInsecureNumber(); } void seedRandomNumberForChild(void) { seedRandomNumber(); } long int randomNumber(void) { return randomInsecureNumber(); } #endif /* process "binary" parameters where this is needed to execute * programs (namely mmexternal and omprog). * Most importantly, split them into argv[] and get the binary name */ rsRetVal ATTR_NONNULL() split_binary_parameters(uchar **const szBinary, char ***const __restrict__ aParams, int *const iParams, es_str_t *const param_binary) { es_size_t iCnt; es_size_t iStr; int iPrm; es_str_t *estrParams = NULL; es_str_t *estrBinary = param_binary; es_str_t *estrTmp = NULL; uchar *c; int bInQuotes; DEFiRet; assert(iParams != NULL); assert(param_binary != NULL); /* Search for end of binary name */ c = es_getBufAddr(param_binary); iCnt = 0; while (iCnt < es_strlen(param_binary)) { if (c[iCnt] == ' ') { /* Split binary name from parameters */ estrBinary = es_newStrFromSubStr(param_binary, 0, iCnt); estrParams = es_newStrFromSubStr(param_binary, iCnt + 1, es_strlen(param_binary)); break; } iCnt++; } *szBinary = (uchar *)es_str2cstr(estrBinary, NULL); DBGPRINTF("szBinary = '%s'\n", *szBinary); *iParams = 1; /* we always have argv[0] */ /* count size of argv[] */ if (estrParams != NULL) { (*iParams)++; /* last parameter is not counted in loop below! */ if (Debug) { char *params = es_str2cstr(estrParams, NULL); dbgprintf("szParams = '%s'\n", params); free(params); } c = es_getBufAddr(estrParams); for (iCnt = 0; iCnt < es_strlen(estrParams); ++iCnt) { if (c[iCnt] == ' ' && c[iCnt - 1] != '\\') (*iParams)++; } } DBGPRINTF("iParams %d (+1 for NULL terminator)\n", *iParams); /* create argv[] */ CHKmalloc(*aParams = malloc((*iParams + 1) * sizeof(char *))); iPrm = 0; bInQuotes = FALSE; /* Set first parameter to binary */ (*aParams)[iPrm] = strdup((char *)*szBinary); iPrm++; if (estrParams != NULL) { iCnt = iStr = 0; c = es_getBufAddr(estrParams); /* Reset to beginning */ while (iCnt < es_strlen(estrParams)) { if (c[iCnt] == '"' && iCnt == iStr && !bInQuotes) { bInQuotes = TRUE; iStr++; } else { int bEOL = iCnt + 1 == es_strlen(estrParams); int bSpace = c[iCnt] == ' '; int bQuoteEnd = bInQuotes && ((bSpace && c[iCnt - 1] == '"') || (c[iCnt] == '"' && bEOL)); if (bEOL || bQuoteEnd || (bSpace && !bInQuotes)) { int iSubCnt = iCnt - iStr; if (bEOL) iSubCnt++; if (bQuoteEnd) iSubCnt--; estrTmp = es_newStrFromSubStr(estrParams, iStr, iSubCnt); } if (bQuoteEnd) bInQuotes = FALSE; } if (estrTmp != NULL) { (*aParams)[iPrm] = es_str2cstr(estrTmp, NULL); iStr = iCnt + 1; /* Set new start */ DBGPRINTF("Param (%d): '%s'\n", iPrm, (*aParams)[iPrm]); es_deleteStr(estrTmp); estrTmp = NULL; iPrm++; } iCnt++; } } (*aParams)[iPrm] = NULL; /* NULL per argv[] convention */ finalize_it: if (estrBinary != param_binary) { es_deleteStr(estrBinary); } if (estrParams != NULL) { es_deleteStr(estrParams); } RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/perctile_ringbuf.c0000644000000000000000000000013215055605325017711 xustar0030 mtime=1756826325.650800698 30 atime=1764930991.547870742 30 ctime=1764935923.224577208 rsyslog-8.2512.0/runtime/perctile_ringbuf.c0000664000175000017500000002311215055605325017354 0ustar00rgerrger/* * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "perctile_ringbuf.h" static uint64_t min(uint64_t a, uint64_t b) { return a < b ? a : b; } /* * circ buf macros derived from linux/circ_buf.h */ /* Return count in buffer. */ #define CIRC_CNT(head, tail, size) (((head) - (tail)) & ((size) - 1)) /* Return space available, 0..size-1. We always leave one free char as a completely full buffer has head == tail, which is the same as empty. */ #define CIRC_SPACE(head, tail, size) CIRC_CNT((tail), ((head) + 1), (size)) /* Return count up to the end of the buffer. Carefully avoid accessing head and tail more than once, so they can change underneath us without returning inconsistent results. */ #define CIRC_CNT_TO_END(head, tail, size) \ ({ \ int end = (size) - (tail); \ int n = ((head) + end) & ((size) - 1); \ n < end ? n : end; \ }) /* Return space available up to the end of the buffer. */ #define CIRC_SPACE_TO_END(head, tail, size) \ ({ \ int end = (size) - 1 - (head); \ int n = (end + (tail)) & ((size) - 1); \ n <= end ? n : end + 1; \ }) /* Move head by size. */ #define CIRC_ADD(idx, size, offset) (((idx) + (offset)) & ((size) - 1)) // simple use of the linux defined circular buffer. ringbuf_t *ringbuf_new(size_t count) { // use nearest power of 2 double x = ceil(log2(count)); size_t bufsize = pow(2, x); ringbuf_t *rb = calloc(1, sizeof(ringbuf_t)); // Note: count needs to be a power of 2, otherwise our macros won't work. ITEM *pbuf = calloc(bufsize, sizeof(ITEM)); rb->cb.buf = pbuf; rb->cb.head = rb->cb.tail = 0; rb->size = bufsize; return rb; } void ringbuf_del(ringbuf_t *rb) { if (rb) { if (rb->cb.buf) { free(rb->cb.buf); } free(rb); } } int ringbuf_append(ringbuf_t *rb, ITEM item) { // lock it and add int head = rb->cb.head, tail = rb->cb.tail; if (!CIRC_SPACE(head, tail, rb->size)) { return -1; } else { /* insert item into buffer */ rb->cb.buf[head] = item; // move head rb->cb.head = CIRC_ADD(head, rb->size, 1); } return 0; } int ringbuf_append_with_overwrite(ringbuf_t *rb, ITEM item) { int head = rb->cb.head, tail = rb->cb.tail; int ret = 0; if (!CIRC_SPACE(head, tail, rb->size)) { rb->cb.tail = CIRC_ADD(tail, rb->size, 1); } ret = ringbuf_append(rb, item); assert(ret == 0); // we shouldn't fail due to no space. return ret; } int ringbuf_read(ringbuf_t *rb, ITEM *buf, size_t count) { int head = rb->cb.head, tail = rb->cb.tail; size_t copy_size = 0; if (!CIRC_CNT(head, tail, rb->size)) { return 0; } // copy to end of buffer copy_size = min((size_t)CIRC_CNT_TO_END(head, tail, rb->size), count); memcpy(buf, rb->cb.buf + tail, copy_size * sizeof(ITEM)); rb->cb.tail = CIRC_ADD(rb->cb.tail, rb->size, copy_size); return copy_size; } size_t ringbuf_read_to_end(ringbuf_t *rb, ITEM *buf, size_t count) { size_t nread = 0; nread += ringbuf_read(rb, buf, count); if (nread == 0) { return nread; } // read the rest if buf circled around nread += ringbuf_read(rb, buf + nread, count - nread); assert(nread <= count); return nread; } bool ringbuf_peek(ringbuf_t *rb, ITEM *item) { if (CIRC_CNT(rb->cb.head, rb->cb.tail, rb->size) == 0) { return false; } *item = rb->cb.buf[rb->cb.tail]; return true; } size_t ringbuf_capacity(ringbuf_t *rb) { return rb->size; } /* ---- RINGBUFFER TESTS ---- */ void ringbuf_init_test(void) { size_t count = 4; ringbuf_t *rb = ringbuf_new(count); // verify ringbuf empty state assert(rb->cb.head == 0); assert(rb->cb.tail == 0); assert(rb->size == 4); ringbuf_del(rb); } void ringbuf_simple_test(void) { size_t count = 3; ITEM item = 0; ringbuf_t *rb = ringbuf_new(count); assert(ringbuf_append(rb, 1) == 0); assert(ringbuf_append(rb, 2) == 0); assert(ringbuf_append(rb, 3) == 0); item = 0; assert(ringbuf_peek(rb, &item) == 0); assert(item == 1); } void ringbuf_append_test(void) { size_t count = 4; ringbuf_t *rb = ringbuf_new(count); assert(ringbuf_append(rb, 1) == 0); assert(ringbuf_append(rb, 2) == 0); assert(ringbuf_append(rb, 3) == 0); // check state of ringbuffer: // {1, 2, 3, X} // T H assert(rb->cb.buf[0] == 1); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.buf[3] == 0); assert(rb->cb.head == 3); assert(rb->cb.tail == 0); ringbuf_del(rb); } void ringbuf_append_wrap_test(void) { size_t count = 4; ITEM item = 0; ringbuf_t *rb = ringbuf_new(count); assert(ringbuf_append(rb, 1) == 0); assert(ringbuf_append(rb, 2) == 0); assert(ringbuf_append(rb, 3) == 0); assert(ringbuf_append(rb, 4) != 0); // check state of ringbuffer: // {1, 2, 3, X} // T H assert(rb->cb.buf[0] == 1); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.head == 3); assert(rb->cb.tail == 0); item = 0; assert(ringbuf_read(rb, &item, 1) == 1); assert(item == 1); assert(ringbuf_append(rb, 4) == 0); // state of ringbuffer: // {1, 2, 3, 4} // H T assert(rb->cb.buf[0] == 1); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.buf[3] == 4); assert(rb->cb.head == 0); assert(rb->cb.tail == 1); item = 0; assert(ringbuf_read(rb, &item, 1) == 1); assert(item == 2); // test wraparound assert(ringbuf_append(rb, 5) == 0); // state of ringbuffer: // {1, 2, 3, 4} // H T assert(rb->cb.buf[0] == 5); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.buf[3] == 4); assert(rb->cb.head == 1); assert(rb->cb.tail == 2); ringbuf_del(rb); } void ringbuf_append_overwrite_test(void) { size_t count = 4; ringbuf_t *rb = ringbuf_new(count); assert(ringbuf_append_with_overwrite(rb, 1) == 0); assert(ringbuf_append_with_overwrite(rb, 2) == 0); assert(ringbuf_append_with_overwrite(rb, 3) == 0); assert(ringbuf_append_with_overwrite(rb, 4) == 0); // check state of ringbuffer: // {1, 2, 3, 4} // H T assert(rb->cb.buf[0] == 1); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.buf[3] == 4); assert(rb->cb.head == 0); assert(rb->cb.tail == 1); assert(ringbuf_append_with_overwrite(rb, 5) == 0); // check state of ringbuffer: // {5, 2, 3, 4} // H T assert(rb->cb.buf[0] == 5); assert(rb->cb.buf[1] == 2); assert(rb->cb.buf[2] == 3); assert(rb->cb.buf[3] == 4); assert(rb->cb.head == 1); assert(rb->cb.tail == 2); ringbuf_del(rb); } void ringbuf_read_test(void) { size_t count = 4; ringbuf_t *rb = ringbuf_new(count); ITEM item_array[3]; ITEM expects[] = {1, 2, 3}; ITEM expects2[] = {4}; assert(ringbuf_append_with_overwrite(rb, 1) == 0); assert(ringbuf_append_with_overwrite(rb, 2) == 0); assert(ringbuf_append_with_overwrite(rb, 3) == 0); assert(ringbuf_read(rb, item_array, count) == 3); assert(memcmp(item_array, expects, 3) == 0); // check state of ringbuffer: // {X, X, X, X} // H // T assert(rb->cb.head == 3); assert(rb->cb.tail == 3); assert(ringbuf_append_with_overwrite(rb, 4) == 0); assert(ringbuf_read(rb, item_array, count) == 1); assert(memcmp(item_array, expects2, 1) == 0); assert(rb->cb.head == 0); assert(rb->cb.tail == 0); ringbuf_del(rb); } void ringbuf_read_to_end_test(void) { size_t count = 4; ringbuf_t *rb = ringbuf_new(count); ITEM item_array[3]; ITEM expects[] = {1, 2, 3}; ITEM expects2[] = {4}; assert(ringbuf_append_with_overwrite(rb, 1) == 0); assert(ringbuf_append_with_overwrite(rb, 2) == 0); assert(ringbuf_append_with_overwrite(rb, 3) == 0); // state of ringbuffer: // {1, 2, 3, X} // T H assert(ringbuf_read_to_end(rb, item_array, 3) == 3); assert(memcmp(item_array, expects, 3) == 0); // check state of ringbuffer: // {1, 2, 3, X} // H // T assert(rb->cb.head == 3); assert(rb->cb.tail == 3); assert(ringbuf_append_with_overwrite(rb, 4) == 0); // state of ringbuffer: // {1, 2, 3, 4} // H T assert(ringbuf_read_to_end(rb, item_array, count) == 1); // check state of ringbuffer (empty): // {1, 2, 3, 4} // H // T assert(memcmp(item_array, expects2, 1) == 0); assert(rb->cb.head == 0); assert(rb->cb.tail == 0); ringbuf_del(rb); } /* ---- END RINGBUFFER TESTS ---- */ rsyslog-8.2512.0/runtime/PaxHeaders/operatingstate.h0000644000000000000000000000013115055605325017423 xustar0030 mtime=1756826325.650800698 30 atime=1764930981.027695065 29 ctime=1764935923.19857681 rsyslog-8.2512.0/runtime/operatingstate.h0000664000175000017500000000212015055605325017063 0ustar00rgerrger/* OperatingStateFile interface. * * Copyright 2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_OPERATINGSTATEFILE_H #define INCLUDED_OPERATINGSTATEFILE_H /* supported TAGS */ #define OSF_TAG_STATE "STATE" #define OSF_TAG_MSG "MSG" void osf_open(void); void ATTR_NONNULL() osf_write(const char *const tag, const char *const line); void osf_close(void); #endif /* #ifndef INCLUDED_OPERATINGSTATEFILE_H */ rsyslog-8.2512.0/runtime/PaxHeaders/obj-types.h0000644000000000000000000000013215055605325016307 xustar0030 mtime=1756826325.650800698 30 atime=1764930979.971677403 30 ctime=1764935923.120575616 rsyslog-8.2512.0/runtime/obj-types.h0000664000175000017500000005257515055605325015771 0ustar00rgerrger/* Some type definitions and macros for the obj object. * I needed to move them out of the main obj.h, because obj.h's * prototypes use other data types. However, their .h's rely * on some of the obj.h data types and macros. So I needed to break * that loop somehow and I've done that by moving the typedefs * into this file here. * * Copyright 2008-2024 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OBJ_TYPES_H_INCLUDED #define OBJ_TYPES_H_INCLUDED #include "stringbuf.h" #include "syslogd-types.h" /* property types for obj[De]Serialize() */ typedef enum { PROPTYPE_NONE = 0, /* currently no value set */ PROPTYPE_PSZ = 1, PROPTYPE_SHORT = 2, PROPTYPE_INT = 3, PROPTYPE_LONG = 4, PROPTYPE_INT64 = 5, PROPTYPE_CSTR = 6, PROPTYPE_SYSLOGTIME = 7 } propType_t; typedef unsigned objID_t; typedef enum { /* IDs of base methods supported by all objects - used for jump table, so * they must start at zero and be incremented. -- rgerhards, 2008-01-04 */ objMethod_CONSTRUCT = 0, objMethod_DESTRUCT = 1, objMethod_SERIALIZE = 2, objMethod_DESERIALIZE = 3, objMethod_SETPROPERTY = 4, objMethod_CONSTRUCTION_FINALIZER = 5, objMethod_GETSEVERITY = 6, objMethod_DEBUGPRINT = 7 } objMethod_t; #define OBJ_NUM_METHODS 8 /* must be updated to contain the max number of methods supported */ /* the base data type for interfaces * This MUST be in sync with the ifBEGIN macro */ struct interface_s { int ifVersion; /* must be set to version requested */ int ifIsLoaded; /* is the interface loaded? (0-no, 1-yes, 2-load failed; if not 1, functions can NOT be called! */ }; struct objInfo_s { uchar *pszID; /* the object ID as a string */ size_t lenID; /* length of the ID string */ int iObjVers; uchar *pszName; rsRetVal (*objMethods[OBJ_NUM_METHODS])(void *, ...); rsRetVal (*QueryIF)(interface_t *); struct modInfo_s *pModInfo; }; struct obj_s { /* the dummy struct that each derived class can be casted to */ objInfo_t *pObjInfo; #ifndef NDEBUG /* this means if debug... */ unsigned int iObjCooCKiE; /* must always be 0xBADEFEE for a valid object */ #endif uchar *pszName; /* the name of *this* specific object instance */ }; /* macros which must be gloablly-visible (because they are used during definition of * other objects. */ #ifndef NDEBUG /* this means if debug... */ #include #define BEGINobjInstance obj_t objData #define ISOBJ_assert(pObj) \ do { \ assert((pObj) != NULL); \ assert((unsigned)((obj_t *)(pObj))->iObjCooCKiE == (unsigned)0xBADEFEE); \ } while (0); #define ISOBJ_TYPE_assert(pObj, objType) \ do { \ assert(pObj != NULL); \ if (strcmp((char *)(((obj_t *)pObj)->pObjInfo->pszID), #objType)) { \ dbgprintf( \ "%s:%d ISOBJ assert failure: invalid object type, expected '%s' " \ "actual '%s', cookie: %X\n", \ __FILE__, __LINE__, #objType, (((obj_t *)pObj)->pObjInfo->pszID), ((obj_t *)(pObj))->iObjCooCKiE); \ fprintf(stderr, \ "%s:%d ISOBJ assert failure: invalid object type, expected '%s' " \ "actual '%s', cookie: %X\n", \ __FILE__, __LINE__, #objType, (((obj_t *)pObj)->pObjInfo->pszID), \ ((obj_t *)(pObj))->iObjCooCKiE); \ fflush(stderr); \ assert(!strcmp((char *)(((obj_t *)pObj)->pObjInfo->pszID), #objType)); \ } \ assert((unsigned)((obj_t *)(pObj))->iObjCooCKiE == (unsigned)0xBADEFEE); \ } while (0) /* now the same for pointers to "regular" objects (like wrkrInstanceData) */ #define PTR_ASSERT_DEF unsigned int _Assert_type; #define PTR_ASSERT_SET_TYPE(_ptr, _type) _ptr->_Assert_type = _type #define PTR_ASSERT_CHK(_ptr, _type) \ do { \ assert(_ptr != NULL); \ if (_ptr->_Assert_type != _type) { \ dbgprintf( \ "%s:%d PTR_ASSERT_CHECK failure: invalid pointer type %x, " \ "expected %x\n", \ __FILE__, __LINE__, _ptr->_Assert_type, _type); \ fprintf(stderr, \ "%s:%d PTR_ASSERT_CHECK failure: invalid pointer type %x, " \ "expected %x\n", \ __FILE__, __LINE__, _ptr->_Assert_type, _type); \ assert(_ptr->_Assert_type == _type); \ } \ } while (0) #else /* non-debug mode, no checks but much faster */ #define BEGINobjInstance obj_t objData #define ISOBJ_TYPE_assert(pObj, objType) #define ISOBJ_assert(pObj) #define PTR_ASSERT_DEF #define PTR_ASSERT_SET_TYPE(_ptr, _type) #define PTR_ASSERT_CHK(_ptr, _type) #endif /* a set method for *very simple* object accesses. Note that this does * NOT conform to the standard calling conventions and should be * used only if actually nothing can go wrong! -- rgerhards, 2008-04-17 */ #define DEFpropGetMeth(obj, prop, dataType) \ dataType obj##Get##prop(void) { \ return pThis->prop = pVal; \ } #define DEFpropSetMethPTR(obj, prop, dataType) \ rsRetVal obj##Set##prop(obj##_t *pThis, dataType *pVal) { \ pThis->prop = pVal; \ return RS_RET_OK; \ } #define PROTOTYPEpropSetMethPTR(obj, prop, dataType) rsRetVal obj##Set##prop(obj##_t *pThis, dataType *) #define DEFpropSetMethFP(obj, prop, dataType) \ rsRetVal obj##Set##prop(obj##_t *pThis, dataType) { \ pThis->prop = pVal; \ return RS_RET_OK; \ } #define PROTOTYPEpropSetMethFP(obj, prop, dataType) rsRetVal obj##Set##prop(obj##_t *pThis, dataType) #define DEFpropSetMeth(obj, prop, dataType) \ rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal); \ rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal) { \ pThis->prop = pVal; \ return RS_RET_OK; \ } #define PROTOTYPEpropSetMeth(obj, prop, dataType) rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal) #define INTERFACEpropSetMeth(obj, prop, dataType) rsRetVal (*Set##prop)(obj##_t * pThis, dataType) /* class initializer */ #define PROTOTYPEObjClassInit(objName) rsRetVal objName##ClassInit(struct modInfo_s *) /* below: objName must be the object name (e.g. vm, strm, ...) and ISCORE must be * 1 if the module is a statically linked core module and 0 if it is a * dynamically loaded one. -- rgerhards, 2008-02-29 */ #define OBJ_IS_CORE_MODULE 1 /* This should better be renamed to something like "OBJ_IS_NOT_LIBHEAD" or so... ;) */ #define OBJ_IS_LOADABLE_MODULE 0 #define BEGINObjClassInit(objName, objVers, objType) \ rsRetVal objName##ClassInit(struct modInfo_s *pModInfo) { \ DEFiRet; \ if (objType == OBJ_IS_CORE_MODULE) { /* are we a core module? */ \ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ \ } \ CHKiRet(obj.InfoConstruct(&pObjInfoOBJ, (uchar *)#objName, objVers, (rsRetVal(*)(void *))objName##Construct, \ (rsRetVal(*)(void *))objName##Destruct, \ (rsRetVal(*)(interface_t *))objName##QueryInterface, pModInfo)); #define ENDObjClassInit(objName) \ iRet = obj.RegisterObj((uchar *)#objName, pObjInfoOBJ); \ finalize_it: \ RETiRet; \ } /* ... and now the same for abstract classes. * TODO: consolidate the two -- rgerhards, 2008-02-29 */ #define BEGINAbstractObjClassInit(objName, objVers, objType) \ rsRetVal objName##ClassInit(struct modInfo_s *pModInfo) { \ DEFiRet; \ if (objType == OBJ_IS_CORE_MODULE) { /* are we a core module? */ \ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ \ } \ CHKiRet(obj.InfoConstruct(&pObjInfoOBJ, (uchar *)#objName, objVers, NULL, NULL, \ (rsRetVal(*)(interface_t *))objName##QueryInterface, pModInfo)); #define ENDObjClassInit(objName) \ iRet = obj.RegisterObj((uchar *)#objName, pObjInfoOBJ); \ finalize_it: \ RETiRet; \ } /* now come the class exit. This is to be called immediately before the class is * unloaded (actual unload for plugins, program termination for core modules) * gerhards, 2008-03-10 */ #define PROTOTYPEObjClassExit(objName) rsRetVal objName##ClassExit(void) #define BEGINObjClassExit(objName, objType) \ rsRetVal objName##ClassExit(void) { \ DEFiRet; #define CODESTARTObjClassExit(objName) #define ENDObjClassExit(objName) \ iRet = obj.UnregisterObj((uchar *)#objName); \ RETiRet; \ } /* this defines both the constructor and initializer * rgerhards, 2008-01-10 */ #define BEGINobjConstruct(obj) \ static rsRetVal obj##Initialize(obj##_t __attribute__((unused)) * pThis) { \ DEFiRet; #define ENDobjConstruct(obj) \ /* use finalize_it: before calling the macro (if you need it)! */ \ RETiRet; \ } \ rsRetVal obj##Construct(obj##_t **ppThis); \ rsRetVal obj##Construct(obj##_t **ppThis) { \ DEFiRet; \ obj##_t *pThis; \ \ assert(ppThis != NULL); \ \ if ((pThis = (obj##_t *)calloc(1, sizeof(obj##_t))) == NULL) { \ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); \ } \ objConstructSetObjInfo(pThis); \ \ obj##Initialize(pThis); \ \ finalize_it: \ OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP \ RETiRet; \ } /* this defines the destructor. The important point is that the base object * destructor is called. The upper-level class shall destruct all of its * properties, but not the instance itself. This is freed here by the * framework (we need an intact pointer because we need to free the * obj_t structures inside it). A pointer to the object pointer must be * parse, because it is re-set to NULL (this, for example, is important in * cancellation handlers). The object pointer is always named pThis. * The object is always freed, even if there is some error while * Cancellation is blocked during destructors, as this could have fatal * side-effects. However, this also means the upper-level object should * not perform any lengthy processing. * IMPORTANT: if the upper level object requires some situations where the * object shall not be destructed (e.g. via reference counting), then * it shall set pThis to NULL, which prevents destruction of the * object. * processing. * rgerhards, 2008-01-30 */ #define PROTOTYPEobjDestruct(OBJ) rsRetVal OBJ##Destruct(OBJ##_t __attribute__((unused)) * *ppThis) /* note: we generate a prototype in any case, as this does not hurt but * many modules otherwise seem to miss one, which generates compiler * warnings. */ #define BEGINobjDestruct(OBJ) \ rsRetVal OBJ##Destruct(OBJ##_t __attribute__((unused)) * *ppThis); \ rsRetVal OBJ##Destruct(OBJ##_t __attribute__((unused)) * *ppThis) { \ DEFiRet; \ OBJ##_t *pThis; #define CODESTARTobjDestruct(OBJ) \ assert(ppThis != NULL); \ pThis = *ppThis; \ ISOBJ_TYPE_assert(pThis, OBJ); /* note: there was a long-time bug in the macro below that lead to *ppThis = NULL * only when the object was actually destructed. I discovered this issue during * introduction of the pRcvFrom property in smsg_t, but it potentially had other * effects, too. I am not sure if some experienced instability resulted from this * bug OR if its fix will cause harm to so-far "correctly" running code. The later * may very well be. Thus I will change it only for the current branch and also * the beta, but not in all old builds. Let's see how things evolve. * rgerhards, 2009-06-30 */ #define ENDobjDestruct(OBJ) \ goto finalize_it; /* prevent compiler warning ;) */ \ /* no more code here! */ \ finalize_it: \ if (pThis != NULL) { \ obj.DestructObjSelf((obj_t *)pThis); \ free(pThis); \ } \ *ppThis = NULL; \ RETiRet; \ } /* this defines the debug print entry point. DebugPrint is optional. If * it is provided, the object should output some meaningful information * via the debug system. * rgerhards, 2008-02-20 */ #define PROTOTYPEObjDebugPrint(obj) rsRetVal obj##DebugPrint(obj##_t *pThis) #define INTERFACEObjDebugPrint(obj) rsRetVal (*DebugPrint)(obj##_t * pThis) #define BEGINobjDebugPrint(obj) \ rsRetVal obj##DebugPrint(obj##_t __attribute__((unused)) * pThis); \ rsRetVal obj##DebugPrint(obj##_t __attribute__((unused)) * pThis) { \ DEFiRet; #define CODESTARTobjDebugPrint(obj) \ assert(pThis != NULL); \ ISOBJ_TYPE_assert(pThis, obj); #define ENDobjDebugPrint(obj) \ RETiRet; \ } /* ------------------------------ object loader system ------------------------------ * * The following code builds a dynamic object loader system. The * root idea is that all objects are dynamically loadable, * which is necessary to get a clean plug-in interface where every plugin can access * rsyslog's rich object model via simple and quite portable methods. * * To do so, each object defines one or more interfaces. They are essentially structures * with function (method) pointers. Anyone interested in calling an object must first * obtain the interface and can then call through it. * * The interface data type must always be called _if_t, as this is expected * by the macros. Having consitent naming is also easier for the programmer. By default, * macros create a static variable named like the object in each calling objects * static data block. * * rgerhards, 2008-02-21 (initial implementation), 2008-04-17 (update of this note) */ /* this defines the QueryInterface print entry point. Over time, it should be * present in all objects. */ #define BEGINobjQueryInterface(obj) \ rsRetVal obj##QueryInterface(obj##_if_t *pIf); \ rsRetVal obj##QueryInterface(obj##_if_t *pIf) { \ DEFiRet; #define CODESTARTobjQueryInterface(obj) assert(pIf != NULL); #define ENDobjQueryInterface(obj) \ RETiRet; \ } #define PROTOTYPEObjQueryInterface(obj) rsRetVal obj##QueryInterface(obj##_if_t *pIf) /* the following macros should be used to define interfaces inside the * header files. */ #define BEGINinterface(obj) \ typedef struct obj##_if_s { \ ifBEGIN /* This MUST always be the first interface member */ #define ENDinterface(obj) \ } \ obj##_if_t; /* the following macro is used to get access to an object (not an instance, * just the class itself!). It must be called before any of the object's * methods can be accessed. The MYLIB part is the name of my library, or NULL if * the caller is a core module. Using the right value here is important to get * the reference counting correct (object accesses from the same library must * not be counted because that would cause a library plugin to never unload, as * its ClassExit() entry points are only called if no object is referenced, which * would never happen as the library references itself. * rgerhards, 2008-03-11 */ #define CORE_COMPONENT NULL /* use this to indicate this is a core component */ #define DONT_LOAD_LIB NULL /* do not load a library to obtain object interface (currently same as CORE_COMPONENT) */ #define objUse(objName, FILENAME) obj.UseObj(__FILE__, (uchar *)#objName, (uchar *)FILENAME, (void *)&objName) #define objRelease(objName, FILENAME) obj.ReleaseObj(__FILE__, (uchar *)#objName, (uchar *)FILENAME, (void *)&objName) /* defines data that must always be present at the very begin of the interface structure */ #define ifBEGIN \ int ifVersion; /* must be set to version requested */ \ int ifIsLoaded; /* is the interface loaded? (0-no, 1-yes; if no, functions can NOT be called! */ /* use the following define some place in your static data (suggested right at * the beginning */ #define DEFobjCurrIf(obj) static obj##_if_t obj = {.ifVersion = obj##CURR_IF_VERSION, .ifIsLoaded = 0}; /* define the prototypes for a class - when we use interfaces, we just have few * functions that actually need to be non-static. */ #define PROTOTYPEObj(obj) \ PROTOTYPEObjClassInit(obj); \ PROTOTYPEObjClassExit(obj); \ PROTOTYPEObjQueryInterface(obj) /* ------------------------------ end object loader system ------------------------------ */ #include "modules.h" #endif /* #ifndef OBJ_TYPES_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/tcpsrv.h0000644000000000000000000000013115114522477015715 xustar0029 mtime=1764926783.04263203 30 atime=1764926784.239661412 30 ctime=1764935923.412580087 rsyslog-8.2512.0/runtime/tcpsrv.h0000664000175000017500000003564215114522477015374 0ustar00rgerrger/* Definitions for tcpsrv class. * * Copyright 2008-2025 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_TCPSRV_H #define INCLUDED_TCPSRV_H #if defined(ENABLE_IMTCP_EPOLL) && defined(HAVE_SYS_EPOLL_H) #include #endif #include "obj.h" #include "prop.h" #include "net.h" #include "tcps_sess.h" #include "statsobj.h" /* support for framing anomalies */ typedef enum ETCPsyslogFramingAnomaly { frame_normal = 0, frame_NetScreen = 1, frame_CiscoIOS = 2 } eTCPsyslogFramingAnomaly; /* config parameters for TCP listeners */ struct tcpLstnParams_s { const uchar *pszPort; /**< the ports the listener shall listen on */ const uchar *pszAddr; /**< the addrs the listener shall listen on */ sbool bSuppOctetFram; /**< do we support octect-counted framing? (if no->legay only!)*/ sbool bSPFramingFix; /**< support work-around for broken Cisco ASA framing? */ sbool bPreserveCase; /**< preserve case in fromhost */ const uchar *pszLstnPortFileName; /**< File in which the dynamic port is written */ char *pszNetworkNamespace; /**< network namespace to use */ uchar *pszStrmDrvrName; /**< stream driver to use */ uchar *pszInputName; /**< value to be used as input name */ prop_t *pInputName; ruleset_t *pRuleset; /**< associated ruleset */ uchar dfltTZ[8]; /**< default TZ if none in timestamp; '\0' =No Default */ }; /* list of tcp listen ports */ struct tcpLstnPortList_s { tcpLstnParams_t *cnf_params; /**< listener config parameters */ tcpsrv_t *pSrv; /**< pointer to higher-level server instance */ statsobj_t *stats; /**< associated stats object */ ratelimit_t *ratelimiter; STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) tcpLstnPortList_t *pNext; /**< next port or NULL */ }; typedef struct tcpsrvWrkrData_s { statsobj_t *stats; STATSCOUNTER_DEF(ctrRuns, mutCtrRuns); STATSCOUNTER_DEF(ctrRead, mutCtrRead); STATSCOUNTER_DEF(ctrEmptyRead, mutCtrEmptyRead); STATSCOUNTER_DEF(ctrStarvation, mutCtrStarvation); STATSCOUNTER_DEF(ctrAccept, mutCtrAccept); } tcpsrvWrkrData_t; typedef struct workQueue_s { tcpsrv_io_descr_t *head; tcpsrv_io_descr_t *tail; pthread_mutex_t mut; pthread_cond_t workRdy; unsigned numWrkr; /* how many workers to spawn */ pthread_t *wrkr_tids; /* array of thread IDs */ tcpsrvWrkrData_t *wrkr_data; } workQueue_t; /** * The following structure is a descriptor for tcpsrv i/o. It is * primarily used together with epoll at the moment. */ struct tcpsrv_io_descr_s { int id; /* index into listener or session table, depending on ptrType */ int sock; /* socket descriptor we need to "monitor" */ unsigned ioDirection; enum { NSD_PTR_TYPE_LSTN, NSD_PTR_TYPE_SESS } ptrType; union { tcps_sess_t *pSess; netstrm_t **ppLstn; /**< accept listener's netstream */ } ptr; int isInError; /* boolean, if set, subsystem indicates we need to close because we had an * unrecoverable error at the network layer. */ tcpsrv_t *pSrv; /* our server object */ tcpsrv_io_descr_t *next; /* for use in workQueue_t */ #if defined(ENABLE_IMTCP_EPOLL) struct epoll_event event; /* to re-enable EPOLLONESHOT */ #endif DEF_ATOMIC_HELPER_MUT(mut_isInError); }; #define TCPSRV_NO_ADDTL_DELIMITER -1 /* specifies that no additional delimiter is to be used in TCP framing */ /* the tcpsrv object */ struct tcpsrv_s { BEGINobjInstance ; /**< Data to implement generic object - MUST be the first data element! */ int bUseKeepAlive; /**< use socket layer KEEPALIVE handling? */ int iKeepAliveIntvl; /**< socket layer KEEPALIVE interval */ int iKeepAliveProbes; /**< socket layer KEEPALIVE probes */ int iKeepAliveTime; /**< socket layer KEEPALIVE timeout */ netstrms_t *pNS; /**< pointer to network stream subsystem */ int iDrvrMode; /**< mode of the stream driver to use */ int DrvrChkExtendedKeyUsage; /**< if true, verify extended key usage in certs */ int DrvrPrioritizeSan; /**< if true, perform stricter checking of names in certs */ int DrvrTlsVerifyDepth; /**< Verify Depth for certificate chains */ uchar *gnutlsPriorityString; /**< priority string for gnutls */ uchar *pszLstnPortFileName; /**< File in which the dynamic port is written */ uchar *pszDrvrAuthMode; /**< auth mode of the stream driver to use */ uchar *pszDrvrPermitExpiredCerts; /**< current driver setting for handlign expired certs */ uchar *pszDrvrCAFile; uchar *pszDrvrCRLFile; uchar *pszDrvrKeyFile; uchar *pszDrvrCertFile; uchar *pszDrvrName; /**< name of stream driver to use */ uchar *pszInputName; /**< value to be used as input name */ uchar *pszOrigin; /**< module to be used as "origin" (e.g. for pstats) */ ruleset_t *pRuleset; /**< ruleset to bind to */ permittedPeers_t *pPermPeers; /**< driver's permitted peers */ sbool bEmitMsgOnClose; /**< emit an informational message when the remote peer closes connection */ sbool bEmitMsgOnOpen; sbool bUseFlowControl; /**< use flow control (make light delayable) */ sbool bSPFramingFix; /**< support work-around for broken Cisco ASA framing? */ int iLstnCurr; /**< max nbr of listeners currently supported */ netstrm_t **ppLstn; /**< our netstream listeners */ /* We could use conditional compilation, but that causes more complexity and is (proofen causing errors) */ union { struct { int efd; } epoll; struct { uint32_t maxfds; uint32_t currfds; struct pollfd *fds; } poll; } evtdata; tcpLstnPortList_t **ppLstnPort; /**< pointer to relevant listen port description */ tcpsrv_io_descr_t **ppioDescrPtr; /**< pointer to i/o descriptor object */ int iLstnMax; /**< max number of listeners supported */ int iSessMax; /**< max number of sessions supported */ uchar dfltTZ[8]; /**< default TZ if none in timestamp; '\0' =No Default */ tcpLstnPortList_t *pLstnPorts; /**< head pointer for listen ports */ int addtlFrameDelim; /**< additional frame delimiter for plain TCP syslog framing (e.g. to handle NetScreen) */ int maxFrameSize; /**< max frame size for octet counted*/ int bDisableLFDelim; /**< if 1, standard LF frame delimiter is disabled (*very dangerous*) */ int discardTruncatedMsg; /**< discard msg part that has been truncated*/ sbool bPreserveCase; /**< preserve case in fromhost */ int iSynBacklog; unsigned int ratelimitInterval; unsigned int ratelimitBurst; tcps_sess_t **pSessions; /**< array of all of our sessions */ unsigned int starvationMaxReads; void *pUsr; /**< a user-settable pointer (provides extensibility for "derived classes")*/ /* callbacks */ int (*pIsPermittedHost)(struct sockaddr *addr, char *fromHostFQDN, void *pUsrSrv, void *pUsrSess); rsRetVal (*pRcvData)(tcps_sess_t *, char *, size_t, ssize_t *, int *, unsigned *); rsRetVal (*OpenLstnSocks)(struct tcpsrv_s *); rsRetVal (*pOnListenDeinit)(void *); rsRetVal (*OnDestruct)(void *); rsRetVal (*pOnRegularClose)(tcps_sess_t *pSess); rsRetVal (*pOnErrClose)(tcps_sess_t *pSess); /* session specific callbacks */ rsRetVal (*pOnSessAccept)(tcpsrv_t *, tcps_sess_t *, char *connInfo); #define TCPSRV_CONNINFO_SIZE (2 * (INET_ADDRSTRLEN + 20)) rsRetVal (*OnSessConstructFinalize)(void *); rsRetVal (*pOnSessDestruct)(void *); rsRetVal (*OnMsgReceive)(tcps_sess_t *, uchar *pszMsg, int iLenMsg); /* submit message callback */ /* work queue */ workQueue_t workQueue; int currWrkrs; }; /** */ struct tcpsrv_workset_s { int idx; /**< index into session table (or -1 if listener) */ void *pUsr; }; /* interfaces */ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(tcpsrv); rsRetVal (*Construct)(tcpsrv_t **ppThis); rsRetVal (*ConstructFinalize)(tcpsrv_t __attribute__((unused)) * pThis); rsRetVal (*Destruct)(tcpsrv_t **ppThis); rsRetVal (*ATTR_NONNULL(1, 2) configureTCPListen)(tcpsrv_t *, tcpLstnParams_t *const cnf_params); rsRetVal (*create_tcp_socket)(tcpsrv_t *pThis); rsRetVal (*Run)(tcpsrv_t *pThis); /* set methods */ rsRetVal (*SetAddtlFrameDelim)(tcpsrv_t *, int); rsRetVal (*SetMaxFrameSize)(tcpsrv_t *, int); rsRetVal (*SetInputName)(tcpsrv_t *const pThis, tcpLstnParams_t *const cnf_params, const uchar *const name); rsRetVal (*SetUsrP)(tcpsrv_t *, void *); rsRetVal (*SetCBIsPermittedHost)(tcpsrv_t *, int (*)(struct sockaddr *addr, char *, void *, void *)); rsRetVal (*SetCBOpenLstnSocks)(tcpsrv_t *, rsRetVal (*)(tcpsrv_t *)); rsRetVal (*SetCBRcvData)(tcpsrv_t *pThis, rsRetVal (*pRcvData)(tcps_sess_t *, char *, size_t, ssize_t *, int *, unsigned *)); rsRetVal (*SetCBOnListenDeinit)(tcpsrv_t *, rsRetVal (*)(void *)); rsRetVal (*SetCBOnDestruct)(tcpsrv_t *, rsRetVal (*)(void *)); rsRetVal (*SetCBOnRegularClose)(tcpsrv_t *, rsRetVal (*)(tcps_sess_t *)); rsRetVal (*SetCBOnErrClose)(tcpsrv_t *, rsRetVal (*)(tcps_sess_t *)); rsRetVal (*SetDrvrMode)(tcpsrv_t *pThis, int iMode); rsRetVal (*SetDrvrAuthMode)(tcpsrv_t *pThis, uchar *pszMode); rsRetVal (*SetDrvrPermitExpiredCerts)(tcpsrv_t *pThis, uchar *pszMode); rsRetVal (*SetDrvrPermPeers)(tcpsrv_t *pThis, permittedPeers_t *); /* session specifics */ rsRetVal (*SetCBOnSessAccept)(tcpsrv_t *, rsRetVal (*)(tcpsrv_t *, tcps_sess_t *, char *)); rsRetVal (*SetCBOnSessDestruct)(tcpsrv_t *, rsRetVal (*)(void *)); rsRetVal (*SetCBOnSessConstructFinalize)(tcpsrv_t *, rsRetVal (*)(void *)); /* added v5 */ rsRetVal (*SetSessMax)(tcpsrv_t *pThis, int iMaxSess); /* 2009-04-09 */ /* added v6 */ rsRetVal (*SetOnMsgReceive)(tcpsrv_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t *, uchar *, int)); /* 2009-05-24 */ rsRetVal (*SetRuleset)(tcpsrv_t *pThis, ruleset_t *); /* 2009-06-12 */ /* added v7 (accidently named v8!) */ rsRetVal (*SetLstnMax)(tcpsrv_t *pThis, int iMaxLstn); /* 2009-08-17 */ rsRetVal (*SetNotificationOnRemoteClose)(tcpsrv_t *pThis, int bNewVal); /* 2009-10-01 */ rsRetVal (*SetNotificationOnRemoteOpen)(tcpsrv_t *pThis, int bNewVal); /* 2022-08-23 */ /* added v9 -- rgerhards, 2010-03-01 */ rsRetVal (*SetbDisableLFDelim)(tcpsrv_t *, int); /* added v10 -- rgerhards, 2011-04-01 */ rsRetVal (*SetDiscardTruncatedMsg)(tcpsrv_t *, int); rsRetVal (*SetUseFlowControl)(tcpsrv_t *, int); /* added v11 -- rgerhards, 2011-05-09 */ rsRetVal (*SetKeepAlive)(tcpsrv_t *, int); /* added v13 -- rgerhards, 2012-10-15 */ rsRetVal (*SetLinuxLikeRatelimiters)(tcpsrv_t *pThis, unsigned int interval, unsigned int burst); /* added v14 -- rgerhards, 2013-07-28 */ rsRetVal (*SetDfltTZ)(tcpsrv_t *pThis, uchar *dfltTZ); /* added v15 -- rgerhards, 2013-09-17 */ rsRetVal (*SetDrvrName)(tcpsrv_t *pThis, uchar *pszName); /* added v16 -- rgerhards, 2014-09-08 */ rsRetVal (*SetOrigin)(tcpsrv_t *, uchar *); /* added v17 */ rsRetVal (*SetKeepAliveIntvl)(tcpsrv_t *, int); rsRetVal (*SetKeepAliveProbes)(tcpsrv_t *, int); rsRetVal (*SetKeepAliveTime)(tcpsrv_t *, int); /* added v18 */ rsRetVal (*SetbSPFramingFix)(tcpsrv_t *, sbool); /* added v19 -- PascalWithopf, 2017-08-08 */ rsRetVal (*SetGnutlsPriorityString)(tcpsrv_t *, uchar *); /* added v21 -- Preserve case in fromhost, 2018-08-16 */ rsRetVal (*SetPreserveCase)(tcpsrv_t *pThis, int bPreserveCase); /* added v23 -- Options for stricter driver behavior, 2019-08-16 */ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(tcpsrv_t *pThis, int ChkExtendedKeyUsage); rsRetVal (*SetDrvrPrioritizeSAN)(tcpsrv_t *pThis, int prioritizeSan); /* added v24 -- Options for TLS verify depth driver behavior, 2019-12-20 */ rsRetVal (*SetDrvrTlsVerifyDepth)(tcpsrv_t *pThis, int verifyDepth); /* added v25 -- Options for TLS certificates, 2021-07-19 */ rsRetVal (*SetDrvrCAFile)(tcpsrv_t *pThis, uchar *pszMode); rsRetVal (*SetDrvrKeyFile)(tcpsrv_t *pThis, uchar *pszMode); rsRetVal (*SetDrvrCertFile)(tcpsrv_t *pThis, uchar *pszMode); /* added v26 -- Options for TLS CRL file */ rsRetVal (*SetDrvrCRLFile)(tcpsrv_t *pThis, uchar *pszMode); /* added v27 -- sync backlog for listen() */ rsRetVal (*SetSynBacklog)(tcpsrv_t *pThis, int); /* added v28 */ rsRetVal (*SetNumWrkr)(tcpsrv_t *pThis, int); rsRetVal (*SetStarvationMaxReads)(tcpsrv_t *pThis, unsigned int); /* added v29 */ /* * @brief Set the Network Namespace into the listener parameters * @param pThis The associated TCP Server instance * @param cnf_params The listener parameters to configure * @param networkNamespace The namespace parameter to set into the * listener configuration parameters * @return RS_RET_OK on success, otherwise a failure code. * @details For platforms that do not support network namespaces, * this function should fail for any non-null and non-empty * namespace passed. Note that the empty string is treated * the same as a NULL, i.e. you are not allowed to actually * use a network namespace with the empty string. So both * a NULL and an empty string "" both mean to use the * original startup network namespace. */ rsRetVal (*SetNetworkNamespace)(tcpsrv_t *pThis, tcpLstnParams_t *const cnf_params, const char *const networkNamespace); ENDinterface(tcpsrv) #define tcpsrvCURR_IF_VERSION 29 /* increment whenever you change the interface structure! */ /* change for v4: * - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10 * - SetInputName() added -- rgerhards, 2008-12-10 * change for v5 and up: see above * for v12: param bSuppOctetFram added to configureTCPListen * for v20: add oserr to setCBRcvData signature -- rgerhards, 2017-09-04 */ /* prototypes */ PROTOTYPEObj(tcpsrv); /* the name of our library binary */ #define LM_TCPSRV_FILENAME "lmtcpsrv" #endif /* #ifndef INCLUDED_TCPSRV_H */ rsyslog-8.2512.0/runtime/PaxHeaders/stream.c0000644000000000000000000000013215055605325015661 xustar0030 mtime=1756826325.653800744 30 atime=1764930992.619888616 30 ctime=1764935923.234577361 rsyslog-8.2512.0/runtime/stream.c0000664000175000017500000025737115055605325015344 0ustar00rgerrger/* The serial stream class. * * A serial stream provides serial data access. In theory, serial streams * can be implemented via a number of methods (e.g. files or in-memory * streams). In practice, there currently only exist the file type (aka * "driver"). * * File begun on 2008-01-09 by RGerhards * Large modifications in 2009-06 to support using it with omfile, including zip writer. * Note that this file obtains the zlib wrapper object is needed, but it never frees it * again. While this sounds like a leak (and one may argue it actually is), there is no * harm associated with that. The reason is that strm is a core object, so it is terminated * only when rsyslogd exists. As we could only release on termination (or else bear more * overhead for keeping track of how many users we have), not releasing zlibw is OK, because * it will be released when rsyslogd terminates. We may want to revisit this decision if * it turns out to be problematic. Then, we need to quasi-refcount the number of accesses * to the object. * * Copyright 2008-2022 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include /* required for HP UX */ #include #include #include #ifdef HAVE_SYS_PRCTL_H #include #endif #include "rsyslog.h" #include "stringbuf.h" #include "srUtils.h" #include "obj.h" #include "stream.h" #include "unicode-helper.h" #include "module-template.h" #include "errmsg.h" #include "zstdw.h" #include "cryprov.h" #include "datetime.h" #include "rsconf.h" /* some platforms do not have large file support :( */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif #ifndef HAVE_LSEEK64 #define lseek64(fd, offset, whence) lseek(fd, offset, whence) #endif /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(zlibw) DEFobjCurrIf(zstdw) /* forward definitions */ static rsRetVal strmFlushInternal(strm_t *pThis, int bFlushZip); static rsRetVal strmWrite(strm_t *__restrict__ const pThis, const uchar *__restrict__ const pBuf, const size_t lenBuf); static rsRetVal strmOpenFile(strm_t *pThis); static rsRetVal strmCloseFile(strm_t *pThis); static void *asyncWriterThread(void *pPtr); static rsRetVal doZipWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf, int bFlush); static rsRetVal doZipFinish(strm_t *pThis); static rsRetVal strmPhysWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf); static rsRetVal strmSeekCurrOffs(strm_t *pThis); /* methods */ /* note: this may return NULL if not line segment is currently set */ // TODO: due to the cstrFinalize() this is not totally clean, albeit for our // current use case it does not hurt -- refactor! rgerhards, 2018-03-27 const uchar *ATTR_NONNULL() strmGetPrevLineSegment(strm_t *const pThis) { const uchar *ret = NULL; if (pThis->prevLineSegment != NULL) { cstrFinalize(pThis->prevLineSegment); ret = rsCStrGetSzStrNoNULL(pThis->prevLineSegment); } return ret; } /* note: this may return NULL if not line segment is currently set */ // TODO: due to the cstrFinalize() this is not totally clean, albeit for our // current use case it does not hurt -- refactor! rgerhards, 2018-03-27 const uchar *ATTR_NONNULL() strmGetPrevMsgSegment(strm_t *const pThis) { const uchar *ret = NULL; if (pThis->prevMsgSegment != NULL) { cstrFinalize(pThis->prevMsgSegment); ret = rsCStrGetSzStrNoNULL(pThis->prevMsgSegment); } return ret; } int ATTR_NONNULL() strmGetPrevWasNL(const strm_t *const pThis) { return pThis->bPrevWasNL; } /* output (current) file name for debug log purposes. Falls back to various * levels of impreciseness if more precise name is not known. */ static const char *getFileDebugName(const strm_t *const pThis) { return (pThis->pszCurrFName == NULL) ? ((pThis->pszFName == NULL) ? "N/A" : (char *)pThis->pszFName) : (const char *)pThis->pszCurrFName; } /* Try to resolve a size limit situation. This is used to support custom-file size handlers * for omfile. It first runs the command, and then checks if we are still above the size * treshold. Note that this works only with single file names, NOT with circular names. * Note that pszCurrFName can NOT be taken from pThis, because the stream is closed when * we are called (and that destroys pszCurrFName, as there is NO CURRENT file name!). So * we need to receive the name as a parameter. * initially wirtten 2005-06-21, moved to this class & updates 2009-06-01, both rgerhards */ static rsRetVal resolveFileSizeLimit(strm_t *pThis, uchar *pszCurrFName) { uchar *pParams; uchar *pCmd; uchar *p; off_t actualFileSize; rsRetVal localRet; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); assert(pszCurrFName != NULL); if (pThis->pszSizeLimitCmd == NULL) { ABORT_FINALIZE(RS_RET_NON_SIZELIMITCMD); /* nothing we can do in this case... */ } /* we first check if we have command line parameters. We assume this, * when we have a space in the program name. If we find it, everything after * the space is treated as a single argument. */ CHKmalloc(pCmd = ustrdup(pThis->pszSizeLimitCmd)); for (p = pCmd; *p && *p != ' '; ++p) { /* JUST SKIP */ } if (*p == ' ') { *p = '\0'; /* pretend string-end */ pParams = p + 1; } else pParams = NULL; /* the execProg() below is probably not great, but at least is is * fairly secure now. Once we change the way file size limits are * handled, we should also revisit how this command is run (and * with which parameters). rgerhards, 2007-07-20 */ execProg(pCmd, 1, pParams); free(pCmd); localRet = getFileSize(pszCurrFName, &actualFileSize); if (localRet == RS_RET_OK && actualFileSize >= pThis->iSizeLimit) { ABORT_FINALIZE(RS_RET_SIZELIMITCMD_DIDNT_RESOLVE); /* OK, it didn't work out... */ } else if (localRet != RS_RET_FILE_NOT_FOUND) { /* file not found is OK, the command may have moved away the file */ ABORT_FINALIZE(localRet); } finalize_it: if (iRet != RS_RET_OK) { if (iRet == RS_RET_SIZELIMITCMD_DIDNT_RESOLVE) { LogError(0, RS_RET_ERR, "file size limit cmd for file '%s' " "did no resolve situation\n", pszCurrFName); } else { LogError(0, RS_RET_ERR, "file size limit cmd for file '%s' " "failed with code %d.\n", pszCurrFName, iRet); } pThis->bDisabled = 1; } RETiRet; } /* Check if the file has grown beyond the configured omfile iSizeLimit * and, if so, initiate processing. */ static rsRetVal doSizeLimitProcessing(strm_t *pThis) { uchar *pszCurrFName = NULL; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); assert(pThis->iSizeLimit != 0); assert(pThis->fd != -1); if (pThis->iCurrOffs >= pThis->iSizeLimit) { /* strmCloseFile() destroys the current file name, so we * need to preserve it. */ CHKmalloc(pszCurrFName = ustrdup(pThis->pszCurrFName)); CHKiRet(strmCloseFile(pThis)); CHKiRet(resolveFileSizeLimit(pThis, pszCurrFName)); } finalize_it: free(pszCurrFName); RETiRet; } /* now, we define type-specific handlers. The provide a generic functionality, * but for this specific type of strm. The mapping to these handlers happens during * strm construction. Later on, handlers are called by pointers present in the * strm instance object. */ /* do the physical open() call on a file. */ static rsRetVal doPhysOpen(strm_t *pThis) { int iFlags = 0; struct stat statOpen; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); /* compute which flags we need to provide to open */ switch (pThis->tOperationsMode) { case STREAMMODE_READ: iFlags = O_CLOEXEC | O_NOCTTY | O_RDONLY; break; case STREAMMODE_WRITE: /* legacy mode used inside queue engine */ iFlags = O_CLOEXEC | O_NOCTTY | O_WRONLY | O_CREAT; break; case STREAMMODE_WRITE_TRUNC: iFlags = O_CLOEXEC | O_NOCTTY | O_WRONLY | O_CREAT | O_TRUNC; break; case STREAMMODE_WRITE_APPEND: iFlags = O_CLOEXEC | O_NOCTTY | O_WRONLY | O_CREAT | O_APPEND; break; case STREAMMMODE_INVALID: default: assert(0); break; } if (pThis->sType == STREAMTYPE_NAMED_PIPE) { DBGPRINTF("Note: stream '%s' is a named pipe, open with O_NONBLOCK\n", pThis->pszCurrFName); iFlags |= O_NONBLOCK; } if (pThis->bAsyncWrite) d_pthread_mutex_lock(&pThis->mut); pThis->fd = open((char *)pThis->pszCurrFName, iFlags | O_LARGEFILE, pThis->tOpenMode); if (pThis->bAsyncWrite) d_pthread_mutex_unlock(&pThis->mut); const int errno_save = errno; /* dbgprintf can mangle it! */ DBGPRINTF("file '%s' opened as #%d with mode %d\n", pThis->pszCurrFName, pThis->fd, (int)pThis->tOpenMode); if (pThis->fd == -1) { const rsRetVal errcode = (errno_save == ENOENT) ? RS_RET_FILE_NOT_FOUND : RS_RET_FILE_OPEN_ERROR; if (pThis->fileNotFoundError) { if (pThis->noRepeatedErrorOutput == 0) { LogError(errno_save, errcode, "file '%s': open error", pThis->pszCurrFName); pThis->noRepeatedErrorOutput = 1; } } else { DBGPRINTF("file '%s': open error", pThis->pszCurrFName); } ABORT_FINALIZE(errcode); } else { pThis->noRepeatedErrorOutput = 0; } if (pThis->tOperationsMode == STREAMMODE_READ) { if (fstat(pThis->fd, &statOpen) == -1) { DBGPRINTF("Error: cannot obtain inode# for file %s\n", pThis->pszCurrFName); ABORT_FINALIZE(RS_RET_IO_ERROR); } pThis->inode = statOpen.st_ino; } if (!ustrcmp(pThis->pszCurrFName, UCHAR_CONSTANT(_PATH_CONSOLE)) || isatty(pThis->fd)) { DBGPRINTF("file %d is a tty-type file\n", pThis->fd); pThis->bIsTTY = 1; } else { pThis->bIsTTY = 0; } if (pThis->cryprov != NULL) { CHKiRet(pThis->cryprov->OnFileOpen(pThis->cryprovData, pThis->pszCurrFName, &pThis->cryprovFileData, (pThis->tOperationsMode == STREAMMODE_READ) ? 'r' : 'w')); pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose); } finalize_it: RETiRet; } static rsRetVal strmSetCurrFName(strm_t *pThis) { DEFiRet; if (pThis->sType == STREAMTYPE_FILE_CIRCULAR) { CHKiRet(genFileName(&pThis->pszCurrFName, pThis->pszDir, pThis->lenDir, pThis->pszFName, pThis->lenFName, pThis->iCurrFNum, pThis->iFileNumDigits)); } else { if (pThis->pszDir == NULL) { if ((pThis->pszCurrFName = ustrdup(pThis->pszFName)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } else { CHKiRet(genFileName(&pThis->pszCurrFName, pThis->pszDir, pThis->lenDir, pThis->pszFName, pThis->lenFName, -1, 0)); } } finalize_it: RETiRet; } /* This function checks if the actual file has changed and, if so, resets the * offset. This is support for monitoring files. It should be called after * deserializing the strm object and before doing any other operation on it * (most importantly not an open or seek!). */ static rsRetVal CheckFileChange(strm_t *pThis) { struct stat statName; DEFiRet; CHKiRet(strmSetCurrFName(pThis)); if (stat((char *)pThis->pszCurrFName, &statName) == -1) ABORT_FINALIZE(RS_RET_IO_ERROR); DBGPRINTF( "CheckFileChange: stream/after deserialize checking for file change " "on '%s', inode %u/%u, size/currOffs %llu/%llu\n", pThis->pszCurrFName, (unsigned)pThis->inode, (unsigned)statName.st_ino, (long long unsigned)statName.st_size, (long long unsigned)pThis->iCurrOffs); if (pThis->inode != statName.st_ino || statName.st_size < pThis->iCurrOffs) { DBGPRINTF("stream: file %s has changed\n", pThis->pszCurrFName); pThis->iCurrOffs = 0; } finalize_it: RETiRet; } /* open a strm file * It is OK to call this function when the stream is already open. In that * case, it returns immediately with RS_RET_OK */ static rsRetVal strmOpenFile(strm_t *pThis) { DEFiRet; off_t offset; assert(pThis != NULL); if (pThis->fd != -1) ABORT_FINALIZE(RS_RET_OK); free(pThis->pszCurrFName); pThis->pszCurrFName = NULL; /* used to prevent mem leak in case of error */ if (pThis->pszFName == NULL) ABORT_FINALIZE(RS_RET_FILE_PREFIX_MISSING); CHKiRet(strmSetCurrFName(pThis)); CHKiRet(doPhysOpen(pThis)); pThis->iCurrOffs = 0; pThis->iBufPtrMax = 0; CHKiRet(getFileSize(pThis->pszCurrFName, &offset)); if (pThis->tOperationsMode == STREAMMODE_WRITE_APPEND) { pThis->iCurrOffs = offset; } else if (pThis->tOperationsMode == STREAMMODE_WRITE_TRUNC) { if (offset != 0) { LogError(0, 0, "file '%s' opened for truncate write, but " "already contains %zd bytes\n", pThis->pszCurrFName, (ssize_t)offset); } } DBGOPRINT((obj_t *)pThis, "opened file '%s' for %s as %d\n", pThis->pszCurrFName, (pThis->tOperationsMode == STREAMMODE_READ) ? "READ" : "WRITE", pThis->fd); finalize_it: if (iRet == RS_RET_OK) { assert(pThis->fd != -1); } else { if (pThis->pszCurrFName != NULL) { free(pThis->pszCurrFName); pThis->pszCurrFName = NULL; /* just to prevent mis-adressing down the road... */ } if (pThis->fd != -1) { close(pThis->fd); pThis->fd = -1; } } RETiRet; } /* wait for the output writer thread to be done. This must be called before actions * that require data to be persisted. May be called in non-async mode and is a null * operation than. Must be called with the mutex locked. */ static void strmWaitAsyncWriterDone(strm_t *pThis) { if (pThis->bAsyncWrite) { /* awake writer thread and make it write out everything */ while (pThis->iCnt > 0) { pthread_cond_signal(&pThis->notEmpty); d_pthread_cond_wait(&pThis->isEmpty, &pThis->mut); } } } /* stop the writer thread (we MUST be runnnig asynchronously when this method * is called!). Note that the mutex must be locked! -- rgerhards, 2009-07-06 */ static void stopWriter(strm_t *const pThis) { pThis->bStopWriter = 1; pthread_cond_signal(&pThis->notEmpty); d_pthread_mutex_unlock(&pThis->mut); pthread_join(pThis->writerThreadID, NULL); } /* close a strm file * Note that the bDeleteOnClose flag is honored. If it is set, the file will be * deleted after close. This is in support for the qRead thread. * Note: it is valid to call this function when the physical file is closed. If so, * strmCloseFile() will still check if there is any unwritten data inside buffers * (this may be the case) and, if so, will open the file, write the data, and then * close it again (this is done via strmFlushInternal and friends). */ static rsRetVal strmCloseFile(strm_t *pThis) { off64_t currOffs; DEFiRet; assert(pThis != NULL); DBGOPRINT((obj_t *)pThis, "file %d(%s) closing, bDeleteOnClose %d\n", pThis->fd, getFileDebugName(pThis), pThis->bDeleteOnClose); if (pThis->tOperationsMode != STREAMMODE_READ) { if (pThis->bAsyncWrite) { strmWaitAsyncWriterDone(pThis); } strmFlushInternal(pThis, 0); if (pThis->iZipLevel) { doZipFinish(pThis); } if (pThis->bAsyncWrite) { stopWriter(pThis); } } /* if we have a signature provider, we must make sure that the crypto * state files are opened and proper close processing happens. */ if (pThis->cryprov != NULL && pThis->fd == -1) { const rsRetVal localRet = strmOpenFile(pThis); if (localRet != RS_RET_OK) { LogError(0, localRet, "could not open file %s, this " "may result in problems with encryption - " "unfortunately, we cannot do anything against " "this.", pThis->pszCurrFName); } } /* the file may already be closed (or never have opened), so guard * against this. -- rgerhards, 2010-03-19 */ if (pThis->fd != -1) { DBGOPRINT((obj_t *)pThis, "file %d(%s) closing\n", pThis->fd, getFileDebugName(pThis)); currOffs = lseek64(pThis->fd, 0, SEEK_CUR); close(pThis->fd); pThis->fd = -1; pThis->inode = 0; if (pThis->cryprov != NULL) { pThis->cryprov->OnFileClose(pThis->cryprovFileData, currOffs); pThis->cryprovFileData = NULL; } } if (pThis->fdDir != -1) { /* close associated directory handle, if it is open */ close(pThis->fdDir); pThis->fdDir = -1; } if (pThis->bDeleteOnClose) { if (pThis->pszCurrFName == NULL) { CHKiRet(genFileName(&pThis->pszCurrFName, pThis->pszDir, pThis->lenDir, pThis->pszFName, pThis->lenFName, pThis->iCurrFNum, pThis->iFileNumDigits)); } DBGPRINTF("strmCloseFile: deleting '%s'\n", pThis->pszCurrFName); if (unlink((char *)pThis->pszCurrFName) == -1) { char errStr[1024]; int err = errno; rs_strerror_r(err, errStr, sizeof(errStr)); DBGPRINTF("error %d unlinking '%s' - ignored: %s\n", errno, pThis->pszCurrFName, errStr); } } pThis->iCurrOffs = 0; /* we are back at begin of file */ finalize_it: free(pThis->pszCurrFName); pThis->pszCurrFName = NULL; RETiRet; } /* switch to next strm file * This method must only be called if we are in a multi-file mode! */ static rsRetVal strmNextFile(strm_t *pThis) { DEFiRet; assert(pThis != NULL); assert(pThis->sType == STREAMTYPE_FILE_CIRCULAR); assert(pThis->iMaxFiles != 0); assert(pThis->fd != -1); CHKiRet(strmCloseFile(pThis)); /* we do modulo operation to ensure we obey the iMaxFile property. This will always * result in a file number lower than iMaxFile, so it if wraps, the name is back to * 0, which results in the first file being overwritten. Not desired for queues, so * make sure their iMaxFiles is large enough. But it is well-desired for other * use cases, e.g. a circular output log file. -- rgerhards, 2008-01-10 */ pThis->iCurrFNum = (pThis->iCurrFNum + 1) % pThis->iMaxFiles; finalize_it: RETiRet; } /* handle the EOF case of a stream * The EOF case is somewhat complicated, as the proper action depends on the * mode the stream is in. If there are multiple files (circular logs, most * important use case is queue files!), we need to close the current file and * try to open the next one. * rgerhards, 2008-02-13 */ static rsRetVal ATTR_NONNULL() strmHandleEOF(strm_t *const pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); switch (pThis->sType) { case STREAMTYPE_FILE_SINGLE: case STREAMTYPE_NAMED_PIPE: ABORT_FINALIZE(RS_RET_EOF); break; case STREAMTYPE_FILE_CIRCULAR: /* we have multiple files and need to switch to the next one */ /* TODO: think about emulating EOF in this case (not yet needed) */ DBGOPRINT((obj_t *)pThis, "file %d EOF\n", pThis->fd); CHKiRet(strmNextFile(pThis)); break; case STREAMTYPE_FILE_MONITOR: DBGOPRINT((obj_t *)pThis, "file '%s' (%d) EOF, rotationCheck %d\n", pThis->pszCurrFName, pThis->fd, pThis->rotationCheck); DBGPRINTF("RGER: EOF!\n"); ABORT_FINALIZE(RS_RET_EOF); break; default: // No action needed for other cases break; } finalize_it: RETiRet; } /* helper to checkTruncation */ static rsRetVal ATTR_NONNULL() rereadTruncated(strm_t *const pThis, const int err_no, const char *const reason, const long long data) { DEFiRet; LogMsg(err_no, RS_RET_FILE_TRUNCATED, LOG_WARNING, "file '%s': truncation detected, " "(%s) - re-start reading from beginning (data %lld)", pThis->pszCurrFName, reason, data); DBGPRINTF("checkTruncation, file %s last buffer CHANGED\n", pThis->pszCurrFName); CHKiRet(strmCloseFile(pThis)); CHKiRet(strmOpenFile(pThis)); iRet = RS_RET_FILE_TRUNCATED; finalize_it: RETiRet; } /* helper to read: * Check if file has been truncated since last read and, if so, re-set reading * to begin of file. To detect truncation, we try to re-read the last block. * If that does not succeed or different data than from the original read is * returned, truncation is assumed. * NOTE: this function must be called only if truncation is enabled AND * when the previous read buffer still is valid (aka "before the next read"). * It is ok to call with a 0-size buffer, which we than assume as begin of * reading. In that case, no truncation will be detected. * rgerhards, 2018-09-20 */ static rsRetVal ATTR_NONNULL() checkTruncation(strm_t *const pThis) { DEFiRet; off64_t ret; assert(pThis->bReopenOnTruncate); assert(pThis->fd != -1); DBGPRINTF("checkTruncation, file %s, iBufPtrMax %zd\n", pThis->pszCurrFName, pThis->iBufPtrMax); if (pThis->iBufPtrMax == 0) { FINALIZE; } const off64_t backseek = -1 * (off64_t)pThis->iBufPtrMax; ret = lseek64(pThis->fd, backseek, SEEK_CUR); if (ret < 0) { iRet = rereadTruncated(pThis, errno, "cannot seek backward to begin of last block", backseek); FINALIZE; } const ssize_t lenRead = read(pThis->fd, pThis->pIOBuf_truncation, pThis->iBufPtrMax); if (lenRead != (ssize_t)pThis->iBufPtrMax) { iRet = rereadTruncated(pThis, errno, "last block could not be re-read", lenRead); FINALIZE; } if (!memcmp(pThis->pIOBuf_truncation, pThis->pIOBuf, pThis->iBufPtrMax)) { DBGPRINTF("checkTruncation, file %s last buffer unchanged\n", pThis->pszCurrFName); } else { iRet = rereadTruncated(pThis, errno, "last block data different", 0); } finalize_it: RETiRet; } /* read the next buffer from disk * rgerhards, 2008-02-13 */ static rsRetVal strmReadBuf(strm_t *pThis, int *padBytes) { DEFiRet; int bRun; long iLenRead; size_t actualDataLen; size_t toRead; ssize_t bytesLeft; ISOBJ_TYPE_assert(pThis, strm); /* We need to try read at least twice because we may run into EOF and need to switch files. */ bRun = 1; while (bRun) { /* first check if we need to (re)open the file. We may have switched to a new one in * circular mode or it may have been rewritten (rotated) if we monitor a file * rgerhards, 2008-02-13 */ CHKiRet(strmOpenFile(pThis)); if (pThis->cryprov == NULL) { toRead = pThis->sIOBufSize; } else { CHKiRet(pThis->cryprov->GetBytesLeftInBlock(pThis->cryprovFileData, &bytesLeft)); if (bytesLeft == -1 || bytesLeft > (ssize_t)pThis->sIOBufSize) { toRead = pThis->sIOBufSize; } else { toRead = (size_t)bytesLeft; } } if (pThis->bReopenOnTruncate) { rsRetVal localRet = checkTruncation(pThis); if (localRet == RS_RET_FILE_TRUNCATED) { continue; } CHKiRet(localRet); } iLenRead = read(pThis->fd, pThis->pIOBuf, toRead); DBGOPRINT((obj_t *)pThis, "file %d read %ld bytes\n", pThis->fd, iLenRead); DBGOPRINT((obj_t *)pThis, "file %d read %*s\n", pThis->fd, (unsigned)iLenRead, (char *)pThis->pIOBuf); /* end crypto */ if (iLenRead == 0) { CHKiRet(strmHandleEOF(pThis)); } else if (iLenRead < 0) ABORT_FINALIZE(RS_RET_IO_ERROR); else { /* good read */ /* here we place our crypto interface */ if (pThis->cryprov != NULL) { actualDataLen = iLenRead; pThis->cryprov->Decrypt(pThis->cryprovFileData, pThis->pIOBuf, &actualDataLen); *padBytes = iLenRead - actualDataLen; iLenRead = actualDataLen; DBGOPRINT((obj_t *)pThis, "encrypted file %d pad bytes %d, actual " "data %ld\n", pThis->fd, *padBytes, iLenRead); } else { *padBytes = 0; } pThis->iBufPtrMax = iLenRead; bRun = 0; /* exit loop */ } } /* if we reach this point, we had a good read */ pThis->iBufPtr = 0; finalize_it: RETiRet; } /* debug output of current buffer */ void strmDebugOutBuf(const strm_t *const pThis) { int strtIdx = pThis->iBufPtr - 50; if (strtIdx < 0) strtIdx = 0; DBGOPRINT((obj_t *)pThis, "strmRead ungetc %d, index %zd, max %zd, buf '%.*s', CURR: '%.*s'\n", pThis->iUngetC, pThis->iBufPtr, pThis->iBufPtrMax, (int)pThis->iBufPtrMax - strtIdx, pThis->pIOBuf + strtIdx, (int)(pThis->iBufPtrMax - pThis->iBufPtr), pThis->pIOBuf + pThis->iBufPtr); } /* logically "read" a character from a file. What actually happens is that * data is taken from the buffer. Only if the buffer is full, data is read * directly from file. In that case, a read is performed blockwise. * rgerhards, 2008-01-07 * NOTE: needs to be enhanced to support sticking with a strm entry (if not * deleted). */ static rsRetVal strmReadChar(strm_t *pThis, uchar *pC) { int padBytes = 0; /* in crypto mode, we may have some padding (non-data) bytes */ DEFiRet; assert(pThis != NULL); assert(pC != NULL); /* DEV debug only: DBGOPRINT((obj_t*) pThis, "strmRead index %zd, max %zd\n", pThis->iBufPtr, pThis->iBufPtrMax); */ if (pThis->iUngetC != -1) { /* do we have an "unread" char that we need to provide? */ *pC = pThis->iUngetC; ++pThis->iCurrOffs; /* one more octet read */ pThis->iUngetC = -1; ABORT_FINALIZE(RS_RET_OK); } /* do we need to obtain a new buffer? */ if (pThis->iBufPtr >= pThis->iBufPtrMax) { CHKiRet(strmReadBuf(pThis, &padBytes)); } pThis->iCurrOffs += padBytes; /* if we reach this point, we have data available in the buffer */ *pC = pThis->pIOBuf[pThis->iBufPtr++]; ++pThis->iCurrOffs; /* one more octet read */ finalize_it: RETiRet; } /* unget a single character just like ungetc(). As with that call, there is only a single * character buffering capability. * rgerhards, 2008-01-07 */ static rsRetVal strmUnreadChar(strm_t *pThis, uchar c) { assert(pThis != NULL); assert(pThis->iUngetC == -1); pThis->iUngetC = c; --pThis->iCurrOffs; /* one less octet read - NOTE: this can cause problems if we got a file change and immediately do an unread and the file is on a buffer boundary and the stream is then persisted. With the queue, this can not happen as an Unread is only done on record begin, which is never split accross files. For other cases we accept the very remote risk. -- rgerhards, 2008-01-12 */ return RS_RET_OK; } /* read a 'paragraph' from a strm file. * A paragraph may be terminated by a LF, by a LFLF, or by LF depending on the option set. * The termination LF characters are read, but are * not returned in the buffer (it is discared). The caller is responsible for * destruction of the returned CStr object! -- dlang 2010-12-13 * * Parameter mode controls legacy multi-line processing: * mode = 0 single line mode (equivalent to ReadLine) * mode = 1 LFLF mode (paragraph, blank line between entries) * mode = 2 LF mode, a log line starts at the beginning of * a line, but following lines that are indented are part of the same log entry */ static rsRetVal ATTR_NONNULL(1, 2) strmReadLine(strm_t *const pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF, const uchar *const escapeLFString, uint32_t trimLineOverBytes, int64 *const strtOffs) { uchar c; uchar finished; const int escapeLFString_len = (escapeLFString == NULL) ? 4 : strlen((char *)escapeLFString); DEFiRet; assert(pThis != NULL); assert(ppCStr != NULL); CHKiRet(cstrConstruct(ppCStr)); CHKiRet(strmReadChar(pThis, &c)); /* append previous message to current message if necessary */ if (pThis->prevLineSegment != NULL) { cstrFinalize(pThis->prevLineSegment); dbgprintf("readLine: have previous line segment: '%s'\n", rsCStrGetSzStrNoNULL(pThis->prevLineSegment)); CHKiRet(cstrAppendCStr(*ppCStr, pThis->prevLineSegment)); cstrDestruct(&pThis->prevLineSegment); } if (mode == 0) { while (c != '\n') { CHKiRet(cstrAppendChar(*ppCStr, c)); CHKiRet(strmReadChar(pThis, &c)); } if (trimLineOverBytes > 0 && (uint32_t)cstrLen(*ppCStr) > trimLineOverBytes) { /* Truncate long line at trimLineOverBytes position */ dbgprintf("Truncate long line at %u, mode %d\n", trimLineOverBytes, mode); rsCStrTruncate(*ppCStr, cstrLen(*ppCStr) - trimLineOverBytes); cstrAppendChar(*ppCStr, '\n'); } cstrFinalize(*ppCStr); } else if (mode == 1) { finished = 0; while (finished == 0) { if (c != '\n') { CHKiRet(cstrAppendChar(*ppCStr, c)); CHKiRet(strmReadChar(pThis, &c)); pThis->bPrevWasNL = 0; } else { if ((((*ppCStr)->iStrLen) > 0)) { if (pThis->bPrevWasNL && escapeLFString_len > 0) { rsCStrTruncate(*ppCStr, (bEscapeLF) ? escapeLFString_len : 1); /* remove the prior newline */ finished = 1; } else { if (bEscapeLF) { if (escapeLFString == NULL) { CHKiRet(rsCStrAppendStrWithLen(*ppCStr, (uchar *)"#012", sizeof("#012") - 1)); } else { CHKiRet(rsCStrAppendStrWithLen(*ppCStr, escapeLFString, escapeLFString_len)); } } else { CHKiRet(cstrAppendChar(*ppCStr, c)); } CHKiRet(strmReadChar(pThis, &c)); pThis->bPrevWasNL = 1; } } else { finished = 1; /* this is a blank line, a \n with nothing since the last complete record */ } } } cstrFinalize(*ppCStr); pThis->bPrevWasNL = 0; } else if (mode == 2) { /* indented follow-up lines */ finished = 0; while (finished == 0) { if ((*ppCStr)->iStrLen == 0) { if (c != '\n') { /* nothing in the buffer, and it's not a newline, add it to the buffer */ CHKiRet(cstrAppendChar(*ppCStr, c)); CHKiRet(strmReadChar(pThis, &c)); } else { finished = 1; /* this is a blank line, a \n with nothing since the last complete record */ } } else { if (pThis->bPrevWasNL) { if ((c == ' ') || (c == '\t')) { CHKiRet(cstrAppendChar(*ppCStr, c)); CHKiRet(strmReadChar(pThis, &c)); pThis->bPrevWasNL = 0; } else { /* clean things up by putting the character we just read back into * the input buffer and removing the LF character that is * currently at the * end of the output string */ CHKiRet(strmUnreadChar(pThis, c)); if (bEscapeLF && escapeLFString_len > 0) { rsCStrTruncate(*ppCStr, (bEscapeLF) ? escapeLFString_len : 1); } finished = 1; } } else { /* not the first character after a newline, add it to the buffer */ if (c == '\n') { pThis->bPrevWasNL = 1; if (bEscapeLF && escapeLFString_len > 0) { if (escapeLFString == NULL) { CHKiRet(rsCStrAppendStrWithLen(*ppCStr, (uchar *)"#012", sizeof("#012") - 1)); } else { CHKiRet(rsCStrAppendStrWithLen(*ppCStr, escapeLFString, escapeLFString_len)); } } else { CHKiRet(cstrAppendChar(*ppCStr, c)); } } else { CHKiRet(cstrAppendChar(*ppCStr, c)); } CHKiRet(strmReadChar(pThis, &c)); } } } if (trimLineOverBytes > 0 && (uint32_t)cstrLen(*ppCStr) > trimLineOverBytes) { /* Truncate long line at trimLineOverBytes position */ dbgprintf("Truncate long line at %u, mode %d\n", trimLineOverBytes, mode); rsCStrTruncate(*ppCStr, cstrLen(*ppCStr) - trimLineOverBytes); cstrAppendChar(*ppCStr, '\n'); } cstrFinalize(*ppCStr); pThis->bPrevWasNL = 0; } finalize_it: if (iRet == RS_RET_OK) { if (strtOffs != NULL) { *strtOffs = pThis->strtOffs; } pThis->strtOffs = pThis->iCurrOffs; /* we are at begin of next line */ } else { DBGPRINTF("RGER: strmReadLine iRet %d\n", iRet); if (*ppCStr != NULL) { if (cstrLen(*ppCStr) > 0) { /* we may have an empty string in an unsuccesfull poll or after restart! */ if (rsCStrConstructFromCStr(&pThis->prevLineSegment, *ppCStr) != RS_RET_OK) { /* we cannot do anything against this, but we can at least * ensure we do not have any follow-on errors. */ pThis->prevLineSegment = NULL; } } cstrDestruct(ppCStr); } } RETiRet; } /* check if the current multi line read is timed out * @return 0 - no timeout, something else - timeout */ int strmReadMultiLine_isTimedOut(const strm_t *const __restrict__ pThis) { /* note: order of evaluation is choosen so that the most inexpensive * processing flow is used. */ DBGPRINTF( "strmReadMultiline_isTimedOut: prevMsgSeg %p, readTimeout %d, " "lastRead %lld\n", pThis->prevMsgSegment, pThis->readTimeout, (long long)pThis->lastRead); return ((pThis->readTimeout) && (pThis->prevMsgSegment != NULL) && (getTime(NULL) > pThis->lastRead + pThis->readTimeout)); } /* read a multi-line message from a strm file. * The multi-line message is terminated based on the user-provided * startRegex or endRegex (Posix ERE). For performance reasons, the regex * must already have been compiled by the user. * added 2015-05-12 rgerhards */ rsRetVal ATTR_NONNULL(1, 2) strmReadMultiLine(strm_t *pThis, cstr_t **ppCStr, regex_t *start_preg, regex_t *end_preg, const sbool bEscapeLF, const uchar *const escapeLFString, const sbool discardTruncatedMsg, const sbool msgDiscardingError, int64 *const strtOffs) { uchar c; uchar finished = 0; cstr_t *thisLine = NULL; rsRetVal readCharRet; const time_t tCurr = pThis->readTimeout ? getTime(NULL) : 0; size_t maxMsgSize = glblGetMaxLine(runConf); DEFiRet; do { CHKiRet(strmReadChar(pThis, &c)); /* immediately exit on EOF */ pThis->lastRead = tCurr; CHKiRet(cstrConstruct(&thisLine)); /* append previous message to current message if necessary */ if (pThis->prevLineSegment != NULL) { CHKiRet(cstrAppendCStr(thisLine, pThis->prevLineSegment)); cstrDestruct(&pThis->prevLineSegment); } while (c != '\n') { CHKiRet(cstrAppendChar(thisLine, c)); readCharRet = strmReadChar(pThis, &c); if (readCharRet == RS_RET_EOF) { /* end of file reached without \n? */ CHKiRet(rsCStrConstructFromCStr(&pThis->prevLineSegment, thisLine)); } CHKiRet(readCharRet); } cstrFinalize(thisLine); /* we have a line, now let's assemble the message */ const int isStartMatch = start_preg ? !regexec(start_preg, (char *)rsCStrGetSzStrNoNULL(thisLine), 0, NULL, 0) : 0; const int isEndMatch = end_preg ? !regexec(end_preg, (char *)rsCStrGetSzStrNoNULL(thisLine), 0, NULL, 0) : 0; if (isStartMatch) { /* in this case, the *previous* message is complete and we are * at the start of a new one. */ if (pThis->ignoringMsg == 0) { if (pThis->prevMsgSegment != NULL) { /* may be NULL in initial poll! */ finished = 1; *ppCStr = pThis->prevMsgSegment; } } CHKiRet(rsCStrConstructFromCStr(&pThis->prevMsgSegment, thisLine)); pThis->ignoringMsg = 0; } else { if (pThis->ignoringMsg == 0) { if (pThis->prevMsgSegment == NULL) { /* may be NULL in initial poll or after timeout! */ CHKiRet(rsCStrConstructFromCStr(&pThis->prevMsgSegment, thisLine)); } else { if (bEscapeLF) { if (escapeLFString == NULL) { rsCStrAppendStrWithLen(pThis->prevMsgSegment, (uchar *)"\\n", 2); } else { rsCStrAppendStr(pThis->prevMsgSegment, escapeLFString); } } else { cstrAppendChar(pThis->prevMsgSegment, '\n'); } size_t currLineLen = cstrLen(thisLine); if (currLineLen > 0) { size_t len; if ((len = cstrLen(pThis->prevMsgSegment) + currLineLen) < maxMsgSize) { CHKiRet(cstrAppendCStr(pThis->prevMsgSegment, thisLine)); /* we could do this faster, but for now keep it simple */ } else { if (cstrLen(pThis->prevMsgSegment) > maxMsgSize) { len = 0; } else { len = currLineLen - (len - maxMsgSize); for (size_t z = 0; z < len; z++) { cstrAppendChar(pThis->prevMsgSegment, thisLine->pBuf[z]); } } finished = 1; *ppCStr = pThis->prevMsgSegment; CHKiRet(rsCStrConstructFromszStr(&pThis->prevMsgSegment, thisLine->pBuf + len)); if (discardTruncatedMsg == 1) { pThis->ignoringMsg = 1; } if (msgDiscardingError == 1) { if (discardTruncatedMsg == 1) { LogError(0, RS_RET_ERR, "imfile error: message received is " "larger than max msg size; " "rest of message will not be " "processed"); } else { LogError(0, RS_RET_ERR, "imfile error: message received is " "larger than max msg size; message " "will be split and processed as " "another message"); } } } } } } } if (isEndMatch) { /* in this case, the *current* message is complete and we are * at the end of it. */ if (pThis->ignoringMsg == 0) { if (pThis->prevMsgSegment != NULL) { finished = 1; *ppCStr = pThis->prevMsgSegment; pThis->prevMsgSegment = NULL; } } pThis->ignoringMsg = 0; } cstrDestruct(&thisLine); } while (finished == 0); finalize_it: *strtOffs = pThis->strtOffs; if (thisLine != NULL) { cstrDestruct(&thisLine); } if (iRet == RS_RET_OK) { pThis->strtOffs = pThis->iCurrOffs; /* we are at begin of next line */ cstrFinalize(*ppCStr); } else { if (pThis->readTimeout && (pThis->prevMsgSegment != NULL) && (tCurr > pThis->lastRead + pThis->readTimeout)) { if (rsCStrConstructFromCStr(ppCStr, pThis->prevMsgSegment) == RS_RET_OK) { cstrFinalize(*ppCStr); cstrDestruct(&pThis->prevMsgSegment); pThis->lastRead = tCurr; pThis->strtOffs = pThis->iCurrOffs; /* we are at begin of next line */ dbgprintf("stream: generated msg based on timeout: %s\n", cstrGetSzStrNoNULL(*ppCStr)); iRet = RS_RET_OK; } } } RETiRet; } /* Standard-Constructor for the strm object */ BEGINobjConstruct(strm) /* be sure to specify the object type also in END macro! */ pThis->iCurrFNum = 1; pThis->fd = -1; pThis->fdDir = -1; pThis->iUngetC = -1; pThis->bVeryReliableZip = 0; pThis->sType = STREAMTYPE_FILE_SINGLE; pThis->sIOBufSize = glblGetIOBufSize(); pThis->tOpenMode = 0600; pThis->compressionDriver = STRM_COMPRESS_ZIP; pThis->pszSizeLimitCmd = NULL; pThis->prevLineSegment = NULL; pThis->prevMsgSegment = NULL; pThis->strtOffs = 0; pThis->ignoringMsg = 0; pThis->bPrevWasNL = 0; pThis->fileNotFoundError = 1; pThis->noRepeatedErrorOutput = 0; pThis->lastRead = getTime(NULL); ENDobjConstruct(strm) /* ConstructionFinalizer * rgerhards, 2008-01-09 */ static rsRetVal strmConstructFinalize(strm_t *pThis) { pthread_mutexattr_t mutAttr; rsRetVal localRet; int i; DEFiRet; assert(pThis != NULL); pThis->iBufPtrMax = 0; /* results in immediate read request */ if (pThis->iZipLevel) { /* do we need a zip buf? */ if (pThis->compressionDriver == STRM_COMPRESS_ZSTD) { localRet = objUse(zstdw, LM_ZSTDW_FILENAME); if (localRet != RS_RET_OK) { pThis->iZipLevel = 0; LogError(0, localRet, "stream was requested with zstd compression mode, " "but zstdw module unavailable - using without compression\n"); } } else { assert(pThis->compressionDriver == STRM_COMPRESS_ZIP); localRet = objUse(zlibw, LM_ZLIBW_FILENAME); if (localRet != RS_RET_OK) { pThis->iZipLevel = 0; LogError(0, localRet, "stream was requested with zip mode, but zlibw " "module unavailable - using without zip\n"); } } /* we use the same size as the original buf, as we would like * to make sure we can write out everything with a SINGLE api call! * We add another 128 bytes to take care of the gzip header and "all eventualities". */ CHKmalloc(pThis->pZipBuf = (Bytef *)malloc(pThis->sIOBufSize + 128)); } /* if we are set to sync, we must obtain a file handle to the directory for fsync() purposes */ if (pThis->bSync && !pThis->bIsTTY && pThis->pszDir != NULL) { pThis->fdDir = open((char *)pThis->pszDir, O_RDONLY | O_CLOEXEC | O_NOCTTY); if (pThis->fdDir == -1) { char errStr[1024]; int err = errno; rs_strerror_r(err, errStr, sizeof(errStr)); DBGPRINTF( "error %d opening directory file for fsync() use - fsync for directory " "disabled: %s\n", errno, errStr); } } /* if we have a flush interval, we need to do async writes in any case */ if (pThis->iFlushInterval != 0) { pThis->bAsyncWrite = 1; } DBGPRINTF("file stream %s params: flush interval %d, async write %d\n", getFileDebugName(pThis), pThis->iFlushInterval, pThis->bAsyncWrite); /* if we work asynchronously, we need a couple of synchronization objects */ if (pThis->bAsyncWrite) { /* the mutex must be recursive, because objects may call into other * object identifiers recursively. */ pthread_mutexattr_init(&mutAttr); pthread_mutexattr_settype(&mutAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&pThis->mut, &mutAttr); pthread_cond_init(&pThis->notFull, 0); pthread_cond_init(&pThis->notEmpty, 0); pthread_cond_init(&pThis->isEmpty, 0); pThis->iCnt = pThis->iEnq = pThis->iDeq = 0; for (i = 0; i < STREAM_ASYNC_NUMBUFS; ++i) { CHKmalloc(pThis->asyncBuf[i].pBuf = (uchar *)malloc(pThis->sIOBufSize)); } pThis->pIOBuf = pThis->asyncBuf[0].pBuf; pThis->bStopWriter = 0; if (pthread_create(&pThis->writerThreadID, &default_thread_attr, asyncWriterThread, pThis) != 0) DBGPRINTF("ERROR: stream %p cold not create writer thread\n", pThis); } else { /* we work synchronously, so we need to alloc a fixed pIOBuf */ CHKmalloc(pThis->pIOBuf = (uchar *)malloc(pThis->sIOBufSize)); CHKmalloc(pThis->pIOBuf_truncation = (char *)malloc(pThis->sIOBufSize)); } finalize_it: RETiRet; } /* destructor for the strm object */ BEGINobjDestruct(strm) /* be sure to specify the object type also in END and CODESTART macros! */ int i; CODESTARTobjDestruct(strm); /* we need to stop the ZIP writer */ if (pThis->bAsyncWrite) /* Note: mutex will be unlocked in strmCloseFile/stopWriter! */ d_pthread_mutex_lock(&pThis->mut); /* strmClose() will handle read-only files as well as need to open * files that have unwritten buffers. -- rgerhards, 2010-03-09 */ strmCloseFile(pThis); if (pThis->bAsyncWrite) { pthread_mutex_destroy(&pThis->mut); pthread_cond_destroy(&pThis->notFull); pthread_cond_destroy(&pThis->notEmpty); pthread_cond_destroy(&pThis->isEmpty); for (i = 0; i < STREAM_ASYNC_NUMBUFS; ++i) { free(pThis->asyncBuf[i].pBuf); } } else { free(pThis->pIOBuf); free(pThis->pIOBuf_truncation); } /* Finally, we can free the resources. * IMPORTANT: we MUST free this only AFTER the ansyncWriter has been stopped, else * we get random errors... */ if (pThis->compressionDriver == STRM_COMPRESS_ZSTD) { zstdw.Destruct(pThis); } if (pThis->prevLineSegment) cstrDestruct(&pThis->prevLineSegment); if (pThis->prevMsgSegment) cstrDestruct(&pThis->prevMsgSegment); free(pThis->pszDir); free(pThis->pZipBuf); free(pThis->pszCurrFName); free(pThis->pszFName); free(pThis->pszSizeLimitCmd); pThis->bStopWriter = 2; /* RG: use as flag for destruction */ ENDobjDestruct(strm) /* check if we need to open a new file (in output mode only). * The decision is based on file size AND record delimition state. * This method may also be called on a closed file, in which case * it immediately returns. */ static rsRetVal strmCheckNextOutputFile(strm_t *pThis) { DEFiRet; if (pThis->fd == -1 || pThis->sType != STREAMTYPE_FILE_CIRCULAR) FINALIZE; /* wait for output to be empty, so that our counts are correct */ strmWaitAsyncWriterDone(pThis); if (pThis->iCurrOffs >= pThis->iMaxFileSize) { DBGOPRINT((obj_t *)pThis, "max file size %ld reached for %d, now %ld - starting new file\n", (long)pThis->iMaxFileSize, pThis->fd, (long)pThis->iCurrOffs); CHKiRet(strmNextFile(pThis)); } finalize_it: RETiRet; } /* try to recover a tty after a write error. This may have happend * due to vhangup(), and, if so, we can simply re-open it. */ #ifdef linux #define ERR_TTYHUP EIO #else #define ERR_TTYHUP EBADF #endif static rsRetVal tryTTYRecover(strm_t *pThis, int err) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); #ifndef __FreeBSD__ if (err == ERR_TTYHUP) { #else /* Try to reopen our file descriptor even on errno 6, FreeBSD bug 200429 * Also try on errno 5, FreeBSD bug 211033 */ if (err == ERR_TTYHUP || err == ENXIO || err == EIO) { #endif /* __FreeBSD__ */ close(pThis->fd); pThis->fd = -1; CHKiRet(doPhysOpen(pThis)); } finalize_it: RETiRet; } #undef ER_TTYHUP /* issue write() api calls until either the buffer is completely * written or an error occurred (it may happen that multiple writes * are required, what is perfectly legal. On exit, *pLenBuf contains * the number of bytes actually written. * rgerhards, 2009-06-08 */ static rsRetVal ATTR_NONNULL(1, 2, 3) doWriteCall(strm_t *pThis, uchar *pBuf, size_t *pLenBuf) { ssize_t lenBuf; ssize_t iTotalWritten; ssize_t iWritten; char *pWriteBuf; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); #ifdef __FreeBSD__ sbool crnlNow = 0; #endif /* __FreeBSD__ */ lenBuf = *pLenBuf; pWriteBuf = (char *)pBuf; iTotalWritten = 0; do { #ifdef __FreeBSD__ if (pThis->bIsTTY && !pThis->iZipLevel && !pThis->cryprov) { char *pNl = NULL; if (crnlNow == 0) pNl = strchr(pWriteBuf, '\n'); else crnlNow = 0; if (pNl == pWriteBuf) { iWritten = write(pThis->fd, "\r", 1); if (iWritten > 0) { crnlNow = 1; iWritten = 0; } } else iWritten = write(pThis->fd, pWriteBuf, pNl ? pNl - pWriteBuf : lenBuf); } else #endif /* __FreeBSD__ */ iWritten = write(pThis->fd, pWriteBuf, lenBuf); if (iWritten < 0) { const int err = errno; iWritten = 0; /* we have written NO bytes! */ if (err == EBADF) { DBGPRINTF( "file %s: errno %d, fd %d no longer valid, recovery by " "reopen; if you see this, consider reporting at " "https://github.com/rsyslog/rsyslog/issues/3404 " "so that we know when it happens. Include output of uname -a. " "OS error reason", pThis->pszCurrFName, err, pThis->fd); pThis->fd = -1; CHKiRet(doPhysOpen(pThis)); } else { if (err != EINTR) { LogError(err, RS_RET_IO_ERROR, "file '%s'[%d] write error - see " "https://www.rsyslog.com/solving-rsyslog-write-errors/ for help " "OS error", pThis->pszCurrFName, pThis->fd); } if (err == EINTR) { /*NO ERROR, just continue */; } else if (!pThis->bIsTTY && (err == ENOTCONN || err == EIO)) { /* Failure for network file system, thus file needs to be closed * and reopened. */ close(pThis->fd); pThis->fd = -1; CHKiRet(doPhysOpen(pThis)); } else { if (pThis->bIsTTY) { CHKiRet(tryTTYRecover(pThis, err)); } else { ABORT_FINALIZE(RS_RET_IO_ERROR); /* Would it make sense to cover more error cases? So far, I * do not see good reason to do so. */ } } } } /* advance buffer to next write position */ iTotalWritten += iWritten; lenBuf -= iWritten; pWriteBuf += iWritten; } while (lenBuf > 0); /* Warning: do..while()! */ DBGOPRINT((obj_t *)pThis, "file %d write wrote %d bytes\n", pThis->fd, (int)iWritten); finalize_it: *pLenBuf = iTotalWritten; RETiRet; } /* write memory buffer to a stream object. */ static rsRetVal doWriteInternal(strm_t *pThis, uchar *pBuf, const size_t lenBuf, const int bFlush) { DEFiRet; DBGOPRINT((obj_t *)pThis, "file %d(%s) doWriteInternal: bFlush %d\n", pThis->fd, getFileDebugName(pThis), bFlush); if (pThis->iZipLevel) { CHKiRet(doZipWrite(pThis, pBuf, lenBuf, bFlush)); } else { /* write without zipping */ CHKiRet(strmPhysWrite(pThis, pBuf, lenBuf)); } finalize_it: RETiRet; } /* This function is called to "do" an async write call, what primarily means that * the data is handed over to the writer thread (which will then do the actual write * in parallel). Note that the stream mutex has already been locked by the * strmWrite...() calls. Also note that we always have only a single producer, * so we can simply serially assign the next free buffer to it and be sure that * the very some producer comes back in sequence to submit the then-filled buffers. * This also enables us to timout on partially written buffers. -- rgerhards, 2009-07-06 */ static rsRetVal doAsyncWriteInternal(strm_t *pThis, size_t lenBuf, const int bFlushZip) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); DBGOPRINT((obj_t *)pThis, "file %d(%s) doAsyncWriteInternal at begin: " "iCnt %d, iEnq %d, bFlushZip %d\n", pThis->fd, getFileDebugName(pThis), pThis->iCnt, pThis->iEnq, bFlushZip); /* the -1 below is important, because we need one buffer for the main thread! */ while (pThis->iCnt >= STREAM_ASYNC_NUMBUFS - 1) d_pthread_cond_wait(&pThis->notFull, &pThis->mut); pThis->asyncBuf[pThis->iEnq % STREAM_ASYNC_NUMBUFS].lenBuf = lenBuf; pThis->pIOBuf = pThis->asyncBuf[++pThis->iEnq % STREAM_ASYNC_NUMBUFS].pBuf; if (!pThis->bFlushNow) /* if we already need to flush, do not overwrite */ pThis->bFlushNow = bFlushZip; pThis->bDoTimedWait = 0; /* everything written, no need to timeout partial buffer writes */ if (++pThis->iCnt == 1) { pthread_cond_signal(&pThis->notEmpty); DBGOPRINT((obj_t *)pThis, "doAsyncWriteInternal signaled notEmpty\n"); } DBGOPRINT((obj_t *)pThis, "file %d(%s) doAsyncWriteInternal at exit: " "iCnt %d, iEnq %d, bFlushZip %d\n", pThis->fd, getFileDebugName(pThis), pThis->iCnt, pThis->iEnq, bFlushZip); RETiRet; } /* schedule writing to the stream. Depending on our concurrency settings, * this either directly writes to the stream or schedules writing via * the background thread. -- rgerhards, 2009-07-07 */ static rsRetVal strmSchedWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf, const int bFlushZip) { DEFiRet; assert(pThis != NULL); /* we need to reset the buffer pointer BEFORE calling the actual write * function. Otherwise, in circular mode, the write function will * potentially close the file, then close will flush and as the * buffer pointer is nonzero, will re-call into this code here. In * the end result, we than have a problem (and things are screwed * up). So we reset the buffer pointer first, and all this can * not happen. It is safe to do so, because that pointer is NOT * used inside the write functions. -- rgerhads, 2010-03-10 */ pThis->iBufPtr = 0; /* we are at the begin of a new buffer */ if (pThis->bAsyncWrite) { CHKiRet(doAsyncWriteInternal(pThis, lenBuf, bFlushZip)); } else { CHKiRet(doWriteInternal(pThis, pBuf, lenBuf, bFlushZip)); } finalize_it: RETiRet; } /* This is the writer thread for asynchronous mode. * -- rgerhards, 2009-07-06 */ static void *asyncWriterThread(void *pPtr) { int iDeq; struct timespec t; sbool bTimedOut = 0; strm_t *pThis = (strm_t *)pPtr; int err; uchar thrdName[256] = "rs:"; ISOBJ_TYPE_assert(pThis, strm); ustrncpy(thrdName + 3, pThis->pszFName, sizeof(thrdName) - 4); dbgOutputTID((char *)thrdName); #if defined(HAVE_PRCTL) && defined(PR_SET_NAME) if (prctl(PR_SET_NAME, (char *)thrdName, 0, 0, 0) != 0) { DBGPRINTF("prctl failed, not setting thread name for '%s'\n", "stream writer"); } #endif d_pthread_mutex_lock(&pThis->mut); while (1) { /* loop broken inside */ while (pThis->iCnt == 0) { DBGOPRINT((obj_t *)pThis, "file %d(%s) asyncWriterThread new iteration, " "iCnt %d, bTimedOut %d, iFlushInterval %d\n", pThis->fd, getFileDebugName(pThis), pThis->iCnt, bTimedOut, pThis->iFlushInterval); if (pThis->bStopWriter) { pthread_cond_broadcast(&pThis->isEmpty); d_pthread_mutex_unlock(&pThis->mut); goto finalize_it; /* break main loop */ } if (bTimedOut && pThis->iBufPtr > 0) { /* if we timed out, we need to flush pending data */ strmFlushInternal(pThis, 1); bTimedOut = 0; continue; } bTimedOut = 0; if (pThis->bDoTimedWait) { timeoutComp(&t, pThis->iFlushInterval * 1000); /* 1000 *millisconds* */ if ((err = pthread_cond_timedwait(&pThis->notEmpty, &pThis->mut, &t)) != 0) { DBGOPRINT((obj_t *)pThis, "file %d(%s) asyncWriterThread timed out\n", pThis->fd, getFileDebugName(pThis)); bTimedOut = 1; /* simulate in any case */ if (err != ETIMEDOUT) { char errStr[1024]; rs_strerror_r(err, errStr, sizeof(errStr)); DBGPRINTF( "stream async writer timeout with error (%d): %s - " "ignoring\n", err, errStr); } } } else { d_pthread_cond_wait(&pThis->notEmpty, &pThis->mut); } } DBGOPRINT((obj_t *)pThis, "file %d(%s) asyncWriterThread awoken, " "iCnt %d, bTimedOut %d\n", pThis->fd, getFileDebugName(pThis), pThis->iCnt, bTimedOut); bTimedOut = 0; /* we may have timed out, but there *is* work to do... */ iDeq = pThis->iDeq++ % STREAM_ASYNC_NUMBUFS; const int bFlush = (pThis->bFlushNow || bTimedOut) ? 1 : 0; pThis->bFlushNow = 0; /* now we can do the actual write in parallel */ d_pthread_mutex_unlock(&pThis->mut); doWriteInternal(pThis, pThis->asyncBuf[iDeq].pBuf, pThis->asyncBuf[iDeq].lenBuf, bFlush); // TODO: error check????? 2009-07-06 d_pthread_mutex_lock(&pThis->mut); --pThis->iCnt; if (pThis->iCnt < STREAM_ASYNC_NUMBUFS) { pthread_cond_signal(&pThis->notFull); if (pThis->iCnt == 0) pthread_cond_broadcast(&pThis->isEmpty); } } /* Not reached */ finalize_it: DBGOPRINT((obj_t *)pThis, "file %d(%s) asyncWriterThread terminated\n", pThis->fd, getFileDebugName(pThis)); return NULL; /* to keep pthreads happy */ } /* sync the file to disk, so that any unwritten data is persisted. This * also syncs the directory and thus makes sure that the file survives * fatal failure. Note that we do NOT return an error status if the * sync fails. Doing so would probably cause more trouble than it * is worth (read: data loss may occur where we otherwise might not * have it). -- rgerhards, 2009-06-08 */ #undef SYNCCALL #if defined(HAVE_FDATASYNC) && !defined(__APPLE__) #define SYNCCALL(x) fdatasync(x) #else #define SYNCCALL(x) fsync(x) #endif static rsRetVal syncFile(strm_t *pThis) { int ret; DEFiRet; if (pThis->bIsTTY) FINALIZE; /* TTYs can not be synced */ DBGPRINTF("syncing file %d\n", pThis->fd); ret = SYNCCALL(pThis->fd); if (ret != 0) { char errStr[1024]; int err = errno; rs_strerror_r(err, errStr, sizeof(errStr)); DBGPRINTF("sync failed for file %d with error (%d): %s - ignoring\n", pThis->fd, err, errStr); } if (pThis->fdDir != -1) { if (fsync(pThis->fdDir) != 0) DBGPRINTF("stream/syncFile: fsync returned error, ignoring\n"); } finalize_it: RETiRet; } #undef SYNCCALL /* physically write to the output file. the provided data is ready for * writing (e.g. zipped if we are requested to do that). * Note that if the write() API fails, we do not reset any pointers, but return * an error code. That means we may redo work in the next iteration. * rgerhards, 2009-06-04 */ static rsRetVal strmPhysWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf) { size_t iWritten; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); DBGPRINTF("strmPhysWrite, stream %p, len %u\n", pThis, (unsigned)lenBuf); if (pThis->fd == -1) CHKiRet(strmOpenFile(pThis)); /* here we place our crypto interface */ if (pThis->cryprov != NULL) { pThis->cryprov->Encrypt(pThis->cryprovFileData, pBuf, &lenBuf); } /* end crypto */ iWritten = lenBuf; CHKiRet(doWriteCall(pThis, pBuf, &iWritten)); pThis->iCurrOffs += iWritten; /* update user counter, if provided */ if (pThis->pUsrWCntr != NULL) *pThis->pUsrWCntr += iWritten; if (pThis->bSync) { CHKiRet(syncFile(pThis)); } if (pThis->sType == STREAMTYPE_FILE_CIRCULAR) { CHKiRet(strmCheckNextOutputFile(pThis)); } finalize_it: RETiRet; } /* write the output buffer in zip mode * This means we compress it first and then do a physical write. * Note that we always do a full deflateInit ... deflate ... deflateEnd * sequence. While this is not optimal, we need to do it because we need * to ensure that the file is readable even when we are aborted. Doing the * full sequence brings us as far towards this goal as possible (and not * doing it would be a total failure). It may be worth considering to * add a config switch so that the user can decide the risk he is ready * to take, but so far this is not yet implemented (not even requested ;)). * rgerhards, 2009-06-04 */ static rsRetVal doZipWrite(strm_t *pThis, uchar *pBuf, size_t lenBuf, const int bFlush) { if (pThis->compressionDriver == STRM_COMPRESS_ZSTD) { return zstdw.doStrmWrite(pThis, pBuf, lenBuf, bFlush, strmPhysWrite); } else { return zlibw.doStrmWrite(pThis, pBuf, lenBuf, bFlush, strmPhysWrite); } } /* finish zlib buffer, to be called before closing the ZIP file (if * running in stream mode). */ static rsRetVal doZipFinish(strm_t *pThis) { if (pThis->compressionDriver == STRM_COMPRESS_ZSTD) { return zstdw.doCompressFinish(pThis, strmPhysWrite); } else { return zlibw.doCompressFinish(pThis, strmPhysWrite); } } /* flush stream output buffer to persistent storage. This can be called at any time * and is automatically called when the output buffer is full. * rgerhards, 2008-01-10 */ static rsRetVal strmFlushInternal(strm_t *pThis, int bFlushZip) { DEFiRet; assert(pThis != NULL); DBGOPRINT((obj_t *)pThis, "strmFlushinternal: file %d(%s) flush, buflen %ld%s\n", pThis->fd, getFileDebugName(pThis), (long)pThis->iBufPtr, (pThis->iBufPtr == 0) ? " (no need to flush)" : ""); if (pThis->tOperationsMode != STREAMMODE_READ && pThis->iBufPtr > 0) { iRet = strmSchedWrite(pThis, pThis->pIOBuf, pThis->iBufPtr, bFlushZip); } RETiRet; } /* flush stream output buffer to persistent storage. This can be called at any time * and is automatically called when the output buffer is full. This function is for * use by EXTERNAL callers. Do NOT use it internally. It locks the async writer * mutex if ther is need to do so. * rgerhards, 2010-03-18 */ static rsRetVal strmFlush(strm_t *pThis) { DEFiRet; assert(pThis != NULL); DBGOPRINT((obj_t *)pThis, "file %d strmFlush\n", pThis->fd); if (pThis->bAsyncWrite) d_pthread_mutex_lock(&pThis->mut); CHKiRet(strmFlushInternal(pThis, 1)); finalize_it: if (pThis->bAsyncWrite) d_pthread_mutex_unlock(&pThis->mut); RETiRet; } /* seek a stream to a specific location. Pending writes are flushed, read data * is invalidated. * rgerhards, 2008-01-12 */ static rsRetVal ATTR_NONNULL() strmSeek(strm_t *pThis, const off64_t offs) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); if (pThis->fd == -1) { CHKiRet(strmOpenFile(pThis)); } else { CHKiRet(strmFlushInternal(pThis, 0)); } DBGOPRINT((obj_t *)pThis, "file %d seek, pos %llu\n", pThis->fd, (long long unsigned)offs); const off64_t i = lseek64(pThis->fd, offs, SEEK_SET); if (i != offs) { LogError(errno, RS_RET_IO_ERROR, "file %s: unexpected error seeking to " "offset %lld (ret %lld) - further malfunctions may happen", pThis->pszCurrFName, (long long)i, (long long)offs); ABORT_FINALIZE(RS_RET_IO_ERROR); } pThis->strtOffs = pThis->iCurrOffs = offs; /* we are now at *this* offset */ pThis->iBufPtr = 0; /* buffer invalidated */ finalize_it: RETiRet; } /* multi-file seek, seeks to file number & offset within file. This * is a support function for the queue, in circular mode. DO NOT USE * IT FOR OTHER NEEDS - it may not work as expected. It will * seek to the new position and delete interim files, as it skips them. * Note: this code can be removed when the queue gets a new disk store * handler (if and when it does ;)). * The output parameter bytesDel receives the number of bytes that have * been deleted (if a file is deleted) or 0 if nothing was deleted. * rgerhards, 2012-11-07 */ rsRetVal strmMultiFileSeek(strm_t *pThis, unsigned int FNum, off64_t offs, off64_t *bytesDel) { struct stat statBuf; int skipped_files; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); if (FNum == 0 && offs == 0) { /* happens during queue init */ *bytesDel = 0; FINALIZE; } skipped_files = FNum - pThis->iCurrFNum; *bytesDel = 0; while (skipped_files > 0) { CHKiRet(genFileName(&pThis->pszCurrFName, pThis->pszDir, pThis->lenDir, pThis->pszFName, pThis->lenFName, pThis->iCurrFNum, pThis->iFileNumDigits)); dbgprintf("rger: processing file %s\n", pThis->pszCurrFName); if (stat((char *)pThis->pszCurrFName, &statBuf) != 0) { LogError(errno, RS_RET_IO_ERROR, "unexpected error doing a stat() " "on file %s - further malfunctions may happen", pThis->pszCurrFName); /* we do NOT error-terminate here as this could worsen the * situation. As such, we just keep running and try to delete * as many files as possible. */ } *bytesDel += statBuf.st_size; DBGPRINTF( "strmMultiFileSeek: detected new filenum, was %u, new %u, " "deleting '%s' (%lld bytes)\n", pThis->iCurrFNum, FNum, pThis->pszCurrFName, (long long)statBuf.st_size); unlink((char *)pThis->pszCurrFName); if (pThis->cryprov != NULL) pThis->cryprov->DeleteStateFiles(pThis->pszCurrFName); free(pThis->pszCurrFName); pThis->pszCurrFName = NULL; pThis->iCurrFNum++; --skipped_files; } DBGOPRINT((obj_t *)pThis, "strmMultiFileSeek: deleted %lld bytes in this run\n", (long long)*bytesDel); pThis->strtOffs = pThis->iCurrOffs = offs; finalize_it: RETiRet; } /* seek to current offset. This is primarily a helper to readjust the OS file * pointer after a strm object has been deserialized. */ static rsRetVal strmSeekCurrOffs(strm_t *pThis) { off64_t targetOffs; uchar c; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); if (pThis->cryprov == NULL || pThis->tOperationsMode != STREAMMODE_READ) { iRet = strmSeek(pThis, pThis->iCurrOffs); FINALIZE; } /* As the cryprov may use CBC or similiar things, we need to read skip data */ targetOffs = pThis->iCurrOffs; pThis->strtOffs = pThis->iCurrOffs = 0; DBGOPRINT((obj_t *)pThis, "encrypted, doing skip read of %lld bytes\n", (long long)targetOffs); while (targetOffs != pThis->iCurrOffs) { CHKiRet(strmReadChar(pThis, &c)); } finalize_it: RETiRet; } /* write a *single* character to a stream object -- rgerhards, 2008-01-10 */ static rsRetVal strmWriteChar(strm_t *__restrict__ const pThis, const uchar c) { DEFiRet; assert(pThis != NULL); if (pThis->bAsyncWrite) d_pthread_mutex_lock(&pThis->mut); if (pThis->bDisabled) ABORT_FINALIZE(RS_RET_STREAM_DISABLED); /* if the buffer is full, we need to flush before we can write */ if (pThis->iBufPtr == pThis->sIOBufSize) { CHKiRet(strmFlushInternal(pThis, 0)); } /* we now always have space for one character, so we simply copy it */ *(pThis->pIOBuf + pThis->iBufPtr) = c; pThis->iBufPtr++; finalize_it: if (pThis->bAsyncWrite) d_pthread_mutex_unlock(&pThis->mut); RETiRet; } /* write an integer value (actually a long) to a stream object * Note that we do not need to lock the mutex here, because we call * strmWrite(), which does the lock (aka: we must not lock it, else we * would run into a recursive lock, resulting in a deadlock!) */ static rsRetVal strmWriteLong(strm_t *__restrict__ const pThis, const long i) { DEFiRet; uchar szBuf[32]; assert(pThis != NULL); CHKiRet(srUtilItoA((char *)szBuf, sizeof(szBuf), i)); CHKiRet(strmWrite(pThis, szBuf, strlen((char *)szBuf))); finalize_it: RETiRet; } /* write memory buffer to a stream object. * process the data in chunks and copy it over to our buffer. The caller-provided data * may theoritically be larger than our buffer. In that case, we do multiple copies. One * may argue if it were more efficient to write out the caller-provided buffer in that case * and earlier versions of rsyslog did this. However, this introduces a lot of complexity * inside the buffered writer and potential performance bottlenecks when trying to solve * it. Now keep in mind that we actually do (almost?) never have a case where the * caller-provided buffer is larger than our one. So instead of optimizing a case * which normally does not exist, we expect some degradation in its case but make us * perform better in the regular cases. -- rgerhards, 2009-07-07 * Note: the pThis->iBufPtr == pThis->sIOBufSize logic below looks a bit like an * on-off error. In fact, it is not, because iBufPtr always points to the next * *free* byte in the buffer. So if it is sIOBufSize - 1, there actually is one * free byte left. This came up during a code walkthrough and was considered * worth nothing. -- rgerhards, 2010-03-10 */ static rsRetVal ATTR_NONNULL(1, 2) strmWrite(strm_t *__restrict__ const pThis, const uchar *__restrict__ const pBuf, size_t lenBuf) { DEFiRet; size_t iWrite; size_t iOffset; assert(pThis != NULL); assert(pBuf != NULL); if (pThis->bDisabled) ABORT_FINALIZE(RS_RET_STREAM_DISABLED); if (pThis->bAsyncWrite) d_pthread_mutex_lock(&pThis->mut); iOffset = 0; do { if (pThis->iBufPtr == pThis->sIOBufSize) { CHKiRet(strmFlushInternal(pThis, 0)); /* get a new buffer for rest of data */ } iWrite = pThis->sIOBufSize - pThis->iBufPtr; /* this fits in current buf */ if (iWrite > lenBuf) iWrite = lenBuf; memcpy(pThis->pIOBuf + pThis->iBufPtr, pBuf + iOffset, iWrite); pThis->iBufPtr += iWrite; iOffset += iWrite; lenBuf -= iWrite; } while (lenBuf > 0); /* now check if the buffer right at the end of the write is full and, if so, * write it. This seems more natural than waiting (hours?) for the next message... */ if (pThis->iBufPtr == pThis->sIOBufSize) { CHKiRet(strmFlushInternal(pThis, 0)); /* get a new buffer for rest of data */ } if (pThis->fd != -1 && pThis->iSizeLimit != 0) { /* Only check if fd already set */ CHKiRet(doSizeLimitProcessing(pThis)); } finalize_it: if (pThis->bAsyncWrite) { if (pThis->bDoTimedWait == 0) { /* we potentially have a partial buffer, so re-activate the * writer thread that it can set and pick up timeouts. */ pThis->bDoTimedWait = 1; pthread_cond_signal(&pThis->notEmpty); } d_pthread_mutex_unlock(&pThis->mut); } RETiRet; } /* property set methods */ /* simple ones first */ DEFpropSetMeth(strm, iMaxFileSize, int64) DEFpropSetMeth(strm, iFileNumDigits, int) DEFpropSetMeth(strm, tOperationsMode, int) DEFpropSetMeth(strm, tOpenMode, mode_t) DEFpropSetMeth(strm, compressionDriver, strm_compressionDriver_t) DEFpropSetMeth(strm, sType, strmType_t) DEFpropSetMeth(strm, iZipLevel, int) DEFpropSetMeth(strm, bVeryReliableZip, int) DEFpropSetMeth(strm, bSync, int) DEFpropSetMeth(strm, bReopenOnTruncate, int) DEFpropSetMeth(strm, sIOBufSize, size_t) DEFpropSetMeth(strm, iSizeLimit, off_t) DEFpropSetMeth(strm, iFlushInterval, int) DEFpropSetMeth(strm, pszSizeLimitCmd, uchar *) DEFpropSetMeth(strm, cryprov, cryprov_if_t *) DEFpropSetMeth(strm, cryprovData, void *) /* sets timeout in seconds */ void ATTR_NONNULL() strmSetReadTimeout(strm_t *const __restrict__ pThis, const int val) { ISOBJ_TYPE_assert(pThis, strm); pThis->readTimeout = val; } static rsRetVal ATTR_NONNULL() strmSetbDeleteOnClose(strm_t *const pThis, const int val) { ISOBJ_TYPE_assert(pThis, strm); pThis->bDeleteOnClose = val; if (pThis->cryprov != NULL) { pThis->cryprov->SetDeleteOnClose(pThis->cryprovFileData, pThis->bDeleteOnClose); } return RS_RET_OK; } static rsRetVal ATTR_NONNULL() strmSetiMaxFiles(strm_t *const pThis, const int iNewVal) { ISOBJ_TYPE_assert(pThis, strm); pThis->iMaxFiles = iNewVal; pThis->iFileNumDigits = getNumberDigits(iNewVal); return RS_RET_OK; } static rsRetVal ATTR_NONNULL() strmSetFileNotFoundError(strm_t *const pThis, const int pFileNotFoundError) { ISOBJ_TYPE_assert(pThis, strm); pThis->fileNotFoundError = pFileNotFoundError; return RS_RET_OK; } /* set the stream's file prefix * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. * rgerhards, 2008-01-09 */ static rsRetVal strmSetFName(strm_t *pThis, uchar *pszName, size_t iLenName) { DEFiRet; assert(pThis != NULL); assert(pszName != NULL); if (iLenName < 1) ABORT_FINALIZE(RS_RET_FILE_PREFIX_MISSING); if (pThis->pszFName != NULL) free(pThis->pszFName); if ((pThis->pszFName = malloc(iLenName + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pszFName, pszName, iLenName + 1); /* always think about the \0! */ pThis->lenFName = iLenName; finalize_it: RETiRet; } /* set the stream's directory * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. * rgerhards, 2008-01-09 */ static rsRetVal strmSetDir(strm_t *pThis, uchar *pszDir, size_t iLenDir) { DEFiRet; assert(pThis != NULL); assert(pszDir != NULL); if (iLenDir < 1) ABORT_FINALIZE(RS_RET_FILE_PREFIX_MISSING); CHKmalloc(pThis->pszDir = malloc(iLenDir + 1)); memcpy(pThis->pszDir, pszDir, iLenDir + 1); /* always think about the \0! */ pThis->lenDir = iLenDir; finalize_it: RETiRet; } /* support for data records * The stream class is able to write to multiple files. However, there are * situation (actually quite common), where a single data record should not * be split across files. This may be problematic if multiple stream write * calls are used to create the record. To support that, we provide the * bInRecord status variable. If it is set, no file spliting occurs. Once * it is set to 0, a check is done if a split is necessary and it then * happens. For a record-oriented caller, the proper sequence is: * * strmRecordBegin() * strmWrite...() * strmRecordEnd() * * Please note that records do not affect the writing of output buffers. They * are always written when full. The only thing affected is circular files * creation. So it is safe to write large records. * * IMPORTANT: RecordBegin() can not be nested! It is a programming error * if RecordBegin() is called while already in a record! * * rgerhards, 2008-01-10 */ static rsRetVal strmRecordBegin(strm_t *pThis) { assert(pThis != NULL); assert(pThis->bInRecord == 0); pThis->bInRecord = 1; return RS_RET_OK; } static rsRetVal strmRecordEnd(strm_t *pThis) { DEFiRet; assert(pThis != NULL); assert(pThis->bInRecord == 1); pThis->bInRecord = 0; iRet = strmCheckNextOutputFile(pThis); /* check if we need to switch files */ RETiRet; } /* end stream record support functions */ /* This method serializes a stream object. That means the whole * object is modified into text form. That text form is suitable for * later reconstruction of the object. * The most common use case for this method is the creation of an * on-disk representation of the message object. * We do not serialize the dynamic properties. * rgerhards, 2008-01-10 */ static rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) { DEFiRet; int i; int64 l; ISOBJ_TYPE_assert(pThis, strm); ISOBJ_TYPE_assert(pStrm, strm); strmFlushInternal(pThis, 0); CHKiRet(obj.BeginSerialize(pStrm, (obj_t *)pThis)); objSerializeSCALAR(pStrm, iCurrFNum, INT); /* implicit cast is OK for persistance */ objSerializePTR(pStrm, pszFName, PSZ); objSerializeSCALAR(pStrm, iMaxFiles, INT); objSerializeSCALAR(pStrm, bDeleteOnClose, INT); i = pThis->sType; objSerializeSCALAR_VAR(pStrm, sType, INT, i); i = pThis->tOperationsMode; objSerializeSCALAR_VAR(pStrm, tOperationsMode, INT, i); i = pThis->tOpenMode; objSerializeSCALAR_VAR(pStrm, tOpenMode, INT, i); l = pThis->iCurrOffs; objSerializeSCALAR_VAR(pStrm, iCurrOffs, INT64, l); l = pThis->inode; objSerializeSCALAR_VAR(pStrm, inode, INT64, l); l = pThis->strtOffs; objSerializeSCALAR_VAR(pStrm, strtOffs, INT64, l); dbgprintf("strmSerialize: pThis->prevLineSegment %p\n", pThis->prevLineSegment); if (pThis->prevLineSegment != NULL) { cstrFinalize(pThis->prevLineSegment); objSerializePTR(pStrm, prevLineSegment, CSTR); } if (pThis->prevMsgSegment != NULL) { cstrFinalize(pThis->prevMsgSegment); objSerializePTR(pStrm, prevMsgSegment, CSTR); } i = pThis->bPrevWasNL; objSerializeSCALAR_VAR(pStrm, bPrevWasNL, INT, i); CHKiRet(obj.EndSerialize(pStrm)); finalize_it: RETiRet; } /* duplicate a stream object excluding dynamic properties. This function is * primarily meant to provide a duplicate that later on can be used to access * the data. This is needed, for example, for a restart of the disk queue. * Note that ConstructFinalize() is NOT called. So our caller may change some * properties before finalizing things. * rgerhards, 2009-05-26 */ static rsRetVal strmDup(strm_t *const pThis, strm_t **ppNew) { strm_t *pNew = NULL; DEFiRet; ISOBJ_TYPE_assert(pThis, strm); assert(ppNew != NULL); CHKiRet(strmConstruct(&pNew)); pNew->sType = pThis->sType; pNew->iCurrFNum = pThis->iCurrFNum; CHKmalloc(pNew->pszFName = ustrdup(pThis->pszFName)); pNew->lenFName = pThis->lenFName; CHKmalloc(pNew->pszDir = ustrdup(pThis->pszDir)); pNew->lenDir = pThis->lenDir; pNew->tOperationsMode = pThis->tOperationsMode; pNew->tOpenMode = pThis->tOpenMode; pNew->compressionDriver = pThis->compressionDriver; pNew->iMaxFileSize = pThis->iMaxFileSize; pNew->iMaxFiles = pThis->iMaxFiles; pNew->iFileNumDigits = pThis->iFileNumDigits; pNew->bDeleteOnClose = pThis->bDeleteOnClose; pNew->iCurrOffs = pThis->iCurrOffs; *ppNew = pNew; pNew = NULL; finalize_it: if (pNew != NULL) strmDestruct(&pNew); RETiRet; } static rsRetVal SetCompressionWorkers(strm_t *const pThis, int num_wrkrs) { ISOBJ_TYPE_assert(pThis, strm); if (num_wrkrs < 0) num_wrkrs = 1; pThis->zstd.num_wrkrs = num_wrkrs; return RS_RET_OK; } /* set a user write-counter. This counter is initialized to zero and * receives the number of bytes written. It is accurate only after a * flush(). This hook is provided as a means to control disk size usage. * The pointer must be valid at all times (so if it is on the stack, be sure * to remove it when you exit the function). Pointers are removed by * calling strmSetWCntr() with a NULL param. Only one pointer is settable, * any new set overwrites the previous one. * rgerhards, 2008-02-27 */ static rsRetVal strmSetWCntr(strm_t *pThis, number_t *pWCnt) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); if (pWCnt != NULL) *pWCnt = 0; pThis->pUsrWCntr = pWCnt; RETiRet; } #include "stringbuf.h" /* This function can be used as a generic way to set properties. * rgerhards, 2008-01-11 */ #define isProp(name) !rsCStrSzStrCmp(pProp->pcsName, UCHAR_CONSTANT(name), sizeof(name) - 1) static rsRetVal strmSetProperty(strm_t *pThis, var_t *pProp) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); assert(pProp != NULL); if (isProp("sType")) { CHKiRet(strmSetsType(pThis, (strmType_t)pProp->val.num)); } else if (isProp("iCurrFNum")) { pThis->iCurrFNum = (unsigned)pProp->val.num; } else if (isProp("pszFName")) { CHKiRet(strmSetFName(pThis, rsCStrGetSzStrNoNULL(pProp->val.pStr), rsCStrLen(pProp->val.pStr))); } else if (isProp("tOperationsMode")) { CHKiRet(strmSettOperationsMode(pThis, pProp->val.num)); } else if (isProp("tOpenMode")) { CHKiRet(strmSettOpenMode(pThis, pProp->val.num)); } else if (isProp("iCurrOffs")) { pThis->iCurrOffs = pProp->val.num; } else if (isProp("inode")) { pThis->inode = (ino_t)pProp->val.num; } else if (isProp("strtOffs")) { pThis->strtOffs = pProp->val.num; } else if (isProp("iMaxFileSize")) { CHKiRet(strmSetiMaxFileSize(pThis, pProp->val.num)); } else if (isProp("fileNotFoundError")) { CHKiRet(strmSetFileNotFoundError(pThis, pProp->val.num)); } else if (isProp("iMaxFiles")) { CHKiRet(strmSetiMaxFiles(pThis, pProp->val.num)); } else if (isProp("iFileNumDigits")) { CHKiRet(strmSetiFileNumDigits(pThis, pProp->val.num)); } else if (isProp("bDeleteOnClose")) { CHKiRet(strmSetbDeleteOnClose(pThis, pProp->val.num)); } else if (isProp("prevLineSegment")) { CHKiRet(rsCStrConstructFromCStr(&pThis->prevLineSegment, pProp->val.pStr)); } else if (isProp("prevMsgSegment")) { CHKiRet(rsCStrConstructFromCStr(&pThis->prevMsgSegment, pProp->val.pStr)); } else if (isProp("bPrevWasNL")) { pThis->bPrevWasNL = (sbool)pProp->val.num; } finalize_it: RETiRet; } #undef isProp /* return the current offset inside the stream. Note that on two consequtive calls, the offset * reported on the second call may actually be lower than on the first call. This is due to * file circulation. A caller must deal with that. -- rgerhards, 2008-01-30 */ static rsRetVal strmGetCurrOffset(strm_t *pThis, int64 *pOffs) { DEFiRet; ISOBJ_TYPE_assert(pThis, strm); assert(pOffs != NULL); *pOffs = pThis->iCurrOffs; RETiRet; } /* queryInterface function * rgerhards, 2008-02-29 */ BEGINobjQueryInterface(strm) CODESTARTobjQueryInterface(strm); if (pIf->ifVersion != strmCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = strmConstruct; pIf->ConstructFinalize = strmConstructFinalize; pIf->Destruct = strmDestruct; pIf->ReadChar = strmReadChar; pIf->UnreadChar = strmUnreadChar; pIf->ReadLine = strmReadLine; pIf->SeekCurrOffs = strmSeekCurrOffs; pIf->Write = strmWrite; pIf->WriteChar = strmWriteChar; pIf->WriteLong = strmWriteLong; pIf->SetFName = strmSetFName; pIf->SetFileNotFoundError = strmSetFileNotFoundError; pIf->SetDir = strmSetDir; pIf->Flush = strmFlush; pIf->RecordBegin = strmRecordBegin; pIf->RecordEnd = strmRecordEnd; pIf->Serialize = strmSerialize; pIf->GetCurrOffset = strmGetCurrOffset; pIf->Dup = strmDup; pIf->SetCompressionWorkers = SetCompressionWorkers; pIf->SetWCntr = strmSetWCntr; pIf->CheckFileChange = CheckFileChange; /* set methods */ pIf->SetbDeleteOnClose = strmSetbDeleteOnClose; pIf->SetiMaxFileSize = strmSetiMaxFileSize; pIf->SetiMaxFiles = strmSetiMaxFiles; pIf->SetiFileNumDigits = strmSetiFileNumDigits; pIf->SettOperationsMode = strmSettOperationsMode; pIf->SettOpenMode = strmSettOpenMode; pIf->SetcompressionDriver = strmSetcompressionDriver; pIf->SetsType = strmSetsType; pIf->SetiZipLevel = strmSetiZipLevel; pIf->SetbVeryReliableZip = strmSetbVeryReliableZip; pIf->SetbSync = strmSetbSync; pIf->SetbReopenOnTruncate = strmSetbReopenOnTruncate; pIf->SetsIOBufSize = strmSetsIOBufSize; pIf->SetiSizeLimit = strmSetiSizeLimit; pIf->SetiFlushInterval = strmSetiFlushInterval; pIf->SetpszSizeLimitCmd = strmSetpszSizeLimitCmd; pIf->Setcryprov = strmSetcryprov; pIf->SetcryprovData = strmSetcryprovData; finalize_it: ENDobjQueryInterface(strm) /* Initialize the stream class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 */ BEGINObjClassInit(strm, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ OBJSetMethodHandler(objMethod_SERIALIZE, strmSerialize); OBJSetMethodHandler(objMethod_SETPROPERTY, strmSetProperty); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, strmConstructFinalize); ENDObjClassInit(strm) rsyslog-8.2512.0/runtime/PaxHeaders/ratelimit.h0000644000000000000000000000013215103061376016361 xustar0030 mtime=1762419454.858381305 30 atime=1764930996.880959613 30 ctime=1764935923.270577912 rsyslog-8.2512.0/runtime/ratelimit.h0000664000175000017500000000443715103061376016035 0ustar00rgerrger/* header for ratelimit.c * * Copyright 2012-2016 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_RATELIMIT_H #define INCLUDED_RATELIMIT_H struct ratelimit_s { char *name; /**< rate limiter name, e.g. for user messages */ /* support for Linux kernel-type ratelimiting */ unsigned int interval; unsigned int burst; intTiny severity; /**< ratelimit only equal or lower severity levels (eq or higher values) */ unsigned done; unsigned missed; time_t begin; /* support for "last message repeated n times */ unsigned nsupp; /**< nbr of msgs suppressed */ smsg_t *pMsg; sbool bThreadSafe; /**< do we need to operate in Thread-Safe mode? */ sbool bNoTimeCache; /**< if we shall not used cached reception time */ pthread_mutex_t mut; /**< mutex if thread-safe operation desired */ }; /* prototypes */ rsRetVal ratelimitNew(ratelimit_t **ppThis, const char *modname, const char *dynname); void ratelimitSetThreadSafe(ratelimit_t *ratelimit); void ratelimitSetLinuxLike(ratelimit_t *ratelimit, unsigned int interval, unsigned int burst); void ratelimitSetNoTimeCache(ratelimit_t *ratelimit); void ratelimitSetSeverity(ratelimit_t *ratelimit, intTiny severity); rsRetVal ratelimitMsgCount(ratelimit_t *ratelimit, time_t tt, const char *const appname); rsRetVal ratelimitMsg(ratelimit_t *ratelimit, smsg_t *pMsg, smsg_t **ppRep); rsRetVal ratelimitAddMsg(ratelimit_t *ratelimit, multi_submit_t *pMultiSub, smsg_t *pMsg); void ratelimitDestruct(ratelimit_t *pThis); int ratelimitChecked(ratelimit_t *ratelimit); rsRetVal ratelimitModInit(void); void ratelimitModExit(void); #endif /* #ifndef INCLUDED_RATELIMIT_H */ rsyslog-8.2512.0/runtime/PaxHeaders/gss-misc.c0000644000000000000000000000013215055605325016113 xustar0030 mtime=1756826325.645800623 30 atime=1764931130.900155499 30 ctime=1764935923.333578877 rsyslog-8.2512.0/runtime/gss-misc.c0000664000175000017500000002047015055605325015562 0ustar00rgerrger/* gss-misc.c * This is a miscellaneous helper class for gss-api features. * * Copyright 2007-2017 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dirty.h" #include "syslogd-types.h" #include "srUtils.h" #include "net.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "obj.h" #include "errmsg.h" #include "gss-misc.h" #include "debug.h" #include "glbl.h" #include "unlimited_select.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) static void display_status_(char *m, OM_uint32 code, int type) { OM_uint32 maj_stat, min_stat, msg_ctx = 0; gss_buffer_desc msg; do { maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NO_OID, &msg_ctx, &msg); if (maj_stat != GSS_S_COMPLETE) { LogError(0, NO_ERRCODE, "GSS-API error in gss_display_status called from <%s>\n", m); break; } else { char buf[1024]; snprintf(buf, sizeof(buf), "GSS-API error %s: %s\n", m, (char *)msg.value); buf[sizeof(buf) - 1] = '\0'; LogError(0, NO_ERRCODE, "%s", buf); } if (msg.length != 0) gss_release_buffer(&min_stat, &msg); } while (msg_ctx); } static void display_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat) { display_status_(m, maj_stat, GSS_C_GSS_CODE); display_status_(m, min_stat, GSS_C_MECH_CODE); } static void display_ctx_flags(OM_uint32 flags) { if (flags & GSS_C_DELEG_FLAG) dbgprintf("GSS_C_DELEG_FLAG\n"); if (flags & GSS_C_MUTUAL_FLAG) dbgprintf("GSS_C_MUTUAL_FLAG\n"); if (flags & GSS_C_REPLAY_FLAG) dbgprintf("GSS_C_REPLAY_FLAG\n"); if (flags & GSS_C_SEQUENCE_FLAG) dbgprintf("GSS_C_SEQUENCE_FLAG\n"); if (flags & GSS_C_CONF_FLAG) dbgprintf("GSS_C_CONF_FLAG\n"); if (flags & GSS_C_INTEG_FLAG) dbgprintf("GSS_C_INTEG_FLAG\n"); } static int read_all(int fd, char *buf, unsigned int nbyte) { int ret; char *ptr; struct timeval tv; #ifdef USE_UNLIMITED_SELECT fd_set *pRfds = malloc(glbl.GetFdSetSize()); if (pRfds == NULL) return -1; #else fd_set rfds; fd_set *pRfds = &rfds; #endif for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { FD_ZERO(pRfds); FD_SET(fd, pRfds); tv.tv_sec = 1; tv.tv_usec = 0; if ((ret = select(FD_SETSIZE, pRfds, NULL, NULL, &tv)) <= 0 || !FD_ISSET(fd, pRfds)) { freeFdSet(pRfds); return ret; } ret = recv(fd, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; freeFdSet(pRfds); return (ret); } else if (ret == 0) { freeFdSet(pRfds); return (ptr - buf); } } freeFdSet(pRfds); return (ptr - buf); } static int write_all(int fd, char *buf, unsigned int nbyte) { int ret; char *ptr; for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { ret = send(fd, ptr, nbyte, 0); if (ret < 0) { if (errno == EINTR) continue; return (ret); } else if (ret == 0) { return (ptr - buf); } } return (ptr - buf); } static int recv_token(int s, gss_buffer_t tok) { int ret; unsigned char lenbuf[4] = "xxx"; // initialized to make clang static analyzer happy unsigned int len; ret = read_all(s, (char *)lenbuf, 4); if (ret < 0) { LogError(0, NO_ERRCODE, "GSS-API error reading token length"); return -1; } else if (!ret) { return 0; } else if (ret != 4) { LogError(0, NO_ERRCODE, "GSS-API error reading token length"); return -1; } len = ((lenbuf[0] << 24) | (lenbuf[1] << 16) | (lenbuf[2] << 8) | lenbuf[3]); tok->length = ntohl(len); tok->value = (char *)malloc(tok->length ? tok->length : 1); if (tok->length && tok->value == NULL) { LogError(0, NO_ERRCODE, "Out of memory allocating token data\n"); return -1; } ret = read_all(s, (char *)tok->value, tok->length); if (ret < 0) { LogError(0, NO_ERRCODE, "GSS-API error reading token data"); free(tok->value); return -1; } else if (ret != (int)tok->length) { LogError(0, NO_ERRCODE, "GSS-API error reading token data"); free(tok->value); return -1; } return 1; } static int send_token(int s, gss_buffer_t tok) { int ret; unsigned char lenbuf[4]; unsigned int len; if (tok->length > 0xffffffffUL) abort(); /* TODO: we need to reconsider this, abort() is not really a solution - degrade, but keep running */ len = htonl(tok->length); lenbuf[0] = (len >> 24) & 0xff; lenbuf[1] = (len >> 16) & 0xff; lenbuf[2] = (len >> 8) & 0xff; lenbuf[3] = len & 0xff; ret = write_all(s, (char *)lenbuf, 4); if (ret < 0) { LogError(0, NO_ERRCODE, "GSS-API error sending token length"); return -1; } else if (ret != 4) { LogError(0, NO_ERRCODE, "GSS-API error sending token length"); return -1; } ret = write_all(s, tok->value, tok->length); if (ret < 0) { LogError(0, NO_ERRCODE, "GSS-API error sending token data"); return -1; } else if (ret != (int)tok->length) { LogError(0, NO_ERRCODE, "GSS-API error sending token data"); return -1; } return 0; } /* queryInterface function * rgerhards, 2008-02-29 */ BEGINobjQueryInterface(gssutil) CODESTARTobjQueryInterface(gssutil); if (pIf->ifVersion != gssutilCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->recv_token = recv_token; pIf->send_token = send_token; pIf->display_status = display_status; pIf->display_ctx_flags = display_ctx_flags; finalize_it: ENDobjQueryInterface(gssutil) /* exit our class * rgerhards, 2008-03-10 */ BEGINObjClassExit(gssutil, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(gssutil); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); ENDObjClassExit(gssutil) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-29 */ BEGINAbstractObjClassInit(gssutil, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDObjClassInit(gssutil) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; gssutilClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(gssutilClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/libcry_common.c0000644000000000000000000000013215055605325017222 xustar0030 mtime=1756826325.646800638 30 atime=1764931130.108142715 30 ctime=1764935923.082575034 rsyslog-8.2512.0/runtime/libcry_common.c0000664000175000017500000001105415055605325016667 0ustar00rgerrger/* libgcry_common.c * This file hosts functions both being used by the rsyslog runtime as * well as tools who do not use the runtime (so we can maintain the * code at a single place). * * Copyright 2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "rsyslog.h" /* we need data typedefs */ #include "libcry_common.h" /* read a key from a key file * @param[out] key - key buffer, must be freed by caller * @param[out] keylen - length of buffer * @returns 0 if OK, something else otherwise (we do not use * iRet as this is also called from non-rsyslog w/o runtime) * on error, errno is set and can be queried * The key length is limited to 64KiB to prevent DoS. * Note well: key is a blob, not a C string (NUL may be present!) */ int cryGetKeyFromFile(const char *const fn, char **const key, unsigned *const keylen) { struct stat sb; int r = -1; const int fd = open(fn, O_RDONLY); if (fd < 0) goto done; if (fstat(fd, &sb) == -1) goto done; if (sb.st_size > 64 * 1024) { errno = EMSGSIZE; goto done; } if ((*key = malloc(sb.st_size)) == NULL) goto done; if (read(fd, *key, sb.st_size) != sb.st_size) goto done; *keylen = sb.st_size; r = 0; done: if (fd >= 0) { close(fd); } return r; } /* execute the child process (must be called in child context * after fork). */ static void execKeyScript(char *cmd, int pipefd[]) { char *newargv[] = {NULL}; char *newenviron[] = {NULL}; dup2(pipefd[0], STDIN_FILENO); dup2(pipefd[1], STDOUT_FILENO); /* finally exec child */ fprintf(stderr, "pre execve: %s\n", cmd); execve(cmd, newargv, newenviron); /* switch to? execlp((char*)program, (char*) program, (char*)arg, NULL); */ /* we should never reach this point, but if we do, we terminate */ return; } static int openPipe(char *cmd, int *fd) { int pipefd[2]; pid_t cpid; int r; if (pipe(pipefd) == -1) { r = 1; goto done; } cpid = fork(); if (cpid == -1) { r = 1; goto done; } if (cpid == 0) { /* we are the child */ execKeyScript(cmd, pipefd); exit(1); } close(pipefd[1]); *fd = pipefd[0]; r = 0; done: return r; } /* Read a character from the program's output. */ static int readProgChar(int fd, char *c) { int r; if (read(fd, c, 1) != 1) { r = 1; goto done; } r = 0; done: return r; } /* Read a line from the script. Line is terminated by LF, which * is NOT put into the buffer. * buf must be 64KiB */ static int readProgLine(int fd, char *buf) { char c; int r; unsigned i; for (i = 0; i < 64 * 1024; ++i) { if ((r = readProgChar(fd, &c)) != 0) goto done; if (c == '\n') break; buf[i] = c; }; if (i >= 64 * 1024) { r = 1; goto done; } buf[i] = '\0'; r = 0; done: return r; } static int readProgKey(int fd, char *buf, unsigned keylen) { char c; int r; unsigned i; for (i = 0; i < keylen; ++i) { if ((r = readProgChar(fd, &c)) != 0) goto done; buf[i] = c; }; r = 0; done: return r; } int cryGetKeyFromProg(char *cmd, char **key, unsigned *keylen) { int r; int fd; char rcvBuf[64 * 1024]; if ((r = openPipe(cmd, &fd)) != 0) goto done; if ((r = readProgLine(fd, rcvBuf)) != 0) goto done; if (strcmp(rcvBuf, "RSYSLOG-KEY-PROVIDER:0")) { r = 2; goto done; } if ((r = readProgLine(fd, rcvBuf)) != 0) goto done; *keylen = atoi(rcvBuf); if ((*key = malloc(*keylen)) == NULL) { r = -1; goto done; } if ((r = readProgKey(fd, *key, *keylen)) != 0) goto done; done: return r; } rsyslog-8.2512.0/runtime/PaxHeaders/sigprov.h0000644000000000000000000000013215055605325016064 xustar0030 mtime=1756826325.652800728 30 atime=1764931032.814555241 30 ctime=1764935923.123575662 rsyslog-8.2512.0/runtime/sigprov.h0000664000175000017500000000300415055605325015525 0ustar00rgerrger/* The interface definition for (file) signature providers. * * This is just an abstract driver interface, which needs to be * implemented by concrete classes. * * Copyright 2013 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_SIGPROV_H #define INCLUDED_SIGPROV_H /* interface */ BEGINinterface(sigprov) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(void *ppThis); rsRetVal (*SetCnfParam)(void *ppThis, struct nvlst *lst); rsRetVal (*Destruct)(void *ppThis); rsRetVal (*OnFileOpen)(void *pThis, uchar *fn, void *pFileInstData); rsRetVal (*OnRecordWrite)(void *pFileInstData, uchar *rec, rs_size_t lenRec); rsRetVal (*OnFileClose)(void *pFileInstData); ENDinterface(sigprov) #define sigprovCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ #endif /* #ifndef INCLUDED_SIGPROV_H */ rsyslog-8.2512.0/runtime/PaxHeaders/module-template.h0000644000000000000000000000013215055605325017471 xustar0030 mtime=1756826325.647800653 30 atime=1764930992.724890367 30 ctime=1764935923.116575555 rsyslog-8.2512.0/runtime/module-template.h0000664000175000017500000014274615055605325017153 0ustar00rgerrger/* module-template.h * This header contains macros that can be used to implement the * plumbing of modules. * * File begun on 2007-07-25 by RGerhards * * Copyright 2007-2025 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MODULE_TEMPLATE_H_INCLUDED #define MODULE_TEMPLATE_H_INCLUDED 1 #include "modules.h" #include "obj.h" #include "objomsr.h" #include "threads.h" /* macro to define standard output-module static data members */ #define DEF_MOD_STATIC_DATA \ static __attribute__((unused)) rsRetVal (*omsdRegCFSLineHdlr)(uchar * pCmdName, int bChainingPermitted, \ ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), \ void *pData, void *pOwnerCookie) #define DEF_OMOD_STATIC_DATA \ DEF_MOD_STATIC_DATA; \ DEFobjCurrIf(obj) static __attribute__((unused)) int bCoreSupportsBatching; #define DEF_IMOD_STATIC_DATA \ DEF_MOD_STATIC_DATA; \ DEFobjCurrIf(obj) #define DEF_LMOD_STATIC_DATA DEF_MOD_STATIC_DATA #define DEF_PMOD_STATIC_DATA \ DEFobjCurrIf(obj); \ DEF_MOD_STATIC_DATA #define DEF_SMOD_STATIC_DATA \ DEFobjCurrIf(obj); \ DEF_MOD_STATIC_DATA #define DEF_FMOD_STATIC_DATA \ DEFobjCurrIf(obj); \ DEF_MOD_STATIC_DATA /* Macro to define the module type. Each module can only have a single type. If * a module provides multiple types, several separate modules must be created which * then should share a single library containing the majority of code. This macro * must be present in each module. -- rgerhards, 2007-12-14 * Note that MODULE_TYPE_TESTBENCH is reserved for testbenches, but * declared in their own header files (because the rest does not need these * defines). -- rgerhards, 2008-06-13 */ #define MODULE_TYPE(x) \ static rsRetVal modGetType(eModType_t *modType) { \ *modType = x; \ return RS_RET_OK; \ } #define MODULE_TYPE_INPUT MODULE_TYPE(eMOD_IN) #define MODULE_TYPE_OUTPUT MODULE_TYPE(eMOD_OUT) #define MODULE_TYPE_PARSER MODULE_TYPE(eMOD_PARSER) #define MODULE_TYPE_STRGEN MODULE_TYPE(eMOD_STRGEN) #define MODULE_TYPE_FUNCTION MODULE_TYPE(eMOD_FUNCTION) #define MODULE_TYPE_LIB \ DEF_LMOD_STATIC_DATA; \ MODULE_TYPE(eMOD_LIB) /* Macro to define whether the module should be kept dynamically linked. */ #define MODULE_KEEP_TYPE(x) \ static rsRetVal modGetKeepType(eModKeepType_t *modKeepType) { \ *modKeepType = x; \ return RS_RET_OK; \ } #define MODULE_TYPE_NOKEEP MODULE_KEEP_TYPE(eMOD_NOKEEP) #define MODULE_TYPE_KEEP MODULE_KEEP_TYPE(eMOD_KEEP) /* macro to define a unique module id. This must be able to fit in a void*. The * module id must be unique inside a running rsyslogd application. It is used to * track ownership of several objects. Most importantly, when the module is * unloaded the module id value is used to find what needs to be destroyed. * We currently use a pointer to modExit() as the module id. This sounds to be * reasonable save, as each module must have this entry point AND there is no valid * reason for twice this entry point being in memory. * rgerhards, 2007-11-21 */ #define STD_LOADABLE_MODULE_ID ((void *)modExit) /* macro to implement the "modGetID()" interface function * rgerhards 2007-11-21 */ #define DEFmodGetID \ static rsRetVal modGetID(void **pID) { \ *pID = STD_LOADABLE_MODULE_ID; \ return RS_RET_OK; \ } /* macro to provide the v6 config system module name */ #define MODULE_CNFNAME(name) \ static rsRetVal modGetCnfName(uchar **cnfName) { \ *cnfName = (uchar *)name; \ return RS_RET_OK; \ } /* to following macros are used to generate function headers and standard * functionality. It works as follows (described on the sample case of * createInstance()): * * BEGINcreateInstance * ... custom variable definitions (on stack) ... (if any) * CODESTARTcreateInstance * ... custom code ... (if any) * ENDcreateInstance */ /* createInstance() */ #define BEGINcreateInstance \ static rsRetVal createInstance(instanceData **ppData) { \ DEFiRet; /* store error code here */ \ instanceData *pData; /* use this to point to data elements */ #define CODESTARTcreateInstance \ if ((pData = calloc(1, sizeof(instanceData))) == NULL) { \ *ppData = NULL; \ return RS_RET_OUT_OF_MEMORY; \ } #define ENDcreateInstance \ *ppData = pData; \ RETiRet; \ } /* freeInstance() * This is the cleanup function for the module instance. It is called immediately before * the module instance is destroyed (unloaded). The module should do any cleanup * here, e.g. close file, free instantance heap memory and the like. Control will * not be passed back to the module once this function is finished. Keep in mind, * however, that other instances may still be loaded and used. So do not destroy * anything that may be used by another instance. If you have such a ressource, you * currently need to do the instance counting yourself. */ #define BEGINfreeInstance \ static rsRetVal freeInstance(void *pModData) { \ DEFiRet; \ instanceData *pData; #define CODESTARTfreeInstance pData = (instanceData *)pModData; #define ENDfreeInstance \ if (pData != NULL) free(pData); /* we need to free this in any case */ \ RETiRet; \ } /* createWrkrInstance() */ #define BEGINcreateWrkrInstance \ static rsRetVal createWrkrInstance(wrkrInstanceData_t **ppWrkrData, instanceData *pData) { \ DEFiRet; /* store error code here */ \ wrkrInstanceData_t *pWrkrData; /* use this to point to data elements */ #define CODESTARTcreateWrkrInstance \ if ((pWrkrData = calloc(1, sizeof(wrkrInstanceData_t))) == NULL) { \ *ppWrkrData = NULL; \ return RS_RET_OUT_OF_MEMORY; \ } \ pWrkrData->pData = pData; #define ENDcreateWrkrInstance \ *ppWrkrData = pWrkrData; \ RETiRet; \ } /* freeWrkrInstance */ #define BEGINfreeWrkrInstance \ static rsRetVal freeWrkrInstance(void *pd) { \ DEFiRet; \ wrkrInstanceData_t *pWrkrData; #define CODESTARTfreeWrkrInstance pWrkrData = (wrkrInstanceData_t *)pd; #define ENDfreeWrkrInstance \ if (pWrkrData != NULL) free(pWrkrData); /* we need to free this in any case */ \ RETiRet; \ } /* isCompatibleWithFeature() */ #define BEGINisCompatibleWithFeature \ static rsRetVal isCompatibleWithFeature(syslogFeature __attribute__((unused)) eFeat) { \ rsRetVal iRet = RS_RET_INCOMPATIBLE; #define CODESTARTisCompatibleWithFeature #define ENDisCompatibleWithFeature \ RETiRet; \ } /* beginTransaction() * introduced in v4.3.3 -- rgerhards, 2009-04-27 */ #define BEGINbeginTransaction \ static rsRetVal beginTransaction(wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ DEFiRet; #define CODESTARTbeginTransaction /* currently empty, but may be extended */ #define ENDbeginTransaction \ RETiRet; \ } /* commitTransaction() * Commits a transaction. Note that beginTransaction() must have been * called before this entry point. It receives the full batch of messages * to be processed in pParam parameter. * introduced in v8.1.3 -- rgerhards, 2013-12-04 */ #define BEGINcommitTransaction \ static rsRetVal commitTransaction(wrkrInstanceData_t __attribute__((unused)) *const pWrkrData, \ actWrkrIParams_t *const pParams, const unsigned nParams) { \ DEFiRet; #define CODESTARTcommitTransaction /* currently empty, but may be extended */ #define ENDcommitTransaction \ RETiRet; \ } /* endTransaction() * introduced in v4.3.3 -- rgerhards, 2009-04-27 */ #define BEGINendTransaction \ static rsRetVal endTransaction(wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ DEFiRet; #define CODESTARTendTransaction /* currently empty, but may be extended */ #define ENDendTransaction \ RETiRet; \ } /* doAction() */ #define BEGINdoAction \ static rsRetVal doAction(void *pMsgData, wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ uchar **ppString = (uchar **)pMsgData; \ DEFiRet; #define CODESTARTdoAction /* ppString may be NULL if the output module requested no strings */ #define ENDdoAction \ RETiRet; \ } /* below is a variant of doAction where the passed-in data is not the common * case of string. */ #define BEGINdoAction_NoStrings \ static rsRetVal doAction(void *pMsgData, wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ DEFiRet; /* dbgPrintInstInfo() * Extra comments: * Print debug information about this instance. */ #define BEGINdbgPrintInstInfo \ static rsRetVal dbgPrintInstInfo(void *pModData) { \ DEFiRet; \ instanceData *pData = NULL; #define CODESTARTdbgPrintInstInfo \ pData = (instanceData *)pModData; \ (void)pData; /* prevent compiler warning if unused! */ #define ENDdbgPrintInstInfo \ RETiRet; \ } /* parseSelectorAct() * Extra comments: * try to process a selector action line. Checks if the action * applies to this module and, if so, processed it. If not, it * is left untouched. The driver will then call another module. * On exit, ppModData must point to instance data. Also, a string * request object must be created and filled. A macro is defined * for that. * For the most usual case, we have defined a macro below. * If more than one string is requested, the macro can be used together * with own code that overwrites the entry count. In this case, the * macro must come before the own code. It is recommended to be * placed right after CODESTARTparseSelectorAct. */ #define BEGINparseSelectorAct \ static rsRetVal parseSelectorAct(uchar **pp, void **ppModData, omodStringRequest_t **ppOMSR) { \ DEFiRet; \ uchar *p; \ instanceData *pData = NULL; #define CODESTARTparseSelectorAct \ assert(pp != NULL); \ assert(ppModData != NULL); \ assert(ppOMSR != NULL); \ p = *pp; #define CODE_STD_STRING_REQUESTparseSelectorAct(NumStrReqEntries) CHKiRet(OMSRconstruct(ppOMSR, NumStrReqEntries)); #define CODE_STD_FINALIZERparseSelectorAct \ finalize_it : ATTR_UNUSED; /* semi-colon needed according to gcc doc! */ \ if (iRet == RS_RET_OK || iRet == RS_RET_OK_WARN || iRet == RS_RET_SUSPENDED) { \ *ppModData = pData; \ *pp = p; \ } else { \ /* cleanup, we failed */ \ if (*ppOMSR != NULL) { \ OMSRdestruct(*ppOMSR); \ *ppOMSR = NULL; \ } \ if (pData != NULL) { \ freeInstance(pData); \ } \ } #define ENDparseSelectorAct \ RETiRet; \ } /* a special replacement macro for modules that do not support legacy config at all */ #define NO_LEGACY_CONF_parseSelectorAct \ static rsRetVal parseSelectorAct(uchar **pp ATTR_UNUSED, void **ppModData ATTR_UNUSED, \ omodStringRequest_t **ppOMSR ATTR_UNUSED) { \ return RS_RET_LEGA_ACT_NOT_SUPPORTED; \ } /* newActInst() * Extra comments: * This creates a new instance of a the action that implements the call. * This is part of the conf2 (rsyslog v6) config system. It is called by * the core when an action object has been obtained. The output module * must then verify parameters and create a new action instance (if * parameters are acceptable) or return an error code. * On exit, ppModData must point to instance data. Also, a string * request object must be created and filled. A macro is defined * for that. * For the most usual case, we have defined a macro below. * If more than one string is requested, the macro can be used together * with own code that overwrites the entry count. In this case, the * macro must come before the own code. It is recommended to be * placed right after CODESTARTnewActInst. */ #define BEGINnewActInst \ static rsRetVal newActInst(uchar __attribute__((unused)) * modName, struct nvlst __attribute__((unused)) * lst, \ void **ppModData, omodStringRequest_t **ppOMSR) { \ DEFiRet; \ instanceData *pData = NULL; \ *ppOMSR = NULL; #define CODESTARTnewActInst #define CODE_STD_STRING_REQUESTnewActInst(NumStrReqEntries) CHKiRet(OMSRconstruct(ppOMSR, NumStrReqEntries)) #define CODE_STD_FINALIZERnewActInst \ finalize_it : if (iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) { \ *ppModData = pData; \ } else { \ /* cleanup, we failed */ \ if (*ppOMSR != NULL) { \ OMSRdestruct(*ppOMSR); \ *ppOMSR = NULL; \ } \ if (pData != NULL) { \ freeInstance(pData); \ } \ } #define ENDnewActInst \ RETiRet; \ } /* newInpInst() * This is basically the equivalent to newActInst() for creating input * module (listener) instances. */ #define BEGINnewInpInst \ static rsRetVal newInpInst(struct nvlst *lst) { \ DEFiRet; #define CODESTARTnewInpInst #define CODE_STD_FINALIZERnewInpInst #define ENDnewInpInst \ RETiRet; \ } /* newParserInst() * This is basically the equivalent to newActInst() for creating parser * module (listener) instances. */ #define BEGINnewParserInst \ static rsRetVal newParserInst(struct nvlst *lst, void *pinst) { \ instanceConf_t *inst; \ DEFiRet; #define CODESTARTnewParserInst #define CODE_STD_FINALIZERnewParserInst #define ENDnewParserInst \ if (iRet == RS_RET_OK) *((instanceConf_t **)pinst) = inst; \ RETiRet; \ } /* freeParserInst */ #define BEGINfreeParserInst \ static rsRetVal freeParserInst(void *pi) { \ DEFiRet; \ instanceConf_t *pInst; #define CODESTARTfreeParserInst pInst = (instanceConf_t *)pi; #define ENDfreeParserInst \ if (pInst != NULL) free(pInst); \ RETiRet; \ } /* tryResume() * This entry point is called to check if a module can resume operations. This * happens when a module requested that it be suspended. In suspended state, * the engine periodically tries to resume the module. If that succeeds, normal * processing continues. If not, the module will not be called unless a * tryResume() call succeeds. * Returns RS_RET_OK, if resumption succeeded, RS_RET_SUSPENDED otherwise * rgerhard, 2007-08-02 */ #define BEGINtryResume \ static rsRetVal tryResume(wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ DEFiRet; #define CODESTARTtryResume assert(pWrkrData != NULL); #define ENDtryResume \ RETiRet; \ } /* initConfVars() - initialize pre-v6.3-config variables */ #define BEGINinitConfVars \ static rsRetVal initConfVars(void) { \ DEFiRet; #define CODESTARTinitConfVars #define ENDinitConfVars \ RETiRet; \ } /* queryEtryPt() */ #define BEGINqueryEtryPt \ DEFmodGetID static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)()) { \ DEFiRet; #define CODESTARTqueryEtryPt \ if ((name == NULL) || (pEtryPoint == NULL)) { \ return RS_RET_PARAM_ERROR; \ } \ *pEtryPoint = NULL; #define ENDqueryEtryPt \ if (iRet == RS_RET_OK) \ if (*pEtryPoint == NULL) { \ dbgprintf("entry point '%s' not present in module\n", name); \ iRet = RS_RET_MODULE_ENTRY_POINT_NOT_FOUND; \ } \ RETiRet; \ } /** \addtogroup module_entrypoint_blocks * \{ * \brief Standard queryEtryPt block for all module types. * * Must be included in every module. This defines default queries * like `modExit`, `modGetID`, etc. */ #define CODEqueryEtryPt_STD_MOD_QUERIES \ if (!strcmp((char *)name, "modExit")) { \ *pEtryPoint = modExit; \ } \ if (!strcmp((char *)name, "modGetID")) { \ *pEtryPoint = modGetID; \ } \ if (!strcmp((char *)name, "getType")) { \ *pEtryPoint = modGetType; \ } \ if (!strcmp((char *)name, "getKeepType")) { \ *pEtryPoint = modGetKeepType; \ } /** * \brief Standard block for output modules without transaction support. */ #define CODEqueryEtryPt_STD_OMOD_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "doAction")) { \ *pEtryPoint = doAction; \ } \ if (!strcmp((char *)name, "dbgPrintInstInfo")) { \ *pEtryPoint = dbgPrintInstInfo; \ } \ if (!strcmp((char *)name, "freeInstance")) { \ *pEtryPoint = freeInstance; \ } \ if (!strcmp((char *)name, "parseSelectorAct")) { \ *pEtryPoint = parseSelectorAct; \ } \ if (!strcmp((char *)name, "isCompatibleWithFeature")) { \ *pEtryPoint = isCompatibleWithFeature; \ } \ if (!strcmp((char *)name, "tryResume")) { \ *pEtryPoint = tryResume; \ } /** * \brief Standard block for output modules using the transaction interface. */ #define CODEqueryEtryPt_STD_OMODTX_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "beginTransaction")) { \ *pEtryPoint = beginTransaction; \ } \ if (!strcmp((char *)name, "commitTransaction")) { \ *pEtryPoint = commitTransaction; \ } \ if (!strcmp((char *)name, "dbgPrintInstInfo")) { \ *pEtryPoint = dbgPrintInstInfo; \ } \ if (!strcmp((char *)name, "freeInstance")) { \ *pEtryPoint = freeInstance; \ } \ if (!strcmp((char *)name, "parseSelectorAct")) { \ *pEtryPoint = parseSelectorAct; \ } \ if (!strcmp((char *)name, "isCompatibleWithFeature")) { \ *pEtryPoint = isCompatibleWithFeature; \ } \ if (!strcmp((char *)name, "tryResume")) { \ *pEtryPoint = tryResume; \ } /** * \brief Additional methods for output module v8+ support. */ #define CODEqueryEtryPt_STD_OMOD8_QUERIES \ if (!strcmp((char *)name, "createWrkrInstance")) { \ *pEtryPoint = createWrkrInstance; \ } \ if (!strcmp((char *)name, "freeWrkrInstance")) { \ *pEtryPoint = freeWrkrInstance; \ } /** * \brief For output modules with transaction interface extension. */ #define CODEqueryEtryPt_TXIF_OMOD_QUERIES \ if (!strcmp((char *)name, "beginTransaction")) { \ *pEtryPoint = beginTransaction; \ } \ if (!strcmp((char *)name, "endTransaction")) { \ *pEtryPoint = endTransaction; \ } /** * \brief Optional support for feature compatibility query. */ #define CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES \ if (!strcmp((char *)name, "isCompatibleWithFeature")) { \ *pEtryPoint = isCompatibleWithFeature; \ } /** * \brief Standard block for input modules. */ #define CODEqueryEtryPt_STD_IMOD_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "runInput")) { \ *pEtryPoint = runInput; \ } \ if (!strcmp((char *)name, "willRun")) { \ *pEtryPoint = willRun; \ } \ if (!strcmp((char *)name, "afterRun")) { \ *pEtryPoint = afterRun; \ } /** * \brief For modules using the config interface v2. */ #define CODEqueryEtryPt_STD_CONF2_QUERIES \ if (!strcmp((char *)name, "beginCnfLoad")) { \ *pEtryPoint = beginCnfLoad; \ } \ if (!strcmp((char *)name, "endCnfLoad")) { \ *pEtryPoint = endCnfLoad; \ } \ if (!strcmp((char *)name, "checkCnf")) { \ *pEtryPoint = checkCnf; \ } \ if (!strcmp((char *)name, "activateCnf")) { \ *pEtryPoint = activateCnf; \ } \ if (!strcmp((char *)name, "freeCnf")) { \ *pEtryPoint = freeCnf; \ } \ CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES #define CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES \ if (!strcmp((char *)name, "setModCnf")) { \ *pEtryPoint = setModCnf; \ } #define CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES \ if (!strcmp((char *)name, "newActInst")) { \ *pEtryPoint = newActInst; \ } \ CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES #define CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES \ if (!strcmp((char *)name, "newInpInst")) { \ *pEtryPoint = newInpInst; \ } \ CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES #define CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES \ if (!strcmp((char *)name, "activateCnfPrePrivDrop")) { \ *pEtryPoint = activateCnfPrePrivDrop; \ } /** * \brief Config interface v6 module name support. */ #define CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES \ if (!strcmp((char *)name, "getModCnfName")) { \ *pEtryPoint = modGetCnfName; \ } /** * \brief Standard block for library modules. */ #define CODEqueryEtryPt_STD_LIB_QUERIES CODEqueryEtryPt_STD_MOD_QUERIES /** * \brief Standard block for parser modules. */ #define CODEqueryEtryPt_STD_PMOD_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "parse")) { \ *pEtryPoint = parse; \ } \ if (!strcmp((char *)name, "GetParserName")) { \ *pEtryPoint = GetParserName; \ } /** * \brief Standard block for parser modules using config v2. */ #define CODEqueryEtryPt_STD_PMOD2_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "parse2")) { \ *pEtryPoint = parse2; \ } \ if (!strcmp((char *)name, "GetParserName")) { \ *pEtryPoint = GetParserName; \ } \ if (!strcmp((char *)name, "newParserInst")) { \ *pEtryPoint = newParserInst; \ } \ if (!strcmp((char *)name, "checkParserInst")) { \ *pEtryPoint = checkParserInst; \ } \ if (!strcmp((char *)name, "freeParserInst")) { \ *pEtryPoint = freeParserInst; \ } \ CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES /** * \brief Standard block for rscript function modules. */ #define CODEqueryEtryPt_STD_FMOD_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "getFunctArray")) { \ *pEtryPoint = getFunctArray; \ } /** * \brief Standard block for strgen modules. */ #define CODEqueryEtryPt_STD_SMOD_QUERIES \ CODEqueryEtryPt_STD_MOD_QUERIES if (!strcmp((char *)name, "strgen")) { \ *pEtryPoint = strgen; \ } \ if (!strcmp((char *)name, "GetName")) { \ *pEtryPoint = GetStrgenName; \ } /** \} */ // end of module_entrypoint_blocks /* modInit() * This has an extra parameter, which is the specific name of the modInit * function. That is needed for built-in modules, which must have unique * names in order to link statically. Please note that this is always only * the case with modInit() and NO other entry point. The reason is that only * modInit() is visible form a linker/loader point of view. All other entry * points are passed via rsyslog-internal query functions and are defined * static inside the modules source. This is an important concept, as it allows * us to support different interface versions within a single module. (Granted, * we do not currently have different interface versions, so we can not put * it to a test - but our firm believe is that we can do all abstraction needed...) * * Extra Comments: * initialize the module * * Later, much more must be done. So far, we only return a pointer * to the queryEtryPt() function * TODO: do interface version checking & handshaking * iIfVersRequetsed is the version of the interface specification that the * caller would like to see being used. ipIFVersProvided is what we * decide to provide. * rgerhards, 2007-11-21: see modExit() comment below for important information * on the need to initialize static data with code. modInit() may be called on a * cached, left-in-memory copy of a previous incarnation. */ #define BEGINmodInit(uniqName) \ rsRetVal __attribute__((unused)) modInit##uniqName( \ int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), \ rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal(**)()), modInfo_t __attribute__((unused)) * pModInfo); \ rsRetVal __attribute__((unused)) modInit##uniqName( \ int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), \ rsRetVal (*pHostQueryEtryPt)(uchar *, rsRetVal(**)()), modInfo_t __attribute__((unused)) * pModInfo) { \ DEFiRet; \ rsRetVal (*pObjGetObjInterface)(obj_if_t * pIf); #define CODESTARTmodInit \ assert(pHostQueryEtryPt != NULL); \ iRet = pHostQueryEtryPt((uchar *)"objGetObjInterface", &pObjGetObjInterface); \ if ((iRet != RS_RET_OK) || (pQueryEtryPt == NULL) || (ipIFVersProvided == NULL) || \ (pObjGetObjInterface == NULL)) { \ return (iRet == RS_RET_OK) ? RS_RET_PARAM_ERROR : iRet; \ } \ /* now get the obj interface so that we can access other objects */ \ CHKiRet(pObjGetObjInterface(&obj)) /* do those initializations necessary for legacy config variables */ #define INITLegCnfVars initConfVars() #define ENDmodInit \ finalize_it : *pQueryEtryPt = queryEtryPt; \ RETiRet; \ } /* now come some check functions, which enable a standard way of obtaining feature * information from the core. feat is the to-be-tested feature and featVar is a * variable that receives the result (0-not support, 1-supported). * This must be a macro, so that it is put into the output's code. Otherwise, we * would need to rely on a library entry point, which is what we intend to avoid ;) * rgerhards, 2009-04-27 */ #define INITChkCoreFeature(featVar, feat) \ { \ rsRetVal MACRO_Ret; \ rsRetVal (*pQueryCoreFeatureSupport)(int *, unsigned); \ int bSupportsIt; \ featVar = 0; \ MACRO_Ret = pHostQueryEtryPt((uchar *)"queryCoreFeatureSupport", &pQueryCoreFeatureSupport); \ if (MACRO_Ret == RS_RET_OK) { \ /* found entry point, so let's see if core supports it */ \ CHKiRet((*pQueryCoreFeatureSupport)(&bSupportsIt, feat)); \ if (bSupportsIt) featVar = 1; \ } else if (MACRO_Ret != RS_RET_ENTRY_POINT_NOT_FOUND) { \ ABORT_FINALIZE(MACRO_Ret); /* Something else went wrong, what is not acceptable */ \ } \ } /* definitions for host API queries */ #define CODEmodInit_QueryRegCFSLineHdlr CHKiRet(pHostQueryEtryPt((uchar *)"regCfSysLineHdlr", &omsdRegCFSLineHdlr)); /* modExit() * This is the counterpart to modInit(). It destroys a module and makes it ready for * unloading. It is similiar to freeInstance() for the instance data. Please note that * this entry point needs to free any module-global data structures and registrations. * For example, the CfSysLineHandlers a module has registered need to be unregistered * here. This entry point is only called immediately before unloading of the module. So * it is likely to be destroyed. HOWEVER, the caller may decide to keep the module cached. * So a module must never assume that it is actually destroyed. A call to modInit() may * happen immediately after modExit(). So a module can NOT assume that static data elements * are being re-initialized by the loader - this must always be done by module code itself. * It is suggested to do this in modInit(). - rgerhards, 2007-11-21 */ #define BEGINmodExit \ static rsRetVal modExit(void) { \ DEFiRet; #define CODESTARTmodExit #define ENDmodExit \ RETiRet; \ } /* beginCnfLoad() * This is a function tells an input module that a new config load begins. * The core passes in a handle to the new module-specific module conf to * the module. -- rgerards, 2011-05-03 */ #define BEGINbeginCnfLoad \ static rsRetVal beginCnfLoad(modConfData_t **ptr, __attribute__((unused)) rsconf_t *pConf) { \ modConfData_t *pModConf; \ DEFiRet; #define CODESTARTbeginCnfLoad \ if ((pModConf = calloc(1, sizeof(modConfData_t))) == NULL) { \ *ptr = NULL; \ return RS_RET_OUT_OF_MEMORY; \ } #define ENDbeginCnfLoad \ *ptr = pModConf; \ RETiRet; \ } /* setModCnf() * This function permits to set module global parameters via the v2 config * interface. It may be called multiple times, but parameters must not be * set in a conflicting way. The module must use its current config load * context when processing the directives. * Note that lst may be NULL, especially if the module is loaded via the * legacy config system. The module must check for this. * NOTE: This entry point must only be implemented if module global * parameters are actually required. */ #define BEGINsetModCnf \ static rsRetVal setModCnf(struct nvlst *lst) { \ DEFiRet; #define CODESTARTsetModCnf #define ENDsetModCnf \ RETiRet; \ } /* endCnfLoad() * This is a function tells an input module that the current config load ended. * It gets a last chance to make changes to its in-memory config object. After * this call, the config object must no longer be changed. * The pModConf pointer passed into the module must no longer be used. * rgerards, 2011-05-03 */ #define BEGINendCnfLoad \ static rsRetVal endCnfLoad(modConfData_t *ptr) { \ modConfData_t __attribute__((unused)) *pModConf = (modConfData_t *)ptr; \ DEFiRet; #define CODESTARTendCnfLoad #define ENDendCnfLoad \ RETiRet; \ } /* checkCnf() * Check the provided config object for errors, inconsistencies and other things * that do not work out. * NOTE: no part of the config must be activated, so some checks that require * activation can not be done in this entry point. They must be done in the * activateConf() stage, where the caller must also be prepared for error * returns. * rgerhards, 2011-05-03 */ #define BEGINcheckCnf \ static rsRetVal checkCnf(modConfData_t *ptr) { \ modConfData_t __attribute__((unused)) *pModConf = (modConfData_t *)ptr; \ DEFiRet; #define CODESTARTcheckCnf #define ENDcheckCnf \ RETiRet; \ } /* checkParserInst() - verifies a parser instance configuration */ #define BEGINcheckParserInst \ static rsRetVal checkParserInst(void *const ptr) { \ instanceConf_t __attribute__((unused)) *pInst = (instanceConf_t *)ptr; \ DEFiRet; #define CODESTARTcheckParserInst #define ENDcheckParserInst \ RETiRet; \ } /* activateCnfPrePrivDrop() * Initial config activation, before dropping privileges. This is an optional * entry points that should only be implemented by those module that really need * it. Processing should be limited to the minimum possible. Main activation * should happen in the normal activateCnf() call. * rgerhards, 2011-05-06 */ #define BEGINactivateCnfPrePrivDrop \ static rsRetVal activateCnfPrePrivDrop(modConfData_t *ptr) { \ modConfData_t *pModConf = (modConfData_t *)ptr; \ DEFiRet; #define CODESTARTactivateCnfPrePrivDrop #define ENDactivateCnfPrePrivDrop \ RETiRet; \ } /* activateCnf() * This activates the provided config, and may report errors if they are detected * during activation. * rgerhards, 2011-05-03 */ #define BEGINactivateCnf \ static rsRetVal activateCnf(modConfData_t *ptr) { \ modConfData_t __attribute__((unused)) *pModConf = (modConfData_t *)ptr; \ DEFiRet; #define CODESTARTactivateCnf #define ENDactivateCnf \ RETiRet; \ } /* freeCnf() * This is a function tells an input module that it must free all data * associated with the passed-in module config. * rgerhards, 2011-05-03 */ #define BEGINfreeCnf \ static rsRetVal freeCnf(void *ptr) { \ modConfData_t *pModConf = (modConfData_t *)ptr; \ DEFiRet; #define CODESTARTfreeCnf #define ENDfreeCnf \ if (pModConf != NULL) free(pModConf); /* we need to free this in any case */ \ RETiRet; \ } /* runInput() * This is the main function for input modules. It is used to gather data from the * input source and submit it to the message queue. Each runInput() instance has its own * thread. This is handled by the rsyslog engine. It needs to spawn off new threads only * if there is a module-internal need to do so. */ #define BEGINrunInput \ static rsRetVal runInput(thrdInfo_t __attribute__((unused)) * pThrd) { \ DEFiRet; #define CODESTARTrunInput dbgSetThrdName((uchar *)__FILE__); /* we need to provide something better later */ #define ENDrunInput \ RETiRet; \ } /* willRun() * This is a function that will be replaced in the longer term. It is used so * that a module can tell the caller if it will run or not. This is to be replaced * when we introduce input module instances. However, these require config syntax * changes and I may (or may not... ;)) hold that until another config file * format is available. -- rgerhards, 2007-12-17 * returns RS_RET_NO_RUN if it will not run (RS_RET_OK or error otherwise) */ #define BEGINwillRun \ static rsRetVal willRun(void) { \ DEFiRet; #define CODESTARTwillRun #define ENDwillRun \ RETiRet; \ } /* afterRun() * This function is called after an input module has been run and its thread has * been terminated. It shall do any necessary cleanup. * This is expected to evolve into a freeInstance type of call once the input module * interface evolves to support multiple instances. * rgerhards, 2007-12-17 */ #define BEGINafterRun \ static rsRetVal afterRun(void) { \ DEFiRet; #define CODESTARTafterRun #define ENDafterRun \ RETiRet; \ } /* doHUP() * This function is optional. Currently, it is available to output plugins * only, but may be made available to other types of plugins in the future. * A plugin does not need to define this entry point. If if does, it gets * called when a HUP at the action level is to be done. A plugin should register * this function so that it can close files, connection or other ressources * on HUP - if it can be assume the user wanted to do this as a part of HUP * processing. Note that the name "HUP" has historical reasons, it stems back * to the infamous SIGHUP which was sent to restart a syslogd. We still retain * that legacy, but may move this to a different signal. * rgerhards, 2008-10-22 */ #define CODEqueryEtryPt_doHUP \ if (!strcmp((char *)name, "doHUP")) { \ *pEtryPoint = doHUP; \ } #define BEGINdoHUP \ static rsRetVal doHUP(instanceData __attribute__((unused)) * pData) { \ DEFiRet; #define CODESTARTdoHUP #define ENDdoHUP \ RETiRet; \ } /* doHUPParser() */ #define CODEqueryEtryPt_doHUPParser \ if (!strcmp((char *)name, "doHUP")) { \ *pEtryPoint = doHUP; \ } #define BEGINdoHUPParser \ static rsRetVal doHUP(instanceConf_t __attribute__((unused)) * pData) { \ DEFiRet; #define CODESTARTdoHUPParser #define ENDdoHUPParser \ RETiRet; \ } /* doHUPWrkr() * This is like doHUP(), but on an action worker level. * rgerhards, 2015-03-25 */ #define CODEqueryEtryPt_doHUPWrkr \ if (!strcmp((char *)name, "doHUPWrkr")) { \ *pEtryPoint = doHUPWrkr; \ } #define BEGINdoHUPWrkr \ static rsRetVal doHUPWrkr(wrkrInstanceData_t __attribute__((unused)) * pWrkrData) { \ DEFiRet; #define CODESTARTdoHUPWrkr #define ENDdoHUPWrkr \ RETiRet; \ } /* SetShutdownImmdtPtr() * This function is optional. If defined by an output plugin, it is called * each time the action is invoked to set the "ShutdownImmediate" pointer, * which is used during termination to indicate the action should shutdown * as quickly as possible. */ #define CODEqueryEtryPt_SetShutdownImmdtPtr \ else if (!strcmp((char *)name, "SetShutdownImmdtPtr")) { \ *pEtryPoint = SetShutdownImmdtPtr; \ } #define BEGINSetShutdownImmdtPtr \ static rsRetVal SetShutdownImmdtPtr(instanceData __attribute__((unused)) * pData, int *pPtr) { \ DEFiRet; #define CODESTARTSetShutdownImmdtPtr #define ENDSetShutdownImmdtPtr \ RETiRet; \ } /* parse() - main entry point of parser modules (v1 config interface) */ #define BEGINparse \ static rsRetVal parse(smsg_t *pMsg) { \ DEFiRet; #define CODESTARTparse assert(pMsg != NULL); #define ENDparse \ RETiRet; \ } /* parse2() - main entry point of parser modules (v2+ config interface) */ #define BEGINparse2 \ static rsRetVal parse2(instanceConf_t *const pInst, smsg_t *pMsg) { \ DEFiRet; #define CODESTARTparse2 \ assert(pInst != NULL); \ assert(pMsg != NULL); #define ENDparse2 \ RETiRet; \ } /* strgen() - main entry point of parser modules * Note that we do NOT use size_t as this permits us to store the * values directly into optimized heap structures. * ppBuf is the buffer pointer * pLenBuf is the current max size of this buffer * pStrLen is an output parameter that MUST hold the length * of the generated string on exit (this is cached) */ #define BEGINstrgen \ static rsRetVal strgen(smsg_t *const pMsg, actWrkrIParams_t *const iparam) { \ DEFiRet; #define CODESTARTstrgen assert(pMsg != NULL); #define ENDstrgen \ RETiRet; \ } /* getFunctArray() - main entry point of parser modules * Note that we do NOT use size_t as this permits us to store the * values directly into optimized heap structures. * ppBuf is the buffer pointer * pLenBuf is the current max size of this buffer * pStrLen is an output parameter that MUST hold the length * of the generated string on exit (this is cached) */ #define BEGINgetFunctArray \ static rsRetVal getFunctArray(int *const version, const struct scriptFunct **const functArray) { \ DEFiRet; #define CODESTARTgetFunctArray #define ENDgetFunctArray \ RETiRet; \ } /* function to specify the parser name. This is done via a single command which * receives a ANSI string as parameter. */ #define PARSER_NAME(x) \ static rsRetVal GetParserName(uchar **ppSz) { \ *ppSz = UCHAR_CONSTANT(x); \ return RS_RET_OK; \ } /* function to specify the strgen name. This is done via a single command which * receives a ANSI string as parameter. */ #define STRGEN_NAME(x) \ static rsRetVal GetStrgenName(uchar **ppSz) { \ *ppSz = UCHAR_CONSTANT(x); \ return RS_RET_OK; \ } #endif /* #ifndef MODULE_TEMPLATE_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/srUtils.h0000644000000000000000000000013215055605325016040 xustar0030 mtime=1756826325.652800728 30 atime=1764930980.056678825 30 ctime=1764935923.188576657 rsyslog-8.2512.0/runtime/srUtils.h0000664000175000017500000001024415055605325015505 0ustar00rgerrger/*! \file srUtils.h * \brief General, small utilities that fit nowhere else. * * \author Rainer Gerhards * \date 2003-09-09 * Coding begun. * * Copyright 2003-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __SRUTILS_H_INCLUDED__ #define __SRUTILS_H_INCLUDED__ 1 #include #include /* syslog names */ #ifndef LOG_MAKEPRI #define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) #endif #define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ #define TABLE_NOPRI 0 /* Value to indicate no priority in f_pmask */ #define TABLE_ALLPRI 0xFF /* Value to indicate all priorities in f_pmask */ #define LOG_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) /* mark "facility" */ typedef struct syslogName_s { const char *c_name; int c_val; } syslogName_t; extern syslogName_t syslogPriNames[]; extern syslogName_t syslogFacNames[]; /** * A reimplementation of itoa(), as this is not available * on all platforms. We used the chance to make an interface * that fits us well, so it is no longer plain itoa(). * * This method works with the US-ASCII alphabet. If you port this * to e.g. EBCDIC, you need to make a small adjustment. Keep in mind, * that on the wire it MUST be US-ASCII, so basically all you need * to do is replace the constant '0' with 0x30 ;). * * \param pBuf Caller-provided buffer that will receive the * generated ASCII string. * * \param iLenBuf Length of the caller-provided buffer. * * \param iToConv The integer to be converted. */ rsRetVal srUtilItoA(char *pBuf, int iLenBuf, number_t iToConv); /** * A method to duplicate a string for which the length is known. * Len must be the length in characters WITHOUT the trailing * '\0' byte. * rgerhards, 2007-07-10 */ unsigned char *srUtilStrDup(unsigned char *pOld, size_t len); /** * A method to create a directory and all its missing parents for * a given file name. Please not that the rightmost element is * considered to be a file name and thus NO directory is being created * for it. * added 2007-07-17 by rgerhards */ int makeFileParentDirs(const uchar *const szFile, const size_t lenFile, const mode_t mode, const uid_t uid, const gid_t gid, const int bFailOnChown); int execProg(uchar *program, int bWait, uchar *arg); void skipWhiteSpace(uchar **pp); rsRetVal genFileName( uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName, size_t lenFName, int64_t lNum, int lNumDigits); int getNumberDigits(long lNum); rsRetVal timeoutComp(struct timespec *pt, long iTimeout); long timeoutVal(struct timespec *pt); void mutexCancelCleanup(void *arg); void srSleep(int iSeconds, int iuSeconds); char *rs_strerror_r(int errnum, char *buf, size_t buflen); int decodeSyslogName(uchar *name, syslogName_t *codetab); int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep); rsRetVal getFileSize(uchar *pszName, off_t *pSize); int containsGlobWildcard(char *str); void seedRandomNumber(void); void seedRandomNumberForChild(void); #define MAX_RANDOM_NUMBER RAND_MAX long int randomNumber(void); long long currentTimeMills(void); rsRetVal ATTR_NONNULL() split_binary_parameters(uchar **const szBinary, char ***const aParams, int *const iParams, es_str_t *const param_binary); #endif /* #ifndef __SRUTILS_H_INCLUDED__ */ rsyslog-8.2512.0/runtime/PaxHeaders/libossl.c0000644000000000000000000000013215055605325016035 xustar0030 mtime=1756826325.646800638 30 atime=1764931130.139143215 30 ctime=1764935923.089575142 rsyslog-8.2512.0/runtime/libossl.c0000664000175000017500000004610715055605325015511 0ustar00rgerrger/* libossl.c - rsyslog's openssl based crypto provider * * * We need to store some additional information in support of encryption. * For this, we create a side-file, which is named like the actual log * file, but with the suffix ".encinfo" appended. It contains the following * records: * IV: The initial vector used at block start. Also indicates start * start of block. * END: The end offset of the block, as uint64_t in decimal notation. * This is used during encryption to know when the current * encryption block ends. * For the current implementation, there must always be an IV record * followed by an END record. Each records is LF-terminated. Record * types can simply be extended in the future by specifying new * types (like "IV") before the colon. * To identify a file as rsyslog encryption info file, it must start with * the line "FILETYPE:rsyslog-enrcyption-info" * There are some size constraints: the recordtype must be 31 bytes at * most and the actual value (between : and LF) must be 1023 bytes at most. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "debug.h" #include "libossl.h" #include "libcry_common.h" #define READBUF_SIZE 4096 /* size of the read buffer */ static rsRetVal rsosslBlkBegin(osslfile gf); /* read a key from a key file * @param[out] key - key buffer, must be freed by caller * @param[out] keylen - length of buffer * @returns 0 if OK, something else otherwise (we do not use * iRet as this is also called from non-rsyslog w/o runtime) * on error, errno is set and can be queried * The key length is limited to 64KiB to prevent DoS. * Note well: key is a blob, not a C string (NUL may be present!) */ int osslGetKeyFromFile(const char* const fn, char** const key, unsigned* const keylen) { struct stat sb; int r = -1; const int fd = open(fn, O_RDONLY); if (fd < 0) goto done; if (fstat(fd, &sb) == -1) goto done; if (sb.st_size > 64 * 1024) { errno = EMSGSIZE; goto done; } if ((*key = malloc(sb.st_size)) == NULL) goto done; if (read(fd, *key, sb.st_size) != sb.st_size) goto done; *keylen = sb.st_size; r = 0; done: if (fd >= 0) { close(fd); } return r; } static void addPadding(osslfile pF, uchar* buf, size_t* plen) { unsigned i; size_t nPad; nPad = (pF->blkLength - *plen % pF->blkLength) % pF->blkLength; DBGPRINTF("libgcry: addPadding %zd chars, blkLength %zd, mod %zd, pad %zd\n", *plen, pF->blkLength, *plen % pF->blkLength, nPad); for (i = 0; i < nPad; ++i) buf[(*plen) + i] = 0x00; (*plen) += nPad; } static void ATTR_NONNULL() removePadding(uchar* const buf, size_t* const plen) { const size_t len = *plen; size_t iSrc, iDst; iSrc = 0; /* skip to first NUL */ while (iSrc < len && buf[iSrc] == '\0') { ++iSrc; } iDst = iSrc; while (iSrc < len) { if (buf[iSrc] != 0x00) buf[iDst++] = buf[iSrc]; ++iSrc; } *plen = iDst; } static rsRetVal eiWriteRec(osslfile gf, const char* recHdr, size_t lenRecHdr, const char* buf, size_t lenBuf) { struct iovec iov[3]; ssize_t nwritten, towrite; DEFiRet; iov[0].iov_base = (void*)recHdr; iov[0].iov_len = lenRecHdr; iov[1].iov_base = (void*)buf; iov[1].iov_len = lenBuf; iov[2].iov_base = (void*)"\n"; iov[2].iov_len = 1; towrite = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; nwritten = writev(gf->fd, iov, sizeof(iov) / sizeof(struct iovec)); if (nwritten != towrite) { DBGPRINTF( "eiWrite%s: error writing file, towrite %d, " "nwritten %d\n", recHdr, (int)towrite, (int)nwritten); ABORT_FINALIZE(RS_RET_EI_WR_ERR); } DBGPRINTF("encryption info file %s: written %s, len %d\n", recHdr, gf->eiName, (int)nwritten); finalize_it: RETiRet; } static rsRetVal eiOpenRead(osslfile gf) { DEFiRet; gf->fd = open((char*)gf->eiName, O_RDONLY | O_NOCTTY | O_CLOEXEC); if (gf->fd == -1) { ABORT_FINALIZE(errno == ENOENT ? RS_RET_EI_NO_EXISTS : RS_RET_EI_OPN_ERR); } finalize_it: RETiRet; } static rsRetVal eiRead(osslfile gf) { ssize_t nRead; DEFiRet; if (gf->readBuf == NULL) { CHKmalloc(gf->readBuf = malloc(READBUF_SIZE)); } nRead = read(gf->fd, gf->readBuf, READBUF_SIZE); if (nRead <= 0) { ABORT_FINALIZE(RS_RET_ERR); } gf->readBufMaxIdx = (int16_t)nRead; gf->readBufIdx = 0; finalize_it: RETiRet; } /* returns EOF on any kind of error */ static int eiReadChar(osslfile gf) { int c; if (gf->readBufIdx >= gf->readBufMaxIdx) { if (eiRead(gf) != RS_RET_OK) { c = EOF; goto finalize_it; } } c = gf->readBuf[gf->readBufIdx++]; finalize_it: return c; } static rsRetVal eiCheckFiletype(osslfile gf) { char hdrBuf[128]; size_t toRead, didRead; sbool bNeedClose = 0; DEFiRet; if (gf->fd == -1) { CHKiRet(eiOpenRead(gf)); assert(gf->fd != -1); /* cannot happen after successful return */ bNeedClose = 1; } if (Debug) memset(hdrBuf, 0, sizeof(hdrBuf)); /* for dbgprintf below! */ toRead = sizeof("FILETYPE:") - 1 + sizeof(RSGCRY_FILETYPE_NAME) - 1 + 1; didRead = read(gf->fd, hdrBuf, toRead); if (bNeedClose) { close(gf->fd); gf->fd = -1; } DBGPRINTF("eiCheckFiletype read %zd bytes: '%s'\n", didRead, hdrBuf); if (didRead != toRead || strncmp(hdrBuf, "FILETYPE:" RSGCRY_FILETYPE_NAME "\n", toRead)) iRet = RS_RET_EI_INVLD_FILE; finalize_it: RETiRet; } /* rectype/value must be EIF_MAX_*_LEN+1 long! * returns 0 on success or something else on error/EOF */ static rsRetVal eiGetRecord(osslfile gf, char* rectype, char* value) { unsigned short i, j; int c; DEFiRet; c = eiReadChar(gf); if (c == EOF) { ABORT_FINALIZE(RS_RET_NO_DATA); } for (i = 0; i < EIF_MAX_RECTYPE_LEN; ++i) { if (c == ':' || c == EOF) break; rectype[i] = c; c = eiReadChar(gf); } if (c != ':') { ABORT_FINALIZE(RS_RET_ERR); } rectype[i] = '\0'; j = 0; for (++i; i < EIF_MAX_VALUE_LEN; ++i, ++j) { c = eiReadChar(gf); if (c == '\n' || c == EOF) break; value[j] = c; } if (c != '\n') { ABORT_FINALIZE(RS_RET_ERR); } value[j] = '\0'; finalize_it: RETiRet; } static rsRetVal eiGetIV(osslfile gf, uchar* iv, size_t leniv) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; size_t valueLen; unsigned short i, j; unsigned char nibble; DEFiRet; CHKiRet(eiGetRecord(gf, rectype, value)); const char* const cmp_IV = "IV"; // work-around for static analyzer if (strcmp(rectype, cmp_IV)) { DBGPRINTF( "no IV record found when expected, record type " "seen is '%s'\n", rectype); ABORT_FINALIZE(RS_RET_ERR); } valueLen = strlen(value); if (valueLen / 2 != leniv) { DBGPRINTF("length of IV is %zd, expected %zd\n", valueLen / 2, leniv); ABORT_FINALIZE(RS_RET_ERR); } for (i = j = 0; i < valueLen; ++i) { if (value[i] >= '0' && value[i] <= '9') nibble = value[i] - '0'; else if (value[i] >= 'a' && value[i] <= 'f') nibble = value[i] - 'a' + 10; else { DBGPRINTF("invalid IV '%s'\n", value); ABORT_FINALIZE(RS_RET_ERR); } if (i % 2 == 0) iv[j] = nibble << 4; else iv[j++] |= nibble; } finalize_it: RETiRet; } static rsRetVal eiGetEND(osslfile gf, off64_t* offs) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; DEFiRet; CHKiRet(eiGetRecord(gf, rectype, value)); const char* const const_END = "END"; // clang static analyzer work-around if (strcmp(rectype, const_END)) { DBGPRINTF( "no END record found when expected, record type " "seen is '%s'\n", rectype); ABORT_FINALIZE(RS_RET_ERR); } *offs = atoll(value); finalize_it: RETiRet; } static rsRetVal eiOpenAppend(osslfile gf) { rsRetVal localRet; DEFiRet; localRet = eiCheckFiletype(gf); if (localRet == RS_RET_OK) { gf->fd = open((char*)gf->eiName, O_WRONLY | O_APPEND | O_NOCTTY | O_CLOEXEC, 0600); if (gf->fd == -1) { ABORT_FINALIZE(RS_RET_EI_OPN_ERR); } } else if (localRet == RS_RET_EI_NO_EXISTS) { /* looks like we need to create a new file */ gf->fd = open((char*)gf->eiName, O_WRONLY | O_CREAT | O_NOCTTY | O_CLOEXEC, 0600); if (gf->fd == -1) { ABORT_FINALIZE(RS_RET_EI_OPN_ERR); } CHKiRet(eiWriteRec(gf, "FILETYPE:", 9, RSGCRY_FILETYPE_NAME, sizeof(RSGCRY_FILETYPE_NAME) - 1)); } else { gf->fd = -1; ABORT_FINALIZE(localRet); } DBGPRINTF("encryption info file %s: opened as #%d\n", gf->eiName, gf->fd); finalize_it: RETiRet; } static rsRetVal __attribute__((nonnull(2))) eiWriteIV(osslfile gf, const uchar* const iv) { static const char hexchars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; unsigned iSrc, iDst; char hex[4096]; DEFiRet; if (gf->blkLength > sizeof(hex) / 2) { DBGPRINTF( "eiWriteIV: crypto block len way too large, aborting " "write"); ABORT_FINALIZE(RS_RET_ERR); } for (iSrc = iDst = 0; iSrc < gf->blkLength; ++iSrc) { hex[iDst++] = hexchars[iv[iSrc] >> 4]; hex[iDst++] = hexchars[iv[iSrc] & 0x0f]; } iRet = eiWriteRec(gf, "IV:", 3, hex, gf->blkLength * 2); finalize_it: RETiRet; } /* we do not return an error state, as we MUST close the file, * no matter what happens. */ static void eiClose(osslfile gf, off64_t offsLogfile) { char offs[21]; size_t len; if (gf->fd == -1) return; if (gf->openMode == 'w') { /* 2^64 is 20 digits, so the snprintf buffer is large enough */ len = snprintf(offs, sizeof(offs), "%lld", (long long)offsLogfile); eiWriteRec(gf, "END:", 4, offs, len); } EVP_CIPHER_CTX_free(gf->chd); free(gf->readBuf); close(gf->fd); gf->fd = -1; DBGPRINTF("encryption info file %s: closed\n", gf->eiName); } /* this returns the number of bytes left inside the block or -1, if the block * size is unbounded. The function automatically handles end-of-block and begins * to read the next block in this case. */ rsRetVal osslfileGetBytesLeftInBlock(osslfile gf, ssize_t* left) { DEFiRet; if (gf->bytesToBlkEnd == 0) { DBGPRINTF("libossl: end of current crypto block\n"); EVP_CIPHER_CTX_free(gf->chd); CHKiRet(rsosslBlkBegin(gf)); } *left = gf->bytesToBlkEnd; finalize_it: RETiRet; } /* this is a special functon for use by the rsyslog disk queue subsystem. It * needs to have the capability to delete state when a queue file is rolled * over. This simply generates the file name and deletes it. It must take care * of "all" state files, which currently happens to be a single one. */ rsRetVal osslfileDeleteState(uchar* logfn) { char fn[MAXFNAME + 1]; DEFiRet; snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX); fn[MAXFNAME] = '\0'; /* be on save side */ DBGPRINTF("ossl crypto provider deletes state file '%s' on request\n", fn); unlink(fn); RETiRet; } static rsRetVal osslfileConstruct(osslctx ctx, osslfile* pgf, uchar* logfn) { char fn[MAXFNAME + 1]; osslfile gf; DEFiRet; CHKmalloc(gf = calloc(1, sizeof(struct osslfile_s))); CHKmalloc(gf->chd = EVP_CIPHER_CTX_new()); gf->ctx = ctx; gf->fd = -1; snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX); fn[MAXFNAME] = '\0'; /* be on save side */ gf->eiName = (uchar*)strdup(fn); *pgf = gf; finalize_it: RETiRet; } osslctx osslCtxNew(void) { osslctx ctx; ctx = calloc(1, sizeof(struct osslctx_s)); if (ctx != NULL) { ctx->cipher = EVP_aes_128_cbc(); ctx->key = NULL; ctx->keyLen = -1; } return ctx; } int osslfileDestruct(osslfile gf, off64_t offsLogfile) { int r = 0; if (gf == NULL) goto done; DBGPRINTF("libossl: close file %s\n", gf->eiName); eiClose(gf, offsLogfile); if (gf->bDeleteOnClose) { DBGPRINTF("unlink file '%s' due to bDeleteOnClose set\n", gf->eiName); unlink((char*)gf->eiName); } free(gf->eiName); free(gf); done: return r; } void rsosslCtxDel(osslctx ctx) { if (ctx != NULL) { free(ctx->key); free(ctx); } } /* returns 0 on succes, positive if key length does not match and key * of return value size is required. */ int rsosslSetKey(osslctx ctx, unsigned char* key, uint16_t keyLen) { uint16_t reqKeyLen; int r; reqKeyLen = EVP_CIPHER_get_key_length(ctx->cipher); if (keyLen != reqKeyLen) { r = reqKeyLen; goto done; } ctx->keyLen = keyLen; ctx->key = malloc(keyLen); memcpy(ctx->key, key, keyLen); r = 0; done: return r; } rsRetVal rsosslSetAlgoMode(osslctx ctx, uchar* algorithm) { EVP_CIPHER* cipher; DEFiRet; cipher = EVP_CIPHER_fetch(NULL, (char*)algorithm, NULL); if (cipher == NULL) { ABORT_FINALIZE(RS_RET_CRY_INVLD_ALGO); } ctx->cipher = cipher; finalize_it: RETiRet; } /* We use random numbers to initiate the IV. Rsyslog runtime will ensure * we get a sufficiently large number. */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif static rsRetVal #if defined(__clang__) __attribute__((no_sanitize("shift"))) /* IV shift causes known overflow */ #endif seedIV(osslfile gf, uchar** iv) { long rndnum = 0; /* keep compiler happy -- this value is always overriden */ DEFiRet; CHKmalloc(*iv = calloc(1, gf->blkLength)); for (size_t i = 0; i < gf->blkLength; ++i) { const int shift = (i % 4) * 8; if (shift == 0) { /* need new random data? */ rndnum = randomNumber(); } (*iv)[i] = 0xff & ((rndnum & (255u << shift)) >> shift); } finalize_it: RETiRet; } static rsRetVal readIV(osslfile gf, uchar** iv) { rsRetVal localRet; DEFiRet; if (gf->fd == -1) { while (gf->fd == -1) { localRet = eiOpenRead(gf); if (localRet == RS_RET_EI_NO_EXISTS) { /* wait until it is created */ srSleep(0, 10000); } else { CHKiRet(localRet); } } CHKiRet(eiCheckFiletype(gf)); } *iv = malloc(gf->blkLength); /* do NOT zero-out! */ iRet = eiGetIV(gf, *iv, (size_t)gf->blkLength); finalize_it: RETiRet; } /* this tries to read the END record. HOWEVER, no such record may be * present, which is the case if we handle a currently-written to queue * file. On the other hand, the queue file may contain multiple blocks. So * what we do is try to see if there is a block end or not - and set the * status accordingly. Note that once we found no end-of-block, we will never * retry. This is because that case can never happen under current queue * implementations. -- gerhards, 2013-05-16 */ static rsRetVal readBlkEnd(osslfile gf) { off64_t blkEnd; DEFiRet; iRet = eiGetEND(gf, &blkEnd); if (iRet == RS_RET_OK) { gf->bytesToBlkEnd = (ssize_t)blkEnd; } else if (iRet == RS_RET_NO_DATA) { gf->bytesToBlkEnd = -1; } else { FINALIZE; } finalize_it: RETiRet; } /* module-init dummy for potential later use */ int rsosslInit(void) { return 0; } /* module-deinit dummy for potential later use */ void rsosslExit(void) { return; } /* Read the block begin metadata and set our state variables accordingly. * Can also be used to init the first block in write case. */ static rsRetVal rsosslBlkBegin(osslfile gf) { uchar* iv = NULL; DEFiRet; const char openMode = gf->openMode; // FIXME error handling if (openMode == 'r') { readIV(gf, &iv); readBlkEnd(gf); } else { CHKiRet(seedIV(gf, &iv)); } if (openMode == 'r') { if ((iRet = EVP_DecryptInit_ex(gf->chd, gf->ctx->cipher, NULL, gf->ctx->key, iv)) != 1) { DBGPRINTF("EVP_DecryptInit_ex failed: %d\n", iRet); ABORT_FINALIZE(RS_RET_ERR); } } else { if ((iRet = EVP_EncryptInit_ex(gf->chd, gf->ctx->cipher, NULL, gf->ctx->key, iv)) != 1) { DBGPRINTF("EVP_EncryptInit_ex failed: %d\n", iRet); ABORT_FINALIZE(RS_RET_ERR); } } if ((iRet = EVP_CIPHER_CTX_set_padding(gf->chd, 0)) != 1) { fprintf(stderr, "EVP_CIPHER_set_padding failed: %d\n", iRet); ABORT_FINALIZE(RS_RET_ERR); } if (openMode == 'w') { CHKiRet(eiOpenAppend(gf)); CHKiRet(eiWriteIV(gf, iv)); } finalize_it: free(iv); RETiRet; } rsRetVal rsosslInitCrypt(osslctx ctx, osslfile* pgf, uchar* fname, char openMode) { osslfile gf = NULL; DEFiRet; CHKiRet(osslfileConstruct(ctx, &gf, fname)); gf->openMode = openMode; gf->blkLength = EVP_CIPHER_get_block_size(ctx->cipher); CHKiRet(rsosslBlkBegin(gf)); *pgf = gf; finalize_it: if (iRet != RS_RET_OK && gf != NULL) osslfileDestruct(gf, -1); RETiRet; } rsRetVal rsosslDecrypt(osslfile pF, uchar* buf, size_t* len) { DEFiRet; int rc; if (pF->bytesToBlkEnd != -1) pF->bytesToBlkEnd -= *len; rc = EVP_DecryptUpdate(pF->chd, buf, (int*)len, buf, (int)*len); if (rc != 1) { DBGPRINTF("EVP_DecryptUpdate failed\n"); ABORT_FINALIZE(RS_RET_ERR); } removePadding(buf, len); dbgprintf("libossl: decrypted, bytesToBlkEnd %lld, buffer is now '%50.50s'\n", (long long)pF->bytesToBlkEnd, buf); finalize_it: RETiRet; } rsRetVal rsosslEncrypt(osslfile pF, uchar* buf, size_t* len) { DEFiRet; int tmplen; if (*len == 0) FINALIZE; addPadding(pF, buf, len); if (EVP_EncryptUpdate(pF->chd, buf, (int*)len, buf, (int)*len) != 1) { dbgprintf("EVP_EncryptUpdate failed\n"); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } if (EVP_EncryptFinal_ex(pF->chd, buf + *len, &tmplen) != 1) { dbgprintf("EVP_EncryptFinal_ex failed\n"); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } *len += tmplen; finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/obj.h0000644000000000000000000000013215055605325015145 xustar0030 mtime=1756826325.650800698 30 atime=1764930980.012678089 30 ctime=1764935923.207576948 rsyslog-8.2512.0/runtime/obj.h0000664000175000017500000001361615055605325014620 0ustar00rgerrger/* Definition of the generic obj class module. * * This module relies heavily on preprocessor macros in order to * provide fast execution time AND ease of use. * * Each object that uses this base class MUST provide a constructor with * the following interface: * * Destruct(pThis); * * A constructor is not necessary (except for some features, e.g. de-serialization). * If it is provided, it is a three-part constructor (to handle all cases with a * generic interface): * * Construct(&pThis); * SetProperty(pThis, property_t *); * ConstructFinalize(pThis); * * SetProperty() and ConstructFinalize() may also be called on an object * instance which has been Construct()'ed outside of this module. * * pThis always references to a pointer of the object. * * Copyright 2008-2025 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OBJ_H_INCLUDED #define OBJ_H_INCLUDED #include "obj-types.h" #include "var.h" #include "stream.h" /* macros */ /* the following one is a helper that prevents us from writing the * ever-same code at the end of Construct() */ #define OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP \ if (iRet == RS_RET_OK) { \ *ppThis = pThis; \ } else { \ if (pThis != NULL) free(pThis); \ } #define objSerializeSCALAR_VAR(strm, propName, propType, var) \ CHKiRet(obj.SerializeProp(strm, (uchar *)#propName, PROPTYPE_##propType, (void *)&var)) #define objSerializeSCALAR(strm, propName, propType) \ CHKiRet(obj.SerializeProp(strm, (uchar *)#propName, PROPTYPE_##propType, (void *)&pThis->propName)) #define objSerializePTR(strm, propName, propType) \ CHKiRet(obj.SerializeProp(strm, (uchar *)#propName, PROPTYPE_##propType, (void *)pThis->propName)) #define DEFobjStaticHelpers \ static objInfo_t __attribute__((unused)) *pObjInfoOBJ = NULL; \ DEFobjCurrIf(obj) #define objGetClassName(pThis) (((obj_t *)(pThis))->pObjInfo->pszID) #define objGetVersion(pThis) (((obj_t *)(pThis))->pObjInfo->iObjVers) /* the next macro MUST be called in Constructors: */ #ifndef NDEBUG /* this means if debug... */ #define objConstructSetObjInfo(pThis) \ ((obj_t *)(pThis))->pObjInfo = pObjInfoOBJ; \ ((obj_t *)(pThis))->pszName = NULL; \ ((obj_t *)(pThis))->iObjCooCKiE = 0xBADEFEE #else #define objConstructSetObjInfo(pThis) \ ((obj_t *)(pThis))->pObjInfo = pObjInfoOBJ; \ ((obj_t *)(pThis))->pszName = NULL #endif #define objSerialize(pThis) (((obj_t *)(pThis))->pObjInfo->objMethods[objMethod_SERIALIZE]) #define OBJSetMethodHandler(methodID, pHdlr) CHKiRet(obj.InfoSetMethod(pObjInfoOBJ, methodID, (rsRetVal(*)())pHdlr)) /* interfaces */ BEGINinterface(obj) /* name must also be changed in ENDinterface macro! */ rsRetVal (*UseObj)(const char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf); rsRetVal (*ReleaseObj)(const char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf); rsRetVal (*InfoConstruct)(objInfo_t **ppThis, uchar *pszID, int iObjVers, rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *), rsRetVal (*pQueryIF)(interface_t *), modInfo_t *); rsRetVal (*DestructObjSelf)(obj_t *pThis); rsRetVal (*BeginSerializePropBag)(strm_t *pStrm, obj_t *pObj); rsRetVal (*InfoSetMethod)(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void *)); rsRetVal (*BeginSerialize)(strm_t *pStrm, obj_t *pObj); rsRetVal (*SerializeProp)(strm_t *pStrm, uchar *pszPropName, propType_t propType, void *pUsr); rsRetVal (*EndSerialize)(strm_t *pStrm); rsRetVal (*RegisterObj)(uchar *pszObjName, objInfo_t *pInfo); rsRetVal (*UnregisterObj)(uchar *pszObjName); rsRetVal (*Deserialize)(void *ppObj, uchar *pszTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t *, void *), void *pUsr); rsRetVal (*DeserializePropBag)(obj_t *pObj, strm_t *pStrm); rsRetVal (*SetName)(obj_t *pThis, uchar *pszName); uchar *(*GetName)(obj_t *pThis); ENDinterface(obj) #define objCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */ /* prototypes */ /* the following define *is* necessary, because it provides the root way of obtaining * interfaces (at some place we need to start our query... */ rsRetVal objGetObjInterface(obj_if_t *pIf); PROTOTYPEObjClassInit(obj); PROTOTYPEObjClassExit(obj); rsRetVal objDeserializeWithMethods(void *ppObj, uchar *pszTypeExpected, int lenTypeExpected, strm_t *pStrm, rsRetVal (*fFixup)(obj_t *, void *), void *pUsr, rsRetVal (*objConstruct)(void **), rsRetVal (*objConstructFinalize)(void *), rsRetVal (*objDeserialize)(void *, strm_t *)); rsRetVal objDeserializeProperty(var_t *pProp, strm_t *pStrm); uchar *objGetName(obj_t *pThis); /* the following definition is only for "friends" */ extern pthread_mutex_t mutObjGlobalOp; /* mutex to guard global operations of the object system */ #endif /* #ifndef OBJ_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/libgcry.h0000644000000000000000000000013215055605325016026 xustar0030 mtime=1756826325.646800638 30 atime=1764931130.128143038 30 ctime=1764935923.086575096 rsyslog-8.2512.0/runtime/libgcry.h0000664000175000017500000000532315055605325015475 0ustar00rgerrger/* libgcry.h - rsyslog's guardtime support library * * Copyright 2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LIBGCRY_H #define INCLUDED_LIBGCRY_H #include #include struct gcryctx_s { uchar *key; size_t keyLen; int algo; int mode; }; typedef struct gcryctx_s *gcryctx; typedef struct gcryfile_s *gcryfile; /* this describes a file, as far as libgcry is concerned */ struct gcryfile_s { gcry_cipher_hd_t chd; /* cypher handle */ size_t blkLength; /* size of low-level crypto block */ uchar *eiName; /* name of .encinfo file */ int fd; /* descriptor of .encinfo file (-1 if not open) */ char openMode; /* 'r': read, 'w': write */ gcryctx ctx; uchar *readBuf; int16_t readBufIdx; int16_t readBufMaxIdx; int8_t bDeleteOnClose; /* for queue support, similar to stream subsys */ ssize_t bytesToBlkEnd; /* number of bytes remaining in current crypto block -1 means -> no end (still being writen to, queue files), 0 means -> end of block, new one must be started. */ }; int rsgcryInit(void); void rsgcryExit(void); int rsgcrySetKey(gcryctx ctx, unsigned char *key, uint16_t keyLen); rsRetVal rsgcrySetMode(gcryctx ctx, uchar *algoname); rsRetVal rsgcrySetAlgo(gcryctx ctx, uchar *modename); gcryctx gcryCtxNew(void); void rsgcryCtxDel(gcryctx ctx); int gcryfileDestruct(gcryfile gf, off64_t offsLogfile); rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode); rsRetVal rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len); rsRetVal rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len); rsRetVal gcryfileDeleteState(uchar *fn); rsRetVal gcryfileGetBytesLeftInBlock(gcryfile gf, ssize_t *left); int rsgcryModename2Mode(char *const __restrict__ modename); int rsgcryAlgoname2Algo(char *const __restrict__ algoname); /* Note: gf may validly be NULL, e.g. if file has not yet been opened! */ static inline void __attribute__((unused)) gcryfileSetDeleteOnClose(gcryfile gf, const int val) { if (gf != NULL) gf->bDeleteOnClose = val; } #endif /* #ifndef INCLUDED_LIBGCRY_H */ rsyslog-8.2512.0/runtime/PaxHeaders/rsyslog.c0000644000000000000000000000013215114522477016072 xustar0030 mtime=1764926783.041632005 30 atime=1764926784.239661412 30 ctime=1764935923.093575203 rsyslog-8.2512.0/runtime/rsyslog.c0000664000175000017500000003010715114522477015537 0ustar00rgerrger/* rsyslog.c - the main entry point into rsyslog's runtime library (RTL) * * This module contains all function which work on a RTL global level. It's * name is abbreviated to "rsrt" (rsyslog runtime). * * Please note that the runtime library tends to be plugin-safe. That is, it must be * initialized by calling a global initialization function. However, that * function checks if the library is already initialized and, if so, does * nothing except incrementing a refeence count. Similarly, the deinit * function does nothing as long as there are still other users (which * is tracked via the refcount). As such, it is safe to call init and * exit multiple times, as long as this are always matching calls. This * capability is needed for a plugin system, where one plugin never * knows what the other did. HOWEVER, as of this writing, not all runtime * library objects may work cleanly without static global data (the * debug system is a very good example of this). So while we aim at the * ability to work well in a plugin environment, things may not really work * out. If you intend to use the rsyslog runtime library inside plugins, * you should investigate the situation in detail. Please note that the * rsyslog project itself does not yet need this functionality - thus you * can safely assume it is totally untested ;). * * rgerhards, 2008-04-17: I have now once again checked on the plugin-safety. * Unfortunately, there is currently no hook at all with which we could * abstract a global data instance class. As such, we can NOT make the * runtime plugin-safe in the above-described sense. As the rsyslog * project itself does not need this functionality (and it is quesationable * if someone else ever will), we do currently do not make an effort to * support it. So if you intend to use rsyslog runtime inside a non-rsyslog * plugin system, be careful! * * The rsyslog runtime library is in general reentrant and thread-safe. There * are some intentional exceptions (e.g. inside the msg object). These are * documented. Any other threading and reentrency issue can be considered a bug. * * Module begun 2008-04-16 by Rainer Gerhards * * Copyright 2008-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #ifdef ENABLE_LIBLOGGING_STDLOG #include #endif #include "rsyslog.h" #include "obj.h" #include "stringbuf.h" #include "wti.h" #include "wtp.h" #include "datetime.h" #include "queue.h" #include "conf.h" #include "rsconf.h" #include "glbl.h" #include "errmsg.h" #include "prop.h" #include "ruleset.h" #include "parser.h" #include "lookup.h" #include "strgen.h" #include "statsobj.h" #include "atomic.h" #include "srUtils.h" pthread_attr_t default_thread_attr; #ifdef HAVE_PTHREAD_SETSCHEDPARAM struct sched_param default_sched_param; int default_thr_sched_policy; #endif /* globally visible static data - see comment in rsyslog.h for details */ uchar *glblModPath; /* module load path */ void (*glblErrLogger)(const int, const int, const uchar *) = dfltErrLogger; /* the error logger to use by the errmsg module */ /* static data */ static int iRefCount = 0; /* our refcount - it MUST exist only once inside a process (not thread) thus it is perfectly OK to use a static. MUST be initialized to 0! */ /* This is the default instance of the error logger. It simply writes the message * to stderr. It is expected that this is replaced by the runtime user very early * during startup (at least if the default is unsuitable). However, we provide a * default so that we can log errors during the initial phase, most importantly * during initialization. -- rgerhards. 2008-04-17 */ void dfltErrLogger(const int severity, const int iErr, const uchar *errMsg) { fprintf(stderr, "rsyslog internal message (%d,%d): %s\n", severity, iErr, errMsg); } /* set the error log function * rgerhards, 2008-04-18 */ void rsrtSetErrLogger(void (*errLogger)(const int, const int, const uchar *)) { assert(errLogger != NULL); glblErrLogger = errLogger; } /* globally initialze the runtime system * NOTE: this is NOT thread safe and must not be called concurrently. If that * ever poses a problem, we may use proper mutex calls - not considered needed yet. * If ppErrObj is provided, it receives a char pointer to the name of the object that * caused the problem (if one occurred). The caller must never free this pointer. If * ppErrObj is NULL, no such information will be provided. pObjIF is the pointer to * the "obj" object interface, which may be used to query any other rsyslog objects. * rgerhards, 2008-04-16 */ rsRetVal rsrtInit(const char **ppErrObj, obj_if_t *pObjIF) { DEFiRet; int ret; char errstr[1024]; if (iRefCount == 0) { seedRandomNumber(); /* init runtime only if not yet done */ #ifdef ENABLE_LIBLOGGING_STDLOG stdlog_init(0); #endif ret = pthread_attr_init(&default_thread_attr); if (ret != 0) { rs_strerror_r(ret, errstr, sizeof(errstr)); fprintf(stderr, "rsyslogd: pthread_attr_init failed during " "startup - can not continue. Error was %s\n", errstr); exit(1); } pthread_attr_setstacksize(&default_thread_attr, 4096 * 1024); #ifdef HAVE_PTHREAD_SETSCHEDPARAM ret = pthread_getschedparam(pthread_self(), &default_thr_sched_policy, &default_sched_param); if (ret != 0) { rs_strerror_r(ret, errstr, sizeof(errstr)); fprintf(stderr, "rsyslogd: pthread_getschedparam failed during " "startup - ignoring. Error was %s\n", errstr); default_thr_sched_policy = 0; /* should be default on all platforms */ } #if defined(_AIX) pthread_attr_setstacksize(&default_thread_attr, 4096 * 512); #endif ret = pthread_attr_setschedpolicy(&default_thread_attr, default_thr_sched_policy); if (ret != 0) { rs_strerror_r(ret, errstr, sizeof(errstr)); fprintf(stderr, "rsyslogd: pthread_attr_setschedpolicy failed during " "startup - tried to set priority %d, now using default " "priority instead. Error was: %s\n", default_thr_sched_policy, errstr); } ret = pthread_attr_setschedparam(&default_thread_attr, &default_sched_param); if (ret != 0) { rs_strerror_r(ret, errstr, sizeof(errstr)); fprintf(stderr, "rsyslogd: pthread_attr_setschedparam failed during " "startup - ignored Error was: %s\n", errstr); } ret = pthread_attr_setinheritsched(&default_thread_attr, PTHREAD_EXPLICIT_SCHED); if (ret != 0) { rs_strerror_r(ret, errstr, sizeof(errstr)); fprintf(stderr, "rsyslogd: pthread_attr_setinheritsched failed during " "startup - ignoring. Error was: %s\n", errstr); } #endif if (ppErrObj != NULL) *ppErrObj = "obj"; CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */ CHKiRet(objGetObjInterface(pObjIF)); /* this provides the root pointer for all other queries */ /* initialize core classes. We must be very careful with the order of events. Some * classes use others and if we do not initialize them in the right order, we may end * up with an invalid call. The most important thing that can happen is that an error * is detected and needs to be logged, wich in turn requires a broader number of classes * to be available. The solution is that we take care in the order of calls AND use a * class immediately after it is initialized. And, of course, we load those classes * first that we use ourselfs... -- rgerhards, 2008-03-07 */ if (ppErrObj != NULL) *ppErrObj = "statsobj"; CHKiRet(statsobjClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "prop"; CHKiRet(propClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "glbl"; CHKiRet(glblClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "msg"; CHKiRet(msgClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "ruleset"; CHKiRet(rulesetClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "wti"; CHKiRet(wtiClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "wtp"; CHKiRet(wtpClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "queue"; CHKiRet(qqueueClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "conf"; CHKiRet(confClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "parser"; CHKiRet(parserClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "strgen"; CHKiRet(strgenClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "rsconf"; CHKiRet(rsconfClassInit(NULL)); if (ppErrObj != NULL) *ppErrObj = "lookup"; CHKiRet(lookupClassInit()); if (ppErrObj != NULL) *ppErrObj = "dynstats"; CHKiRet(dynstatsClassInit()); if (ppErrObj != NULL) *ppErrObj = "perctile_stats"; CHKiRet(perctileClassInit()); /* dummy "classes" */ if (ppErrObj != NULL) *ppErrObj = "str"; CHKiRet(strInit()); } ++iRefCount; dbgprintf("rsyslog runtime initialized, version %s, current users %d\n", VERSION, iRefCount); finalize_it: RETiRet; } /* globally de-initialze the runtime system * NOTE: this is NOT thread safe and must not be called concurrently. If that * ever poses a problem, we may use proper mutex calls - not considered needed yet. * This function must be provided with the caller's obj object pointer. This is * automatically deinitialized by the runtime system. * rgerhards, 2008-04-16 */ rsRetVal rsrtExit(void) { DEFiRet; if (iRefCount == 1) { /* do actual de-init only if we are the last runtime user */ confClassExit(); glblClassExit(); rulesetClassExit(); wtiClassExit(); wtpClassExit(); strgenClassExit(); propClassExit(); statsobjClassExit(); objClassExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */ } --iRefCount; /* TODO we must deinit this pointer! pObjIF = NULL; / * no longer exists for this caller */ dbgprintf("rsyslog runtime de-initialized, current users %d\n", iRefCount); RETiRet; } /* returns 0 if the rsyslog runtime is not initialized and another value * if it is. This function is primarily meant to be used by runtime functions * itself. However, it is safe to call it before initializing the runtime. * Plugins should NOT rely on this function. The reason is that another caller * may have already initialized it but deinits it before this plugin is done. * So for plugins and like architectures, the right course of action is to * call rsrtInit() and rsrtExit(), which can be called by multiple callers. * rgerhards, 2008-04-16 */ int rsrtIsInit(void) { return iRefCount; } /* vim:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/parser.c0000644000000000000000000000013215055605325015662 xustar0030 mtime=1756826325.650800698 30 atime=1764930983.250732228 30 ctime=1764935923.154576137 rsyslog-8.2512.0/runtime/parser.c0000664000175000017500000006150115055605325015331 0ustar00rgerrger/* parser.c * This module contains functions for message parsers. It still needs to be * converted into an object (and much extended). * * Module begun 2008-10-09 by Rainer Gerhards (based on previous code from syslogd.c) * * Copyright 2008-2021 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "dirty.h" #include "msg.h" #include "obj.h" #include "datetime.h" #include "errmsg.h" #include "parser.h" #include "ruleset.h" #include "unicode-helper.h" #include "dirty.h" #include "cfsysline.h" /* some defines */ #define DEFUPRI (LOG_USER | LOG_NOTICE) /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) DEFobjCurrIf(ruleset) /* static data */ static char hexdigit[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; BEGINobjDestruct(parser) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(parser); DBGPRINTF("destructing parser '%s'\n", pThis->pName); if (pThis->pInst != NULL) { pThis->pModule->mod.pm.freeParserInst(pThis->pInst); } free(pThis->pName); ENDobjDestruct(parser) /* destruct a parser list. The list elements are destroyed, but the parser objects * themselves are not modified. (That is done at a late stage during rsyslogd * shutdown and need not be considered here.) */ static rsRetVal DestructParserList(parserList_t **ppListRoot) { parserList_t *pParsLst; parserList_t *pParsLstDel; pParsLst = *ppListRoot; while (pParsLst != NULL) { pParsLstDel = pParsLst; pParsLst = pParsLst->pNext; free(pParsLstDel); } *ppListRoot = NULL; return RS_RET_OK; } /* Add a parser to the list. We use a VERY simple and ineffcient algorithm, * but it is employed only for a few milliseconds during config processing. So * I prefer to keep it very simple and with simple data structures. Unfortunately, * we need to preserve the order, but I don't like to add a tail pointer as that * would require a container object. So I do the extra work to skip to the tail * when adding elements... * rgerhards, 2009-11-03 */ static rsRetVal AddParserToList(parserList_t **ppListRoot, parser_t *pParser) { parserList_t *pThis; parserList_t *pTail; DEFiRet; CHKmalloc(pThis = malloc(sizeof(parserList_t))); pThis->pParser = pParser; pThis->pNext = NULL; if (*ppListRoot == NULL) { pThis->pNext = *ppListRoot; *ppListRoot = pThis; } else { /* find tail first */ for (pTail = *ppListRoot; pTail->pNext != NULL; pTail = pTail->pNext) /* just search, do nothing else */ ; /* add at tail */ pTail->pNext = pThis; } DBGPRINTF("DDDDD: added parser '%s' to list %p\n", pParser->pName, ppListRoot); finalize_it: RETiRet; } void printParserList(parserList_t *pList) { while (pList != NULL) { dbgprintf("parser: %s\n", pList->pParser->pName); pList = pList->pNext; } } /* find a parser based on the provided name */ static rsRetVal FindParser(parserList_t *pParserListRoot, parser_t **ppParser, uchar *pName) { parserList_t *pThis; DEFiRet; for (pThis = pParserListRoot; pThis != NULL; pThis = pThis->pNext) { if (ustrcmp(pThis->pParser->pName, pName) == 0) { *ppParser = pThis->pParser; FINALIZE; /* found it, iRet still eq. OK! */ } } iRet = RS_RET_PARSER_NOT_FOUND; finalize_it: RETiRet; } /* --- END helper functions for parser list handling --- */ /* Add a an already existing parser to the default list. As usual, order * of calls is important (most importantly, that means the legacy parser, * which can process everything, MUST be added last!). * rgerhards, 2009-11-04 */ static rsRetVal AddDfltParser(uchar *pName) { parser_t *pParser; DEFiRet; CHKiRet(FindParser(loadConf->parsers.pParsLstRoot, &pParser, pName)); CHKiRet(AddParserToList(&loadConf->parsers.pDfltParsLst, pParser)); DBGPRINTF("Parser '%s' added to default parser set.\n", pName); finalize_it: RETiRet; } /* set the parser name - string is copied over, call can continue to use it, * but must free it if desired. */ static rsRetVal SetName(parser_t *pThis, uchar *name) { DEFiRet; ISOBJ_TYPE_assert(pThis, parser); assert(name != NULL); if (pThis->pName != NULL) { free(pThis->pName); pThis->pName = NULL; } CHKmalloc(pThis->pName = ustrdup(name)); finalize_it: RETiRet; } /* set a pointer to "our" module. Note that no module * pointer must already be set. */ static rsRetVal SetModPtr(parser_t *pThis, modInfo_t *pMod) { ISOBJ_TYPE_assert(pThis, parser); assert(pMod != NULL); assert(pThis->pModule == NULL); pThis->pModule = pMod; return RS_RET_OK; } /* Specify if we should do standard PRI parsing before we pass the data * down to the parser module. */ static rsRetVal SetDoPRIParsing(parser_t *pThis, int bDoIt) { ISOBJ_TYPE_assert(pThis, parser); pThis->bDoPRIParsing = bDoIt; return RS_RET_OK; } BEGINobjConstruct(parser) /* be sure to specify the object type also in END macro! */ ENDobjConstruct(parser) /* ConstructionFinalizer. The most important chore is to add the parser object * to our global list of available parsers. * rgerhards, 2009-11-03 */ static rsRetVal parserConstructFinalize(parser_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, parser); CHKiRet(AddParserToList(&loadConf->parsers.pParsLstRoot, pThis)); DBGPRINTF("Parser '%s' added to list of available parsers.\n", pThis->pName); finalize_it: RETiRet; } /* construct a parser object via a pointer to the parser module * and the name. This is a separate function because we need it * in multiple spots inside the code. */ rsRetVal parserConstructViaModAndName(modInfo_t *__restrict__ pMod, uchar *const __restrict__ pName, void *pInst) { rsRetVal localRet; parser_t *pParser = NULL; DEFiRet; if (pInst == NULL && pMod->mod.pm.newParserInst != NULL) { /* this happens for the default instance on ModLoad time */ CHKiRet(pMod->mod.pm.newParserInst(NULL, &pInst)); } CHKiRet(parserConstruct(&pParser)); /* check some features */ localRet = pMod->isCompatibleWithFeature(sFEATUREAutomaticSanitazion); if (localRet == RS_RET_OK) { pParser->bDoSanitazion = RSTRUE; } localRet = pMod->isCompatibleWithFeature(sFEATUREAutomaticPRIParsing); if (localRet == RS_RET_OK) { CHKiRet(SetDoPRIParsing(pParser, RSTRUE)); } CHKiRet(SetName(pParser, pName)); CHKiRet(SetModPtr(pParser, pMod)); pParser->pInst = pInst; CHKiRet(parserConstructFinalize(pParser)); finalize_it: if (iRet != RS_RET_OK) free(pParser); RETiRet; } /* uncompress a received message if it is compressed. * pMsg->pszRawMsg buffer is updated. * rgerhards, 2008-10-09 */ static rsRetVal uncompressMessage(smsg_t *pMsg) { DEFiRet; uchar *deflateBuf = NULL; uLongf iLenDefBuf; uchar *pszMsg; size_t lenMsg; assert(pMsg != NULL); pszMsg = pMsg->pszRawMsg; lenMsg = pMsg->iLenRawMsg; /* we first need to check if we have a compressed record. If so, * we must decompress it. */ if (lenMsg > 0 && *pszMsg == 'z' && runConf->globals.bSupportCompressionExtension) { /* compressed data present? */ /* we have compressed data, so let's deflate it. We support a maximum * message size of iMaxLine. If it is larger, an error message is logged * and the message is dropped. We do NOT try to decompress larger messages * as such might be used for denial of service. It might happen to later * builds that such functionality be added as an optional, operator-configurable * feature. */ int ret; iLenDefBuf = glbl.GetMaxLine(runConf); CHKmalloc(deflateBuf = malloc(iLenDefBuf + 1)); ret = uncompress((uchar *)deflateBuf, &iLenDefBuf, (uchar *)pszMsg + 1, lenMsg - 1); DBGPRINTF("Compressed message uncompressed with status %d, length: new %ld, old %d.\n", ret, (long)iLenDefBuf, (int)(lenMsg - 1)); /* Now check if the uncompression worked. If not, there is not much we can do. In * that case, we log an error message but ignore the message itself. Storing the * compressed text is dangerous, as it contains control characters. So we do * not do this. If someone would like to have a copy, this code here could be * modified to do a hex-dump of the buffer in question. We do not include * this functionality right now. * rgerhards, 2006-12-07 */ if (ret != Z_OK) { LogError(0, NO_ERRCODE, "Uncompression of a message failed with return code %d " "- enable debug logging if you need further information. " "Message ignored.", ret); FINALIZE; /* unconditional exit, nothing left to do... */ } MsgSetRawMsg(pMsg, (char *)deflateBuf, iLenDefBuf); } finalize_it: if (deflateBuf != NULL) free(deflateBuf); RETiRet; } /* sanitize a received message * if a message gets to large during sanitization, it is truncated. This is * as specified in the upcoming syslog RFC series. * rgerhards, 2008-10-09 * We check if we have a NUL character at the very end of the * message. This seems to be a frequent problem with a number of senders. * So I have now decided to drop these NULs. However, if they are intentional, * that may cause us some problems, e.g. with syslog-sign. On the other hand, * current code always has problems with intentional NULs (as it needs to escape * them to prevent problems with the C string libraries), so that does not * really matter. Just to be on the save side, we'll log destruction of such * NULs in the debug log. * rgerhards, 2007-09-14 */ static rsRetVal SanitizeMsg(smsg_t *pMsg) { DEFiRet; uchar *pszMsg; uchar *pDst; /* destination for copy job */ size_t lenMsg; size_t iSrc; size_t iDst; size_t iMaxLine; size_t maxDest; uchar pc; sbool bUpdatedLen = RSFALSE; uchar szSanBuf[32 * 1024]; /* buffer used for sanitizing a string */ assert(pMsg != NULL); assert(pMsg->iLenRawMsg > 0); pszMsg = pMsg->pszRawMsg; lenMsg = pMsg->iLenRawMsg; /* remove NUL character at end of message (see comment in function header) * Note that we do not need to add a NUL character in this case, because it * is already present ;) */ if (pszMsg[lenMsg - 1] == '\0') { DBGPRINTF("dropped NUL at very end of message\n"); bUpdatedLen = RSTRUE; lenMsg--; } /* then we check if we need to drop trailing LFs, which often make * their way into syslog messages unintentionally. In order to remain * compatible to recent IETF developments, we allow the user to * turn on/off this handling. rgerhards, 2007-07-23 */ if (glbl.GetParserDropTrailingLFOnReception(runConf) && lenMsg > 0 && pszMsg[lenMsg - 1] == '\n') { DBGPRINTF("dropped LF at very end of message (DropTrailingLF is set)\n"); lenMsg--; pszMsg[lenMsg] = '\0'; bUpdatedLen = RSTRUE; } /* it is much quicker to sweep over the message and see if it actually * needs sanitation than to do the sanitation in any case. So we first do * this and terminate when it is not needed - which is expectedly the case * for the vast majority of messages. -- rgerhards, 2009-06-15 * Note that we do NOT check here if tab characters are to be escaped or * not. I expect this functionality to be seldomly used and thus I do not * like to pay the performance penalty. So the penalty is only with those * that actually use it, because we may call the sanitizer without actual * need below (but it then still will work perfectly well!). -- rgerhards, 2009-11-27 */ int bNeedSanitize = 0; for (iSrc = 0; iSrc < lenMsg; iSrc++) { if (pszMsg[iSrc] < 32) { if (glbl.GetParserSpaceLFOnReceive(runConf) && pszMsg[iSrc] == '\n') { pszMsg[iSrc] = ' '; } else if (pszMsg[iSrc] == '\0' || glbl.GetParserEscapeControlCharactersOnReceive(runConf)) { bNeedSanitize = 1; if (!glbl.GetParserSpaceLFOnReceive(runConf)) { break; } } } else if (pszMsg[iSrc] > 127 && glbl.GetParserEscape8BitCharactersOnReceive(runConf)) { bNeedSanitize = 1; break; } } if (!bNeedSanitize) { if (bUpdatedLen == RSTRUE) MsgSetRawMsgSize(pMsg, lenMsg); FINALIZE; } /* now copy over the message and sanitize it. Note that up to iSrc-1 there was * obviously no need to sanitize, so we can go over that quickly... */ iMaxLine = glbl.GetMaxLine(runConf); maxDest = lenMsg * 4; /* message can grow at most four-fold */ if (maxDest > iMaxLine) maxDest = iMaxLine; /* but not more than the max size! */ if (maxDest < sizeof(szSanBuf)) pDst = szSanBuf; else CHKmalloc(pDst = malloc(maxDest + 1)); if (iSrc > 0) { iSrc--; /* go back to where everything is OK */ if (iSrc > maxDest) { DBGPRINTF( "parser.Sanitize: have oversize index %zd, " "max %zd - corrected, but should not happen\n", iSrc, maxDest); iSrc = maxDest; } memcpy(pDst, pszMsg, iSrc); /* fast copy known good */ } iDst = iSrc; while (iSrc < lenMsg && iDst < maxDest - 3) { /* leave some space if last char must be escaped */ if ((pszMsg[iSrc] < 32) && (pszMsg[iSrc] != '\t' || glbl.GetParserEscapeControlCharacterTab(runConf))) { /* note: \0 must always be escaped, the rest of the code currently * can not handle it! -- rgerhards, 2009-08-26 */ if (pszMsg[iSrc] == '\0' || glbl.GetParserEscapeControlCharactersOnReceive(runConf)) { /* we are configured to escape control characters. Please note * that this most probably break non-western character sets like * Japanese, Korean or Chinese. rgerhards, 2007-07-17 */ if (glbl.GetParserEscapeControlCharactersCStyle(runConf)) { pDst[iDst++] = '\\'; switch (pszMsg[iSrc]) { case '\0': pDst[iDst++] = '0'; break; case '\a': pDst[iDst++] = 'a'; break; case '\b': pDst[iDst++] = 'b'; break; case '\x1b': /* equivalent to '\e' which is not accepted by XLC */ pDst[iDst++] = 'e'; break; case '\f': pDst[iDst++] = 'f'; break; case '\n': pDst[iDst++] = 'n'; break; case '\r': pDst[iDst++] = 'r'; break; case '\t': pDst[iDst++] = 't'; break; case '\v': pDst[iDst++] = 'v'; break; default: pDst[iDst++] = 'x'; pc = pszMsg[iSrc]; pDst[iDst++] = hexdigit[(pc & 0xF0) >> 4]; pDst[iDst++] = hexdigit[pc & 0xF]; break; } } else { pDst[iDst++] = glbl.GetParserControlCharacterEscapePrefix(runConf); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0300) >> 6); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0070) >> 3); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0007)); } } } else if (pszMsg[iSrc] > 127 && glbl.GetParserEscape8BitCharactersOnReceive(runConf)) { if (glbl.GetParserEscapeControlCharactersCStyle(runConf)) { pDst[iDst++] = '\\'; pDst[iDst++] = 'x'; pc = pszMsg[iSrc]; pDst[iDst++] = hexdigit[(pc & 0xF0) >> 4]; pDst[iDst++] = hexdigit[pc & 0xF]; } else { /* In this case, we also do the conversion. Note that this most * probably breaks European languages. -- rgerhards, 2010-01-27 */ pDst[iDst++] = glbl.GetParserControlCharacterEscapePrefix(runConf); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0300) >> 6); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0070) >> 3); pDst[iDst++] = '0' + ((pszMsg[iSrc] & 0007)); } } else { pDst[iDst++] = pszMsg[iSrc]; } ++iSrc; } pDst[iDst] = '\0'; MsgSetRawMsg(pMsg, (char *)pDst, iDst); /* save sanitized string */ if (pDst != szSanBuf) free(pDst); finalize_it: RETiRet; } /* A standard parser to parse out the PRI. This is made available in * this module as it is expected that allmost all parsers will need * that functionality and so they do not need to implement it themsleves. */ static rsRetVal ParsePRI(smsg_t *pMsg) { syslog_pri_t pri; uchar *msg; int lenMsg; DEFiRet; /* pull PRI */ lenMsg = pMsg->iLenRawMsg; msg = pMsg->pszRawMsg; pri = DEFUPRI; if (pMsg->msgFlags & NO_PRI_IN_RAW) { /* In this case, simply do so as if the pri would be right at top */ MsgSetAfterPRIOffs(pMsg, 0); } else { if (*msg == '<') { pri = 0; while (--lenMsg > 0 && isdigit((int)*++msg) && pri <= LOG_MAXPRI) { pri = 10 * pri + (*msg - '0'); } if (*msg == '>') { ++msg; } else { pri = LOG_PRI_INVLD; } if (pri > LOG_MAXPRI) pri = LOG_PRI_INVLD; } msgSetPRI(pMsg, pri); MsgSetAfterPRIOffs(pMsg, (pri == LOG_PRI_INVLD) ? 0 : msg - pMsg->pszRawMsg); } RETiRet; } /* Parse a received message. The object's rawmsg property is taken and * parsed according to the relevant standards. This can later be * extended to support configured parsers. * rgerhards, 2008-10-09 */ static rsRetVal ParseMsg(smsg_t *pMsg) { rsRetVal localRet = RS_RET_ERR; parserList_t *pParserList; parser_t *pParser; sbool bIsSanitized; sbool bPRIisParsed; static int iErrMsgRateLimiter = 0; DEFiRet; if (pMsg->iLenRawMsg == 0) ABORT_FINALIZE(RS_RET_EMPTY_MSG); CHKiRet(uncompressMessage(pMsg)); /* we take the risk to print a non-sanitized string, because this is the best we can get * (and that functionality is too important for debugging to drop it...). */ DBGPRINTF("msg parser: flags %x, from '%s', msg '%.60s'\n", pMsg->msgFlags, (pMsg->msgFlags & NEEDS_DNSRESOL) ? UCHAR_CONSTANT("~NOTRESOLVED~") : getRcvFrom(pMsg), pMsg->pszRawMsg); /* we now need to go through our list of parsers and see which one is capable of * parsing the message. Note that the first parser that requires message sanitization * will cause it to happen. After that, access to the unsanitized message is no * loger possible. */ pParserList = ruleset.GetParserList(runConf, pMsg); if (pParserList == NULL) { pParserList = runConf->parsers.pDfltParsLst; } DBGPRINTF("parse using parser list %p%s.\n", pParserList, (pParserList == runConf->parsers.pDfltParsLst) ? " (the default list)" : ""); bIsSanitized = RSFALSE; bPRIisParsed = RSFALSE; while (pParserList != NULL) { pParser = pParserList->pParser; if (pParser->bDoSanitazion && bIsSanitized == RSFALSE) { CHKiRet(SanitizeMsg(pMsg)); if (pParser->bDoPRIParsing && bPRIisParsed == RSFALSE) { CHKiRet(ParsePRI(pMsg)); bPRIisParsed = RSTRUE; } bIsSanitized = RSTRUE; } if (pParser->pModule->mod.pm.parse2 == NULL) localRet = pParser->pModule->mod.pm.parse(pMsg); else localRet = pParser->pModule->mod.pm.parse2(pParser->pInst, pMsg); DBGPRINTF("Parser '%s' returned %d\n", pParser->pName, localRet); if (localRet != RS_RET_COULD_NOT_PARSE) break; pParserList = pParserList->pNext; } /* We need to log a warning message and drop the message if we did not find a parser. * Note that we log at most the first 1000 message, as this may very well be a problem * that causes a message generation loop. We do not synchronize that counter, it doesn't * matter if we log a handful messages more than we should... */ if (localRet != RS_RET_OK) { if (++iErrMsgRateLimiter < 1000) { LogError(0, localRet, "Error: one message could not be processed by " "any parser, message is being discarded (start of raw msg: '%.60s')", pMsg->pszRawMsg); } DBGPRINTF("No parser could process the message (state %d), we need to discard it.\n", localRet); ABORT_FINALIZE(localRet); } /* "finalize" message object */ pMsg->msgFlags &= ~NEEDS_PARSING; /* this message is now parsed */ finalize_it: RETiRet; } /* This destroys the master parserlist and all of its parser entries. * Parser modules are NOT unloaded, rsyslog does that at a later stage * for all dynamically loaded modules. */ static rsRetVal destroyMasterParserList(parserList_t *pParserListRoot) { DEFiRet; parserList_t *pParsLst; parserList_t *pParsLstDel; pParsLst = pParserListRoot; while (pParsLst != NULL) { parserDestruct(&pParsLst->pParser); pParsLstDel = pParsLst; pParsLst = pParsLst->pNext; free(pParsLstDel); } RETiRet; } /* queryInterface function-- rgerhards, 2009-11-03 */ BEGINobjQueryInterface(parser) CODESTARTobjQueryInterface(parser); if (pIf->ifVersion != parserCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = parserConstruct; pIf->ConstructFinalize = parserConstructFinalize; pIf->Destruct = parserDestruct; pIf->SetName = SetName; pIf->SetModPtr = SetModPtr; pIf->SetDoPRIParsing = SetDoPRIParsing; pIf->ParseMsg = ParseMsg; pIf->SanitizeMsg = SanitizeMsg; pIf->DestructParserList = DestructParserList; pIf->AddParserToList = AddParserToList; pIf->AddDfltParser = AddDfltParser; pIf->FindParser = FindParser; pIf->destroyMasterParserList = destroyMasterParserList; finalize_it: ENDobjQueryInterface(parser) /* Exit our class. * rgerhards, 2009-11-04 */ BEGINObjClassExit(parser, OBJ_IS_CORE_MODULE) /* class, version */ objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDObjClassExit(parser) /* Initialize the parser class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2009-11-02 */ BEGINObjClassInit(parser, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); ENDObjClassInit(parser) rsyslog-8.2512.0/runtime/PaxHeaders/unlimited_select.h0000644000000000000000000000013115055605325017723 xustar0030 mtime=1756826325.654800759 30 atime=1764931023.937408595 29 ctime=1764935923.13457583 rsyslog-8.2512.0/runtime/unlimited_select.h0000664000175000017500000000244115055605325017371 0ustar00rgerrger/* unlimited_select.h * Tweak the macros for accessing fd_set so that the select() syscall * won't be limited to a particular number of file descriptors. * * Copyright 2009-2012 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef UNLIMITED_SELECT_H_INCLUDED #define UNLIMITED_SELECT_H_INCLUDED #include #include #include #include "glbl.h" #ifdef USE_UNLIMITED_SELECT #undef FD_ZERO #define FD_ZERO(set) memset((set), 0, glbl.GetFdSetSize()); #endif #ifdef USE_UNLIMITED_SELECT static inline void freeFdSet(fd_set *p) { free(p); } #else #define freeFdSet(x) #endif #endif /* #ifndef UNLIMITED_SELECT_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/lmcry_gcry.h0000644000000000000000000000013115055605325016544 xustar0030 mtime=1756826325.646800638 30 atime=1764931130.874155079 29 ctime=1764935923.32657877 rsyslog-8.2512.0/runtime/lmcry_gcry.h0000664000175000017500000000246515055605325016220 0ustar00rgerrger/* An implementation of the cryprov interface for libgcrypt. * * Copyright 2013 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LMCRY_GCRY_H #define INCLUDED_LMCRY_GCRY_H #include "cryprov.h" /* interface is defined in cryprov.h, we just implement it! */ #define lmcry_gcryCURR_IF_VERSION cryprovCURR_IF_VERSION typedef cryprov_if_t lmcry_gcry_if_t; /* the lmcry_gcry object */ struct lmcry_gcry_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ gcryctx ctx; }; typedef struct lmcry_gcry_s lmcry_gcry_t; /* prototypes */ PROTOTYPEObj(lmcry_gcry); #endif /* #ifndef INCLUDED_LMCRY_GCRY_H */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_gtls.c0000644000000000000000000000013215114522477016205 xustar0030 mtime=1764926783.040631981 30 atime=1764926784.239661412 30 ctime=1764935923.357579244 rsyslog-8.2512.0/runtime/nsd_gtls.c0000664000175000017500000026023515114522477015661 0ustar00rgerrger/* nsd_gtls.c * * An implementation of the nsd interface for GnuTLS. * * Copyright (C) 2007-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include #if GNUTLS_VERSION_NUMBER <= 0x020b00 #include #endif #include #include #include #include #include #include #include "rsyslog.h" #include "syslogd-types.h" #include "module-template.h" #include "cfsysline.h" #include "obj.h" #include "stringbuf.h" #include "errmsg.h" #include "net.h" #include "datetime.h" #include "netstrm.h" #include "netstrms.h" #include "nsd_ptcp.h" #include "nsd_gtls.h" #include "unicode-helper.h" #include "rsconf.h" #if GNUTLS_VERSION_NUMBER <= 0x020b00 GCRY_THREAD_OPTION_PTHREAD_IMPL; #endif MODULE_TYPE_LIB MODULE_TYPE_KEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(net) DEFobjCurrIf(datetime) DEFobjCurrIf(nsd_ptcp) /* Static Helper variables for certless communication */ static gnutls_anon_client_credentials_t anoncred; /**< client anon credentials */ static gnutls_anon_server_credentials_t anoncredSrv; /**< server anon credentials */ static int dhBits = 2048; /**< number of bits for Diffie-Hellman key */ static int dhMinBits = 512; /**< minimum number of bits for Diffie-Hellman key */ static pthread_mutex_t mutGtlsStrerror; /*< a mutex protecting the potentially non-reentrant gtlStrerror() function */ static gnutls_dh_params_t dh_params; /**< server DH parameters for anon mode */ /* Module-level bitfield for warnings that have been logged (shared across all instances) * NOTE: Intentionally NOT thread-safe. Occasional duplicate warnings (1-2) are acceptable * vs. thousands without this mechanism. Atomic ops/locks are overkill for startup warnings. */ static unsigned loggedWarnings = 0; /* bitfield for warnings that have been logged */ enum { GTLS_LOGGED_WARN_CERT_MISSING = 1 << 0, GTLS_LOGGED_WARN_KEY_MISSING = 1 << 1, GTLS_LOGGED_WARN_CA_MISSING = 1 << 2 }; /* a macro to abort if GnuTLS error is not acceptable. We split this off from * CHKgnutls() to avoid some Coverity report in cases where we know GnuTLS * failed. Note: gnuRet must already be set accordingly! */ #define ABORTgnutls \ { \ uchar *pErr = gtlsStrerror(gnuRet); \ LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \ free(pErr); \ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \ } /* a macro to check GnuTLS calls against unexpected errors */ #define CHKgnutls(x) \ { \ gnuRet = (x); \ if (gnuRet == GNUTLS_E_FILE_ERROR) { \ LogError(0, RS_RET_GNUTLS_ERR, \ "error reading file - a common cause is that the " \ "file does not exist"); \ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \ } else if (gnuRet != 0) { \ ABORTgnutls; \ } \ } /* ------------------------------ GnuTLS specifics ------------------------------ */ static rsRetVal doRetry(nsd_gtls_t *pNsd) { DEFiRet; int gnuRet; dbgprintf("doRetry: GnuTLS requested retry of operation %d - executing\n", pNsd->rtryCall); /* We follow a common scheme here: first, we do the systen call and * then we check the result. So far, the result is checked after the * switch, because the result check is the same for all calls. Note that * this may change once we deal with the read and write calls (but * probably this becomes an issue only when we begin to work on TLS * for relp). -- rgerhards, 2008-04-30 */ switch (pNsd->rtryCall) { case gtlsRtry_handshake: gnuRet = gnutls_handshake(pNsd->sess); if (gnuRet == GNUTLS_E_AGAIN || gnuRet == GNUTLS_E_INTERRUPTED) { dbgprintf( "doRetry: GnuTLS handshake retry did not finish - " "setting to retry (this is OK and can happen)\n"); FINALIZE; } else if (gnuRet == 0) { pNsd->rtryCall = gtlsRtry_None; /* we are done */ /* we got a handshake, now check authorization */ CHKiRet(gtlsChkPeerAuth(pNsd)); } else { uchar *pGnuErr = gtlsStrerror(gnuRet); uchar *fromHostIP = NULL; int remotePort; uchar remotePortStr[8]; nsd_ptcp.GetRemoteHName(pNsd->pTcp, &fromHostIP); nsd_ptcp.GetRemotePort(pNsd->pTcp, &remotePort); nsd_ptcp.FmtRemotePortStr(remotePort, remotePortStr, sizeof(remotePortStr)); LogError(0, RS_RET_TLS_HANDSHAKE_ERR, "nsd_gtls:TLS session terminated with remote client '%s:%s': " " GnuTLS handshake retry returned error: %s", fromHostIP, remotePortStr, pGnuErr); free(fromHostIP); free(pGnuErr); ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR); } break; case gtlsRtry_recv: case gtlsRtry_None: default: assert(0); /* this shall not happen! */ dbgprintf("ERROR: pNsd->rtryCall %d invalid in nsd_gtls.c:%d\n", pNsd->rtryCall, __LINE__); gnuRet = 0; /* if it happens, we have at least a defined behaviour... ;) */ break; } if (gnuRet == 0) { pNsd->rtryCall = gtlsRtry_None; /* we are done */ } else if (gnuRet != GNUTLS_E_AGAIN && gnuRet != GNUTLS_E_INTERRUPTED) { uchar *pErr = gtlsStrerror(gnuRet); LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); free(pErr); pNsd->rtryCall = gtlsRtry_None; /* we are also done... ;) */ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } /* if we are interrupted once again (else case), we do not need to * change our status because we are already setup for retries. */ finalize_it: if (iRet != RS_RET_OK && iRet != RS_RET_CLOSED && iRet != RS_RET_RETRY) pNsd->bAbortConn = 1; /* request abort */ RETiRet; } /* This defines a log function to be provided to GnuTLS. It hopefully * helps us track down hard to find problems. * rgerhards, 2008-06-20 */ static void logFunction(int level, const char *msg) { dbgprintf("GnuTLS log msg, level %d: %s\n", level, msg); } /* read in the whole content of a file. The caller is responsible for * freeing the buffer. To prevent DOS, this function can NOT read * files larger than 1MB (which still is *very* large). * rgerhards, 2008-05-26 */ static rsRetVal readFile(const uchar *const pszFile, gnutls_datum_t *const pBuf) { int fd; struct stat stat_st; DEFiRet; assert(pszFile != NULL); assert(pBuf != NULL); pBuf->data = NULL; if ((fd = open((char *)pszFile, O_RDONLY)) == -1) { LogError(errno, RS_RET_FILE_NOT_FOUND, "can not read file '%s'", pszFile); ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); } if (fstat(fd, &stat_st) == -1) { LogError(errno, RS_RET_FILE_NO_STAT, "can not stat file '%s'", pszFile); ABORT_FINALIZE(RS_RET_FILE_NO_STAT); } /* 1MB limit */ if (stat_st.st_size > 1024 * 1024) { LogError(0, RS_RET_FILE_TOO_LARGE, "file '%s' too large, max 1MB", pszFile); ABORT_FINALIZE(RS_RET_FILE_TOO_LARGE); } CHKmalloc(pBuf->data = malloc(stat_st.st_size)); pBuf->size = stat_st.st_size; if (read(fd, pBuf->data, stat_st.st_size) != stat_st.st_size) { LogError(0, RS_RET_IO_ERROR, "error or incomplete read of file '%s'", pszFile); ABORT_FINALIZE(RS_RET_IO_ERROR); } finalize_it: if (fd != -1) close(fd); if (iRet != RS_RET_OK) { if (pBuf->data != NULL) { free(pBuf->data); pBuf->data = NULL; pBuf->size = 0; } } RETiRet; } /* Load the certificate and the private key into our own store. We need to do * this in the client case, to support fingerprint authentication. In that case, * we may be presented no matching root certificate, but we must provide ours. * The only way to do that is via the cert callback interface, but for it we * need to load certificates into our private store. * rgerhards, 2008-05-26 */ static rsRetVal gtlsLoadOurCertKey(nsd_gtls_t *pThis) { DEFiRet; int gnuRet; gnutls_datum_t data = {NULL, 0}; const uchar *keyFile; const uchar *certFile; ISOBJ_TYPE_assert(pThis, nsd_gtls); certFile = (pThis->pszCertFile == NULL) ? glbl.GetDfltNetstrmDrvrCertFile(runConf) : pThis->pszCertFile; keyFile = (pThis->pszKeyFile == NULL) ? glbl.GetDfltNetstrmDrvrKeyFile(runConf) : pThis->pszKeyFile; if (certFile == NULL || keyFile == NULL) { /* in this case, we can not set our certificate. If we are * a client and the server is running in "anon" auth mode, this * may be well acceptable. In other cases, we will see some * more error messages down the road. -- rgerhards, 2008-07-02 */ dbgprintf("gtlsLoadOurCertKey our certificate is not set, file name values are cert: '%s', key: '%s'\n", certFile, keyFile); ABORT_FINALIZE(RS_RET_CERTLESS); } /* try load certificate */ CHKiRet(readFile(certFile, &data)); pThis->nOurCerts = sizeof(pThis->pOurCerts) / sizeof(gnutls_x509_crt_t); gnuRet = gnutls_x509_crt_list_import(pThis->pOurCerts, &pThis->nOurCerts, &data, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); if (gnuRet < 0) { ABORTgnutls; } pThis->bOurCertIsInit = 1; free(data.data); data.data = NULL; /* try load private key */ CHKiRet(readFile(keyFile, &data)); CHKgnutls(gnutls_x509_privkey_init(&pThis->ourKey)); pThis->bOurKeyIsInit = 1; CHKgnutls(gnutls_x509_privkey_import(pThis->ourKey, &data, GNUTLS_X509_FMT_PEM)); free(data.data); finalize_it: if (iRet == RS_RET_CERTLESS) { dbgprintf("gtlsLoadOurCertKey certless exit\n"); pThis->bOurCertIsInit = 0; pThis->bOurKeyIsInit = 0; } else if (iRet != RS_RET_OK) { dbgprintf("gtlsLoadOurCertKey error exit\n"); if (data.data != NULL) free(data.data); if (pThis->bOurCertIsInit) { for (unsigned i = 0; i < pThis->nOurCerts; ++i) { gnutls_x509_crt_deinit(pThis->pOurCerts[i]); } pThis->bOurCertIsInit = 0; } if (pThis->bOurKeyIsInit) { gnutls_x509_privkey_deinit(pThis->ourKey); pThis->bOurKeyIsInit = 0; } } else { dbgprintf("gtlsLoadOurCertKey Successfully Loaded cert '%s' and key: '%s'\n", certFile, keyFile); } RETiRet; } /* This callback must be associated with a session by calling * gnutls_certificate_client_set_retrieve_function(session, cert_callback), * before a handshake. We will always return the configured certificate, * even if it does not match the peer's trusted CAs. This is necessary * to use self-signed certs in fingerprint mode. And, yes, this usage * of the callback is quite a hack. But it seems the only way to * obey to the IETF -transport-tls I-D. * Note: GnuTLS requires the function to return 0 on success and * -1 on failure. * rgerhards, 2008-05-27 */ static int gtlsClientCertCallback(gnutls_session_t session, __attribute__((unused)) const gnutls_datum_t *req_ca_rdn, int __attribute__((unused)) nreqs, __attribute__((unused)) const gnutls_pk_algorithm_t *sign_algos, int __attribute__((unused)) sign_algos_length, #if HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION gnutls_retr2_st *st #else gnutls_retr_st *st #endif ) { nsd_gtls_t *pThis; pThis = (nsd_gtls_t *)gnutls_session_get_ptr(session); #if HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION st->cert_type = GNUTLS_CRT_X509; #else st->type = GNUTLS_CRT_X509; #endif st->ncerts = pThis->nOurCerts; st->cert.x509 = pThis->pOurCerts; st->key.x509 = pThis->ourKey; st->deinit_all = 0; return 0; } /* This function extracts some information about this session's peer * certificate. Works for X.509 certificates only. Adds all * of the info to a cstr_t, which is handed over to the caller. * Caller must destruct it when no longer needed. * rgerhards, 2008-05-21 */ static rsRetVal gtlsGetCertInfo(nsd_gtls_t *const pThis, cstr_t **ppStr) { uchar szBufA[1024]; uchar *szBuf = szBufA; size_t szBufLen = sizeof(szBufA), tmp; unsigned int algo, bits; time_t expiration_time, activation_time; const gnutls_datum_t *cert_list; unsigned cert_list_size = 0; gnutls_x509_crt_t cert; cstr_t *pStr = NULL; int gnuRet; DEFiRet; unsigned iAltName; assert(ppStr != NULL); ISOBJ_TYPE_assert(pThis, nsd_gtls); if (gnutls_certificate_type_get(pThis->sess) != GNUTLS_CRT_X509) return RS_RET_TLS_CERT_ERR; cert_list = gnutls_certificate_get_peers(pThis->sess, &cert_list_size); CHKiRet(rsCStrConstructFromszStrf(&pStr, "peer provided %d certificate(s). ", cert_list_size)); if (cert_list_size > 0) { /* we only print information about the first certificate */ CHKgnutls(gnutls_x509_crt_init(&cert)); CHKgnutls(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); expiration_time = gnutls_x509_crt_get_expiration_time(cert); activation_time = gnutls_x509_crt_get_activation_time(cert); ctime_r(&activation_time, (char *)szBuf); szBuf[ustrlen(szBuf) - 1] = '\0'; /* strip linefeed */ CHKiRet(rsCStrAppendStrf(pStr, "Certificate 1 info: " "certificate valid from %s ", szBuf)); ctime_r(&expiration_time, (char *)szBuf); szBuf[ustrlen(szBuf) - 1] = '\0'; /* strip linefeed */ CHKiRet(rsCStrAppendStrf(pStr, "to %s; ", szBuf)); /* Extract some of the public key algorithm's parameters */ algo = gnutls_x509_crt_get_pk_algorithm(cert, &bits); CHKiRet(rsCStrAppendStrf(pStr, "Certificate public key: %s; ", gnutls_pk_algorithm_get_name(algo))); /* names */ tmp = szBufLen; if (gnutls_x509_crt_get_dn(cert, (char *)szBuf, &tmp) == GNUTLS_E_SHORT_MEMORY_BUFFER) { szBufLen = tmp; szBuf = malloc(tmp); gnutls_x509_crt_get_dn(cert, (char *)szBuf, &tmp); } CHKiRet(rsCStrAppendStrf(pStr, "DN: %s; ", szBuf)); tmp = szBufLen; if (gnutls_x509_crt_get_issuer_dn(cert, (char *)szBuf, &tmp) == GNUTLS_E_SHORT_MEMORY_BUFFER) { szBufLen = tmp; szBuf = realloc((szBuf == szBufA) ? NULL : szBuf, tmp); gnutls_x509_crt_get_issuer_dn(cert, (char *)szBuf, &tmp); } CHKiRet(rsCStrAppendStrf(pStr, "Issuer DN: %s; ", szBuf)); /* dNSName alt name */ iAltName = 0; while (1) { /* loop broken below */ tmp = szBufLen; gnuRet = gnutls_x509_crt_get_subject_alt_name(cert, iAltName, szBuf, &tmp, NULL); if (gnuRet == GNUTLS_E_SHORT_MEMORY_BUFFER) { szBufLen = tmp; szBuf = realloc((szBuf == szBufA) ? NULL : szBuf, tmp); continue; } else if (gnuRet < 0) break; else if (gnuRet == GNUTLS_SAN_DNSNAME) { /* we found it! */ CHKiRet(rsCStrAppendStrf(pStr, "SAN:DNSname: %s; ", szBuf)); /* do NOT break, because there may be multiple dNSName's! */ } else if (gnuRet == GNUTLS_SAN_IPADDRESS) { char ipAddress[INET6_ADDRSTRLEN]; /* we found it! */ inet_ntop(((tmp == sizeof(struct in6_addr)) ? AF_INET6 : AF_INET), szBuf, ipAddress, sizeof(ipAddress)); CHKiRet(rsCStrAppendStrf(pStr, "SAN:IPaddress: %s; ", ipAddress)); /* do NOT break, because there may be multiple ipAddr's! */ } ++iAltName; } gnutls_x509_crt_deinit(cert); } cstrFinalize(pStr); *ppStr = pStr; finalize_it: if (iRet != RS_RET_OK) { if (pStr != NULL) rsCStrDestruct(&pStr); } if (szBuf != szBufA) free(szBuf); RETiRet; } #if 0 /* we may need this in the future - code needs to be looked at then! */ /* This function will print some details of the * given pThis->sess. */ static rsRetVal print_info(nsd_gtls_t *pThis) { const char *tmp; gnutls_credentials_type cred; gnutls_kx_algorithm kx; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); /* print the key exchange's algorithm name */ kx = gnutls_kx_get(pThis->sess); tmp = gnutls_kx_get_name(kx); dbgprintf("- Key Exchange: %s\n", tmp); /* Check the authentication type used and switch * to the appropriate. */ cred = gnutls_auth_get_type(pThis->sess); switch (cred) { case GNUTLS_CRD_ANON: /* anonymous authentication */ dbgprintf("- Anonymous DH using prime of %d bits\n", gnutls_dh_get_prime_bits(pThis->sess)); break; case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */ /* Check if we have been using ephemeral Diffie Hellman. */ if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { dbgprintf("\n- Ephemeral DH using prime of %d bits\n", gnutls_dh_get_prime_bits(pThis->sess)); } /* if the certificate list is available, then * print some information about it. */ gtlsPrintCert(pThis); break; case GNUTLS_CRD_SRP: /* certificate authentication */ dbgprintf("GNUTLS_CRD_SRP/IA"); break; case GNUTLS_CRD_PSK: /* certificate authentication */ dbgprintf("GNUTLS_CRD_PSK"); break; case GNUTLS_CRD_IA: /* certificate authentication */ dbgprintf("GNUTLS_CRD_IA"); break; } /* switch */ /* print the protocol's name (ie TLS 1.0) */ tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(pThis->sess)); dbgprintf("- Protocol: %s\n", tmp); /* print the certificate type of the peer. * ie X.509 */ tmp = gnutls_certificate_type_get_name( gnutls_certificate_type_get(pThis->sess)); dbgprintf("- Certificate Type: %s\n", tmp); /* print the compression algorithm (if any) */ tmp = gnutls_compression_get_name( gnutls_compression_get(pThis->sess)); dbgprintf("- Compression: %s\n", tmp); /* print the name of the cipher used. * ie 3DES. */ tmp = gnutls_cipher_get_name(gnutls_cipher_get(pThis->sess)); dbgprintf("- Cipher: %s\n", tmp); /* Print the MAC algorithms name. * ie SHA1 */ tmp = gnutls_mac_get_name(gnutls_mac_get(pThis->sess)); dbgprintf("- MAC: %s\n", tmp); RETiRet; } #endif /* Convert a fingerprint to printable data. The conversion is carried out * according IETF I-D syslog-transport-tls-12. The fingerprint string is * returned in a new cstr object. It is the caller's responsibility to * destruct that object. * rgerhards, 2008-05-08 */ static rsRetVal GenFingerprintStr(uchar *pFingerprint, size_t sizeFingerprint, cstr_t **ppStr, const char *prefix) { cstr_t *pStr = NULL; uchar buf[4]; size_t i; DEFiRet; CHKiRet(rsCStrConstruct(&pStr)); CHKiRet(rsCStrAppendStrWithLen(pStr, (uchar *)prefix, strlen(prefix))); for (i = 0; i < sizeFingerprint; ++i) { snprintf((char *)buf, sizeof(buf), ":%2.2X", pFingerprint[i]); CHKiRet(rsCStrAppendStrWithLen(pStr, buf, 3)); } cstrFinalize(pStr); *ppStr = pStr; finalize_it: if (iRet != RS_RET_OK) { if (pStr != NULL) rsCStrDestruct(&pStr); } RETiRet; } /* a thread-safe variant of gnutls_strerror * The caller must free the returned string. * rgerhards, 2008-04-30 */ uchar *gtlsStrerror(int error) { uchar *pErr; pthread_mutex_lock(&mutGtlsStrerror); pErr = (uchar *)strdup(gnutls_strerror(error)); pthread_mutex_unlock(&mutGtlsStrerror); return pErr; } /* try to receive a record from the remote peer. This works with * our own abstraction and handles local buffering and EAGAIN. * See details on local buffering in Rcv() header-comment. * This function MUST only be called when the local buffer is * empty. Calling it otherwise will cause losss of current buffer * data. * rgerhards, 2008-06-24 */ rsRetVal gtlsRecordRecv(nsd_gtls_t *const pThis, unsigned int *nextIODirection) { ssize_t lenRcvd; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); DBGPRINTF("gtlsRecordRecv: start (Pending Data: %zd | Wanted Direction: %s)\n", gnutls_record_check_pending(pThis->sess), (gnutls_record_get_direction(pThis->sess) == gtlsDir_READ ? "READ" : "WRITE")); lenRcvd = gnutls_record_recv(pThis->sess, pThis->pszRcvBuf, NSD_GTLS_MAX_RCVBUF); if (lenRcvd >= 0) { DBGPRINTF("gtlsRecordRecv: gnutls_record_recv received %zd bytes\n", lenRcvd); pThis->lenRcvBuf = lenRcvd; pThis->ptrRcvBuf = 0; /* Check for additional data in SSL buffer */ size_t stBytesLeft = gnutls_record_check_pending(pThis->sess); if (stBytesLeft > 0) { DBGPRINTF("gtlsRecordRecv: %zd Bytes pending after gnutls_record_recv, expand buffer.\n", stBytesLeft); /* realloc buffer size and preserve char content */ char *const newbuf = realloc(pThis->pszRcvBuf, NSD_GTLS_MAX_RCVBUF + stBytesLeft); CHKmalloc(newbuf); pThis->pszRcvBuf = newbuf; /* 2nd read will read missing bytes from the current SSL Packet */ lenRcvd = gnutls_record_recv(pThis->sess, pThis->pszRcvBuf + NSD_GTLS_MAX_RCVBUF, stBytesLeft); if (lenRcvd > 0) { DBGPRINTF("gtlsRecordRecv: 2nd SSL_read received %zd bytes\n", (NSD_GTLS_MAX_RCVBUF + lenRcvd)); pThis->lenRcvBuf = NSD_GTLS_MAX_RCVBUF + lenRcvd; } else { if (lenRcvd == GNUTLS_E_AGAIN || lenRcvd == GNUTLS_E_INTERRUPTED) { goto sslerragain; /* Go to ERR AGAIN handling */ } else { /* Do all other error handling */ int gnuRet = lenRcvd; ABORTgnutls; } } } } else if (lenRcvd == GNUTLS_E_AGAIN || lenRcvd == GNUTLS_E_INTERRUPTED) { sslerragain: /* Check if the underlaying file descriptor needs to read or write data!*/ pThis->rtryCall = gtlsRtry_recv; /* _recv refers to the gnutls call, not socket layer! */ dbgprintf("GnuTLS receive requires a retry, this most probably is OK and no error condition\n"); *nextIODirection = (gnutls_record_get_direction(pThis->sess) == 0) ? NSDSEL_RD : NSDSEL_WR; ABORT_FINALIZE(RS_RET_RETRY); } else { int gnuRet = lenRcvd; ABORTgnutls; } finalize_it: dbgprintf("gtlsRecordRecv return. nsd %p, iRet %d, lenRcvd %d, lenRcvBuf %d, ptrRcvBuf %d\n", pThis, iRet, (int)lenRcvd, pThis->lenRcvBuf, pThis->ptrRcvBuf); RETiRet; } /* add our own certificate to the certificate set, so that the peer * can identify us. Please note that we try to use mutual authentication, * so we always add a cert, even if we are in the client role (later, * this may be controlled by a config setting). * rgerhards, 2008-05-15 */ static rsRetVal gtlsAddOurCert(nsd_gtls_t *const pThis) { int gnuRet = 0; const uchar *keyFile; const uchar *certFile; uchar *pGnuErr; /* for GnuTLS error reporting */ DEFiRet; certFile = (pThis->pszCertFile == NULL) ? glbl.GetDfltNetstrmDrvrCertFile(runConf) : pThis->pszCertFile; keyFile = (pThis->pszKeyFile == NULL) ? glbl.GetDfltNetstrmDrvrKeyFile(runConf) : pThis->pszKeyFile; dbgprintf("GTLS certificate file: '%s'\n", certFile); dbgprintf("GTLS key file: '%s'\n", keyFile); if (certFile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_CERT_MISSING)) { LogError(0, RS_RET_CERT_MISSING, "warning: certificate file is not set"); loggedWarnings |= GTLS_LOGGED_WARN_CERT_MISSING; } if (keyFile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_KEY_MISSING)) { LogError(0, RS_RET_CERTKEY_MISSING, "warning: key file is not set"); loggedWarnings |= GTLS_LOGGED_WARN_KEY_MISSING; } /* set certificate in gnutls */ if (certFile != NULL && keyFile != NULL) { CHKgnutls( gnutls_certificate_set_x509_key_file(pThis->xcred, (char *)certFile, (char *)keyFile, GNUTLS_X509_FMT_PEM)); } finalize_it: if (iRet != RS_RET_OK && iRet != RS_RET_CERT_MISSING && iRet != RS_RET_CERTKEY_MISSING) { pGnuErr = gtlsStrerror(gnuRet); errno = 0; LogError(0, iRet, "error adding our certificate. GnuTLS error %d, message: '%s', " "key: '%s', cert: '%s'", gnuRet, pGnuErr, keyFile, certFile); free(pGnuErr); } RETiRet; } /* * removecomment ifdef out if needed */ #ifdef false static void print_cipher_suite_list(const char *priorities) { size_t i; int ret; unsigned int idx; const char *name; const char *err; unsigned char id[2]; gnutls_protocol_t version; gnutls_priority_t pcache; if (priorities != NULL) { printf("print_cipher_suite_list: Cipher suites for %s\n", priorities); ret = gnutls_priority_init(&pcache, priorities, &err); if (ret < 0) { fprintf(stderr, "print_cipher_suite_list: Syntax error at: %s\n", err); exit(1); } for (i = 0;; i++) { ret = gnutls_priority_get_cipher_suite_index(pcache, i, &idx); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) continue; name = gnutls_cipher_suite_info(idx, id, NULL, NULL, NULL, &version); if (name != NULL) dbgprintf("print_cipher_suite_list: %-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char)id[0], (unsigned char)id[1], gnutls_protocol_get_name(version)); } return; } } #endif /* initialize GnuTLS credential structure (certs etc) */ static rsRetVal gtlsInitCred(nsd_gtls_t *const pThis) { int gnuRet; const uchar *cafile, *crlfile; DEFiRet; /* X509 stuff */ if (pThis->xcred == NULL) { /* Allocate only ONCE */ CHKgnutls(gnutls_certificate_allocate_credentials(&pThis->xcred)); } /* sets the trusted cas file */ cafile = (pThis->pszCAFile == NULL) ? glbl.GetDfltNetstrmDrvrCAF(runConf) : pThis->pszCAFile; if (cafile == NULL && !(loggedWarnings & GTLS_LOGGED_WARN_CA_MISSING)) { LogError(0, RS_RET_CA_CERT_MISSING, "Warning: CA certificate is not set"); loggedWarnings |= GTLS_LOGGED_WARN_CA_MISSING; } if (cafile != NULL) { dbgprintf("GTLS CA file: '%s'\n", cafile); gnuRet = gnutls_certificate_set_x509_trust_file(pThis->xcred, (char *)cafile, GNUTLS_X509_FMT_PEM); if (gnuRet == GNUTLS_E_FILE_ERROR) { LogError(0, RS_RET_GNUTLS_ERR, "error reading certificate file '%s' - a common cause is that the " "file does not exist", cafile); ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } else if (gnuRet < 0) { /* TODO; a more generic error-tracking function (this one based on CHKgnutls()) */ uchar *pErr = gtlsStrerror(gnuRet); LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error reading CA certificate file %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); free(pErr); ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } } crlfile = (pThis->pszCRLFile == NULL) ? glbl.GetDfltNetstrmDrvrCRLF(runConf) : pThis->pszCRLFile; if (crlfile == NULL) { dbgprintf("Certificate revocation list (CRL) file not set."); } else { dbgprintf("GTLS CRL file: '%s'\n", crlfile); gnuRet = gnutls_certificate_set_x509_crl_file(pThis->xcred, (char *)crlfile, GNUTLS_X509_FMT_PEM); if (gnuRet == GNUTLS_E_FILE_ERROR) { LogError(0, RS_RET_GNUTLS_ERR, "error reading Certificate revocation list (CRL) '%s' - a common cause is that the " "file does not exist", crlfile); ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } else if (gnuRet < 0) { /* TODO; a more generic error-tracking function (this one based on CHKgnutls()) */ uchar *pErr = gtlsStrerror(gnuRet); LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error reading Certificate revocation list (CRL) %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); free(pErr); ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } } finalize_it: RETiRet; } /* globally initialize GnuTLS */ static rsRetVal gtlsGlblInit(void) { int gnuRet; DEFiRet; dbgprintf("gtlsGlblInit: Running Version: '%#010x'\n", GNUTLS_VERSION_NUMBER); /* gcry_control must be called first, so that the thread system is correctly set up */ #if GNUTLS_VERSION_NUMBER <= 0x020b00 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif CHKgnutls(gnutls_global_init()); if (GetGnuTLSLoglevel(runConf) > 0) { gnutls_global_set_log_function(logFunction); gnutls_global_set_log_level(GetGnuTLSLoglevel(runConf)); /* 0 (no) to 9 (most), 10 everything */ } /* Init Anon cipher helpers */ CHKgnutls(gnutls_dh_params_init(&dh_params)); CHKgnutls(gnutls_dh_params_generate2(dh_params, dhBits)); /* Allocate ANON Client Cred */ CHKgnutls(gnutls_anon_allocate_client_credentials(&anoncred)); /* Allocate ANON Server Cred */ CHKgnutls(gnutls_anon_allocate_server_credentials(&anoncredSrv)); gnutls_anon_set_server_dh_params(anoncredSrv, dh_params); finalize_it: RETiRet; } static rsRetVal gtlsInitSession(nsd_gtls_t *pThis) { DEFiRet; int gnuRet = 0; gnutls_session_t session; gnutls_init(&session, GNUTLS_SERVER); pThis->bHaveSess = 1; pThis->bIsInitiator = 0; pThis->sess = session; /* Moved CertKey Loading to top */ #if HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION /* store a pointer to ourselfs (needed by callback) */ gnutls_session_set_ptr(pThis->sess, (void *)pThis); iRet = gtlsLoadOurCertKey(pThis); /* first load .pem files */ if (iRet == RS_RET_OK) { dbgprintf("gtlsInitSession: enable certificate checking (VerifyDepth=%d)\n", pThis->DrvrVerifyDepth); gnutls_certificate_set_retrieve_function(pThis->xcred, gtlsClientCertCallback); if (pThis->DrvrVerifyDepth != 0) { gnutls_certificate_set_verify_limits(pThis->xcred, 8200, pThis->DrvrVerifyDepth); } } else if (iRet == RS_RET_CERTLESS) { dbgprintf("gtlsInitSession: certificates not configured, not loaded.\n"); } else { ABORT_FINALIZE(iRet); /* we have an error case! */ } #endif /* avoid calling all the priority functions, since the defaults are adequate. */ CHKgnutls(gnutls_credentials_set(pThis->sess, GNUTLS_CRD_CERTIFICATE, pThis->xcred)); /* check for anon authmode */ if (pThis->authMode == GTLS_AUTH_CERTANON) { dbgprintf("gtlsInitSession: anon authmode, gnutls_credentials_set GNUTLS_CRD_ANON\n"); CHKgnutls(gnutls_credentials_set(pThis->sess, GNUTLS_CRD_ANON, anoncredSrv)); gnutls_dh_set_prime_bits(pThis->sess, dhMinBits); } /* request client certificate if any. */ gnutls_certificate_server_set_request(pThis->sess, GNUTLS_CERT_REQUEST); finalize_it: if (iRet != RS_RET_OK && iRet != RS_RET_CERTLESS) { LogError(0, iRet, "gtlsInitSession failed to INIT Session %d", gnuRet); } RETiRet; } /* Obtain the CN from the DN field and hand it back to the caller * (which is responsible for destructing it). We try to follow * RFC2253 as far as it makes sense for our use-case. This function * is considered a compromise providing good-enough correctness while * limiting code size and complexity. If a problem occurs, we may enhance * this function. A (pointer to a) certificate must be caller-provided. * If no CN is contained in the cert, no string is returned * (*ppstrCN remains NULL). *ppstrCN MUST be NULL on entry! * rgerhards, 2008-05-22 */ static rsRetVal gtlsGetCN(gnutls_x509_crt_t *pCert, cstr_t **ppstrCN) { DEFiRet; int gnuRet; int i; int bFound; cstr_t *pstrCN = NULL; size_t size; /* big var the last, so we hope to have all we usually neeed within one mem cache line */ uchar szDN[1024]; /* this should really be large enough for any non-malicious case... */ assert(pCert != NULL); assert(ppstrCN != NULL); assert(*ppstrCN == NULL); size = sizeof(szDN); CHKgnutls(gnutls_x509_crt_get_dn(*pCert, (char *)szDN, &size)); /* now search for the CN part */ i = 0; bFound = 0; while (!bFound && szDN[i] != '\0') { /* note that we do not overrun our string due to boolean shortcut * operations. If we have '\0', the if does not match and evaluation * stops. Order of checks is obviously important! */ if (szDN[i] == 'C' && szDN[i + 1] == 'N' && szDN[i + 2] == '=') { bFound = 1; i += 2; } i++; } if (!bFound) { FINALIZE; /* we are done */ } /* we found a common name, now extract it */ CHKiRet(cstrConstruct(&pstrCN)); while (szDN[i] != '\0' && szDN[i] != ',') { if (szDN[i] == '\\') { /* hex escapes are not implemented */ ++i; /* escape char processed */ if (szDN[i] == '\0') ABORT_FINALIZE(RS_RET_CERT_INVALID_DN); CHKiRet(cstrAppendChar(pstrCN, szDN[i])); } else { CHKiRet(cstrAppendChar(pstrCN, szDN[i])); } ++i; /* char processed */ } cstrFinalize(pstrCN); /* we got it - we ignore the rest of the DN string (if any). So we may * not detect if it contains more than one CN */ *ppstrCN = pstrCN; finalize_it: if (iRet != RS_RET_OK) { if (pstrCN != NULL) cstrDestruct(&pstrCN); } RETiRet; } /* Check the peer's ID in fingerprint auth mode. * rgerhards, 2008-05-22 */ static rsRetVal gtlsChkPeerFingerprint(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert) { uchar fingerprint[20]; uchar fingerprintSha256[32]; size_t size; size_t sizeSha256; cstr_t *pstrFingerprint = NULL; cstr_t *pstrFingerprintSha256 = NULL; int bFoundPositiveMatch; permittedPeers_t *pPeer; int gnuRet; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); /* obtain the SHA1 fingerprint */ size = sizeof(fingerprint); sizeSha256 = sizeof(fingerprintSha256); CHKgnutls(gnutls_x509_crt_get_fingerprint(*pCert, GNUTLS_DIG_SHA1, fingerprint, &size)); CHKgnutls(gnutls_x509_crt_get_fingerprint(*pCert, GNUTLS_DIG_SHA256, fingerprintSha256, &sizeSha256)); CHKiRet(GenFingerprintStr(fingerprint, size, &pstrFingerprint, "SHA1")); CHKiRet(GenFingerprintStr(fingerprintSha256, sizeSha256, &pstrFingerprintSha256, "SHA256")); dbgprintf("peer's certificate SHA1 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprint)); dbgprintf("peer's certificate SHA256 fingerprint: %s\n", cstrGetSzStrNoNULL(pstrFingerprintSha256)); /* now search through the permitted peers to see if we can find a permitted one */ bFoundPositiveMatch = 0; pPeer = pThis->pPermPeers; while (pPeer != NULL && !bFoundPositiveMatch) { if (!rsCStrSzStrCmp(pstrFingerprint, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("gtlsChkPeerFingerprint: peer's certificate SHA1 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else if (!rsCStrSzStrCmp(pstrFingerprintSha256, pPeer->pszID, strlen((char *)pPeer->pszID))) { dbgprintf("gtlsChkPeerFingerprint: peer's certificate SHA256 MATCH found: %s\n", pPeer->pszID); bFoundPositiveMatch = 1; } else { pPeer = pPeer->pNext; } } if (!bFoundPositiveMatch) { dbgprintf("invalid peer fingerprint, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { errno = 0; LogError(0, RS_RET_INVALID_FINGERPRINT, "error: peer fingerprint '%s' unknown - we are " "not permitted to talk to it", cstrGetSzStrNoNULL(pstrFingerprint)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } finalize_it: if (pstrFingerprint != NULL) cstrDestruct(&pstrFingerprint); if (pstrFingerprintSha256 != NULL) cstrDestruct(&pstrFingerprintSha256); RETiRet; } /* Perform a match on ONE peer name obtained from the certificate. This name * is checked against the set of configured credentials. *pbFoundPositiveMatch is * set to 1 if the ID matches. *pbFoundPositiveMatch must have been initialized * to 0 by the caller (this is a performance enhancement as we expect to be * called multiple times). * TODO: implemet wildcards? * rgerhards, 2008-05-26 */ static rsRetVal gtlsChkOnePeerName(nsd_gtls_t *pThis, uchar *pszPeerID, int *pbFoundPositiveMatch) { permittedPeers_t *pPeer; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); assert(pszPeerID != NULL); assert(pbFoundPositiveMatch != NULL); if (pThis->pPermPeers) { /* do we have configured peer IDs? */ pPeer = pThis->pPermPeers; while (pPeer != NULL) { CHKiRet(net.PermittedPeerWildcardMatch(pPeer, pszPeerID, pbFoundPositiveMatch)); if (*pbFoundPositiveMatch) break; pPeer = pPeer->pNext; } } else { /* we do not have configured peer IDs, so we use defaults */ if (pThis->pszConnectHost && !strcmp((char *)pszPeerID, (char *)pThis->pszConnectHost)) { *pbFoundPositiveMatch = 1; } } finalize_it: RETiRet; } /* Check the peer's ID in name auth mode. * rgerhards, 2008-05-22 */ static rsRetVal gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt_t *pCert) { uchar lnBuf[256]; char szAltName[1024]; /* this is sufficient for the DNSNAME and IPADDRESS... */ int iAltName; size_t szAltNameLen; int bFoundPositiveMatch; int bHaveSAN = 0; cstr_t *pStr = NULL; cstr_t *pstrCN = NULL; int gnuRet; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); bFoundPositiveMatch = 0; CHKiRet(rsCStrConstruct(&pStr)); /* first search through the dNSName subject alt names */ iAltName = 0; while (!bFoundPositiveMatch) { /* loop broken below */ szAltNameLen = sizeof(szAltName); gnuRet = gnutls_x509_crt_get_subject_alt_name(*pCert, iAltName, szAltName, &szAltNameLen, NULL); if (gnuRet < 0) break; else if (gnuRet == GNUTLS_SAN_DNSNAME) { bHaveSAN = 1; dbgprintf("subject alt dnsName: '%s'\n", szAltName); snprintf((char *)lnBuf, sizeof(lnBuf), "DNSname: %s; ", szAltName); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(gtlsChkOnePeerName(pThis, (uchar *)szAltName, &bFoundPositiveMatch)); /* do NOT break, because there may be multiple dNSName's! */ } else if (gnuRet == GNUTLS_SAN_IPADDRESS) { bHaveSAN = 1; char ipAddress[INET6_ADDRSTRLEN]; inet_ntop(((szAltNameLen == sizeof(struct in6_addr)) ? AF_INET6 : AF_INET), szAltName, ipAddress, INET6_ADDRSTRLEN); dbgprintf("subject alt ipAddr: '%s'\n", ipAddress); snprintf((char *)lnBuf, sizeof(lnBuf), "IPaddress: %s; ", ipAddress); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(gtlsChkOnePeerName(pThis, (uchar *)ipAddress, &bFoundPositiveMatch)); /* do NOT break, because there may be multiple ipAddr's! */ } ++iAltName; } /* Check also CN only if not configured per stricter RFC 6125 or no SAN present*/ if (!bFoundPositiveMatch && (!pThis->bSANpriority || !bHaveSAN)) { CHKiRet(gtlsGetCN(pCert, &pstrCN)); if (pstrCN != NULL) { /* NULL if there was no CN present */ dbgprintf("gtls now checking auth for CN '%s'\n", cstrGetSzStrNoNULL(pstrCN)); snprintf((char *)lnBuf, sizeof(lnBuf), "CN: %s; ", cstrGetSzStrNoNULL(pstrCN)); CHKiRet(rsCStrAppendStr(pStr, lnBuf)); CHKiRet(gtlsChkOnePeerName(pThis, cstrGetSzStrNoNULL(pstrCN), &bFoundPositiveMatch)); } } if (!bFoundPositiveMatch) { dbgprintf("invalid peer name, not permitted to talk to it\n"); if (pThis->bReportAuthErr == 1) { cstrFinalize(pStr); errno = 0; LogError(0, RS_RET_INVALID_FINGERPRINT, "error: peer name not authorized - " "not permitted to talk to it. Names: %s", cstrGetSzStrNoNULL(pStr)); pThis->bReportAuthErr = 0; } ABORT_FINALIZE(RS_RET_INVALID_FINGERPRINT); } finalize_it: if (pStr != NULL) rsCStrDestruct(&pStr); if (pstrCN != NULL) rsCStrDestruct(&pstrCN); RETiRet; } /* check the ID of the remote peer - used for both fingerprint and * name authentication. This is common code. Will call into specific * drivers once the certificate has been obtained. * rgerhards, 2008-05-08 */ static rsRetVal gtlsChkPeerID(nsd_gtls_t *pThis) { const gnutls_datum_t *cert_list; unsigned int list_size = 0; gnutls_x509_crt_t cert; int bMustDeinitCert = 0; int gnuRet; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); /* This function only works for X.509 certificates. */ if (gnutls_certificate_type_get(pThis->sess) != GNUTLS_CRT_X509) return RS_RET_TLS_CERT_ERR; cert_list = gnutls_certificate_get_peers(pThis->sess, &list_size); if (list_size < 1) { if (pThis->bReportAuthErr == 1) { uchar *fromHost = NULL; errno = 0; pThis->bReportAuthErr = 0; nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHost); LogError(0, RS_RET_TLS_NO_CERT, "error: peer %s did not provide a certificate, " "not permitted to talk to it", fromHost); free(fromHost); } ABORT_FINALIZE(RS_RET_TLS_NO_CERT); } /* If we reach this point, we have at least one valid certificate. * We always use only the first certificate. As of GnuTLS documentation, the * first certificate always contains the remote peer's own certificate. All other * certificates are issuer's certificates (up the chain). We are only interested * in the first certificate, which is our peer. -- rgerhards, 2008-05-08 */ CHKgnutls(gnutls_x509_crt_init(&cert)); bMustDeinitCert = 1; /* indicate cert is initialized and must be freed on exit */ CHKgnutls(gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)); /* Now we see which actual authentication code we must call. */ if (pThis->authMode == GTLS_AUTH_CERTFINGERPRINT) { CHKiRet(gtlsChkPeerFingerprint(pThis, &cert)); } else { assert(pThis->authMode == GTLS_AUTH_CERTNAME); CHKiRet(gtlsChkPeerName(pThis, &cert)); } finalize_it: if (bMustDeinitCert) gnutls_x509_crt_deinit(cert); RETiRet; } /* Verify the validity of the remote peer's certificate. * rgerhards, 2008-05-21 */ static rsRetVal gtlsChkPeerCertValidity(nsd_gtls_t *pThis) { DEFiRet; const char *pszErrCause; int gnuRet; cstr_t *pStr = NULL; unsigned stateCert; const gnutls_datum_t *cert_list; unsigned cert_list_size = 0; gnutls_x509_crt_t cert; unsigned i; time_t ttCert; time_t ttNow; sbool bAbort = RSFALSE; int iAbortCode = RS_RET_OK; ISOBJ_TYPE_assert(pThis, nsd_gtls); /* check if we have at least one cert */ cert_list = gnutls_certificate_get_peers(pThis->sess, &cert_list_size); if (cert_list_size < 1) { errno = 0; uchar *fromHost = NULL; nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHost); LogError(0, RS_RET_TLS_NO_CERT, "peer %s did not provide a certificate, not permitted to talk to it", fromHost); free(fromHost); ABORT_FINALIZE(RS_RET_TLS_NO_CERT); } #ifdef EXTENDED_CERT_CHECK_AVAILABLE if (pThis->dataTypeCheck == GTLS_NONE) { #endif CHKgnutls(gnutls_certificate_verify_peers2(pThis->sess, &stateCert)); #ifdef EXTENDED_CERT_CHECK_AVAILABLE } else { /* we have configured data to check in addition to cert */ gnutls_typed_vdata_st data; data.type = GNUTLS_DT_KEY_PURPOSE_OID; if (pThis->bIsInitiator) { /* client mode */ data.data = (uchar *)GNUTLS_KP_TLS_WWW_SERVER; } else { /* server mode */ data.data = (uchar *)GNUTLS_KP_TLS_WWW_CLIENT; } data.size = ustrlen(data.data); CHKgnutls(gnutls_certificate_verify_peers(pThis->sess, &data, 1, &stateCert)); } #endif if (stateCert & GNUTLS_CERT_INVALID) { /* Default abort code */ iAbortCode = RS_RET_CERT_INVALID; /* provide error details if we have them */ if (stateCert & GNUTLS_CERT_EXPIRED) { dbgprintf("GnuTLS returned GNUTLS_CERT_EXPIRED, handling mode %d ...\n", pThis->permitExpiredCerts); /* Handle expired certs */ if (pThis->permitExpiredCerts == GTLS_EXPIRED_DENY) { bAbort = RSTRUE; iAbortCode = RS_RET_CERT_EXPIRED; } else if (pThis->permitExpiredCerts == GTLS_EXPIRED_WARN) { LogMsg(0, RS_RET_NO_ERRCODE, LOG_WARNING, "Warning, certificate expired but expired certs are permitted"); } else { dbgprintf("GnuTLS returned GNUTLS_CERT_EXPIRED, but expired certs are permitted.\n"); } pszErrCause = "certificate expired"; } else if (stateCert & GNUTLS_CERT_SIGNER_NOT_FOUND) { pszErrCause = "signer not found"; bAbort = RSTRUE; } else if (stateCert & GNUTLS_CERT_SIGNER_NOT_CA) { pszErrCause = "signer is not a CA"; bAbort = RSTRUE; } else if (stateCert & GNUTLS_CERT_INSECURE_ALGORITHM) { pszErrCause = "insecure algorithm"; bAbort = RSTRUE; } else if (stateCert & GNUTLS_CERT_REVOKED) { pszErrCause = "certificate revoked"; bAbort = RSTRUE; iAbortCode = RS_RET_CERT_REVOKED; #ifdef EXTENDED_CERT_CHECK_AVAILABLE } else if (stateCert & GNUTLS_CERT_PURPOSE_MISMATCH) { pszErrCause = "key purpose OID does not match"; bAbort = RSTRUE; #endif } else { pszErrCause = "GnuTLS returned no specific reason"; dbgprintf( "GnuTLS returned no specific reason for GNUTLS_CERT_INVALID, certificate " "status is %d\n", stateCert); bAbort = RSTRUE; } } if (bAbort == RSTRUE) { uchar *fromHost = NULL; nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHost); LogError(0, NO_ERRCODE, "not permitted to talk to peer '%s', certificate invalid: %s", fromHost, pszErrCause); free(fromHost); gtlsGetCertInfo(pThis, &pStr); LogError(0, NO_ERRCODE, "invalid cert info: %s", cstrGetSzStrNoNULL(pStr)); cstrDestruct(&pStr); ABORT_FINALIZE(iAbortCode); } /* get current time for certificate validation */ if (datetime.GetTime(&ttNow) == -1) ABORT_FINALIZE(RS_RET_SYS_ERR); /* as it looks, we need to validate the expiration dates ourselves... * We need to loop through all certificates as we need to make sure the * interim certificates are also not expired. */ for (i = 0; i < cert_list_size; ++i) { CHKgnutls(gnutls_x509_crt_init(&cert)); CHKgnutls(gnutls_x509_crt_import(cert, &cert_list[i], GNUTLS_X509_FMT_DER)); ttCert = gnutls_x509_crt_get_activation_time(cert); if (ttCert == -1) ABORT_FINALIZE(RS_RET_TLS_CERT_ERR); else if (ttCert > ttNow) { uchar *fromHost = NULL; nsd_ptcp.GetRemoteHName((nsd_t *)pThis->pTcp, &fromHost); LogError(0, RS_RET_CERT_NOT_YET_ACTIVE, "not permitted to talk to peer '%s': " "certificate %d not yet active", fromHost, i); free(fromHost); gtlsGetCertInfo(pThis, &pStr); LogError(0, RS_RET_CERT_NOT_YET_ACTIVE, "invalid cert info: %s", cstrGetSzStrNoNULL(pStr)); cstrDestruct(&pStr); ABORT_FINALIZE(RS_RET_CERT_NOT_YET_ACTIVE); } gnutls_x509_crt_deinit(cert); } finalize_it: RETiRet; } /* check if it is OK to talk to the remote peer * rgerhards, 2008-05-21 */ rsRetVal gtlsChkPeerAuth(nsd_gtls_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); /* call the actual function based on current auth mode */ switch (pThis->authMode) { case GTLS_AUTH_CERTNAME: /* if we check the name, we must ensure the cert is valid */ CHKiRet(gtlsChkPeerCertValidity(pThis)); CHKiRet(gtlsChkPeerID(pThis)); break; case GTLS_AUTH_CERTFINGERPRINT: CHKiRet(gtlsChkPeerID(pThis)); break; case GTLS_AUTH_CERTVALID: CHKiRet(gtlsChkPeerCertValidity(pThis)); break; case GTLS_AUTH_CERTANON: FINALIZE; break; default: // No action needed for other cases break; } finalize_it: RETiRet; } /* globally de-initialize GnuTLS */ static rsRetVal gtlsGlblExit(void) { DEFiRet; gnutls_anon_free_server_credentials(anoncredSrv); gnutls_dh_params_deinit(dh_params); gnutls_global_deinit(); RETiRet; } /* end a GnuTLS session * The function checks if we have a session and ends it only if so. So it can * always be called, even if there currently is no session. */ static rsRetVal gtlsEndSess(nsd_gtls_t *pThis) { int gnuRet; DEFiRet; if (pThis->bHaveSess) { if (pThis->bIsInitiator) { gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_WR); while (gnuRet == GNUTLS_E_INTERRUPTED || gnuRet == GNUTLS_E_AGAIN) { gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_WR); } } gnutls_deinit(pThis->sess); pThis->bHaveSess = 0; } RETiRet; } /* a small wrapper for gnutls_transport_set_ptr(). The main intension for * creating this wrapper is to get the annoying "cast to pointer from different * size" compiler warning just once. There seems to be no way around it, see: * http://lists.gnu.org/archive/html/help-gnutls/2008-05/msg00000.html * rgerhards, 2008.05-07 */ #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" static inline void gtlsSetTransportPtr(nsd_gtls_t *pThis, int sock) { /* Note: the compiler warning for the next line is OK - see header comment! */ gnutls_transport_set_ptr(pThis->sess, (gnutls_transport_ptr_t)sock); } #pragma GCC diagnostic warning "-Wint-to-pointer-cast" /* ---------------------------- end GnuTLS specifics ---------------------------- */ /* Standard-Constructor */ BEGINobjConstruct(nsd_gtls) /* be sure to specify the object type also in END macro! */ iRet = nsd_ptcp.Construct(&pThis->pTcp); pThis->bReportAuthErr = 1; ENDobjConstruct(nsd_gtls) /* destructor for the nsd_gtls object */ PROTOTYPEobjDestruct(nsd_gtls); BEGINobjDestruct(nsd_gtls) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(nsd_gtls); if (pThis->iMode == 1) { gtlsEndSess(pThis); } if (pThis->pTcp != NULL) { nsd_ptcp.Destruct(&pThis->pTcp); } free(pThis->pszConnectHost); free(pThis->pszRcvBuf); free((void *)pThis->pszCAFile); free((void *)pThis->pszCRLFile); if (pThis->bOurCertIsInit) for (unsigned i = 0; i < pThis->nOurCerts; ++i) { gnutls_x509_crt_deinit(pThis->pOurCerts[i]); } if (pThis->bOurKeyIsInit) gnutls_x509_privkey_deinit(pThis->ourKey); if (pThis->bHaveSess) gnutls_deinit(pThis->sess); if (pThis->xcred != NULL && (pThis->bIsInitiator || (!pThis->xcred_is_copy && (!pThis->bIsInitiator || pThis->bHaveSess)))) { gnutls_certificate_free_credentials(pThis->xcred); free((void *)pThis->pszKeyFile); free((void *)pThis->pszCertFile); } ENDobjDestruct(nsd_gtls) /* Set the driver mode. For us, this has the following meaning: * 0 - work in plain tcp mode, without tls (e.g. before a STARTTLS) * 1 - work in TLS mode * rgerhards, 2008-04-28 */ static rsRetVal SetMode(nsd_t *const pNsd, const int mode) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); dbgprintf("(tls) mode: %d\n", mode); if (mode != 0 && mode != 1) { LogError(0, RS_RET_INVALID_DRVR_MODE, "error: driver mode %d not supported by " "gtls netstream driver", mode); ABORT_FINALIZE(RS_RET_INVALID_DRVR_MODE); } pThis->iMode = mode; finalize_it: RETiRet; } /* Set the authentication mode. For us, the following is supported: * anon - no certificate checks whatsoever (discouraged, but supported) * x509/certvalid - (just) check certificate validity * x509/fingerprint - certificate fingerprint * x509/name - cerfificate name check * mode == NULL is valid and defaults to x509/name * rgerhards, 2008-05-16 */ static rsRetVal SetAuthMode(nsd_t *pNsd, uchar *mode) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (mode == NULL || !strcasecmp((char *)mode, "x509/name")) { pThis->authMode = GTLS_AUTH_CERTNAME; } else if (!strcasecmp((char *)mode, "x509/fingerprint")) { pThis->authMode = GTLS_AUTH_CERTFINGERPRINT; } else if (!strcasecmp((char *)mode, "x509/certvalid")) { pThis->authMode = GTLS_AUTH_CERTVALID; } else if (!strcasecmp((char *)mode, "anon")) { pThis->authMode = GTLS_AUTH_CERTANON; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: authentication mode '%s' not supported by " "gtls netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetAuthMode to %s\n", (mode != NULL ? (char *)mode : "NULL")); /* TODO: clear stored IDs! */ finalize_it: RETiRet; } /* Set the PermitExpiredCerts mode. For us, the following is supported: * on - fail if certificate is expired * off - ignore expired certificates * warn - warn if certificate is expired * alorbach, 2018-12-20 */ static rsRetVal SetPermitExpiredCerts(nsd_t *pNsd, uchar *mode) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); /* default is set to off! */ if (mode == NULL || !strcasecmp((char *)mode, "off")) { pThis->permitExpiredCerts = GTLS_EXPIRED_DENY; } else if (!strcasecmp((char *)mode, "warn")) { pThis->permitExpiredCerts = GTLS_EXPIRED_WARN; } else if (!strcasecmp((char *)mode, "on")) { pThis->permitExpiredCerts = GTLS_EXPIRED_PERMIT; } else { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: permitexpiredcerts mode '%s' not supported by " "gtls netstream driver", mode); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } dbgprintf("SetPermitExpiredCerts: Set Mode %s/%d\n", (mode != NULL ? (char *)mode : "NULL"), pThis->permitExpiredCerts); /* TODO: clear stored IDs! */ finalize_it: RETiRet; } /* Set permitted peers. It is depending on the auth mode if this are * fingerprints or names. -- rgerhards, 2008-05-19 */ static rsRetVal SetPermPeers(nsd_t *pNsd, permittedPeers_t *pPermPeers) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (pPermPeers == NULL) FINALIZE; if (pThis->authMode != GTLS_AUTH_CERTFINGERPRINT && pThis->authMode != GTLS_AUTH_CERTNAME) { LogError(0, RS_RET_VALUE_NOT_IN_THIS_MODE, "authentication not supported by " "gtls netstream driver in the configured authentication mode - ignored"); ABORT_FINALIZE(RS_RET_VALUE_NOT_IN_THIS_MODE); } pThis->pPermPeers = pPermPeers; finalize_it: RETiRet; } /* gnutls priority string * PascalWithopf 2017-08-16 */ static rsRetVal SetGnutlsPriorityString(nsd_t *pNsd, uchar *gnutlsPriorityString) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); pThis->gnutlsPriorityString = gnutlsPriorityString; dbgprintf("gnutlsPriorityString: set to '%s'\n", (gnutlsPriorityString != NULL ? (char *)gnutlsPriorityString : "NULL")); RETiRet; } /* Set the driver cert extended key usage check setting * 0 - ignore contents of extended key usage * 1 - verify that cert contents is compatible with appropriate OID * jvymazal, 2019-08-16 */ static rsRetVal SetCheckExtendedKeyUsage(nsd_t *pNsd, int ChkExtendedKeyUsage) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (ChkExtendedKeyUsage != 0 && ChkExtendedKeyUsage != 1) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver ChkExtendedKeyUsage %d " "not supported by gtls netstream driver", ChkExtendedKeyUsage); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } pThis->dataTypeCheck = ChkExtendedKeyUsage; finalize_it: RETiRet; } /* Set the driver name checking strictness * 0 - less strict per RFC 5280, section 4.1.2.6 - either SAN or CN match is good * 1 - more strict per RFC 6125 - if any SAN present it must match (CN is ignored) * jvymazal, 2019-08-16 */ static rsRetVal SetPrioritizeSAN(nsd_t *pNsd, int prioritizeSan) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (prioritizeSan != 0 && prioritizeSan != 1) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "error: driver prioritizeSan %d " "not supported by gtls netstream driver", prioritizeSan); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } pThis->bSANpriority = prioritizeSan; finalize_it: RETiRet; } /* Set the driver tls verifyDepth * alorbach, 2019-12-20 */ static rsRetVal SetTlsVerifyDepth(nsd_t *pNsd, int verifyDepth) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (verifyDepth == 0) { FINALIZE; } assert(verifyDepth >= 2); pThis->DrvrVerifyDepth = verifyDepth; finalize_it: RETiRet; } static rsRetVal SetTlsCAFile(nsd_t *pNsd, const uchar *const caFile) { DEFiRet; nsd_gtls_t *const pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (caFile == NULL) { pThis->pszCAFile = NULL; } else { CHKmalloc(pThis->pszCAFile = (const uchar *)strdup((const char *)caFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCRLFile(nsd_t *pNsd, const uchar *const crlFile) { DEFiRet; nsd_gtls_t *const pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (crlFile == NULL) { pThis->pszCRLFile = NULL; } else { CHKmalloc(pThis->pszCRLFile = (const uchar *)strdup((const char *)crlFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsKeyFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_gtls_t *const pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (pszFile == NULL) { pThis->pszKeyFile = NULL; } else { CHKmalloc(pThis->pszKeyFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } static rsRetVal SetTlsCertFile(nsd_t *pNsd, const uchar *const pszFile) { DEFiRet; nsd_gtls_t *const pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (pszFile == NULL) { pThis->pszCertFile = NULL; } else { CHKmalloc(pThis->pszCertFile = (const uchar *)strdup((const char *)pszFile)); } finalize_it: RETiRet; } /* Provide access to the underlying OS socket. This is primarily * useful for other drivers (like nsd_gtls) who utilize ourselfs * for some of their functionality. -- rgerhards, 2008-04-18 */ static rsRetVal SetSock(nsd_t *pNsd, int sock) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); assert(sock >= 0); nsd_ptcp.SetSock(pThis->pTcp, sock); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveIntvl(nsd_t *pNsd, int keepAliveIntvl) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); assert(keepAliveIntvl >= 0); nsd_ptcp.SetKeepAliveIntvl(pThis->pTcp, keepAliveIntvl); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveProbes(nsd_t *pNsd, int keepAliveProbes) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); assert(keepAliveProbes >= 0); nsd_ptcp.SetKeepAliveProbes(pThis->pTcp, keepAliveProbes); RETiRet; } /* Keep Alive Options */ static rsRetVal SetKeepAliveTime(nsd_t *pNsd, int keepAliveTime) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert((pThis), nsd_gtls); assert(keepAliveTime >= 0); nsd_ptcp.SetKeepAliveTime(pThis->pTcp, keepAliveTime); RETiRet; } /* abort a connection. This is meant to be called immediately * before the Destruct call. -- rgerhards, 2008-03-24 */ static rsRetVal Abort(nsd_t *pNsd) { nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert((pThis), nsd_gtls); if (pThis->iMode == 0) { nsd_ptcp.Abort(pThis->pTcp); } RETiRet; } /* Callback after netstrm obj init in nsd_ptcp - permits us to add some data */ static rsRetVal LstnInitDrvr(netstrm_t *const pThis) { DEFiRet; CHKiRet(gtlsInitCred((nsd_gtls_t *)pThis->pDrvrData)); CHKiRet(gtlsAddOurCert((nsd_gtls_t *)pThis->pDrvrData)); finalize_it: RETiRet; } /* initialize the tcp socket for a listner * Here, we use the ptcp driver - because there is nothing special * at this point with GnuTLS. Things become special once we accept * a session, but not during listener setup. * gerhards, 2008-04-25 */ static rsRetVal ATTR_NONNULL(1, 3, 5) LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal (*fAddLstn)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params) { DEFiRet; pNS->fLstnInitDrvr = LstnInitDrvr; iRet = nsd_ptcp.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params); // finalize_it: RETiRet; } /* This function checks if the connection is still alive - well, kind of... * This is a dummy here. For details, check function common in ptcp driver. * rgerhards, 2008-06-09 */ static rsRetVal CheckConnection(nsd_t __attribute__((unused)) * pNsd) { nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); dbgprintf("CheckConnection for %p\n", pNsd); return nsd_ptcp.CheckConnection(pThis->pTcp); } /* Provide access to the underlying OS socket. */ static rsRetVal GetSock(nsd_t *pNsd, int *pSock) { nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; return nsd_ptcp.GetSock(pThis->pTcp, pSock); } /* get the remote hostname. The returned hostname must be freed by the caller. * rgerhards, 2008-04-25 */ static rsRetVal GetRemoteHName(nsd_t *pNsd, uchar **ppszHName) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); iRet = nsd_ptcp.GetRemoteHName(pThis->pTcp, ppszHName); RETiRet; } /* Provide access to the sockaddr_storage of the remote peer. This * is needed by the legacy ACL system. --- gerhards, 2008-12-01 */ static rsRetVal GetRemAddr(nsd_t *pNsd, struct sockaddr_storage **ppAddr) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); iRet = nsd_ptcp.GetRemAddr(pThis->pTcp, ppAddr); RETiRet; } /* get the remote host's IP address. Caller must Destruct the object. */ static rsRetVal GetRemoteIP(nsd_t *pNsd, prop_t **ip) { DEFiRet; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); iRet = nsd_ptcp.GetRemoteIP(pThis->pTcp, ip); RETiRet; } /* accept an incoming connection request - here, we do the usual accept * handling. TLS specific handling is done thereafter (and if we run in TLS * mode at this time). * rgerhards, 2008-04-25 */ static rsRetVal AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew, char *const connInfo) { DEFiRet; int gnuRet; nsd_gtls_t *pNew = NULL; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; const char *error_position = NULL; ISOBJ_TYPE_assert((pThis), nsd_gtls); CHKiRet(nsd_gtlsConstruct(&pNew)); // TODO: prevent construct/destruct! CHKiRet(nsd_ptcp.Destruct(&pNew->pTcp)); CHKiRet(nsd_ptcp.AcceptConnReq(pThis->pTcp, &pNew->pTcp, connInfo)); if (pThis->iMode == 0) { /* we are in non-TLS mode, so we are done */ *ppNew = (nsd_t *)pNew; FINALIZE; } /* copy Properties to pnew first */ pNew->authMode = pThis->authMode; pNew->permitExpiredCerts = pThis->permitExpiredCerts; pNew->pPermPeers = pThis->pPermPeers; pNew->gnutlsPriorityString = pThis->gnutlsPriorityString; pNew->DrvrVerifyDepth = pThis->DrvrVerifyDepth; pNew->dataTypeCheck = pThis->dataTypeCheck; pNew->bSANpriority = pThis->bSANpriority; pNew->pszCertFile = pThis->pszCertFile; pNew->pszKeyFile = pThis->pszKeyFile; pNew->xcred = pThis->xcred; // TODO: verify once again; xcred is read only at this stage pNew->xcred_is_copy = 1; // do not free on pNew Destruction /* if we reach this point, we are in TLS mode */ iRet = gtlsInitSession(pNew); if (iRet != RS_RET_OK) { if (iRet == RS_RET_CERTLESS) { dbgprintf("AcceptConnReq certless mode\n"); /* Set status to OK */ iRet = RS_RET_OK; } else { goto finalize_it; } } gtlsSetTransportPtr(pNew, ((nsd_ptcp_t *)(pNew->pTcp))->sock); dbgprintf("AcceptConnReq bOurCertIsInit=%hu bOurKeyIsInit=%hu \n", pNew->bOurCertIsInit, pNew->bOurKeyIsInit); /* here is the priorityString set */ if (pNew->gnutlsPriorityString != NULL) { dbgprintf("AcceptConnReq setting configured priority string (ciphers)\n"); if (gnutls_priority_set_direct(pNew->sess, (const char *)pNew->gnutlsPriorityString, &error_position) == GNUTLS_E_INVALID_REQUEST) { LogError(0, RS_RET_GNUTLS_ERR, "Syntax Error in" " Priority String: \"%s\"\n", error_position); } } else { if (pThis->authMode == GTLS_AUTH_CERTANON) { /* Allow ANON Ciphers */ dbgprintf("AcceptConnReq setting anon ciphers Try1: %s\n", GTLS_ANON_PRIO_NOTLSV13); if (gnutls_priority_set_direct(pNew->sess, (const char *)GTLS_ANON_PRIO_NOTLSV13, &error_position) == GNUTLS_E_INVALID_REQUEST) { dbgprintf("AcceptConnReq setting anon ciphers Try2 (TLS1.3 unknown): %s\n", GTLS_ANON_PRIO); CHKgnutls(gnutls_priority_set_direct(pNew->sess, GTLS_ANON_PRIO, &error_position)); } /* Uncomment for DEBUG print_cipher_suite_list("NORMAL:+ANON-DH:+ANON-ECDH:+COMP-ALL"); */ } else { /* Use default priorities */ dbgprintf("AcceptConnReq setting default ciphers\n"); CHKgnutls(gnutls_set_default_priority(pNew->sess)); } } /* we now do the handshake. This is a bit complicated, because we are * on non-blocking sockets. Usually, the handshake will not complete * immediately, so that we need to retry it some time later. */ gnuRet = gnutls_handshake(pNew->sess); if (gnuRet == GNUTLS_E_AGAIN || gnuRet == GNUTLS_E_INTERRUPTED) { pNew->rtryCall = gtlsRtry_handshake; dbgprintf( "GnuTLS handshake does not complete immediately - " "setting to retry (this is OK and normal)\n"); } else if (gnuRet == 0) { /* we got a handshake, now check authorization */ CHKiRet(gtlsChkPeerAuth(pNew)); } else { uchar *pGnuErr = gtlsStrerror(gnuRet); uchar *fromHostIP = NULL; int remotePort; uchar remotePortStr[8]; nsd_ptcp.GetRemoteHName((nsd_t *)pNew->pTcp, &fromHostIP); nsd_ptcp.GetRemotePort((nsd_t *)pNew->pTcp, &remotePort); nsd_ptcp.FmtRemotePortStr(remotePort, remotePortStr, sizeof(remotePortStr)); LogError(0, RS_RET_TLS_HANDSHAKE_ERR, "nsd_gtls:TLS session terminated with remote client '%s:%s': " "gnutls returned error on handshake: %s", fromHostIP, remotePortStr, pGnuErr); free(fromHostIP); free(pGnuErr); ABORT_FINALIZE(RS_RET_TLS_HANDSHAKE_ERR); } pNew->iMode = 1; /* this session is now in TLS mode! */ *ppNew = (nsd_t *)pNew; finalize_it: if (iRet != RS_RET_OK) { if (error_position != NULL) { dbgprintf("AcceptConnReq error_position=%s\n", error_position); } if (pNew != NULL) nsd_gtlsDestruct(&pNew); } RETiRet; } /* receive data from a tcp socket * The lenBuf parameter must contain the max buffer size on entry and contains * the number of octets read on exit. This function * never blocks, not even when called on a blocking socket. That is important * for client sockets, which are set to block during send, but should not * block when trying to read data. -- rgerhards, 2008-03-17 * The function now follows the usual iRet calling sequence. * With GnuTLS, we may need to restart a recv() system call. If so, we need * to supply the SAME buffer on the retry. We can not assure this, as the * caller is free to call us with any buffer location (and in current * implementation, it is on the stack and extremely likely to change). To * work-around this problem, we allocate a buffer ourselfs and always receive * into that buffer. We pass data on to the caller only after we have received it. * To save some space, we allocate that internal buffer only when it is actually * needed, which means when we reach this function for the first time. To keep * the algorithm simple, we always supply data only from the internal buffer, * even if it is a single byte. As we have a stream, the caller must be prepared * to accept messages in any order, so we do not need to take care about this. * Please note that the logic also forces us to do some "faking" in select(), as * we must provide a fake "is ready for readign" status if we have data inside our * buffer. -- rgerhards, 2008-06-23 */ static rsRetVal Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf, int *const oserr, unsigned *const nextIODirection) { DEFiRet; ssize_t iBytesCopy; /* how many bytes are to be copied to the client buffer? */ nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf, oserr, nextIODirection)); FINALIZE; } /* --- in TLS mode now --- */ if (pThis->rtryCall == gtlsRtry_handshake) { /* note: we are in receive, so we acually will retry receive in any case */ DBGPRINTF("need to do retry handshake\n"); CHKiRet(doRetry(pThis)); ABORT_FINALIZE(RS_RET_RETRY); } /* Buffer logic applies only if we are in TLS mode. Here we * assume that we will switch from plain to TLS, but never back. This * assumption may be unsafe, but it is the model for the time being and I * do not see any valid reason why we should switch back to plain TCP after * we were in TLS mode. However, in that case we may lose something that * is already in the receive buffer ... risk accepted. -- rgerhards, 2008-06-23 */ if (pThis->pszRcvBuf == NULL) { /* we have no buffer, so we need to malloc one */ CHKmalloc(pThis->pszRcvBuf = malloc(NSD_GTLS_MAX_RCVBUF)); pThis->lenRcvBuf = -1; } /* now check if we have something in our buffer. If so, we satisfy * the request from buffer contents. */ if (pThis->lenRcvBuf == -1) { /* no data present, must read */ CHKiRet(gtlsRecordRecv(pThis, nextIODirection)); } if (pThis->lenRcvBuf == 0) { /* EOS */ *oserr = errno; ABORT_FINALIZE(RS_RET_CLOSED); } /* if we reach this point, data is present in the buffer and must be copied */ iBytesCopy = pThis->lenRcvBuf - pThis->ptrRcvBuf; if (iBytesCopy > *pLenBuf) { iBytesCopy = *pLenBuf; } else { pThis->lenRcvBuf = -1; /* buffer will be emptied below */ } memcpy(pBuf, pThis->pszRcvBuf + pThis->ptrRcvBuf, iBytesCopy); pThis->ptrRcvBuf += iBytesCopy; *pLenBuf = iBytesCopy; finalize_it: if (iRet != RS_RET_OK && iRet != RS_RET_RETRY) { /* We need to free the receive buffer in error error case unless a retry is wanted. , if we * allocated one. -- rgerhards, 2008-12-03 -- moved here by alorbach, 2015-12-01 */ *pLenBuf = 0; free(pThis->pszRcvBuf); pThis->pszRcvBuf = NULL; } dbgprintf("gtlsRcv return. nsd %p, iRet %d, lenRcvBuf %d, ptrRcvBuf %d\n", pThis, iRet, pThis->lenRcvBuf, pThis->ptrRcvBuf); RETiRet; } /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has * been written. * rgerhards, 2008-03-19 */ static rsRetVal Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf) { int iSent; int wantsWriteData = 0; nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; DEFiRet; ISOBJ_TYPE_assert(pThis, nsd_gtls); if (pThis->rtryCall == gtlsRtry_recv) { CHKiRet(doRetry(pThis)); FINALIZE; } if (pThis->bAbortConn) ABORT_FINALIZE(RS_RET_CONNECTION_ABORTREQ); if (pThis->iMode == 0) { CHKiRet(nsd_ptcp.Send(pThis->pTcp, pBuf, pLenBuf)); FINALIZE; } while (1) { /* loop broken inside */ iSent = gnutls_record_send(pThis->sess, pBuf, *pLenBuf); if (iSent >= 0) { *pLenBuf = iSent; break; } if (iSent == GNUTLS_E_AGAIN || iSent == GNUTLS_E_INTERRUPTED) { /* * GnuTLS may require us to read to make progress (e.g. KeyUpdate). * If direction is READ, call the buffered recv helper so we do not lose data. */ if (gnutls_record_get_direction(pThis->sess) == gtlsDir_READ) { unsigned nextIODirection ATTR_UNUSED; rsRetVal rcvRet = gtlsRecordRecv(pThis, &nextIODirection); if (rcvRet == RS_RET_CLOSED || pThis->lenRcvBuf == 0) { /* check for explicit close or 0-byte read */ ABORT_FINALIZE(RS_RET_CLOSED); } else if (rcvRet != RS_RET_OK && rcvRet != RS_RET_RETRY) { ABORT_FINALIZE(rcvRet); } } continue; /* retry send */ } else { /* Check if the underlaying file descriptor needs to read or write data!*/ wantsWriteData = gnutls_record_get_direction(pThis->sess); uchar *pErr = gtlsStrerror(iSent); LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d, wantsWriteData=%d - this " "could be caused by a broken connection. GnuTLS reports: %s\n", iSent, wantsWriteData, pErr); free(pErr); gnutls_perror(iSent); ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } } finalize_it: RETiRet; } /* Enable KEEPALIVE handling on the socket. * rgerhards, 2009-06-02 */ static rsRetVal EnableKeepAlive(nsd_t *pNsd) { nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; ISOBJ_TYPE_assert(pThis, nsd_gtls); return nsd_ptcp.EnableKeepAlive(pThis->pTcp); } /* * SNI should not be used if the hostname is a bare IP address */ static int SetServerNameIfPresent(nsd_gtls_t *pThis, uchar *host) { struct sockaddr_in sa; struct sockaddr_in6 sa6; int inet_pton_ret = inet_pton(AF_INET, CHAR_CONVERT(host), &(sa.sin_addr)); if (inet_pton_ret == 0) { // host wasn't a bare IPv4 address: try IPv6 inet_pton_ret = inet_pton(AF_INET6, CHAR_CONVERT(host), &(sa6.sin6_addr)); } switch (inet_pton_ret) { case 1: // host is a valid IP address: don't use SNI return 0; case 0: // host isn't a valid IP address: assume it's a domain name, use SNI return gnutls_server_name_set(pThis->sess, GNUTLS_NAME_DNS, host, ustrlen(host)); default: // unexpected error return -1; } } /* open a connection to a remote host (server). With GnuTLS, we always * open a plain tcp socket and then, if in TLS mode, do a handshake on it. * rgerhards, 2008-03-19 */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" /* TODO: FIX Warnings! */ static rsRetVal Connect(nsd_t *pNsd, int family, uchar *port, uchar *host, char *device) { nsd_gtls_t *pThis = (nsd_gtls_t *)pNsd; int sock; int gnuRet; const char *error_position; #ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY static const int cert_type_priority[2] = {GNUTLS_CRT_X509, 0}; #endif DEFiRet; dbgprintf("Connect to %s:%s\n", host, port); ISOBJ_TYPE_assert(pThis, nsd_gtls); assert(port != NULL); assert(host != NULL); CHKiRet(gtlsInitCred(pThis)); CHKiRet(gtlsAddOurCert(pThis)); CHKiRet(nsd_ptcp.Connect(pThis->pTcp, family, port, host, device)); if (pThis->iMode == 0) FINALIZE; /* we reach this point if in TLS mode */ CHKgnutls(gnutls_init(&pThis->sess, GNUTLS_CLIENT)); pThis->bHaveSess = 1; pThis->bIsInitiator = 1; CHKgnutls(SetServerNameIfPresent(pThis, host)); /* in the client case, we need to set a callback that ensures our certificate * will be presented to the server even if it is not signed by one of the server's * trusted roots. This is necessary to support fingerprint authentication. */ /* store a pointer to ourselfs (needed by callback) */ gnutls_session_set_ptr(pThis->sess, (void *)pThis); iRet = gtlsLoadOurCertKey(pThis); /* first load .pem files */ if (iRet == RS_RET_OK) { #if HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION gnutls_certificate_set_retrieve_function(pThis->xcred, gtlsClientCertCallback); #else gnutls_certificate_client_set_retrieve_function(pThis->xcred, gtlsClientCertCallback); #endif dbgprintf("Connect: enable certificate checking (VerifyDepth=%d)\n", pThis->DrvrVerifyDepth); if (pThis->DrvrVerifyDepth != 0) { gnutls_certificate_set_verify_limits(pThis->xcred, 8200, pThis->DrvrVerifyDepth); } } else if (iRet == RS_RET_CERTLESS) { dbgprintf("Connect: certificates not configured, not loaded.\n"); } else { LogError(0, iRet, "Connect failed to INIT Session %d", gnuRet); ABORT_FINALIZE(iRet); ; /* we have an error case! */ } /*priority string setzen*/ if (pThis->gnutlsPriorityString != NULL) { dbgprintf("Connect: setting configured priority string (ciphers)\n"); if (gnutls_priority_set_direct(pThis->sess, (const char *)pThis->gnutlsPriorityString, &error_position) == GNUTLS_E_INVALID_REQUEST) { LogError(0, RS_RET_GNUTLS_ERR, "Syntax Error in" " Priority String: \"%s\"\n", error_position); } } else { if (pThis->authMode == GTLS_AUTH_CERTANON || pThis->bOurCertIsInit == 0) { /* Allow ANON Ciphers */ dbgprintf("Connect: setting anon ciphers Try1: %s\n", GTLS_ANON_PRIO_NOTLSV13); if (gnutls_priority_set_direct(pThis->sess, (const char *)GTLS_ANON_PRIO_NOTLSV13, &error_position) == GNUTLS_E_INVALID_REQUEST) { dbgprintf("Connect: setting anon ciphers Try2 (TLS1.3 unknown): %s\n", GTLS_ANON_PRIO); CHKgnutls(gnutls_priority_set_direct(pThis->sess, GTLS_ANON_PRIO, &error_position)); } /* Uncomment for DEBUG print_cipher_suite_list("NORMAL:+ANON-DH:+ANON-ECDH:+COMP-ALL"); */ } else { /* Use default priorities */ dbgprintf("Connect: setting default ciphers\n"); CHKgnutls(gnutls_set_default_priority(pThis->sess)); } } #ifdef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY /* The gnutls_certificate_type_set_priority function is deprecated * and not available in recent GnuTLS versions. However, there is no * doc how to properly replace it with gnutls_priority_set_direct. * A lot of folks have simply removed it, when they also called * gnutls_set_default_priority. This is what we now also do. If * this causes problems or someone has an idea of how to replace * the deprecated function in a better way, please let us know! * In any case, we use it as long as it is available and let * not insult us by the deprecation warnings. * 2015-05-18 rgerhards */ CHKgnutls(gnutls_certificate_type_set_priority(pThis->sess, cert_type_priority)); #endif /* put the x509 credentials to the current session */ CHKgnutls(gnutls_credentials_set(pThis->sess, GNUTLS_CRD_CERTIFICATE, pThis->xcred)); /* check for anon authmode */ if (pThis->authMode == GTLS_AUTH_CERTANON) { dbgprintf("Connect: anon authmode, gnutls_credentials_set GNUTLS_CRD_ANON\n"); CHKgnutls(gnutls_credentials_set(pThis->sess, GNUTLS_CRD_ANON, anoncred)); gnutls_dh_set_prime_bits(pThis->sess, dhMinBits); } CHKiRet(nsd_ptcp.GetSock(pThis->pTcp, &sock)); /* assign the socket to GnuTls */ gtlsSetTransportPtr(pThis, sock); /* we need to store the hostname as an alternate mean of authentication if no * permitted peer names are given. Using the hostname is quite useful. It permits * auto-configuration of security if a commen root cert is present. -- rgerhards, 2008-05-26 */ CHKmalloc(pThis->pszConnectHost = (uchar *)strdup((char *)host)); /* and perform the handshake */ gnutls_handshake_set_timeout(pThis->sess, 3000); CHKgnutls(gnutls_handshake(pThis->sess)); dbgprintf("GnuTLS handshake succeeded\n"); /* now check if the remote peer is permitted to talk to us - ideally, we * should do this during the handshake, but GnuTLS does not yet provide * the necessary callbacks -- rgerhards, 2008-05-26 */ CHKiRet(gtlsChkPeerAuth(pThis)); finalize_it: if (iRet != RS_RET_OK) { if (pThis->bHaveSess) { gnutls_deinit(pThis->sess); pThis->bHaveSess = 0; /* Free memory using gnutls api first*/ gnutls_certificate_free_credentials(pThis->xcred); pThis->xcred = NULL; /* Free other memory */ free(pThis->pszConnectHost); pThis->pszConnectHost = NULL; } } RETiRet; } #pragma GCC diagnostic pop /* queryInterface function */ BEGINobjQueryInterface(nsd_gtls) CODESTARTobjQueryInterface(nsd_gtls); if (pIf->ifVersion != nsdCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = (rsRetVal(*)(nsd_t **))nsd_gtlsConstruct; pIf->Destruct = (rsRetVal(*)(nsd_t **))nsd_gtlsDestruct; pIf->Abort = Abort; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->Rcv = Rcv; pIf->Send = Send; pIf->Connect = Connect; pIf->GetSock = GetSock; pIf->SetSock = SetSock; pIf->SetMode = SetMode; pIf->SetAuthMode = SetAuthMode; pIf->SetPermitExpiredCerts = SetPermitExpiredCerts; pIf->SetPermPeers = SetPermPeers; pIf->CheckConnection = CheckConnection; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->GetRemAddr = GetRemAddr; pIf->EnableKeepAlive = EnableKeepAlive; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetCheckExtendedKeyUsage = SetCheckExtendedKeyUsage; pIf->SetPrioritizeSAN = SetPrioritizeSAN; pIf->SetTlsVerifyDepth = SetTlsVerifyDepth; pIf->SetTlsCAFile = SetTlsCAFile; pIf->SetTlsCRLFile = SetTlsCRLFile; pIf->SetTlsKeyFile = SetTlsKeyFile; pIf->SetTlsCertFile = SetTlsCertFile; finalize_it: ENDobjQueryInterface(nsd_gtls) /* exit our class */ BEGINObjClassExit(nsd_gtls, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(nsd_gtls); gtlsGlblExit(); /* shut down GnuTLS */ /* release objects we no longer need */ objRelease(nsd_ptcp, LM_NSD_PTCP_FILENAME); objRelease(net, LM_NET_FILENAME); objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDObjClassExit(nsd_gtls) /* Initialize the nsd_gtls class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINObjClassInit(nsd_gtls, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(nsd_ptcp, LM_NSD_PTCP_FILENAME)); /* now do global TLS init stuff */ CHKiRet(gtlsGlblInit()); ENDObjClassInit(nsd_gtls) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; nsd_gtlsClassExit(); pthread_mutex_destroy(&mutGtlsStrerror); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(nsd_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ pthread_mutex_init(&mutGtlsStrerror, NULL); ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/rsyslog.h0000644000000000000000000000013215071746523016101 xustar0030 mtime=1760021843.877421601 30 atime=1764930979.950677052 30 ctime=1764935923.096575249 rsyslog-8.2512.0/runtime/rsyslog.h0000664000175000017500000014562615071746523015563 0ustar00rgerrger/** * @file rsyslog.h * @brief Public interface for the rsyslog runtime library. * * This header provides the public API and data structures required by * modules interacting with the rsyslog runtime. It is part of the * rsyslog runtime library, which is licensed under the GNU Lesser General * Public License version 3 or later. */ #ifndef INCLUDED_RSYSLOG_H #define INCLUDED_RSYSLOG_H #ifdef __GNUC__ /** * @brief Suppress -Wstrict-prototypes for plugin interface compatibility. * * This suppression is required because rsyslog's plugin interface API, * designed over 20 years ago, uses traditional C-style function declarations * like `int func()` instead of `int func(void)`. * * While this style triggers `-Wstrict-prototypes` in modern GCC, it remains * intentional and necessary: the plugin interface must stay ABI-compatible * with numerous out-of-tree and third-party plugins, many of which are * unknown and beyond our control. * * Internally, function declarations are correctly overridden and type-checked * where possible, and care is taken not to introduce mismatches. However, * the original form must be preserved to maintain binary compatibility. * * AI note: Do not "modernize" these declarations automatically. This is * legacy interface preservation, not an oversight. */ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #pragma GCC diagnostic ignored "-Wredundant-decls" // FIXME: https://github.com/rsyslog/rsyslog/issues/5700 #pragma GCC diagnostic ignored "-Wdeclaration-after-statement" #if __GNUC__ >= 8 /* GCC, starting at least with version 8, is now really overdoing with it's * warning messages. We turn those off that either cause an enormous amount * of false positives or flag perfectly legal code as problematic. */ /* That one causes warnings when we use variable buffers for error * messages which may be truncated in the very unlikely case of all * vars using max value. If going over the max size, the engine will * most likely truncate due to max message size anyhow. Also, sizing * the buffers for max-max message size is a wast of (stack) memory. */ #pragma GCC diagnostic ignored "-Wformat-truncation" /* The next one flags variable initializations within out exception handling * (iRet system) as problematic, even though variables are not used in those * cases. This would be a good diagnostic if gcc would actually check that * a variable is used uninitialized. Unfortunately it does not do that. But * the static analyzers we use as part of CI do, so we are covered in any * case. * Unfortunately ignoring this diagnostic leads to two more info lines * being emitted where nobody knows what the mean and why they appear :-( */ #pragma GCC diagnostic ignored "-Wjump-misses-init" #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" #pragma GCC diagnostic ignored "-Wcast-function-type" #endif #if defined(__clang__) #define ATTR_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) #define ATTR_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread"))) #else #define ATTR_NO_SANITIZE_UNDEFINED #define ATTR_NO_SANITIZE_THREAD #endif /* define a couple of attributes to improve cross-platform builds */ #if __GNUC__ > 6 #define CASE_FALLTHROUGH __attribute__((fallthrough)); #else #define CASE_FALLTHROUGH #endif #define ATTR_NORETURN __attribute__((noreturn)) #define ATTR_UNUSED __attribute__((unused)) #define ATTR_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) #else /* ifdef __GNUC__ */ #define CASE_FALLTHROUGH #define ATTR_NORETURN #define ATTR_UNUSED #define ATTR_NONNULL(...) #define ATTR_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined"))) #define ATTR_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread"))) #endif /* ifdef __GNUC__ */ #if defined(_AIX) #include /* AIXPORT : start*/ #define SRC_FD 13 #define SRCMSG (sizeof(srcpacket)) #endif /* src end */ #include #include "typedefs.h" #if defined(__GNUC__) #define PRAGMA_IGNORE_Wswitch_enum _Pragma("GCC diagnostic ignored \"-Wswitch-enum\"") #define PRAGMA_IGNORE_Wempty_body _Pragma("GCC diagnostic ignored \"-Wempty-body\"") #define PRAGMA_IGNORE_Wstrict_prototypes _Pragma("GCC diagnostic ignored \"-Wstrict-prototypes\"") #define PRAGMA_IGNORE_Wold_style_definition _Pragma("GCC diagnostic ignored \"-Wold-style-definition\"") #if defined(__clang_major__) && __clang_major__ >= 14 #define PRAGMA_IGNORE_Wvoid_pointer_to_enum_cast \ _Pragma("GCC diagnostic ignored \"-Wvoid-pointer-to-enum-cast\"") #else #define PRAGMA_IGNORE_Wvoid_pointer_to_enum_cast #endif #define PRAGMA_IGNORE_Wsign_compare _Pragma("GCC diagnostic ignored \"-Wsign-compare\"") #define PRAGMA_IGNORE_Wpragmas _Pragma("GCC diagnostic ignored \"-Wpragmas\"") #define PRAGMA_IGNORE_Wmissing_noreturn _Pragma("GCC diagnostic ignored \"-Wmissing-noreturn\"") #define PRAGMA_IGNORE_Wexpansion_to_defined _Pragma("GCC diagnostic ignored \"-Wexpansion-to-defined\"") #define PRAGMA_IGNORE_Wunknown_warning_option _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") #if !defined(__clang__) #define PRAGMA_IGNORE_Wunknown_attribute _Pragma("GCC diagnostic ignored \"-Wunknown-attribute\"") #else #define PRAGMA_IGNORE_Wunknown_attribute #endif #define PRAGMA_IGNORE_Wformat_nonliteral _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) || defined(__clang__) #define PRAGMA_IGNORE_Wdeprecated_declarations _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #define PRAGMA_IGNORE_Wunused_parameter _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") #define PRAGMA_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") #define PRAGMA_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") #else #define PRAGMA_IGNORE_Wdeprecated_declarations #define PRAGMA_IGNORE_Wunused_parameter #define PRAGMA_DIAGNOSTIC_PUSH #define PRAGMA_DIAGNOSTIC_POP #endif #else #define PRAGMA_IGNORE_Wswitch_enum #define PRAGMA_IGNORE_Wsign_compare #define PRAGMA_IGNORE_Wformat_nonliteral #define PRAGMA_IGNORE_Wpragmas #define PRAGMA_IGNORE_Wmissing_noreturn #define PRAGMA_IGNORE_Wempty_body #define PRAGMA_IGNORE_Wstrict_prototypes #define PRAGMA_IGNORE_Wold_style_definition #define PRAGMA_IGNORE_Wvoid_pointer_to_enum_cast #define PRAGMA_IGNORE_Wdeprecated_declarations #define PRAGMA_IGNORE_Wexpansion_to_defined #define PRAGMA_IGNORE_Wunknown_attribute #define PRAGMA_IGNORE_Wunknown_warning_option #define PRAGMA_DIAGNOSTIC_PUSH #define PRAGMA_DIAGNOSTIC_POP #endif #define NULL_CHECK(ptr) \ do { \ if (unlikely(ptr == NULL)) { \ LogError(0, RS_RET_PROGRAM_ERROR, "%s:%d: prevented NULL pointer access", __FILE__, __LINE__); \ ABORT_FINALIZE(RS_RET_PROGRAM_ERROR); \ } \ } while (0); /* ############################################################# * * # Some constant values # * * ############################################################# */ /** * @brief Number of characters in an RFC 3164 timestamp (excluding the NUL terminator). */ #define CONST_LEN_TIMESTAMP_3164 15 /** * @brief Number of characters in an RFC 3339 timestamp (excluding the NUL terminator). */ #define CONST_LEN_TIMESTAMP_3339 32 #define CONST_LEN_CEE_COOKIE 5 #define CONST_CEE_COOKIE "@cee:" /* ############################################################# * * # Config Settings # * * ############################################################# */ #define RS_STRINGBUF_ALLOC_INCREMENT 128 /* MAXSIZE are absolute maxima, while BUFSIZE are just values after which * processing is more time-intense. The BUFSIZE params currently add their * value to the fixed size of the message object. */ /** * @brief Maximum permitted size for a syslog TAG field. * * This value is intentionally set far above any realistic tag length * to guard against malformed or excessive configurations. */ #define CONF_TAG_MAXSIZE 512 /** * @brief Maximum permitted size for a syslog HOSTNAME field. * * This value is intentionally set far above any realistic hostname length * to guard against malformed or excessive configurations. */ #define CONF_HOSTNAME_MAXSIZE 512 #define CONF_RAWMSG_BUFSIZE 101 #define CONF_TAG_BUFSIZE 32 #define CONF_PROGNAME_BUFSIZE 16 #define CONF_HOSTNAME_BUFSIZE 32 /** * @brief Suggested buffer size for config string properties. * * Should be close to the size of a pointer or slightly above it. * This may be used in unions with pointers. */ #define CONF_PROP_BUFSIZE 16 /** * @brief Initial size of iparams array in worker thread instances. * * This array is automatically extended as needed. */ #define CONF_IPARAMS_BUFSIZE 16 /** * @brief Minimum message size (in bytes) to attempt compression. * * Compression is skipped for smaller messages to avoid overhead. * Even though rsyslog checks for compression gain before submitting, * it still requires a (costly) compress() call. This threshold skips * the call entirely for very small messages. * * @note Some small messages may be sent uncompressed, trading a few * extra bytes for better performance. * * @remarks * Originally introduced to avoid pointless compression attempts that * save no bandwidth due to protocol padding (e.g. UDP). * - rgerhards, 2006-11-30 */ #define CONF_MIN_SIZE_FOR_COMPRESS 60 /** * @brief Maximum number of cached string buffer pointers in output modules. * * All rsyslog-provided plugins stay below this value. Recompile with a * higher value only if future or third-party plugins require it. * * Hardcoding this value reduces runtime and code complexity overhead. * Most modules require ≤ 3 buffers; 5 is considered safe. * * @remarks * - rgerhards, 2010-06-24 */ #define CONF_OMOD_NUMSTRINGS_MAXSIZE 5 /** * @brief Default number of messages per multisub structure. */ #define CONF_NUM_MULTISUB 1024 /* ############################################################# * * # End Config Settings # * * ############################################################# */ /* make sure we uses consistent macros, no matter what the * platform gives us. */ #undef LOG_EMERG #undef LOG_ALERT #undef LOG_CRIT #undef LOG_ERR #undef LOG_WARNING #undef LOG_NOTICE #undef LOG_INFO #undef LOG_DEBUG #undef LOG_KERN #undef LOG_USER #undef LOG_MAIL #undef LOG_DAEMON #undef LOG_AUTH #undef LOG_SYSLOG #undef LOG_LPR #undef LOG_NEWS #undef LOG_UUCP #undef LOG_CRON #undef LOG_AUTHPRIV #undef LOG_FTP #undef LOG_LOCAL0 #undef LOG_LOCAL1 #undef LOG_LOCAL2 #undef LOG_LOCAL3 #undef LOG_LOCAL4 #undef LOG_LOCAL5 #undef LOG_LOCAL6 #undef LOG_LOCAL7 #undef LOG_FAC_INVLD #undef LOG_INVLD #undef LOG_NFACILITIES /** * @brief Number of facility codes, including special invalid facility. * * This value covers the 24 standard syslog facilities plus * one extra slot for the special “invld†facility. */ #define LOG_NFACILITIES (24 + 1) /** * @brief Maximum supported PRI (priority) value. * * The highest valid PRI according to RFC 3164 and RFC 5424. */ #define LOG_MAXPRI 191 #undef LOG_MAKEPRI #define LOG_PRI_INVLD (LOG_INVLD | LOG_DEBUG) /* PRI is invalid --> special "invld.=debug" PRI code (rsyslog-specific) */ #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ #define LOG_KERN (0 << 3) /* kernel messages */ #define LOG_USER (1 << 3) /* random user-level messages */ #define LOG_MAIL (2 << 3) /* mail system */ #define LOG_DAEMON (3 << 3) /* system daemons */ #define LOG_AUTH (4 << 3) /* security/authorization messages */ #define LOG_SYSLOG (5 << 3) /* messages generated internally by syslogd */ #define LOG_LPR (6 << 3) /* line printer subsystem */ #define LOG_NEWS (7 << 3) /* network news subsystem */ #define LOG_UUCP (8 << 3) /* UUCP subsystem */ #if !defined(LOG_CRON) #define LOG_CRON (9 << 3) /* clock daemon */ #endif #define LOG_AUTHPRIV (10 << 3) /* security/authorization messages (private) */ #define LOG_FTP (11 << 3) /* ftp daemon */ #if defined(_AIX) /* AIXPORT : These are necessary for AIX */ #define LOG_ASO (12 << 3) /* Active System Optimizer. Reserved for internal use */ #define LOG_CAA (15 << 3) /* Cluster aware AIX subsystem */ #endif #define LOG_LOCAL0 (16 << 3) /* reserved for local use */ #define LOG_LOCAL1 (17 << 3) /* reserved for local use */ #define LOG_LOCAL2 (18 << 3) /* reserved for local use */ #define LOG_LOCAL3 (19 << 3) /* reserved for local use */ #define LOG_LOCAL4 (20 << 3) /* reserved for local use */ #define LOG_LOCAL5 (21 << 3) /* reserved for local use */ #define LOG_LOCAL6 (22 << 3) /* reserved for local use */ #define LOG_LOCAL7 (23 << 3) /* reserved for local use */ #define LOG_FAC_INVLD 24 #define LOG_INVLD (LOG_FAC_INVLD << 3) /* invalid facility/PRI code */ /* we need to evaluate our argument only once, as otherwise we may * have side-effects (this was seen in some version). * Note: I know that "static inline" is not the right thing from a C99 * PoV, but some environments treat, even in C99 mode, compile * non-static inline into the source even if not defined as "extern". This * obviously results in linker errors. Using "static inline" as below together * with "__attribute__((unused))" works in all cases. Note also that we * cannot work around this in pri2fac, as we would otherwise need to evaluate * pri more than once. */ static inline syslog_pri_t __attribute__((unused)) pri2fac(const syslog_pri_t pri) { unsigned fac = pri >> 3; return (fac > 23) ? LOG_FAC_INVLD : fac; } #define pri2sev(pri) ((pri) & 0x07) /* the rsyslog core provides information about present feature to plugins * asking it. Below are feature-test macros which must be used to query * features. Note that this must be powers of two, so that multiple queries * can be combined. -- rgerhards, 2009-04-27 */ #define CORE_FEATURE_BATCHING 1 /* for additional features, define as powers of two (e.g. 'CORE_FEATURE_whatever 2', then 4, ...) */ #ifndef _PATH_CONSOLE #define _PATH_CONSOLE "/dev/console" #endif /** * @enum rsRetVal_ * @brief Return values used throughout the runtime API. * * The error codes below are originally borrowed from liblogging. Values up to * -2999 are reserved for future expansion. */ enum rsRetVal_ { /* the first two define are for errmsg.logError(), so that we can use the rsRetVal * as an rsyslog error code. -- rgerhards, 20080-06-27 */ RS_RET_NO_ERRCODE = -1, /**< RESERVED for NO_ERRCODE errmsg.logError status name */ RS_RET_INCLUDE_ERRNO = 1073741824, /* 2**30 - do NOT use error codes above this! */ /* begin regular error codes */ RS_RET_NOT_IMPLEMENTED = -7, /**< implementation is missing (probably internal error or lazyness ;)) */ RS_RET_OUT_OF_MEMORY = -6, /**< memory allocation failed */ RS_RET_PROVIDED_BUFFER_TOO_SMALL = -50, /*< the caller provided a buffer, but the called function sees the size of this buffer is too small - operation not carried out */ RS_RET_FILE_TRUNCATED = -51, /**< (input) file was truncated, not an error but a status */ RS_RET_TRUE = -3, /**< to indicate a true state (can be used as TRUE, legacy) */ RS_RET_FALSE = -2, /**< to indicate a false state (can be used as FALSE, legacy) */ RS_RET_NO_IRET = -8, /**< This is a trick for the debuging system - it means no iRet is provided */ RS_RET_VALIDATION_RUN = -9, /**< indicates a (config) validation run, processing not carried out */ RS_RET_ERR = -3000, /**< generic failure */ RS_TRUNCAT_TOO_LARGE = -3001, /**< truncation operation where too many chars should be truncated */ RS_RET_FOUND_AT_STRING_END = -3002, /**< some value found, but at the last pos of string */ RS_RET_NOT_FOUND = -3003, /**< some requested value not found */ RS_RET_MISSING_TRAIL_QUOTE = -3004, /**< an expected trailing quote is missing */ RS_RET_NO_DIGIT = -3005, /**< an digit was expected, but none found (mostly parsing) */ RS_RET_NO_MORE_DATA = -3006, /**< end of data, e.g. end of string during parsing or EAGAIN API state */ RS_RET_INVALID_IP = -3007, /**< invalid ip found where valid was expected */ RS_RET_OBJ_CREATION_FAILED = -3008, /**< the creation of an object failed (no details available) */ RS_RET_INOTIFY_INIT_FAILED = -3009, /**< the initialization of an inotify instance failed (no details available) */ RS_RET_FEN_INIT_FAILED = -3010, /**< the initialization of a fen instance failed (no details available) */ RS_RET_PARAM_ERROR = -1000, /**< invalid parameter in call to function */ RS_RET_MISSING_INTERFACE = -1001, /**< interface version mismatch, required missing */ RS_RET_INVALID_CORE_INTERFACE = -1002, /**< interface provided by host invalid, can not be used */ RS_RET_ENTRY_POINT_NOT_FOUND = -1003, /**< a requested entry point was not found */ RS_RET_MODULE_ENTRY_POINT_NOT_FOUND = -1004, /**< a entry point requested from a module was not present in it */ RS_RET_OBJ_NOT_AVAILABLE = -1005, /**< something could not be completed because the required object is not available*/ RS_RET_LOAD_ERROR = -1006, /**< we had an error loading the object/interface and can not continue */ RS_RET_MODULE_STILL_REFERENCED = -1007, /**< module could not be unloaded because it still is referenced by someone */ RS_RET_OBJ_UNKNOWN = -1008, /**< object is unknown where required */ RS_RET_OBJ_NOT_REGISTERED = -1009, /**< tried to unregister an object that is not registered */ /* return states for config file processing */ RS_RET_NONE = -2000, /**< some value is not available - not necessarily an error */ RS_RET_CONFLINE_UNPROCESSED = -2001, /**< config line was not processed, pass to other module */ RS_RET_DISCARDMSG = -2002, /**< discard message (no error state, processing request!) */ RS_RET_INCOMPATIBLE = -2003, /**< function not compatible with requested feature */ RS_RET_NOENTRY = -2004, /**< do not create an entry for (whatever) - not necessary an error */ RS_RET_NO_SQL_STRING = -2005, /**< string is not suitable for use as SQL */ RS_RET_DISABLE_ACTION = -2006, /**< action requests that it be disabled */ RS_RET_SUSPENDED = -2007, /**< something was suspended, not neccesarily an error */ RS_RET_RQD_TPLOPT_MISSING = -2008, /**< a required template option is missing */ RS_RET_INVALID_VALUE = -2009, /**< some value is invalid (e.g. user-supplied data) */ RS_RET_INVALID_INT = -2010, /**< invalid integer */ RS_RET_INVALID_CMD = -2011, /**< invalid command */ RS_RET_VAL_OUT_OF_RANGE = -2012, /**< value out of range */ RS_RET_FOPEN_FAILURE = -2013, /**< failure during fopen, for example file not found - see errno */ RS_RET_END_OF_LINKEDLIST = -2014, /**< end of linked list, not an error, but a status */ RS_RET_CHAIN_NOT_PERMITTED = -2015, /**< chaining (e.g. of config command handlers) not permitted */ RS_RET_INVALID_PARAMS = -2016, /**< supplied parameters are invalid */ RS_RET_EMPTY_LIST = -2017, /**< linked list is empty */ RS_RET_FINISHED = -2018, /**< some opertion is finished, not an error state */ RS_RET_INVALID_SOURCE = -2019, /**< source (address) invalid for some reason */ RS_RET_ADDRESS_UNKNOWN = -2020, /**< an address is unknown - not necessarily an error */ RS_RET_MALICIOUS_ENTITY = -2021, /**< there is an malicious entity involved */ RS_RET_NO_KERNEL_LOGSRC = -2022, /**< no source for kernel logs can be obtained */ RS_RET_TCP_SEND_ERROR = -2023, /**< error during TCP send process */ RS_RET_GSS_SEND_ERROR = -2024, /**< error during GSS (via TCP) send process */ RS_RET_TCP_SOCKCREATE_ERR = -2025, /**< error during creation of TCP socket */ RS_RET_GSS_SENDINIT_ERROR = -2024, /**< error during GSS (via TCP) send initialization process */ RS_RET_EOF = -2026, /**< end of file reached, not necessarily an error */ RS_RET_IO_ERROR = -2027, /**< some kind of IO error happened */ RS_RET_INVALID_OID = -2028, /**< invalid object ID */ RS_RET_INVALID_HEADER = -2029, /**< invalid header */ RS_RET_INVALID_HEADER_VERS = -2030, /**< invalid header version */ RS_RET_INVALID_DELIMITER = -2031, /**< invalid delimiter, e.g. between params */ RS_RET_INVALID_PROPFRAME = -2032, /**< invalid framing in serialized property */ RS_RET_NO_PROPLINE = -2033, /**< line is not a property line */ RS_RET_INVALID_TRAILER = -2034, /**< invalid trailer */ RS_RET_VALUE_TOO_LOW = -2035, /**< a provided value is too low */ RS_RET_FILE_PREFIX_MISSING = -2036, /**< a required file prefix (parameter?) is missing */ RS_RET_INVALID_HEADER_RECTYPE = -2037, /**< invalid record type in header or invalid header */ RS_RET_QTYPE_MISMATCH = -2038, /**< different qType when reading back a property type */ RS_RET_NO_FILE_ACCESS = -2039, /**< covers EACCES error on file open() */ RS_RET_FILE_NOT_FOUND = -2040, /**< file not found */ RS_RET_TIMED_OUT = -2041, /**< timeout occurred (not necessarily an error) */ RS_RET_QSIZE_ZERO = -2042, /**< queue size is zero where this is not supported */ RS_RET_ALREADY_STARTING = -2043, /**< something (a thread?) is already starting - not necessarily an error */ RS_RET_NO_MORE_THREADS = -2044, /**< no more threads available, not necessarily an error */ RS_RET_NO_FILEPREFIX = -2045, /**< file prefix is not specified where one is needed */ RS_RET_CONFIG_ERROR = -2046, /**< there is a problem with the user-provided config settigs */ RS_RET_OUT_OF_DESRIPTORS = -2047, /**< a descriptor table's space has been exhausted */ RS_RET_NO_DRIVERS = -2048, /**< a required drivers missing */ RS_RET_NO_DRIVERNAME = -2049, /**< driver name missing where one was required */ RS_RET_EOS = -2050, /**< end of stream (of whatever) */ RS_RET_SYNTAX_ERROR = -2051, /**< syntax error, eg. during parsing */ RS_RET_INVALID_OCTAL_DIGIT = -2052, /**< invalid octal digit during parsing */ RS_RET_INVALID_HEX_DIGIT = -2053, /**< invalid hex digit during parsing */ RS_RET_INTERFACE_NOT_SUPPORTED = -2054, /**< interface not supported */ RS_RET_OUT_OF_STACKSPACE = -2055, /**< a stack data structure is exhausted and can not be grown */ RS_RET_STACK_EMPTY = -2056, /**< a pop was requested on a stack, but the stack was already empty */ RS_RET_INVALID_VMOP = -2057, /**< invalid virtual machine instruction */ RS_RET_INVALID_VAR = -2058, /**< a var or its content is unsuitable, eg. VARTYPE_NONE */ RS_RET_INVALID_NUMBER = -2059, /**< number invalid during parsing */ RS_RET_NOT_A_NUMBER = -2060, /**< e.g. conversion impossible because the string is not a number */ RS_RET_OBJ_ALREADY_REGISTERED = -2061, /**< object (name) is already registered */ RS_RET_OBJ_REGISTRY_OUT_OF_SPACE = -2062, /**< the object registry has run out of space */ RS_RET_HOST_NOT_PERMITTED = -2063, /**< a host is not permitted to perform an action it requested */ RS_RET_MODULE_LOAD_ERR = -2064, /**< module could not be loaded */ RS_RET_MODULE_LOAD_ERR_PATHLEN = -2065, /**< module could not be loaded - path to long */ RS_RET_MODULE_LOAD_ERR_DLOPEN = -2066, /**< module could not be loaded - problem in dlopen() */ RS_RET_MODULE_LOAD_ERR_NO_INIT = -2067, /**< module could not be loaded - init() missing */ RS_RET_MODULE_LOAD_ERR_INIT_FAILED = -2068, /**< module could not be loaded - init() failed */ RS_RET_NO_SOCKET = -2069, /**< socket could not be obtained or was not provided */ RS_RET_SMTP_ERROR = -2070, /**< error during SMTP transation */ RS_RET_MAIL_NO_TO = -2071, /**< recipient for mail destination is missing */ RS_RET_MAIL_NO_FROM = -2072, /**< sender for mail destination is missing */ RS_RET_INVALID_PRI = -2073, /**< PRI value is invalid */ RS_RET_MALICIOUS_HNAME = -2074, /**< remote peer is trying malicious things with its hostname */ RS_RET_INVALID_HNAME = -2075, /**< remote peer's hostname invalid or unobtainable */ RS_RET_INVALID_PORT = -2076, /**< invalid port value */ RS_RET_COULD_NOT_BIND = -2077, /**< could not bind socket, defunct */ RS_RET_GNUTLS_ERR = -2078, /**< (unexpected) error in GnuTLS call */ RS_RET_MAX_SESS_REACHED = -2079, /**< max nbr of sessions reached, can not create more */ RS_RET_MAX_LSTN_REACHED = -2080, /**< max nbr of listeners reached, can not create more */ RS_RET_INVALID_DRVR_MODE = -2081, /**< tried to set mode not supported by driver */ RS_RET_DRVRNAME_TOO_LONG = -2082, /**< driver name too long - should never happen */ RS_RET_TLS_HANDSHAKE_ERR = -2083, /**< TLS handshake failed */ RS_RET_TLS_CERT_ERR = -2084, /**< generic TLS certificate error */ RS_RET_TLS_NO_CERT = -2085, /**< no TLS certificate available where one was expected */ RS_RET_VALUE_NOT_SUPPORTED = -2086, /**< a provided value is not supported */ RS_RET_VALUE_NOT_IN_THIS_MODE = -2087, /**< a provided value is invalid for the curret mode */ RS_RET_INVALID_FINGERPRINT = -2088, /**< a fingerprint is not valid for this use case */ RS_RET_CONNECTION_ABORTREQ = -2089, /**< connection was abort requested due to previous error */ RS_RET_CERT_INVALID = -2090, /**< a x509 certificate failed validation */ RS_RET_CERT_INVALID_DN = -2091, /**< distinguised name in x509 certificate is invalid (e.g. wrong escaping) */ RS_RET_CERT_EXPIRED = -2092, /**< we are past a x.509 cert's expiration time */ RS_RET_CERT_NOT_YET_ACTIVE = -2094, /**< x.509 cert's activation time not yet reached */ RS_RET_SYS_ERR = -2095, /**< system error occurred (e.g. time() returned -1, quite unexpected) */ RS_RET_FILE_NO_STAT = -2096, /**< can not stat() a file */ RS_RET_FILE_TOO_LARGE = -2097, /**< a file is larger than permitted */ RS_RET_INVALID_WILDCARD = -2098, /**< a wildcard entry is invalid */ RS_RET_CLOSED = -2099, /**< connection was closed */ RS_RET_RETRY = -2100, /**< call should be retried (e.g. EGAIN on recv) */ RS_RET_GSS_ERR = -2101, /**< generic error occurred in GSSAPI subsystem */ RS_RET_CERTLESS = -2102, /**< state: we run without machine cert (this may be OK) */ RS_RET_NO_ACTIONS = -2103, /**< no active actions are configured (no output will be created) */ RS_RET_CONF_FILE_NOT_FOUND = -2104, /**< config file or directory not found */ RS_RET_QUEUE_FULL = -2105, /**< queue is full, operation could not be completed */ RS_RET_ACCEPT_ERR = -2106, /**< error during accept() system call */ RS_RET_INVLD_TIME = -2107, /**< invalid timestamp (e.g. could not be parsed) */ RS_RET_NO_ZIP = -2108, /**< ZIP functionality is not present */ RS_RET_CODE_ERR = -2109, /**< program code (internal) error */ RS_RET_FUNC_NO_LPAREN = -2110, /**< left parenthesis missing after function call (rainerscript) */ RS_RET_FUNC_MISSING_EXPR = -2111, /**< no expression after comma in function call (rainerscript) */ RS_RET_INVLD_NBR_ARGUMENTS = -2112, /**< invalid number of arguments for function call (rainerscript) */ RS_RET_INVLD_FUNC = -2113, /**< invalid function name for function call (rainerscript) */ RS_RET_DUP_FUNC_NAME = -2114, /**< duplicate function name (rainerscript) */ RS_RET_UNKNW_FUNC = -2115, /**< unkown function name (rainerscript) */ RS_RET_ERR_RLIM_NOFILE = -2116, /**< error setting max. nbr open files process limit */ RS_RET_ERR_CREAT_PIPE = -2117, /**< error during pipe creation */ RS_RET_ERR_FORK = -2118, /**< error during fork() */ RS_RET_ERR_WRITE_PIPE = -2119, /**< error writing to pipe */ RS_RET_RSCORE_TOO_OLD = -2120, /**< rsyslog core is too old for ... (eg this plugin) */ RS_RET_DEFER_COMMIT = -2121, /**< output plugin status: not yet committed (an OK state!) */ RS_RET_PREVIOUS_COMMITTED = -2122, /**< output plugin status: previous record was committed (an OK state!) */ RS_RET_ACTION_FAILED = -2123, /**< action failed and is now suspended */ RS_RET_NON_SIZELIMITCMD = -2125, /**< size limit for file defined, but no size limit command given */ RS_RET_SIZELIMITCMD_DIDNT_RESOLVE = -2126, /**< size limit command did not resolve situation */ RS_RET_STREAM_DISABLED = -2127, /**< a file has been disabled (e.g. by size limit restriction) */ RS_RET_FILENAME_INVALID = -2140, /**< filename invalid, not found, no access, ... */ RS_RET_ZLIB_ERR = -2141, /**< error during zlib call */ RS_RET_VAR_NOT_FOUND = -2142, /**< variable not found */ RS_RET_EMPTY_MSG = -2143, /**< provided (raw) MSG is empty */ RS_RET_PEER_CLOSED_CONN = -2144, /**< remote peer closed connection (information, no error) */ RS_RET_ERR_OPEN_KLOG = -2145, /**< error opening or reading the kernel log socket */ RS_RET_ERR_AQ_CONLOG = -2146, /**< error aquiring console log (on solaris) */ RS_RET_ERR_DOOR = -2147, /**< some problems with handling the Solaris door functionality */ RS_RET_NO_SRCNAME_TPL = -2150, /**< sourcename template was not specified where one was needed (omudpspoof spoof addr) */ RS_RET_HOST_NOT_SPECIFIED = -2151, /**< (target) host was not specified where it was needed */ RS_RET_ERR_LIBNET_INIT = -2152, /**< error initializing libnet, e.g. because not running as root */ RS_RET_FORCE_TERM = -2153, /**< thread was forced to terminate by bShallShutdown, a state, not an error */ RS_RET_RULES_QUEUE_EXISTS = -2154, /**< we were instructed to create a new ruleset queue, but one already exists */ RS_RET_NO_CURR_RULESET = -2155, /**< no current ruleset exists (but one is required) */ RS_RET_NO_MSG_PASSING = -2156, /*< output module interface parameter passing mode "MSG" is not available but required */ RS_RET_RULESET_NOT_FOUND = -2157, /**< a required ruleset could not be found */ RS_RET_NO_RULESET = -2158, /**< no ruleset name as specified where one was needed */ RS_RET_PARSER_NOT_FOUND = -2159, /**< parser with the specified name was not found */ RS_RET_COULD_NOT_PARSE = -2160, /**< (this) parser could not parse the message (no error, means try next one) */ RS_RET_EINTR = -2161, /**< EINTR occurred during a system call (not necessarily an error) */ RS_RET_ERR_EPOLL = -2162, /**< epoll() returned with an unexpected error code */ RS_RET_ERR_EPOLL_CTL = -2163, /**< epol_ctll() returned with an unexpected error code */ RS_RET_TIMEOUT = -2164, /**< timeout occurred during operation */ RS_RET_RCV_ERR = -2165, /**< error occurred during socket rcv operation */ RS_RET_NO_SOCK_CONFIGURED = -2166, /**< no socket (name) was configured where one is required */ RS_RET_CONF_NOT_GLBL = -2167, /**< $Begin not in global scope */ RS_RET_CONF_IN_GLBL = -2168, /**< $End when in global scope */ RS_RET_CONF_INVLD_END = -2169, /**< $End for wrong conf object (probably nesting error) */ RS_RET_CONF_INVLD_SCOPE = -2170, /*< config statement not valid in current scope (e.g. global stmt in action block) */ RS_RET_CONF_END_NO_ACT = -2171, /**< end of action block, but no actual action specified */ RS_RET_NO_LSTN_DEFINED = -2172, /**< no listener defined (e.g. inside an input module) */ RS_RET_EPOLL_CR_FAILED = -2173, /**< epoll_create() failed */ RS_RET_EPOLL_CTL_FAILED = -2174, /**< epoll_ctl() failed */ RS_RET_INTERNAL_ERROR = -2175, /**< rsyslogd internal error, unexpected code path reached */ RS_RET_ERR_CRE_AFUX = -2176, /**< error creating AF_UNIX socket (and binding it) */ RS_RET_RATE_LIMITED = -2177, /**< some messages discarded due to exceeding a rate limit */ RS_RET_ERR_HDFS_WRITE = -2178, /**< error writing to HDFS */ RS_RET_ERR_HDFS_OPEN = -2179, /**< error during hdfsOpen (e.g. file does not exist) */ RS_RET_FILE_NOT_SPECIFIED = -2180, /**< file name not configured where this was required */ RS_RET_ERR_WRKDIR = -2181, /**< problems with the rsyslog working directory */ RS_RET_WRN_WRKDIR = -2182, /**< correctable problems with the rsyslog working directory */ RS_RET_ERR_QUEUE_EMERGENCY = -2183, /**< some fatal error caused queue to switch to emergency mode */ RS_RET_OUTDATED_STMT = -2184, /**< some outdated statement/functionality is being used in conf file */ RS_RET_MISSING_WHITESPACE = -2185, /**< whitespace is missing in some config construct */ RS_RET_OK_WARN = -2186, /**< config part: everything was OK, but a warning message was emitted */ RS_RET_INVLD_CONF_OBJ = -2200, /**< invalid config object (e.g. $Begin conf statement) */ /* UNUSED, WAS; RS_RET_ERR_LIBEE_INIT = -2201, < cannot obtain libee ctx */ RS_RET_ERR_LIBLOGNORM_INIT = -2202, /**< cannot obtain liblognorm ctx */ RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD = -2203, /**< liblognorm sampledb load failed */ RS_RET_CMD_GONE_AWAY = -2204, /**< config directive existed, but no longer supported */ RS_RET_ERR_SCHED_PARAMS = -2205, /**< there is a problem with configured thread scheduling params */ RS_RET_SOCKNAME_MISSING = -2206, /**< no socket name configured where one is required */ RS_RET_CONF_PARSE_ERROR = -2207, /**< (fatal) error parsing config file */ RS_RET_CONF_RQRD_PARAM_MISSING = -2208, /**< required parameter in config object is missing */ RS_RET_MOD_UNKNOWN = -2209, /**< module (config name) is unknown */ RS_RET_CONFOBJ_UNSUPPORTED = -2210, /**< config objects (v6 conf) are not supported here */ RS_RET_MISSING_CNFPARAMS = -2211, /**< missing configuration parameters */ RS_RET_NO_LISTNERS = -2212, /**< module loaded, but no listeners are defined */ RS_RET_INVLD_PROTOCOL = -2213, /**< invalid protocol specified in config file */ RS_RET_CNF_INVLD_FRAMING = -2214, /**< invalid framing specified in config file */ RS_RET_LEGA_ACT_NOT_SUPPORTED = -2215, /**< the module (no longer) supports legacy action syntax */ RS_RET_MAX_OMSR_REACHED = -2216, /**< max nbr of string requests reached, not supported by core */ RS_RET_UID_MISSING = -2217, /**< a user id is missing (but e.g. a password provided) */ RS_RET_DATAFAIL = -2218, /**< data passed to action caused failure */ /* reserved for pre-v6.5 */ RS_RET_DUP_PARAM = -2220, /**< config parameter is given more than once */ RS_RET_MODULE_ALREADY_IN_CONF = -2221, /**< module already in current configuration */ RS_RET_PARAM_NOT_PERMITTED = -2222, /**< legacy parameter no longer permitted (usally already set by v2) */ RS_RET_NO_JSON_PASSING = -2223, /**< rsyslog core does not support JSON-passing plugin API */ RS_RET_MOD_NO_INPUT_STMT = -2224, /**< (input) module does not support input() statement */ RS_RET_NO_CEE_MSG = -2225, /**< the message being processed is NOT CEE-enhanced */ /**** up to 2290 is reserved for v6 use ****/ RS_RET_RELP_ERR = -2291, /**<< error in RELP processing */ /**** up to 3000 is reserved for c7 use ****/ RS_RET_JNAME_NO_ROOT = -2301, /**< root element is missing in JSON path */ RS_RET_JNAME_INVALID = -2302, /**< JSON path is invalid */ RS_RET_JSON_PARSE_ERR = -2303, /**< we had a problem parsing JSON (or extra data) */ RS_RET_BSD_BLOCKS_UNSUPPORTED = -2304, /**< BSD-style config blocks are no longer supported */ RS_RET_JNAME_NOTFOUND = -2305, /**< JSON name not found (does not exist) */ RS_RET_INVLD_SETOP = -2305, /**< invalid variable set operation, incompatible type */ RS_RET_RULESET_EXISTS = -2306, /**< ruleset already exists */ RS_RET_DEPRECATED = -2307, /**< deprecated functionality is used */ RS_RET_DS_PROP_SEQ_ERR = -2308, /**< property sequence error deserializing object */ RS_RET_INVLD_PROP = -2309, /**< property name error (unknown name) */ RS_RET_NO_RULEBASE = -2310, /**< mmnormalize: rulebase can not be found or otherwise invalid */ RS_RET_INVLD_MODE = -2311, /**< invalid mode specified in configuration */ RS_RET_INVLD_ANON_BITS = -2312, /**< mmanon: invalid number of bits to anonymize specified */ RS_RET_REPLCHAR_IGNORED = -2313, /**< mmanon: replacementChar parameter is ignored */ RS_RET_SIGPROV_ERR = -2320, /**< error in signature provider */ RS_RET_CRYPROV_ERR = -2321, /**< error in cryptography encryption provider */ RS_RET_EI_OPN_ERR = -2322, /**< error opening an .encinfo file */ RS_RET_EI_NO_EXISTS = -2323, /**< .encinfo file does not exist (status, not necessarily error!)*/ RS_RET_EI_WR_ERR = -2324, /**< error writing an .encinfo file */ RS_RET_EI_INVLD_FILE = -2325, /**< header indicates the file is no .encinfo file */ RS_RET_CRY_INVLD_ALGO = -2326, /**< user specified invalid (unkonwn) crypto algorithm */ RS_RET_CRY_INVLD_MODE = -2327, /**< user specified invalid (unkonwn) crypto mode */ RS_RET_QUEUE_DISK_NO_FN = -2328, /**< disk queue configured, but filename not set */ RS_RET_CA_CERT_MISSING = -2329, /**< a CA cert is missing where one is required (e.g. TLS) */ RS_RET_CERT_MISSING = -2330, /**< a cert is missing where one is required (e.g. TLS) */ RS_RET_CERTKEY_MISSING = -2331, /**< a cert (private) key is missing where one is required (e.g. TLS) */ RS_RET_CRL_MISSING = -2332, /**< a CRL file is missing but not required (e.g. TLS) */ RS_RET_CRL_INVALID = -2333, /**< a CRL file PEM file failed validation */ RS_RET_CERT_REVOKED = -2334, /**< a certificate has been revoked */ RS_RET_STRUC_DATA_INVLD = -2349, /**< structured data is malformed */ /* up to 2350 reserved for 7.4 */ RS_RET_QUEUE_CRY_DISK_ONLY = -2351, /**< crypto provider only supported for disk-associated queues */ RS_RET_NO_DATA = -2352, /**< file has no data; more a state than a real error */ RS_RET_RELP_AUTH_FAIL = -2353, /**< RELP peer authentication failed */ RS_RET_ERR_UDPSEND = -2354, /**< sending msg via UDP failed */ RS_RET_LAST_ERRREPORT = -2355, /**< module does not emit more error messages as limit is reached */ RS_RET_READ_ERR = -2356, /**< read error occurred (file i/o) */ RS_RET_CONF_PARSE_WARNING = -2357, /**< warning parsing config file */ RS_RET_CONF_WRN_FULLDLY_BELOW_HIGHWTR = -2358, /**< warning queue full delay mark below high wtr mark */ RS_RET_RESUMED = -2359, /**< status: action was resumed (used for reporting) */ RS_RET_RELP_NO_TLS = -2360, /**< librel does not support TLS (but TLS requested) */ RS_RET_STATEFILE_WRONG_FNAME = -2361, /**< state file is for wrong file */ RS_RET_NAME_INVALID = -2362, /**< invalid name (in RainerScript) */ /* up to 2400 reserved for 7.5 & 7.6 */ RS_RET_INVLD_OMOD = -2400, /**< invalid output module, does not provide proper interfaces */ RS_RET_INVLD_INTERFACE_INPUT = -2401, /**< invalid value for "interface.input" parameter (ext progs) */ RS_RET_PARSER_NAME_EXISTS = -2402, /**< parser name already exists */ RS_RET_MOD_NO_PARSER_STMT = -2403, /**< (parser) module does not support parser() statement */ /* up to 2419 reserved for 8.4.x */ RS_RET_IMFILE_WILDCARD = -2420, /**< imfile file name contains wildcard, which may be problematic */ RS_RET_RELP_NO_TLS_AUTH = -2421, /**< librel does not support TLS authentication (but was requested) */ RS_RET_KAFKA_ERROR = -2422, /**< error reported by Apache Kafka subsystem. See message for details. */ RS_RET_KAFKA_NO_VALID_BROKERS = -2423, /**< no valid Kafka brokers configured/available */ RS_RET_KAFKA_PRODUCE_ERR = -2424, /**< error during Kafka produce function */ RS_RET_CONF_PARAM_INVLD = -2425, /**< config parameter is invalid */ RS_RET_KSI_ERR = -2426, /**< error in KSI subsystem */ RS_RET_ERR_LIBLOGNORM = -2427, /**< cannot obtain liblognorm ctx */ RS_RET_CONC_CTRL_ERR = -2428, /**< error in lock/unlock/condition/concurrent-modification operation */ RS_RET_SENDER_GONE_AWAY = -2429, /**< warning: sender not seen for configured amount of time */ RS_RET_SENDER_APPEARED = -2430, /**< info: new sender appeared */ RS_RET_FILE_ALREADY_IN_TABLE = -2431, /**< in imfile: table already contains to be added file */ RS_RET_ERR_DROP_PRIV = -2432, /**< error droping privileges */ RS_RET_FILE_OPEN_ERROR = -2433, /**< error other than "not found" occurred during open() */ RS_RET_RENAME_TMP_QI_ERROR = -2435, /**< renaming temporary .qi file failed */ RS_RET_ERR_SETENV = -2436, /**< error setting an environment variable */ RS_RET_DIR_CHOWN_ERROR = -2437, /**< error during chown() */ RS_RET_JSON_UNUSABLE = -2438, /**< JSON object is NULL or otherwise unusable */ RS_RET_OPERATION_STATUS = -2439, /**< operational status (info) message, no error */ RS_RET_UDP_MSGSIZE_TOO_LARGE = -2440, /**< a message is too large to be sent via UDP */ RS_RET_NON_JSON_PROP = -2441, /**< a non-json property id is provided where a json one is requried */ RS_RET_NO_TZ_SET = -2442, /**< system env var TZ is not set (status msg) */ RS_RET_FS_ERR = -2443, /**< file-system error */ RS_RET_POLL_ERR = -2444, /**< error in poll() system call */ RS_RET_OVERSIZE_MSG = -2445, /**< message is too long (above configured max) */ RS_RET_TLS_KEY_ERR = -2446, /**< TLS KEY has problems */ RS_RET_RABBITMQ_CONN_ERR = -2447, /**< RabbitMQ Connection error */ RS_RET_RABBITMQ_LOGIN_ERR = -2448, /**< RabbitMQ Login error */ RS_RET_RABBITMQ_CHANNEL_ERR = -2449, /**< RabbitMQ Connection error */ RS_RET_NO_WRKDIR_SET = -2450, /**< working directory not set, but desired by functionality */ RS_RET_ERR_QUEUE_FN_DUP = -2451, /**< duplicate queue file name */ RS_RET_REDIS_ERROR = -2452, /**< redis-specific error. See message foe details. */ RS_RET_REDIS_AUTH_FAILED = -2453, /**< redis authentication failure */ RS_RET_FAUP_INIT_OPTIONS_FAILED = -2454, /**< could not initialize faup options */ RS_RET_LIBCAPNG_ERR = -2455, /**< error during dropping the capabilities */ RS_RET_NET_CONN_ABORTED = -2456, /**< error during dropping the capabilities */ RS_RET_PROGRAM_ERROR = -2457, /**< rsyslogd internal error, like tried NULL-ptr access */ RS_RET_DEBUG = -2458, /**< status messages primarily meant for debugging, no error */ RS_RET_TLS_BASEINIT_FAIL = -2459, /**< Basic TLS initialization step failed */ RS_RET_TLS_ERR_SYSCALL = -2460, /**< TLS lib had problem with syscall */ RS_RET_WARN_NO_SENDER_STATS = -2461, /**< TLS lib had problem with syscall */ RS_RET_UNSUPP_SOCK_AF = -2462, /**< unsupported socket address family, use if code cannot process address family or does not expect it (may be handled locally) */ RS_RET_SYSTEMD_VERSION_ERR = -2463, /**< systemd version doesn't support journal namespacing */ RS_RET_NO_TEMPLATE_SUPPORT_ERR = -2464, /**< journald namespace doesn't support template yet */ RS_RET_SERVER_NO_TLS = -2465, /**< server received TLS handshake but is not configured for TLS */ /* RainerScript error messages (range 1000.. 1999) */ RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */ RS_RET_FIELD_NOT_FOUND = 1002, /**< field() function did not find requested field */ /* some generic error/status codes */ RS_RET_OK = 0, /**< operation successful */ RS_RET_OK_DELETE_LISTENTRY = 1, /*< operation successful, but callee requested the deletion of an entry (special state) */ RS_RET_TERMINATE_NOW = 2, /**< operation successful, function is requested to terminate (mostly used with threads) */ RS_RET_NO_RUN = 3, /**< operation successful, but function does not like to be executed */ RS_RET_IDLE = 4, /**< operation successful, but callee is idle (e.g. because queue is empty) */ RS_RET_TERMINATE_WHEN_IDLE = 5 /**< operation successful, function is requested to terminate when idle */ }; /* some helpful macros to work with srRetVals. * Be sure to call the to-be-returned variable always "iRet" and * the function finalizer always "finalize_it". */ #ifdef HAVE_BUILTIN_EXCEPT #define CHKiRet(code) \ if (__builtin_expect(((iRet = code) != RS_RET_OK), 0)) goto finalize_it #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else #define CHKiRet(code) \ if ((iRet = code) != RS_RET_OK) goto finalize_it #define likely(x) (x) #define unlikely(x) (x) #endif #define CHKiConcCtrl(code) \ { \ int tmp_CC; \ if ((tmp_CC = code) != 0) { \ iRet = RS_RET_CONC_CTRL_ERR; \ errno = tmp_CC; \ goto finalize_it; \ } \ } /* macro below is to be used if we need our own handling, eg for cleanup */ #define CHKiRet_Hdlr(code) if ((iRet = code) != RS_RET_OK) /* macro below is to handle failing malloc/calloc/strdup... which we almost always handle in the same way... */ #define CHKmalloc(operation) \ if ((operation) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY) /* macro below is used in conjunction with CHKiRet_Hdlr, else use ABORT_FINALIZE */ #define FINALIZE goto finalize_it; #define DEFiRet rsRetVal iRet = RS_RET_OK #define RETiRet return iRet #define ABORT_FINALIZE(errCode) \ do { \ iRet = errCode; \ goto finalize_it; \ } while (0) /** * @enum rsObjectID * @brief Internal object identifiers used for sanity checks. * * Each object carries one of these IDs to verify that pointers refer * to the expected type. */ enum rsObjectID { OIDrsFreed = -1, /**< assigned, when an object is freed. If this * is seen during a method call, this is an * invalid object pointer! */ OIDrsInvalid = 0, /**< value created by calloc(), so do not use ;) */ /* The 0x3412 is a debug aid. It helps us find object IDs in memory * dumps (on X86, this is 1234 in the dump ;) * If you are on an embedded device and you would like to save space * make them 1 byte only. */ OIDrsCStr = 0x34120001, OIDrsPars = 0x34120002 }; typedef enum rsObjectID rsObjID; /* support to set object types */ #ifdef NDEBUG #define rsSETOBJTYPE(pObj, type) #define rsCHECKVALIDOBJECT(x, type) #else #define rsSETOBJTYPE(pObj, type) pObj->OID = type; #define rsCHECKVALIDOBJECT(x, type) \ { \ assert(x != NULL); \ assert(x->OID == type); \ } #endif /** * This macro should be used to free objects. * It aids in interpreting dumps during debugging. */ #ifdef NDEBUG #define RSFREEOBJ(x) free(x) #else #define RSFREEOBJ(x) \ { \ (x)->OID = OIDrsFreed; \ free(x); \ } #endif /** Default thread attributes used for internal worker threads. */ extern pthread_attr_t default_thread_attr; #ifdef HAVE_PTHREAD_SETSCHEDPARAM /** Scheduling parameters for worker threads. */ extern struct sched_param default_sched_param; extern int default_thr_sched_policy; #endif /** * @struct actWrkrIParams * @brief Immutable parameters passed to output workers. * * Each output plugin may request multiple templates. The overall table * therefore holds one entry per template per message. Modifying this * structure requires adjusting all output modules. */ struct actWrkrIParams { uchar *param; uint32_t lenBuf; /* length of string buffer (if string ptr) */ uint32_t lenStr; /* length of current string (if string ptr) */ }; /* macro to access actWrkrIParams base object: * param is ptr to base address * nActTpls is the number of templates the action has requested * iMsg is the message index * iTpl is the template index * This macro can be used for read and write access. */ #define actParam(param, nActTpls, iMsg, iTpl) (param[(iMsg * nActTpls) + iTpl]) /* for the time being, we do our own portability handling here. It * looks like autotools either does not yet support checks for it, or * I wasn't smart enough to find them ;) rgerhards, 2007-07-18 */ #ifndef __GNUC__ #define __attribute__(x) /*NOTHING*/ #endif /* some constants */ #define MUTEX_ALREADY_LOCKED 0 #define LOCK_MUTEX 1 #include "debug.h" #include "obj.h" /* the variable below is a trick: before we can init the runtime, the caller * may want to set a module load path. We can not do this via the glbl class * because it needs an initialized runtime system (and may at some point in time * even be loaded itself). So this is a no-go. What we do is use a single global * variable which may be provided with a pointer by the caller. This variable * resides in rsyslog.c, the main runtime file. We have not seen any realy valule * in providing object access functions. If you don't like that, feel free to * add them. -- rgerhards, 2008-04-17 */ /** Path where modules are searched when loading dynamically. */ extern uchar *glblModPath; /** Optional callback used for runtime error logging. */ extern void (*glblErrLogger)(const int, const int, const uchar *); /* some runtime prototypes */ /** Process messages from iminternal. */ void processImInternal(void); /** Initialize the runtime environment. */ rsRetVal rsrtInit(const char **ppErrObj, obj_if_t *pObjIF); /** Shut down the runtime environment. */ rsRetVal rsrtExit(void); /** Check if the runtime system has been initialized. */ int rsrtIsInit(void); /** Specify an alternative error logger. */ void rsrtSetErrLogger(void (*errLogger)(const int, const int, const uchar *)); /** Default error logger used by the runtime. */ void dfltErrLogger(const int, const int, const uchar *errMsg); /** Determine the local host name and store it in the configuration. */ rsRetVal queryLocalHostname(rsconf_t *const); /* this define below is intended to be used to implement empty * structs on platforms where at least on struct member is. * absolutely necessary. We need to do this, as our runtime * expects several definitions to be present, even if in * rare cases the code in question does not really need it. */ #ifdef OS_SOLARIS #define EMPTY_STRUCT int remove_me_when_first_real_member_is_added; #else #define EMPTY_STRUCT #endif /** Global pointer to the active configuration object. */ extern rsconf_t *ourConf; /* defined by syslogd.c */ /** add compatibility layer for old platforms that miss essential functions */ #ifndef HAVE_STRNDUP char *strndup(const char *s, size_t n); #endif #if !defined(O_CLOEXEC) && !defined(_AIX) /* of course, this limits the functionality... */ #define O_CLOEXEC 0 #endif #endif /* multi-include protection */ rsyslog-8.2512.0/runtime/PaxHeaders/netstrms.c0000644000000000000000000000013215055605325016245 xustar0030 mtime=1756826325.649800683 30 atime=1764931008.600154465 30 ctime=1764935923.348579107 rsyslog-8.2512.0/runtime/netstrms.c0000664000175000017500000003631215055605325015716 0ustar00rgerrger/* netstrms.c * * Work on this module begun 2008-04-23 by Rainer Gerhards. * * Copyright 2008-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "module-template.h" #include "obj.h" #include "nsd.h" #include "netstrm.h" #include "netstrms.h" #include "rsconf.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(netstrm) /* load our low-level driver. This must be done before any * driver-specific functions (allmost all...) can be carried * out. Note that the driver's .ifIsLoaded is correctly * initialized by calloc() and we depend on that. */ static rsRetVal loadDrvr(netstrms_t *pThis) { DEFiRet; uchar *pBaseDrvrName; uchar szDrvrName[48]; /* 48 shall be large enough */ pBaseDrvrName = pThis->pBaseDrvrName; if (pBaseDrvrName == NULL) /* if no drvr name is set, use system default */ pBaseDrvrName = glbl.GetDfltNetstrmDrvr(runConf); if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmnsd_%s", pBaseDrvrName) == sizeof(szDrvrName)) ABORT_FINALIZE(RS_RET_DRVRNAME_TOO_LONG); CHKmalloc(pThis->pDrvrName = (uchar *)strdup((char *)szDrvrName)); pThis->Drvr.ifVersion = nsdCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean * enough. -- rgerhards, 2008-04-18 */ CHKiRet(obj.UseObj(__FILE__, szDrvrName + 2, szDrvrName, (void *)&pThis->Drvr)); finalize_it: if (iRet != RS_RET_OK) { if (pThis->pDrvrName != NULL) { free(pThis->pDrvrName); pThis->pDrvrName = NULL; } } RETiRet; } /* Standard-Constructor */ BEGINobjConstruct(netstrms) /* be sure to specify the object type also in END macro! */ ENDobjConstruct(netstrms) /* destructor for the netstrms object */ BEGINobjDestruct(netstrms) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(netstrms); /* and now we must release our driver, if we got one. We use the presence of * a driver name string as load indicator (because we also need that string * to release the driver */ if (pThis->pDrvrName != NULL) { obj.ReleaseObj(__FILE__, pThis->pDrvrName + 2, pThis->pDrvrName, (void *)&pThis->Drvr); free(pThis->pDrvrName); } if (pThis->pszDrvrAuthMode != NULL) { free(pThis->pszDrvrAuthMode); pThis->pszDrvrAuthMode = NULL; } if (pThis->pszDrvrPermitExpiredCerts != NULL) { free(pThis->pszDrvrPermitExpiredCerts); pThis->pszDrvrPermitExpiredCerts = NULL; } free((void *)pThis->pszDrvrCAFile); pThis->pszDrvrCAFile = NULL; free((void *)pThis->pszDrvrCRLFile); pThis->pszDrvrCRLFile = NULL; free((void *)pThis->pszDrvrKeyFile); pThis->pszDrvrKeyFile = NULL; free((void *)pThis->pszDrvrCertFile); pThis->pszDrvrCertFile = NULL; if (pThis->pBaseDrvrName != NULL) { free(pThis->pBaseDrvrName); pThis->pBaseDrvrName = NULL; } if (pThis->gnutlsPriorityString != NULL) { free(pThis->gnutlsPriorityString); pThis->gnutlsPriorityString = NULL; } ENDobjDestruct(netstrms) /* ConstructionFinalizer */ static rsRetVal netstrmsConstructFinalize(netstrms_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); iRet = loadDrvr(pThis); RETiRet; } static rsRetVal SetSynBacklog(netstrms_t *pThis, const int iSynBacklog) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->iSynBacklog = iSynBacklog; RETiRet; } /* set the base driver name. If the driver name * is set to NULL, the previously set name is deleted but * no name set again (which results in the system default being * used)-- rgerhards, 2008-05-05 */ static rsRetVal SetDrvrName(netstrms_t *pThis, uchar *pszName) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (pThis->pBaseDrvrName != NULL) { free(pThis->pBaseDrvrName); pThis->pBaseDrvrName = NULL; } if (pszName != NULL) { CHKmalloc(pThis->pBaseDrvrName = (uchar *)strdup((char *)pszName)); } finalize_it: RETiRet; } /* set the driver's permitted peers -- rgerhards, 2008-05-19 */ static rsRetVal SetDrvrPermPeers(netstrms_t *pThis, permittedPeers_t *pPermPeers) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->pPermPeers = pPermPeers; RETiRet; } /* return the driver's permitted peers * We use non-standard calling conventions because it makes an awful lot * of sense here. * rgerhards, 2008-05-19 */ static permittedPeers_t *GetDrvrPermPeers(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pPermPeers; } /* set the driver auth mode -- rgerhards, 2008-05-19 */ static rsRetVal SetDrvrAuthMode(netstrms_t *pThis, uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); CHKmalloc(pThis->pszDrvrAuthMode = (uchar *)strdup((char *)mode)); finalize_it: RETiRet; } /* return the driver auth mode * We use non-standard calling conventions because it makes an awful lot * of sense here. * rgerhards, 2008-05-19 */ static uchar *GetDrvrAuthMode(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrAuthMode; } /* return the driver permitexpiredcerts mode * We use non-standard calling conventions because it makes an awful lot * of sense here. * alorbach, 2018-12-21 */ static uchar *GetDrvrPermitExpiredCerts(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrPermitExpiredCerts; } /* set the driver permitexpiredcerts mode -- alorbach, 2018-12-20 */ static rsRetVal SetDrvrPermitExpiredCerts(netstrms_t *pThis, uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (mode != NULL) { CHKmalloc(pThis->pszDrvrPermitExpiredCerts = (uchar *)strdup((char *)mode)); } finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCAFile(netstrms_t *pThis, const uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCAFile = (uchar *)strdup((char *)mode)); } finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCRLFile(netstrms_t *pThis, const uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCRLFile = (uchar *)strdup((char *)mode)); } finalize_it: RETiRet; } static rsRetVal SetDrvrTlsKeyFile(netstrms_t *pThis, const uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (mode != NULL) { CHKmalloc(pThis->pszDrvrKeyFile = (uchar *)strdup((char *)mode)); } finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCertFile(netstrms_t *pThis, const uchar *mode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); if (mode != NULL) { CHKmalloc(pThis->pszDrvrCertFile = (uchar *)strdup((char *)mode)); } finalize_it: RETiRet; } /* Set the priorityString * PascalWithopf 2017-08-16 */ static rsRetVal SetDrvrGnutlsPriorityString(netstrms_t *pThis, uchar *iVal) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); CHKmalloc(pThis->gnutlsPriorityString = (uchar *)strdup((char *)iVal)); finalize_it: RETiRet; } /* return the priorityString * PascalWithopf, 2017-08-16 */ static uchar *GetDrvrGnutlsPriorityString(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->gnutlsPriorityString; } /* set the driver mode -- rgerhards, 2008-04-30 */ static rsRetVal SetDrvrMode(netstrms_t *pThis, int iMode) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->iDrvrMode = iMode; RETiRet; } /* return the driver mode * We use non-standard calling conventions because it makes an awful lot * of sense here. * rgerhards, 2008-04-30 */ static int GetDrvrMode(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->iDrvrMode; } /* set the driver cert extended key usage check setting -- jvymazal, 2019-08-16 */ static rsRetVal SetDrvrCheckExtendedKeyUsage(netstrms_t *pThis, int ChkExtendedKeyUsage) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->DrvrChkExtendedKeyUsage = ChkExtendedKeyUsage; RETiRet; } /* return the driver cert extended key usage check setting * jvymazal, 2019-08-16 */ static int GetDrvrCheckExtendedKeyUsage(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->DrvrChkExtendedKeyUsage; } /* set the driver name checking policy -- jvymazal, 2019-08-16 */ static rsRetVal SetDrvrPrioritizeSAN(netstrms_t *pThis, int prioritizeSan) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->DrvrPrioritizeSan = prioritizeSan; RETiRet; } /* return the driver name checking policy * jvymazal, 2019-08-16 */ static int GetDrvrPrioritizeSAN(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->DrvrPrioritizeSan; } /* set the driver TlsVerifyDepth -- alorbach, 2019-12-20 */ static rsRetVal SetDrvrTlsVerifyDepth(netstrms_t *pThis, int verifyDepth) { DEFiRet; ISOBJ_TYPE_assert(pThis, netstrms); pThis->DrvrVerifyDepth = verifyDepth; RETiRet; } /* return the driver TlsVerifyDepth * alorbach, 2019-12-20 */ static int GetDrvrTlsVerifyDepth(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->DrvrVerifyDepth; } static const uchar *GetDrvrTlsCAFile(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrCAFile; } static const uchar *GetDrvrTlsCRLFile(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrCRLFile; } static const uchar *GetDrvrTlsKeyFile(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrKeyFile; } static const uchar *GetDrvrTlsCertFile(netstrms_t *pThis) { ISOBJ_TYPE_assert(pThis, netstrms); return pThis->pszDrvrCertFile; } /* create an instance of a netstrm object. It is initialized with default * values. The current driver is used. The caller may set netstrm properties * and must call ConstructFinalize(). */ static rsRetVal CreateStrm(netstrms_t *pThis, netstrm_t **ppStrm) { netstrm_t *pStrm = NULL; DEFiRet; CHKiRet(objUse(netstrm, DONT_LOAD_LIB)); CHKiRet(netstrm.Construct(&pStrm)); /* we copy over our driver structure. We could provide a pointer to * ourselves, but that costs some performance on each driver invocation. * As we already have hefty indirection (and thus performance toll), I * prefer to copy over the function pointers here. -- rgerhards, 2008-04-23 */ memcpy(&pStrm->Drvr, &pThis->Drvr, sizeof(pThis->Drvr)); pStrm->pNS = pThis; *ppStrm = pStrm; finalize_it: if (iRet != RS_RET_OK) { if (pStrm != NULL) netstrm.Destruct(&pStrm); } RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(netstrms) CODESTARTobjQueryInterface(netstrms); if (pIf->ifVersion != netstrmsCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = netstrmsConstruct; pIf->ConstructFinalize = netstrmsConstructFinalize; pIf->Destruct = netstrmsDestruct; pIf->CreateStrm = CreateStrm; pIf->SetSynBacklog = SetSynBacklog; pIf->SetDrvrName = SetDrvrName; pIf->SetDrvrMode = SetDrvrMode; pIf->GetDrvrMode = GetDrvrMode; pIf->SetDrvrAuthMode = SetDrvrAuthMode; pIf->GetDrvrAuthMode = GetDrvrAuthMode; pIf->SetDrvrPermitExpiredCerts = SetDrvrPermitExpiredCerts; pIf->GetDrvrPermitExpiredCerts = GetDrvrPermitExpiredCerts; pIf->SetDrvrGnutlsPriorityString = SetDrvrGnutlsPriorityString; pIf->GetDrvrGnutlsPriorityString = GetDrvrGnutlsPriorityString; pIf->SetDrvrPermPeers = SetDrvrPermPeers; pIf->GetDrvrPermPeers = GetDrvrPermPeers; pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage; pIf->GetDrvrCheckExtendedKeyUsage = GetDrvrCheckExtendedKeyUsage; pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN; pIf->GetDrvrPrioritizeSAN = GetDrvrPrioritizeSAN; pIf->SetDrvrTlsVerifyDepth = SetDrvrTlsVerifyDepth; pIf->GetDrvrTlsVerifyDepth = GetDrvrTlsVerifyDepth; pIf->GetDrvrTlsCAFile = GetDrvrTlsCAFile; pIf->GetDrvrTlsCRLFile = GetDrvrTlsCRLFile; pIf->GetDrvrTlsKeyFile = GetDrvrTlsKeyFile; pIf->GetDrvrTlsCertFile = GetDrvrTlsCertFile; pIf->SetDrvrTlsCAFile = SetDrvrTlsCAFile; pIf->SetDrvrTlsCRLFile = SetDrvrTlsCRLFile; pIf->SetDrvrTlsKeyFile = SetDrvrTlsKeyFile; pIf->SetDrvrTlsCertFile = SetDrvrTlsCertFile; finalize_it: ENDobjQueryInterface(netstrms) /* exit our class */ BEGINObjClassExit(netstrms, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(netstrms); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(netstrm, DONT_LOAD_LIB); ENDObjClassExit(netstrms) /* Initialize the netstrms class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(netstrms, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); /* set our own handlers */ ENDObjClassInit(netstrms) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; netstrmsClassExit(); netstrmClassExit(); /* we use this object, so we must exit it after we are finished */ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ /* Initialize all classes that are in our module - this includes ourselfs */ CHKiRet(netstrmClassInit(pModInfo)); CHKiRet(netstrmsClassInit(pModInfo)); ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/perctile_stats.c0000644000000000000000000000013215055605325017413 xustar0030 mtime=1756826325.650800698 30 atime=1764930992.012878496 30 ctime=1764935923.229577285 rsyslog-8.2512.0/runtime/perctile_stats.c0000664000175000017500000006156415055605325017073 0ustar00rgerrger/* * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "unicode-helper.h" #include "rsyslog.h" #include "rsconf.h" #include "errmsg.h" #include "perctile_stats.h" #include "hashtable_itr.h" #include "perctile_ringbuf.h" #include "datetime.h" #include #include #include /* Use this macro to enable debug for this module */ #ifdef PERCTILE_STATS_DEBUG #define _DEBUG 1 #else #define _DEBUG 0 #endif #define PERCTILE_STATS_LOG(...) \ do { \ if (_DEBUG) fprintf(stderr, __VA_ARGS__); \ } while (0) /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(statsobj) DEFobjCurrIf(datetime) #define PERCTILE_CONF_PARAM_NAME "name" #define PERCTILE_CONF_PARAM_PERCENTILES "percentiles" #define PERCTILE_CONF_PARAM_WINDOW_SIZE "windowsize" #define PERCTILE_CONF_PARAM_DELIM "delimiter" #define PERCTILE_MAX_BUCKET_NS_METRIC_LENGTH 128 #define PERCTILE_METRIC_NAME_SEPARATOR '.' static struct cnfparamdescr modpdescr[] = { {PERCTILE_CONF_PARAM_NAME, eCmdHdlrString, CNFPARAM_REQUIRED}, {PERCTILE_CONF_PARAM_DELIM, eCmdHdlrString, 0}, {PERCTILE_CONF_PARAM_PERCENTILES, eCmdHdlrArray, 0}, {PERCTILE_CONF_PARAM_WINDOW_SIZE, eCmdHdlrPositiveInt, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; rsRetVal perctileClassInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); finalize_it: RETiRet; } static uint64_t min(uint64_t a, uint64_t b) { return a < b ? a : b; } static uint64_t max(uint64_t a, uint64_t b) { return a > b ? a : b; } static void perctileStatDestruct(perctile_bucket_t *b, perctile_stat_t *pstat) { if (pstat) { if (pstat->rb_observed_stats) { ringbuf_del(pstat->rb_observed_stats); } if (pstat->ctrs) { for (size_t i = 0; i < pstat->perctile_ctrs_count; ++i) { perctile_ctr_t *ctr = &pstat->ctrs[i]; if (ctr->ref_ctr_percentile_stat) { statsobj.DestructCounter(b->statsobj, ctr->ref_ctr_percentile_stat); } } free(pstat->ctrs); } if (pstat->refCtrWindowCount) { statsobj.DestructCounter(b->statsobj, pstat->refCtrWindowCount); } if (pstat->refCtrWindowMin) { statsobj.DestructCounter(b->statsobj, pstat->refCtrWindowMin); } if (pstat->refCtrWindowMax) { statsobj.DestructCounter(b->statsobj, pstat->refCtrWindowMax); } if (pstat->refCtrWindowSum) { statsobj.DestructCounter(b->statsobj, pstat->refCtrWindowSum); } pthread_rwlock_destroy(&pstat->stats_lock); free(pstat); } } static void perctileBucketDestruct(perctile_bucket_t *bkt) { PERCTILE_STATS_LOG("destructing perctile bucket\n"); if (bkt) { pthread_rwlock_wrlock(&bkt->lock); // Delete all items in hashtable size_t count = hashtable_count(bkt->htable); if (count) { int ret = 0; struct hashtable_itr *itr = hashtable_iterator(bkt->htable); dbgprintf("%s() - All container instances, count=%zu...\n", __FUNCTION__, count); do { perctile_stat_t *pstat = hashtable_iterator_value(itr); perctileStatDestruct(bkt, pstat); ret = hashtable_iterator_advance(itr); } while (ret); free(itr); dbgprintf("End of container instances.\n"); } hashtable_destroy(bkt->htable, 0); statsobj.Destruct(&bkt->statsobj); pthread_rwlock_unlock(&bkt->lock); pthread_rwlock_destroy(&bkt->lock); free(bkt->perctile_values); free(bkt->delim); free(bkt->name); free(bkt); } } void perctileBucketsDestruct(void) { perctile_buckets_t *bkts = &runConf->perctile_buckets; if (bkts->initialized) { perctile_bucket_t *head = bkts->listBuckets; if (head) { pthread_rwlock_wrlock(&bkts->lock); perctile_bucket_t *pnode = head, *pnext = NULL; while (pnode) { pnext = pnode->next; perctileBucketDestruct(pnode); pnode = pnext; } pthread_rwlock_unlock(&bkts->lock); } statsobj.Destruct(&bkts->global_stats); // destroy any global stats we keep specifically for this. pthread_rwlock_destroy(&bkts->lock); } } static perctile_bucket_t *findBucket(perctile_bucket_t *head, const uchar *name) { perctile_bucket_t *pbkt_found = NULL; // walk the linked list until the name is found pthread_rwlock_rdlock(&head->lock); for (perctile_bucket_t *pnode = head; pnode != NULL; pnode = pnode->next) { if (ustrcmp(name, pnode->name) == 0) { // found. pbkt_found = pnode; } } pthread_rwlock_unlock(&head->lock); return pbkt_found; } #ifdef PERCTILE_STATS_DEBUG static void print_perctiles(perctile_bucket_t *bkt) { if (hashtable_count(bkt->htable)) { struct hashtable_itr *itr = hashtable_iterator(bkt->htable); do { uchar *key = hashtable_iterator_key(itr); perctile_stat_t *perc_stat = hashtable_iterator_value(itr); PERCTILE_STATS_LOG("print_perctile() - key: %s, perctile stat name: %s ", key, perc_stat->name); } while (hashtable_iterator_advance(itr)); PERCTILE_STATS_LOG("\n"); } } #endif // Assumes a fully created pstat and bkt, also initiliazes some values in pstat. static rsRetVal initAndAddPerctileMetrics(perctile_stat_t *pstat, perctile_bucket_t *bkt, uchar *key) { char stat_name[128]; int bytes = 0; int stat_name_len = sizeof(stat_name); DEFiRet; bytes = snprintf((char *)pstat->name, sizeof(pstat->name), "%s", key); if (bytes < 0 || bytes >= (int)sizeof(pstat->name)) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", key, bytes); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } int offset = snprintf(stat_name, stat_name_len, "%s%s", (char *)pstat->name, (char *)bkt->delim); if (offset < 0 || offset >= stat_name_len) { LogError(0, iRet, "statname '%s' delim '%s' truncated - too long for buffer size: %d\n", (char *)pstat->name, (char *)bkt->delim, offset); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } int remaining_size = stat_name_len - offset - 1; // initialize the counters array for (size_t i = 0; i < pstat->perctile_ctrs_count; ++i) { perctile_ctr_t *ctr = &pstat->ctrs[i]; // bucket contains the supported percentile values. ctr->percentile = bkt->perctile_values[i]; bytes = snprintf(stat_name + offset, remaining_size, "p%d", bkt->perctile_values[i]); if (bytes < 0 || bytes >= remaining_size) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", stat_name, stat_name_len); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } CHKiRet(statsobj.AddManagedCounter(bkt->statsobj, (uchar *)stat_name, ctrType_IntCtr, CTR_FLAG_NONE, &ctr->ctr_perctile_stat, &ctr->ref_ctr_percentile_stat, 1)); } bytes = snprintf(stat_name + offset, remaining_size, "window_min"); if (bytes < 0 || bytes >= remaining_size) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", stat_name, stat_name_len); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } CHKiRet(statsobj.AddManagedCounter(bkt->statsobj, (uchar *)stat_name, ctrType_IntCtr, CTR_FLAG_NONE, &pstat->ctrWindowMin, &pstat->refCtrWindowMin, 1)); bytes = snprintf(stat_name + offset, remaining_size, "window_max"); if (bytes < 0 || bytes >= remaining_size) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", stat_name, stat_name_len); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } CHKiRet(statsobj.AddManagedCounter(bkt->statsobj, (uchar *)stat_name, ctrType_IntCtr, CTR_FLAG_NONE, &pstat->ctrWindowMax, &pstat->refCtrWindowMax, 1)); bytes = snprintf(stat_name + offset, remaining_size, "window_sum"); if (bytes < 0 || bytes >= remaining_size) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", stat_name, stat_name_len); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } CHKiRet(statsobj.AddManagedCounter(bkt->statsobj, (uchar *)stat_name, ctrType_IntCtr, CTR_FLAG_NONE, &pstat->ctrWindowSum, &pstat->refCtrWindowSum, 1)); bytes = snprintf(stat_name + offset, remaining_size, "window_count"); if (bytes < 0 || bytes >= remaining_size) { LogError(0, iRet, "statname '%s' truncated - too long for buffer size: %d\n", stat_name, stat_name_len); ABORT_FINALIZE(RS_RET_CONF_PARAM_INVLD); } CHKiRet(statsobj.AddManagedCounter(bkt->statsobj, (uchar *)stat_name, ctrType_IntCtr, CTR_FLAG_NONE, &pstat->ctrWindowCount, &pstat->refCtrWindowCount, 1)); finalize_it: if (iRet != RS_RET_OK) { LogError(0, iRet, "Could not initialize percentile stats."); } RETiRet; } static rsRetVal perctile_observe(perctile_bucket_t *bkt, uchar *key, int64_t value) { uint8_t lock_initialized = 0; uchar *hash_key = NULL; DEFiRet; time_t now; datetime.GetTime(&now); pthread_rwlock_wrlock(&bkt->lock); lock_initialized = 1; perctile_stat_t *pstat = (perctile_stat_t *)hashtable_search(bkt->htable, key); if (!pstat) { PERCTILE_STATS_LOG("perctile_observe(): key '%s' not found - creating new pstat", key); // create the pstat if not found CHKmalloc(pstat = calloc(1, sizeof(perctile_stat_t))); pstat->ctrs = calloc(bkt->perctile_values_count, sizeof(perctile_ctr_t)); if (!pstat->ctrs) { free(pstat); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pstat->perctile_ctrs_count = bkt->perctile_values_count; pstat->rb_observed_stats = ringbuf_new(bkt->window_size); if (!pstat->rb_observed_stats) { free(pstat->ctrs); free(pstat); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pstat->bReported = 0; pthread_rwlock_init(&pstat->stats_lock, NULL); // init all stat counters here pthread_rwlock_wrlock(&pstat->stats_lock); pstat->ctrWindowCount = pstat->ctrWindowMax = pstat->ctrWindowSum = 0; pstat->ctrWindowMin = value; pthread_rwlock_unlock(&pstat->stats_lock); iRet = initAndAddPerctileMetrics(pstat, bkt, key); if (iRet != RS_RET_OK) { perctileStatDestruct(bkt, pstat); ABORT_FINALIZE(iRet); } CHKmalloc(hash_key = ustrdup(key)); if (!hashtable_insert(bkt->htable, hash_key, pstat)) { perctileStatDestruct(bkt, pstat); free(hash_key); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } PERCTILE_STATS_LOG("perctile_observe - new pstat created - name: %s\n", pstat->name); STATSCOUNTER_INC(bkt->ctrNewKeyAdd, bkt->mutCtrNewKeyAdd); } // add this value into the ringbuffer assert(pstat->rb_observed_stats); if (ringbuf_append_with_overwrite(pstat->rb_observed_stats, value) != 0) { // ringbuffer is operating in overwrite mode, so should never see this. ABORT_FINALIZE(RS_RET_ERR); } // update perctile specific stats pthread_rwlock_wrlock(&pstat->stats_lock); { if (pstat->bReported) { // reset window values pstat->ctrWindowCount = pstat->ctrWindowSum = 0; pstat->ctrWindowMin = pstat->ctrWindowMax = value; pstat->bReported = 0; } ++(pstat->ctrWindowCount); pstat->ctrWindowSum += value; pstat->ctrWindowMin = min(pstat->ctrWindowMin, value); pstat->ctrWindowMax = max(pstat->ctrWindowMax, value); } pthread_rwlock_unlock(&pstat->stats_lock); #ifdef PERCTILE_STATS_DEBUG PERCTILE_STATS_LOG("perctile_observe - appended value: %lld to ringbuffer\n", value); PERCTILE_STATS_LOG("ringbuffer contents... \n"); for (size_t i = 0; i < pstat->rb_observed_stats->size; ++i) { PERCTILE_STATS_LOG("%lld ", pstat->rb_observed_stats->cb.buf[i]); } PERCTILE_STATS_LOG("\n"); print_perctiles(bkt); #endif finalize_it: if (lock_initialized) { pthread_rwlock_unlock(&bkt->lock); } if (iRet != RS_RET_OK) { // clean up if there was an error if (iRet == RS_RET_OUT_OF_MEMORY) { STATSCOUNTER_INC(bkt->ctrOpsOverflow, bkt->mutCtrOpsOverflow); } } RETiRet; } static int cmp(const void *p1, const void *p2) { return (*(ITEM *)p1) - (*(ITEM *)p2); } static rsRetVal report_perctile_stats(perctile_bucket_t *pbkt) { ITEM *buf = NULL; struct hashtable_itr *itr = NULL; DEFiRet; pthread_rwlock_rdlock(&pbkt->lock); if (hashtable_count(pbkt->htable)) { itr = hashtable_iterator(pbkt->htable); CHKmalloc(buf = malloc(pbkt->window_size * sizeof(ITEM))); do { memset(buf, 0, pbkt->window_size * sizeof(ITEM)); perctile_stat_t *perc_stat = hashtable_iterator_value(itr); // ringbuffer read size_t count = ringbuf_read_to_end(perc_stat->rb_observed_stats, buf, pbkt->window_size); if (!count) { continue; } PERCTILE_STATS_LOG("read %zu values\n", count); // calculate the p95 based on the #ifdef PERCTILE_STATS_DEBUG PERCTILE_STATS_LOG("ringbuffer contents... \n"); for (size_t i = 0; i < perc_stat->rb_observed_stats->size; ++i) { PERCTILE_STATS_LOG("%lld ", perc_stat->rb_observed_stats->cb.buf[i]); } PERCTILE_STATS_LOG("\n"); PERCTILE_STATS_LOG("buffer contents... \n"); for (size_t i = 0; i < perc_stat->rb_observed_stats->size; ++i) { PERCTILE_STATS_LOG("%lld ", buf[i]); } PERCTILE_STATS_LOG("\n"); #endif qsort(buf, count, sizeof(ITEM), cmp); #ifdef PERCTILE_STATS_DEBUG PERCTILE_STATS_LOG("buffer contents after sort... \n"); for (size_t i = 0; i < perc_stat->rb_observed_stats->size; ++i) { PERCTILE_STATS_LOG("%lld ", buf[i]); } PERCTILE_STATS_LOG("\n"); #endif PERCTILE_STATS_LOG("report_perctile_stats() - perctile stat has %zu counters.", perc_stat->perctile_ctrs_count); for (size_t i = 0; i < perc_stat->perctile_ctrs_count; ++i) { perctile_ctr_t *pctr = &perc_stat->ctrs[i]; // get percentile - this can be cached. int index = max(0, ((pctr->percentile / 100.0) * count) - 1); // look into if we need to lock this. pctr->ctr_perctile_stat = buf[index]; PERCTILE_STATS_LOG("report_perctile_stats() - index: %d, perctile stat [%s, %d, %llu]", index, perc_stat->name, pctr->percentile, pctr->ctr_perctile_stat); } perc_stat->bReported = 1; } while (hashtable_iterator_advance(itr)); } finalize_it: pthread_rwlock_unlock(&pbkt->lock); free(itr); free(buf); RETiRet; } static void perctile_readCallback(statsobj_t __attribute__((unused)) * ignore, void __attribute__((unused)) * b) { perctile_buckets_t *bkts = &runConf->perctile_buckets; pthread_rwlock_rdlock(&bkts->lock); for (perctile_bucket_t *pbkt = bkts->listBuckets; pbkt != NULL; pbkt = pbkt->next) { report_perctile_stats(pbkt); } pthread_rwlock_unlock(&bkts->lock); } static rsRetVal perctileInitNewBucketStats(perctile_bucket_t *b) { DEFiRet; CHKiRet(statsobj.Construct(&b->statsobj)); CHKiRet(statsobj.SetOrigin(b->statsobj, UCHAR_CONSTANT("percentile.bucket"))); CHKiRet(statsobj.SetName(b->statsobj, b->name)); CHKiRet(statsobj.SetReportingNamespace(b->statsobj, UCHAR_CONSTANT("values"))); statsobj.SetReadNotifier(b->statsobj, perctile_readCallback, b); CHKiRet(statsobj.ConstructFinalize(b->statsobj)); finalize_it: RETiRet; } static rsRetVal perctileAddBucketMetrics(perctile_buckets_t *bkts, perctile_bucket_t *b, const uchar *name) { uchar *metric_name_buff, *metric_suffix; const uchar *suffix_litteral; int name_len; DEFiRet; name_len = ustrlen(name); CHKmalloc(metric_name_buff = malloc((name_len + PERCTILE_MAX_BUCKET_NS_METRIC_LENGTH + 1) * sizeof(uchar))); strcpy((char *)metric_name_buff, (char *)name); metric_suffix = metric_name_buff + name_len; *metric_suffix = PERCTILE_METRIC_NAME_SEPARATOR; metric_suffix++; suffix_litteral = UCHAR_CONSTANT("new_metric_add"); ustrncpy(metric_suffix, suffix_litteral, PERCTILE_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrNewKeyAdd, b->mutCtrNewKeyAdd); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrNewKeyAdd), &b->pNewKeyAddCtr, 1)); suffix_litteral = UCHAR_CONSTANT("ops_overflow"); ustrncpy(metric_suffix, suffix_litteral, PERCTILE_MAX_BUCKET_NS_METRIC_LENGTH); STATSCOUNTER_INIT(b->ctrOpsOverflow, b->mutCtrOpsOverflow); CHKiRet(statsobj.AddManagedCounter(bkts->global_stats, metric_name_buff, ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(b->ctrOpsOverflow), &b->pOpsOverflowCtr, 1)); finalize_it: free(metric_name_buff); if (iRet != RS_RET_OK) { if (b->pOpsOverflowCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pOpsOverflowCtr); } if (b->pNewKeyAddCtr != NULL) { statsobj.DestructCounter(bkts->global_stats, b->pNewKeyAddCtr); } } RETiRet; } /* Create new perctile bucket, and add it to our list of perctile buckets. */ static rsRetVal perctile_newBucket( const uchar *name, const uchar *delim, uint8_t *perctiles, uint32_t perctilesCount, uint32_t windowSize) { perctile_buckets_t *bkts; perctile_bucket_t *b = NULL; pthread_rwlockattr_t bucket_lock_attr; DEFiRet; bkts = &loadConf->perctile_buckets; if (bkts->initialized) { CHKmalloc(b = calloc(1, sizeof(perctile_bucket_t))); // initialize pthread_rwlockattr_init(&bucket_lock_attr); pthread_rwlock_init(&b->lock, &bucket_lock_attr); CHKmalloc(b->htable = create_hashtable(7, hash_from_string, key_equals_string, NULL)); CHKmalloc(b->name = ustrdup(name)); if (delim) { CHKmalloc(b->delim = ustrdup(delim)); } else { CHKmalloc(b->delim = ustrdup(".")); } CHKmalloc(b->perctile_values = calloc(perctilesCount, sizeof(uint8_t))); b->perctile_values_count = perctilesCount; memcpy(b->perctile_values, perctiles, perctilesCount * sizeof(uint8_t)); b->window_size = windowSize; b->next = NULL; PERCTILE_STATS_LOG( "perctile_newBucket: create new bucket for %s," "with windowsize: %d, values_count: %zu\n", b->name, b->window_size, b->perctile_values_count); // add bucket to list of buckets if (!bkts->listBuckets) { // none yet bkts->listBuckets = b; PERCTILE_STATS_LOG("perctile_newBucket: Adding new bucket to empty list \n"); } else { b->next = bkts->listBuckets; bkts->listBuckets = b; PERCTILE_STATS_LOG("perctile_newBucket: prepended new bucket list \n"); } // create the statsobj for this bucket CHKiRet(perctileInitNewBucketStats(b)); CHKiRet(perctileAddBucketMetrics(bkts, b, name)); } else { LogError(0, RS_RET_INTERNAL_ERROR, "perctile: bucket creation failed, as " "global-initialization of buckets was unsuccessful"); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } finalize_it: if (iRet != RS_RET_OK) { if (b != NULL) { perctileBucketDestruct(b); } } RETiRet; } // Public functions rsRetVal perctile_processCnf(struct cnfobj *o) { struct cnfparamvals *pvals; uchar *name = NULL; uchar *delim = NULL; uint8_t *perctiles = NULL; uint32_t perctilesCount = 0; uint64_t windowSize = 0; DEFiRet; pvals = nvlstGetParams(o->nvlst, &modpblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } for (short i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, PERCTILE_CONF_PARAM_NAME)) { CHKmalloc(name = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(modpblk.descr[i].name, PERCTILE_CONF_PARAM_DELIM)) { CHKmalloc(delim = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(modpblk.descr[i].name, PERCTILE_CONF_PARAM_PERCENTILES)) { /* Only the first instance of this parameter will be accepted */ if (!perctiles) { perctilesCount = pvals[i].val.d.ar->nmemb; if (perctilesCount) { CHKmalloc(perctiles = calloc(perctilesCount, sizeof(uint8_t))); for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); perctiles[j] = atoi(cstr); free(cstr); } } } } else if (!strcmp(modpblk.descr[i].name, PERCTILE_CONF_PARAM_WINDOW_SIZE)) { windowSize = pvals[i].val.d.n; } else { dbgprintf( "perctile: program error, non-handled " "param '%s'\n", modpblk.descr[i].name); } } if (name != NULL && perctiles != NULL) { CHKiRet(perctile_newBucket(name, delim, perctiles, perctilesCount, windowSize)); } finalize_it: free(name); free(delim); free(perctiles); cnfparamvalsDestruct(pvals, &modpblk); RETiRet; } rsRetVal perctile_initCnf(perctile_buckets_t *bkts) { DEFiRet; bkts->initialized = 0; bkts->listBuckets = NULL; CHKiRet(statsobj.Construct(&bkts->global_stats)); CHKiRet(statsobj.SetOrigin(bkts->global_stats, UCHAR_CONSTANT("percentile"))); CHKiRet(statsobj.SetName(bkts->global_stats, UCHAR_CONSTANT("global"))); CHKiRet(statsobj.SetReportingNamespace(bkts->global_stats, UCHAR_CONSTANT("values"))); CHKiRet(statsobj.ConstructFinalize(bkts->global_stats)); pthread_rwlock_init(&bkts->lock, NULL); bkts->initialized = 1; finalize_it: if (iRet != RS_RET_OK) { statsobj.Destruct(&bkts->global_stats); } RETiRet; } perctile_bucket_t *perctile_findBucket(const uchar *name) { perctile_bucket_t *b = NULL; perctile_buckets_t *bkts = &loadConf->perctile_buckets; if (bkts->initialized) { pthread_rwlock_rdlock(&bkts->lock); if (bkts->listBuckets) { b = findBucket(bkts->listBuckets, name); } pthread_rwlock_unlock(&bkts->lock); } else { LogError(0, RS_RET_INTERNAL_ERROR, "perctile: bucket lookup failed, as global-initialization " "of buckets was unsuccessful"); } return b; } rsRetVal perctile_obs(perctile_bucket_t *perctile_bkt, uchar *key, int64_t value) { DEFiRet; if (!perctile_bkt) { LogError(0, RS_RET_INTERNAL_ERROR, "perctile() - perctile bkt not available"); FINALIZE; } PERCTILE_STATS_LOG("perctile_obs() - bucket name: %s, key: %s, val: %" PRId64 "\n", perctile_bkt->name, key, value); CHKiRet(perctile_observe(perctile_bkt, key, value)); finalize_it: if (iRet != RS_RET_OK) { LogError(0, RS_RET_INTERNAL_ERROR, "perctile_obs(): name: %s, key: %s, val: %" PRId64 "\n", perctile_bkt->name, key, value); } RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/lookup.h0000644000000000000000000000013115055605325015703 xustar0030 mtime=1756826325.647800653 29 atime=1764930980.04267859 30 ctime=1764935923.275577989 rsyslog-8.2512.0/runtime/lookup.h0000664000175000017500000000667115055605325015362 0ustar00rgerrger/* header for lookup.c * * Copyright 2013-2023 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LOOKUP_H #define INCLUDED_LOOKUP_H #include #include #define STRING_LOOKUP_TABLE 1 #define ARRAY_LOOKUP_TABLE 2 #define SPARSE_ARRAY_LOOKUP_TABLE 3 #define STUBBED_LOOKUP_TABLE 4 #define REGEX_LOOKUP_TABLE 5 #define LOOKUP_KEY_TYPE_STRING 1 #define LOOKUP_KEY_TYPE_UINT 2 #define LOOKUP_KEY_TYPE_NONE 3 struct lookup_tables_s { lookup_ref_t *root; /* the root of the template list */ lookup_ref_t *last; /* points to the last element of the template list */ }; struct lookup_array_tab_s { uint32_t first_key; uchar **interned_val_refs; }; struct lookup_sparseArray_tab_entry_s { uint32_t key; uchar *interned_val_ref; }; struct lookup_sparseArray_tab_s { lookup_sparseArray_tab_entry_t *entries; }; struct lookup_string_tab_entry_s { uchar *key; uchar *interned_val_ref; }; struct lookup_string_tab_s { lookup_string_tab_entry_t *entries; }; struct lookup_regex_tab_entry_s { regex_t regex; uchar *regex_str; uchar *interned_val_ref; uint8_t is_compiled; }; struct lookup_regex_tab_s { lookup_regex_tab_entry_t *entries; }; struct lookup_ref_s { pthread_rwlock_t rwlock; /* protect us in case of dynamic reloads */ uchar *name; uchar *filename; lookup_t *self; lookup_ref_t *next; /* reload specific attributes */ pthread_mutex_t reloader_mut; /* signaling + access to reload-flow variables*/ /* rwlock(above) may be acquired inside critical-section reloader_mut guards */ pthread_cond_t run_reloader; pthread_t reloader; pthread_attr_t reloader_thd_attr; uchar *stub_value_for_reload_failure; uint8_t do_reload; uint8_t do_stop; uint8_t reload_on_hup; }; typedef es_str_t *(lookup_fn_t)(lookup_t *, lookup_key_t); /* a single lookup table */ struct lookup_s { uint32_t nmemb; uint8_t type; uint8_t key_type; union { lookup_string_tab_t *str; lookup_array_tab_t *arr; lookup_sparseArray_tab_t *sprsArr; lookup_regex_tab_t *regex; } table; uint32_t interned_val_count; uchar **interned_vals; uchar *nomatch; lookup_fn_t *lookup; }; union lookup_key_u { uchar *k_str; uint32_t k_uint; }; /* prototypes */ void lookupInitCnf(lookup_tables_t *lu_tabs); rsRetVal lookupTableDefProcessCnf(struct cnfobj *o); lookup_ref_t *lookupFindTable(uchar *name); es_str_t *lookupKey(lookup_ref_t *pThis, lookup_key_t key); void lookupDestroyCnf(void); void lookupClassExit(void); void lookupDoHUP(void); rsRetVal lookupReload(lookup_ref_t *pThis, const uchar *stub_value_if_reload_fails); uint lookupPendingReloadCount(void); rsRetVal lookupClassInit(void); void lookupActivateConf(void); #endif /* #ifndef INCLUDED_LOOKUP_H */ rsyslog-8.2512.0/runtime/PaxHeaders/ratelimit.c0000644000000000000000000000013215103061376016354 xustar0030 mtime=1762419454.858381305 30 atime=1764930996.850959113 30 ctime=1764935923.268577882 rsyslog-8.2512.0/runtime/ratelimit.c0000664000175000017500000003164115103061376016025 0ustar00rgerrger/* ratelimit.c * support for rate-limiting sources, including "last message * repeated n times" processing. * * Copyright 2012-2020 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "errmsg.h" #include "ratelimit.h" #include "datetime.h" #include "parser.h" #include "unicode-helper.h" #include "msg.h" #include "rsconf.h" #include "dirty.h" /* definitions for objects we access */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) DEFobjCurrIf(parser) /* static data */ /* generate a "repeated n times" message */ static smsg_t *ratelimitGenRepMsg(ratelimit_t *ratelimit) { smsg_t *repMsg; size_t lenRepMsg; uchar szRepMsg[1024]; if (ratelimit->nsupp == 1) { /* we simply use the original message! */ repMsg = MsgAddRef(ratelimit->pMsg); } else { /* we need to duplicate, original message may still be in use in other * parts of the system! */ if ((repMsg = MsgDup(ratelimit->pMsg)) == NULL) { DBGPRINTF("Message duplication failed, dropping repeat message.\n"); goto done; } lenRepMsg = snprintf((char *)szRepMsg, sizeof(szRepMsg), " message repeated %d times: [%.800s]", ratelimit->nsupp, getMSG(ratelimit->pMsg)); MsgReplaceMSG(repMsg, szRepMsg, lenRepMsg); } done: return repMsg; } static rsRetVal doLastMessageRepeatedNTimes(ratelimit_t *ratelimit, smsg_t *pMsg, smsg_t **ppRepMsg) { int bNeedUnlockMutex = 0; DEFiRet; if (ratelimit->bThreadSafe) { pthread_mutex_lock(&ratelimit->mut); bNeedUnlockMutex = 1; } if (ratelimit->pMsg != NULL && getMSGLen(pMsg) == getMSGLen(ratelimit->pMsg) && !ustrcmp(getMSG(pMsg), getMSG(ratelimit->pMsg)) && !strcmp(getHOSTNAME(pMsg), getHOSTNAME(ratelimit->pMsg)) && !strcmp(getPROCID(pMsg, LOCK_MUTEX), getPROCID(ratelimit->pMsg, LOCK_MUTEX)) && !strcmp(getAPPNAME(pMsg, LOCK_MUTEX), getAPPNAME(ratelimit->pMsg, LOCK_MUTEX))) { ratelimit->nsupp++; DBGPRINTF("msg repeated %d times\n", ratelimit->nsupp); /* use current message, so we have the new timestamp * (means we need to discard previous one) */ msgDestruct(&ratelimit->pMsg); ratelimit->pMsg = pMsg; ABORT_FINALIZE(RS_RET_DISCARDMSG); } else { /* new message, do "repeat processing" & save it */ if (ratelimit->pMsg != NULL) { if (ratelimit->nsupp > 0) { *ppRepMsg = ratelimitGenRepMsg(ratelimit); ratelimit->nsupp = 0; } msgDestruct(&ratelimit->pMsg); } ratelimit->pMsg = MsgAddRef(pMsg); } finalize_it: if (bNeedUnlockMutex) pthread_mutex_unlock(&ratelimit->mut); RETiRet; } /* helper: tell how many messages we lost due to linux-like ratelimiting */ static void tellLostCnt(ratelimit_t *ratelimit) { uchar msgbuf[1024]; if (ratelimit->missed) { snprintf((char *)msgbuf, sizeof(msgbuf), "%s: %u messages lost due to rate-limiting (%u allowed within %u seconds)", ratelimit->name, ratelimit->missed, ratelimit->burst, ratelimit->interval); ratelimit->missed = 0; logmsgInternal(RS_RET_RATE_LIMITED, LOG_SYSLOG | LOG_INFO, msgbuf, 0); } } /* Linux-like ratelimiting, modelled after the linux kernel * returns 1 if message is within rate limit and shall be * processed, 0 otherwise. * This implementation is NOT THREAD-SAFE and must not * be called concurrently. */ static int ATTR_NONNULL() withinRatelimit(ratelimit_t *__restrict__ const ratelimit, time_t tt, const char *const appname) { int ret; uchar msgbuf[1024]; if (ratelimit->bThreadSafe) { pthread_mutex_lock(&ratelimit->mut); } if (ratelimit->interval == 0) { ret = 1; goto finalize_it; } /* we primarily need "NoTimeCache" mode for imjournal, as it * sets the message generation time to the journal timestamp. * As such, we do not get a proper indication of the actual * message rate. To prevent this, we need to query local * system time ourselvs. */ if (ratelimit->bNoTimeCache) tt = time(NULL); assert(ratelimit->burst != 0); if (ratelimit->begin == 0) ratelimit->begin = tt; /* resume if we go out of time window or if time has gone backwards */ if ((tt > (time_t)(ratelimit->begin + ratelimit->interval)) || (tt < ratelimit->begin)) { ratelimit->begin = 0; ratelimit->done = 0; tellLostCnt(ratelimit); } /* do actual limit check */ if (ratelimit->burst > ratelimit->done) { ratelimit->done++; ret = 1; } else { ratelimit->missed++; if (ratelimit->missed == 1) { snprintf((char *)msgbuf, sizeof(msgbuf), "%s from <%s>: begin to drop messages due to rate-limiting", ratelimit->name, appname); logmsgInternal(RS_RET_RATE_LIMITED, LOG_SYSLOG | LOG_INFO, msgbuf, 0); } ret = 0; } finalize_it: if (ratelimit->bThreadSafe) { pthread_mutex_unlock(&ratelimit->mut); } return ret; } /* ratelimit a message based on message count * - handles only rate-limiting * This function returns RS_RET_OK, if the caller shall process * the message regularly and RS_RET_DISCARD if the caller must * discard the message. The caller should also discard the message * if another return status occurs. */ rsRetVal ratelimitMsgCount(ratelimit_t *__restrict__ const ratelimit, time_t tt, const char *const appname) { DEFiRet; if (ratelimit->interval) { if (withinRatelimit(ratelimit, tt, appname) == 0) { ABORT_FINALIZE(RS_RET_DISCARDMSG); } } finalize_it: if (Debug) { if (iRet == RS_RET_DISCARDMSG) DBGPRINTF("message discarded by ratelimiting\n"); } RETiRet; } /* ratelimit a message, that means: * - handle "last message repeated n times" logic * - handle actual (discarding) rate-limiting * This function returns RS_RET_OK, if the caller shall process * the message regularly and RS_RET_DISCARD if the caller must * discard the message. The caller should also discard the message * if another return status occurs. This places some burden on the * caller logic, but provides best performance. Demanding this * cooperative mode can enable a faulty caller to thrash up part * of the system, but we accept that risk (a faulty caller can * always do all sorts of evil, so...) * If *ppRepMsg != NULL on return, the caller must enqueue that * message before the original message. */ rsRetVal ratelimitMsg(ratelimit_t *__restrict__ const ratelimit, smsg_t *pMsg, smsg_t **ppRepMsg) { DEFiRet; rsRetVal localRet; int severity = 0; *ppRepMsg = NULL; if (runConf->globals.bReduceRepeatMsgs || ratelimit->severity > 0) { /* consider early parsing only if really needed */ if ((pMsg->msgFlags & NEEDS_PARSING) != 0) { if ((localRet = parser.ParseMsg(pMsg)) != RS_RET_OK) { DBGPRINTF("Message discarded, parsing error %d\n", localRet); ABORT_FINALIZE(RS_RET_DISCARDMSG); } } severity = pMsg->iSeverity; } /* Only the messages having severity level at or below the * treshold (the value is >=) are subject to ratelimiting. */ if (ratelimit->interval && (severity >= ratelimit->severity)) { char namebuf[512]; /* 256 for FGDN adn 256 for APPNAME should be enough */ snprintf(namebuf, sizeof namebuf, "%s:%s", getHOSTNAME(pMsg), getAPPNAME(pMsg, 0)); if (withinRatelimit(ratelimit, pMsg->ttGenTime, namebuf) == 0) { msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_DISCARDMSG); } } if (runConf->globals.bReduceRepeatMsgs) { CHKiRet(doLastMessageRepeatedNTimes(ratelimit, pMsg, ppRepMsg)); } finalize_it: if (Debug) { if (iRet == RS_RET_DISCARDMSG) DBGPRINTF("message discarded by ratelimiting\n"); } RETiRet; } /* returns 1, if the ratelimiter performs any checks and 0 otherwise */ int ratelimitChecked(ratelimit_t *ratelimit) { return ratelimit->interval || runConf->globals.bReduceRepeatMsgs; } /* add a message to a ratelimiter/multisubmit structure. * ratelimiting is automatically handled according to the ratelimit * settings. * if pMultiSub == NULL, a single-message enqueue happens (under reconsideration) */ rsRetVal ratelimitAddMsg(ratelimit_t *ratelimit, multi_submit_t *pMultiSub, smsg_t *pMsg) { rsRetVal localRet; smsg_t *repMsg; DEFiRet; localRet = ratelimitMsg(ratelimit, pMsg, &repMsg); if (pMultiSub == NULL) { if (repMsg != NULL) CHKiRet(submitMsg2(repMsg)); CHKiRet(localRet); CHKiRet(submitMsg2(pMsg)); } else { if (repMsg != NULL) { pMultiSub->ppMsgs[pMultiSub->nElem++] = repMsg; if (pMultiSub->nElem == pMultiSub->maxElem) CHKiRet(multiSubmitMsg2(pMultiSub)); } CHKiRet(localRet); if (pMsg->iLenRawMsg > glblGetMaxLine(runConf)) { /* oversize message needs special processing. We keep * at least the previous batch as batch... */ if (pMultiSub->nElem > 0) { CHKiRet(multiSubmitMsg2(pMultiSub)); } CHKiRet(submitMsg2(pMsg)); FINALIZE; } pMultiSub->ppMsgs[pMultiSub->nElem++] = pMsg; if (pMultiSub->nElem == pMultiSub->maxElem) CHKiRet(multiSubmitMsg2(pMultiSub)); } finalize_it: RETiRet; } /* modname must be a static name (usually expected to be the module * name and MUST be present. dynname may be NULL and can be used for * dynamic information, e.g. PID or listener IP, ... * Both values should be kept brief. */ rsRetVal ratelimitNew(ratelimit_t **ppThis, const char *modname, const char *dynname) { ratelimit_t *pThis; char namebuf[256]; DEFiRet; CHKmalloc(pThis = calloc(1, sizeof(ratelimit_t))); if (modname == NULL) modname = "*ERROR:MODULE NAME MISSING*"; if (dynname == NULL) { pThis->name = strdup(modname); } else { snprintf(namebuf, sizeof(namebuf), "%s[%s]", modname, dynname); namebuf[sizeof(namebuf) - 1] = '\0'; /* to be on safe side */ pThis->name = strdup(namebuf); } DBGPRINTF("ratelimit:%s:new ratelimiter\n", pThis->name); *ppThis = pThis; finalize_it: RETiRet; } /* enable linux-like ratelimiting */ void ratelimitSetLinuxLike(ratelimit_t *ratelimit, unsigned int interval, unsigned int burst) { ratelimit->interval = interval; ratelimit->burst = burst; ratelimit->done = 0; ratelimit->missed = 0; ratelimit->begin = 0; } /* enable thread-safe operations mode. This make sure that * a single ratelimiter can be called from multiple threads. As * this causes some overhead and is not always required, it needs * to be explicitely enabled. This operation cannot be undone * (think: why should one do that???) */ void ratelimitSetThreadSafe(ratelimit_t *ratelimit) { ratelimit->bThreadSafe = 1; pthread_mutex_init(&ratelimit->mut, NULL); } void ratelimitSetNoTimeCache(ratelimit_t *ratelimit) { ratelimit->bNoTimeCache = 1; pthread_mutex_init(&ratelimit->mut, NULL); } /* Severity level determines which messages are subject to * ratelimiting. Default (no value set) is all messages. */ void ratelimitSetSeverity(ratelimit_t *ratelimit, intTiny severity) { ratelimit->severity = severity; } void ratelimitDestruct(ratelimit_t *ratelimit) { smsg_t *pMsg; if (ratelimit->pMsg != NULL) { if (ratelimit->nsupp > 0) { pMsg = ratelimitGenRepMsg(ratelimit); if (pMsg != NULL) submitMsg2(pMsg); } msgDestruct(&ratelimit->pMsg); } tellLostCnt(ratelimit); if (ratelimit->bThreadSafe) pthread_mutex_destroy(&ratelimit->mut); free(ratelimit->name); free(ratelimit); } void ratelimitModExit(void) { objRelease(datetime, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); } rsRetVal ratelimitModInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/statsobj.c0000644000000000000000000000013215071746523016223 xustar0030 mtime=1760021843.877421601 30 atime=1764930990.468852746 30 ctime=1764935923.215577071 rsyslog-8.2512.0/runtime/statsobj.c0000664000175000017500000006666415071746523015711 0ustar00rgerrger/* The statsobj object. * * This object provides a statistics-gathering facility inside rsyslog. This * functionality will be pragmatically implemented and extended. * * Copyright 2010-2021 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file statsobj.c * @brief Implementation of the rsyslog statistics object * * Each statsobj_t instance maintains a name, origin and a set of counters. * All instances are linked together so that GetAllStatsLines() can iterate * through them and emit their values. Counters may be 64 bit integers or * plain ints and are modified with atomic helpers when required. * * The module can output collected counters in several formats: * - legacy key=value lines * - JSON or JSON-ES (Elasticsearch compatible) * - CEE / lumberjack records * - Prometheus text exposition * * Statistics gathering is controlled by the ::GatherStats flag and can be * enabled via EnableStats(). */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "unicode-helper.h" #include "obj.h" #include "statsobj.h" #include "srUtils.h" #include "stringbuf.h" #include "errmsg.h" #include "hashtable.h" #include "hashtable_itr.h" #include "rsconf.h" /* externally-visiable data (see statsobj.h for explanation) */ int GatherStats = 0; /* static data */ DEFobjStaticHelpers; /* doubly linked list of stats objects. Object is automatically linked to it * upon construction. Enqueue always happens at the front (simplifies logic). */ static statsobj_t *objRoot = NULL; static statsobj_t *objLast = NULL; static pthread_mutex_t mutStats; static pthread_mutex_t mutSenders; static struct hashtable *stats_senders = NULL; /* ------------------------------ statsobj linked list maintenance ------------------------------ */ static void addToObjList(statsobj_t *pThis) { pthread_mutex_lock(&mutStats); if (pThis->flags && STATSOBJ_FLAG_DO_PREPEND) { pThis->next = objRoot; if (objRoot != NULL) { objRoot->prev = pThis; } objRoot = pThis; if (objLast == NULL) objLast = pThis; } else { pThis->prev = objLast; if (objLast != NULL) objLast->next = pThis; objLast = pThis; if (objRoot == NULL) objRoot = pThis; } pthread_mutex_unlock(&mutStats); } static void removeFromObjList(statsobj_t *pThis) { pthread_mutex_lock(&mutStats); if (pThis->prev != NULL) pThis->prev->next = pThis->next; if (pThis->next != NULL) pThis->next->prev = pThis->prev; if (objLast == pThis) objLast = pThis->prev; if (objRoot == pThis) objRoot = pThis->next; pthread_mutex_unlock(&mutStats); } static void addCtrToList(statsobj_t *pThis, ctr_t *pCtr) { pthread_mutex_lock(&pThis->mutCtr); pCtr->prev = pThis->ctrLast; if (pThis->ctrLast != NULL) pThis->ctrLast->next = pCtr; pThis->ctrLast = pCtr; if (pThis->ctrRoot == NULL) pThis->ctrRoot = pCtr; pthread_mutex_unlock(&pThis->mutCtr); } /* ------------------------------ methods ------------------------------ */ /* Standard-Constructor */ BEGINobjConstruct(statsobj) /* be sure to specify the object type also in END macro! */ pthread_mutex_init(&pThis->mutCtr, NULL); pThis->ctrLast = NULL; pThis->ctrRoot = NULL; pThis->read_notifier = NULL; pThis->flags = 0; ENDobjConstruct(statsobj) /* ConstructionFinalizer */ static rsRetVal statsobjConstructFinalize(statsobj_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, statsobj); addToObjList(pThis); RETiRet; } /* set read_notifier (a function which is invoked after stats are read). */ static rsRetVal setReadNotifier(statsobj_t *pThis, statsobj_read_notifier_t notifier, void *ctx) { DEFiRet; pThis->read_notifier = notifier; pThis->read_notifier_ctx = ctx; RETiRet; } /* set origin (module name, etc). * Note that we make our own copy of the memory, caller is * responsible to free up name it passes in (if required). */ static rsRetVal setOrigin(statsobj_t *pThis, uchar *origin) { DEFiRet; CHKmalloc(pThis->origin = ustrdup(origin)); finalize_it: RETiRet; } /* set name. Note that we make our own copy of the memory, caller is * responsible to free up name it passes in (if required). */ static rsRetVal setName(statsobj_t *pThis, uchar *name) { DEFiRet; CHKmalloc(pThis->name = ustrdup(name)); finalize_it: RETiRet; } static void setStatsObjFlags(statsobj_t *pThis, int flags) { pThis->flags = flags; } static rsRetVal setReportingNamespace(statsobj_t *pThis, uchar *ns) { DEFiRet; CHKmalloc(pThis->reporting_ns = ustrdup(ns)); finalize_it: RETiRet; } /* add a counter to an object * ctrName is duplicated, caller must free it if requried * NOTE: The counter is READ-ONLY and MUST NOT be modified (most * importantly, it must not be initialized, so the caller must * ensure the counter is properly initialized before AddCounter() * is called. */ static rsRetVal addManagedCounter(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr, ctr_t **entryRef, int8_t linked) { ctr_t *ctr; DEFiRet; *entryRef = NULL; CHKmalloc(ctr = calloc(1, sizeof(ctr_t))); ctr->next = NULL; ctr->prev = NULL; if ((ctr->name = ustrdup(ctrName)) == NULL) { DBGPRINTF("addCounter: OOM in strdup()\n"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } ctr->flags = flags; ctr->ctrType = ctrType; switch (ctrType) { case ctrType_IntCtr: ctr->val.pIntCtr = (intctr_t *)pCtr; break; case ctrType_Int: ctr->val.pInt = (int *)pCtr; break; default: // No action needed for other cases break; } if (linked) { addCtrToList(pThis, ctr); } *entryRef = ctr; finalize_it: if (iRet != RS_RET_OK) { if (ctr != NULL) { free(ctr->name); free(ctr); } } RETiRet; } static void addPreCreatedCounter(statsobj_t *pThis, ctr_t *pCtr) { pCtr->next = NULL; pCtr->prev = NULL; addCtrToList(pThis, pCtr); } static rsRetVal addCounter(statsobj_t *pThis, const uchar *ctrName, statsCtrType_t ctrType, int8_t flags, void *pCtr) { ctr_t *ctr; DEFiRet; iRet = addManagedCounter(pThis, ctrName, ctrType, flags, pCtr, &ctr, 1); RETiRet; } static void destructUnlinkedCounter(ctr_t *ctr) { free(ctr->name); free(ctr); } static void destructCounter(statsobj_t *pThis, ctr_t *pCtr) { pthread_mutex_lock(&pThis->mutCtr); if (pCtr->prev != NULL) { pCtr->prev->next = pCtr->next; } if (pCtr->next != NULL) { pCtr->next->prev = pCtr->prev; } if (pThis->ctrLast == pCtr) { pThis->ctrLast = pCtr->prev; } if (pThis->ctrRoot == pCtr) { pThis->ctrRoot = pCtr->next; } pthread_mutex_unlock(&pThis->mutCtr); destructUnlinkedCounter(pCtr); } static void resetResettableCtr(ctr_t *pCtr, int8_t bResetCtrs) { if ((bResetCtrs && (pCtr->flags & CTR_FLAG_RESETTABLE)) || (pCtr->flags & CTR_FLAG_MUST_RESET)) { switch (pCtr->ctrType) { case ctrType_IntCtr: *(pCtr->val.pIntCtr) = 0; break; case ctrType_Int: *(pCtr->val.pInt) = 0; break; default: // No action needed for other cases break; } } } static rsRetVal addCtrForReporting(json_object *to, const uchar *field_name, intctr_t value) { json_object *v; DEFiRet; /*We should migrate libfastjson to support uint64_t in addition to int64_t. Although no counter is likely to grow to int64 max-value, this is theoritically incorrect (as intctr_t is uint64)*/ CHKmalloc(v = json_object_new_int64((int64_t)value)); json_object_object_add(to, (const char *)field_name, v); finalize_it: /* v cannot be NULL in error case, as this would only happen during malloc fail, * which itself sets it to NULL -- so not doing cleanup here. */ RETiRet; } static rsRetVal addContextForReporting(json_object *to, const uchar *field_name, const uchar *value) { json_object *v; DEFiRet; CHKmalloc(v = json_object_new_string((const char *)value)); json_object_object_add(to, (const char *)field_name, v); finalize_it: RETiRet; } static intctr_t accumulatedValue(ctr_t *pCtr) { switch (pCtr->ctrType) { case ctrType_IntCtr: return *(pCtr->val.pIntCtr); case ctrType_Int: return *(pCtr->val.pInt); default: // No action needed for other cases break; } return -1; } /* get all the object's countes together as CEE. */ static rsRetVal getStatsLineCEE(statsobj_t *pThis, cstr_t **ppcstr, const statsFmtType_t fmt, const int8_t bResetCtrs) { cstr_t *pcstr = NULL; ctr_t *pCtr; json_object *root, *values; int locked = 0; DEFiRet; root = values = NULL; CHKiRet(cstrConstruct(&pcstr)); if (fmt == statsFmt_CEE) CHKiRet(rsCStrAppendStrWithLen(pcstr, UCHAR_CONSTANT(CONST_CEE_COOKIE " "), CONST_LEN_CEE_COOKIE + 1)); CHKmalloc(root = json_object_new_object()); CHKiRet(addContextForReporting(root, UCHAR_CONSTANT("name"), pThis->name)); if (pThis->origin != NULL) { CHKiRet(addContextForReporting(root, UCHAR_CONSTANT("origin"), pThis->origin)); } if (pThis->reporting_ns == NULL) { values = json_object_get(root); } else { CHKmalloc(values = json_object_new_object()); json_object_object_add(root, (const char *)pThis->reporting_ns, json_object_get(values)); } /* now add all counters to this line */ pthread_mutex_lock(&pThis->mutCtr); locked = 1; for (pCtr = pThis->ctrRoot; pCtr != NULL; pCtr = pCtr->next) { if (fmt == statsFmt_JSON_ES) { /* work-around for broken Elasticsearch JSON implementation: * we need to replace dots by a different char, we use bang. * Note: ES 2.0 does not longer accept dot in name */ uchar esbuf[256]; strncpy((char *)esbuf, (char *)pCtr->name, sizeof(esbuf) - 1); esbuf[sizeof(esbuf) - 1] = '\0'; for (uchar *c = esbuf; *c; ++c) { if (*c == '.') *c = '!'; } CHKiRet(addCtrForReporting(values, esbuf, accumulatedValue(pCtr))); } else { CHKiRet(addCtrForReporting(values, pCtr->name, accumulatedValue(pCtr))); } resetResettableCtr(pCtr, bResetCtrs); } pthread_mutex_unlock(&pThis->mutCtr); locked = 0; CHKiRet(rsCStrAppendStr(pcstr, (const uchar *)json_object_to_json_string(root))); cstrFinalize(pcstr); *ppcstr = pcstr; pcstr = NULL; finalize_it: if (locked) { pthread_mutex_unlock(&pThis->mutCtr); } if (pcstr != NULL) { cstrDestruct(&pcstr); } if (root != NULL) { json_object_put(root); } if (values != NULL) { json_object_put(values); } RETiRet; } /* get all the object's countes together with object name as one line. */ static rsRetVal getStatsLine(statsobj_t *pThis, cstr_t **ppcstr, int8_t bResetCtrs) { cstr_t *pcstr; ctr_t *pCtr; DEFiRet; CHKiRet(cstrConstruct(&pcstr)); rsCStrAppendStr(pcstr, pThis->name); rsCStrAppendStrWithLen(pcstr, UCHAR_CONSTANT(": "), 2); if (pThis->origin != NULL) { rsCStrAppendStrWithLen(pcstr, UCHAR_CONSTANT("origin="), 7); rsCStrAppendStr(pcstr, pThis->origin); cstrAppendChar(pcstr, ' '); } /* now add all counters to this line */ pthread_mutex_lock(&pThis->mutCtr); for (pCtr = pThis->ctrRoot; pCtr != NULL; pCtr = pCtr->next) { rsCStrAppendStr(pcstr, pCtr->name); cstrAppendChar(pcstr, '='); switch (pCtr->ctrType) { case ctrType_IntCtr: rsCStrAppendInt(pcstr, *(pCtr->val.pIntCtr)); // TODO: OK????? break; case ctrType_Int: rsCStrAppendInt(pcstr, *(pCtr->val.pInt)); break; default: // No action needed for other cases break; } cstrAppendChar(pcstr, ' '); resetResettableCtr(pCtr, bResetCtrs); } pthread_mutex_unlock(&pThis->mutCtr); cstrFinalize(pcstr); *ppcstr = pcstr; finalize_it: RETiRet; } /* this function obtains all sender stats. hlper to getAllStatsLines() * We need to keep this looked to avoid resizing of the hash table * (what could otherwise cause a segfault). */ static void getSenderStats(rsRetVal (*cb)(void *, const char *), void *usrptr, statsFmtType_t fmt, const int8_t bResetCtrs) { struct hashtable_itr *itr = NULL; struct sender_stats *stat; char fmtbuf[2048]; pthread_mutex_lock(&mutSenders); /* Iterator constructor only returns a valid iterator if * the hashtable is not empty */ if (hashtable_count(stats_senders) > 0) { itr = hashtable_iterator(stats_senders); do { stat = (struct sender_stats *)hashtable_iterator_value(itr); if (fmt == statsFmt_Legacy) { snprintf(fmtbuf, sizeof(fmtbuf), "_sender_stat: sender=%s messages=%" PRIu64, stat->sender, stat->nMsgs); } else { snprintf(fmtbuf, sizeof(fmtbuf), "{ \"name\":\"_sender_stat\", " "\"origin\":\"impstats\", " "\"sender\":\"%s\", \"messages\":%" PRIu64 "}", stat->sender, stat->nMsgs); } fmtbuf[sizeof(fmtbuf) - 1] = '\0'; cb(usrptr, fmtbuf); if (bResetCtrs) stat->nMsgs = 0; } while (hashtable_iterator_advance(itr)); } free(itr); pthread_mutex_unlock(&mutSenders); } /** * Helper: For a single statsobj_t (named o->name), iterate its counters * and emit Prometheus lines via cb. We generate, for each counter: * # HELP _ Generic help: " object, counter " * # TYPE _ counter * _ * * If bResetCtrs=TRUE and the counter has CTR_FLAG_RESETTABLE, zero it after reading. * * Note: by rsyslog stats subsystem design decision, read and write counters is racy * because we need the performance. It is OK that the counters in question are * not 100% precise. */ static ATTR_NO_SANITIZE_THREAD rsRetVal emitPrometheusForObject(statsobj_t *o, rsRetVal (*cb)(void *, const char *), void *usrptr, int8_t bResetCtrs) { ctr_t *pCtr; char linebuf[512]; int len; uint64_t value; const char *objName = (const char *)o->name; const char *origin = o->origin ? (const char *)o->origin : ""; /* Iterate each counter in o->ctrRoot. Lock while walking the linked list. */ pthread_mutex_lock(&o->mutCtr); for (pCtr = o->ctrRoot; pCtr != NULL; pCtr = pCtr->next) { /* 1) Read the current accumulated value. Might be IntCtr or Int. */ switch (pCtr->ctrType) { case ctrType_IntCtr: value = *(pCtr->val.pIntCtr); break; case ctrType_Int: value = (uint64_t)(*(pCtr->val.pInt)); break; default: value = 0; break; } /* 2) Optionally reset if requested and allowed. */ if ((bResetCtrs && (pCtr->flags & CTR_FLAG_RESETTABLE)) || (pCtr->flags & CTR_FLAG_MUST_RESET)) { switch (pCtr->ctrType) { case ctrType_IntCtr: *(pCtr->val.pIntCtr) = 0; break; case ctrType_Int: *(pCtr->val.pInt) = 0; break; default: break; } } pthread_mutex_unlock(&o->mutCtr); /* 3) Build the metric name: "__total" */ /* It is conventional in Prometheus to append "_total" to counters. */ len = snprintf(linebuf, sizeof(linebuf), "# HELP %s_%s_total rsyslog stats: origin=\"%s\" object=\"%s\", counter=\"%s\"\n" "# TYPE %s_%s_total counter\n" "%s_%s_total %llu\n", /* HELP */ objName, pCtr->name, origin, objName, pCtr->name, /* TYPE */ objName, pCtr->name, /* VALUE */ objName, pCtr->name, (unsigned long long)value); if (len < 0 || len >= (int)sizeof(linebuf)) { /* In case our buffer is too small, just skip emitting this counter. */ } else { /* Emit this chunk (all three lines) in one callback */ cb(usrptr, linebuf); } /* Acquire the lock again before advancing to the next counter */ pthread_mutex_lock(&o->mutCtr); } pthread_mutex_unlock(&o->mutCtr); return RS_RET_OK; } /* this function can be used to obtain all stats lines. In this case, * a callback must be provided. This module than iterates over all objects and * submits each stats line to the callback. The callback has two parameters: * the first one is a caller-provided void*, the second one the cstr_t with the * line. If the callback reports an error, processing is stopped. */ static rsRetVal getAllStatsLines(rsRetVal (*cb)(void *, const char *), void *const usrptr, statsFmtType_t fmt, const int8_t bResetCtrs) { statsobj_t *o; cstr_t *cstr = NULL; DEFiRet; if (fmt == statsFmt_Prometheus) { // TODO: move to function /* For each statsobj in our linked list, emit Prometheus lines. */ for (o = objRoot; o != NULL; o = o->next) { emitPrometheusForObject(o, cb, usrptr, bResetCtrs); /* If the object has a read_notifier, call it now */ if (o->read_notifier != NULL) { o->read_notifier(o, o->read_notifier_ctx); } } /* Optionally, handle sender stats as additional metrics: * e.g. emit "rsyslog_sender_ " lines. * For simplicity, we skip this, or you can extend similarly. */ FINALIZE; } for (o = objRoot; o != NULL; o = o->next) { switch (fmt) { case statsFmt_Legacy: CHKiRet(getStatsLine(o, &cstr, bResetCtrs)); break; case statsFmt_CEE: case statsFmt_JSON: case statsFmt_JSON_ES: CHKiRet(getStatsLineCEE(o, &cstr, fmt, bResetCtrs)); break; case statsFmt_Prometheus: // TODO: move to function /* For each statsobj in our linked list, emit Prometheus lines. */ for (o = objRoot; o != NULL; o = o->next) { emitPrometheusForObject(o, cb, usrptr, bResetCtrs); /* If the object has a read_notifier, call it now */ if (o->read_notifier != NULL) { o->read_notifier(o, o->read_notifier_ctx); } } /* Optionally, handle sender stats as additional metrics: * e.g. emit "rsyslog_sender_ " lines. * For simplicity, we skip this, or you can extend similarly. */ break; default: // No action needed for other cases break; } CHKiRet(cb(usrptr, (const char *)cstrGetSzStrNoNULL(cstr))); rsCStrDestruct(&cstr); if (o->read_notifier != NULL) { o->read_notifier(o, o->read_notifier_ctx); } } getSenderStats(cb, usrptr, fmt, bResetCtrs); finalize_it: if (cstr != NULL) { rsCStrDestruct(&cstr); } RETiRet; } /* Enable statistics gathering. currently there is no function to disable it * again, as this is right now not needed. */ static rsRetVal enableStats(void) { GatherStats = 1; return RS_RET_OK; } rsRetVal statsRecordSender(const uchar *sender, unsigned nMsgs, time_t lastSeen) { struct sender_stats *stat; int mustUnlock = 0; DEFiRet; if (stats_senders == NULL) FINALIZE; /* unlikely: we could not init our hash table */ pthread_mutex_lock(&mutSenders); mustUnlock = 1; stat = hashtable_search(stats_senders, (void *)sender); if (stat == NULL) { DBGPRINTF("statsRecordSender: sender '%s' not found, adding\n", sender); CHKmalloc(stat = calloc(1, sizeof(struct sender_stats))); stat->sender = (const uchar *)strdup((const char *)sender); stat->nMsgs = 0; if (runConf->globals.reportNewSenders) { LogMsg(0, RS_RET_SENDER_APPEARED, LOG_INFO, "new sender '%s'", stat->sender); } if (hashtable_insert(stats_senders, (void *)stat->sender, (void *)stat) == 0) { LogError(errno, RS_RET_INTERNAL_ERROR, "error inserting sender '%s' into sender " "hash table", sender); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } } stat->nMsgs += nMsgs; stat->lastSeen = lastSeen; DBGPRINTF("DDDDD: statsRecordSender: '%s', nmsgs %u [%llu], lastSeen %llu\n", sender, nMsgs, (long long unsigned)stat->nMsgs, (long long unsigned)lastSeen); finalize_it: if (mustUnlock) pthread_mutex_unlock(&mutSenders); RETiRet; } static ctr_t *unlinkAllCounters(statsobj_t *pThis) { ctr_t *ctr; pthread_mutex_lock(&pThis->mutCtr); ctr = pThis->ctrRoot; pThis->ctrLast = NULL; pThis->ctrRoot = NULL; pthread_mutex_unlock(&pThis->mutCtr); return ctr; } static void destructUnlinkedCounters(ctr_t *ctr) { ctr_t *ctrToDel; while (ctr != NULL) { ctrToDel = ctr; ctr = ctr->next; destructUnlinkedCounter(ctrToDel); } } /* check if a sender has not sent info to us for an extended period * of time. */ void checkGoneAwaySenders(const time_t tCurr) { struct hashtable_itr *itr = NULL; struct sender_stats *stat; const time_t rqdLast = tCurr - runConf->globals.senderStatsTimeout; struct tm tm; pthread_mutex_lock(&mutSenders); /* Iterator constructor only returns a valid iterator if * the hashtable is not empty */ if (hashtable_count(stats_senders) > 0) { itr = hashtable_iterator(stats_senders); do { stat = (struct sender_stats *)hashtable_iterator_value(itr); if (stat->lastSeen < rqdLast) { if (runConf->globals.reportGoneAwaySenders) { localtime_r(&stat->lastSeen, &tm); LogMsg(0, RS_RET_SENDER_GONE_AWAY, LOG_WARNING, "removing sender '%s' from connection " "table, last seen at " "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", stat->sender, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } hashtable_remove(stats_senders, (void *)stat->sender); } } while (hashtable_iterator_advance(itr)); } pthread_mutex_unlock(&mutSenders); free(itr); } /* destructor for the statsobj object */ BEGINobjDestruct(statsobj) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(statsobj); removeFromObjList(pThis); /* destruct counters */ destructUnlinkedCounters(unlinkAllCounters(pThis)); pthread_mutex_destroy(&pThis->mutCtr); free(pThis->name); free(pThis->origin); free(pThis->reporting_ns); ENDobjDestruct(statsobj) /* debugprint for the statsobj object */ BEGINobjDebugPrint(statsobj) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDebugPrint(statsobj); dbgoprint((obj_t *)pThis, "statsobj object, currently no state info available\n"); ENDobjDebugPrint(statsobj) /* queryInterface function */ BEGINobjQueryInterface(statsobj) CODESTARTobjQueryInterface(statsobj); if (pIf->ifVersion != statsobjCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = statsobjConstruct; pIf->ConstructFinalize = statsobjConstructFinalize; pIf->Destruct = statsobjDestruct; pIf->DebugPrint = statsobjDebugPrint; pIf->SetName = setName; pIf->SetOrigin = setOrigin; pIf->SetReadNotifier = setReadNotifier; pIf->SetReportingNamespace = setReportingNamespace; pIf->SetStatsObjFlags = setStatsObjFlags; pIf->GetAllStatsLines = getAllStatsLines; pIf->AddCounter = addCounter; pIf->AddManagedCounter = addManagedCounter; pIf->AddPreCreatedCtr = addPreCreatedCounter; pIf->DestructCounter = destructCounter; pIf->DestructUnlinkedCounter = destructUnlinkedCounter; pIf->UnlinkAllCounters = unlinkAllCounters; pIf->EnableStats = enableStats; finalize_it: ENDobjQueryInterface(statsobj) /* Initialize the statsobj class. Must be called as the very first method * before anything else is called inside this class. */ BEGINAbstractObjClassInit(statsobj, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ /* set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, statsobjDebugPrint); OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, statsobjConstructFinalize); /* init other data items */ pthread_mutex_init(&mutStats, NULL); pthread_mutex_init(&mutSenders, NULL); if ((stats_senders = create_hashtable(100, hash_from_string, key_equals_string, NULL)) == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "error trying to initialize hash-table " "for sender table. Sender statistics and warnings are disabled."); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } ENDObjClassInit(statsobj) /* Exit the class. */ BEGINObjClassExit(statsobj, OBJ_IS_CORE_MODULE) /* class, version */ /* release objects we no longer need */ pthread_mutex_destroy(&mutStats); pthread_mutex_destroy(&mutSenders); hashtable_destroy(stats_senders, 1); ENDObjClassExit(statsobj) rsyslog-8.2512.0/runtime/PaxHeaders/stringbuf.h0000644000000000000000000000013215055605325016376 xustar0030 mtime=1756826325.653800744 30 atime=1764930979.974677453 30 ctime=1764935923.178576504 rsyslog-8.2512.0/runtime/stringbuf.h0000664000175000017500000001266015055605325016047 0ustar00rgerrger/* stringbuf.h * The counted string object * * \author Rainer Gerhards * \date 2005-09-07 * Initial version begun. * * Copyright 2005-2016 Adiscon GmbH. All Rights Reserved. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _STRINGBUF_H_INCLUDED__ #define _STRINGBUF_H_INCLUDED__ 1 #include #include /** * The dynamic string buffer object. */ typedef struct cstr_s { #ifndef NDEBUG rsObjID OID; /**< object ID */ sbool isFinalized; #endif uchar *pBuf; /**< pointer to the string buffer, may be NULL if string is empty */ size_t iBufSize; /**< current maximum size of the string buffer */ size_t iStrLen; /**< length of the string in characters. */ } cstr_t; /** * Construct a rsCStr object. */ rsRetVal cstrConstruct(cstr_t **ppThis); #define rsCStrConstruct(x) cstrConstruct((x)) rsRetVal cstrConstructFromESStr(cstr_t **ppThis, es_str_t *str); rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, const uchar *sz); rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, const cstr_t *pFrom); rsRetVal rsCStrConstructFromszStrf(cstr_t **ppThis, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /** * Destruct the string buffer object. */ void rsCStrDestruct(cstr_t **ppThis); #define cstrDestruct(x) rsCStrDestruct((x)) /* Append a character to the current string object. This may only be done until * cstrFinalize() is called. * rgerhards, 2009-06-16 */ rsRetVal cstrAppendChar(cstr_t *pThis, const uchar c); /* Finalize the string object. This must be called after all data is added to it * but before that data is used. * rgerhards, 2009-06-16 */ #ifdef NDEBUG #define cstrFinalize(pThis) \ { \ if ((pThis)->iStrLen > 0) (pThis)->pBuf[(pThis)->iStrLen] = '\0'; /* space is always reserved for this */ \ } #else #define cstrFinalize(pThis) \ { \ if ((pThis)->iStrLen > 0) (pThis)->pBuf[(pThis)->iStrLen] = '\0'; /* space is always reserved for this */ \ (pThis)->isFinalized = 1; \ } #endif /** * Truncate "n" number of characters from the end of the * string. The buffer remains unchanged, just the * string length is manipulated. This is for performance * reasons. */ rsRetVal rsCStrTruncate(cstr_t *pThis, size_t nTrunc); void cstrTrimTrailingWhiteSpace(cstr_t *pThis); /** * Append a string to the buffer. For performance reasons, * use rsCStrAppenStrWithLen() if you know the length. * * \param psz pointer to string to be appended. Must not be NULL. */ rsRetVal rsCStrAppendStr(cstr_t *pThis, const uchar *psz); /** * Append a string to the buffer. * * \param psz pointer to string to be appended. Must not be NULL. * \param iStrLen the length of the string pointed to by psz */ rsRetVal rsCStrAppendStrWithLen(cstr_t *pThis, const uchar *psz, size_t iStrLen); /** * Append a printf-style formated string to the buffer. * * \param fmt pointer to the format string (see man 3 printf for details). Must not be NULL. */ rsRetVal rsCStrAppendStrf(cstr_t *pThis, const char *fmt, ...) __attribute__((format(printf, 2, 3))); /** * Append an integer to the string. No special formatting is * done. */ rsRetVal rsCStrAppendInt(cstr_t *pThis, long i); rsRetVal strExit(void); uchar *cstrGetSzStrNoNULL(cstr_t *pThis); #define rsCStrGetSzStrNoNULL(x) cstrGetSzStrNoNULL(x) rsRetVal rsCStrSetSzStr(cstr_t *pThis, uchar *pszNew); int rsCStrCStrCmp(cstr_t *pCS1, cstr_t *pCS2); int rsCStrSzStrCmp(cstr_t *pCS1, uchar *psz, size_t iLenSz); int rsCStrOffsetSzStrCmp(cstr_t *pCS1, size_t iOffset, uchar *psz, size_t iLenSz); int rsCStrLocateSzStr(cstr_t *pCStr, uchar *sz); int rsCStrLocateInSzStr(cstr_t *pThis, uchar *sz); int rsCStrSzStrStartsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz); int rsCStrSzStrEndsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz); rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *cache); void rsCStrRegexDestruct(void *rc); /* new calling interface */ rsRetVal cstrConvSzStrAndDestruct(cstr_t **pThis, uchar **ppSz, int bRetNULL); rsRetVal cstrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend); /* now come inline-like functions */ #ifdef NDEBUG #define cstrLen(x) ((size_t)((x)->iStrLen)) #else size_t cstrLen(cstr_t *pThis); #endif #define rsCStrLen(s) cstrLen((s)) #define rsCStrGetBufBeg(x) ((x)->pBuf) rsRetVal strInit(void); #endif /* single include */ rsyslog-8.2512.0/runtime/PaxHeaders/net_ossl.h0000644000000000000000000000013215055605325016221 xustar0030 mtime=1756826325.648800668 30 atime=1764931011.598204215 30 ctime=1764935923.369579428 rsyslog-8.2512.0/runtime/net_ossl.h0000664000175000017500000001531215055605325015667 0ustar00rgerrger/* Definitions for generic OpenSSL include stuff. * * Copyright 2023 Andre Lorbach and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_NET_OSSL_H #define INCLUDED_NET_OSSL_H /* Needed OpenSSL Includes */ #include #include #include #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) #include #endif #ifndef OPENSSL_NO_ENGINE #include #endif #include #include /* Internal OpenSSL defined ENUMS */ typedef enum { OSSL_AUTH_CERTNAME = 0, OSSL_AUTH_CERTFINGERPRINT = 1, OSSL_AUTH_CERTVALID = 2, OSSL_AUTH_CERTANON = 3 } AuthMode; typedef enum { OSSL_EXPIRED_PERMIT = 0, OSSL_EXPIRED_DENY = 1, OSSL_EXPIRED_WARN = 2 } PermitExpiredCerts; typedef enum { osslServer = 0, /**< Server SSL Object */ osslClient = 1 /**< Client SSL Object */ } osslSslState_t; /* the net_ossl object */ struct net_ossl_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ /* Config Cert vars */ const uchar *pszCAFile; const uchar *pszCRLFile; const uchar *pszExtraCAFiles; const uchar *pszKeyFile; const uchar *pszCertFile; AuthMode authMode; permittedPeers_t *pPermPeers; /* permitted peers */ int bReportAuthErr; /* only the first auth error is to be reported, this var triggers it. Initially, it is * set to 1 and changed to 0 after the first report. It is changed back to 1 after * one successful authentication. */ int bSANpriority; /* if true, we do stricter checking (if any SAN present we do not check CN) */ /* Open SSL objects */ BIO *bio; /* OpenSSL main BIO obj */ int ctx_is_copy; SSL_CTX *ctx; /* credentials, ciphers, ... */ SSL *ssl; /* OpenSSL main SSL obj */ osslSslState_t sslState; /**< what must we retry? */ }; /* interface */ BEGINinterface(net_ossl) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(net_ossl_t **ppThis); rsRetVal (*Destruct)(net_ossl_t **ppThis); rsRetVal (*osslCtxInit)(net_ossl_t *pThis, const SSL_METHOD *method); #if OPENSSL_VERSION_NUMBER >= 0x10100000L rsRetVal (*osslCtxInitCookie)(net_ossl_t *pThis); #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L rsRetVal (*osslInitEngine)(net_ossl_t *pThis); // OpenSSL Helper function exports rsRetVal (*osslChkpeername)(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP); rsRetVal (*osslPeerfingerprint)(net_ossl_t *pThis, X509 *certpeer, uchar *fromHostIP); X509 *(*osslGetpeercert)(net_ossl_t *pThis, SSL *ssl, uchar *fromHostIP); rsRetVal (*osslChkpeercertvalidity)(net_ossl_t *pThis, SSL *ssl, uchar *fromHostIP); #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) rsRetVal (*osslApplyTlscgfcmd)(net_ossl_t *pThis, uchar *tlscfgcmd); #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L void (*osslSetBioCallback)(BIO *conn); void (*osslSetCtxVerifyCallback)(SSL_CTX *pCtx, int flags); void (*osslSetSslVerifyCallback)(SSL *pSsl, int flags); void (*osslLastOpenSSLErrorMsg)(uchar *fromHost, const int ret, SSL *ssl, int severity, const char *pszCallSource, const char *pszOsslApi); ENDinterface(net_ossl) #define net_osslCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ // ------------------------------------------------------ /* OpenSSL API differences */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L #define RSYSLOG_X509_NAME_oneline(X509CERT) X509_get_subject_name(X509CERT) #define RSYSLOG_BIO_method_name(SSLBIO) BIO_method_name(SSLBIO) #define RSYSLOG_BIO_number_read(SSLBIO) BIO_number_read(SSLBIO) #define RSYSLOG_BIO_number_written(SSLBIO) BIO_number_written(SSLBIO) #else #define RSYSLOG_X509_NAME_oneline(X509CERT) (X509CERT != NULL ? X509CERT->cert_info->subject : NULL) #define RSYSLOG_BIO_method_name(SSLBIO) SSLBIO->method->name #define RSYSLOG_BIO_number_read(SSLBIO) SSLBIO->num #define RSYSLOG_BIO_number_written(SSLBIO) SSLBIO->num #endif /*-----------------------------------------------------------------------------*/ /* OpenSSL Global Helper functions prototypes */ #define MUTEX_TYPE pthread_mutex_t #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL) #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x)) #define MUTEX_LOCK(x) pthread_mutex_lock(&(x)) #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x)) #define THREAD_ID pthread_self() /* This array will store all of the mutexes available to OpenSSL. */ struct CRYPTO_dynlock_value { MUTEX_TYPE mutex; }; void dyn_destroy_function(struct CRYPTO_dynlock_value *l, __attribute__((unused)) const char *file, __attribute__((unused)) int line); void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, __attribute__((unused)) const char *file, __attribute__((unused)) int line); struct CRYPTO_dynlock_value *dyn_create_function(__attribute__((unused)) const char *file, __attribute__((unused)) int line); unsigned long id_function(void); void locking_function(int mode, int n, __attribute__((unused)) const char *file, __attribute__((unused)) int line); int opensslh_THREAD_setup(void); int opensslh_THREAD_cleanup(void); void osslGlblInit(void); void osslGlblExit(void); /*-----------------------------------------------------------------------------*/ /* prototypes */ PROTOTYPEObj(net_ossl); /* the name of our library binary */ // #define LM_NET_OSSL_FILENAME "lmnet_ossl" #define LM_NET_OSSL_FILENAME "lmnsd_ossl" #endif /* #ifndef INCLUDED_NET_OSSL_H */ rsyslog-8.2512.0/runtime/PaxHeaders/libgcry.c0000644000000000000000000000013115055605325016020 xustar0030 mtime=1756826325.646800638 29 atime=1764931130.09914257 30 ctime=1764935923.079574989 rsyslog-8.2512.0/runtime/libgcry.c0000664000175000017500000005077315055605325015501 0ustar00rgerrger/* gcry.c - rsyslog's libgcrypt based crypto provider * * Copyright 2013-2018 Adiscon GmbH. * * We need to store some additional information in support of encryption. * For this, we create a side-file, which is named like the actual log * file, but with the suffix ".encinfo" appended. It contains the following * records: * IV: The initial vector used at block start. Also indicates start * start of block. * END: The end offset of the block, as uint64_t in decimal notation. * This is used during encryption to know when the current * encryption block ends. * For the current implementation, there must always be an IV record * followed by an END record. Each records is LF-terminated. Record * types can simply be extended in the future by specifying new * types (like "IV") before the colon. * To identify a file as rsyslog encryption info file, it must start with * the line "FILETYPE:rsyslog-enrcyption-info" * There are some size constraints: the recordtype must be 31 bytes at * most and the actual value (between : and LF) must be 1023 bytes at most. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "debug.h" #include "libgcry.h" #include "libcry_common.h" #define READBUF_SIZE 4096 /* size of the read buffer */ static rsRetVal rsgcryBlkBegin(gcryfile gf); int rsgcryAlgoname2Algo(char *const __restrict__ algoname) { if (!strcmp((char *)algoname, "3DES")) return GCRY_CIPHER_3DES; if (!strcmp((char *)algoname, "CAST5")) return GCRY_CIPHER_CAST5; if (!strcmp((char *)algoname, "BLOWFISH")) return GCRY_CIPHER_BLOWFISH; if (!strcmp((char *)algoname, "AES128")) return GCRY_CIPHER_AES128; if (!strcmp((char *)algoname, "AES192")) return GCRY_CIPHER_AES192; if (!strcmp((char *)algoname, "AES256")) return GCRY_CIPHER_AES256; if (!strcmp((char *)algoname, "TWOFISH")) return GCRY_CIPHER_TWOFISH; if (!strcmp((char *)algoname, "TWOFISH128")) return GCRY_CIPHER_TWOFISH128; if (!strcmp((char *)algoname, "ARCFOUR")) return GCRY_CIPHER_ARCFOUR; if (!strcmp((char *)algoname, "DES")) return GCRY_CIPHER_DES; if (!strcmp((char *)algoname, "SERPENT128")) return GCRY_CIPHER_SERPENT128; if (!strcmp((char *)algoname, "SERPENT192")) return GCRY_CIPHER_SERPENT192; if (!strcmp((char *)algoname, "SERPENT256")) return GCRY_CIPHER_SERPENT256; if (!strcmp((char *)algoname, "RFC2268_40")) return GCRY_CIPHER_RFC2268_40; if (!strcmp((char *)algoname, "SEED")) return GCRY_CIPHER_SEED; if (!strcmp((char *)algoname, "CAMELLIA128")) return GCRY_CIPHER_CAMELLIA128; if (!strcmp((char *)algoname, "CAMELLIA192")) return GCRY_CIPHER_CAMELLIA192; if (!strcmp((char *)algoname, "CAMELLIA256")) return GCRY_CIPHER_CAMELLIA256; return GCRY_CIPHER_NONE; } int rsgcryModename2Mode(char *const __restrict__ modename) { if (!strcmp((char *)modename, "ECB")) return GCRY_CIPHER_MODE_ECB; if (!strcmp((char *)modename, "CFB")) return GCRY_CIPHER_MODE_CFB; if (!strcmp((char *)modename, "CBC")) return GCRY_CIPHER_MODE_CBC; if (!strcmp((char *)modename, "STREAM")) return GCRY_CIPHER_MODE_STREAM; if (!strcmp((char *)modename, "OFB")) return GCRY_CIPHER_MODE_OFB; if (!strcmp((char *)modename, "CTR")) return GCRY_CIPHER_MODE_CTR; #ifdef GCRY_CIPHER_MODE_AESWRAP if (!strcmp((char *)modename, "AESWRAP")) return GCRY_CIPHER_MODE_AESWRAP; #endif return GCRY_CIPHER_MODE_NONE; } static rsRetVal eiWriteRec(gcryfile gf, const char *recHdr, size_t lenRecHdr, const char *buf, size_t lenBuf) { struct iovec iov[3]; ssize_t nwritten, towrite; DEFiRet; iov[0].iov_base = (void *)recHdr; iov[0].iov_len = lenRecHdr; iov[1].iov_base = (void *)buf; iov[1].iov_len = lenBuf; iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1; towrite = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len; nwritten = writev(gf->fd, iov, sizeof(iov) / sizeof(struct iovec)); if (nwritten != towrite) { DBGPRINTF( "eiWrite%s: error writing file, towrite %d, " "nwritten %d\n", recHdr, (int)towrite, (int)nwritten); ABORT_FINALIZE(RS_RET_EI_WR_ERR); } DBGPRINTF("encryption info file %s: written %s, len %d\n", recHdr, gf->eiName, (int)nwritten); finalize_it: RETiRet; } static rsRetVal eiOpenRead(gcryfile gf) { DEFiRet; gf->fd = open((char *)gf->eiName, O_RDONLY | O_NOCTTY | O_CLOEXEC); if (gf->fd == -1) { ABORT_FINALIZE(errno == ENOENT ? RS_RET_EI_NO_EXISTS : RS_RET_EI_OPN_ERR); } finalize_it: RETiRet; } static rsRetVal eiRead(gcryfile gf) { ssize_t nRead; DEFiRet; if (gf->readBuf == NULL) { CHKmalloc(gf->readBuf = malloc(READBUF_SIZE)); } nRead = read(gf->fd, gf->readBuf, READBUF_SIZE); if (nRead <= 0) { ABORT_FINALIZE(RS_RET_ERR); } gf->readBufMaxIdx = (int16_t)nRead; gf->readBufIdx = 0; finalize_it: RETiRet; } /* returns EOF on any kind of error */ static int eiReadChar(gcryfile gf) { int c; if (gf->readBufIdx >= gf->readBufMaxIdx) { if (eiRead(gf) != RS_RET_OK) { c = EOF; goto finalize_it; } } c = gf->readBuf[gf->readBufIdx++]; finalize_it: return c; } static rsRetVal eiCheckFiletype(gcryfile gf) { char hdrBuf[128]; size_t toRead, didRead; sbool bNeedClose = 0; DEFiRet; if (gf->fd == -1) { CHKiRet(eiOpenRead(gf)); assert(gf->fd != -1); /* cannot happen after successful return */ bNeedClose = 1; } if (Debug) memset(hdrBuf, 0, sizeof(hdrBuf)); /* for dbgprintf below! */ toRead = sizeof("FILETYPE:") - 1 + sizeof(RSGCRY_FILETYPE_NAME) - 1 + 1; didRead = read(gf->fd, hdrBuf, toRead); if (bNeedClose) { close(gf->fd); gf->fd = -1; } DBGPRINTF("eiCheckFiletype read %zd bytes: '%s'\n", didRead, hdrBuf); if (didRead != toRead || strncmp(hdrBuf, "FILETYPE:" RSGCRY_FILETYPE_NAME "\n", toRead)) iRet = RS_RET_EI_INVLD_FILE; finalize_it: RETiRet; } /* rectype/value must be EIF_MAX_*_LEN+1 long! * returns 0 on success or something else on error/EOF */ static rsRetVal eiGetRecord(gcryfile gf, char *rectype, char *value) { unsigned short i, j; int c; DEFiRet; c = eiReadChar(gf); if (c == EOF) { ABORT_FINALIZE(RS_RET_NO_DATA); } for (i = 0; i < EIF_MAX_RECTYPE_LEN; ++i) { if (c == ':' || c == EOF) break; rectype[i] = c; c = eiReadChar(gf); } if (c != ':') { ABORT_FINALIZE(RS_RET_ERR); } rectype[i] = '\0'; j = 0; for (++i; i < EIF_MAX_VALUE_LEN; ++i, ++j) { c = eiReadChar(gf); if (c == '\n' || c == EOF) break; value[j] = c; } if (c != '\n') { ABORT_FINALIZE(RS_RET_ERR); } value[j] = '\0'; finalize_it: RETiRet; } static rsRetVal eiGetIV(gcryfile gf, uchar *iv, size_t leniv) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; size_t valueLen; unsigned short i, j; unsigned char nibble; DEFiRet; CHKiRet(eiGetRecord(gf, rectype, value)); const char *const cmp_IV = "IV"; // work-around for static analyzer if (strcmp(rectype, cmp_IV)) { DBGPRINTF( "no IV record found when expected, record type " "seen is '%s'\n", rectype); ABORT_FINALIZE(RS_RET_ERR); } valueLen = strlen(value); if (valueLen / 2 != leniv) { DBGPRINTF("length of IV is %zd, expected %zd\n", valueLen / 2, leniv); ABORT_FINALIZE(RS_RET_ERR); } for (i = j = 0; i < valueLen; ++i) { if (value[i] >= '0' && value[i] <= '9') nibble = value[i] - '0'; else if (value[i] >= 'a' && value[i] <= 'f') nibble = value[i] - 'a' + 10; else { DBGPRINTF("invalid IV '%s'\n", value); ABORT_FINALIZE(RS_RET_ERR); } if (i % 2 == 0) iv[j] = nibble << 4; else iv[j++] |= nibble; } finalize_it: RETiRet; } static rsRetVal eiGetEND(gcryfile gf, off64_t *offs) { char rectype[EIF_MAX_RECTYPE_LEN + 1]; char value[EIF_MAX_VALUE_LEN + 1]; DEFiRet; CHKiRet(eiGetRecord(gf, rectype, value)); const char *const const_END = "END"; // clang static analyzer work-around if (strcmp(rectype, const_END)) { DBGPRINTF( "no END record found when expected, record type " "seen is '%s'\n", rectype); ABORT_FINALIZE(RS_RET_ERR); } *offs = atoll(value); finalize_it: RETiRet; } static rsRetVal eiOpenAppend(gcryfile gf) { rsRetVal localRet; DEFiRet; localRet = eiCheckFiletype(gf); if (localRet == RS_RET_OK) { gf->fd = open((char *)gf->eiName, O_WRONLY | O_APPEND | O_NOCTTY | O_CLOEXEC, 0600); if (gf->fd == -1) { ABORT_FINALIZE(RS_RET_EI_OPN_ERR); } } else if (localRet == RS_RET_EI_NO_EXISTS) { /* looks like we need to create a new file */ gf->fd = open((char *)gf->eiName, O_WRONLY | O_CREAT | O_NOCTTY | O_CLOEXEC, 0600); if (gf->fd == -1) { ABORT_FINALIZE(RS_RET_EI_OPN_ERR); } CHKiRet(eiWriteRec(gf, "FILETYPE:", 9, RSGCRY_FILETYPE_NAME, sizeof(RSGCRY_FILETYPE_NAME) - 1)); } else { gf->fd = -1; ABORT_FINALIZE(localRet); } DBGPRINTF("encryption info file %s: opened as #%d\n", gf->eiName, gf->fd); finalize_it: RETiRet; } static rsRetVal __attribute__((nonnull(2))) eiWriteIV(gcryfile gf, const uchar *const iv) { static const char hexchars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; unsigned iSrc, iDst; char hex[4096]; DEFiRet; if (gf->blkLength > sizeof(hex) / 2) { DBGPRINTF( "eiWriteIV: crypto block len way too large, aborting " "write"); ABORT_FINALIZE(RS_RET_ERR); } for (iSrc = iDst = 0; iSrc < gf->blkLength; ++iSrc) { hex[iDst++] = hexchars[iv[iSrc] >> 4]; hex[iDst++] = hexchars[iv[iSrc] & 0x0f]; } iRet = eiWriteRec(gf, "IV:", 3, hex, gf->blkLength * 2); finalize_it: RETiRet; } /* we do not return an error state, as we MUST close the file, * no matter what happens. */ static void eiClose(gcryfile gf, off64_t offsLogfile) { char offs[21]; size_t len; if (gf->fd == -1) return; if (gf->openMode == 'w') { /* 2^64 is 20 digits, so the snprintf buffer is large enough */ len = snprintf(offs, sizeof(offs), "%lld", (long long)offsLogfile); eiWriteRec(gf, "END:", 4, offs, len); } gcry_cipher_close(gf->chd); free(gf->readBuf); close(gf->fd); gf->fd = -1; DBGPRINTF("encryption info file %s: closed\n", gf->eiName); } /* this returns the number of bytes left inside the block or -1, if the block * size is unbounded. The function automatically handles end-of-block and begins * to read the next block in this case. */ rsRetVal gcryfileGetBytesLeftInBlock(gcryfile gf, ssize_t *left) { DEFiRet; if (gf->bytesToBlkEnd == 0) { DBGPRINTF("libgcry: end of current crypto block\n"); gcry_cipher_close(gf->chd); CHKiRet(rsgcryBlkBegin(gf)); } *left = gf->bytesToBlkEnd; finalize_it: RETiRet; } /* this is a special functon for use by the rsyslog disk queue subsystem. It * needs to have the capability to delete state when a queue file is rolled * over. This simply generates the file name and deletes it. It must take care * of "all" state files, which currently happens to be a single one. */ rsRetVal gcryfileDeleteState(uchar *logfn) { char fn[MAXFNAME + 1]; DEFiRet; snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX); fn[MAXFNAME] = '\0'; /* be on save side */ DBGPRINTF("crypto provider deletes state file '%s' on request\n", fn); unlink(fn); RETiRet; } static rsRetVal gcryfileConstruct(gcryctx ctx, gcryfile *pgf, uchar *logfn) { char fn[MAXFNAME + 1]; gcryfile gf; DEFiRet; CHKmalloc(gf = calloc(1, sizeof(struct gcryfile_s))); gf->ctx = ctx; gf->fd = -1; snprintf(fn, sizeof(fn), "%s%s", logfn, ENCINFO_SUFFIX); fn[MAXFNAME] = '\0'; /* be on save side */ gf->eiName = (uchar *)strdup(fn); *pgf = gf; finalize_it: RETiRet; } gcryctx gcryCtxNew(void) { gcryctx ctx; ctx = calloc(1, sizeof(struct gcryctx_s)); if (ctx != NULL) { ctx->algo = GCRY_CIPHER_AES128; ctx->mode = GCRY_CIPHER_MODE_CBC; } return ctx; } int gcryfileDestruct(gcryfile gf, off64_t offsLogfile) { int r = 0; if (gf == NULL) goto done; DBGPRINTF("libgcry: close file %s\n", gf->eiName); eiClose(gf, offsLogfile); if (gf->bDeleteOnClose) { DBGPRINTF("unlink file '%s' due to bDeleteOnClose set\n", gf->eiName); unlink((char *)gf->eiName); } free(gf->eiName); free(gf); done: return r; } void rsgcryCtxDel(gcryctx ctx) { if (ctx != NULL) { free(ctx->key); free(ctx); } } static void addPadding(gcryfile pF, uchar *buf, size_t *plen) { unsigned i; size_t nPad; nPad = (pF->blkLength - *plen % pF->blkLength) % pF->blkLength; DBGPRINTF("libgcry: addPadding %zd chars, blkLength %zd, mod %zd, pad %zd\n", *plen, pF->blkLength, *plen % pF->blkLength, nPad); for (i = 0; i < nPad; ++i) buf[(*plen) + i] = 0x00; (*plen) += nPad; } static void ATTR_NONNULL() removePadding(uchar *const buf, size_t *const plen) { const size_t len = *plen; size_t iSrc, iDst; iSrc = 0; /* skip to first NUL */ while (iSrc < len && buf[iSrc] == '\0') { ++iSrc; } iDst = iSrc; while (iSrc < len) { if (buf[iSrc] != 0x00) buf[iDst++] = buf[iSrc]; ++iSrc; } *plen = iDst; } /* returns 0 on succes, positive if key length does not match and key * of return value size is required. */ int rsgcrySetKey(gcryctx ctx, unsigned char *key, uint16_t keyLen) { uint16_t reqKeyLen; int r; reqKeyLen = gcry_cipher_get_algo_keylen(ctx->algo); if (keyLen != reqKeyLen) { r = reqKeyLen; goto done; } ctx->keyLen = keyLen; ctx->key = malloc(keyLen); memcpy(ctx->key, key, keyLen); r = 0; done: return r; } rsRetVal rsgcrySetMode(gcryctx ctx, uchar *modename) { int mode; DEFiRet; mode = rsgcryModename2Mode((char *)modename); if (mode == GCRY_CIPHER_MODE_NONE) { ABORT_FINALIZE(RS_RET_CRY_INVLD_MODE); } ctx->mode = mode; finalize_it: RETiRet; } rsRetVal rsgcrySetAlgo(gcryctx ctx, uchar *algoname) { int algo; DEFiRet; algo = rsgcryAlgoname2Algo((char *)algoname); if (algo == GCRY_CIPHER_NONE) { ABORT_FINALIZE(RS_RET_CRY_INVLD_ALGO); } ctx->algo = algo; finalize_it: RETiRet; } /* We use random numbers to initiate the IV. Rsyslog runtime will ensure * we get a sufficiently large number. */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif static rsRetVal #if defined(__clang__) __attribute__((no_sanitize("shift"))) /* IV shift causes known overflow */ #endif seedIV(gcryfile gf, uchar **iv) { long rndnum = 0; /* keep compiler happy -- this value is always overriden */ DEFiRet; CHKmalloc(*iv = calloc(1, gf->blkLength)); for (size_t i = 0; i < gf->blkLength; ++i) { const int shift = (i % 4) * 8; if (shift == 0) { /* need new random data? */ rndnum = randomNumber(); } (*iv)[i] = 0xff & ((rndnum & (255u << shift)) >> shift); } finalize_it: RETiRet; } static rsRetVal readIV(gcryfile gf, uchar **iv) { rsRetVal localRet; DEFiRet; if (gf->fd == -1) { while (gf->fd == -1) { localRet = eiOpenRead(gf); if (localRet == RS_RET_EI_NO_EXISTS) { /* wait until it is created */ srSleep(0, 10000); } else { CHKiRet(localRet); } } CHKiRet(eiCheckFiletype(gf)); } *iv = malloc(gf->blkLength); /* do NOT zero-out! */ iRet = eiGetIV(gf, *iv, (size_t)gf->blkLength); finalize_it: RETiRet; } /* this tries to read the END record. HOWEVER, no such record may be * present, which is the case if we handle a currently-written to queue * file. On the other hand, the queue file may contain multiple blocks. So * what we do is try to see if there is a block end or not - and set the * status accordingly. Note that once we found no end-of-block, we will never * retry. This is because that case can never happen under current queue * implementations. -- gerhards, 2013-05-16 */ static rsRetVal readBlkEnd(gcryfile gf) { off64_t blkEnd; DEFiRet; iRet = eiGetEND(gf, &blkEnd); if (iRet == RS_RET_OK) { gf->bytesToBlkEnd = (ssize_t)blkEnd; } else if (iRet == RS_RET_NO_DATA) { gf->bytesToBlkEnd = -1; } else { FINALIZE; } finalize_it: RETiRet; } /* Read the block begin metadata and set our state variables accordingly. Can also * be used to init the first block in write case. */ static rsRetVal rsgcryBlkBegin(gcryfile gf) { gcry_error_t gcryError; uchar *iv = NULL; DEFiRet; const char openMode = gf->openMode; gcryError = gcry_cipher_open(&gf->chd, gf->ctx->algo, gf->ctx->mode, 0); if (gcryError) { DBGPRINTF("gcry_cipher_open failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); ABORT_FINALIZE(RS_RET_ERR); } gcryError = gcry_cipher_setkey(gf->chd, gf->ctx->key, gf->ctx->keyLen); if (gcryError) { DBGPRINTF("gcry_cipher_setkey failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); ABORT_FINALIZE(RS_RET_ERR); } if (openMode == 'r') { readIV(gf, &iv); readBlkEnd(gf); } else { CHKiRet(seedIV(gf, &iv)); } gcryError = gcry_cipher_setiv(gf->chd, iv, gf->blkLength); if (gcryError) { DBGPRINTF("gcry_cipher_setiv failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); ABORT_FINALIZE(RS_RET_ERR); } if (openMode == 'w') { CHKiRet(eiOpenAppend(gf)); CHKiRet(eiWriteIV(gf, iv)); } finalize_it: free(iv); RETiRet; } rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname, char openMode) { gcryfile gf = NULL; DEFiRet; CHKiRet(gcryfileConstruct(ctx, &gf, fname)); gf->openMode = openMode; gf->blkLength = gcry_cipher_get_algo_blklen(ctx->algo); CHKiRet(rsgcryBlkBegin(gf)); *pgf = gf; finalize_it: if (iRet != RS_RET_OK && gf != NULL) gcryfileDestruct(gf, -1); RETiRet; } rsRetVal rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len) { int gcryError; DEFiRet; if (*len == 0) FINALIZE; addPadding(pF, buf, len); gcryError = gcry_cipher_encrypt(pF->chd, buf, *len, NULL, 0); if (gcryError) { dbgprintf("gcry_cipher_encrypt failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: RETiRet; } /* test-read END record; if present, store offset, else unbounded (current active block) * when decrypting, check if bound is reached. If yes, split into two blocks, get new IV for * second one. */ rsRetVal rsgcryDecrypt(gcryfile pF, uchar *buf, size_t *len) { gcry_error_t gcryError; DEFiRet; if (pF->bytesToBlkEnd != -1) pF->bytesToBlkEnd -= *len; gcryError = gcry_cipher_decrypt(pF->chd, buf, *len, NULL, 0); if (gcryError) { DBGPRINTF("gcry_cipher_decrypt failed: %s/%s\n", gcry_strsource(gcryError), gcry_strerror(gcryError)); ABORT_FINALIZE(RS_RET_ERR); } removePadding(buf, len); finalize_it: RETiRet; } /* module-init dummy for potential later use */ int rsgcryInit(void) { return 0; } /* module-deinit dummy for potential later use */ void rsgcryExit(void) { return; } rsyslog-8.2512.0/runtime/PaxHeaders/netstrm.h0000644000000000000000000000013215055605325016067 xustar0030 mtime=1756826325.649800683 30 atime=1764931008.697156076 30 ctime=1764935923.354579199 rsyslog-8.2512.0/runtime/netstrm.h0000664000175000017500000001401515055605325015534 0ustar00rgerrger/* Definitions for the stream-based netstrmworking class. * * Copyright 2007-2020 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_NETSTRM_H #define INCLUDED_NETSTRM_H #include "tcpsrv.h" #include "netstrms.h" /* the netstrm object */ struct netstrm_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pDrvrData; /**< the driver's data elements (at most other places, this is called pNsd) */ nsd_if_t Drvr; /**< our stream driver */ uchar *pszDrvrAuthMode; /**< auth mode of the stream driver to use */ void *pUsr; /**< pointer to user-provided data structure */ netstrms_t *pNS; /**< pointer to our netstream subsystem object */ }; /* interface */ BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(netstrm_t **ppThis); rsRetVal (*ConstructFinalize)(netstrm_t *pThis); rsRetVal (*Destruct)(netstrm_t **ppThis); rsRetVal (*AbortDestruct)(netstrm_t **ppThis); rsRetVal (*AcceptConnReq)(netstrm_t *pThis, netstrm_t **ppNew, char *connInfo); rsRetVal (*Rcv)(netstrm_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf, int *oserr, unsigned *nextIODirection); rsRetVal (*Send)(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf); rsRetVal (*Connect)(netstrm_t *pThis, int family, unsigned char *port, unsigned char *host, char *device); rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName); rsRetVal (*GetRemoteIP)(netstrm_t *pThis, prop_t **ip); rsRetVal (*SetDrvrMode)(netstrm_t *pThis, int iMode); rsRetVal (*SetDrvrAuthMode)(netstrm_t *pThis, uchar *); rsRetVal (*SetDrvrPermitExpiredCerts)(netstrm_t *pThis, uchar *); rsRetVal (*SetDrvrPermPeers)(netstrm_t *pThis, permittedPeers_t *); rsRetVal (*CheckConnection)(netstrm_t *pThis); /* This is a trick mostly for plain tcp syslog */ /* the GetSock() below is a hack to make imgssapi work. In the long term, * we should migrate imgssapi to a stream driver, which will relieve us of * this problem. Please note that nobody else should use GetSock(). Using it * will also tie the caller to nsd_ptcp, because other drivers may not support * it at all. Once the imgssapi problem is solved, GetSock should be removed from * this interface. -- rgerhards, 2008-05-05 */ rsRetVal (*GetSock)(netstrm_t *pThis, int *pSock); rsRetVal (*GetRemAddr)(netstrm_t *pThis, struct sockaddr_storage **ppAddr); /* getRemAddr() is an aid needed by the legacy ACL system. It exposes the remote * peer's socket addr structure, so that the legacy matching functions can work on * it. Note that this ties netstream drivers to things that can be implemented over * sockets - not really desirable, but not the end of the world... */ /* v4 */ rsRetVal (*EnableKeepAlive)(netstrm_t *pThis); /* v7 */ rsRetVal (*SetKeepAliveProbes)(netstrm_t *pThis, int keepAliveProbes); rsRetVal (*SetKeepAliveTime)(netstrm_t *pThis, int keepAliveTime); rsRetVal (*SetKeepAliveIntvl)(netstrm_t *pThis, int keepAliveIntvl); rsRetVal (*SetGnutlsPriorityString)(netstrm_t *pThis, uchar *priorityString); /* v11 -- Parameter pszLstnFileName added to LstnInit*/ rsRetVal(ATTR_NONNULL(1, 3, 5) * LstnInit)(netstrms_t * pNS, void *pUsr, rsRetVal (*)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params); /* v12 -- two new binary flags added to gtls driver enabling stricter operation */ rsRetVal (*SetDrvrCheckExtendedKeyUsage)(netstrm_t *pThis, int ChkExtendedKeyUsage); rsRetVal (*SetDrvrPrioritizeSAN)(netstrm_t *pThis, int prioritizeSan); /* v14 -- Tls functions */ rsRetVal (*SetDrvrTlsVerifyDepth)(netstrm_t *pThis, int verifyDepth); /* v15 -- Tls cert functions */ rsRetVal (*SetDrvrTlsCAFile)(netstrm_t *pThis, const uchar *file); rsRetVal (*SetDrvrTlsCRLFile)(netstrm_t *pThis, const uchar *file); rsRetVal (*SetDrvrTlsKeyFile)(netstrm_t *pThis, const uchar *file); rsRetVal (*SetDrvrTlsCertFile)(netstrm_t *pThis, const uchar *file); ENDinterface(netstrm) #define netstrmCURR_IF_VERSION 17 /* increment whenever you change the interface structure! */ /* interface version 3 added GetRemAddr() * interface version 4 added EnableKeepAlive() -- rgerhards, 2009-06-02 * interface version 5 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06 * interface version 6 changed signature of GetRemoteIP() -- rgerhards, 2013-01-21 * interface version 7 added KeepAlive parameter set functions * interface version 8 changed signature of Connect() -- dsa, 2016-11-14 * interface version 9 added SetGnutlsPriorityString -- PascalWithopf, 2017-08-08 * interface version 10 added oserr parameter to Rcv() -- rgerhards, 2017-09-04 * interface version 16 CRL file -- Oracle, 2022-01-16 * interface version 17 added nextIODirection parameter to Rcv() -- rgehards, 2025-04-17 * */ /* prototypes */ PROTOTYPEObj(netstrm); /* the name of our library binary */ #define LM_NETSTRM_FILENAME LM_NETSTRMS_FILENAME #endif /* #ifndef INCLUDED_NETSTRM_H */ rsyslog-8.2512.0/runtime/PaxHeaders/im-helper.h0000644000000000000000000000013215055605325016255 xustar0030 mtime=1756826325.645800623 30 atime=1764931023.942408677 30 ctime=1764935923.118575586 rsyslog-8.2512.0/runtime/im-helper.h0000664000175000017500000000435315055605325015726 0ustar00rgerrger/* im-helper.h * This file contains helper constructs that save time writing input modules. It * assumes some common field names and plumbing. It is intended to be used together * with module-template.h * * File begun on 2011-05-04 by RGerhards * * Copyright 2011-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef IM_HELPER_H_INCLUDED #define IM_HELPER_H_INCLUDED 1 /* The following function provides a complete implementation to check a * ruleset and set the actual ruleset pointer. The macro assumes that * standard field names are used. A functon std_checkRuleset_genErrMsg() * must be defined to generate error messages in case the ruleset cannot * be found. */ static inline void std_checkRuleset_genErrMsg(modConfData_t *modConf, instanceConf_t *inst); static inline rsRetVal std_checkRuleset(modConfData_t *modConf, instanceConf_t *inst) { ruleset_t *pRuleset; rsRetVal localRet; DEFiRet; inst->pBindRuleset = NULL; /* assume default ruleset */ if (inst->pszBindRuleset == NULL) FINALIZE; localRet = ruleset.GetRuleset(modConf->pConf, &pRuleset, inst->pszBindRuleset); if (localRet == RS_RET_NOT_FOUND) { std_checkRuleset_genErrMsg(modConf, inst); } CHKiRet(localRet); inst->pBindRuleset = pRuleset; finalize_it: RETiRet; } #endif /* #ifndef IM_HELPER_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/prop.h0000644000000000000000000000013215071746523015357 xustar0030 mtime=1760021843.868421459 30 atime=1764930980.021678239 30 ctime=1764935923.266577851 rsyslog-8.2512.0/runtime/prop.h0000664000175000017500000000612215071746523015024 0ustar00rgerrger/* The prop object. * * This implements props within rsyslog. * * Copyright 2009-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_PROP_H #define INCLUDED_PROP_H #include "atomic.h" /* the prop object */ struct prop_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ int iRefCount; /* reference counter */ union { uchar *psz; /* stored string */ uchar sz[CONF_PROP_BUFSIZE]; } szVal; int len; /* we use int intentionally, otherwise we may get some troubles... */ DEF_ATOMIC_HELPER_MUT(mutRefCount); }; /* interfaces */ BEGINinterface(prop) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(prop); rsRetVal (*Construct)(prop_t **ppThis); rsRetVal (*ConstructFinalize)(prop_t *pThis); rsRetVal (*Destruct)(prop_t **ppThis); rsRetVal (*SetString)(prop_t *pThis, const uchar *psz, const int len); rsRetVal (*GetString)(prop_t *pThis, uchar **ppsz, int *plen); int (*GetStringLen)(prop_t *pThis); rsRetVal (*AddRef)(prop_t *pThis); rsRetVal (*CreateStringProp)(prop_t **ppThis, const uchar *psz, const int len); rsRetVal (*CreateOrReuseStringProp)(prop_t **ppThis, const uchar *psz, const int len); ENDinterface(prop) #define propCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */ /* get classic c-style string */ /* Note: I know that "static inline" is not the right thing from a C99 * PoV, but some environments treat, even in C99 mode, compile * non-static inline into the source even if not defined as "extern". This * obviously results in linker errors. Using "static inline" as below together * with "__attribute__((unused))" works in all cases. Note also that we * cannot work around this as we would otherwise need to evaluate * pThis more than once. */ static inline uchar *__attribute__((unused)) ATTR_NONNULL(1) propGetSzStr(prop_t *pThis) { return (pThis->len < CONF_PROP_BUFSIZE) ? pThis->szVal.sz : pThis->szVal.psz; } static inline const char *__attribute__((unused)) propGetSzStrOrDefault(prop_t *pThis, const char *dflt) { return (pThis != NULL) ? (const char *)propGetSzStr(pThis) : dflt; } static inline const char *__attribute__((unused)) szStrOrDefault(const uchar *psz, const char *dflt) { return (psz != NULL) ? (const char *)psz : dflt; } /* prototypes */ PROTOTYPEObj(prop); #endif /* #ifndef INCLUDED_PROP_H */ rsyslog-8.2512.0/runtime/PaxHeaders/operatingstate.c0000644000000000000000000000013215055605325017417 xustar0030 mtime=1756826325.650800698 30 atime=1764930988.384817973 30 ctime=1764935923.195576764 rsyslog-8.2512.0/runtime/operatingstate.c0000664000175000017500000001273715055605325017075 0ustar00rgerrger/* OperatingStateFile Handler. * * Copyright 2018 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "errmsg.h" #include "operatingstate.h" #include "rsconf.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif #ifndef HAVE_LSEEK64 #define lseek64(fd, offset, whence) lseek(fd, offset, whence) #endif /* some important standard states */ #define STATE_INITIALIZING "INITIALIZING" #define STATE_CLEAN_CLOSE "CLEAN CLOSE" static int fd_osf = -1; /* check if old osf points to a problem and, if so, report */ static void osf_checkOnStartup(void) { int do_rename = 1; const char *fn_osf = (const char *)glblGetOperatingStateFile(loadConf); char iobuf[sizeof(STATE_CLEAN_CLOSE)]; const int len_clean_close = sizeof(STATE_CLEAN_CLOSE) - 1; assert(fn_osf != NULL); const int fd = open(fn_osf, O_RDONLY | O_LARGEFILE | O_CLOEXEC, 0); if (fd == -1) { if (errno != ENOENT) { LogError(errno, RS_RET_ERR, "error opening existing operatingStateFile '%s' - " "this may be an indication of a problem; ignoring", fn_osf); } do_rename = 0; goto done; } assert(fd != -1); int offs = lseek64(fd, -(len_clean_close + 1), SEEK_END); if (offs == -1) { LogError(errno, RS_RET_IO_ERROR, "error seeking to end of existing operatingStateFile " "'%s' - this may be an indication of a problem, e.g. empty file", fn_osf); goto done; } int rd = read(fd, iobuf, len_clean_close); if (rd == -1) { LogError(errno, RS_RET_IO_ERROR, "error reading existing operatingStateFile " "'%s' - this probably indicates an improper shutdown", fn_osf); goto done; } else { assert(rd <= len_clean_close); iobuf[rd] = '\0'; if (rd != len_clean_close || strcmp(iobuf, STATE_CLEAN_CLOSE) != 0) { LogError(errno, RS_RET_IO_ERROR, "existing operatingStateFile '%s' does not end " "with '%s, instead it has '%s' - this probably indicates an " "improper shutdown", fn_osf, STATE_CLEAN_CLOSE, iobuf); goto done; } } /* all ok! */ do_rename = 0; done: if (fd != -1) { close(fd); } if (do_rename) { char newname[MAXFNAME]; snprintf(newname, sizeof(newname) - 1, "%s.previous", fn_osf); newname[MAXFNAME - 1] = '\0'; if (rename(fn_osf, newname) != 0) { LogError(errno, RS_RET_IO_ERROR, "could not rename existing operatingStateFile " "'%s' to '%s' - ignored, but will probably be overwritten now", fn_osf, newname); } else { LogMsg(errno, RS_RET_OK, LOG_INFO, "existing state file '%s' renamed " "to '%s' - you may want to review it", fn_osf, newname); } } return; } void osf_open(void) { assert(fd_osf == -1); const char *fn_osf = (const char *)glblGetOperatingStateFile(loadConf); assert(fn_osf != NULL); osf_checkOnStartup(); fd_osf = open(fn_osf, O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd_osf == -1) { LogError(errno, RS_RET_ERR, "error opening operatingStateFile '%s' for write - " "ignoring it", fn_osf); goto done; } assert(fd_osf != -1); osf_write(OSF_TAG_STATE, STATE_INITIALIZING " " VERSION); done: return; } void ATTR_NONNULL() osf_write(const char *const tag, const char *const line) { char buf[1024]; /* intentionally small */ time_t tt; ssize_t wr; size_t len; struct tm tm; DBGPRINTF("osf: %s %s: ", tag, line); /* ensure everything is inside the debug log */ if (fd_osf == -1) return; time(&tt); localtime_r(&tt, &tm); len = snprintf(buf, sizeof(buf) - 1, "%d%2.2d%2.2d-%2.2d%2.2d%2.2d: %-5.5s %s\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tag, line); if (len > sizeof(buf) - 1) { len = sizeof(buf) - 1; /* overflow, truncate */ } wr = write(fd_osf, buf, len); // TODO: handle EINTR if (wr != (ssize_t)len) { LogError(errno, RS_RET_IO_ERROR, "error writing operating state file - line lost"); } } void osf_close(void) { if (fd_osf == -1) return; osf_write(OSF_TAG_STATE, STATE_CLEAN_CLOSE); close(fd_osf); } rsyslog-8.2512.0/runtime/PaxHeaders/timezones.c0000644000000000000000000000013215055605325016403 xustar0030 mtime=1756826325.654800759 30 atime=1764931002.251048975 30 ctime=1764935923.319578663 rsyslog-8.2512.0/runtime/timezones.c0000664000175000017500000001402715055605325016053 0ustar00rgerrger/* timezones.c * Support for timezones in RainerScript. * * Copyright 2022 Attila Lakatos and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include "rsyslog.h" #include "unicode-helper.h" #include "errmsg.h" #include "parserif.h" #include "rainerscript.h" #include "srUtils.h" #include "rsconf.h" static struct cnfparamdescr timezonecnfparamdescr[] = {{"id", eCmdHdlrString, CNFPARAM_REQUIRED}, {"offset", eCmdHdlrGetWord, CNFPARAM_REQUIRED}}; static struct cnfparamblk timezonepblk = { CNFPARAMBLK_VERSION, sizeof(timezonecnfparamdescr) / sizeof(struct cnfparamdescr), timezonecnfparamdescr}; /* Note: this function is NOT thread-safe! * This is currently not needed as used only during * initialization. */ static rsRetVal addTimezoneInfo(rsconf_t *cnf, uchar *tzid, char offsMode, int8_t offsHour, int8_t offsMin) { DEFiRet; tzinfo_t *newti; CHKmalloc(newti = realloc(cnf->timezones.tzinfos, (cnf->timezones.ntzinfos + 1) * sizeof(tzinfo_t))); if ((newti[cnf->timezones.ntzinfos].id = strdup((char *)tzid)) == NULL) { free(newti); DBGPRINTF("addTimezoneInfo: strdup failed with OOM\n"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } newti[cnf->timezones.ntzinfos].offsMode = offsMode; newti[cnf->timezones.ntzinfos].offsHour = offsHour; newti[cnf->timezones.ntzinfos].offsMin = offsMin; ++cnf->timezones.ntzinfos, cnf->timezones.tzinfos = newti; finalize_it: RETiRet; } void glblProcessTimezone(struct cnfobj *o) { struct cnfparamvals *pvals; uchar *id = NULL; uchar *offset = NULL; char offsMode; int8_t offsHour; int8_t offsMin; int i; pvals = nvlstGetParams(o->nvlst, &timezonepblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing timezone " "config parameters"); goto done; } if (Debug) { dbgprintf("timezone param blk after glblProcessTimezone:\n"); cnfparamsPrint(&timezonepblk, pvals); } for (i = 0; i < timezonepblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(timezonepblk.descr[i].name, "id")) { id = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(timezonepblk.descr[i].name, "offset")) { offset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf( "glblProcessTimezone: program error, non-handled " "param '%s'\n", timezonepblk.descr[i].name); } } /* note: the following two checks for NULL are not strictly necessary * as these are required parameters for the config block. But we keep * them to make the clang static analyzer happy, which also helps * guard against logic errors. */ if (offset == NULL) { parser_errmsg("offset parameter missing (logic error?), timezone config ignored"); goto done; } if (id == NULL) { parser_errmsg("id parameter missing (logic error?), timezone config ignored"); goto done; } if (strlen((char *)offset) != 6 || !(offset[0] == '-' || offset[0] == '+') || !(isdigit(offset[1]) && isdigit(offset[2])) || offset[3] != ':' || !(isdigit(offset[4]) && isdigit(offset[5]))) { parser_errmsg("timezone offset has invalid format. Must be +/-hh:mm, e.g. \"-07:00\"."); goto done; } offsHour = (offset[1] - '0') * 10 + offset[2] - '0'; offsMin = (offset[4] - '0') * 10 + offset[5] - '0'; offsMode = offset[0]; if (offsHour > 12 || offsMin > 59) { parser_errmsg("timezone offset outside of supported range (hours 0..12, minutes 0..59)"); goto done; } addTimezoneInfo(loadConf, id, offsMode, offsHour, offsMin); done: cnfparamvalsDestruct(pvals, &timezonepblk); free(id); free(offset); } /* comparison function for qsort() and string array compare * this is for the string lookup table type */ static int qs_arrcmp_tzinfo(const void *s1, const void *s2) { return strcmp(((tzinfo_t *)s1)->id, ((tzinfo_t *)s2)->id); } void sortTimezones(rsconf_t *cnf) { if (cnf->timezones.ntzinfos > 0) { qsort(cnf->timezones.tzinfos, cnf->timezones.ntzinfos, sizeof(tzinfo_t), qs_arrcmp_tzinfo); } } void displayTimezones(rsconf_t *cnf) { if (!Debug) return; for (int i = 0; i < cnf->timezones.ntzinfos; ++i) dbgprintf("tzinfo: '%s':%c%2.2d:%2.2d\n", cnf->timezones.tzinfos[i].id, cnf->timezones.tzinfos[i].offsMode, cnf->timezones.tzinfos[i].offsHour, cnf->timezones.tzinfos[i].offsMin); } static int bs_arrcmp_tzinfo(const void *s1, const void *s2) { return strcmp((char *)s1, (char *)((tzinfo_t *)s2)->id); } /* returns matching timezone info or NULL if no entry exists */ tzinfo_t *glblFindTimezone(rsconf_t *cnf, char *id) { return (tzinfo_t *)bsearch(id, cnf->timezones.tzinfos, cnf->timezones.ntzinfos, sizeof(tzinfo_t), bs_arrcmp_tzinfo); } static void freeTimezone(tzinfo_t *tzinfo) { free(tzinfo->id); } void freeTimezones(rsconf_t *cnf) { for (int i = 0; i < cnf->timezones.ntzinfos; ++i) freeTimezone(&cnf->timezones.tzinfos[i]); if (cnf->timezones.ntzinfos > 0) free(cnf->timezones.tzinfos); cnf->timezones.tzinfos = NULL; } rsyslog-8.2512.0/runtime/PaxHeaders/lib_ksi_queue.h0000644000000000000000000000013215055605325017213 xustar0030 mtime=1756826325.645800623 30 atime=1764931131.107158841 30 ctime=1764935923.398579872 rsyslog-8.2512.0/runtime/lib_ksi_queue.h0000664000175000017500000000325615055605325016665 0ustar00rgerrger#ifndef INCLUDED_LIBRSKSI_QUEUE_H #define INCLUDED_LIBRSKSI_QUEUE_H #include #include #include #define RB_GROW_FACTOR 2 typedef struct RingBuffer_st { void** buffer; size_t size; size_t count; size_t head; size_t tail; } RingBuffer; RingBuffer* RingBuffer_new(size_t size); void RingBuffer_free(RingBuffer* this); bool RingBuffer_pushBack(RingBuffer* this, void* item); bool RingBuffer_popFront(RingBuffer* this, void** item); bool RingBuffer_peekFront(RingBuffer* this, void** item); bool RingBuffer_getItem(RingBuffer* this, size_t index, void** item); size_t RingBuffer_count(RingBuffer* this); typedef struct ProtectedQueue_st { bool bStop; RingBuffer* workItems; pthread_mutex_t mutex; pthread_cond_t condition; } ProtectedQueue; ProtectedQueue* ProtectedQueue_new(size_t queueSize); void ProtectedQueue_free(ProtectedQueue* this); void ProtectedQueue_stop(ProtectedQueue* this); bool ProtectedQueue_addItem(ProtectedQueue* this, void* item); bool ProtectedQueue_peekFront(ProtectedQueue* this, void** item); bool ProtectedQueue_popFront(ProtectedQueue* this, void** item); size_t ProtectedQueue_popFrontBatch(ProtectedQueue* this, void** items, size_t bufSize); int ProtectedQueue_waitForItem(ProtectedQueue* this, void** item, uint64_t timeout); size_t ProtectedQueue_count(ProtectedQueue* this); bool ProtectedQueue_getItem(ProtectedQueue* this, size_t index, void** item); typedef struct WorkerThreadContext_st { bool (*workerFunc)(void*); bool (*timeoutFunc)(void); ProtectedQueue* queue; unsigned timeout; } WorkerThreadContext; void* worker_thread_main(void* arg); #endif // INCLUDED_LIBRSKSI_QUEUE_H rsyslog-8.2512.0/runtime/PaxHeaders/glbl.h0000644000000000000000000000013115071746523015316 xustar0029 mtime=1760021843.86342138 30 atime=1764930980.015678139 30 ctime=1764935923.130575769 rsyslog-8.2512.0/runtime/glbl.h0000664000175000017500000001466115071746523014773 0ustar00rgerrger/* Definition of globally-accessible data items. * * This module provides access methods to items of global scope. Most often, * these globals serve as defaults to initialize local settings. Currently, * many of them are either constants or global variable references. However, * this module provides the necessary hooks to change that at any time. * * Please note that there currently is no glbl.c file as we do not yet * have any implementations. * * Copyright 2008-2024 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef GLBL_H_INCLUDED #define GLBL_H_INCLUDED #include #ifdef ENABLE_LIBLOGGING_STDLOG #include #endif #include "rainerscript.h" #include "prop.h" #define glblGetIOBufSize() 4096 /* size of the IO buffer, e.g. for strm class */ #define glblOversizeMsgInputMode_Truncate 0 #define glblOversizeMsgInputMode_Split 1 #define glblOversizeMsgInputMode_Accept 2 extern pid_t glbl_ourpid; /* interfaces */ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */ uchar *(*GetWorkDir)(rsconf_t *cnf); int (*GetMaxLine)(rsconf_t *cnf); #define SIMP_PROP(name, dataType) \ dataType (*Get##name)(void); \ rsRetVal (*Set##name)(dataType) SIMP_PROP(OptimizeUniProc, int); SIMP_PROP(PreserveFQDN, int); SIMP_PROP(LocalFQDNName, uchar *); SIMP_PROP(mainqCnfObj, struct cnfobj *); SIMP_PROP(LocalHostName, uchar *); SIMP_PROP(LocalDomain, uchar *); /* added v3, 2009-06-30 */ rsRetVal (*GenerateLocalHostNameProperty)(void); prop_t *(*GetLocalHostNameProp)(void); /* added v4, 2009-07-20 */ int (*GetGlobalInputTermState)(void); void (*SetGlobalInputTermination)(void); /* added v5, 2009-11-03 */ /* note: v4, v5 are already used by more recent versions, so we need to skip them! */ /* added v6, 2009-11-16 as part of varmojfekoj's "unlimited select()" patch * Note that it must be always present, otherwise the interface would have different * versions depending on compile settings, what is not acceptable. * Use this property with care, it is only truly available if UNLIMITED_SELECT is enabled * (I did not yet further investigate the details, because that code hopefully can be removed * at some later stage). */ SIMP_PROP(FdSetSize, int); /* v7: was neeeded to mean v5+v6 - do NOT add anything else for that version! */ /* next change is v9! */ /* v8 - 2012-03-21 */ prop_t *(*GetLocalHostIP)(void); uchar *(*GetSourceIPofLocalClient)(void); /* [ar] */ rsRetVal (*SetSourceIPofLocalClient)(uchar *); /* [ar] */ /* v9 - 2015-01-12 SetMaxLine method removed */ /* v10 - global variables should be moved to the rsconf_t data structure, so * dynamic configuration reload can be introduced. This is why each getter needs additional * parameter specifying a configuration it belongs to(either loadConf or runConf) */ #undef SIMP_PROP #define SIMP_PROP(name, dataType) \ dataType (*Get##name)(rsconf_t * cnf); \ rsRetVal (*Set##name)(dataType) SIMP_PROP(DropMalPTRMsgs, int); SIMP_PROP(DfltNetstrmDrvrCAF, uchar *); SIMP_PROP(DfltNetstrmDrvrCRLF, uchar *); SIMP_PROP(DfltNetstrmDrvrCertFile, uchar *); SIMP_PROP(DfltNetstrmDrvrKeyFile, uchar *); SIMP_PROP(DfltNetstrmDrvr, uchar *); SIMP_PROP(DfltOpensslEngine, uchar *); SIMP_PROP(DefPFFamily, int); SIMP_PROP(DisableDNS, int); SIMP_PROP(NetstrmDrvrCAExtraFiles, uchar *); SIMP_PROP(ParserControlCharacterEscapePrefix, uchar); SIMP_PROP(ParserDropTrailingLFOnReception, int); SIMP_PROP(ParserEscapeControlCharactersOnReceive, int); SIMP_PROP(ParserSpaceLFOnReceive, int); SIMP_PROP(ParserEscape8BitCharactersOnReceive, int); SIMP_PROP(ParserEscapeControlCharacterTab, int); SIMP_PROP(ParserEscapeControlCharactersCStyle, int); SIMP_PROP(ParseHOSTNAMEandTAG, int); SIMP_PROP(OptionDisallowWarning, int); #undef SIMP_PROP ENDinterface(glbl) #define glblCURR_IF_VERSION 10 /* increment whenever you change the interface structure! */ /* version 2 had PreserveFQDN added - rgerhards, 2008-12-08 */ /* the remaining prototypes */ PROTOTYPEObj(glbl); extern int glblJsonFormatOpt; extern int glblUnloadModules; extern short janitorInterval; extern char **glblDbgFiles; extern size_t glblDbgFilesNum; extern int glblDbgWhitelist; extern int glblPermitCtlC; extern int glblAbortOnProgramError; extern int bTerminateInputs; #ifndef HAVE_ATOMIC_BUILTINS extern DEF_ATOMIC_HELPER_MUT(mutTerminateInputs); #endif /* Developer options enable some strange things for developer-only testing. * These should never be enabled in a user build, except if explicitly told * by a developer. The options are acutally flags, so they should be powers * of two. Flag assignment may change between versions, **backward * compatibility is NOT necessary**. * rgerhards, 2018-04-28 */ #define DEV_OPTION_KEEP_RUNNING_ON_HARD_CONF_ERROR 1 #define DEV_OPTION_8_1905_HANG_TEST 2 // TODO: remove - temporary for bughunt #define glblGetOurPid() glbl_ourpid #define glblSetOurPid(pid) \ { glbl_ourpid = (pid); } void glblPrepCnf(void); void glblProcessCnf(struct cnfobj *o); void glblProcessMainQCnf(struct cnfobj *o); void glblDestructMainqCnfObj(void); rsRetVal glblDoneLoadCnf(void); const uchar *glblGetWorkDirRaw(rsconf_t *cnf); int GetGnuTLSLoglevel(rsconf_t *cnf); int glblGetMaxLine(rsconf_t *cnf); int bs_arrcmp_glblDbgFiles(const void *s1, const void *s2); uchar *glblGetOversizeMsgErrorFile(rsconf_t *cnf); const uchar *glblGetOperatingStateFile(rsconf_t *cnf); int glblGetOversizeMsgInputMode(rsconf_t *cnf); int glblReportOversizeMessage(rsconf_t *cnf); void glblReportChildProcessExit(rsconf_t *cnf, const uchar *name, pid_t pid, int status); uchar *glblGetLocalHostName(void); #endif /* #ifndef GLBL_H_INCLUDED */ rsyslog-8.2512.0/runtime/PaxHeaders/lmsig_ksi-ls12.h0000644000000000000000000000013215055605325017133 xustar0030 mtime=1756826325.647800653 30 atime=1764931131.075158325 30 ctime=1764935923.388579719 rsyslog-8.2512.0/runtime/lmsig_ksi-ls12.h0000664000175000017500000000266715055605325016612 0ustar00rgerrger/* An implementation of the sigprov interface for KSI-LS12. * * Copyright 2013-2017 Adiscon GmbH and Guardtime, Inc. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LMSIG_LS12_KSI_H #define INCLUDED_LMSIG_LS12_KSI_H #include "sigprov.h" #include "lib_ksils12.h" /* interface is defined in sigprov.h, we just implement it! */ #define lmsig_ksi_ls12CURR_IF_VERSION sigprovCURR_IF_VERSION typedef sigprov_if_t lmsig_ksi_ls12_if_t; /* the lmsig_ksi object */ struct lmsig_ksi_ls12_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ rsksictx ctx; /* librsksi context - contains all we need */ }; typedef struct lmsig_ksi_ls12_s lmsig_ksi_ls12_t; /* prototypes */ PROTOTYPEObj(lmsig_ksi_ls12); #endif /* #ifndef INCLUDED_LMSIG_LS12_KSI_H */ rsyslog-8.2512.0/runtime/PaxHeaders/hashtable.h0000644000000000000000000000013215055605325016326 xustar0030 mtime=1756826325.645800623 30 atime=1764930980.044678624 30 ctime=1764935923.299578357 rsyslog-8.2512.0/runtime/hashtable.h0000664000175000017500000001706415055605325016002 0ustar00rgerrger/* Copyright (C) 2002 Christopher Clark */ #ifndef __HASHTABLE_CWC22_H__ #define __HASHTABLE_CWC22_H__ struct hashtable; /* Example of use: * * struct hashtable *h; * struct some_key *k; * struct some_value *v; * * static unsigned int hash_from_key_fn( void *k ); * static int keys_equal_fn ( void *key1, void *key2 ); * * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn); * k = (struct some_key *) malloc(sizeof(struct some_key)); * v = (struct some_value *) malloc(sizeof(struct some_value)); * * (initialise k and v to suitable values) * * if (! hashtable_insert(h,k,v) ) * { exit(-1); } * * if (NULL == (found = hashtable_search(h,k) )) * { printf("not found!"); } * * if (NULL == (found = hashtable_remove(h,k) )) * { printf("Not found\n"); } * */ /* Macros may be used to define type-safe(r) hashtable access functions, with * methods specialized to take known key and value types as parameters. * * Example: * * Insert this at the start of your file: * * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value); * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value); * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value); * * This defines the functions 'insert_some', 'search_some' and 'remove_some'. * These operate just like hashtable_insert etc., with the same parameters, * but their function signatures have 'struct some_key *' rather than * 'void *', and hence can generate compile time errors if your program is * supplying incorrect data as a key (and similarly for value). * * Note that the hash and key equality functions passed to create_hashtable * still take 'void *' parameters instead of 'some key *'. This shouldn't be * a difficult issue as they're only defined and passed once, and the other * functions will ensure that only valid keys are supplied to them. * * The cost for this checking is increased code size and runtime overhead * - if performance is important, it may be worth switching back to the * unsafe methods once your program has been debugged with the safe methods. * This just requires switching to some simple alternative defines - eg: * #define insert_some hashtable_insert * */ /***************************************************************************** * create_hashtable * @name create_hashtable * @param minsize minimum initial size of hashtable * @param hashfunction function for hashing keys * @param key_eq_fn function for determining key equality * @param dest destructor for value entries (NULL -> use free()) * @return newly created hashtable or NULL on failure */ struct hashtable *create_hashtable(unsigned int minsize, unsigned int (*hashfunction)(void *), int (*key_eq_fn)(void *, void *), void (*dest)(void *)); /***************************************************************************** * hashtable_insert * @name hashtable_insert * @param h the hashtable to insert into * @param k the key - hashtable claims ownership and will free on removal * @param v the value - does not claim ownership * @return non-zero for successful insertion * * This function will cause the table to expand if the insertion would take * the ratio of entries to table size over the maximum load factor. * * This function does not check for repeated insertions with a duplicate key. * The value returned when using a duplicate key is undefined -- when * the hashtable changes size, the order of retrieval of duplicate key * entries is reversed. * If in doubt, remove before insert. */ int hashtable_insert(struct hashtable *h, void *k, void *v); #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \ int fnname(struct hashtable *h, keytype *k, valuetype *v) { \ return hashtable_insert(h, k, v); \ } /***************************************************************************** * hashtable_search * @name hashtable_search * @param h the hashtable to search * @param k the key to search for - does not claim ownership * @return the value associated with the key, or NULL if none found */ void *hashtable_search(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \ valuetype *fnname(struct hashtable *h, keytype *k) { \ return (valuetype *)(hashtable_search(h, k)); \ } /***************************************************************************** * hashtable_remove * @name hashtable_remove * @param h the hashtable to remove the item from * @param k the key to search for - does not claim ownership * @return the value associated with the key, or NULL if none found */ void * /* returns value */ hashtable_remove(struct hashtable *h, void *k); #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \ valuetype *fnname(struct hashtable *h, keytype *k) { \ return (valuetype *)(hashtable_remove(h, k)); \ } /***************************************************************************** * hashtable_count * @name hashtable_count * @param h the hashtable * @return the number of items stored in the hashtable */ unsigned int hashtable_count(struct hashtable *h); /***************************************************************************** * hashtable_destroy * @name hashtable_destroy * @param h the hashtable * @param free_values whether to call 'free' on the remaining values */ void hashtable_destroy(struct hashtable *h, int free_values); /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ unsigned __attribute__((nonnull(1))) int hash_from_string(void *k); int key_equals_string(void *key1, void *key2); #endif /* __HASHTABLE_CWC22_H__ */ rsyslog-8.2512.0/runtime/PaxHeaders/lmsig_ksi-ls12.c0000644000000000000000000000013215055605325017126 xustar0030 mtime=1756826325.647800653 30 atime=1764931131.065158163 30 ctime=1764935923.386579688 rsyslog-8.2512.0/runtime/lmsig_ksi-ls12.c0000664000175000017500000003256615055605325016606 0ustar00rgerrger/* lmsig_ksi-ls12.c * * An implementation of the sigprov interface for KSI-LS12. * * Copyright 2013-2017 Adiscon GmbH and Guardtime, Inc. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "sigprov.h" #include "lmsig_ksi-ls12.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfpdescr[] = { {"sig.hashfunction", eCmdHdlrGetWord, 0}, {"sig.aggregator.url", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"sig.aggregator.user", eCmdHdlrGetWord, 0}, {"sig.aggregator.key", eCmdHdlrGetWord, 0}, {"sig.aggregator.hmacAlg", eCmdHdlrGetWord, 0}, {"sig.block.levelLimit", eCmdHdlrSize, CNFPARAM_REQUIRED}, {"sig.block.timeLimit", eCmdHdlrInt, 0}, {"sig.block.signtimeout", eCmdHdlrInt, 0}, {"sig.confinterval", eCmdHdlrInt, 0}, {"sig.keeprecordhashes", eCmdHdlrBinary, 0}, {"sig.keeptreehashes", eCmdHdlrBinary, 0}, {"sig.fileformat", eCmdHdlrString, 0}, {"sig.syncmode", eCmdHdlrString, 0}, {"sig.randomsource", eCmdHdlrString, 0}, {"sig.debugfile", eCmdHdlrString, 0}, {"sig.debuglevel", eCmdHdlrInt, 0}, {"dirowner", eCmdHdlrUID, 0}, /* legacy: dirowner */ {"dirownernum", eCmdHdlrInt, 0}, /* legacy: dirownernum */ {"dirgroup", eCmdHdlrGID, 0}, /* legacy: dirgroup */ {"dirgroupnum", eCmdHdlrInt, 0}, /* legacy: dirgroupnum */ {"fileowner", eCmdHdlrUID, 0}, /* legacy: fileowner */ {"fileownernum", eCmdHdlrInt, 0}, /* legacy: fileownernum */ {"filegroup", eCmdHdlrGID, 0}, /* legacy: filegroup */ {"filegroupnum", eCmdHdlrInt, 0}, /* legacy: filegroupnum */ {"dircreatemode", eCmdHdlrFileCreateMode, 0}, /* legacy: dircreatemode */ {"filecreatemode", eCmdHdlrFileCreateMode, 0} /* legacy: filecreatemode */ }; static struct cnfparamblk pblk = {CNFPARAMBLK_VERSION, sizeof(cnfpdescr) / sizeof(struct cnfparamdescr), cnfpdescr}; static void errfunc(__attribute__((unused)) void *usrptr, uchar *emsg) { LogError(0, RS_RET_SIGPROV_ERR, "KSI Signature Provider" "Error: %s", emsg); } static void logfunc(__attribute__((unused)) void *usrptr, uchar *emsg) { LogMsg(0, RS_RET_NO_ERRCODE, LOG_INFO, "KSI/LS12 Signature Provider: %s", emsg); } /* Standard-Constructor */ BEGINobjConstruct(lmsig_ksi_ls12) pThis->ctx = rsksiCtxNew(); rsksisetErrFunc(pThis->ctx, errfunc, NULL); rsksisetLogFunc(pThis->ctx, logfunc, NULL); ENDobjConstruct(lmsig_ksi_ls12) /* destructor for the lmsig_ksi object */ BEGINobjDestruct(lmsig_ksi_ls12) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(lmsig_ksi_ls12); rsksiCtxDel(pThis->ctx); ENDobjDestruct(lmsig_ksi_ls12) #define REPORT_PARAM_MISSING(param) \ do { \ pThis->ctx->disabled = true; \ LogError(0, RS_RET_ERR, "%s missing - signing disabled", param); \ /* TODO: ABORT_FINALIZE actually is useless because the return value is not checked by the caller*/ \ ABORT_FINALIZE(RS_RET_KSI_ERR); \ } while (0) /* apply all params from param block to us. This must be called * after construction, but before the OnFileOpen() entry point. * Defaults are expected to have been set during construction. */ static rsRetVal SetCnfParam(void *pT, struct nvlst *lst) { char *ag_uri = NULL, *ag_loginid = NULL, *ag_key = NULL; char *hash = NULL, *hmac = NULL; lmsig_ksi_ls12_t *pThis = (lmsig_ksi_ls12_t *)pT; int i; uchar *cstr; struct cnfparamvals *pvals; DEFiRet; pvals = nvlstGetParams(lst, &pblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_ERR, "Failed to load configuration - signing disabled"); pThis->ctx->disabled = true; ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("sig param blk in lmsig_ksi:\n"); cnfparamsPrint(&pblk, pvals); } for (i = 0; i < pblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(pblk.descr[i].name, "sig.hashfunction")) { hash = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "sig.aggregator.url")) { ag_uri = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "sig.aggregator.user")) { ag_loginid = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "sig.aggregator.key")) { ag_key = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "sig.aggregator.hmacAlg")) { hmac = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "sig.block.levelLimit")) { if (pvals[i].val.d.n < 2) { LogError(0, RS_RET_ERR, "sig.block.levelLimit " "%llu invalid - signing disabled", pvals[i].val.d.n); pThis->ctx->disabled = true; } else { rsksiSetBlockLevelLimit(pThis->ctx, pvals[i].val.d.n); } } else if (!strcmp(pblk.descr[i].name, "sig.block.timeLimit")) { if (pvals[i].val.d.n < 0) { LogError(0, RS_RET_ERR, "sig.block.timeLimit " "%llu invalid - signing disabled", pvals[i].val.d.n); pThis->ctx->disabled = true; } else { rsksiSetBlockTimeLimit(pThis->ctx, pvals[i].val.d.n); } } else if (!strcmp(pblk.descr[i].name, "sig.confinterval")) { if (pvals[i].val.d.n < 0) { LogError(0, RS_RET_ERR, "sig.confinterval " "%llu invalid - signing disabled", pvals[i].val.d.n); pThis->ctx->disabled = true; } else { rsksiSetConfInterval(pThis->ctx, pvals[i].val.d.n); } } else if (!strcmp(pblk.descr[i].name, "sig.keeprecordhashes")) { rsksiSetKeepRecordHashes(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "sig.block.signtimeout")) { if (pvals[i].val.d.n < 0) { LogError(0, RS_RET_ERR, "sig.block.signtimeout " "%llu invalid - signing disabled", pvals[i].val.d.n); pThis->ctx->disabled = true; } else { rsksiSetBlockSigTimeout(pThis->ctx, pvals[i].val.d.n); } } else if (!strcmp(pblk.descr[i].name, "sig.keeptreehashes")) { rsksiSetKeepTreeHashes(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "sig.syncmode")) { cstr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcasecmp((char *)cstr, "sync")) rsksiSetSyncMode(pThis->ctx, LOGSIG_SYNCHRONOUS); else if (!strcasecmp((char *)cstr, "async")) rsksiSetSyncMode(pThis->ctx, LOGSIG_ASYNCHRONOUS); else LogError(0, RS_RET_ERR, "sig.syncmode '%s' unknown - using default", cstr); free(cstr); } else if (!strcmp(pblk.descr[i].name, "sig.randomsource")) { cstr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); rsksiSetRandomSource(pThis->ctx, (char *)cstr); free(cstr); } else if (!strcmp(pblk.descr[i].name, "sig.debugfile")) { cstr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); rsksiSetDebugFile(pThis->ctx, (char *)cstr); free(cstr); } else if (!strcmp(pblk.descr[i].name, "sig.debuglevel")) { rsksiSetDebugLevel(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "dirowner")) { rsksiSetDirUID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "dirownernum")) { rsksiSetDirUID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "dirgroup")) { rsksiSetDirGID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "dirgroupnum")) { rsksiSetDirGID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "fileowner")) { rsksiSetFileUID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "fileownernum")) { rsksiSetFileUID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "filegroup")) { rsksiSetFileGID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "filegroupnum")) { rsksiSetFileGID(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "dircreatemode")) { rsksiSetDirCreateMode(pThis->ctx, pvals[i].val.d.n); } else if (!strcmp(pblk.descr[i].name, "filecreatemode")) { rsksiSetCreateMode(pThis->ctx, pvals[i].val.d.n); } else { DBGPRINTF( "lmsig_ksi: program error, non-handled " "param '%s'\n", pblk.descr[i].name); } } if (rsksiSetHashFunction(pThis->ctx, hash ? hash : (char *)"default") != KSI_OK) { ABORT_FINALIZE(RS_RET_KSI_ERR); } if (rsksiSetHmacFunction(pThis->ctx, hmac ? hmac : (char *)"default") != KSI_OK) { ABORT_FINALIZE(RS_RET_KSI_ERR); } if (rsksiSetAggregator(pThis->ctx, ag_uri, ag_loginid, ag_key) != KSI_OK) { ABORT_FINALIZE(RS_RET_KSI_ERR); } finalize_it: free(ag_uri); free(ag_loginid); free(ag_key); free(hash); free(hmac); if (pvals != NULL) cnfparamvalsDestruct(pvals, &pblk); RETiRet; } static rsRetVal OnFileOpen(void *pT, uchar *fn, void *pGF) { lmsig_ksi_ls12_t *pThis = (lmsig_ksi_ls12_t *)pT; ksifile *pgf = (ksifile *)pGF; DEFiRet; /* note: if *pgf is set to NULL, this auto-disables GT functions */ *pgf = rsksiCtxOpenFile(pThis->ctx, fn); sigblkInitKSI(*pgf); RETiRet; } /* Note: we assume that the record is terminated by a \n. * As of the GuardTime paper, \n is not part of the signed * message, so we subtract one from the record size. This * may cause issues with non-standard formats, but let's * see how things evolve (the verifier will not work in * any case when the records are not \n delimited...). * rgerhards, 2013-03-17 */ static rsRetVal OnRecordWrite(void *pF, uchar *rec, rs_size_t lenRec) { DEFiRet; DBGPRINTF("lmsig_ksi-ls12: onRecordWrite (%d): %s\n", lenRec - 1, rec); sigblkAddRecordKSI(pF, rec, lenRec - 1); RETiRet; } static rsRetVal OnFileClose(void *pF) { DEFiRet; DBGPRINTF("lmsig_ksi_ls12: onFileClose\n"); rsksifileDestruct(pF); RETiRet; } BEGINobjQueryInterface(lmsig_ksi_ls12) CODESTARTobjQueryInterface(lmsig_ksi_ls12); if (pIf->ifVersion != sigprovCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } pIf->Construct = (rsRetVal(*)(void *))lmsig_ksi_ls12Construct; pIf->SetCnfParam = SetCnfParam; pIf->Destruct = (rsRetVal(*)(void *))lmsig_ksi_ls12Destruct; pIf->OnFileOpen = OnFileOpen; pIf->OnRecordWrite = OnRecordWrite; pIf->OnFileClose = OnFileClose; finalize_it: ENDobjQueryInterface(lmsig_ksi_ls12) BEGINObjClassExit(lmsig_ksi_ls12, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(lmsig_ksi_ls12); /* release objects we no longer need */ objRelease(glbl, CORE_COMPONENT); ENDObjClassExit(lmsig_ksi_ls12) BEGINObjClassInit(lmsig_ksi_ls12, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDObjClassInit(lmsig_ksi_ls12) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; lmsig_ksi_ls12ClassExit(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CHKiRet(lmsig_ksi_ls12ClassInit(pModInfo)); ENDmodInit rsyslog-8.2512.0/runtime/PaxHeaders/tcps_sess.h0000644000000000000000000000013115071746523016404 xustar0030 mtime=1760021843.877421601 30 atime=1764931008.705156208 29 ctime=1764935923.40758001 rsyslog-8.2512.0/runtime/tcps_sess.h0000664000175000017500000000762515071746523016063 0ustar00rgerrger/* Definitions for tcps_sess class. This implements a session of the * plain TCP server. * * Copyright 2008-2025 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_TCPS_SESS_H #define INCLUDED_TCPS_SESS_H #include "obj.h" #include "prop.h" /* a forward-definition, we are somewhat cyclic */ struct tcpsrv_s; /* the tcps_sess object */ struct tcps_sess_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ tcpsrv_t *pSrv; /* pointer back to my server (e.g. for callbacks) */ tcpLstnPortList_t *pLstnInfo; /* pointer back to listener info */ netstrm_t *pStrm; int iMsg; /* index of next char to store in msg */ sbool bSuppOctetFram; /**< copy from listener, to speed up access */ sbool bSPFramingFix; enum { eAtStrtFram, eInOctetCnt, eInMsg, eInMsgTruncating } inputState; /* our current state */ int iOctetsRemain; /* Number of Octets remaining in message */ TCPFRAMINGMODE eFraming; uchar *pMsg; /* message (fragment) received */ prop_t *fromHost; /* host name we received messages from */ prop_t *fromHostIP; prop_t *fromHostPort; void *pUsr; /* a user-pointer */ rsRetVal (*DoSubmitMessage)(tcps_sess_t *, uchar *, int); /* submit message callback */ int iMaxLine; /* fast lookup buffer for config property */ pthread_mutex_t mut; unsigned tlsProbeBytes; /**< number of bytes collected for TLS client detection */ uchar tlsProbeBuf[5]; /**< first bytes received for TLS client detection */ sbool tlsProbeDone; /**< indicates TLS client detection has been completed */ sbool tlsMismatchWarned; /**< avoids logging the same TLS mismatch twice */ }; /* interfaces */ BEGINinterface(tcps_sess) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(tcps_sess); rsRetVal (*Construct)(tcps_sess_t **ppThis); rsRetVal (*ConstructFinalize)(tcps_sess_t __attribute__((unused)) * pThis); rsRetVal (*Destruct)(tcps_sess_t **ppThis); rsRetVal (*PrepareClose)(tcps_sess_t *pThis); rsRetVal (*Close)(tcps_sess_t *pThis); rsRetVal (*DataRcvd)(tcps_sess_t *pThis, char *pData, size_t iLen); /* set methods */ rsRetVal (*SetTcpsrv)(tcps_sess_t *pThis, struct tcpsrv_s *pSrv); rsRetVal (*SetLstnInfo)(tcps_sess_t *pThis, tcpLstnPortList_t *pLstnInfo); rsRetVal (*SetUsrP)(tcps_sess_t *, void *); rsRetVal (*SetHost)(tcps_sess_t *pThis, uchar *); rsRetVal (*SetHostIP)(tcps_sess_t *pThis, prop_t *); rsRetVal (*SetHostPort)(tcps_sess_t *pThis, prop_t *); rsRetVal (*SetStrm)(tcps_sess_t *pThis, netstrm_t *); rsRetVal (*SetMsgIdx)(tcps_sess_t *pThis, int); rsRetVal (*SetOnMsgReceive)(tcps_sess_t *pThis, rsRetVal (*OnMsgReceive)(tcps_sess_t *, uchar *, int)); ENDinterface(tcps_sess) #define tcps_sessCURR_IF_VERSION 4 /* increment whenever you change the interface structure! */ /* interface changes * to version v2, rgerhards, 2009-05-22 * - Data structures changed * - SetLstnInfo entry point added * version 3, rgerhards, 2013-01-21: * - signature of SetHostIP() changed * version 4, 2025-01-??: * - SetHostPort() entry point added */ /* prototypes */ PROTOTYPEObj(tcps_sess); #endif /* #ifndef INCLUDED_TCPS_SESS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_mbedtls.h0000644000000000000000000000013215114522477016673 xustar0030 mtime=1764926783.041632005 30 atime=1764926783.489643004 30 ctime=1764935923.364579352 rsyslog-8.2512.0/runtime/nsd_mbedtls.h0000664000175000017500000000673315114522477016350 0ustar00rgerrger/* An implementation of the nsd interface for Mbed TLS. * * Copyright 2008-2021 Adiscon GmbH. * Copyright (C) 2023 CS Group. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NSD_MBEDTLS_H #define INCLUDED_NSD_MBEDTLS_H #include #include #include #include #include #include "nsd.h" typedef nsd_if_t nsd_mbedtls_if_t; /* we just *implement* this interface */ /* the nsd_mbedtls object */ struct nsd_mbedtls_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */ uchar *pszConnectHost; /**< hostname used for connect - may be used to authenticate peer if no other name given */ const uchar *pszCAFile; const uchar *pszCRLFile; const uchar *pszKeyFile; const uchar *pszCertFile; int iMode; /* 0 - plain tcp, 1 - TLS */ int bAbortConn; /* if set, abort conncection (fatal error had happened) */ enum { MBEDTLS_AUTH_CERTNAME = 0, MBEDTLS_AUTH_CERTFINGERPRINT = 1, MBEDTLS_AUTH_CERTVALID = 2, MBEDTLS_AUTH_CERTANON = 3 } authMode; enum { MBEDTLS_EXPIRED_PERMIT = 0, MBEDTLS_EXPIRED_DENY = 1, MBEDTLS_EXPIRED_WARN = 2, } permitExpiredCerts; enum { MBEDTLS_NONE = 0, MBEDTLS_PURPOSE = 1 } dataTypeCheck; int bHaveSess; /* true if a tls session is active */ int DrvrVerifyDepth; /* Verify Depth for certificate chains */ permittedPeers_t *pPermPeers; /* permitted peers */ int *anzCipherSuites; /* array of cipher suites (IANA ids) in decreasing priority order (0-terminated) */ int bSANpriority; /* if true, we do stricter checking (if any SAN present we do not check CN) */ int bReportAuthErr; /* only the first auth error is to be reported, this var triggers it. Initially, it is * set to 1 and changed to 0 after the first report. It is changed back to 1 after * one successful authentication. */ int sock; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; int bHaveCaCert; mbedtls_x509_crt cacert; int bHaveCrl; mbedtls_x509_crl crl; int bHaveKey; mbedtls_pk_context pkey; int bHaveCert; mbedtls_x509_crt srvcert; }; /* interface is defined in nsd.h, we just implement it! */ #define nsd_mbedtlsCURR_IF_VERSION nsdCURR_IF_VERSION /* prototypes */ PROTOTYPEObj(nsd_mbedtls); /* the name of our library binary */ #define LM_NSD_MBEDTLS_FILENAME "lmnsd_mbedtls" #endif /* #ifndef INCLUDED_NSD_MBEDTLS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/typedefs.h0000644000000000000000000000013115114522477016217 xustar0029 mtime=1764926783.04263203 30 atime=1764926784.239661412 30 ctime=1764935923.099575295 rsyslog-8.2512.0/runtime/typedefs.h0000664000175000017500000002552715114522477015677 0ustar00rgerrger/* This defines some types commonly used. Do NOT include any other * rsyslog runtime file. * * Begun 2010-11-25 RGerhards * * Copyright (C) 2005-2020 by Rainer Gerhards and Adiscon GmbH * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #ifndef INCLUDED_TYPEDEFS_H #define INCLUDED_TYPEDEFS_H #include #if defined(__FreeBSD__) || !defined(HAVE_LSEEK64) #include #endif /* some universal fixed size integer defines ... */ #ifndef _AIX typedef long long int64; #endif typedef long long unsigned uint64; typedef int64 number_t; /* type to use for numbers - TODO: maybe an autoconf option? */ typedef char intTiny; /* 0..127! */ typedef unsigned char uintTiny; /* 0..255! */ /* define some base data types */ typedef uint16_t syslog_pri_t; /* to be used for syslog PRI values */ typedef unsigned char uchar; /* get rid of the unhandy "unsigned char" */ typedef struct aUsrp_s aUsrp_t; typedef struct thrdInfo thrdInfo_t; typedef struct obj_s obj_t; typedef struct ruleset_s ruleset_t; typedef struct rule_s rule_t; typedef struct NetAddr netAddr_t; typedef struct netstrms_s netstrms_t; typedef struct netstrm_s netstrm_t; typedef struct nssel_s nssel_t; typedef enum nsdsel_waitOp_e nsdsel_waitOp_t; typedef struct net_ossl_s net_ossl_t; typedef struct nsd_ptcp_s nsd_ptcp_t; typedef struct nsd_gtls_s nsd_gtls_t; typedef struct nsd_ossl_s nsd_ossl_t; typedef struct nsd_mbedtls_s nsd_mbedtls_t; typedef struct nsd_gsspi_s nsd_gsspi_t; typedef struct nsd_nss_s nsd_nss_t; typedef struct wti_s wti_t; typedef struct msgPropDescr_s msgPropDescr_t; typedef struct msg smsg_t; typedef struct queue_s qqueue_t; typedef struct prop_s prop_t; typedef struct interface_s interface_t; typedef struct objInfo_s objInfo_t; typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */ typedef rsRetVal (*errLogFunc_t)(uchar *); /* this is a trick to store a function ptr to a function returning a function ptr... */ typedef struct permittedPeers_s permittedPeers_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ typedef struct permittedPeerWildcard_s permittedPeerWildcard_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ typedef struct tcpsrv_s tcpsrv_t; typedef struct tcps_sess_s tcps_sess_t; typedef struct strmsrv_s strmsrv_t; typedef struct strms_sess_s strms_sess_t; typedef struct vmstk_s vmstk_t; typedef struct batch_obj_s batch_obj_t; typedef struct batch_s batch_t; typedef struct wtp_s wtp_t; typedef struct modInfo_s modInfo_t; typedef struct parser_s parser_t; typedef struct parserList_s parserList_t; typedef struct strgen_s strgen_t; typedef struct strgenList_s strgenList_t; typedef struct statsobj_s statsobj_t; typedef void (*statsobj_read_notifier_t)(statsobj_t *, void *); // typedef struct nsd_epworkset_s nsd_epworkset_t; // TODO: REMOVE typedef struct tcpsrv_io_descr_s tcpsrv_io_descr_t; // i/o descriptor used for tcpsrv network i/o typedef struct templates_s templates_t; typedef struct parsers_s parsers_t; typedef struct queuecnf_s queuecnf_t; typedef struct parsercnf_s parsercnf_t; typedef struct rulesets_s rulesets_t; typedef struct globals_s globals_t; typedef struct defaults_s defaults_t; typedef struct actions_s actions_t; typedef struct timezones_s timezones_t; typedef struct rsconf_s rsconf_t; typedef struct cfgmodules_s cfgmodules_t; typedef struct cfgmodules_etry_s cfgmodules_etry_t; typedef struct outchannels_s outchannels_t; typedef struct modConfData_s modConfData_t; typedef struct instanceConf_s instanceConf_t; typedef struct ratelimit_s ratelimit_t; typedef struct lookup_string_tab_entry_s lookup_string_tab_entry_t; typedef struct lookup_string_tab_s lookup_string_tab_t; typedef struct lookup_array_tab_s lookup_array_tab_t; typedef struct lookup_sparseArray_tab_s lookup_sparseArray_tab_t; typedef struct lookup_sparseArray_tab_entry_s lookup_sparseArray_tab_entry_t; typedef struct lookup_regex_tab_entry_s lookup_regex_tab_entry_t; typedef struct lookup_tables_s lookup_tables_t; typedef struct lookup_regex_tab_s lookup_regex_tab_t; typedef union lookup_key_u lookup_key_t; typedef struct lookup_s lookup_t; typedef struct lookup_ref_s lookup_ref_t; typedef struct action_s action_t; typedef int rs_size_t; /* we do never need more than 2Gig strings, signed permits to * use -1 as a special flag. */ typedef rsRetVal (*prsf_t)(struct vmstk_s *, int); /* pointer to a RainerScript function */ typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */ typedef struct tcpLstnParams_s tcpLstnParams_t; typedef struct tcpLstnPortList_s tcpLstnPortList_t; // TODO: rename? typedef struct strmLstnPortList_s strmLstnPortList_t; // TODO: rename? typedef struct actWrkrIParams actWrkrIParams_t; typedef struct dynstats_bucket_s dynstats_bucket_t; typedef struct dynstats_buckets_s dynstats_buckets_t; typedef struct perctile_buckets_s perctile_buckets_t; typedef struct dynstats_ctr_s dynstats_ctr_t; /* under Solaris (actually only SPARC), we need to redefine some types * to be void, so that we get void* pointers. Otherwise, we will see * alignment errors. */ #ifdef OS_SOLARIS typedef void *obj_t_ptr; typedef void nsd_t; #else typedef obj_t *obj_t_ptr; typedef obj_t nsd_t; #endif #ifdef __hpux typedef unsigned int u_int32_t; /* TODO: is this correct? */ typedef int socklen_t; #endif typedef struct epoll_event epoll_event_t; typedef signed char sbool; /* (small bool) I intentionally use char, to keep it slim so that many fit into the CPU cache! */ /* settings for flow control * TODO: is there a better place for them? -- rgerhards, 2008-03-14 */ typedef enum { eFLOWCTL_NO_DELAY = 0, /**< UDP and other non-delayable sources */ eFLOWCTL_LIGHT_DELAY = 1, /**< some light delay possible, but no extended period of time */ eFLOWCTL_FULL_DELAY = 2 /**< delay possible for extended period of time */ } flowControl_t; /* filter operations */ typedef enum { FIOP_NOP = 0, /* do not use - No Operation */ FIOP_CONTAINS = 1, /* contains string? */ FIOP_ISEQUAL = 2, /* is (exactly) equal? */ FIOP_STARTSWITH = 3, /* starts with a string? */ FIOP_ENDSWITH = 4, /* ends with a string? */ FIOP_REGEX = 5, /* matches a (BRE) regular expression? */ FIOP_EREREGEX = 6, /* matches a ERE regular expression? */ FIOP_ISEMPTY = 7 /* string empty <=> strlen(s) == 0 ?*/ } fiop_t; #ifndef HAVE_LSEEK64 #ifndef HAVE_OFF64_T typedef off_t off64_t; #endif #endif /* properties are now encoded as (tiny) integers. I do not use an enum as I would like * to keep the memory footprint small (and thus cache hits high). * rgerhards, 2009-06-26 */ typedef uintTiny propid_t; #define PROP_INVALID 0 #define PROP_MSG 1 #define PROP_TIMESTAMP 2 #define PROP_HOSTNAME 3 #define PROP_SYSLOGTAG 4 #define PROP_RAWMSG 5 #define PROP_INPUTNAME 6 #define PROP_FROMHOST 7 #define PROP_FROMHOST_IP 8 #define PROP_PRI 9 #define PROP_PRI_TEXT 10 #define PROP_IUT 11 #define PROP_SYSLOGFACILITY 12 #define PROP_SYSLOGFACILITY_TEXT 13 #define PROP_SYSLOGSEVERITY 14 #define PROP_SYSLOGSEVERITY_TEXT 15 #define PROP_TIMEGENERATED 16 #define PROP_PROGRAMNAME 17 #define PROP_PROTOCOL_VERSION 18 #define PROP_STRUCTURED_DATA 19 #define PROP_APP_NAME 20 #define PROP_PROCID 21 #define PROP_MSGID 22 #define PROP_PARSESUCCESS 23 #define PROP_JSONMESG 24 #define PROP_RAWMSG_AFTER_PRI 25 #define PROP_FROMHOST_PORT 26 #define PROP_SYS_NOW 150 #define PROP_SYS_YEAR 151 #define PROP_SYS_MONTH 152 #define PROP_SYS_DAY 153 #define PROP_SYS_HOUR 154 #define PROP_SYS_HHOUR 155 #define PROP_SYS_QHOUR 156 #define PROP_SYS_MINUTE 157 #define PROP_SYS_MYHOSTNAME 158 #define PROP_SYS_BOM 159 #define PROP_SYS_UPTIME 160 #define PROP_UUID 161 #define PROP_SYS_NOW_UTC 162 #define PROP_SYS_YEAR_UTC 163 #define PROP_SYS_MONTH_UTC 164 #define PROP_SYS_DAY_UTC 165 #define PROP_SYS_HOUR_UTC 166 #define PROP_SYS_HHOUR_UTC 167 #define PROP_SYS_QHOUR_UTC 168 #define PROP_SYS_MINUTE_UTC 169 #define PROP_SYS_WDAY 170 #define PROP_SYS_WDAY_UTC 171 #define PROP_SYS_NOW_UXTIMESTAMP 173 #define PROP_CEE 200 #define PROP_CEE_ALL_JSON 201 #define PROP_LOCAL_VAR 202 #define PROP_GLOBAL_VAR 203 #define PROP_CEE_ALL_JSON_PLAIN 204 /* types of configuration handlers. These are used in rainerscript.h */ typedef enum cslCmdHdlrType { eCmdHdlrInvalid = 0, /* invalid handler type - indicates a coding error */ eCmdHdlrCustomHandler, /* custom handler, just call handler function */ eCmdHdlrUID, eCmdHdlrGID, eCmdHdlrBinary, eCmdHdlrFileCreateMode, eCmdHdlrInt, eCmdHdlrNonNegInt, eCmdHdlrPositiveInt, eCmdHdlrSize, eCmdHdlrGetChar, eCmdHdlrFacility, eCmdHdlrSeverity, eCmdHdlrGetWord, eCmdHdlrString, eCmdHdlrArray, eCmdHdlrQueueType, eCmdHdlrGoneAway /* statment existed, but is no longer supported */ } ecslCmdHdrlType; /* the next type describes $Begin .. $End block object types */ typedef enum cslConfObjType { eConfObjGlobal = 0, /* global directives */ eConfObjAction, /* action-specific directives */ /* now come states that indicate that we wait for a block-end. These are * states that permit us to do some safety checks and they hopefully ease * migration to a "real" parser/grammar. */ eConfObjActionWaitEnd, eConfObjAlways /* always valid, very special case (guess $End only!) */ } ecslConfObjType; /* multi-submit support. * This is done via a simple data structure, which holds the number of elements * as well as an array of to-be-submitted messages. * rgerhards, 2009-06-16 */ typedef struct multi_submit_s multi_submit_t; struct multi_submit_s { short maxElem; /* maximum number of Elements */ short nElem; /* current number of Elements, points to the next one FREE */ smsg_t **ppMsgs; }; /* the following structure is a helper to describe a message property */ struct msgPropDescr_s { propid_t id; uchar *name; /* name and lenName are only set for dynamic */ int nameLen; /* properties (JSON) */ }; /* some forward-definitions from the grammar */ struct nvlst; struct cnfobj; #endif /* multi-include protection */ rsyslog-8.2512.0/runtime/PaxHeaders/parser.h0000644000000000000000000000013215055605325015667 xustar0030 mtime=1756826325.650800698 30 atime=1764930980.050678724 30 ctime=1764935923.151576091 rsyslog-8.2512.0/runtime/parser.h0000664000175000017500000000604015055605325015333 0ustar00rgerrger/* header for parser.c * * Copyright 2008-2021 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_PARSER_H #define INCLUDED_PARSER_H /* we create a small helper object, a list of parsers, that we can use to * build a chain of them whereever this is needed (initially thought to be * used in ruleset.c as well as ourselvs). */ struct parserList_s { parser_t *pParser; parserList_t *pNext; }; /* the parser object, a dummy because we have only static methods */ struct parser_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ uchar *pName; /* name of this parser */ modInfo_t *pModule; /* pointer to parser's module */ void *pInst; /* instance data for the parser (v2+ module interface) */ sbool bDoSanitazion; /* do standard message sanitazion before calling parser? */ sbool bDoPRIParsing; /* do standard PRI parsing before calling parser? */ }; /* interfaces */ BEGINinterface(parser) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(var); rsRetVal (*Construct)(parser_t **ppThis); rsRetVal (*ConstructFinalize)(parser_t *pThis); rsRetVal (*Destruct)(parser_t **ppThis); rsRetVal (*SetName)(parser_t *pThis, uchar *name); rsRetVal (*SetModPtr)(parser_t *pThis, modInfo_t *pMod); rsRetVal (*SetDoPRIParsing)(parser_t *pThis, int); rsRetVal (*FindParser)(parserList_t *pParserListRoot, parser_t **ppThis, uchar *name); rsRetVal (*DestructParserList)(parserList_t **pListRoot); rsRetVal (*AddParserToList)(parserList_t **pListRoot, parser_t *pParser); rsRetVal (*destroyMasterParserList)(parserList_t *pParserListRoot); /* static functions */ rsRetVal (*ParseMsg)(smsg_t *pMsg); rsRetVal (*SanitizeMsg)(smsg_t *pMsg); rsRetVal (*AddDfltParser)(uchar *); ENDinterface(parser) #define parserCURR_IF_VERSION 3 /* increment whenever you change the interface above! */ /* version changes 2 SetDoSanitization removed, no longer needed 3 InitParserList removed, no longer needed destroyMasterParserList added findParser extended with new parameter specifying the parser list */ void printParserList(parserList_t *pList); /* prototypes */ PROTOTYPEObj(parser); rsRetVal parserConstructViaModAndName(modInfo_t *pMod, uchar *const pName, void *parserInst); #endif /* #ifndef INCLUDED_PARSER_H */ rsyslog-8.2512.0/runtime/PaxHeaders/cfsysline.c0000644000000000000000000000013215071746523016371 xustar0030 mtime=1760021843.861421349 30 atime=1764930997.880976263 30 ctime=1764935923.278578035 rsyslog-8.2512.0/runtime/cfsysline.c0000664000175000017500000007727015071746523016052 0ustar00rgerrger/* cfsysline.c * Implementation of the configuration system line object. * * File begun on 2007-07-30 by RGerhards * * Copyright (C) 2007-2020 Adiscon GmbH. * * This file is part of rsyslog. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "cfsysline.h" #include "obj.h" #include "conf.h" #include "errmsg.h" #include "srUtils.h" #include "unicode-helper.h" #include "rsconf.h" #include "parserif.h" /* static data */ DEFobjCurrIf(obj) linkedList_t llCmdList; /* this is NOT a pointer - no typo here ;) */ /* --------------- START functions for handling canned syntaxes --------------- */ /* parse a character from the config line * added 2007-07-17 by rgerhards * TODO: enhance this function to handle different classes of characters * HINT: check if char is ' and, if so, use 'c' where c may also be things * like \t etc. */ static rsRetVal doGetChar(uchar **pp, rsRetVal (*pSetHdlr)(void *, uchar *), void *pVal) { DEFiRet; assert(pp != NULL); assert(*pp != NULL); skipWhiteSpace(pp); /* skip over any whitespace */ /* if we are not at a '\0', we have our new char - no validity checks here... */ if (**pp == '\0') { LogError(0, RS_RET_NOT_FOUND, "No character available"); iRet = RS_RET_NOT_FOUND; } else { if (pSetHdlr == NULL) { /* we should set value directly to var */ *((uchar *)pVal) = **pp; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, *pp)); } ++(*pp); /* eat processed char */ } finalize_it: RETiRet; } /* Parse a number from the configuration line. This is more or less * a shell to call the custom handler. * rgerhards, 2007-07-31 */ static rsRetVal doCustomHdlr(uchar **pp, rsRetVal (*pSetHdlr)(uchar **, void *), void *pVal) { DEFiRet; assert(pp != NULL); assert(*pp != NULL); CHKiRet(pSetHdlr(pp, pVal)); finalize_it: RETiRet; } /* Parse a number from the configuration line. This functions just parses * the number and does NOT call any handlers or set any values. It is just * for INTERNAL USE by other parse functions! * rgerhards, 2008-01-08 */ static rsRetVal parseIntVal(uchar **pp, int64 *pVal) { DEFiRet; uchar *p; int64 i; int bWasNegative; assert(pp != NULL); assert(*pp != NULL); assert(pVal != NULL); skipWhiteSpace(pp); /* skip over any whitespace */ p = *pp; if (*p == '-') { bWasNegative = 1; ++p; /* eat it */ } else { bWasNegative = 0; } if (!isdigit((int)*p)) { errno = 0; LogError(0, RS_RET_INVALID_INT, "invalid number"); ABORT_FINALIZE(RS_RET_INVALID_INT); } /* pull value */ for (i = 0; *p && (isdigit((int)*p) || *p == '.' || *p == ','); ++p) { if (isdigit((int)*p)) { i = i * 10 + *p - '0'; } } if (bWasNegative) i *= -1; *pVal = i; *pp = p; finalize_it: RETiRet; } /* Parse a size from the configuration line. This is basically an integer * syntax, but modifiers may be added after the integer (e.g. 1k to mean * 1024). The size must immediately follow the number. Note that the * param value must be int64! * rgerhards, 2008-01-09 */ static rsRetVal doGetSize(uchar **pp, rsRetVal (*pSetHdlr)(void *, int64), void *pVal) { DEFiRet; int64 i; assert(pp != NULL); assert(*pp != NULL); CHKiRet(parseIntVal(pp, &i)); /* we now check if the next character is one of our known modifiers. * If so, we accept it as such. If not, we leave it alone. tera and * above does not make any sense as that is above a 32-bit int value. */ switch (**pp) { /* traditional binary-based definitions */ case 'k': i *= 1024; ++(*pp); break; case 'm': i *= 1024 * 1024; ++(*pp); break; case 'g': i *= 1024 * 1024 * 1024; ++(*pp); break; case 't': i *= (int64)1024 * 1024 * 1024 * 1024; ++(*pp); break; /* tera */ case 'p': i *= (int64)1024 * 1024 * 1024 * 1024 * 1024; ++(*pp); break; /* peta */ case 'e': i *= (int64)1024 * 1024 * 1024 * 1024 * 1024 * 1024; ++(*pp); break; /* exa */ /* and now the "new" 1000-based definitions */ case 'K': i *= 1000; ++(*pp); break; case 'M': i *= 1000000; ++(*pp); break; case 'G': i *= 1000000000; ++(*pp); break; /* we need to use the multiplication below because otherwise * the compiler gets an error during constant parsing */ case 'T': i *= (int64)1000 * 1000000000; ++(*pp); break; /* tera */ case 'P': i *= (int64)1000000 * 1000000000; ++(*pp); break; /* peta */ case 'E': i *= (int64)1000000000 * 1000000000; ++(*pp); break; /* exa */ default: // No action needed for other cases break; } /* done */ if (pSetHdlr == NULL) { /* we should set value directly to var */ *((int64 *)pVal) = i; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, i)); } finalize_it: RETiRet; } /* Parse a number from the configuration line. * rgerhards, 2007-07-31 */ static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void *, uid_t), void *pVal) { uchar *p; DEFiRet; int64 i; assert(pp != NULL); assert(*pp != NULL); CHKiRet(doGetSize(pp, NULL, &i)); p = *pp; if (i > 2147483648ll) { /*2^31*/ LogError(0, RS_RET_INVALID_VALUE, "value %lld too large for integer argument.", i); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } if (pSetHdlr == NULL) { /* we should set value directly to var */ *((int *)pVal) = (int)i; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, (int)i)); } *pp = p; finalize_it: RETiRet; } /* Parse and interpret a $FileCreateMode and $umask line. This function * pulls the creation mode and, if successful, stores it * into the global variable so that the rest of rsyslogd * opens files with that mode. Any previous value will be * overwritten. * HINT: if we store the creation mode in selector_t, we * can even specify multiple modes simply be virtue of * being placed in the right section of rsyslog.conf * rgerhards, 2007-07-4 (happy independence day to my US friends!) * Parameter **pp has a pointer to the current config line. * On exit, it will be updated to the processed position. */ static rsRetVal doFileCreateMode(uchar **pp, rsRetVal (*pSetHdlr)(void *, uid_t), void *pVal) { uchar *p; DEFiRet; int iVal; assert(pp != NULL); assert(*pp != NULL); skipWhiteSpace(pp); /* skip over any whitespace */ p = *pp; /* for now, we parse and accept only octal numbers * Sequence of tests is important, we are using boolean shortcuts * to avoid addressing invalid memory! */ if (!((*p == '0') && (*(p + 1) && *(p + 1) >= '0' && *(p + 1) <= '7') && (*(p + 2) && *(p + 2) >= '0' && *(p + 2) <= '7') && (*(p + 3) && *(p + 3) >= '0' && *(p + 3) <= '7'))) { LogError(0, RS_RET_INVALID_VALUE, "value must be octal (e.g 0644)."); ABORT_FINALIZE(RS_RET_INVALID_VALUE); } /* we reach this code only if the octal number is ok - so we can now * compute the value. */ iVal = (*(p + 1) - '0') * 64 + (*(p + 2) - '0') * 8 + (*(p + 3) - '0'); if (pSetHdlr == NULL) { /* we should set value directly to var */ *((int *)pVal) = iVal; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, iVal)); } p += 4; /* eat the octal number */ *pp = p; finalize_it: RETiRet; } /* Parse and interpret an on/off inside a config file line. This is most * often used for boolean options, but of course it may also be used * for other things. The passed-in pointer is updated to point to * the first unparsed character on exit. Function emits error messages * if the value is neither on or off. It returns 0 if the option is off, * 1 if it is on and another value if there was an error. * rgerhards, 2007-07-15 */ static int doParseOnOffOption(uchar **pp) { uchar *pOptStart; uchar szOpt[32]; assert(pp != NULL); assert(*pp != NULL); pOptStart = *pp; skipWhiteSpace(pp); /* skip over any whitespace */ if (getSubString(pp, (char *)szOpt, sizeof(szOpt), ' ') != 0) { LogError(0, NO_ERRCODE, "Invalid $-configline - could not extract on/off option"); return -1; } if (!strcmp((char *)szOpt, "on")) { return 1; } else if (!strcmp((char *)szOpt, "off")) { return 0; } else { LogError(0, NO_ERRCODE, "Option value must be on or off, but is '%s'", (char *)pOptStart); return -1; } } /* extract a groupname and return its gid. * rgerhards, 2007-07-17 */ static rsRetVal doGetGID(uchar **pp, rsRetVal (*pSetHdlr)(void *, uid_t), void *pVal) { struct group *pgBuf = NULL; struct group gBuf; DEFiRet; uchar szName[256]; int bufSize = 1024; char *stringBuf = NULL; int err; assert(pp != NULL); assert(*pp != NULL); if (getSubString(pp, (char *)szName, sizeof(szName), ' ') != 0) { if (loadConf->globals.abortOnIDResolutionFail) { fprintf(stderr, "could not extract group name: %s\n", (char *)szName); exit(1); /* good exit */ } else { LogError(0, RS_RET_NOT_FOUND, "could not extract group name"); ABORT_FINALIZE(RS_RET_NOT_FOUND); } } do { char *p; /* Increase bufsize and try again.*/ bufSize *= 2; CHKmalloc(p = realloc(stringBuf, bufSize)); stringBuf = p; err = getgrnam_r((char *)szName, &gBuf, stringBuf, bufSize, &pgBuf); } while ((pgBuf == NULL) && (err == ERANGE)); if (pgBuf == NULL) { if (err != 0) { LogError(err, RS_RET_NOT_FOUND, "Query for group '%s' resulted in an error", szName); } else { LogError(0, RS_RET_NOT_FOUND, "ID for group '%s' could not be found", szName); } iRet = RS_RET_NOT_FOUND; if (loadConf->globals.abortOnIDResolutionFail) { fprintf(stderr, "ID for group '%s' could not be found or error\n", szName); exit(1); /* good exit */ } } else { if (pSetHdlr == NULL) { /* we should set value directly to var */ *((gid_t *)pVal) = pgBuf->gr_gid; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, pgBuf->gr_gid)); } dbgprintf("gid %d obtained for group '%s'\n", (int)pgBuf->gr_gid, szName); } skipWhiteSpace(pp); /* skip over any whitespace */ finalize_it: free(stringBuf); RETiRet; } /* extract a username and return its uid. * rgerhards, 2007-07-17 */ static rsRetVal doGetUID(uchar **pp, rsRetVal (*pSetHdlr)(void *, uid_t), void *pVal) { struct passwd *ppwBuf; struct passwd pwBuf; DEFiRet; uchar szName[256]; char stringBuf[2048]; /* I hope this is large enough... */ assert(pp != NULL); assert(*pp != NULL); if (getSubString(pp, (char *)szName, sizeof(szName), ' ') != 0) { if (loadConf->globals.abortOnIDResolutionFail) { fprintf(stderr, "could not extract user name: %s\n", (char *)szName); exit(1); /* good exit */ } else { LogError(0, RS_RET_NOT_FOUND, "could not extract user name"); ABORT_FINALIZE(RS_RET_NOT_FOUND); } } getpwnam_r((char *)szName, &pwBuf, stringBuf, sizeof(stringBuf), &ppwBuf); if (ppwBuf == NULL) { if (loadConf->globals.abortOnIDResolutionFail) { fprintf(stderr, "ID for user '%s' could not be found or error\n", (char *)szName); exit(1); /* good exit */ } else { LogError(0, RS_RET_NOT_FOUND, "ID for user '%s' could not be found or error", (char *)szName); iRet = RS_RET_NOT_FOUND; } } else { if (pSetHdlr == NULL) { /* we should set value directly to var */ *((uid_t *)pVal) = ppwBuf->pw_uid; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, ppwBuf->pw_uid)); } dbgprintf("uid %d obtained for user '%s'\n", (int)ppwBuf->pw_uid, szName); } skipWhiteSpace(pp); /* skip over any whitespace */ finalize_it: RETiRet; } /* Parse and process an binary cofig option. pVal must be * a pointer to an integer which is to receive the option * value. * rgerhards, 2007-07-15 */ static rsRetVal doBinaryOptionLine(uchar **pp, rsRetVal (*pSetHdlr)(void *, int), void *pVal) { int iOption; DEFiRet; assert(pp != NULL); assert(*pp != NULL); if ((iOption = doParseOnOffOption(pp)) == -1) return RS_RET_ERR; /* nothing left to do */ if (pSetHdlr == NULL) { /* we should set value directly to var */ *((int *)pVal) = iOption; } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, iOption)); } skipWhiteSpace(pp); /* skip over any whitespace */ finalize_it: RETiRet; } /* parse a whitespace-delimited word from the provided string. This is a * helper function for a number of syntaxes. The parsed value is returned * in ppStrB (which must be provided by caller). * rgerhards, 2008-02-14 */ static rsRetVal getWord(uchar **pp, cstr_t **ppStrB) { DEFiRet; uchar *p; assert(pp != NULL); assert(*pp != NULL); assert(ppStrB != NULL); CHKiRet(cstrConstruct(ppStrB)); skipWhiteSpace(pp); /* skip over any whitespace */ /* parse out the word */ p = *pp; while (*p && !isspace((int)*p)) { CHKiRet(cstrAppendChar(*ppStrB, *p++)); } cstrFinalize(*ppStrB); *pp = p; finalize_it: RETiRet; } /* Parse and a word config line option. A word is a consequtive * sequence of non-whitespace characters. pVal must be * a pointer to a string which is to receive the option * value. The returned string must be freed by the caller. * rgerhards, 2007-09-07 * To facilitate multiple instances of the same command line * directive, doGetWord() now checks if pVal is already a * non-NULL pointer. If so, we assume it was created by a previous * incarnation and is automatically freed. This happens only when * no custom handler is defined. If it is, the customer handler * must do the cleanup. I have checked and this was al also memory * leak with some code. Obviously, not a large one. -- rgerhards, 2007-12-20 * Just to clarify: if pVal is parsed to a custom handler, this handler * is responsible for freeing pVal. -- rgerhards, 2008-03-20 */ static rsRetVal doGetWord(uchar **pp, rsRetVal (*pSetHdlr)(void *, uchar *), void *pVal) { DEFiRet; cstr_t *pStrB = NULL; uchar *pNewVal; assert(pp != NULL); assert(*pp != NULL); CHKiRet(getWord(pp, &pStrB)); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, &pNewVal, 0)); DBGPRINTF("doGetWord: get newval '%s' (len %d), hdlr %p\n", pNewVal, (int)ustrlen(pNewVal), pSetHdlr); /* we got the word, now set it */ if (pSetHdlr == NULL) { /* we should set value directly to var */ if (*((uchar **)pVal) != NULL) free(*((uchar **)pVal)); /* free previous entry */ *((uchar **)pVal) = pNewVal; /* set new one */ } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, pNewVal)); } skipWhiteSpace(pp); /* skip over any whitespace */ finalize_it: if (iRet != RS_RET_OK) { if (pStrB != NULL) cstrDestruct(&pStrB); } RETiRet; } /* parse a syslog name from the string. This is the generic code that is * called by the facility/severity functions. Note that we do not check the * validity of numerical values, something that should probably change over * time (TODO). -- rgerhards, 2008-02-14 */ static rsRetVal doSyslogName(uchar **pp, rsRetVal (*pSetHdlr)(void *, int), void *pVal, syslogName_t *pNameTable) { DEFiRet; cstr_t *pStrB; int iNewVal; assert(pp != NULL); assert(*pp != NULL); CHKiRet(getWord(pp, &pStrB)); /* get word */ iNewVal = decodeSyslogName(cstrGetSzStrNoNULL(pStrB), pNameTable); if (pSetHdlr == NULL) { /* we should set value directly to var */ *((int *)pVal) = iNewVal; /* set new one */ } else { /* we set value via a set function */ CHKiRet(pSetHdlr(pVal, iNewVal)); } skipWhiteSpace(pp); /* skip over any whitespace */ finalize_it: if (pStrB != NULL) rsCStrDestruct(&pStrB); RETiRet; } /* Implements the facility syntax. * rgerhards, 2008-02-14 */ static rsRetVal doFacility(uchar **pp, rsRetVal (*pSetHdlr)(void *, int), void *pVal) { DEFiRet; iRet = doSyslogName(pp, pSetHdlr, pVal, syslogFacNames); RETiRet; } static rsRetVal doGoneAway(__attribute__((unused)) uchar **pp, __attribute__((unused)) rsRetVal (*pSetHdlr)(void *, int), __attribute__((unused)) void *pVal) { parser_warnmsg("config directive is no longer supported -- ignored"); return RS_RET_CMD_GONE_AWAY; } /* Implements the severity syntax. * rgerhards, 2008-02-14 */ static rsRetVal doSeverity(uchar **pp, rsRetVal (*pSetHdlr)(void *, int), void *pVal) { DEFiRet; iRet = doSyslogName(pp, pSetHdlr, pVal, syslogPriNames); RETiRet; } /* --------------- END functions for handling canned syntaxes --------------- */ /* destructor for cslCmdHdlr * pThis is actually a cslCmdHdlr_t, but we do not cast it as all we currently * need to do is free it. */ static rsRetVal cslchDestruct(void *pThis) { assert(pThis != NULL); free(pThis); return RS_RET_OK; } /* constructor for cslCmdHdlr */ static rsRetVal cslchConstruct(cslCmdHdlr_t **ppThis) { cslCmdHdlr_t *pThis; DEFiRet; assert(ppThis != NULL); if ((pThis = calloc(1, sizeof(cslCmdHdlr_t))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } finalize_it: *ppThis = pThis; RETiRet; } /* destructor for linked list keys. As we do not use any dynamic memory, * we simply return. However, this entry point must be defined for the * linkedList class to make sure we have not forgotten a destructor. * rgerhards, 2007-11-21 */ static rsRetVal cslchKeyDestruct(void __attribute__((unused)) * pData) { return RS_RET_OK; } /* Key compare operation for linked list class. This compares two * owner cookies (void *). * rgerhards, 2007-11-21 */ static int cslchKeyCompare(void *pKey1, void *pKey2) { if (pKey1 == pKey2) return 0; else if (pKey1 < pKey2) return -1; else return 1; } /* set data members for this object */ static rsRetVal cslchSetEntry( cslCmdHdlr_t *pThis, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, int *permitted) { assert(pThis != NULL); assert(eType != eCmdHdlrInvalid); pThis->eType = eType; pThis->cslCmdHdlr = pHdlr; pThis->pData = pData; pThis->permitted = permitted; return RS_RET_OK; } /* call the specified handler */ static rsRetVal cslchCallHdlr(cslCmdHdlr_t *pThis, uchar **ppConfLine) { DEFiRet; assert(pThis != NULL); assert(ppConfLine != NULL); switch (pThis->eType) { case eCmdHdlrCustomHandler: CHKiRet(doCustomHdlr(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrUID: CHKiRet(doGetUID(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrGID: CHKiRet(doGetGID(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrBinary: CHKiRet(doBinaryOptionLine(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrFileCreateMode: CHKiRet(doFileCreateMode(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrInt: CHKiRet(doGetInt(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrSize: CHKiRet(doGetSize(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrGetChar: CHKiRet(doGetChar(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrFacility: CHKiRet(doFacility(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrSeverity: CHKiRet(doSeverity(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrGetWord: CHKiRet(doGetWord(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; case eCmdHdlrGoneAway: CHKiRet(doGoneAway(ppConfLine, pThis->cslCmdHdlr, pThis->pData)); break; /* some non-legacy handler (used in v6+ solely) */ case eCmdHdlrInvalid: case eCmdHdlrNonNegInt: case eCmdHdlrPositiveInt: case eCmdHdlrString: case eCmdHdlrArray: case eCmdHdlrQueueType: default: dbgprintf("error: command handler type %d not implemented in legacy system\n", pThis->eType); iRet = RS_RET_NOT_IMPLEMENTED; goto finalize_it; } finalize_it: RETiRet; } /* ---------------------------------------------------------------------- * * now come the handlers for cslCmd_t * ---------------------------------------------------------------------- */ /* destructor for a cslCmd list key (a string as of now) */ static rsRetVal cslcKeyDestruct(void *pData) { free(pData); /* we do not need to cast as all we do is free it anyway... */ return RS_RET_OK; } /* destructor for cslCmd */ static rsRetVal cslcDestruct(void *pData) { cslCmd_t *pThis = (cslCmd_t *)pData; assert(pThis != NULL); llDestroy(&pThis->llCmdHdlrs); free(pThis); return RS_RET_OK; } /* constructor for cslCmd */ static rsRetVal cslcConstruct(cslCmd_t **ppThis, int bChainingPermitted) { cslCmd_t *pThis; DEFiRet; assert(ppThis != NULL); if ((pThis = calloc(1, sizeof(cslCmd_t))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pThis->bChainingPermitted = bChainingPermitted; CHKiRet(llInit(&pThis->llCmdHdlrs, cslchDestruct, cslchKeyDestruct, (int (*)(void *, void *))cslchKeyCompare)); finalize_it: *ppThis = pThis; RETiRet; } /* add a handler entry to a known command */ static rsRetVal cslcAddHdlr( cslCmd_t *pThis, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, void *pOwnerCookie, int *permitted) { DEFiRet; cslCmdHdlr_t *pCmdHdlr = NULL; assert(pThis != NULL); CHKiRet(cslchConstruct(&pCmdHdlr)); CHKiRet(cslchSetEntry(pCmdHdlr, eType, pHdlr, pData, permitted)); CHKiRet(llAppend(&pThis->llCmdHdlrs, pOwnerCookie, pCmdHdlr)); finalize_it: if (iRet != RS_RET_OK) { if (pHdlr != NULL) cslchDestruct(pCmdHdlr); } RETiRet; } /* function that registers cfsysline handlers. * The supplied pCmdName is copied and a new buffer is allocated. This * buffer is automatically destroyed when the element is freed, the * caller does not need to take care of that. The caller must, however, * free pCmdName if he allocated it dynamically! -- rgerhards, 2007-08-09 * Parameter permitted has been added to support the v2 config system. With it, * we can tell the legacy system (us here!) to check if a config directive is * still permitted. For example, the v2 system will disable module global * parameters if the are supplied via the native v2 callbacks. In order not * to break exisiting modules, we have renamed the rgCfSysLinHdlr routine to * version 2 and added a new one with the original name. It just calls the * v2 function and supplies a "don't care (NULL)" pointer as this argument. * rgerhards, 2012-06-26 */ rsRetVal regCfSysLineHdlr2(const uchar *pCmdName, int bChainingPermitted, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, void *pOwnerCookie, int *permitted) { DEFiRet; cslCmd_t *pThis; uchar *pMyCmdName; iRet = llFind(&llCmdList, (void *)pCmdName, (void *)&pThis); if (iRet == RS_RET_NOT_FOUND) { /* new command */ CHKiRet(cslcConstruct(&pThis, bChainingPermitted)); CHKiRet_Hdlr(cslcAddHdlr(pThis, eType, pHdlr, pData, pOwnerCookie, permitted)) { cslcDestruct(pThis); FINALIZE; } /* important: add to list, AFTER everything else is OK. Else * we mess up things in the error case. */ if ((pMyCmdName = (uchar *)strdup((char *)pCmdName)) == NULL) { cslcDestruct(pThis); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } CHKiRet_Hdlr(llAppend(&llCmdList, pMyCmdName, (void *)pThis)) { cslcDestruct(pThis); FINALIZE; } } else { /* command already exists, are we allowed to chain? */ if (pThis->bChainingPermitted == 0 || bChainingPermitted == 0) { ABORT_FINALIZE(RS_RET_CHAIN_NOT_PERMITTED); } CHKiRet_Hdlr(cslcAddHdlr(pThis, eType, pHdlr, pData, pOwnerCookie, permitted)) { cslcDestruct(pThis); FINALIZE; } } finalize_it: RETiRet; } rsRetVal regCfSysLineHdlr(const uchar *pCmdName, int bChainingPermitted, ecslCmdHdrlType eType, rsRetVal (*pHdlr)(), void *pData, void *pOwnerCookie) { DEFiRet; iRet = regCfSysLineHdlr2(pCmdName, bChainingPermitted, eType, pHdlr, pData, pOwnerCookie, NULL); RETiRet; } rsRetVal unregCfSysLineHdlrs(void) { return llDestroy(&llCmdList); } /* helper function for unregCfSysLineHdlrs4Owner(). This is used to see if there is * a handler of this owner inside the element and, if so, remove it. Please note that * it keeps track of a pointer to the last linked list entry, as this is needed to * remove an entry from the list. * rgerhards, 2007-11-21 */ DEFFUNC_llExecFunc(unregHdlrsHeadExec) { DEFiRet; cslCmd_t *pListHdr = (cslCmd_t *)pData; int iNumElts; /* first find element */ CHKiRet(llFindAndDelete(&(pListHdr->llCmdHdlrs), pParam)); /* now go back and check how many elements are left */ CHKiRet(llGetNumElts(&(pListHdr->llCmdHdlrs), &iNumElts)); if (iNumElts == 0) { /* nothing left in header, so request to delete it */ iRet = RS_RET_OK_DELETE_LISTENTRY; } finalize_it: RETiRet; } /* unregister and destroy cfSysLineHandlers for a specific owner. This method is * most importantly used before unloading a loadable module providing some handlers. * The full list of handlers is searched. If the to-be removed handler was the only * handler for a directive name, the directive header, too, is deleted. * rgerhards, 2007-11-21 */ rsRetVal unregCfSysLineHdlrs4Owner(void *pOwnerCookie) { DEFiRet; /* we need to walk through all directive names, as the linked list * class does not provide a way to just search the lower-level handlers. */ iRet = llExecFunc(&llCmdList, unregHdlrsHeadExec, pOwnerCookie); if (iRet == RS_RET_NOT_FOUND) { /* It is not considered an error if a module had no hanlers registered. */ iRet = RS_RET_OK; } RETiRet; } /* process a cfsysline command (based on handler structure) * param "p" is a pointer to the command line after the command. Should be * updated. */ rsRetVal processCfSysLineCommand(uchar *pCmdName, uchar **p) { DEFiRet; rsRetVal iRetLL; /* for linked list handling */ cslCmd_t *pCmd; cslCmdHdlr_t *pCmdHdlr; linkedListCookie_t llCookieCmdHdlr; uchar *pHdlrP; /* the handler's private p (else we could only call one handler) */ int bWasOnceOK; /* was the result of an handler at least once RS_RET_OK? */ uchar *pOKp = NULL; /* returned conf line pointer when it was OK */ iRet = llFind(&llCmdList, (void *)pCmdName, (void *)&pCmd); if (iRet == RS_RET_NOT_FOUND) { LogError(0, RS_RET_NOT_FOUND, "invalid or yet-unknown config file command '%s' - " "have you forgotten to load a module?", pCmdName); } if (iRet != RS_RET_OK) goto finalize_it; llCookieCmdHdlr = NULL; bWasOnceOK = 0; while ((iRetLL = llGetNextElt(&pCmd->llCmdHdlrs, &llCookieCmdHdlr, (void *)&pCmdHdlr)) == RS_RET_OK) { /* for the time being, we ignore errors during handlers. The * reason is that handlers are independent. An error in one * handler does not necessarily mean that another one will * fail, too. Later, we might add a config variable to control * this behaviour (but I am not sure if that is really * necessary). -- rgerhards, 2007-07-31 */ pHdlrP = *p; if (pCmdHdlr->permitted != NULL && !*(pCmdHdlr->permitted)) { LogError(0, RS_RET_PARAM_NOT_PERMITTED, "command '%s' is currently not " "permitted - did you already set it via a RainerScript command (v6+ config)?", pCmdName); ABORT_FINALIZE(RS_RET_PARAM_NOT_PERMITTED); } else if ((iRet = cslchCallHdlr(pCmdHdlr, &pHdlrP)) == RS_RET_OK) { bWasOnceOK = 1; pOKp = pHdlrP; } } if (bWasOnceOK == 1) { *p = pOKp; iRet = RS_RET_OK; } if (iRetLL != RS_RET_END_OF_LINKEDLIST) iRet = iRetLL; finalize_it: RETiRet; } /* debug print the command handler structure */ void dbgPrintCfSysLineHandlers(void) { cslCmd_t *pCmd; cslCmdHdlr_t *pCmdHdlr; linkedListCookie_t llCookieCmd; linkedListCookie_t llCookieCmdHdlr; uchar *pKey; dbgprintf("System Line Configuration Commands:\n"); llCookieCmd = NULL; while (llGetNextElt(&llCmdList, &llCookieCmd, (void *)&pCmd) == RS_RET_OK) { llGetKey(llCookieCmd, (void *)&pKey); /* TODO: using the cookie is NOT clean! */ dbgprintf("\tCommand '%s':\n", pKey); llCookieCmdHdlr = NULL; while (llGetNextElt(&pCmd->llCmdHdlrs, &llCookieCmdHdlr, (void *)&pCmdHdlr) == RS_RET_OK) { dbgprintf("\t\ttype : %d\n", pCmdHdlr->eType); dbgprintf("\t\tpData: 0x%lx\n", (unsigned long)pCmdHdlr->pData); dbgprintf("\t\tHdlr : 0x%lx\n", (unsigned long)pCmdHdlr->cslCmdHdlr); dbgprintf("\t\tOwner: 0x%lx\n", (unsigned long)llCookieCmdHdlr->pKey); dbgprintf("\n"); } } dbgprintf("\n"); } rsRetVal cfsyslineInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(llInit(&llCmdList, cslcDestruct, cslcKeyDestruct, (int (*)(void *, void *))strcasecmp)); finalize_it: RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/ruleset.h0000644000000000000000000000013215055605325016056 xustar0030 mtime=1756826325.652800728 30 atime=1764930980.049678708 30 ctime=1764935923.261577775 rsyslog-8.2512.0/runtime/ruleset.h0000664000175000017500000001022015055605325015515 0ustar00rgerrger/* The ruleset object. * * This implements rulesets within rsyslog. * * Copyright 2009-2021 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_RULESET_H #define INCLUDED_RULESET_H #include "queue.h" #include "linkedlist.h" #include "rsconf.h" /* the ruleset object */ struct ruleset_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ uchar *pszName; /* name of our ruleset */ qqueue_t *pQueue; /* "main" message queue, if the ruleset has its own (else NULL) */ struct cnfstmt *root; struct cnfstmt *last; parserList_t *pParserLst; /* list of parsers to use for this ruleset */ }; /* interfaces */ BEGINinterface(ruleset) /* name must also be changed in ENDinterface macro! */ INTERFACEObjDebugPrint(ruleset); rsRetVal (*DebugPrintAll)(rsconf_t *conf); rsRetVal (*Construct)(ruleset_t **ppThis); rsRetVal (*ConstructFinalize)(rsconf_t *conf, ruleset_t __attribute__((unused)) * pThis); rsRetVal (*Destruct)(ruleset_t **ppThis); rsRetVal (*DestructAllActions)(rsconf_t *conf); rsRetVal (*SetName)(ruleset_t *pThis, uchar *pszName); rsRetVal (*ProcessBatch)(batch_t *, wti_t *); rsRetVal (*GetRuleset)(rsconf_t *conf, ruleset_t **ppThis, uchar *); rsRetVal (*SetDefaultRuleset)(rsconf_t *conf, uchar *); rsRetVal (*SetCurrRuleset)(rsconf_t *conf, uchar *); ruleset_t *(*GetCurrent)(rsconf_t *conf); qqueue_t *(*GetRulesetQueue)(ruleset_t *); /* v3, 2009-11-04 */ parserList_t *(*GetParserList)(rsconf_t *conf, smsg_t *); /* v5, 2011-04-19 * added support for the rsconf object -- fundamental change * v6, 2011-07-15 * removed conf ptr from SetName, AddRule as the flex/bison based * system uses globals in any case. */ /* v7, 2012-09-04 */ /* AddRule() removed */ /*TODO:REMOVE*/ rsRetVal (*IterateAllActions)(rsconf_t *conf, rsRetVal (*pFunc)(void *, void *), void *pParam); void (*AddScript)(ruleset_t *pThis, struct cnfstmt *script); /* v8: changed processBatch interface */ ENDinterface(ruleset) #define rulesetCURR_IF_VERSION 8 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(ruleset); /* TODO: remove these -- currently done dirty for config file * redo -- rgerhards, 2011-04-19 * rgerhards, 2012-04-19: actually, it may be way cooler not to remove * them and use plain c-style conventions at least inside core objects. */ rsRetVal rulesetDestructForLinkedList(void *pData); rsRetVal rulesetKeyDestruct(void __attribute__((unused)) * pData); /* Get name associated to ruleset. This function cannot fail (except, * of course, if previously something went really wrong). Returned * pointer is read-only. * rgerhards, 2012-04-18 */ #define rulesetGetName(pRuleset) ((pRuleset)->pszName) /* returns 1 if the ruleset has a queue associated, 0 if not */ #define rulesetHasQueue(pRuleset) \ (((pRuleset)->pQueue != NULL) && ((pRuleset)->pQueue->qType != QUEUETYPE_DIRECT) ? 1 : 0) /* we will most probably convert this module back to traditional C * calling sequence, so here we go... */ rsRetVal rulesetGetRuleset(rsconf_t *conf, ruleset_t **ppRuleset, uchar *pszName); rsRetVal rulesetOptimizeAll(rsconf_t *conf); rsRetVal rulesetProcessCnf(struct cnfobj *o); rsRetVal activateRulesetQueues(void); /* Set a current rule set to already-known pointer */ #define rulesetSetCurrRulesetPtr(pRuleset) (loadConf->rulesets.pCurr = (pRuleset)) #endif /* #ifndef INCLUDED_RULESET_H */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_gtls.h0000644000000000000000000000013215114522477016212 xustar0030 mtime=1764926783.040631981 30 atime=1764926784.239661412 30 ctime=1764935923.359579275 rsyslog-8.2512.0/runtime/nsd_gtls.h0000664000175000017500000001223015114522477015654 0ustar00rgerrger/* An implementation of the nsd interface for GnuTLS. * * Copyright 2008-2021 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NSD_GTLS_H #define INCLUDED_NSD_GTLS_H #include "nsd.h" #define NSD_GTLS_MAX_RCVBUF 16 * 1024 + 1 /* TLS RFC 8449: max size of buffer for message reception */ #define NSD_GTLS_MAX_CERT 10 /* max number of certs in our chain */ typedef enum { gtlsRtry_None = 0, /**< no call needs to be retried */ gtlsRtry_handshake = 1, gtlsRtry_recv = 2 } gtlsRtryCall_t; /**< IDs of calls that needs to be retried */ typedef enum { gtlsDir_READ = 0, /**< GNUTLS wants READ */ gtlsDir_WRITE = 1 /**< GNUTLS wants WRITE */ } gtlsDirection_t; typedef nsd_if_t nsd_gtls_if_t; /* we just *implement* this interface */ /* the nsd_gtls object */ struct nsd_gtls_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */ uchar *pszConnectHost; /**< hostname used for connect - may be used to authenticate peer if no other name given */ const uchar *pszCAFile; const uchar *pszCRLFile; const uchar *pszKeyFile; const uchar *pszCertFile; gnutls_certificate_credentials_t xcred; int xcred_is_copy; int iMode; /* 0 - plain tcp, 1 - TLS */ int bAbortConn; /* if set, abort conncection (fatal error had happened) */ enum { GTLS_AUTH_CERTNAME = 0, GTLS_AUTH_CERTFINGERPRINT = 1, GTLS_AUTH_CERTVALID = 2, GTLS_AUTH_CERTANON = 3 } authMode; enum { GTLS_EXPIRED_PERMIT = 0, GTLS_EXPIRED_DENY = 1, GTLS_EXPIRED_WARN = 2 } permitExpiredCerts; enum { GTLS_NONE = 0, GTLS_PURPOSE = 1 } dataTypeCheck; int bSANpriority; /* if true, we do stricter checking (if any SAN present we do not cehck CN) */ gtlsRtryCall_t rtryCall; /**< what must we retry? */ int bIsInitiator; /**< 0 if socket is the server end (listener), 1 if it is the initiator */ gnutls_session_t sess; int bHaveSess; /* as we don't know exactly which gnutls_session values are invalid, we use this one to flag whether or not we are in a session (same as -1 for a socket meaning no sess) */ int bReportAuthErr; /* only the first auth error is to be reported, this var triggers it. Initially, it is * set to 1 and changed to 0 after the first report. It is changed back to 1 after * one successful authentication. */ permittedPeers_t *pPermPeers; /* permitted peers */ uchar *gnutlsPriorityString; /* gnutls priority string */ int DrvrVerifyDepth; /* Verify Depth for certificate chains */ gnutls_x509_crt_t pOurCerts[NSD_GTLS_MAX_CERT]; /**< our certificate, if in client mode (unused in server mode) */ unsigned int nOurCerts; /* number of certificates in our chain */ gnutls_x509_privkey_t ourKey; /**< our private key, if in client mode (unused in server mode) */ short bOurCertIsInit; /**< 1 if our certificate is initialized and must be deinit on destruction */ short bOurKeyIsInit; /**< 1 if our private key is initialized and must be deinit on destruction */ char *pszRcvBuf; int lenRcvBuf; /**< -1: empty, 0: connection closed, 1..NSD_GTLS_MAX_RCVBUF-1: data of that size present */ int ptrRcvBuf; /**< offset for next recv operation if 0 < lenRcvBuf < NSD_GTLS_MAX_RCVBUF */ }; /* interface is defined in nsd.h, we just implement it! */ #define nsd_gtlsCURR_IF_VERSION nsdCURR_IF_VERSION /* prototypes */ PROTOTYPEObj(nsd_gtls); /* some prototypes for things used by our nsdsel_gtls helper class */ uchar *gtlsStrerror(int error); rsRetVal gtlsChkPeerAuth(nsd_gtls_t *pThis); rsRetVal gtlsRecordRecv(nsd_gtls_t *pThis, unsigned *); /* the name of our library binary */ #define LM_NSD_GTLS_FILENAME "lmnsd_gtls" #if GNUTLS_VERSION_NUMBER <= 0x00030000 #define GTLS_ANON_PRIO_NOTLSV13 "NORMAL:-VERS-TLS1.3:+ANON-DH:+COMP-ALL" #define GTLS_ANON_PRIO "NORMAL:+ANON-DH:+COMP-ALL" #else #define GTLS_ANON_PRIO_NOTLSV13 "NORMAL:-VERS-TLS1.3:+ANON-DH:+ANON-ECDH:+COMP-ALL" #define GTLS_ANON_PRIO "NORMAL:+ANON-DH:+ANON-ECDH:+COMP-ALL" #endif #if GNUTLS_VERSION_MAJOR > 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR >= 4) #define EXTENDED_CERT_CHECK_AVAILABLE #endif #endif /* #ifndef INCLUDED_NSD_GTLS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/nsd_ossl.h0000644000000000000000000000013215055605325016217 xustar0030 mtime=1756826325.649800683 30 atime=1764931012.577220453 30 ctime=1764935923.374579505 rsyslog-8.2512.0/runtime/nsd_ossl.h0000664000175000017500000000731515055605325015671 0ustar00rgerrger/* An implementation of the nsd interface for OpenSSL. * * Copyright 2018-2023 Adiscon GmbH. * Author: Andre Lorbach * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NSD_OSSL_H #define INCLUDED_NSD_OSSL_H #include "nsd.h" #define NSD_OSSL_MAX_RCVBUF 16 * 1024 + 1 /* TLS RFC 8449: max size of buffer for message reception */ typedef enum { osslRtry_None = 0, /**< no call needs to be retried */ osslRtry_handshake = 1, osslRtry_recv = 2 } osslRtryCall_t; /**< IDs of calls that needs to be retried */ typedef nsd_if_t nsd_ossl_if_t; /* we just *implement* this interface */ /* the nsd_ossl object */ struct nsd_ossl_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */ uchar *pszConnectHost; /**< hostname used for connect - may be used to authenticate peer if no other name given */ int iMode; /* 0 - plain tcp, 1 - TLS */ int bAbortConn; /* if set, abort conncection (fatal error had happened) */ PermitExpiredCerts permitExpiredCerts; osslRtryCall_t rtryCall; /**< what must we retry? */ int rtryOsslErr; /**< store ssl error code into like SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE */ int bIsInitiator; /**< 0 if socket is the server end (listener), 1 if it is the initiator */ int bHaveSess; /* as we don't know exactly which gnutls_session values are invalid, we use this one to flag whether or not we are in a session (same as -1 for a socket meaning no sess) */ uchar *gnutlsPriorityString; /* gnutls priority string */ int DrvrVerifyDepth; /* Verify Depth for certificate chains */ short bOurCertIsInit; /**< 1 if our certificate is initialized and must be deinit on destruction */ short bOurKeyIsInit; /**< 1 if our private key is initialized and must be deinit on destruction */ char *pszRcvBuf; int lenRcvBuf; /**< -1: empty, 0: connection closed, 1..NSD_OSSL_MAX_RCVBUF-1: data of that size present */ int ptrRcvBuf; /**< offset for next recv operation if 0 < lenRcvBuf < NSD_OSSL_MAX_RCVBUF */ /* OpenSSL and Config Cert vars inside net_ossl_t now */ net_ossl_t *pNetOssl; /* OSSL shared Config and object vars are here */ }; /* interface is defined in nsd.h, we just implement it! */ #define nsd_osslCURR_IF_VERSION nsdCURR_IF_VERSION /* prototypes */ PROTOTYPEObj(nsd_ossl); /* some prototypes for things used by our nsdsel_ossl helper class */ uchar *osslStrerror(int error); rsRetVal osslChkPeerAuth(nsd_ossl_t *pThis); rsRetVal osslRecordRecv(nsd_ossl_t *pThis, unsigned *); rsRetVal osslHandshakeCheck(nsd_ossl_t *pNsd); void nsd_ossl_lastOpenSSLErrorMsg( nsd_ossl_t const *pThis, const int ret, SSL *ssl, int severity, const char *pszCallSource, const char *pszOsslApi); rsRetVal osslPostHandshakeCheck(nsd_ossl_t *pNsd); /* the name of our library binary */ #define LM_NSD_OSSL_FILENAME "lmnsd_ossl" #endif /* #ifndef INCLUDED_NSD_OSSL_H */ rsyslog-8.2512.0/runtime/PaxHeaders/Makefile.in0000644000000000000000000000013215114544320016260 xustar0030 mtime=1764935888.353043192 30 atime=1764935894.206132845 30 ctime=1764935923.077574958 rsyslog-8.2512.0/runtime/Makefile.in0000664000175000017500000041733515114544320015741 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ sbin_PROGRAMS = @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_1 = ${LIBLOGGING_STDLOG_CFLAGS} @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_2 = $(LIBLOGGING_STDLOG_LIBS) # # regular expression support # @ENABLE_REGEXP_TRUE@am__append_3 = lmregexp.la @ENABLE_LIBLOGGING_STDLOG_TRUE@@ENABLE_REGEXP_TRUE@am__append_4 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@@ENABLE_REGEXP_TRUE@am__append_5 = $(LIBLOGGING_STDLOG_LIBS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_6 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_7 = $(LIBLOGGING_STDLOG_LIBS) # netstream drivers # plain tcp driver - main driver @ENABLE_INET_TRUE@am__append_8 = lmnetstrms.la lmnsd_ptcp.la @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_9 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_10 = $(LIBLOGGING_STDLOG_LIBS) @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_11 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_12 = $(LIBLOGGING_STDLOG_LIBS) @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_13 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_INET_TRUE@@ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_14 = $(LIBLOGGING_STDLOG_LIBS) # # openssl base and netstream driver # # noinst_LTLIBRARIES += lmnsd_ossl.la @ENABLE_OPENSSL_TRUE@am__append_15 = lmnsd_ossl.la # # GnuTLS netstream driver # @ENABLE_GNUTLS_TRUE@am__append_16 = lmnsd_gtls.la # # Mbed TLS netstream driver # @ENABLE_MBEDTLS_TRUE@am__append_17 = lmnsd_mbedtls.la # # support library for libgcrypt # @ENABLE_LIBGCRYPT_TRUE@am__append_18 = libgcry.la @ENABLE_LIBGCRYPT_TRUE@am__append_19 = lmcry_gcry.la @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am__append_20 = libossl.la @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am__append_21 = lmcry_ossl.la # # support library for zstd # @ENABLE_LIBZSTD_TRUE@am__append_22 = lmzstdw.la # # gssapi support # @ENABLE_GSSAPI_TRUE@am__append_23 = lmgssutil.la @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_24 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_25 = $(LIBLOGGING_STDLOG_LIBS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_26 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_27 = $(LIBLOGGING_STDLOG_LIBS) # # support library for Guardtime KSI-LS12 # @ENABLE_KSI_LS12_TRUE@am__append_28 = lmsig_ksi_ls12.la subdir = runtime ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pkglibdir)" PROGRAMS = $(sbin_PROGRAMS) LIBRARIES = $(noinst_LIBRARIES) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES) libgcry_la_LIBADD = am__libgcry_la_SOURCES_DIST = libgcry.c libcry_common.c \ libcry_common.h libgcry.h @ENABLE_LIBGCRYPT_TRUE@am_libgcry_la_OBJECTS = libgcry_la-libgcry.lo \ @ENABLE_LIBGCRYPT_TRUE@ libgcry_la-libcry_common.lo libgcry_la_OBJECTS = $(am_libgcry_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = @ENABLE_LIBGCRYPT_TRUE@am_libgcry_la_rpath = libossl_la_LIBADD = am__libossl_la_SOURCES_DIST = libossl.c libossl.h libcry_common.c \ libcry_common.h @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am_libossl_la_OBJECTS = \ @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@ libossl_la-libossl.lo \ @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@ libossl_la-libcry_common.lo libossl_la_OBJECTS = $(am_libossl_la_OBJECTS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am_libossl_la_rpath = am__DEPENDENCIES_1 = @ENABLE_LIBLOGGING_STDLOG_TRUE@am__DEPENDENCIES_2 = \ @ENABLE_LIBLOGGING_STDLOG_TRUE@ $(am__DEPENDENCIES_1) librsyslog_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am__dirstamp = $(am__leading_dot)dirstamp am_librsyslog_la_OBJECTS = librsyslog_la-rsyslog.lo \ librsyslog_la-dnscache.lo librsyslog_la-glbl.lo \ librsyslog_la-conf.lo librsyslog_la-janitor.lo \ librsyslog_la-rsconf.lo librsyslog_la-parser.lo \ librsyslog_la-strgen.lo librsyslog_la-msg.lo \ librsyslog_la-linkedlist.lo librsyslog_la-objomsr.lo \ librsyslog_la-stringbuf.lo librsyslog_la-datetime.lo \ librsyslog_la-srutils.lo librsyslog_la-errmsg.lo \ librsyslog_la-operatingstate.lo librsyslog_la-debug.lo \ librsyslog_la-obj.lo librsyslog_la-modules.lo \ librsyslog_la-statsobj.lo librsyslog_la-dynstats.lo \ librsyslog_la-perctile_ringbuf.lo \ librsyslog_la-perctile_stats.lo librsyslog_la-stream.lo \ librsyslog_la-var.lo librsyslog_la-wtp.lo librsyslog_la-wti.lo \ librsyslog_la-queue.lo librsyslog_la-ruleset.lo \ librsyslog_la-prop.lo librsyslog_la-ratelimit.lo \ librsyslog_la-lookup.lo librsyslog_la-cfsysline.lo \ ../librsyslog_la-action.lo ../librsyslog_la-threads.lo \ ../librsyslog_la-parse.lo librsyslog_la-hashtable.lo \ librsyslog_la-hashtable_itr.lo ../librsyslog_la-outchannel.lo \ ../librsyslog_la-template.lo librsyslog_la-timezones.lo librsyslog_la_OBJECTS = $(am_librsyslog_la_OBJECTS) am__lmcry_gcry_la_SOURCES_DIST = lmcry_gcry.c lmcry_gcry.h @ENABLE_LIBGCRYPT_TRUE@am_lmcry_gcry_la_OBJECTS = \ @ENABLE_LIBGCRYPT_TRUE@ lmcry_gcry_la-lmcry_gcry.lo lmcry_gcry_la_OBJECTS = $(am_lmcry_gcry_la_OBJECTS) lmcry_gcry_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmcry_gcry_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_LIBGCRYPT_TRUE@am_lmcry_gcry_la_rpath = -rpath $(pkglibdir) am__lmcry_ossl_la_SOURCES_DIST = lmcry_ossl.c lmcry_ossl.h @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am_lmcry_ossl_la_OBJECTS = lmcry_ossl_la-lmcry_ossl.lo lmcry_ossl_la_OBJECTS = $(am_lmcry_ossl_la_OBJECTS) lmcry_ossl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmcry_ossl_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@am_lmcry_ossl_la_rpath = -rpath \ @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@ $(pkglibdir) @ENABLE_GSSAPI_TRUE@lmgssutil_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__lmgssutil_la_SOURCES_DIST = gss-misc.c gss-misc.h @ENABLE_GSSAPI_TRUE@am_lmgssutil_la_OBJECTS = \ @ENABLE_GSSAPI_TRUE@ lmgssutil_la-gss-misc.lo lmgssutil_la_OBJECTS = $(am_lmgssutil_la_OBJECTS) lmgssutil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmgssutil_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_GSSAPI_TRUE@am_lmgssutil_la_rpath = -rpath $(pkglibdir) lmnet_la_DEPENDENCIES = am_lmnet_la_OBJECTS = lmnet_la-net.lo lmnet_la-netns_socket.lo lmnet_la_OBJECTS = $(am_lmnet_la_OBJECTS) lmnet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmnet_la_LDFLAGS) $(LDFLAGS) -o $@ lmnetstrms_la_DEPENDENCIES = am__lmnetstrms_la_SOURCES_DIST = netstrms.c netstrms.h netstrm.c \ netstrm.h @ENABLE_INET_TRUE@am_lmnetstrms_la_OBJECTS = \ @ENABLE_INET_TRUE@ lmnetstrms_la-netstrms.lo \ @ENABLE_INET_TRUE@ lmnetstrms_la-netstrm.lo lmnetstrms_la_OBJECTS = $(am_lmnetstrms_la_OBJECTS) lmnetstrms_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmnetstrms_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_INET_TRUE@am_lmnetstrms_la_rpath = -rpath $(pkglibdir) @ENABLE_GNUTLS_TRUE@lmnsd_gtls_la_DEPENDENCIES = \ @ENABLE_GNUTLS_TRUE@ $(am__DEPENDENCIES_1) am__lmnsd_gtls_la_SOURCES_DIST = nsd_gtls.c nsd_gtls.h @ENABLE_GNUTLS_TRUE@am_lmnsd_gtls_la_OBJECTS = \ @ENABLE_GNUTLS_TRUE@ lmnsd_gtls_la-nsd_gtls.lo lmnsd_gtls_la_OBJECTS = $(am_lmnsd_gtls_la_OBJECTS) lmnsd_gtls_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmnsd_gtls_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_GNUTLS_TRUE@am_lmnsd_gtls_la_rpath = -rpath $(pkglibdir) @ENABLE_MBEDTLS_TRUE@lmnsd_mbedtls_la_DEPENDENCIES = \ @ENABLE_MBEDTLS_TRUE@ $(am__DEPENDENCIES_1) am__lmnsd_mbedtls_la_SOURCES_DIST = nsd_mbedtls.c nsd_mbedtls.h @ENABLE_MBEDTLS_TRUE@am_lmnsd_mbedtls_la_OBJECTS = \ @ENABLE_MBEDTLS_TRUE@ lmnsd_mbedtls_la-nsd_mbedtls.lo lmnsd_mbedtls_la_OBJECTS = $(am_lmnsd_mbedtls_la_OBJECTS) lmnsd_mbedtls_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(lmnsd_mbedtls_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_MBEDTLS_TRUE@am_lmnsd_mbedtls_la_rpath = -rpath $(pkglibdir) @ENABLE_OPENSSL_TRUE@lmnsd_ossl_la_DEPENDENCIES = \ @ENABLE_OPENSSL_TRUE@ $(am__DEPENDENCIES_1) am__lmnsd_ossl_la_SOURCES_DIST = net_ossl.c net_ossl.h nsd_ossl.c \ nsd_ossl.h @ENABLE_OPENSSL_TRUE@am_lmnsd_ossl_la_OBJECTS = \ @ENABLE_OPENSSL_TRUE@ lmnsd_ossl_la-net_ossl.lo \ @ENABLE_OPENSSL_TRUE@ lmnsd_ossl_la-nsd_ossl.lo lmnsd_ossl_la_OBJECTS = $(am_lmnsd_ossl_la_OBJECTS) lmnsd_ossl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmnsd_ossl_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_OPENSSL_TRUE@am_lmnsd_ossl_la_rpath = -rpath $(pkglibdir) lmnsd_ptcp_la_DEPENDENCIES = am__lmnsd_ptcp_la_SOURCES_DIST = nsd_ptcp.c nsd_ptcp.h @ENABLE_INET_TRUE@am_lmnsd_ptcp_la_OBJECTS = \ @ENABLE_INET_TRUE@ lmnsd_ptcp_la-nsd_ptcp.lo lmnsd_ptcp_la_OBJECTS = $(am_lmnsd_ptcp_la_OBJECTS) lmnsd_ptcp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmnsd_ptcp_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_INET_TRUE@am_lmnsd_ptcp_la_rpath = -rpath $(pkglibdir) lmregexp_la_DEPENDENCIES = am__lmregexp_la_SOURCES_DIST = regexp.c regexp.h @ENABLE_REGEXP_TRUE@am_lmregexp_la_OBJECTS = lmregexp_la-regexp.lo lmregexp_la_OBJECTS = $(am_lmregexp_la_OBJECTS) lmregexp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmregexp_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_REGEXP_TRUE@am_lmregexp_la_rpath = -rpath $(pkglibdir) lmsig_ksi_ls12_la_LIBADD = am__lmsig_ksi_ls12_la_SOURCES_DIST = lmsig_ksi-ls12.c lmsig_ksi-ls12.h \ lib_ksils12.c lib_ksils12.h lib_ksi_queue.c lib_ksi_queue.h @ENABLE_KSI_LS12_TRUE@am_lmsig_ksi_ls12_la_OBJECTS = \ @ENABLE_KSI_LS12_TRUE@ lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo \ @ENABLE_KSI_LS12_TRUE@ lmsig_ksi_ls12_la-lib_ksils12.lo \ @ENABLE_KSI_LS12_TRUE@ lmsig_ksi_ls12_la-lib_ksi_queue.lo lmsig_ksi_ls12_la_OBJECTS = $(am_lmsig_ksi_ls12_la_OBJECTS) lmsig_ksi_ls12_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(lmsig_ksi_ls12_la_LDFLAGS) $(LDFLAGS) \ -o $@ @ENABLE_KSI_LS12_TRUE@am_lmsig_ksi_ls12_la_rpath = -rpath $(pkglibdir) lmtcpclt_la_DEPENDENCIES = am_lmtcpclt_la_OBJECTS = lmtcpclt_la-tcpclt.lo lmtcpclt_la_OBJECTS = $(am_lmtcpclt_la_OBJECTS) lmtcpclt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmtcpclt_la_LDFLAGS) $(LDFLAGS) -o $@ lmtcpsrv_la_DEPENDENCIES = am_lmtcpsrv_la_OBJECTS = lmtcpsrv_la-tcps_sess.lo \ lmtcpsrv_la-tcpsrv.lo lmtcpsrv_la_OBJECTS = $(am_lmtcpsrv_la_OBJECTS) lmtcpsrv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmtcpsrv_la_LDFLAGS) $(LDFLAGS) -o $@ lmzlibw_la_DEPENDENCIES = am_lmzlibw_la_OBJECTS = lmzlibw_la-zlibw.lo lmzlibw_la_OBJECTS = $(am_lmzlibw_la_OBJECTS) lmzlibw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmzlibw_la_LDFLAGS) $(LDFLAGS) -o $@ lmzstdw_la_DEPENDENCIES = am__lmzstdw_la_SOURCES_DIST = zstdw.c zstdw.h @ENABLE_LIBZSTD_TRUE@am_lmzstdw_la_OBJECTS = lmzstdw_la-zstdw.lo lmzstdw_la_OBJECTS = $(am_lmzstdw_la_OBJECTS) lmzstdw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(lmzstdw_la_LDFLAGS) $(LDFLAGS) -o $@ @ENABLE_LIBZSTD_TRUE@am_lmzstdw_la_rpath = -rpath $(pkglibdir) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ../$(DEPDIR)/librsyslog_la-action.Plo \ ../$(DEPDIR)/librsyslog_la-outchannel.Plo \ ../$(DEPDIR)/librsyslog_la-parse.Plo \ ../$(DEPDIR)/librsyslog_la-template.Plo \ ../$(DEPDIR)/librsyslog_la-threads.Plo \ ./$(DEPDIR)/libgcry_la-libcry_common.Plo \ ./$(DEPDIR)/libgcry_la-libgcry.Plo \ ./$(DEPDIR)/libossl_la-libcry_common.Plo \ ./$(DEPDIR)/libossl_la-libossl.Plo \ ./$(DEPDIR)/librsyslog_la-cfsysline.Plo \ ./$(DEPDIR)/librsyslog_la-conf.Plo \ ./$(DEPDIR)/librsyslog_la-datetime.Plo \ ./$(DEPDIR)/librsyslog_la-debug.Plo \ ./$(DEPDIR)/librsyslog_la-dnscache.Plo \ ./$(DEPDIR)/librsyslog_la-dynstats.Plo \ ./$(DEPDIR)/librsyslog_la-errmsg.Plo \ ./$(DEPDIR)/librsyslog_la-glbl.Plo \ ./$(DEPDIR)/librsyslog_la-hashtable.Plo \ ./$(DEPDIR)/librsyslog_la-hashtable_itr.Plo \ ./$(DEPDIR)/librsyslog_la-janitor.Plo \ ./$(DEPDIR)/librsyslog_la-linkedlist.Plo \ ./$(DEPDIR)/librsyslog_la-lookup.Plo \ ./$(DEPDIR)/librsyslog_la-modules.Plo \ ./$(DEPDIR)/librsyslog_la-msg.Plo \ ./$(DEPDIR)/librsyslog_la-obj.Plo \ ./$(DEPDIR)/librsyslog_la-objomsr.Plo \ ./$(DEPDIR)/librsyslog_la-operatingstate.Plo \ ./$(DEPDIR)/librsyslog_la-parser.Plo \ ./$(DEPDIR)/librsyslog_la-perctile_ringbuf.Plo \ ./$(DEPDIR)/librsyslog_la-perctile_stats.Plo \ ./$(DEPDIR)/librsyslog_la-prop.Plo \ ./$(DEPDIR)/librsyslog_la-queue.Plo \ ./$(DEPDIR)/librsyslog_la-ratelimit.Plo \ ./$(DEPDIR)/librsyslog_la-rsconf.Plo \ ./$(DEPDIR)/librsyslog_la-rsyslog.Plo \ ./$(DEPDIR)/librsyslog_la-ruleset.Plo \ ./$(DEPDIR)/librsyslog_la-srutils.Plo \ ./$(DEPDIR)/librsyslog_la-statsobj.Plo \ ./$(DEPDIR)/librsyslog_la-stream.Plo \ ./$(DEPDIR)/librsyslog_la-strgen.Plo \ ./$(DEPDIR)/librsyslog_la-stringbuf.Plo \ ./$(DEPDIR)/librsyslog_la-timezones.Plo \ ./$(DEPDIR)/librsyslog_la-var.Plo \ ./$(DEPDIR)/librsyslog_la-wti.Plo \ ./$(DEPDIR)/librsyslog_la-wtp.Plo \ ./$(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Plo \ ./$(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Plo \ ./$(DEPDIR)/lmgssutil_la-gss-misc.Plo \ ./$(DEPDIR)/lmnet_la-net.Plo \ ./$(DEPDIR)/lmnet_la-netns_socket.Plo \ ./$(DEPDIR)/lmnetstrms_la-netstrm.Plo \ ./$(DEPDIR)/lmnetstrms_la-netstrms.Plo \ ./$(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Plo \ ./$(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Plo \ ./$(DEPDIR)/lmnsd_ossl_la-net_ossl.Plo \ ./$(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Plo \ ./$(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Plo \ ./$(DEPDIR)/lmregexp_la-regexp.Plo \ ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Plo \ ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Plo \ ./$(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Plo \ ./$(DEPDIR)/lmtcpclt_la-tcpclt.Plo \ ./$(DEPDIR)/lmtcpsrv_la-tcps_sess.Plo \ ./$(DEPDIR)/lmtcpsrv_la-tcpsrv.Plo \ ./$(DEPDIR)/lmzlibw_la-zlibw.Plo \ ./$(DEPDIR)/lmzstdw_la-zstdw.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libgcry_la_SOURCES) $(libossl_la_SOURCES) \ $(librsyslog_la_SOURCES) $(lmcry_gcry_la_SOURCES) \ $(lmcry_ossl_la_SOURCES) $(lmgssutil_la_SOURCES) \ $(lmnet_la_SOURCES) $(lmnetstrms_la_SOURCES) \ $(lmnsd_gtls_la_SOURCES) $(lmnsd_mbedtls_la_SOURCES) \ $(lmnsd_ossl_la_SOURCES) $(lmnsd_ptcp_la_SOURCES) \ $(lmregexp_la_SOURCES) $(lmsig_ksi_ls12_la_SOURCES) \ $(lmtcpclt_la_SOURCES) $(lmtcpsrv_la_SOURCES) \ $(lmzlibw_la_SOURCES) $(lmzstdw_la_SOURCES) DIST_SOURCES = $(am__libgcry_la_SOURCES_DIST) \ $(am__libossl_la_SOURCES_DIST) $(librsyslog_la_SOURCES) \ $(am__lmcry_gcry_la_SOURCES_DIST) \ $(am__lmcry_ossl_la_SOURCES_DIST) \ $(am__lmgssutil_la_SOURCES_DIST) $(lmnet_la_SOURCES) \ $(am__lmnetstrms_la_SOURCES_DIST) \ $(am__lmnsd_gtls_la_SOURCES_DIST) \ $(am__lmnsd_mbedtls_la_SOURCES_DIST) \ $(am__lmnsd_ossl_la_SOURCES_DIST) \ $(am__lmnsd_ptcp_la_SOURCES_DIST) \ $(am__lmregexp_la_SOURCES_DIST) \ $(am__lmsig_ksi_ls12_la_SOURCES_DIST) $(lmtcpclt_la_SOURCES) \ $(lmtcpsrv_la_SOURCES) $(lmzlibw_la_SOURCES) \ $(am__lmzstdw_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = noinst_LIBRARIES = noinst_LTLIBRARIES = librsyslog.la $(am__append_18) $(am__append_20) # # zlib support # # # basic network support, needed for rsyslog startup (e.g. our own system name) # pkglib_LTLIBRARIES = $(am__append_3) lmzlibw.la lmnet.la \ $(am__append_8) $(am__append_15) $(am__append_16) \ $(am__append_17) $(am__append_19) $(am__append_21) \ $(am__append_22) $(am__append_23) lmtcpsrv.la lmtcpclt.la \ $(am__append_28) #pkglib_LTLIBRARIES = librsyslog.la librsyslog_la_SOURCES = \ rsyslog.c \ rsyslog.h \ typedefs.h \ dnscache.c \ dnscache.h \ unicode-helper.h \ atomic.h \ batch.h \ syslogd-types.h \ module-template.h \ im-helper.h \ obj-types.h \ sigprov.h \ cryprov.h \ nsd.h \ glbl.h \ glbl.c \ unlimited_select.h \ conf.c \ conf.h \ janitor.c \ janitor.h \ rsconf.c \ rsconf.h \ parser.h \ parser.c \ strgen.h \ strgen.c \ msg.c \ msg.h \ linkedlist.c \ linkedlist.h \ objomsr.c \ objomsr.h \ stringbuf.c \ stringbuf.h \ datetime.c \ datetime.h \ srutils.c \ srUtils.h \ errmsg.c \ errmsg.h \ operatingstate.c \ operatingstate.h \ debug.c \ debug.h \ obj.c \ obj.h \ modules.c \ modules.h \ statsobj.c \ statsobj.h \ dynstats.c \ dynstats.h \ perctile_ringbuf.c \ perctile_ringbuf.h \ perctile_stats.c \ perctile_stats.h \ statsobj.h \ stream.c \ stream.h \ var.c \ var.h \ wtp.c \ wtp.h \ wti.c \ wti.h \ queue.c \ queue.h \ ruleset.c \ ruleset.h \ prop.c \ prop.h \ ratelimit.c \ ratelimit.h \ lookup.c \ lookup.h \ cfsysline.c \ cfsysline.h \ \ ../action.h \ ../action.c \ ../threads.c \ ../threads.h \ \ ../parse.c \ ../parse.h \ \ hashtable.c \ hashtable.h \ hashtable_itr.c \ hashtable_itr.h \ hashtable_private.h \ \ ../outchannel.c \ ../outchannel.h \ ../template.c \ ../template.h \ timezones.c \ timezones.h #librsyslog_la_LDFLAGS = -module -avoid-version @WITH_MODDIRS_FALSE@librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS \ @WITH_MODDIRS_FALSE@ -D_PATH_MODDIR=\"$(pkglibdir)/\" \ @WITH_MODDIRS_FALSE@ -I\$(top_srcdir) -I\$(top_srcdir)/grammar \ @WITH_MODDIRS_FALSE@ $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ @WITH_MODDIRS_FALSE@ $(LIBUUID_CFLAGS) $(LIBFASTJSON_CFLAGS) \ @WITH_MODDIRS_FALSE@ ${LIBESTR_CFLAGS} $(am__append_1) \ @WITH_MODDIRS_FALSE@ -I\$(top_srcdir)/tools # the files with ../ we need to work on - so that they either become part of the # runtime or will no longer be needed. -- rgerhards, 2008-06-13 # #if OS_LINUX #librsyslog_la_SOURCES += \ #endif #librsyslog_la_LDFLAGS = -module -avoid-version @WITH_MODDIRS_TRUE@librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS \ @WITH_MODDIRS_TRUE@ -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\" \ @WITH_MODDIRS_TRUE@ $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ @WITH_MODDIRS_TRUE@ $(LIBUUID_CFLAGS) $(LIBFASTJSON_CFLAGS) \ @WITH_MODDIRS_TRUE@ ${LIBESTR_CFLAGS} $(am__append_1) \ @WITH_MODDIRS_TRUE@ -I\$(top_srcdir)/tools librsyslog_la_LIBADD = $(DL_LIBS) $(RT_LIBS) $(LIBUUID_LIBS) \ $(LIBFASTJSON_LIBS) ${LIBESTR_LIBS} -lm $(am__append_2) @ENABLE_REGEXP_TRUE@lmregexp_la_SOURCES = regexp.c regexp.h @ENABLE_REGEXP_TRUE@lmregexp_la_CPPFLAGS = $(PTHREADS_CFLAGS) \ @ENABLE_REGEXP_TRUE@ $(RSRT_CFLAGS) $(am__append_4) @ENABLE_REGEXP_TRUE@lmregexp_la_LDFLAGS = -module -avoid-version \ @ENABLE_REGEXP_TRUE@ $(am__append_5) @ENABLE_REGEXP_TRUE@lmregexp_la_LIBADD = lmzlibw_la_SOURCES = zlibw.c zlibw.h lmzlibw_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ $(am__append_6) lmzlibw_la_LDFLAGS = -module -avoid-version $(ZLIB_LIBS) \ $(am__append_7) lmzlibw_la_LIBADD = lmnet_la_SOURCES = net.c net.h netns_socket.c netns_socket.h lmnet_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(am__append_9) lmnet_la_LDFLAGS = -module -avoid-version \ ../compat/compat_la-getifaddrs.lo $(am__append_10) lmnet_la_LIBADD = # network stream master class and stream factory @ENABLE_INET_TRUE@lmnetstrms_la_SOURCES = netstrms.c netstrms.h \ @ENABLE_INET_TRUE@ netstrm.c netstrm.h @ENABLE_INET_TRUE@lmnetstrms_la_CPPFLAGS = $(PTHREADS_CFLAGS) \ @ENABLE_INET_TRUE@ $(RSRT_CFLAGS) $(am__append_11) @ENABLE_INET_TRUE@lmnetstrms_la_LDFLAGS = -module -avoid-version \ @ENABLE_INET_TRUE@ $(am__append_12) @ENABLE_INET_TRUE@lmnetstrms_la_LIBADD = @ENABLE_INET_TRUE@lmnsd_ptcp_la_SOURCES = nsd_ptcp.c nsd_ptcp.h @ENABLE_INET_TRUE@lmnsd_ptcp_la_CPPFLAGS = $(PTHREADS_CFLAGS) \ @ENABLE_INET_TRUE@ $(RSRT_CFLAGS) $(am__append_13) @ENABLE_INET_TRUE@lmnsd_ptcp_la_LDFLAGS = -module -avoid-version \ @ENABLE_INET_TRUE@ $(am__append_14) @ENABLE_INET_TRUE@lmnsd_ptcp_la_LIBADD = @ENABLE_OPENSSL_TRUE@lmnsd_ossl_la_SOURCES = net_ossl.c net_ossl.h nsd_ossl.c nsd_ossl.h @ENABLE_OPENSSL_TRUE@lmnsd_ossl_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(OPENSSL_CFLAGS) @ENABLE_OPENSSL_TRUE@lmnsd_ossl_la_LDFLAGS = -module -avoid-version @ENABLE_OPENSSL_TRUE@lmnsd_ossl_la_LIBADD = $(OPENSSL_LIBS) @ENABLE_GNUTLS_TRUE@lmnsd_gtls_la_SOURCES = nsd_gtls.c nsd_gtls.h @ENABLE_GNUTLS_TRUE@lmnsd_gtls_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(GNUTLS_CFLAGS) @ENABLE_GNUTLS_TRUE@lmnsd_gtls_la_LDFLAGS = -module -avoid-version @ENABLE_GNUTLS_TRUE@lmnsd_gtls_la_LIBADD = $(GNUTLS_LIBS) @ENABLE_MBEDTLS_TRUE@lmnsd_mbedtls_la_SOURCES = nsd_mbedtls.c nsd_mbedtls.h @ENABLE_MBEDTLS_TRUE@lmnsd_mbedtls_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(MBEDTLS_CFLAGS) @ENABLE_MBEDTLS_TRUE@lmnsd_mbedtls_la_LDFLAGS = -module -avoid-version @ENABLE_MBEDTLS_TRUE@lmnsd_mbedtls_la_LIBADD = $(MBEDTLS_LIBS) @ENABLE_LIBGCRYPT_TRUE@libgcry_la_SOURCES = libgcry.c libcry_common.c libcry_common.h libgcry.h @ENABLE_LIBGCRYPT_TRUE@libgcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS) @ENABLE_LIBGCRYPT_TRUE@lmcry_gcry_la_DEPENDENCIES = libgcry.la @ENABLE_LIBGCRYPT_TRUE@lmcry_gcry_la_SOURCES = lmcry_gcry.c lmcry_gcry.h @ENABLE_LIBGCRYPT_TRUE@lmcry_gcry_la_CPPFLAGS = $(RSRT_CFLAGS) $(LIBGCRYPT_CFLAGS) @ENABLE_LIBGCRYPT_TRUE@lmcry_gcry_la_LDFLAGS = -module -avoid-version @ENABLE_LIBGCRYPT_TRUE@lmcry_gcry_la_LIBADD = libgcry.la $(LIBGCRYPT_LIBS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@libossl_la_SOURCES = libossl.c libossl.h libcry_common.c libcry_common.h @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@libossl_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(OPENSSL_CFLAGS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@lmcry_ossl_la_DEPENDENCIES = libossl.la @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@lmcry_ossl_la_SOURCES = lmcry_ossl.c lmcry_ossl.h @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@lmcry_ossl_la_CPPFLAGS = $(RSRT_CFLAGS) $(OPENSSL_FLAGS) @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@lmcry_ossl_la_LDFLAGS = -module -avoid-version @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@lmcry_ossl_la_LIBADD = libossl.la $(OPENSSL_LIBS) @ENABLE_LIBZSTD_TRUE@lmzstdw_la_SOURCES = zstdw.c zstdw.h @ENABLE_LIBZSTD_TRUE@lmzstdw_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) @ENABLE_LIBZSTD_TRUE@lmzstdw_la_LDFLAGS = -module -avoid-version $(ZSTD_LIBS) @ENABLE_LIBZSTD_TRUE@lmzstdw_la_LIBADD = -lzstd @ENABLE_GSSAPI_TRUE@lmgssutil_la_SOURCES = gss-misc.c gss-misc.h @ENABLE_GSSAPI_TRUE@lmgssutil_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) @ENABLE_GSSAPI_TRUE@lmgssutil_la_LDFLAGS = -module -avoid-version @ENABLE_GSSAPI_TRUE@lmgssutil_la_LIBADD = $(GSS_LIBS) # # # TCP (stream) server support # lmtcpsrv_la_SOURCES = \ tcps_sess.c \ tcps_sess.h \ tcpsrv.c \ tcpsrv.h lmtcpsrv_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ $(am__append_24) lmtcpsrv_la_LDFLAGS = -module -avoid-version $(am__append_25) lmtcpsrv_la_LIBADD = # # TCP (stream) client support # lmtcpclt_la_SOURCES = \ tcpclt.c \ tcpclt.h lmtcpclt_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ $(am__append_26) lmtcpclt_la_LDFLAGS = -module -avoid-version $(am__append_27) lmtcpclt_la_LIBADD = @ENABLE_KSI_LS12_TRUE@lmsig_ksi_ls12_la_SOURCES = lmsig_ksi-ls12.c lmsig_ksi-ls12.h lib_ksils12.c \ @ENABLE_KSI_LS12_TRUE@ lib_ksils12.h lib_ksi_queue.c lib_ksi_queue.h @ENABLE_KSI_LS12_TRUE@lmsig_ksi_ls12_la_CPPFLAGS = $(RSRT_CFLAGS) $(GT_KSI_LS12_CFLAGS) @ENABLE_KSI_LS12_TRUE@lmsig_ksi_ls12_la_LDFLAGS = -module -avoid-version $(GT_KSI_LS12_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu runtime/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu runtime/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libgcry.la: $(libgcry_la_OBJECTS) $(libgcry_la_DEPENDENCIES) $(EXTRA_libgcry_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libgcry_la_rpath) $(libgcry_la_OBJECTS) $(libgcry_la_LIBADD) $(LIBS) libossl.la: $(libossl_la_OBJECTS) $(libossl_la_DEPENDENCIES) $(EXTRA_libossl_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(am_libossl_la_rpath) $(libossl_la_OBJECTS) $(libossl_la_LIBADD) $(LIBS) ../$(am__dirstamp): @$(MKDIR_P) .. @: > ../$(am__dirstamp) ../$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../$(DEPDIR) @: > ../$(DEPDIR)/$(am__dirstamp) ../librsyslog_la-action.lo: ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) ../librsyslog_la-threads.lo: ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) ../librsyslog_la-parse.lo: ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) ../librsyslog_la-outchannel.lo: ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) ../librsyslog_la-template.lo: ../$(am__dirstamp) \ ../$(DEPDIR)/$(am__dirstamp) librsyslog.la: $(librsyslog_la_OBJECTS) $(librsyslog_la_DEPENDENCIES) $(EXTRA_librsyslog_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(librsyslog_la_OBJECTS) $(librsyslog_la_LIBADD) $(LIBS) lmcry_gcry.la: $(lmcry_gcry_la_OBJECTS) $(lmcry_gcry_la_DEPENDENCIES) $(EXTRA_lmcry_gcry_la_DEPENDENCIES) $(AM_V_CCLD)$(lmcry_gcry_la_LINK) $(am_lmcry_gcry_la_rpath) $(lmcry_gcry_la_OBJECTS) $(lmcry_gcry_la_LIBADD) $(LIBS) lmcry_ossl.la: $(lmcry_ossl_la_OBJECTS) $(lmcry_ossl_la_DEPENDENCIES) $(EXTRA_lmcry_ossl_la_DEPENDENCIES) $(AM_V_CCLD)$(lmcry_ossl_la_LINK) $(am_lmcry_ossl_la_rpath) $(lmcry_ossl_la_OBJECTS) $(lmcry_ossl_la_LIBADD) $(LIBS) lmgssutil.la: $(lmgssutil_la_OBJECTS) $(lmgssutil_la_DEPENDENCIES) $(EXTRA_lmgssutil_la_DEPENDENCIES) $(AM_V_CCLD)$(lmgssutil_la_LINK) $(am_lmgssutil_la_rpath) $(lmgssutil_la_OBJECTS) $(lmgssutil_la_LIBADD) $(LIBS) lmnet.la: $(lmnet_la_OBJECTS) $(lmnet_la_DEPENDENCIES) $(EXTRA_lmnet_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnet_la_LINK) -rpath $(pkglibdir) $(lmnet_la_OBJECTS) $(lmnet_la_LIBADD) $(LIBS) lmnetstrms.la: $(lmnetstrms_la_OBJECTS) $(lmnetstrms_la_DEPENDENCIES) $(EXTRA_lmnetstrms_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnetstrms_la_LINK) $(am_lmnetstrms_la_rpath) $(lmnetstrms_la_OBJECTS) $(lmnetstrms_la_LIBADD) $(LIBS) lmnsd_gtls.la: $(lmnsd_gtls_la_OBJECTS) $(lmnsd_gtls_la_DEPENDENCIES) $(EXTRA_lmnsd_gtls_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnsd_gtls_la_LINK) $(am_lmnsd_gtls_la_rpath) $(lmnsd_gtls_la_OBJECTS) $(lmnsd_gtls_la_LIBADD) $(LIBS) lmnsd_mbedtls.la: $(lmnsd_mbedtls_la_OBJECTS) $(lmnsd_mbedtls_la_DEPENDENCIES) $(EXTRA_lmnsd_mbedtls_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnsd_mbedtls_la_LINK) $(am_lmnsd_mbedtls_la_rpath) $(lmnsd_mbedtls_la_OBJECTS) $(lmnsd_mbedtls_la_LIBADD) $(LIBS) lmnsd_ossl.la: $(lmnsd_ossl_la_OBJECTS) $(lmnsd_ossl_la_DEPENDENCIES) $(EXTRA_lmnsd_ossl_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnsd_ossl_la_LINK) $(am_lmnsd_ossl_la_rpath) $(lmnsd_ossl_la_OBJECTS) $(lmnsd_ossl_la_LIBADD) $(LIBS) lmnsd_ptcp.la: $(lmnsd_ptcp_la_OBJECTS) $(lmnsd_ptcp_la_DEPENDENCIES) $(EXTRA_lmnsd_ptcp_la_DEPENDENCIES) $(AM_V_CCLD)$(lmnsd_ptcp_la_LINK) $(am_lmnsd_ptcp_la_rpath) $(lmnsd_ptcp_la_OBJECTS) $(lmnsd_ptcp_la_LIBADD) $(LIBS) lmregexp.la: $(lmregexp_la_OBJECTS) $(lmregexp_la_DEPENDENCIES) $(EXTRA_lmregexp_la_DEPENDENCIES) $(AM_V_CCLD)$(lmregexp_la_LINK) $(am_lmregexp_la_rpath) $(lmregexp_la_OBJECTS) $(lmregexp_la_LIBADD) $(LIBS) lmsig_ksi_ls12.la: $(lmsig_ksi_ls12_la_OBJECTS) $(lmsig_ksi_ls12_la_DEPENDENCIES) $(EXTRA_lmsig_ksi_ls12_la_DEPENDENCIES) $(AM_V_CCLD)$(lmsig_ksi_ls12_la_LINK) $(am_lmsig_ksi_ls12_la_rpath) $(lmsig_ksi_ls12_la_OBJECTS) $(lmsig_ksi_ls12_la_LIBADD) $(LIBS) lmtcpclt.la: $(lmtcpclt_la_OBJECTS) $(lmtcpclt_la_DEPENDENCIES) $(EXTRA_lmtcpclt_la_DEPENDENCIES) $(AM_V_CCLD)$(lmtcpclt_la_LINK) -rpath $(pkglibdir) $(lmtcpclt_la_OBJECTS) $(lmtcpclt_la_LIBADD) $(LIBS) lmtcpsrv.la: $(lmtcpsrv_la_OBJECTS) $(lmtcpsrv_la_DEPENDENCIES) $(EXTRA_lmtcpsrv_la_DEPENDENCIES) $(AM_V_CCLD)$(lmtcpsrv_la_LINK) -rpath $(pkglibdir) $(lmtcpsrv_la_OBJECTS) $(lmtcpsrv_la_LIBADD) $(LIBS) lmzlibw.la: $(lmzlibw_la_OBJECTS) $(lmzlibw_la_DEPENDENCIES) $(EXTRA_lmzlibw_la_DEPENDENCIES) $(AM_V_CCLD)$(lmzlibw_la_LINK) -rpath $(pkglibdir) $(lmzlibw_la_OBJECTS) $(lmzlibw_la_LIBADD) $(LIBS) lmzstdw.la: $(lmzstdw_la_OBJECTS) $(lmzstdw_la_DEPENDENCIES) $(EXTRA_lmzstdw_la_DEPENDENCIES) $(AM_V_CCLD)$(lmzstdw_la_LINK) $(am_lmzstdw_la_rpath) $(lmzstdw_la_OBJECTS) $(lmzstdw_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../*.$(OBJEXT) -rm -f ../*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/librsyslog_la-action.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/librsyslog_la-outchannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/librsyslog_la-parse.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/librsyslog_la-template.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@../$(DEPDIR)/librsyslog_la-threads.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcry_la-libcry_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcry_la-libgcry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libossl_la-libcry_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libossl_la-libossl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-cfsysline.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-conf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-datetime.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-debug.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-dnscache.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-dynstats.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-errmsg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-glbl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-hashtable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-hashtable_itr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-janitor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-linkedlist.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-lookup.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-modules.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-msg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-obj.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-objomsr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-operatingstate.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-perctile_ringbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-perctile_stats.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-prop.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-queue.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-ratelimit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-rsconf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-rsyslog.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-ruleset.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-srutils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-statsobj.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-stream.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-strgen.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-stringbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-timezones.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-var.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-wti.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librsyslog_la-wtp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmgssutil_la-gss-misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnet_la-net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnet_la-netns_socket.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnetstrms_la-netstrm.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnetstrms_la-netstrms.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnsd_ossl_la-net_ossl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmregexp_la-regexp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmtcpclt_la-tcpclt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmtcpsrv_la-tcps_sess.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmtcpsrv_la-tcpsrv.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmzlibw_la-zlibw.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lmzstdw_la-zstdw.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libgcry_la-libgcry.lo: libgcry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgcry_la-libgcry.lo -MD -MP -MF $(DEPDIR)/libgcry_la-libgcry.Tpo -c -o libgcry_la-libgcry.lo `test -f 'libgcry.c' || echo '$(srcdir)/'`libgcry.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcry_la-libgcry.Tpo $(DEPDIR)/libgcry_la-libgcry.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libgcry.c' object='libgcry_la-libgcry.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgcry_la-libgcry.lo `test -f 'libgcry.c' || echo '$(srcdir)/'`libgcry.c libgcry_la-libcry_common.lo: libcry_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgcry_la-libcry_common.lo -MD -MP -MF $(DEPDIR)/libgcry_la-libcry_common.Tpo -c -o libgcry_la-libcry_common.lo `test -f 'libcry_common.c' || echo '$(srcdir)/'`libcry_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgcry_la-libcry_common.Tpo $(DEPDIR)/libgcry_la-libcry_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcry_common.c' object='libgcry_la-libcry_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgcry_la-libcry_common.lo `test -f 'libcry_common.c' || echo '$(srcdir)/'`libcry_common.c libossl_la-libossl.lo: libossl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libossl_la-libossl.lo -MD -MP -MF $(DEPDIR)/libossl_la-libossl.Tpo -c -o libossl_la-libossl.lo `test -f 'libossl.c' || echo '$(srcdir)/'`libossl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libossl_la-libossl.Tpo $(DEPDIR)/libossl_la-libossl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libossl.c' object='libossl_la-libossl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libossl_la-libossl.lo `test -f 'libossl.c' || echo '$(srcdir)/'`libossl.c libossl_la-libcry_common.lo: libcry_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libossl_la-libcry_common.lo -MD -MP -MF $(DEPDIR)/libossl_la-libcry_common.Tpo -c -o libossl_la-libcry_common.lo `test -f 'libcry_common.c' || echo '$(srcdir)/'`libcry_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libossl_la-libcry_common.Tpo $(DEPDIR)/libossl_la-libcry_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcry_common.c' object='libossl_la-libcry_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libossl_la-libcry_common.lo `test -f 'libcry_common.c' || echo '$(srcdir)/'`libcry_common.c librsyslog_la-rsyslog.lo: rsyslog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-rsyslog.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-rsyslog.Tpo -c -o librsyslog_la-rsyslog.lo `test -f 'rsyslog.c' || echo '$(srcdir)/'`rsyslog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-rsyslog.Tpo $(DEPDIR)/librsyslog_la-rsyslog.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsyslog.c' object='librsyslog_la-rsyslog.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-rsyslog.lo `test -f 'rsyslog.c' || echo '$(srcdir)/'`rsyslog.c librsyslog_la-dnscache.lo: dnscache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-dnscache.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-dnscache.Tpo -c -o librsyslog_la-dnscache.lo `test -f 'dnscache.c' || echo '$(srcdir)/'`dnscache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-dnscache.Tpo $(DEPDIR)/librsyslog_la-dnscache.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dnscache.c' object='librsyslog_la-dnscache.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-dnscache.lo `test -f 'dnscache.c' || echo '$(srcdir)/'`dnscache.c librsyslog_la-glbl.lo: glbl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-glbl.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-glbl.Tpo -c -o librsyslog_la-glbl.lo `test -f 'glbl.c' || echo '$(srcdir)/'`glbl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-glbl.Tpo $(DEPDIR)/librsyslog_la-glbl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glbl.c' object='librsyslog_la-glbl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-glbl.lo `test -f 'glbl.c' || echo '$(srcdir)/'`glbl.c librsyslog_la-conf.lo: conf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-conf.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-conf.Tpo -c -o librsyslog_la-conf.lo `test -f 'conf.c' || echo '$(srcdir)/'`conf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-conf.Tpo $(DEPDIR)/librsyslog_la-conf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='conf.c' object='librsyslog_la-conf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-conf.lo `test -f 'conf.c' || echo '$(srcdir)/'`conf.c librsyslog_la-janitor.lo: janitor.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-janitor.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-janitor.Tpo -c -o librsyslog_la-janitor.lo `test -f 'janitor.c' || echo '$(srcdir)/'`janitor.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-janitor.Tpo $(DEPDIR)/librsyslog_la-janitor.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='janitor.c' object='librsyslog_la-janitor.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-janitor.lo `test -f 'janitor.c' || echo '$(srcdir)/'`janitor.c librsyslog_la-rsconf.lo: rsconf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-rsconf.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-rsconf.Tpo -c -o librsyslog_la-rsconf.lo `test -f 'rsconf.c' || echo '$(srcdir)/'`rsconf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-rsconf.Tpo $(DEPDIR)/librsyslog_la-rsconf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsconf.c' object='librsyslog_la-rsconf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-rsconf.lo `test -f 'rsconf.c' || echo '$(srcdir)/'`rsconf.c librsyslog_la-parser.lo: parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-parser.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-parser.Tpo -c -o librsyslog_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-parser.Tpo $(DEPDIR)/librsyslog_la-parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='parser.c' object='librsyslog_la-parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c librsyslog_la-strgen.lo: strgen.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-strgen.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-strgen.Tpo -c -o librsyslog_la-strgen.lo `test -f 'strgen.c' || echo '$(srcdir)/'`strgen.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-strgen.Tpo $(DEPDIR)/librsyslog_la-strgen.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strgen.c' object='librsyslog_la-strgen.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-strgen.lo `test -f 'strgen.c' || echo '$(srcdir)/'`strgen.c librsyslog_la-msg.lo: msg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-msg.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-msg.Tpo -c -o librsyslog_la-msg.lo `test -f 'msg.c' || echo '$(srcdir)/'`msg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-msg.Tpo $(DEPDIR)/librsyslog_la-msg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='msg.c' object='librsyslog_la-msg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-msg.lo `test -f 'msg.c' || echo '$(srcdir)/'`msg.c librsyslog_la-linkedlist.lo: linkedlist.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-linkedlist.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-linkedlist.Tpo -c -o librsyslog_la-linkedlist.lo `test -f 'linkedlist.c' || echo '$(srcdir)/'`linkedlist.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-linkedlist.Tpo $(DEPDIR)/librsyslog_la-linkedlist.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='linkedlist.c' object='librsyslog_la-linkedlist.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-linkedlist.lo `test -f 'linkedlist.c' || echo '$(srcdir)/'`linkedlist.c librsyslog_la-objomsr.lo: objomsr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-objomsr.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-objomsr.Tpo -c -o librsyslog_la-objomsr.lo `test -f 'objomsr.c' || echo '$(srcdir)/'`objomsr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-objomsr.Tpo $(DEPDIR)/librsyslog_la-objomsr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='objomsr.c' object='librsyslog_la-objomsr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-objomsr.lo `test -f 'objomsr.c' || echo '$(srcdir)/'`objomsr.c librsyslog_la-stringbuf.lo: stringbuf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-stringbuf.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-stringbuf.Tpo -c -o librsyslog_la-stringbuf.lo `test -f 'stringbuf.c' || echo '$(srcdir)/'`stringbuf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-stringbuf.Tpo $(DEPDIR)/librsyslog_la-stringbuf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stringbuf.c' object='librsyslog_la-stringbuf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-stringbuf.lo `test -f 'stringbuf.c' || echo '$(srcdir)/'`stringbuf.c librsyslog_la-datetime.lo: datetime.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-datetime.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-datetime.Tpo -c -o librsyslog_la-datetime.lo `test -f 'datetime.c' || echo '$(srcdir)/'`datetime.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-datetime.Tpo $(DEPDIR)/librsyslog_la-datetime.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='datetime.c' object='librsyslog_la-datetime.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-datetime.lo `test -f 'datetime.c' || echo '$(srcdir)/'`datetime.c librsyslog_la-srutils.lo: srutils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-srutils.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-srutils.Tpo -c -o librsyslog_la-srutils.lo `test -f 'srutils.c' || echo '$(srcdir)/'`srutils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-srutils.Tpo $(DEPDIR)/librsyslog_la-srutils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='srutils.c' object='librsyslog_la-srutils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-srutils.lo `test -f 'srutils.c' || echo '$(srcdir)/'`srutils.c librsyslog_la-errmsg.lo: errmsg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-errmsg.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-errmsg.Tpo -c -o librsyslog_la-errmsg.lo `test -f 'errmsg.c' || echo '$(srcdir)/'`errmsg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-errmsg.Tpo $(DEPDIR)/librsyslog_la-errmsg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='errmsg.c' object='librsyslog_la-errmsg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-errmsg.lo `test -f 'errmsg.c' || echo '$(srcdir)/'`errmsg.c librsyslog_la-operatingstate.lo: operatingstate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-operatingstate.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-operatingstate.Tpo -c -o librsyslog_la-operatingstate.lo `test -f 'operatingstate.c' || echo '$(srcdir)/'`operatingstate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-operatingstate.Tpo $(DEPDIR)/librsyslog_la-operatingstate.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='operatingstate.c' object='librsyslog_la-operatingstate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-operatingstate.lo `test -f 'operatingstate.c' || echo '$(srcdir)/'`operatingstate.c librsyslog_la-debug.lo: debug.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-debug.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-debug.Tpo -c -o librsyslog_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-debug.Tpo $(DEPDIR)/librsyslog_la-debug.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='debug.c' object='librsyslog_la-debug.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c librsyslog_la-obj.lo: obj.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-obj.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-obj.Tpo -c -o librsyslog_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-obj.Tpo $(DEPDIR)/librsyslog_la-obj.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obj.c' object='librsyslog_la-obj.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c librsyslog_la-modules.lo: modules.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-modules.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-modules.Tpo -c -o librsyslog_la-modules.lo `test -f 'modules.c' || echo '$(srcdir)/'`modules.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-modules.Tpo $(DEPDIR)/librsyslog_la-modules.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules.c' object='librsyslog_la-modules.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-modules.lo `test -f 'modules.c' || echo '$(srcdir)/'`modules.c librsyslog_la-statsobj.lo: statsobj.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-statsobj.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-statsobj.Tpo -c -o librsyslog_la-statsobj.lo `test -f 'statsobj.c' || echo '$(srcdir)/'`statsobj.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-statsobj.Tpo $(DEPDIR)/librsyslog_la-statsobj.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='statsobj.c' object='librsyslog_la-statsobj.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-statsobj.lo `test -f 'statsobj.c' || echo '$(srcdir)/'`statsobj.c librsyslog_la-dynstats.lo: dynstats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-dynstats.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-dynstats.Tpo -c -o librsyslog_la-dynstats.lo `test -f 'dynstats.c' || echo '$(srcdir)/'`dynstats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-dynstats.Tpo $(DEPDIR)/librsyslog_la-dynstats.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dynstats.c' object='librsyslog_la-dynstats.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-dynstats.lo `test -f 'dynstats.c' || echo '$(srcdir)/'`dynstats.c librsyslog_la-perctile_ringbuf.lo: perctile_ringbuf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-perctile_ringbuf.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-perctile_ringbuf.Tpo -c -o librsyslog_la-perctile_ringbuf.lo `test -f 'perctile_ringbuf.c' || echo '$(srcdir)/'`perctile_ringbuf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-perctile_ringbuf.Tpo $(DEPDIR)/librsyslog_la-perctile_ringbuf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='perctile_ringbuf.c' object='librsyslog_la-perctile_ringbuf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-perctile_ringbuf.lo `test -f 'perctile_ringbuf.c' || echo '$(srcdir)/'`perctile_ringbuf.c librsyslog_la-perctile_stats.lo: perctile_stats.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-perctile_stats.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-perctile_stats.Tpo -c -o librsyslog_la-perctile_stats.lo `test -f 'perctile_stats.c' || echo '$(srcdir)/'`perctile_stats.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-perctile_stats.Tpo $(DEPDIR)/librsyslog_la-perctile_stats.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='perctile_stats.c' object='librsyslog_la-perctile_stats.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-perctile_stats.lo `test -f 'perctile_stats.c' || echo '$(srcdir)/'`perctile_stats.c librsyslog_la-stream.lo: stream.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-stream.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-stream.Tpo -c -o librsyslog_la-stream.lo `test -f 'stream.c' || echo '$(srcdir)/'`stream.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-stream.Tpo $(DEPDIR)/librsyslog_la-stream.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='stream.c' object='librsyslog_la-stream.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-stream.lo `test -f 'stream.c' || echo '$(srcdir)/'`stream.c librsyslog_la-var.lo: var.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-var.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-var.Tpo -c -o librsyslog_la-var.lo `test -f 'var.c' || echo '$(srcdir)/'`var.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-var.Tpo $(DEPDIR)/librsyslog_la-var.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='var.c' object='librsyslog_la-var.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-var.lo `test -f 'var.c' || echo '$(srcdir)/'`var.c librsyslog_la-wtp.lo: wtp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-wtp.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-wtp.Tpo -c -o librsyslog_la-wtp.lo `test -f 'wtp.c' || echo '$(srcdir)/'`wtp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-wtp.Tpo $(DEPDIR)/librsyslog_la-wtp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wtp.c' object='librsyslog_la-wtp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-wtp.lo `test -f 'wtp.c' || echo '$(srcdir)/'`wtp.c librsyslog_la-wti.lo: wti.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-wti.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-wti.Tpo -c -o librsyslog_la-wti.lo `test -f 'wti.c' || echo '$(srcdir)/'`wti.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-wti.Tpo $(DEPDIR)/librsyslog_la-wti.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='wti.c' object='librsyslog_la-wti.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-wti.lo `test -f 'wti.c' || echo '$(srcdir)/'`wti.c librsyslog_la-queue.lo: queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-queue.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-queue.Tpo -c -o librsyslog_la-queue.lo `test -f 'queue.c' || echo '$(srcdir)/'`queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-queue.Tpo $(DEPDIR)/librsyslog_la-queue.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='queue.c' object='librsyslog_la-queue.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-queue.lo `test -f 'queue.c' || echo '$(srcdir)/'`queue.c librsyslog_la-ruleset.lo: ruleset.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-ruleset.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-ruleset.Tpo -c -o librsyslog_la-ruleset.lo `test -f 'ruleset.c' || echo '$(srcdir)/'`ruleset.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-ruleset.Tpo $(DEPDIR)/librsyslog_la-ruleset.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ruleset.c' object='librsyslog_la-ruleset.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-ruleset.lo `test -f 'ruleset.c' || echo '$(srcdir)/'`ruleset.c librsyslog_la-prop.lo: prop.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-prop.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-prop.Tpo -c -o librsyslog_la-prop.lo `test -f 'prop.c' || echo '$(srcdir)/'`prop.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-prop.Tpo $(DEPDIR)/librsyslog_la-prop.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='prop.c' object='librsyslog_la-prop.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-prop.lo `test -f 'prop.c' || echo '$(srcdir)/'`prop.c librsyslog_la-ratelimit.lo: ratelimit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-ratelimit.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-ratelimit.Tpo -c -o librsyslog_la-ratelimit.lo `test -f 'ratelimit.c' || echo '$(srcdir)/'`ratelimit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-ratelimit.Tpo $(DEPDIR)/librsyslog_la-ratelimit.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ratelimit.c' object='librsyslog_la-ratelimit.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-ratelimit.lo `test -f 'ratelimit.c' || echo '$(srcdir)/'`ratelimit.c librsyslog_la-lookup.lo: lookup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-lookup.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-lookup.Tpo -c -o librsyslog_la-lookup.lo `test -f 'lookup.c' || echo '$(srcdir)/'`lookup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-lookup.Tpo $(DEPDIR)/librsyslog_la-lookup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lookup.c' object='librsyslog_la-lookup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-lookup.lo `test -f 'lookup.c' || echo '$(srcdir)/'`lookup.c librsyslog_la-cfsysline.lo: cfsysline.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-cfsysline.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-cfsysline.Tpo -c -o librsyslog_la-cfsysline.lo `test -f 'cfsysline.c' || echo '$(srcdir)/'`cfsysline.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-cfsysline.Tpo $(DEPDIR)/librsyslog_la-cfsysline.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cfsysline.c' object='librsyslog_la-cfsysline.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-cfsysline.lo `test -f 'cfsysline.c' || echo '$(srcdir)/'`cfsysline.c ../librsyslog_la-action.lo: ../action.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../librsyslog_la-action.lo -MD -MP -MF ../$(DEPDIR)/librsyslog_la-action.Tpo -c -o ../librsyslog_la-action.lo `test -f '../action.c' || echo '$(srcdir)/'`../action.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/librsyslog_la-action.Tpo ../$(DEPDIR)/librsyslog_la-action.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../action.c' object='../librsyslog_la-action.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../librsyslog_la-action.lo `test -f '../action.c' || echo '$(srcdir)/'`../action.c ../librsyslog_la-threads.lo: ../threads.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../librsyslog_la-threads.lo -MD -MP -MF ../$(DEPDIR)/librsyslog_la-threads.Tpo -c -o ../librsyslog_la-threads.lo `test -f '../threads.c' || echo '$(srcdir)/'`../threads.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/librsyslog_la-threads.Tpo ../$(DEPDIR)/librsyslog_la-threads.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../threads.c' object='../librsyslog_la-threads.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../librsyslog_la-threads.lo `test -f '../threads.c' || echo '$(srcdir)/'`../threads.c ../librsyslog_la-parse.lo: ../parse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../librsyslog_la-parse.lo -MD -MP -MF ../$(DEPDIR)/librsyslog_la-parse.Tpo -c -o ../librsyslog_la-parse.lo `test -f '../parse.c' || echo '$(srcdir)/'`../parse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/librsyslog_la-parse.Tpo ../$(DEPDIR)/librsyslog_la-parse.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../parse.c' object='../librsyslog_la-parse.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../librsyslog_la-parse.lo `test -f '../parse.c' || echo '$(srcdir)/'`../parse.c librsyslog_la-hashtable.lo: hashtable.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-hashtable.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-hashtable.Tpo -c -o librsyslog_la-hashtable.lo `test -f 'hashtable.c' || echo '$(srcdir)/'`hashtable.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-hashtable.Tpo $(DEPDIR)/librsyslog_la-hashtable.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hashtable.c' object='librsyslog_la-hashtable.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-hashtable.lo `test -f 'hashtable.c' || echo '$(srcdir)/'`hashtable.c librsyslog_la-hashtable_itr.lo: hashtable_itr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-hashtable_itr.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-hashtable_itr.Tpo -c -o librsyslog_la-hashtable_itr.lo `test -f 'hashtable_itr.c' || echo '$(srcdir)/'`hashtable_itr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-hashtable_itr.Tpo $(DEPDIR)/librsyslog_la-hashtable_itr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hashtable_itr.c' object='librsyslog_la-hashtable_itr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-hashtable_itr.lo `test -f 'hashtable_itr.c' || echo '$(srcdir)/'`hashtable_itr.c ../librsyslog_la-outchannel.lo: ../outchannel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../librsyslog_la-outchannel.lo -MD -MP -MF ../$(DEPDIR)/librsyslog_la-outchannel.Tpo -c -o ../librsyslog_la-outchannel.lo `test -f '../outchannel.c' || echo '$(srcdir)/'`../outchannel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/librsyslog_la-outchannel.Tpo ../$(DEPDIR)/librsyslog_la-outchannel.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../outchannel.c' object='../librsyslog_la-outchannel.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../librsyslog_la-outchannel.lo `test -f '../outchannel.c' || echo '$(srcdir)/'`../outchannel.c ../librsyslog_la-template.lo: ../template.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ../librsyslog_la-template.lo -MD -MP -MF ../$(DEPDIR)/librsyslog_la-template.Tpo -c -o ../librsyslog_la-template.lo `test -f '../template.c' || echo '$(srcdir)/'`../template.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../$(DEPDIR)/librsyslog_la-template.Tpo ../$(DEPDIR)/librsyslog_la-template.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../template.c' object='../librsyslog_la-template.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ../librsyslog_la-template.lo `test -f '../template.c' || echo '$(srcdir)/'`../template.c librsyslog_la-timezones.lo: timezones.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT librsyslog_la-timezones.lo -MD -MP -MF $(DEPDIR)/librsyslog_la-timezones.Tpo -c -o librsyslog_la-timezones.lo `test -f 'timezones.c' || echo '$(srcdir)/'`timezones.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/librsyslog_la-timezones.Tpo $(DEPDIR)/librsyslog_la-timezones.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='timezones.c' object='librsyslog_la-timezones.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(librsyslog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o librsyslog_la-timezones.lo `test -f 'timezones.c' || echo '$(srcdir)/'`timezones.c lmcry_gcry_la-lmcry_gcry.lo: lmcry_gcry.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmcry_gcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmcry_gcry_la-lmcry_gcry.lo -MD -MP -MF $(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Tpo -c -o lmcry_gcry_la-lmcry_gcry.lo `test -f 'lmcry_gcry.c' || echo '$(srcdir)/'`lmcry_gcry.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Tpo $(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lmcry_gcry.c' object='lmcry_gcry_la-lmcry_gcry.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmcry_gcry_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmcry_gcry_la-lmcry_gcry.lo `test -f 'lmcry_gcry.c' || echo '$(srcdir)/'`lmcry_gcry.c lmcry_ossl_la-lmcry_ossl.lo: lmcry_ossl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmcry_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmcry_ossl_la-lmcry_ossl.lo -MD -MP -MF $(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Tpo -c -o lmcry_ossl_la-lmcry_ossl.lo `test -f 'lmcry_ossl.c' || echo '$(srcdir)/'`lmcry_ossl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Tpo $(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lmcry_ossl.c' object='lmcry_ossl_la-lmcry_ossl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmcry_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmcry_ossl_la-lmcry_ossl.lo `test -f 'lmcry_ossl.c' || echo '$(srcdir)/'`lmcry_ossl.c lmgssutil_la-gss-misc.lo: gss-misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmgssutil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmgssutil_la-gss-misc.lo -MD -MP -MF $(DEPDIR)/lmgssutil_la-gss-misc.Tpo -c -o lmgssutil_la-gss-misc.lo `test -f 'gss-misc.c' || echo '$(srcdir)/'`gss-misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmgssutil_la-gss-misc.Tpo $(DEPDIR)/lmgssutil_la-gss-misc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gss-misc.c' object='lmgssutil_la-gss-misc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmgssutil_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmgssutil_la-gss-misc.lo `test -f 'gss-misc.c' || echo '$(srcdir)/'`gss-misc.c lmnet_la-net.lo: net.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnet_la-net.lo -MD -MP -MF $(DEPDIR)/lmnet_la-net.Tpo -c -o lmnet_la-net.lo `test -f 'net.c' || echo '$(srcdir)/'`net.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnet_la-net.Tpo $(DEPDIR)/lmnet_la-net.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net.c' object='lmnet_la-net.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnet_la-net.lo `test -f 'net.c' || echo '$(srcdir)/'`net.c lmnet_la-netns_socket.lo: netns_socket.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnet_la-netns_socket.lo -MD -MP -MF $(DEPDIR)/lmnet_la-netns_socket.Tpo -c -o lmnet_la-netns_socket.lo `test -f 'netns_socket.c' || echo '$(srcdir)/'`netns_socket.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnet_la-netns_socket.Tpo $(DEPDIR)/lmnet_la-netns_socket.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netns_socket.c' object='lmnet_la-netns_socket.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnet_la-netns_socket.lo `test -f 'netns_socket.c' || echo '$(srcdir)/'`netns_socket.c lmnetstrms_la-netstrms.lo: netstrms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnetstrms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnetstrms_la-netstrms.lo -MD -MP -MF $(DEPDIR)/lmnetstrms_la-netstrms.Tpo -c -o lmnetstrms_la-netstrms.lo `test -f 'netstrms.c' || echo '$(srcdir)/'`netstrms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnetstrms_la-netstrms.Tpo $(DEPDIR)/lmnetstrms_la-netstrms.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netstrms.c' object='lmnetstrms_la-netstrms.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnetstrms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnetstrms_la-netstrms.lo `test -f 'netstrms.c' || echo '$(srcdir)/'`netstrms.c lmnetstrms_la-netstrm.lo: netstrm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnetstrms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnetstrms_la-netstrm.lo -MD -MP -MF $(DEPDIR)/lmnetstrms_la-netstrm.Tpo -c -o lmnetstrms_la-netstrm.lo `test -f 'netstrm.c' || echo '$(srcdir)/'`netstrm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnetstrms_la-netstrm.Tpo $(DEPDIR)/lmnetstrms_la-netstrm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='netstrm.c' object='lmnetstrms_la-netstrm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnetstrms_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnetstrms_la-netstrm.lo `test -f 'netstrm.c' || echo '$(srcdir)/'`netstrm.c lmnsd_gtls_la-nsd_gtls.lo: nsd_gtls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_gtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnsd_gtls_la-nsd_gtls.lo -MD -MP -MF $(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Tpo -c -o lmnsd_gtls_la-nsd_gtls.lo `test -f 'nsd_gtls.c' || echo '$(srcdir)/'`nsd_gtls.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Tpo $(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nsd_gtls.c' object='lmnsd_gtls_la-nsd_gtls.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_gtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnsd_gtls_la-nsd_gtls.lo `test -f 'nsd_gtls.c' || echo '$(srcdir)/'`nsd_gtls.c lmnsd_mbedtls_la-nsd_mbedtls.lo: nsd_mbedtls.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_mbedtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnsd_mbedtls_la-nsd_mbedtls.lo -MD -MP -MF $(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Tpo -c -o lmnsd_mbedtls_la-nsd_mbedtls.lo `test -f 'nsd_mbedtls.c' || echo '$(srcdir)/'`nsd_mbedtls.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Tpo $(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nsd_mbedtls.c' object='lmnsd_mbedtls_la-nsd_mbedtls.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_mbedtls_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnsd_mbedtls_la-nsd_mbedtls.lo `test -f 'nsd_mbedtls.c' || echo '$(srcdir)/'`nsd_mbedtls.c lmnsd_ossl_la-net_ossl.lo: net_ossl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnsd_ossl_la-net_ossl.lo -MD -MP -MF $(DEPDIR)/lmnsd_ossl_la-net_ossl.Tpo -c -o lmnsd_ossl_la-net_ossl.lo `test -f 'net_ossl.c' || echo '$(srcdir)/'`net_ossl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnsd_ossl_la-net_ossl.Tpo $(DEPDIR)/lmnsd_ossl_la-net_ossl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='net_ossl.c' object='lmnsd_ossl_la-net_ossl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnsd_ossl_la-net_ossl.lo `test -f 'net_ossl.c' || echo '$(srcdir)/'`net_ossl.c lmnsd_ossl_la-nsd_ossl.lo: nsd_ossl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnsd_ossl_la-nsd_ossl.lo -MD -MP -MF $(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Tpo -c -o lmnsd_ossl_la-nsd_ossl.lo `test -f 'nsd_ossl.c' || echo '$(srcdir)/'`nsd_ossl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Tpo $(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nsd_ossl.c' object='lmnsd_ossl_la-nsd_ossl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ossl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnsd_ossl_la-nsd_ossl.lo `test -f 'nsd_ossl.c' || echo '$(srcdir)/'`nsd_ossl.c lmnsd_ptcp_la-nsd_ptcp.lo: nsd_ptcp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ptcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmnsd_ptcp_la-nsd_ptcp.lo -MD -MP -MF $(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Tpo -c -o lmnsd_ptcp_la-nsd_ptcp.lo `test -f 'nsd_ptcp.c' || echo '$(srcdir)/'`nsd_ptcp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Tpo $(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nsd_ptcp.c' object='lmnsd_ptcp_la-nsd_ptcp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmnsd_ptcp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmnsd_ptcp_la-nsd_ptcp.lo `test -f 'nsd_ptcp.c' || echo '$(srcdir)/'`nsd_ptcp.c lmregexp_la-regexp.lo: regexp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmregexp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmregexp_la-regexp.lo -MD -MP -MF $(DEPDIR)/lmregexp_la-regexp.Tpo -c -o lmregexp_la-regexp.lo `test -f 'regexp.c' || echo '$(srcdir)/'`regexp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmregexp_la-regexp.Tpo $(DEPDIR)/lmregexp_la-regexp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='regexp.c' object='lmregexp_la-regexp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmregexp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmregexp_la-regexp.lo `test -f 'regexp.c' || echo '$(srcdir)/'`regexp.c lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo: lmsig_ksi-ls12.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo -MD -MP -MF $(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Tpo -c -o lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo `test -f 'lmsig_ksi-ls12.c' || echo '$(srcdir)/'`lmsig_ksi-ls12.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Tpo $(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lmsig_ksi-ls12.c' object='lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmsig_ksi_ls12_la-lmsig_ksi-ls12.lo `test -f 'lmsig_ksi-ls12.c' || echo '$(srcdir)/'`lmsig_ksi-ls12.c lmsig_ksi_ls12_la-lib_ksils12.lo: lib_ksils12.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmsig_ksi_ls12_la-lib_ksils12.lo -MD -MP -MF $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Tpo -c -o lmsig_ksi_ls12_la-lib_ksils12.lo `test -f 'lib_ksils12.c' || echo '$(srcdir)/'`lib_ksils12.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Tpo $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib_ksils12.c' object='lmsig_ksi_ls12_la-lib_ksils12.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmsig_ksi_ls12_la-lib_ksils12.lo `test -f 'lib_ksils12.c' || echo '$(srcdir)/'`lib_ksils12.c lmsig_ksi_ls12_la-lib_ksi_queue.lo: lib_ksi_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmsig_ksi_ls12_la-lib_ksi_queue.lo -MD -MP -MF $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Tpo -c -o lmsig_ksi_ls12_la-lib_ksi_queue.lo `test -f 'lib_ksi_queue.c' || echo '$(srcdir)/'`lib_ksi_queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Tpo $(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='lib_ksi_queue.c' object='lmsig_ksi_ls12_la-lib_ksi_queue.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmsig_ksi_ls12_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmsig_ksi_ls12_la-lib_ksi_queue.lo `test -f 'lib_ksi_queue.c' || echo '$(srcdir)/'`lib_ksi_queue.c lmtcpclt_la-tcpclt.lo: tcpclt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpclt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmtcpclt_la-tcpclt.lo -MD -MP -MF $(DEPDIR)/lmtcpclt_la-tcpclt.Tpo -c -o lmtcpclt_la-tcpclt.lo `test -f 'tcpclt.c' || echo '$(srcdir)/'`tcpclt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmtcpclt_la-tcpclt.Tpo $(DEPDIR)/lmtcpclt_la-tcpclt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcpclt.c' object='lmtcpclt_la-tcpclt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpclt_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmtcpclt_la-tcpclt.lo `test -f 'tcpclt.c' || echo '$(srcdir)/'`tcpclt.c lmtcpsrv_la-tcps_sess.lo: tcps_sess.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpsrv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmtcpsrv_la-tcps_sess.lo -MD -MP -MF $(DEPDIR)/lmtcpsrv_la-tcps_sess.Tpo -c -o lmtcpsrv_la-tcps_sess.lo `test -f 'tcps_sess.c' || echo '$(srcdir)/'`tcps_sess.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmtcpsrv_la-tcps_sess.Tpo $(DEPDIR)/lmtcpsrv_la-tcps_sess.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcps_sess.c' object='lmtcpsrv_la-tcps_sess.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpsrv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmtcpsrv_la-tcps_sess.lo `test -f 'tcps_sess.c' || echo '$(srcdir)/'`tcps_sess.c lmtcpsrv_la-tcpsrv.lo: tcpsrv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpsrv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmtcpsrv_la-tcpsrv.lo -MD -MP -MF $(DEPDIR)/lmtcpsrv_la-tcpsrv.Tpo -c -o lmtcpsrv_la-tcpsrv.lo `test -f 'tcpsrv.c' || echo '$(srcdir)/'`tcpsrv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmtcpsrv_la-tcpsrv.Tpo $(DEPDIR)/lmtcpsrv_la-tcpsrv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcpsrv.c' object='lmtcpsrv_la-tcpsrv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmtcpsrv_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmtcpsrv_la-tcpsrv.lo `test -f 'tcpsrv.c' || echo '$(srcdir)/'`tcpsrv.c lmzlibw_la-zlibw.lo: zlibw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmzlibw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmzlibw_la-zlibw.lo -MD -MP -MF $(DEPDIR)/lmzlibw_la-zlibw.Tpo -c -o lmzlibw_la-zlibw.lo `test -f 'zlibw.c' || echo '$(srcdir)/'`zlibw.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmzlibw_la-zlibw.Tpo $(DEPDIR)/lmzlibw_la-zlibw.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='zlibw.c' object='lmzlibw_la-zlibw.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmzlibw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmzlibw_la-zlibw.lo `test -f 'zlibw.c' || echo '$(srcdir)/'`zlibw.c lmzstdw_la-zstdw.lo: zstdw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmzstdw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lmzstdw_la-zstdw.lo -MD -MP -MF $(DEPDIR)/lmzstdw_la-zstdw.Tpo -c -o lmzstdw_la-zstdw.lo `test -f 'zstdw.c' || echo '$(srcdir)/'`zstdw.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lmzstdw_la-zstdw.Tpo $(DEPDIR)/lmzstdw_la-zstdw.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='zstdw.c' object='lmzstdw_la-zstdw.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lmzstdw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lmzstdw_la-zstdw.lo `test -f 'zstdw.c' || echo '$(srcdir)/'`zstdw.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf ../.libs ../_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f ../$(DEPDIR)/$(am__dirstamp) -rm -f ../$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -f ../$(DEPDIR)/librsyslog_la-action.Plo -rm -f ../$(DEPDIR)/librsyslog_la-outchannel.Plo -rm -f ../$(DEPDIR)/librsyslog_la-parse.Plo -rm -f ../$(DEPDIR)/librsyslog_la-template.Plo -rm -f ../$(DEPDIR)/librsyslog_la-threads.Plo -rm -f ./$(DEPDIR)/libgcry_la-libcry_common.Plo -rm -f ./$(DEPDIR)/libgcry_la-libgcry.Plo -rm -f ./$(DEPDIR)/libossl_la-libcry_common.Plo -rm -f ./$(DEPDIR)/libossl_la-libossl.Plo -rm -f ./$(DEPDIR)/librsyslog_la-cfsysline.Plo -rm -f ./$(DEPDIR)/librsyslog_la-conf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-datetime.Plo -rm -f ./$(DEPDIR)/librsyslog_la-debug.Plo -rm -f ./$(DEPDIR)/librsyslog_la-dnscache.Plo -rm -f ./$(DEPDIR)/librsyslog_la-dynstats.Plo -rm -f ./$(DEPDIR)/librsyslog_la-errmsg.Plo -rm -f ./$(DEPDIR)/librsyslog_la-glbl.Plo -rm -f ./$(DEPDIR)/librsyslog_la-hashtable.Plo -rm -f ./$(DEPDIR)/librsyslog_la-hashtable_itr.Plo -rm -f ./$(DEPDIR)/librsyslog_la-janitor.Plo -rm -f ./$(DEPDIR)/librsyslog_la-linkedlist.Plo -rm -f ./$(DEPDIR)/librsyslog_la-lookup.Plo -rm -f ./$(DEPDIR)/librsyslog_la-modules.Plo -rm -f ./$(DEPDIR)/librsyslog_la-msg.Plo -rm -f ./$(DEPDIR)/librsyslog_la-obj.Plo -rm -f ./$(DEPDIR)/librsyslog_la-objomsr.Plo -rm -f ./$(DEPDIR)/librsyslog_la-operatingstate.Plo -rm -f ./$(DEPDIR)/librsyslog_la-parser.Plo -rm -f ./$(DEPDIR)/librsyslog_la-perctile_ringbuf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-perctile_stats.Plo -rm -f ./$(DEPDIR)/librsyslog_la-prop.Plo -rm -f ./$(DEPDIR)/librsyslog_la-queue.Plo -rm -f ./$(DEPDIR)/librsyslog_la-ratelimit.Plo -rm -f ./$(DEPDIR)/librsyslog_la-rsconf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-rsyslog.Plo -rm -f ./$(DEPDIR)/librsyslog_la-ruleset.Plo -rm -f ./$(DEPDIR)/librsyslog_la-srutils.Plo -rm -f ./$(DEPDIR)/librsyslog_la-statsobj.Plo -rm -f ./$(DEPDIR)/librsyslog_la-stream.Plo -rm -f ./$(DEPDIR)/librsyslog_la-strgen.Plo -rm -f ./$(DEPDIR)/librsyslog_la-stringbuf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-timezones.Plo -rm -f ./$(DEPDIR)/librsyslog_la-var.Plo -rm -f ./$(DEPDIR)/librsyslog_la-wti.Plo -rm -f ./$(DEPDIR)/librsyslog_la-wtp.Plo -rm -f ./$(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Plo -rm -f ./$(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Plo -rm -f ./$(DEPDIR)/lmgssutil_la-gss-misc.Plo -rm -f ./$(DEPDIR)/lmnet_la-net.Plo -rm -f ./$(DEPDIR)/lmnet_la-netns_socket.Plo -rm -f ./$(DEPDIR)/lmnetstrms_la-netstrm.Plo -rm -f ./$(DEPDIR)/lmnetstrms_la-netstrms.Plo -rm -f ./$(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Plo -rm -f ./$(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Plo -rm -f ./$(DEPDIR)/lmnsd_ossl_la-net_ossl.Plo -rm -f ./$(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Plo -rm -f ./$(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Plo -rm -f ./$(DEPDIR)/lmregexp_la-regexp.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Plo -rm -f ./$(DEPDIR)/lmtcpclt_la-tcpclt.Plo -rm -f ./$(DEPDIR)/lmtcpsrv_la-tcps_sess.Plo -rm -f ./$(DEPDIR)/lmtcpsrv_la-tcpsrv.Plo -rm -f ./$(DEPDIR)/lmzlibw_la-zlibw.Plo -rm -f ./$(DEPDIR)/lmzstdw_la-zstdw.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-sbinPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ../$(DEPDIR)/librsyslog_la-action.Plo -rm -f ../$(DEPDIR)/librsyslog_la-outchannel.Plo -rm -f ../$(DEPDIR)/librsyslog_la-parse.Plo -rm -f ../$(DEPDIR)/librsyslog_la-template.Plo -rm -f ../$(DEPDIR)/librsyslog_la-threads.Plo -rm -f ./$(DEPDIR)/libgcry_la-libcry_common.Plo -rm -f ./$(DEPDIR)/libgcry_la-libgcry.Plo -rm -f ./$(DEPDIR)/libossl_la-libcry_common.Plo -rm -f ./$(DEPDIR)/libossl_la-libossl.Plo -rm -f ./$(DEPDIR)/librsyslog_la-cfsysline.Plo -rm -f ./$(DEPDIR)/librsyslog_la-conf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-datetime.Plo -rm -f ./$(DEPDIR)/librsyslog_la-debug.Plo -rm -f ./$(DEPDIR)/librsyslog_la-dnscache.Plo -rm -f ./$(DEPDIR)/librsyslog_la-dynstats.Plo -rm -f ./$(DEPDIR)/librsyslog_la-errmsg.Plo -rm -f ./$(DEPDIR)/librsyslog_la-glbl.Plo -rm -f ./$(DEPDIR)/librsyslog_la-hashtable.Plo -rm -f ./$(DEPDIR)/librsyslog_la-hashtable_itr.Plo -rm -f ./$(DEPDIR)/librsyslog_la-janitor.Plo -rm -f ./$(DEPDIR)/librsyslog_la-linkedlist.Plo -rm -f ./$(DEPDIR)/librsyslog_la-lookup.Plo -rm -f ./$(DEPDIR)/librsyslog_la-modules.Plo -rm -f ./$(DEPDIR)/librsyslog_la-msg.Plo -rm -f ./$(DEPDIR)/librsyslog_la-obj.Plo -rm -f ./$(DEPDIR)/librsyslog_la-objomsr.Plo -rm -f ./$(DEPDIR)/librsyslog_la-operatingstate.Plo -rm -f ./$(DEPDIR)/librsyslog_la-parser.Plo -rm -f ./$(DEPDIR)/librsyslog_la-perctile_ringbuf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-perctile_stats.Plo -rm -f ./$(DEPDIR)/librsyslog_la-prop.Plo -rm -f ./$(DEPDIR)/librsyslog_la-queue.Plo -rm -f ./$(DEPDIR)/librsyslog_la-ratelimit.Plo -rm -f ./$(DEPDIR)/librsyslog_la-rsconf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-rsyslog.Plo -rm -f ./$(DEPDIR)/librsyslog_la-ruleset.Plo -rm -f ./$(DEPDIR)/librsyslog_la-srutils.Plo -rm -f ./$(DEPDIR)/librsyslog_la-statsobj.Plo -rm -f ./$(DEPDIR)/librsyslog_la-stream.Plo -rm -f ./$(DEPDIR)/librsyslog_la-strgen.Plo -rm -f ./$(DEPDIR)/librsyslog_la-stringbuf.Plo -rm -f ./$(DEPDIR)/librsyslog_la-timezones.Plo -rm -f ./$(DEPDIR)/librsyslog_la-var.Plo -rm -f ./$(DEPDIR)/librsyslog_la-wti.Plo -rm -f ./$(DEPDIR)/librsyslog_la-wtp.Plo -rm -f ./$(DEPDIR)/lmcry_gcry_la-lmcry_gcry.Plo -rm -f ./$(DEPDIR)/lmcry_ossl_la-lmcry_ossl.Plo -rm -f ./$(DEPDIR)/lmgssutil_la-gss-misc.Plo -rm -f ./$(DEPDIR)/lmnet_la-net.Plo -rm -f ./$(DEPDIR)/lmnet_la-netns_socket.Plo -rm -f ./$(DEPDIR)/lmnetstrms_la-netstrm.Plo -rm -f ./$(DEPDIR)/lmnetstrms_la-netstrms.Plo -rm -f ./$(DEPDIR)/lmnsd_gtls_la-nsd_gtls.Plo -rm -f ./$(DEPDIR)/lmnsd_mbedtls_la-nsd_mbedtls.Plo -rm -f ./$(DEPDIR)/lmnsd_ossl_la-net_ossl.Plo -rm -f ./$(DEPDIR)/lmnsd_ossl_la-nsd_ossl.Plo -rm -f ./$(DEPDIR)/lmnsd_ptcp_la-nsd_ptcp.Plo -rm -f ./$(DEPDIR)/lmregexp_la-regexp.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksi_queue.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lib_ksils12.Plo -rm -f ./$(DEPDIR)/lmsig_ksi_ls12_la-lmsig_ksi-ls12.Plo -rm -f ./$(DEPDIR)/lmtcpclt_la-tcpclt.Plo -rm -f ./$(DEPDIR)/lmtcpsrv_la-tcps_sess.Plo -rm -f ./$(DEPDIR)/lmtcpsrv_la-tcpsrv.Plo -rm -f ./$(DEPDIR)/lmzlibw_la-zlibw.Plo -rm -f ./$(DEPDIR)/lmzstdw_la-zstdw.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES uninstall-sbinPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES \ clean-sbinPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-pkglibLTLIBRARIES \ install-ps install-ps-am install-sbinPROGRAMS install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am \ uninstall-pkglibLTLIBRARIES uninstall-sbinPROGRAMS .PRECIOUS: Makefile # # support library for openssl crypto provider # @ENABLE_OPENSSL_CRYPTO_PROVIDER_TRUE@ # Helper # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/runtime/PaxHeaders/lib_ksi_queue.c0000644000000000000000000000013215055605325017206 xustar0030 mtime=1756826325.645800623 30 atime=1764931131.099158711 30 ctime=1764935923.395579826 rsyslog-8.2512.0/runtime/lib_ksi_queue.c0000664000175000017500000001321015055605325016647 0ustar00rgerrger#define _POSIX_C_SOURCE 199309L #include #include #include #include "lib_ksi_queue.h" RingBuffer* RingBuffer_new(size_t size) { RingBuffer* p = calloc(1, sizeof(RingBuffer)); if (!p) return NULL; p->buffer = calloc(size, sizeof(void*)); p->size = size; return p; } void RingBuffer_free(RingBuffer* this) { if (this->buffer != NULL) free(this->buffer); free(this); } static bool RingBuffer_grow(RingBuffer* this) { void** pTmp = calloc(this->size * RB_GROW_FACTOR, sizeof(void*)); void* pTmpItem = NULL; if (!pTmp) return false; for (size_t i = 0; i < this->size; ++i) { RingBuffer_popFront(this, &pTmpItem); pTmp[i] = pTmpItem; } free(this->buffer); this->buffer = pTmp; this->head = 0; this->tail = this->size; this->count = this->size; this->size = this->size * RB_GROW_FACTOR; return true; } bool RingBuffer_pushBack(RingBuffer* this, void* item) { if (this->size == this->count && !RingBuffer_grow(this)) return false; if (this->size == 0) return false; this->buffer[this->tail] = item; this->tail = (this->tail + 1) % this->size; this->count += 1; return true; } bool RingBuffer_popFront(RingBuffer* this, void** item) { if (this->count == 0) return false; *item = this->buffer[this->head]; this->buffer[this->head] = NULL; this->count -= 1; this->head = (this->head + 1) % this->size; return true; } bool RingBuffer_peekFront(RingBuffer* this, void** item) { if (this->count == 0) return false; *item = this->buffer[this->head]; return true; } size_t RingBuffer_count(RingBuffer* this) { return this->count; } bool RingBuffer_getItem(RingBuffer* this, size_t index, void** item) { if (this->count == 0 || index >= this->count) return false; *item = this->buffer[(this->head + index) % this->size]; return true; } ProtectedQueue* ProtectedQueue_new(size_t queueSize) { ProtectedQueue* p = calloc(1, sizeof(ProtectedQueue)); if (!p) return NULL; pthread_mutex_init(&p->mutex, 0); p->bStop = false; p->workItems = RingBuffer_new(queueSize); return p; } void ProtectedQueue_free(ProtectedQueue* this) { pthread_mutex_destroy(&this->mutex); pthread_cond_destroy(&this->condition); this->bStop = true; RingBuffer_free(this->workItems); free(this); } /// Signal stop. All threads waiting in FetchItme will be returned false from FetchItem void ProtectedQueue_stop(ProtectedQueue* this) { this->bStop = true; pthread_cond_broadcast(&this->condition); } /// Atomically adds an item into work item queue and releases a thread waiting /// in FetchItem bool ProtectedQueue_addItem(ProtectedQueue* this, void* item) { bool ret = false; if (this->bStop) return false; pthread_mutex_lock(&this->mutex); if ((ret = RingBuffer_pushBack(this->workItems, item)) == true) pthread_cond_signal(&this->condition); pthread_mutex_unlock(&this->mutex); return ret; } bool ProtectedQueue_peekFront(ProtectedQueue* this, void** item) { bool ret; pthread_mutex_lock(&this->mutex); ret = RingBuffer_peekFront(this->workItems, item); pthread_mutex_unlock(&this->mutex); return ret; } bool ProtectedQueue_popFront(ProtectedQueue* this, void** item) { bool ret; pthread_mutex_lock(&this->mutex); ret = RingBuffer_popFront(this->workItems, item); pthread_mutex_unlock(&this->mutex); return ret; } size_t ProtectedQueue_popFrontBatch(ProtectedQueue* this, void** items, size_t bufSize) { size_t i; pthread_mutex_lock(&this->mutex); for (i = 0; RingBuffer_count(this->workItems) > 0 && i < bufSize; ++i) RingBuffer_popFront(this->workItems, items[i]); pthread_mutex_unlock(&this->mutex); return i; } bool ProtectedQueue_getItem(ProtectedQueue* this, size_t index, void** item) { bool ret = false; pthread_mutex_lock(&this->mutex); ret = RingBuffer_getItem(this->workItems, index, item); pthread_mutex_unlock(&this->mutex); return ret; } /* Waits for a new work item or timeout (if specified). Returns 0 in case of exit * condition, 1 if item became available and ETIMEDOUT in case of timeout. */ int ProtectedQueue_waitForItem(ProtectedQueue* this, void** item, uint64_t timeout) { struct timespec ts; pthread_mutex_lock(&this->mutex); if (timeout > 0) { clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += timeout / 1000LL; ts.tv_nsec += (timeout % 1000LL) * 1000LL; } if (timeout) { if (pthread_cond_timedwait(&this->condition, &this->mutex, &ts) == ETIMEDOUT) { pthread_mutex_unlock(&this->mutex); return ETIMEDOUT; } } else pthread_cond_wait(&this->condition, &this->mutex); if (this->bStop) { pthread_mutex_unlock(&this->mutex); return 0; } if (RingBuffer_count(this->workItems) != 0 && item != NULL) RingBuffer_popFront(this->workItems, item); pthread_mutex_unlock(&this->mutex); return 1; } size_t ProtectedQueue_count(ProtectedQueue* this) { size_t nCount; pthread_mutex_lock(&this->mutex); nCount = RingBuffer_count(this->workItems); pthread_mutex_unlock(&this->mutex); return nCount; } void* worker_thread_main(void* arg) { int res; void* item; WorkerThreadContext* tc = (WorkerThreadContext*)arg; while (1) { item = NULL; res = ProtectedQueue_waitForItem(tc->queue, &item, tc->timeout); if (tc->queue->bStop) return NULL; if (res == ETIMEDOUT) { if (!tc->timeoutFunc()) return NULL; } else if (item != NULL && !tc->workerFunc(item)) return NULL; } } rsyslog-8.2512.0/runtime/PaxHeaders/hashtable_itr.c0000644000000000000000000000013215055605325017177 xustar0030 mtime=1756826325.645800623 30 atime=1764931000.592021381 30 ctime=1764935923.302578403 rsyslog-8.2512.0/runtime/hashtable_itr.c0000664000175000017500000001315715055605325016652 0ustar00rgerrger/* Copyright (C) 2002, 2004 Christopher Clark */ #include "hashtable_private.h" #include "hashtable_itr.h" #include /* defines NULL */ /*****************************************************************************/ /* hashtable_iterator - iterator constructor */ struct hashtable_itr *hashtable_iterator(struct hashtable *h) { unsigned int i, tablelength; struct hashtable_itr *itr = (struct hashtable_itr *)malloc(sizeof(struct hashtable_itr)); if (NULL == itr) return NULL; itr->h = h; itr->e = NULL; itr->parent = NULL; tablelength = h->tablelength; itr->index = tablelength; if (0 == h->entrycount) return itr; for (i = 0; i < tablelength; i++) { if (NULL != h->table[i]) { itr->e = h->table[i]; itr->index = i; break; } } return itr; } /*****************************************************************************/ /* key - return the key of the (key,value) pair at the current position */ /* value - return the value of the (key,value) pair at the current position */ #if 0 /* these are now inline functions! */ void * hashtable_iterator_key(struct hashtable_itr *i) { return i->e->k; } void * hashtable_iterator_value(struct hashtable_itr *i) { return i->e->v; } #endif /*****************************************************************************/ /* advance - advance the iterator to the next element * returns zero if advanced to end of table */ int hashtable_iterator_advance(struct hashtable_itr *itr) { unsigned int j, tablelength; struct entry **table; struct entry *next; if (NULL == itr->e) return 0; /* stupidity check */ next = itr->e->next; if (NULL != next) { itr->parent = itr->e; itr->e = next; return -1; } tablelength = itr->h->tablelength; itr->parent = NULL; if (tablelength <= (j = ++(itr->index))) { itr->e = NULL; return 0; } table = itr->h->table; while (NULL == (next = table[j])) { if (++j >= tablelength) { itr->index = tablelength; itr->e = NULL; return 0; } } itr->index = j; itr->e = next; return -1; } /*****************************************************************************/ /* remove - remove the entry at the current iterator position * and advance the iterator, if there is a successive * element. * If you want the value, read it before you remove: * beware memory leaks if you don't. * Returns zero if end of iteration. */ int hashtable_iterator_remove(struct hashtable_itr *itr) { struct entry *remember_e, *remember_parent; int ret; /* Do the removal */ if (NULL == (itr->parent)) { /* element is head of a chain */ itr->h->table[itr->index] = itr->e->next; } else { /* element is mid-chain */ itr->parent->next = itr->e->next; } /* itr->e is now outside the hashtable */ remember_e = itr->e; itr->h->entrycount--; freekey(remember_e->k); /* Advance the iterator, correcting the parent */ remember_parent = itr->parent; ret = hashtable_iterator_advance(itr); if (itr->parent == remember_e) { itr->parent = remember_parent; } free(remember_e); return ret; } /*****************************************************************************/ int /* returns zero if not found */ hashtable_iterator_search(struct hashtable_itr *itr, struct hashtable *h, void *k) { struct entry *e, *parent; unsigned int hashvalue, index; hashvalue = hash(h, k); index = indexFor(h->tablelength, hashvalue); e = h->table[index]; parent = NULL; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { itr->index = index; itr->e = e; itr->parent = parent; itr->h = h; return -1; } parent = e; e = e->next; } return 0; } /* * Copyright (c) 2002, 2004, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ rsyslog-8.2512.0/runtime/PaxHeaders/libcry_common.h0000644000000000000000000000013215055603742017230 xustar0030 mtime=1756825570.288068897 30 atime=1764931130.118142876 30 ctime=1764935923.084575065 rsyslog-8.2512.0/runtime/libcry_common.h0000664000175000017500000000250015055603742016671 0ustar00rgerrger/* libgcry.h - rsyslog's guardtime support library * * Copyright 2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LIBCRY_COMMON_H #define INCLUDED_LIBCRY_COMMON_H #include /* error states */ #define RSGCRYE_EI_OPEN 1 /* error opening .encinfo file */ #define RSGCRYE_OOM 4 /* ran out of memory */ #define EIF_MAX_RECTYPE_LEN 31 /* max length of record types */ #define EIF_MAX_VALUE_LEN 1023 /* max length of value types */ #define RSGCRY_FILETYPE_NAME "rsyslog-enrcyption-info" #define ENCINFO_SUFFIX ".encinfo" int cryGetKeyFromFile(const char* const fn, char** const key, unsigned* const keylen); int cryGetKeyFromProg(char* cmd, char** key, unsigned* keylen); #endif rsyslog-8.2512.0/runtime/PaxHeaders/regexp.c0000644000000000000000000000013215055605325015660 xustar0030 mtime=1756826325.651800713 30 atime=1764931005.012094873 30 ctime=1764935923.381579612 rsyslog-8.2512.0/runtime/regexp.c0000664000175000017500000002631115055605325015327 0ustar00rgerrger/* The regexp object. * * Module begun 2008-03-05 by Rainer Gerhards, based on some code * from syslogd.c * * Copyright 2008-2012 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "module-template.h" #include "obj.h" #include "regexp.h" #include "errmsg.h" #include "hashtable.h" #include "hashtable_itr.h" MODULE_TYPE_LIB MODULE_TYPE_NOKEEP; /* static data */ DEFobjStaticHelpers; /* When using glibc, we enable per-thread regex to avoid lock contention. * See: * - https://github.com/rsyslog/rsyslog/issues/2759 * - https://github.com/rsyslog/rsyslog/pull/2786 * - https://sourceware.org/bugzilla/show_bug.cgi?id=11159 * * This should not affect BSD as they don't seem to take a lock in regexec. */ #ifdef __GLIBC__ #define USE_PERTHREAD_REGEX 1 #else #define USE_PERTHREAD_REGEX 0 #endif static pthread_mutex_t mut_regexp; // Map a regex_t to its associated uncompiled parameters. static struct hashtable *regex_to_uncomp = NULL; // Map a (regexp_t, pthead_t) to a perthread_regex. static struct hashtable *perthread_regexs = NULL; /* * This stores un-compiled regex to allow further * call to regexec to re-compile a new regex dedicated * to the calling thread. */ typedef struct uncomp_regex { char *regex; int cflags; regex_t *preg; } uncomp_regex_t; /* * This stores a regex dedicated to a single thread. */ typedef struct perthread_regex { const regex_t *original_preg; regex_t preg; int ret; pthread_mutex_t lock; pthread_t thread; } perthread_regex_t; static unsigned __attribute__((nonnull(1))) int hash_from_regex(void *k) { return (uintptr_t) * (regex_t **)k; } static int key_equals_regex(void *key1, void *key2) { return *(regex_t **)key1 == *(regex_t **)key2; } static unsigned __attribute__((nonnull(1))) int hash_from_tregex(void *k) { perthread_regex_t *entry = k; // Cast to (void*) is ok here because already used in other parts of the code. uintptr_t thread_id = (uintptr_t)(void *)entry->thread; return thread_id ^ (uintptr_t)entry->original_preg; } static int key_equals_tregex(void *key1, void *key2) { perthread_regex_t *entry1 = key1; perthread_regex_t *entry2 = key2; return (pthread_equal(entry1->thread, entry2->thread) && entry1->original_preg == entry2->original_preg); } /* ------------------------------ methods ------------------------------ */ // Create a copy of preg to be used by this thread only. static perthread_regex_t *create_perthread_regex(const regex_t *preg, uncomp_regex_t *uncomp) { perthread_regex_t *entry = NULL; if (Debug) { DBGPRINTF("Creating new regex_t for thread %p original regexp_t %p (pattern: %s, cflags: %x)\n", (void *)pthread_self(), preg, uncomp->regex, uncomp->cflags); } entry = calloc(1, sizeof(*entry)); if (!entry) return entry; entry->original_preg = preg; DBGPRINTF("regexp: regcomp %p %p\n", entry, &entry->preg); entry->ret = regcomp(&entry->preg, uncomp->regex, uncomp->cflags); pthread_mutex_init(&entry->lock, NULL); entry->thread = pthread_self(); return entry; } // Get (or create) a regex_t to be used by the current thread. static perthread_regex_t *get_perthread_regex(const regex_t *preg) { perthread_regex_t *entry = NULL; perthread_regex_t key = {.original_preg = preg, .thread = pthread_self()}; pthread_mutex_lock(&mut_regexp); entry = hashtable_search(perthread_regexs, (void *)&key); if (!entry) { uncomp_regex_t *uncomp = hashtable_search(regex_to_uncomp, (void *)&preg); if (uncomp) { entry = create_perthread_regex(preg, uncomp); if (!hashtable_insert(perthread_regexs, (void *)entry, entry)) { LogError(0, RS_RET_INTERNAL_ERROR, "error trying to insert thread-regexp into hash-table - things " "will not work 100%% correctly (mostly probably out of memory issue)"); } } } if (entry) { pthread_mutex_lock(&entry->lock); } pthread_mutex_unlock(&mut_regexp); return entry; } static void remove_uncomp_regexp(regex_t *preg) { uncomp_regex_t *uncomp = NULL; pthread_mutex_lock(&mut_regexp); uncomp = hashtable_remove(regex_to_uncomp, (void *)&preg); if (uncomp) { if (Debug) { DBGPRINTF("Removing everything linked to regexp_t %p (pattern: %s, cflags: %x)\n", preg, uncomp->regex, uncomp->cflags); } free(uncomp->regex); free(uncomp); } pthread_mutex_unlock(&mut_regexp); } static void _regfree(regex_t *preg) { int ret = 0; struct hashtable_itr *itr = NULL; if (!preg) return; regfree(preg); remove_uncomp_regexp(preg); pthread_mutex_lock(&mut_regexp); if (!hashtable_count(perthread_regexs)) { pthread_mutex_unlock(&mut_regexp); return; } // This can be long to iterate other all regexps, but regfree doesn't get called // a lot during processing. itr = hashtable_iterator(perthread_regexs); do { perthread_regex_t *entry = (perthread_regex_t *)hashtable_iterator_value(itr); // Do it before freeing the entry. ret = hashtable_iterator_advance(itr); if (entry->original_preg == preg) { // This allows us to avoid freeing this while somebody is still using it. pthread_mutex_lock(&entry->lock); // We can unlock immediately after because mut_regexp is locked. pthread_mutex_unlock(&entry->lock); pthread_mutex_destroy(&entry->lock); regfree(&entry->preg); // Do it last because it will free entry. hashtable_remove(perthread_regexs, (void *)entry); } } while (ret); free(itr); pthread_mutex_unlock(&mut_regexp); } static int _regcomp(regex_t *preg, const char *regex, int cflags) { int ret = 0; regex_t **ppreg = NULL; uncomp_regex_t *uncomp; // Remove previous data if caller forgot to call regfree(). remove_uncomp_regexp(preg); // Make sure preg itself it correctly initalized. ret = regcomp(preg, regex, cflags); if (ret != 0) return ret; uncomp = calloc(1, sizeof(*uncomp)); if (!uncomp) return REG_ESPACE; uncomp->preg = preg; uncomp->regex = strdup(regex); uncomp->cflags = cflags; pthread_mutex_lock(&mut_regexp); // We need to allocate the key because hashtable will free it on remove. ppreg = malloc(sizeof(regex_t *)); *ppreg = preg; ret = hashtable_insert(regex_to_uncomp, (void *)ppreg, uncomp); pthread_mutex_unlock(&mut_regexp); if (ret == 0) { free(uncomp->regex); free(uncomp); return REG_ESPACE; } perthread_regex_t *entry = get_perthread_regex(preg); if (entry) { ret = entry->ret; pthread_mutex_unlock(&entry->lock); } else { ret = REG_ESPACE; } return ret; } static int _regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { perthread_regex_t *entry = get_perthread_regex(preg); int ret = REG_NOMATCH; if (entry != NULL) { ret = regexec(&entry->preg, string, nmatch, pmatch, eflags); pthread_mutex_unlock(&entry->lock); } return ret; } static size_t _regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) { perthread_regex_t *entry = get_perthread_regex(preg); if (entry) preg = &entry->preg; size_t ret = regerror(errcode, preg, errbuf, errbuf_size); if (entry) pthread_mutex_unlock(&entry->lock); return ret; } /* queryInterface function * rgerhards, 2008-03-05 */ BEGINobjQueryInterface(regexp) CODESTARTobjQueryInterface(regexp); if (pIf->ifVersion != regexpCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ if (USE_PERTHREAD_REGEX) { pIf->regcomp = _regcomp; pIf->regexec = _regexec; pIf->regerror = _regerror; pIf->regfree = _regfree; } else { pIf->regcomp = regcomp; pIf->regexec = regexec; pIf->regerror = regerror; pIf->regfree = regfree; } finalize_it: ENDobjQueryInterface(regexp) /* Initialize the regexp class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(regexp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */ /* request objects we use */ if (USE_PERTHREAD_REGEX) { pthread_mutex_init(&mut_regexp, NULL); regex_to_uncomp = create_hashtable(100, hash_from_regex, key_equals_regex, NULL); perthread_regexs = create_hashtable(100, hash_from_tregex, key_equals_tregex, NULL); if (regex_to_uncomp == NULL || perthread_regexs == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "error trying to initialize hash-table " "for regexp table. regexp will be disabled."); if (regex_to_uncomp) hashtable_destroy(regex_to_uncomp, 1); if (perthread_regexs) hashtable_destroy(perthread_regexs, 1); regex_to_uncomp = NULL; perthread_regexs = NULL; ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } } ENDObjClassInit(regexp) /* Exit the class. */ BEGINObjClassExit(regexp, OBJ_IS_LOADABLE_MODULE) /* class, version */ if (USE_PERTHREAD_REGEX) { /* release objects we no longer need */ pthread_mutex_destroy(&mut_regexp); if (regex_to_uncomp) hashtable_destroy(regex_to_uncomp, 1); if (perthread_regexs) hashtable_destroy(perthread_regexs, 1); } ENDObjClassExit(regexp) /* --------------- here now comes the plumbing that makes as a library module --------------- */ BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_LIB_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CHKiRet(regexpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */ /* Initialize all classes that are in our module - this includes ourselfs */ ENDmodInit /* vi:set ai: */ rsyslog-8.2512.0/runtime/PaxHeaders/netns_socket.c0000644000000000000000000000013115071746523017070 xustar0030 mtime=1760021843.866421427 30 atime=1764931007.551137048 29 ctime=1764935923.34357903 rsyslog-8.2512.0/runtime/netns_socket.c0000664000175000017500000001206715071746523016543 0ustar00rgerrger/* Implementation for netns_socket API * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include "rsyslog.h" #include "debug.h" #include "errmsg.h" #include "netns_socket.h" /* Change to the given network namespace. * This function based on previous implementation * of tools/omfwd.c function changeToNs. */ rsRetVal netns_switch(const char *ns) { DEFiRet; #ifdef HAVE_SETNS int ns_fd = -1; char *nsPath = NULL; if (ns && *ns) { /* Build network namespace path */ if (asprintf(&nsPath, "/var/run/netns/%s", ns) == -1) { // Some implementations say nsPath would be undefined on failure nsPath = NULL; LogError(0, RS_RET_OUT_OF_MEMORY, "%s: asprintf failed", __func__); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } /* Open file descriptor of destination network namespace */ ns_fd = open(nsPath, O_RDONLY); if (ns_fd < 0) { LogError(errno, RS_RET_IO_ERROR, "%s: could not open namespace '%s'", __func__, ns); ABORT_FINALIZE(RS_RET_IO_ERROR); } /* Change to the destination network namespace */ if (setns(ns_fd, CLONE_NEWNET) != 0) { LogError(errno, RS_RET_IO_ERROR, "%s: could not change to namespace '%s'", __func__, ns); ABORT_FINALIZE(RS_RET_IO_ERROR); } dbgprintf("%s: changed to network namespace '%s'\n", __func__, ns); } finalize_it: free(nsPath); if ((ns_fd >= 0) && (close(ns_fd) != 0)) { LogError(errno, RS_RET_IO_ERROR, "%s: failed to close namespace '%s'", __func__, ns); } #else // ndef HAVE_SETNS if (ns && *ns) { LogError(ENOSYS, RS_RET_VALUE_NOT_SUPPORTED, "%s: could not change to namespace '%s'", __func__, ns); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } finalize_it: #endif // ndef HAVE_SETNS RETiRet; } /* Return to the startup network namespace. * This function based on code in tools/omfwd.c */ rsRetVal ATTR_NONNULL() netns_restore(int *fd) { DEFiRet; #ifdef HAVE_SETNS if (*fd >= 0) { if (setns(*fd, CLONE_NEWNET) != 0) { LogError(errno, RS_RET_IO_ERROR, "%s: could not return to startup namespace", __func__); ABORT_FINALIZE(RS_RET_IO_ERROR); } dbgprintf("%s: returned to startup network namespace\n", __func__); } finalize_it: #endif // def HAVE_SETNS if (*fd >= 0 && close(*fd) != 0) { LogError(errno, RS_RET_IO_ERROR, "%s: could not close startup namespace fd", __func__); } *fd = -1; RETiRet; } /* Save the current network namespace fd */ rsRetVal ATTR_NONNULL() netns_save(int *fd) { DEFiRet; /* * The fd must always point to either a valid fd * or to -1. We expect it to be -1 on entry here. * To avoid bugs, or possible descriptor leaks, * check that it is always -1 on entry. */ #ifdef HAVE_SETNS if (*fd != -1) { LogError(0, RS_RET_CODE_ERR, "%s: called with uninitialized descriptor", __func__); ABORT_FINALIZE(RS_RET_CODE_ERR); } *fd = open("/proc/self/ns/net", O_RDONLY); if (*fd == -1) { LogError(errno, RS_RET_IO_ERROR, "%s: could not access startup namespace", __func__); ABORT_FINALIZE(RS_RET_IO_ERROR); } dbgprintf("%s: saved startup network namespace\n", __func__); finalize_it: #endif // def HAVE_SETNS RETiRet; } rsRetVal netns_socket(int *fdp, int domain, int type, int protocol, const char *ns) { DEFiRet; int fd = -1; #ifndef HAVE_SETNS if (ns && *ns) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "Network namespaces are not supported"); ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED); } #else /* def HAVE_SETNS */ rsRetVal iRet_restore; int ns_fd = -1; if (ns && *ns) { CHKiRet(netns_save(&ns_fd)); CHKiRet(netns_switch(ns)); } #endif /* def HAVE_SETNS */ *fdp = fd = socket(domain, type, protocol); if (fd == -1) { LogError(errno, RS_RET_NO_SOCKET, "%s: socket(%d, %d, %d) failed", __func__, domain, type, protocol); ABORT_FINALIZE(RS_RET_NO_SOCKET); } finalize_it: #ifdef HAVE_SETNS iRet_restore = netns_restore(&ns_fd); if (iRet == RS_RET_OK) iRet = iRet_restore; #endif /* def HAVE_SETNS */ if (iRet != RS_RET_OK && fd != -1) { (void)close(fd); *fdp = -1; } RETiRet; } rsyslog-8.2512.0/runtime/PaxHeaders/dynstats.h0000644000000000000000000000013215055605325016244 xustar0030 mtime=1756826325.644800608 30 atime=1764930980.043678607 30 ctime=1764935923.222577178 rsyslog-8.2512.0/runtime/dynstats.h0000664000175000017500000000526415055605325015717 0ustar00rgerrger/* * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_DYNSTATS_H #define INCLUDED_DYNSTATS_H #include "hashtable.h" typedef struct hashtable htable; struct dynstats_ctr_s { STATSCOUNTER_DEF(ctr, mutCtr); ctr_t *pCtr; uchar *metric; /* linked list ptr */ struct dynstats_ctr_s *next; struct dynstats_ctr_s *prev; }; struct dynstats_bucket_s { htable *table; uchar *name; pthread_rwlock_t lock; statsobj_t *stats; STATSCOUNTER_DEF(ctrOpsOverflow, mutCtrOpsOverflow); ctr_t *pOpsOverflowCtr; STATSCOUNTER_DEF(ctrNewMetricAdd, mutCtrNewMetricAdd); ctr_t *pNewMetricAddCtr; STATSCOUNTER_DEF(ctrNoMetric, mutCtrNoMetric); ctr_t *pNoMetricCtr; STATSCOUNTER_DEF(ctrMetricsPurged, mutCtrMetricsPurged); ctr_t *pMetricsPurgedCtr; STATSCOUNTER_DEF(ctrOpsIgnored, mutCtrOpsIgnored); ctr_t *pOpsIgnoredCtr; STATSCOUNTER_DEF(ctrPurgeTriggered, mutCtrPurgeTriggered); ctr_t *pPurgeTriggeredCtr; struct dynstats_bucket_s *next; /* linked list ptr */ struct dynstats_ctr_s *ctrs; /*survivor objects are used to keep counter values around for upto unused-ttl duration, so in case it is accessed within (ttl - 2 * ttl) time-period we can re-store the accumulator value from this */ struct dynstats_ctr_s *survivor_ctrs; htable *survivor_table; uint32_t maxCardinality; uint32_t metricCount; pthread_mutex_t mutMetricCount; uint32_t unusedMetricLife; uint32_t lastResetTs; struct timespec metricCleanupTimeout; uint8_t resettable; }; struct dynstats_buckets_s { struct dynstats_bucket_s *list; statsobj_t *global_stats; pthread_rwlock_t lock; uint8_t initialized; }; rsRetVal dynstats_initCnf(dynstats_buckets_t *b); rsRetVal dynstats_processCnf(struct cnfobj *o); dynstats_bucket_t *dynstats_findBucket(const uchar *name); rsRetVal dynstats_inc(dynstats_bucket_t *bucket, uchar *metric); void dynstats_destroyAllBuckets(void); void dynstats_resetExpired(void); rsRetVal dynstatsClassInit(void); #endif /* #ifndef INCLUDED_DYNSTATS_H */ rsyslog-8.2512.0/runtime/PaxHeaders/queue.c0000644000000000000000000000013215071746523015516 xustar0030 mtime=1760021843.875421569 30 atime=1764930994.966927732 30 ctime=1764935923.253577652 rsyslog-8.2512.0/runtime/queue.c0000664000175000017500000045321615071746523015175 0ustar00rgerrger/* queue.c * * This file implements the queue object and its several queueing methods. * * File begun on 2008-01-03 by RGerhards * * There is some in-depth documentation available in doc/dev_queue.html * (and in the web doc set on https://www.rsyslog.com/doc/). Be sure to read it * if you are getting aquainted to the object. * * NOTE: as of 2009-04-22, I have begin to remove the qqueue* prefix from static * function names - this makes it really hard to read and does not provide much * benefit, at least I (now) think so... * * Copyright 2008-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ /** * @file queue.c * @brief This file implements the rsyslog queueing subsystem. * * @section queue_maintenance Important Note on Maintenance * * This header comment contains critical information on the system's * architecture and design philosophy. It is essential that this comment, and * all other relevant documentation, be **updated whenever architectural or * other significant changes are made to the queueing subsystem.** * * Maintaining synchronization between code and documentation is vital for * long-term project health, developer onboarding, and to enable automated * tools and AI agents to accurately analyze the codebase and detect potential * issues arising from undocumented changes. This documentation reflects the * state of the system as of mid-2025, based on a battle-proven design that * originated circa 2004. * * @section queue_architecture Architectural Overview and Design Philosophy * * The rsyslog queueing system is a fundamental component for providing both * performance and reliability. It is built on a powerful abstraction: a queue * can be placed at two key points in the message processing pipeline: * * 1. **Ruleset Queue (Main Message Queue):** Each ruleset has a single queue * that buffers messages received from inputs *before* they are processed * by the ruleset's filters. This decouples message ingestion from filter * processing, allowing rsyslog to handle massive input bursts without * losing messages. The queue for the default ruleset is often referred * to by its historical name, the "main message queue". * * 2. **Action Queue:** Each action within a ruleset can have its own dedicated * queue. This decouples the filter engine from the output action (e.g., * writing to a file or sending over the network). * * This system's design is a testament to operator-centric control, providing * a sophisticated toolkit of compromises. This contrasts sharply with modern * "WAL-only" log shippers, making rsyslog uniquely versatile. * * * @subsection queue_types The Four Queue Types * * Rsyslog offers four queue types, each with a specific performance and * reliability profile. They are listed here from most lightweight to most * robust. * * 1. **Direct (The "No-Queue" Queue)** * - **Behavior:** The default for all **action queues**. No buffering occurs. The * worker thread from the parent queue (usually the ruleset's queue) * executes the action's logic directly. * - **Use Case:** For fast, non-blocking, local actions (e.g., `omfile`). * - **Warning:** If a Direct-queued action blocks, it stalls the worker * thread, potentially halting all processing for that worker. * * 2. **In-Memory (LinkedList and FixedArray)** * - **Behavior:** Buffers messages in RAM. Extremely fast but offers no * persistence across restarts. * - **Sub-Types:** * - `LinkedList`: The recommended default for most in-memory queues. It is * memory-efficient, allocating space only for messages it holds. * - `FixedArray`: A legacy option that pre-allocates a static array of * pointers. It can be slightly faster under constant load but is * less memory-efficient. It remains the default for ruleset queues. * - **Use Case:** High-performance buffering where a potential loss of * in-flight messages on crash is acceptable. * * 3. **Disk (The "Pure-Disk" Queue)** * - **Behavior:** Writes every single message to a disk-based queue structure * before acknowledging the enqueue operation. This queue provides a * **"Limited Duplication"** guarantee, not a simple "at-least-once". * - **The `.qi` Checkpoint File:** The queue's state (read/write pointers) * is persisted in a `.qi` file. The `queue.checkpointInterval` parameter * dictates how often this file is updated, allowing the user to tune * the trade-off between I/O performance and duplication risk. A value * of `1` provides near-exactly-once delivery, essential for "dumb" * (non-deduplicating) receivers. * - **Use Case:** For audit-grade logging chains where no message loss can * be tolerated, even in the case of a power failure or ungraceful shutdown. * * 4. **Disk-Assisted (DA) (The Hybrid "Best-of-Both-Worlds" Queue)** * - **Behavior:** This is the most sophisticated queue type. It acts as a * multi-stage defense system against data loss. * - **Stage 1: In-Memory First:** By default, it operates as a high-speed * `LinkedList` queue with zero disk I/O. * - **Stage 2: Disk Spooling:** If the in-memory queue exceeds its * `highwatermark` (e.g., due to downstream backpressure), it seamlessly * activates its internal **Disk Queue** and begins spooling messages * to disk. This provides resilience to transient failures without the * constant performance penalty of a pure Disk queue. The disk portion * operates with its own "Limited Duplication" guarantee. * - **Stage 3: Load Shedding:** If all buffers (memory and disk) are full, * the queue hits the `queue.discardMark`. It can then begin to discard * messages based on severity (`queue.discardSeverity`), preserving * critical logs during a total system overload. * - **Use Case:** The recommended choice for any potentially unreliable or * slow action, or for a ruleset queue that needs to survive downstream * outages. * * * @subsection comparison_to_wal Rsyslog's "Bounded Queue" vs. a WAL's "Unbounded Stream" * * It is critical to understand that rsyslog's disk-based queues implement a * **Bounded FIFO Queue**, which is architecturally different from the * **Unbounded Stream** model of a Write-Ahead Log (WAL) found in tools like * Fluent Bit or Vector. * * - **Rsyslog's Model:** The `.qi` file checkpoints the queue's *structure*, * containing two primary tuples: `write_ptr = (segment, offset)` and * `read_ptr = (segment, offset)`. This defines the queue's boundaries. * Consumption is a destructive action that advances the `read_ptr`. On a * graceful restart (e.g., K8s `SIGTERM`), DA queues flush memory to disk, * ensuring **zero data loss**. On a crash, only the `checkpointInterval`-worth * of messages are at risk of replay. This fine-grained control makes it safe * for both smart and dumb receivers. **Note:** A known operational risk is * that the current implementation does not gracefully handle a missing or * corrupt `.qi` file in conjunction with pre-existing queue segment files. * This can lead to startup failures or inconsistent state and is a top * priority for future reliability enhancements. * * * - **WAL Model:** A WAL is a simple, append-only log. The checkpoint is just * a consumer's *offset*. On restart, a WAL-based shipper replays *all data* * from the last offset, which can be massive. This model mandates a smart, * idempotent receiver and is fundamentally unsafe for dumb endpoints.* * @subsection naming_convention Historical Naming: queue vs. qqueue * * Throughout the code, you will see types and variables prefixed with `qqueue` * (e.g., `qqueue_t`). This is the result of a historical name change. * Originally, these were named `queue`, but this caused symbol clashes on some * platforms (e.g., AIX) where `queue` is a reserved name in system libraries. * The name was changed to `qqueue` ("queue object for the queueing subsystem") * to ensure portability. * * * @section conclusion Summary for Developers * * When working with this code, remember that you are not dealing with a simple * log appender. You are maintaining a transactional, persistent FIFO queue. * The logic surrounding the `.qi` file, segment files, and the read/write * pointers is designed to provide robust, tunable delivery guarantees that are * a core feature of rsyslog. This makes it more versatile than pure WAL-based * log shippers. * */ #include "config.h" #include #include #include #include #include #include #include #include #include /* required for HP UX */ #include #include #include #include "rsyslog.h" #include "queue.h" #include "stringbuf.h" #include "srUtils.h" #include "obj.h" #include "wtp.h" #include "wti.h" #include "msg.h" #include "obj.h" #include "atomic.h" #include "errmsg.h" #include "datetime.h" #include "unicode-helper.h" #include "statsobj.h" #include "parserif.h" #include "rsconf.h" #ifdef OS_SOLARIS #include #endif /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(glbl) DEFobjCurrIf(strm) DEFobjCurrIf(datetime) DEFobjCurrIf(statsobj) #if __GNUC__ >= 8 #pragma GCC diagnostic ignored "-Wcast-function-type" // TODO: investigate further! #endif /* if __GNUC__ >= 8 */ #ifdef ENABLE_IMDIAG unsigned int iOverallQueueSize = 0; #endif #define OVERSIZE_QUEUE_WATERMARK 500000 /* when is a queue considered to be "overly large"? */ /* forward-definitions */ static rsRetVal doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, smsg_t *pMsg); static rsRetVal qqueueChkPersist(qqueue_t *pThis, int nUpdates); static rsRetVal RateLimiter(qqueue_t *pThis); static rsRetVal qqueueChkStopWrkrDA(qqueue_t *pThis); static rsRetVal GetDeqBatchSize(qqueue_t *pThis, int *pVal); static rsRetVal ConsumerDA(qqueue_t *pThis, wti_t *pWti); static rsRetVal batchProcessed(qqueue_t *pThis, wti_t *pWti); static rsRetVal qqueueMultiEnqObjNonDirect(qqueue_t *pThis, multi_submit_t *pMultiSub); static rsRetVal qqueueMultiEnqObjDirect(qqueue_t *pThis, multi_submit_t *pMultiSub); static rsRetVal qAddDirect(qqueue_t *pThis, smsg_t *pMsg); static rsRetVal qDestructDirect(qqueue_t __attribute__((unused)) * pThis); static rsRetVal qConstructDirect(qqueue_t __attribute__((unused)) * pThis); static rsRetVal qDestructDisk(qqueue_t *pThis); rsRetVal qqueueSetSpoolDir(qqueue_t *pThis, uchar *pszSpoolDir, int lenSpoolDir); /* some constants for queuePersist () */ #define QUEUE_CHECKPOINT 1 #define QUEUE_NO_CHECKPOINT 0 /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfpdescr[] = {{"queue.filename", eCmdHdlrGetWord, 0}, {"queue.spooldirectory", eCmdHdlrGetWord, 0}, {"queue.size", eCmdHdlrSize, 0}, {"queue.dequeuebatchsize", eCmdHdlrInt, 0}, {"queue.mindequeuebatchsize", eCmdHdlrInt, 0}, {"queue.mindequeuebatchsize.timeout", eCmdHdlrInt, 0}, {"queue.maxdiskspace", eCmdHdlrSize, 0}, {"queue.highwatermark", eCmdHdlrInt, 0}, {"queue.lowwatermark", eCmdHdlrInt, 0}, {"queue.fulldelaymark", eCmdHdlrInt, 0}, {"queue.lightdelaymark", eCmdHdlrInt, 0}, {"queue.discardmark", eCmdHdlrInt, 0}, {"queue.discardseverity", eCmdHdlrFacility, 0}, {"queue.checkpointinterval", eCmdHdlrInt, 0}, {"queue.syncqueuefiles", eCmdHdlrBinary, 0}, {"queue.type", eCmdHdlrQueueType, 0}, {"queue.workerthreads", eCmdHdlrInt, 0}, {"queue.timeoutshutdown", eCmdHdlrInt, 0}, {"queue.timeoutactioncompletion", eCmdHdlrInt, 0}, {"queue.timeoutenqueue", eCmdHdlrInt, 0}, {"queue.timeoutworkerthreadshutdown", eCmdHdlrInt, 0}, {"queue.workerthreadminimummessages", eCmdHdlrInt, 0}, {"queue.maxfilesize", eCmdHdlrSize, 0}, {"queue.saveonshutdown", eCmdHdlrBinary, 0}, {"queue.dequeueslowdown", eCmdHdlrInt, 0}, {"queue.dequeuetimebegin", eCmdHdlrInt, 0}, {"queue.dequeuetimeend", eCmdHdlrInt, 0}, {"queue.cry.provider", eCmdHdlrGetWord, 0}, {"queue.samplinginterval", eCmdHdlrInt, 0}, {"queue.takeflowctlfrommsg", eCmdHdlrBinary, 0}}; static struct cnfparamblk pblk = {CNFPARAMBLK_VERSION, sizeof(cnfpdescr) / sizeof(struct cnfparamdescr), cnfpdescr}; /* support to detect duplicate queue file names */ struct queue_filename { struct queue_filename *next; const char *dirname; const char *filename; }; struct queue_filename *queue_filename_root = NULL; /* debug aid */ #if 0 static inline void displayBatchState(batch_t *pBatch) { int i; for(i = 0 ; i < pBatch->nElem ; ++i) { DBGPRINTF("displayBatchState %p[%d]: %d\n", pBatch, i, pBatch->eltState[i]); } } #endif static rsRetVal qqueuePersist(qqueue_t *pThis, int bIsCheckpoint); /* do cleanup when config is loaded */ void qqueueDoneLoadCnf(void) { struct queue_filename *next, *del; next = queue_filename_root; while (next != NULL) { del = next; next = next->next; free((void *)del->filename); free((void *)del->dirname); free((void *)del); } } /*********************************************************************** * we need a private data structure, the "to-delete" list. As C does * not provide any partly private data structures, we implement this * structure right here inside the module. * Note that this list must always be kept sorted based on a unique * dequeue ID (which is monotonically increasing). * rgerhards, 2009-05-18 ***********************************************************************/ /* generate next uniqueue dequeue ID. Note that uniqueness is only required * on a per-queue basis and while this instance runs. So a stricly monotonically * increasing counter is sufficient (if enough bits are used). */ static inline qDeqID getNextDeqID(qqueue_t *pQueue) { ISOBJ_TYPE_assert(pQueue, qqueue); return pQueue->deqIDAdd++; } /* return the top element of the to-delete list or NULL, if the * list is empty. */ static toDeleteLst_t *tdlPeek(qqueue_t *pQueue) { ISOBJ_TYPE_assert(pQueue, qqueue); return pQueue->toDeleteLst; } /* remove the top element of the to-delete list. Nothing but the * element itself is destroyed. Must not be called when the list * is empty. */ static rsRetVal tdlPop(qqueue_t *pQueue) { toDeleteLst_t *pRemove; DEFiRet; ISOBJ_TYPE_assert(pQueue, qqueue); assert(pQueue->toDeleteLst != NULL); pRemove = pQueue->toDeleteLst; pQueue->toDeleteLst = pQueue->toDeleteLst->pNext; free(pRemove); RETiRet; } /* Add a new to-delete list entry. The function allocates the data * structure, populates it with the values provided and links the new * element into the correct place inside the list. */ static rsRetVal tdlAdd(qqueue_t *pQueue, qDeqID deqID, int nElemDeq) { toDeleteLst_t *pNew; toDeleteLst_t *pPrev; DEFiRet; ISOBJ_TYPE_assert(pQueue, qqueue); assert(pQueue->toDeleteLst != NULL); CHKmalloc(pNew = malloc(sizeof(toDeleteLst_t))); pNew->deqID = deqID; pNew->nElemDeq = nElemDeq; /* now find right spot */ for (pPrev = pQueue->toDeleteLst; pPrev != NULL && deqID > pPrev->deqID; pPrev = pPrev->pNext) { /*JUST SEARCH*/; } if (pPrev == NULL) { pNew->pNext = pQueue->toDeleteLst; pQueue->toDeleteLst = pNew; } else { pNew->pNext = pPrev->pNext; pPrev->pNext = pNew; } finalize_it: RETiRet; } /* methods */ static const char *getQueueTypeName(queueType_t t) { const char *r; switch (t) { case QUEUETYPE_FIXED_ARRAY: r = "FixedArray"; break; case QUEUETYPE_LINKEDLIST: r = "LinkedList"; break; case QUEUETYPE_DISK: r = "Disk"; break; case QUEUETYPE_DIRECT: r = "Direct"; break; default: r = "invalid/unknown queue mode"; break; } return r; } void qqueueDbgPrint(qqueue_t *pThis) { dbgoprint((obj_t *)pThis, "parameter dump:\n"); dbgoprint((obj_t *)pThis, "queue.filename '%s'\n", (pThis->pszFilePrefix == NULL) ? "[NONE]" : (char *)pThis->pszFilePrefix); dbgoprint((obj_t *)pThis, "queue.size: %d\n", pThis->iMaxQueueSize); dbgoprint((obj_t *)pThis, "queue.dequeuebatchsize: %d\n", pThis->iDeqBatchSize); dbgoprint((obj_t *)pThis, "queue.mindequeuebatchsize: %d\n", pThis->iMinDeqBatchSize); dbgoprint((obj_t *)pThis, "queue.mindequeuebatchsize.timeout: %d\n", pThis->toMinDeqBatchSize); dbgoprint((obj_t *)pThis, "queue.maxdiskspace: %lld\n", pThis->sizeOnDiskMax); dbgoprint((obj_t *)pThis, "queue.highwatermark: %d\n", pThis->iHighWtrMrk); dbgoprint((obj_t *)pThis, "queue.lowwatermark: %d\n", pThis->iLowWtrMrk); dbgoprint((obj_t *)pThis, "queue.fulldelaymark: %d\n", pThis->iFullDlyMrk); dbgoprint((obj_t *)pThis, "queue.lightdelaymark: %d\n", pThis->iLightDlyMrk); dbgoprint((obj_t *)pThis, "queue.takeflowctlfrommsg: %d\n", pThis->takeFlowCtlFromMsg); dbgoprint((obj_t *)pThis, "queue.discardmark: %d\n", pThis->iDiscardMrk); dbgoprint((obj_t *)pThis, "queue.discardseverity: %d\n", pThis->iDiscardSeverity); dbgoprint((obj_t *)pThis, "queue.checkpointinterval: %d\n", pThis->iPersistUpdCnt); dbgoprint((obj_t *)pThis, "queue.syncqueuefiles: %d\n", pThis->bSyncQueueFiles); dbgoprint((obj_t *)pThis, "queue.type: %d [%s]\n", pThis->qType, getQueueTypeName(pThis->qType)); dbgoprint((obj_t *)pThis, "queue.workerthreads: %d\n", pThis->iNumWorkerThreads); dbgoprint((obj_t *)pThis, "queue.timeoutshutdown: %d\n", pThis->toQShutdown); dbgoprint((obj_t *)pThis, "queue.timeoutactioncompletion: %d\n", pThis->toActShutdown); dbgoprint((obj_t *)pThis, "queue.timeoutenqueue: %d\n", pThis->toEnq); dbgoprint((obj_t *)pThis, "queue.timeoutworkerthreadshutdown: %d\n", pThis->toWrkShutdown); dbgoprint((obj_t *)pThis, "queue.workerthreadminimummessages: %d\n", pThis->iMinMsgsPerWrkr); dbgoprint((obj_t *)pThis, "queue.maxfilesize: %lld\n", pThis->iMaxFileSize); dbgoprint((obj_t *)pThis, "queue.saveonshutdown: %d\n", pThis->bSaveOnShutdown); dbgoprint((obj_t *)pThis, "queue.dequeueslowdown: %d\n", pThis->iDeqSlowdown); dbgoprint((obj_t *)pThis, "queue.dequeuetimebegin: %d\n", pThis->iDeqtWinFromHr); dbgoprint((obj_t *)pThis, "queue.dequeuetimeend: %d\n", pThis->iDeqtWinToHr); } /* get the physical queue size. Must only be called * while mutex is locked! * rgerhards, 2008-01-29 */ static int getPhysicalQueueSize(qqueue_t *pThis) { return (int)PREFER_FETCH_32BIT(pThis->iQueueSize); } /* get the logical queue size (that is store size minus logically dequeued elements). * Must only be called while mutex is locked! * rgerhards, 2009-05-19 */ static int getLogicalQueueSize(qqueue_t *pThis) { return pThis->iQueueSize - pThis->nLogDeq; } /* This function drains the queue in cases where this needs to be done. The most probable * reason is a HUP which needs to discard data (because the queue is configured to be lossy). * During a shutdown, this is typically not needed, as the OS frees up ressources and does * this much quicker than when we clean up ourselvs. -- rgerhards, 2008-10-21 * This function returns void, as it makes no sense to communicate an error back, even if * it happens. * This functions works "around" the regular deque mechanism, because it is only used to * clean up (in cases where message loss is acceptable). */ static void queueDrain(qqueue_t *pThis) { smsg_t *pMsg; assert(pThis != NULL); DBGOPRINT((obj_t *)pThis, "queue (type %d) will lose %d messages, destroying...\n", pThis->qType, pThis->iQueueSize); /* iQueueSize is not decremented by qDel(), so we need to do it ourselves */ while (ATOMIC_DEC_AND_FETCH(&pThis->iQueueSize, &pThis->mutQueueSize) > 0) { pThis->qDeq(pThis, &pMsg); if (pMsg != NULL) { msgDestruct(&pMsg); } pThis->qDel(pThis); } } /* --------------- code for disk-assisted (DA) queue modes -------------------- */ /* returns the number of workers that should be advised at * this point in time. The mutex must be locked when * ths function is called. -- rgerhards, 2008-01-25 */ static rsRetVal qqueueAdviseMaxWorkers(qqueue_t *pThis) { DEFiRet; int iMaxWorkers; ISOBJ_TYPE_assert(pThis, qqueue); if (!pThis->bEnqOnly) { if (pThis->bIsDA && getLogicalQueueSize(pThis) >= pThis->iHighWtrMrk) { DBGOPRINT((obj_t *)pThis, "(re)activating DA worker\n"); wtpAdviseMaxWorkers(pThis->pWtpDA, 1, DENY_WORKER_START_DURING_SHUTDOWN); /* disk queues have always one worker */ } if (getLogicalQueueSize(pThis) == 0) { iMaxWorkers = 0; } else if (pThis->iMinMsgsPerWrkr == 0) { iMaxWorkers = 1; } else { iMaxWorkers = getLogicalQueueSize(pThis) / pThis->iMinMsgsPerWrkr + 1; } wtpAdviseMaxWorkers(pThis->pWtpReg, iMaxWorkers, DENY_WORKER_START_DURING_SHUTDOWN); } RETiRet; } /* check if we run in disk-assisted mode and record that * setting for easy (and quick!) access in the future. This * function must only be called from constructors and only * from those that support disk-assisted modes (aka memory- * based queue drivers). * rgerhards, 2008-01-14 */ static rsRetVal qqueueChkIsDA(qqueue_t *pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); if (pThis->pszFilePrefix != NULL) { pThis->bIsDA = 1; DBGOPRINT((obj_t *)pThis, "is disk-assisted, disk will be used on demand\n"); } else { DBGOPRINT((obj_t *)pThis, "is NOT disk-assisted\n"); } RETiRet; } /* Start disk-assisted queue mode. * rgerhards, 2008-01-15 */ static rsRetVal StartDA(qqueue_t *pThis) { DEFiRet; uchar pszDAQName[128]; ISOBJ_TYPE_assert(pThis, qqueue); /* create message queue */ CHKiRet(qqueueConstruct(&pThis->pqDA, QUEUETYPE_DISK, pThis->iNumWorkerThreads, 0, pThis->pConsumer)); /* give it a name */ snprintf((char *)pszDAQName, sizeof(pszDAQName), "%s[DA]", obj.GetName((obj_t *)pThis)); obj.SetName((obj_t *)pThis->pqDA, pszDAQName); /* as the created queue is the same object class, we take the * liberty to access its properties directly. */ pThis->pqDA->pqParent = pThis; CHKiRet(qqueueSetpAction(pThis->pqDA, pThis->pAction)); CHKiRet(qqueueSetsizeOnDiskMax(pThis->pqDA, pThis->sizeOnDiskMax)); CHKiRet(qqueueSetiDeqSlowdown(pThis->pqDA, pThis->iDeqSlowdown)); CHKiRet(qqueueSetMaxFileSize(pThis->pqDA, pThis->iMaxFileSize)); CHKiRet(qqueueSetFilePrefix(pThis->pqDA, pThis->pszFilePrefix, pThis->lenFilePrefix)); CHKiRet(qqueueSetSpoolDir(pThis->pqDA, pThis->pszSpoolDir, pThis->lenSpoolDir)); CHKiRet(qqueueSetiPersistUpdCnt(pThis->pqDA, pThis->iPersistUpdCnt)); CHKiRet(qqueueSetbSyncQueueFiles(pThis->pqDA, pThis->bSyncQueueFiles)); CHKiRet(qqueueSettoActShutdown(pThis->pqDA, pThis->toActShutdown)); CHKiRet(qqueueSettoEnq(pThis->pqDA, pThis->toEnq)); CHKiRet(qqueueSetiDeqtWinFromHr(pThis->pqDA, pThis->iDeqtWinFromHr)); CHKiRet(qqueueSetiDeqtWinToHr(pThis->pqDA, pThis->iDeqtWinToHr)); CHKiRet(qqueueSettoQShutdown(pThis->pqDA, pThis->toQShutdown)); CHKiRet(qqueueSetiHighWtrMrk(pThis->pqDA, 0)); CHKiRet(qqueueSetiDiscardMrk(pThis->pqDA, 0)); pThis->pqDA->iDeqBatchSize = pThis->iDeqBatchSize; pThis->pqDA->iMinDeqBatchSize = pThis->iMinDeqBatchSize; pThis->pqDA->iMinMsgsPerWrkr = pThis->iMinMsgsPerWrkr; pThis->pqDA->iLowWtrMrk = pThis->iLowWtrMrk; if (pThis->useCryprov) { /* hand over cryprov to DA queue - in-mem queue does no longer need it * and DA queue will be kept active from now on until termination. */ pThis->pqDA->useCryprov = pThis->useCryprov; pThis->pqDA->cryprov = pThis->cryprov; pThis->pqDA->cryprovData = pThis->cryprovData; pThis->pqDA->cryprovName = pThis->cryprovName; pThis->pqDA->cryprovNameFull = pThis->cryprovNameFull; /* reset memory queue parameters */ pThis->useCryprov = 0; /* pThis->cryprov cannot and need not be reset, is structure */ pThis->cryprovData = NULL; pThis->cryprovName = NULL; pThis->cryprovNameFull = NULL; } iRet = qqueueStart(runConf, pThis->pqDA); /* file not found is expected, that means it is no previous QIF available */ if (iRet != RS_RET_OK && iRet != RS_RET_FILE_NOT_FOUND) { errno = 0; /* else an errno is shown in errmsg! */ LogError(errno, iRet, "error starting up disk queue, using pure in-memory mode"); pThis->bIsDA = 0; /* disable memory mode */ FINALIZE; /* something is wrong */ } DBGOPRINT((obj_t *)pThis, "DA queue initialized, disk queue 0x%lx\n", qqueueGetID(pThis->pqDA)); finalize_it: if (iRet != RS_RET_OK) { if (pThis->pqDA != NULL) { qqueueDestruct(&pThis->pqDA); } LogError(0, iRet, "%s: error creating disk queue - giving up.", obj.GetName((obj_t *)pThis)); pThis->bIsDA = 0; } RETiRet; } /* initiate DA mode * param bEnqOnly tells if the disk queue is to be run in enqueue-only mode. This may * be needed during shutdown of memory queues which need to be persisted to disk. * If this function fails (should not happen), DA mode is not turned on. * rgerhards, 2008-01-16 */ static rsRetVal ATTR_NONNULL() InitDA(qqueue_t *const pThis, const int bLockMutex) { DEFiRet; uchar pszBuf[64]; size_t lenBuf; ISOBJ_TYPE_assert(pThis, qqueue); if (bLockMutex == LOCK_MUTEX) { d_pthread_mutex_lock(pThis->mut); } /* check if we already have a DA worker pool. If not, initiate one. Please note that the * pool is created on first need but never again destructed (until the queue is). This * is intentional. We assume that when we need it once, we may also need it on another * occasion. Ressources used are quite minimal when no worker is running. * rgerhards, 2008-01-24 * NOTE: this is the DA worker *pool*, not the DA queue! */ lenBuf = snprintf((char *)pszBuf, sizeof(pszBuf), "%s:DAwpool", obj.GetName((obj_t *)pThis)); CHKiRet(wtpConstruct(&pThis->pWtpDA)); CHKiRet(wtpSetDbgHdr(pThis->pWtpDA, pszBuf, lenBuf)); CHKiRet(wtpSetpfChkStopWrkr(pThis->pWtpDA, (rsRetVal(*)(void *pUsr, int))qqueueChkStopWrkrDA)); CHKiRet(wtpSetpfGetDeqBatchSize(pThis->pWtpDA, (rsRetVal(*)(void *pUsr, int *))GetDeqBatchSize)); CHKiRet(wtpSetpfDoWork(pThis->pWtpDA, (rsRetVal(*)(void *pUsr, void *pWti))ConsumerDA)); CHKiRet(wtpSetpfObjProcessed(pThis->pWtpDA, (rsRetVal(*)(void *pUsr, wti_t *pWti))batchProcessed)); CHKiRet(wtpSetpmutUsr(pThis->pWtpDA, pThis->mut)); CHKiRet(wtpSetiNumWorkerThreads(pThis->pWtpDA, 1)); CHKiRet(wtpSettoWrkShutdown(pThis->pWtpDA, pThis->toWrkShutdown)); CHKiRet(wtpSetpUsr(pThis->pWtpDA, pThis)); CHKiRet(wtpConstructFinalize(pThis->pWtpDA)); /* if we reach this point, we have a "good" DA worker pool */ /* now construct the actual queue (if it does not already exist) */ if (pThis->pqDA == NULL) { CHKiRet(StartDA(pThis)); } finalize_it: if (bLockMutex == LOCK_MUTEX) { d_pthread_mutex_unlock(pThis->mut); } RETiRet; } /* --------------- end code for disk-assisted queue modes -------------------- */ /* Now, we define type-specific handlers. The provide a generic functionality, * but for this specific type of queue. The mapping to these handlers happens during * queue construction. Later on, handlers are called by pointers present in the * queue instance object. */ /* -------------------- fixed array -------------------- */ static rsRetVal qConstructFixedArray(qqueue_t *pThis) { DEFiRet; assert(pThis != NULL); if (pThis->iMaxQueueSize == 0) ABORT_FINALIZE(RS_RET_QSIZE_ZERO); if ((pThis->tVars.farray.pBuf = malloc(sizeof(void *) * pThis->iMaxQueueSize)) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pThis->tVars.farray.deqhead = 0; pThis->tVars.farray.head = 0; pThis->tVars.farray.tail = 0; qqueueChkIsDA(pThis); finalize_it: RETiRet; } static rsRetVal qDestructFixedArray(qqueue_t *pThis) { DEFiRet; assert(pThis != NULL); queueDrain(pThis); /* discard any remaining queue entries */ free(pThis->tVars.farray.pBuf); RETiRet; } static rsRetVal qAddFixedArray(qqueue_t *pThis, smsg_t *in) { DEFiRet; assert(pThis != NULL); pThis->tVars.farray.pBuf[pThis->tVars.farray.tail] = in; pThis->tVars.farray.tail++; if (pThis->tVars.farray.tail == pThis->iMaxQueueSize) pThis->tVars.farray.tail = 0; RETiRet; } static rsRetVal qDeqFixedArray(qqueue_t *pThis, smsg_t **out) { DEFiRet; assert(pThis != NULL); *out = (void *)pThis->tVars.farray.pBuf[pThis->tVars.farray.deqhead]; pThis->tVars.farray.deqhead++; if (pThis->tVars.farray.deqhead == pThis->iMaxQueueSize) pThis->tVars.farray.deqhead = 0; RETiRet; } static rsRetVal qDelFixedArray(qqueue_t *pThis) { DEFiRet; assert(pThis != NULL); pThis->tVars.farray.head++; if (pThis->tVars.farray.head == pThis->iMaxQueueSize) pThis->tVars.farray.head = 0; RETiRet; } /* -------------------- linked list -------------------- */ static rsRetVal qConstructLinkedList(qqueue_t *pThis) { DEFiRet; assert(pThis != NULL); pThis->tVars.linklist.pDeqRoot = NULL; pThis->tVars.linklist.pDelRoot = NULL; pThis->tVars.linklist.pLast = NULL; qqueueChkIsDA(pThis); RETiRet; } static rsRetVal qDestructLinkedList(qqueue_t __attribute__((unused)) * pThis) { DEFiRet; queueDrain(pThis); /* discard any remaining queue entries */ /* with the linked list type, there is nothing left to do here. The * reason is that there are no dynamic elements for the list itself. */ RETiRet; } static rsRetVal qAddLinkedList(qqueue_t *pThis, smsg_t *pMsg) { qLinkedList_t *pEntry; DEFiRet; CHKmalloc((pEntry = (qLinkedList_t *)malloc(sizeof(qLinkedList_t)))); pEntry->pNext = NULL; pEntry->pMsg = pMsg; if (pThis->tVars.linklist.pDelRoot == NULL) { pThis->tVars.linklist.pDelRoot = pThis->tVars.linklist.pDeqRoot = pThis->tVars.linklist.pLast = pEntry; } else { pThis->tVars.linklist.pLast->pNext = pEntry; pThis->tVars.linklist.pLast = pEntry; } if (pThis->tVars.linklist.pDeqRoot == NULL) { pThis->tVars.linklist.pDeqRoot = pEntry; } finalize_it: RETiRet; } static rsRetVal qDeqLinkedList(qqueue_t *pThis, smsg_t **ppMsg) { qLinkedList_t *pEntry; DEFiRet; pEntry = pThis->tVars.linklist.pDeqRoot; if (pEntry != NULL) { *ppMsg = pEntry->pMsg; pThis->tVars.linklist.pDeqRoot = pEntry->pNext; } else { /* Check and return NULL for linklist.pDeqRoot */ dbgprintf("qDeqLinkedList: pDeqRoot is NULL!\n"); *ppMsg = NULL; pThis->tVars.linklist.pDeqRoot = NULL; } RETiRet; } static rsRetVal qDelLinkedList(qqueue_t *pThis) { qLinkedList_t *pEntry; DEFiRet; pEntry = pThis->tVars.linklist.pDelRoot; if (pThis->tVars.linklist.pDelRoot == pThis->tVars.linklist.pLast) { pThis->tVars.linklist.pDelRoot = pThis->tVars.linklist.pDeqRoot = pThis->tVars.linklist.pLast = NULL; } else { pThis->tVars.linklist.pDelRoot = pEntry->pNext; } free(pEntry); RETiRet; } /* -------------------- disk -------------------- */ /* The following function is used to "save" ourself from being killed by * a fatally failed disk queue. A fatal failure is, for example, if no * data can be read or written. In that case, the disk support is disabled, * with all on-disk structures kept as-is as much as possible. However, * we do not really stop or destruct the in-memory disk queue object. * Practice has shown that this may cause races during destruction which * themselfs can lead to segfault. So we prefer to was some ressources by * keeping the queue active. * Instead, the queue is switched to direct mode, so that at least * some processing can happen. Of course, this may still have lots of * undesired side-effects, but is probably better than aborting the * syslogd. Note that this function *must* succeed in one way or another, as * we can not recover from failure here. But it may emit different return * states, which can trigger different processing in the higher layers. * rgerhards, 2011-05-03 */ static rsRetVal queueSwitchToEmergencyMode(qqueue_t *pThis, rsRetVal initiatingError) { pThis->iQueueSize = 0; pThis->nLogDeq = 0; pThis->qType = QUEUETYPE_DIRECT; pThis->qConstruct = qConstructDirect; pThis->qDestruct = qDestructDirect; /* these entry points shall not be used in direct mode * To catch program errors, make us abort if that happens! * rgerhards, 2013-11-05 */ pThis->qAdd = qAddDirect; pThis->MultiEnq = qqueueMultiEnqObjDirect; pThis->qDel = NULL; if (pThis->pqParent != NULL) { DBGOPRINT((obj_t *)pThis, "DA queue is in emergency mode, disabling DA in parent\n"); pThis->pqParent->bIsDA = 0; pThis->pqParent->pqDA = NULL; /* This may have undesired side effects, not sure if I really evaluated * all. So you know where to look at if you come to this point during * troubleshooting ;) -- rgerhards, 2011-05-03 */ } LogError(0, initiatingError, "fatal error on disk queue '%s', " "emergency switch to direct mode", obj.GetName((obj_t *)pThis)); return RS_RET_ERR_QUEUE_EMERGENCY; } static rsRetVal qqueueLoadPersStrmInfoFixup(strm_t *pStrm, qqueue_t __attribute__((unused)) * pThis) { DEFiRet; ISOBJ_TYPE_assert(pStrm, strm); ISOBJ_TYPE_assert(pThis, qqueue); CHKiRet(strm.SetDir(pStrm, pThis->pszSpoolDir, pThis->lenSpoolDir)); CHKiRet(strm.SetbSync(pStrm, pThis->bSyncQueueFiles)); finalize_it: RETiRet; } /* The method loads the persistent queue information. * rgerhards, 2008-01-11 */ static rsRetVal qqueueTryLoadPersistedInfo(qqueue_t *pThis) { DEFiRet; strm_t *psQIF = NULL; struct stat stat_buf; ISOBJ_TYPE_assert(pThis, qqueue); /* check if the file exists */ if (stat((char *)pThis->pszQIFNam, &stat_buf) == -1) { if (errno == ENOENT) { DBGOPRINT((obj_t *)pThis, "clean startup, no .qi file found\n"); ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); } else { LogError(errno, RS_RET_IO_ERROR, "queue: %s: error %d could not access .qi file", obj.GetName((obj_t *)pThis), errno); ABORT_FINALIZE(RS_RET_IO_ERROR); } } /* If we reach this point, we have a .qi file */ CHKiRet(strm.Construct(&psQIF)); CHKiRet(strm.SettOperationsMode(psQIF, STREAMMODE_READ)); CHKiRet(strm.SetsType(psQIF, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetFName(psQIF, pThis->pszQIFNam, pThis->lenQIFNam)); CHKiRet(strm.ConstructFinalize(psQIF)); /* first, we try to read the property bag for ourselfs */ CHKiRet(obj.DeserializePropBag((obj_t *)pThis, psQIF)); /* then the stream objects (same order as when persisted!) */ CHKiRet(obj.Deserialize(&pThis->tVars.disk.pWrite, (uchar *)"strm", psQIF, (rsRetVal(*)(obj_t *, void *))qqueueLoadPersStrmInfoFixup, pThis)); CHKiRet(obj.Deserialize(&pThis->tVars.disk.pReadDel, (uchar *)"strm", psQIF, (rsRetVal(*)(obj_t *, void *))qqueueLoadPersStrmInfoFixup, pThis)); /* create a duplicate for the read "pointer". */ CHKiRet(strm.Dup(pThis->tVars.disk.pReadDel, &pThis->tVars.disk.pReadDeq)); CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDeq, 0)); /* deq must NOT delete the files! */ CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDeq)); /* if we use a crypto provider, we need to amend the objects with it's info */ if (pThis->useCryprov) { CHKiRet(strm.Setcryprov(pThis->tVars.disk.pWrite, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pWrite, pThis->cryprovData)); CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDeq, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDeq, pThis->cryprovData)); CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDel, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDel, pThis->cryprovData)); } CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pWrite)); CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDel)); CHKiRet(strm.SeekCurrOffs(pThis->tVars.disk.pReadDeq)); /* OK, we could successfully read the file, so we now can request that it be * deleted when we are done with the persisted information. */ pThis->bNeedDelQIF = 1; LogMsg(0, RS_RET_OK, LOG_INFO, "%s: queue files exist on disk, re-starting with " "%d messages. This will keep the disk queue file open, details: " "https://rainer.gerhards.net/2013/07/rsyslog-why-disk-assisted-queues-keep-a-file-open.html", objGetName((obj_t *)pThis), getLogicalQueueSize(pThis)); finalize_it: if (psQIF != NULL) strm.Destruct(&psQIF); if (iRet != RS_RET_OK) { DBGOPRINT((obj_t *)pThis, "state %d reading .qi file - can not read persisted info (if any)\n", iRet); } RETiRet; } /* disk queue constructor. * Note that we use a file limit of 10,000,000 files. That number should never pose a * problem. If so, I guess the user has a design issue... But of course, the code can * always be changed (though it would probably be more appropriate to increase the * allowed file size at this point - that should be a config setting... * rgerhards, 2008-01-10 */ static rsRetVal qConstructDisk(qqueue_t *pThis) { DEFiRet; int bRestarted = 0; assert(pThis != NULL); /* and now check if there is some persistent information that needs to be read in */ iRet = qqueueTryLoadPersistedInfo(pThis); if (iRet == RS_RET_OK) bRestarted = 1; else if (iRet != RS_RET_FILE_NOT_FOUND) FINALIZE; if (bRestarted == 1) { ; } else { CHKiRet(strm.Construct(&pThis->tVars.disk.pWrite)); CHKiRet(strm.SetbSync(pThis->tVars.disk.pWrite, pThis->bSyncQueueFiles)); CHKiRet(strm.SetDir(pThis->tVars.disk.pWrite, pThis->pszSpoolDir, pThis->lenSpoolDir)); CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pWrite, 10000000)); CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pWrite, STREAMMODE_WRITE)); CHKiRet(strm.SetsType(pThis->tVars.disk.pWrite, STREAMTYPE_FILE_CIRCULAR)); if (pThis->useCryprov) { CHKiRet(strm.Setcryprov(pThis->tVars.disk.pWrite, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pWrite, pThis->cryprovData)); } CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pWrite)); CHKiRet(strm.Construct(&pThis->tVars.disk.pReadDeq)); CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDeq, 0)); CHKiRet(strm.SetDir(pThis->tVars.disk.pReadDeq, pThis->pszSpoolDir, pThis->lenSpoolDir)); CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pReadDeq, 10000000)); CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pReadDeq, STREAMMODE_READ)); CHKiRet(strm.SetsType(pThis->tVars.disk.pReadDeq, STREAMTYPE_FILE_CIRCULAR)); if (pThis->useCryprov) { CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDeq, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDeq, pThis->cryprovData)); } CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDeq)); CHKiRet(strm.Construct(&pThis->tVars.disk.pReadDel)); CHKiRet(strm.SetbSync(pThis->tVars.disk.pReadDel, pThis->bSyncQueueFiles)); CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 1)); CHKiRet(strm.SetDir(pThis->tVars.disk.pReadDel, pThis->pszSpoolDir, pThis->lenSpoolDir)); CHKiRet(strm.SetiMaxFiles(pThis->tVars.disk.pReadDel, 10000000)); CHKiRet(strm.SettOperationsMode(pThis->tVars.disk.pReadDel, STREAMMODE_READ)); CHKiRet(strm.SetsType(pThis->tVars.disk.pReadDel, STREAMTYPE_FILE_CIRCULAR)); if (pThis->useCryprov) { CHKiRet(strm.Setcryprov(pThis->tVars.disk.pReadDel, &pThis->cryprov)); CHKiRet(strm.SetcryprovData(pThis->tVars.disk.pReadDel, pThis->cryprovData)); } CHKiRet(strm.ConstructFinalize(pThis->tVars.disk.pReadDel)); CHKiRet(strm.SetFName(pThis->tVars.disk.pWrite, pThis->pszFilePrefix, pThis->lenFilePrefix)); CHKiRet(strm.SetFName(pThis->tVars.disk.pReadDeq, pThis->pszFilePrefix, pThis->lenFilePrefix)); CHKiRet(strm.SetFName(pThis->tVars.disk.pReadDel, pThis->pszFilePrefix, pThis->lenFilePrefix)); } /* now we set (and overwrite in case of a persisted restart) some parameters which * should always reflect the current configuration variables. Be careful by doing so, * for example file name generation must not be changed as that would break the * ability to read existing queue files. -- rgerhards, 2008-01-12 */ CHKiRet(strm.SetiMaxFileSize(pThis->tVars.disk.pWrite, pThis->iMaxFileSize)); CHKiRet(strm.SetiMaxFileSize(pThis->tVars.disk.pReadDeq, pThis->iMaxFileSize)); CHKiRet(strm.SetiMaxFileSize(pThis->tVars.disk.pReadDel, pThis->iMaxFileSize)); finalize_it: RETiRet; } static rsRetVal qDestructDisk(qqueue_t *pThis) { DEFiRet; assert(pThis != NULL); free(pThis->pszQIFNam); if (pThis->tVars.disk.pWrite != NULL) { int64 currOffs; strm.GetCurrOffset(pThis->tVars.disk.pWrite, &currOffs); if (currOffs == 0) { /* if no data is present, we can (and must!) delete this * file. Else we can leave garbagge after termination. */ strm.SetbDeleteOnClose(pThis->tVars.disk.pWrite, 1); } strm.Destruct(&pThis->tVars.disk.pWrite); } if (pThis->tVars.disk.pReadDeq != NULL) strm.Destruct(&pThis->tVars.disk.pReadDeq); if (pThis->tVars.disk.pReadDel != NULL) strm.Destruct(&pThis->tVars.disk.pReadDel); RETiRet; } static rsRetVal ATTR_NONNULL(1, 2) qAddDisk(qqueue_t *const pThis, smsg_t *pMsg) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); ISOBJ_TYPE_assert(pMsg, msg); number_t nWriteCount; const int oldfile = strmGetCurrFileNum(pThis->tVars.disk.pWrite); CHKiRet(strm.SetWCntr(pThis->tVars.disk.pWrite, &nWriteCount)); CHKiRet((objSerialize(pMsg))(pMsg, pThis->tVars.disk.pWrite)); CHKiRet(strm.Flush(pThis->tVars.disk.pWrite)); CHKiRet(strm.SetWCntr(pThis->tVars.disk.pWrite, NULL)); /* no more counting for now... */ pThis->tVars.disk.sizeOnDisk += nWriteCount; /* we have enqueued the user element to disk. So we now need to destruct * the in-memory representation. The instance will be re-created upon * dequeue. -- rgerhards, 2008-07-09 */ msgDestruct(&pMsg); DBGOPRINT((obj_t *)pThis, "write wrote %lld octets to disk, queue disk size now %lld octets, EnqOnly:%d\n", nWriteCount, pThis->tVars.disk.sizeOnDisk, pThis->bEnqOnly); /* Did we have a change in the on-disk file? If so, we * should do a "robustness sync" of the .qi file to guard * against the most harsh consequences of kill -9 and power off. */ int newfile; newfile = strmGetCurrFileNum(pThis->tVars.disk.pWrite); if (newfile != oldfile) { DBGOPRINT((obj_t *)pThis, "current to-be-written-to file has changed from " "number %d to number %d - requiring a .qi write for robustness\n", oldfile, newfile); pThis->tVars.disk.nForcePersist = 2; } finalize_it: RETiRet; } static rsRetVal msgConstructFromVoid(void **ppThis) { return msgConstructForDeserializer((smsg_t **)ppThis); } static rsRetVal msgDeserializeFromVoid(void *pObj, strm_t *pStrm) { return MsgDeserialize((smsg_t *)pObj, pStrm); } static rsRetVal qDeqDisk(qqueue_t *pThis, smsg_t **ppMsg) { DEFiRet; iRet = objDeserializeWithMethods(ppMsg, (uchar *)"msg", sizeof("msg") - 1, pThis->tVars.disk.pReadDeq, NULL, NULL, msgConstructFromVoid, NULL, msgDeserializeFromVoid); if (iRet != RS_RET_OK) { LogError(0, iRet, "%s: qDeqDisk error happened at around offset %lld", obj.GetName((obj_t *)pThis), (long long)pThis->tVars.disk.pReadDeq->iCurrOffs); } RETiRet; } /* -------------------- direct (no queueing) -------------------- */ static rsRetVal qConstructDirect(qqueue_t __attribute__((unused)) * pThis) { return RS_RET_OK; } static rsRetVal qDestructDirect(qqueue_t __attribute__((unused)) * pThis) { return RS_RET_OK; } static rsRetVal qAddDirectWithWti(qqueue_t *pThis, smsg_t *pMsg, wti_t *pWti) { batch_t singleBatch; batch_obj_t batchObj; batch_state_t batchState = BATCH_STATE_RDY; DEFiRet; // TODO: init batchObj (states _OK and new fields -- CHECK) assert(pThis != NULL); /* calling the consumer is quite different here than it is from a worker thread */ /* we need to provide the consumer's return value back to the caller because in direct * mode the consumer probably has a lot to convey (which get's lost in the other modes * because they are asynchronous. But direct mode is deliberately synchronous. * rgerhards, 2008-02-12 * We use our knowledge about the batch_t structure below, but without that, we * pay a too-large performance toll... -- rgerhards, 2009-04-22 */ memset(&batchObj, 0, sizeof(batch_obj_t)); memset(&singleBatch, 0, sizeof(batch_t)); batchObj.pMsg = pMsg; singleBatch.nElem = 1; /* there always is only one in direct mode */ singleBatch.pElem = &batchObj; singleBatch.eltState = &batchState; iRet = pThis->pConsumer(pThis->pAction, &singleBatch, pWti); msgDestruct(&pMsg); RETiRet; } /* this is called if we do not have a pWti. This currently only happens * when we are called from a main queue in direct mode. If so, we need * to obtain a dummy pWti. */ static rsRetVal qAddDirect(qqueue_t *pThis, smsg_t *pMsg) { wti_t *pWti; DEFiRet; pWti = wtiGetDummy(); pWti->pbShutdownImmediate = &pThis->bShutdownImmediate; iRet = qAddDirectWithWti(pThis, pMsg, pWti); RETiRet; } /* --------------- end type-specific handlers -------------------- */ /* generic code to add a queue entry * We use some specific code to most efficiently support direct mode * queues. This is justified in spite of the gain and the need to do some * things truely different. -- rgerhards, 2008-02-12 */ static rsRetVal qqueueAdd(qqueue_t *pThis, smsg_t *pMsg) { DEFiRet; assert(pThis != NULL); static int msgCnt = 0; if (pThis->iSmpInterval > 0) { msgCnt = (msgCnt + 1) % (pThis->iSmpInterval); if (msgCnt != 0) { msgDestruct(&pMsg); goto finalize_it; } } CHKiRet(pThis->qAdd(pThis, pMsg)); if (pThis->qType != QUEUETYPE_DIRECT) { ATOMIC_INC(&pThis->iQueueSize, &pThis->mutQueueSize); #ifdef ENABLE_IMDIAG #ifdef HAVE_ATOMIC_BUILTINS /* mutex is never used due to conditional compilation */ ATOMIC_INC(&iOverallQueueSize, &NULL); #else ++iOverallQueueSize; /* racy, but we can't wait for a mutex! */ #endif #endif } finalize_it: RETiRet; } /* generic code to dequeue a queue entry */ static rsRetVal qqueueDeq(qqueue_t *pThis, smsg_t **ppMsg) { DEFiRet; assert(pThis != NULL); /* we do NOT abort if we encounter an error, because otherwise the queue * will not be decremented, what will most probably result in an endless loop. * If we decrement, however, we may lose a message. But that is better than * losing the whole process because it loops... -- rgerhards, 2008-01-03 */ iRet = pThis->qDeq(pThis, ppMsg); ATOMIC_INC(&pThis->nLogDeq, &pThis->mutLogDeq); DBGOPRINT((obj_t *)pThis, "entry deleted, size now log %d, phys %d entries\n", getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); RETiRet; } /* Try to shut down regular and DA queue workers, within the queue timeout * period. That means processing continues as usual. This is the expected * usual case, where during shutdown those messages remaining are being * processed. At this point, it is acceptable that the queue can not be * fully depleted, that case is handled in the next step. During this phase, * we first shut down the main queue DA worker to prevent new data to arrive * at the DA queue, and then we ask the regular workers of both the Regular * and DA queue to try complete processing. * rgerhards, 2009-10-14 */ static rsRetVal ATTR_NONNULL(1) tryShutdownWorkersWithinQueueTimeout(qqueue_t *const pThis) { struct timespec tTimeout; rsRetVal iRetLocal; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pThis->pqParent == NULL); /* detect invalid calling sequence */ if (pThis->bIsDA) { /* We need to lock the mutex, as otherwise we may have a race that prevents * us from awaking the DA worker. */ d_pthread_mutex_lock(pThis->mut); /* tell regular queue DA worker to stop shuffling messages to DA queue... */ DBGOPRINT((obj_t *)pThis, "setting EnqOnly mode for DA worker\n"); pThis->pqDA->bEnqOnly = 1; wtpSetState(pThis->pWtpDA, wtpState_SHUTDOWN_IMMEDIATE); wtpAdviseMaxWorkers(pThis->pWtpDA, 1, DENY_WORKER_START_DURING_SHUTDOWN); DBGOPRINT((obj_t *)pThis, "awoke DA worker, told it to shut down.\n"); /* also tell the DA queue worker to shut down, so that it already knows... */ wtpSetState(pThis->pqDA->pWtpReg, wtpState_SHUTDOWN); wtpAdviseMaxWorkers(pThis->pqDA->pWtpReg, 1, DENY_WORKER_START_DURING_SHUTDOWN); /* awake its lone worker */ DBGOPRINT((obj_t *)pThis, "awoke DA queue regular worker, told it to shut down when done.\n"); d_pthread_mutex_unlock(pThis->mut); } /* first calculate absolute timeout - we need the absolute value here, because we need to coordinate * shutdown of both the regular and DA queue on *the same* timeout. */ timeoutComp(&tTimeout, pThis->toQShutdown); DBGOPRINT((obj_t *)pThis, "trying shutdown of regular workers\n"); iRetLocal = wtpShutdownAll(pThis->pWtpReg, wtpState_SHUTDOWN, &tTimeout); if (iRetLocal == RS_RET_TIMED_OUT) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "%s: regular queue shutdown timed out on primary queue " "(this is OK, timeout was %d)", objGetName((obj_t *)pThis), pThis->toQShutdown); } else { DBGOPRINT((obj_t *)pThis, "regular queue workers shut down.\n"); } /* OK, the worker for the regular queue is processed, on the the DA queue regular worker. */ if (pThis->pqDA != NULL) { DBGOPRINT((obj_t *)pThis, "we have a DA queue (0x%lx), requesting its shutdown.\n", qqueueGetID(pThis->pqDA)); /* we use the same absolute timeout as above, so we do not use more than the configured * timeout interval! */ DBGOPRINT((obj_t *)pThis, "trying shutdown of regular worker of DA queue\n"); iRetLocal = wtpShutdownAll(pThis->pqDA->pWtpReg, wtpState_SHUTDOWN, &tTimeout); if (iRetLocal == RS_RET_TIMED_OUT) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "%s: regular queue shutdown timed out on DA queue (this is OK, " "timeout was %d)", objGetName((obj_t *)pThis), pThis->toQShutdown); } else { DBGOPRINT((obj_t *)pThis, "DA queue worker shut down.\n"); } } RETiRet; } /* Try to shut down regular and DA queue workers, within the action timeout * period. This aborts processing, but at the end of the current action, in * a well-defined manner. During this phase, we terminate all three worker * pools, including the regular queue DA worker if it not yet has terminated. * Not finishing processing all messages is OK (and expected) at this stage * (they may be preserved later, depending * on bSaveOnShutdown setting). * rgerhards, 2009-10-14 */ static rsRetVal tryShutdownWorkersWithinActionTimeout(qqueue_t *pThis) { struct timespec tTimeout; rsRetVal iRetLocal; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pThis->pqParent == NULL); /* detect invalid calling sequence */ /* instruct workers to finish ASAP, even if still work exists */ DBGOPRINT((obj_t *)pThis, "trying to shutdown workers within Action Timeout"); DBGOPRINT((obj_t *)pThis, "setting EnqOnly mode\n"); pThis->bEnqOnly = 1; pThis->bShutdownImmediate = 1; /* now DA queue */ if (pThis->bIsDA) { pThis->pqDA->bEnqOnly = 1; pThis->pqDA->bShutdownImmediate = 1; } /* now give the queue workers a last chance to gracefully shut down (based on action timeout setting) */ timeoutComp(&tTimeout, pThis->toActShutdown); DBGOPRINT((obj_t *)pThis, "trying immediate shutdown of regular workers (if any)\n"); iRetLocal = wtpShutdownAll(pThis->pWtpReg, wtpState_SHUTDOWN_IMMEDIATE, &tTimeout); if (iRetLocal == RS_RET_TIMED_OUT) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "%s: immediate shutdown timed out on primary queue (this is acceptable and " "triggers cancellation)", objGetName((obj_t *)pThis)); } else if (iRetLocal != RS_RET_OK) { LogMsg(0, iRetLocal, LOG_WARNING, "%s: potential internal error: unexpected return state after trying " "immediate shutdown of the primary queue in disk save mode. " "Continuing, but results are unpredictable", objGetName((obj_t *)pThis)); } if (pThis->pqDA != NULL) { /* and now the same for the DA queue */ DBGOPRINT((obj_t *)pThis, "trying immediate shutdown of DA queue workers\n"); iRetLocal = wtpShutdownAll(pThis->pqDA->pWtpReg, wtpState_SHUTDOWN_IMMEDIATE, &tTimeout); if (iRetLocal == RS_RET_TIMED_OUT) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "%s: immediate shutdown timed out on DA queue (this is acceptable and " "triggers cancellation)", objGetName((obj_t *)pThis)); } else if (iRetLocal != RS_RET_OK) { LogMsg(0, iRetLocal, LOG_WARNING, "%s: potential internal error: unexpected return state after trying " "immediate shutdown of the DA queue in disk save mode. " "Continuing, but results are unpredictable", objGetName((obj_t *)pThis)); } /* and now we need to terminate the DA worker itself. We always grant it a 100ms timeout, * which should be sufficient and usually not be required (it is expected to have finished * long before while we were processing the queue timeout in shutdown phase 1). * rgerhards, 2009-10-14 */ timeoutComp(&tTimeout, 100); DBGOPRINT((obj_t *)pThis, "trying regular shutdown of main queue DA worker pool\n"); iRetLocal = wtpShutdownAll(pThis->pWtpDA, wtpState_SHUTDOWN_IMMEDIATE, &tTimeout); if (iRetLocal == RS_RET_TIMED_OUT) { LogMsg(0, iRetLocal, LOG_WARNING, "%s: shutdown timed out on main queue DA worker pool " "(this is not good, but possibly OK)", objGetName((obj_t *)pThis)); } else { DBGOPRINT((obj_t *)pThis, "main queue DA worker pool shut down.\n"); } } RETiRet; } /* This function cancels all remaining regular workers for both the main and the DA * queue. * rgerhards, 2009-05-29 */ static rsRetVal cancelWorkers(qqueue_t *pThis) { rsRetVal iRetLocal; DEFiRet; assert(pThis->qType != QUEUETYPE_DIRECT); /* Now queue workers should have terminated. If not, we need to cancel them as we have applied * all timeout setting. If any worker in any queue still executes, its consumer is possibly * long-running and cancelling is the only way to get rid of it. */ DBGOPRINT((obj_t *)pThis, "checking to see if we need to cancel any worker threads of the primary queue\n"); iRetLocal = wtpCancelAll(pThis->pWtpReg, objGetName((obj_t *)pThis)); /* ^-- returns immediately if all threads already have terminated */ if (iRetLocal != RS_RET_OK) { DBGOPRINT((obj_t *)pThis, "unexpected iRet state %d trying to cancel primary queue worker " "threads, continuing, but results are unpredictable\n", iRetLocal); } /* ... and now the DA queue, if it exists (should always be after the primary one) */ if (pThis->pqDA != NULL) { DBGOPRINT((obj_t *)pThis, "checking to see if we need to cancel any worker threads of " "the DA queue\n"); iRetLocal = wtpCancelAll(pThis->pqDA->pWtpReg, objGetName((obj_t *)pThis)); /* returns immediately if all threads already have terminated */ if (iRetLocal != RS_RET_OK) { DBGOPRINT((obj_t *)pThis, "unexpected iRet state %d trying to cancel DA queue worker " "threads, continuing, but results are unpredictable\n", iRetLocal); } /* finally, we cancel the main queue's DA worker pool, if it still is running. It may be * restarted later to persist the queue. But we stop it, because otherwise we get into * big trouble when resetting the logical dequeue pointer. This operation can only be * done when *no* worker is running. So time for a shutdown... -- rgerhards, 2009-05-28 */ DBGOPRINT((obj_t *)pThis, "checking to see if main queue DA worker pool needs to be cancelled\n"); wtpCancelAll(pThis->pWtpDA, objGetName((obj_t *)pThis)); /* returns immediately if all threads already have terminated */ } RETiRet; } /* This function shuts down all worker threads and waits until they * have terminated. If they timeout, they are cancelled. * rgerhards, 2008-01-24 * Please note that this function shuts down BOTH the parent AND the child queue * in DA case. This is necessary because their timeouts are tightly coupled. Most * importantly, the timeouts would be applied twice (or logic be extremely * complex) if each would have its own shutdown. The function does not self check * this condition - the caller must make sure it is not called with a parent. * rgerhards, 2009-05-26: we do NO longer persist the queue here if bSaveOnShutdown * is set. This must be handled by the caller. Not doing that cleans up the queue * shutdown considerably. Also, older engines had a potential hang condition when * the DA queue was already started and the DA worker configured for infinite * retries and the action was during retry processing. This was a design issue, * which is solved as of now. Note that the shutdown now may take a little bit * longer, because we no longer can persist the queue in parallel to waiting * on worker timeouts. */ rsRetVal ATTR_NONNULL(1) qqueueShutdownWorkers(qqueue_t *const pThis) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); if (pThis->qType == QUEUETYPE_DIRECT) { FINALIZE; } assert(pThis->pqParent == NULL); /* detect invalid calling sequence */ DBGOPRINT((obj_t *)pThis, "initiating worker thread shutdown sequence %p\n", pThis); CHKiRet(tryShutdownWorkersWithinQueueTimeout(pThis)); pthread_mutex_lock(pThis->mut); int physQueueSize; physQueueSize = getPhysicalQueueSize(pThis); pthread_mutex_unlock(pThis->mut); if (physQueueSize > 0) { CHKiRet(tryShutdownWorkersWithinActionTimeout(pThis)); } CHKiRet(cancelWorkers(pThis)); /* ... finally ... all worker threads have terminated :-) * Well, more precisely, they *are in termination*. Some cancel cleanup handlers * may still be running. Note that the main queue's DA worker may still be running. */ DBGOPRINT((obj_t *)pThis, "worker threads terminated, remaining queue size log %d, phys %d.\n", getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); finalize_it: RETiRet; } /* Constructor for the queue object * This constructs the data structure, but does not yet start the queue. That * is done by queueStart(). The reason is that we want to give the caller a chance * to modify some parameters before the queue is actually started. */ rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThreads, int iMaxQueueSize, rsRetVal (*pConsumer)(void *, batch_t *, wti_t *)) { DEFiRet; qqueue_t *pThis; const uchar *const workDir = glblGetWorkDirRaw(ourConf); assert(ppThis != NULL); assert(pConsumer != NULL); assert(iWorkerThreads >= 0); CHKmalloc(pThis = (qqueue_t *)calloc(1, sizeof(qqueue_t))); /* we have an object, so let's fill the properties */ objConstructSetObjInfo(pThis); if (workDir != NULL) { if ((pThis->pszSpoolDir = ustrdup(workDir)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pThis->lenSpoolDir = ustrlen(pThis->pszSpoolDir); } /* set some water marks so that we have useful defaults if none are set specifically */ pThis->iFullDlyMrk = -1; pThis->iLightDlyMrk = -1; pThis->iMaxFileSize = 1024 * 1024; /* default is 1 MiB */ pThis->iQueueSize = 0; pThis->nLogDeq = 0; pThis->useCryprov = 0; pThis->takeFlowCtlFromMsg = 0; pThis->iMaxQueueSize = iMaxQueueSize; pThis->pConsumer = pConsumer; pThis->iNumWorkerThreads = iWorkerThreads; pThis->iDeqtWinToHr = 25; /* disable time-windowed dequeuing by default */ pThis->iDeqBatchSize = 8; /* conservative default, should still provide good performance */ pThis->iMinDeqBatchSize = 0; /* conservative default, should still provide good performance */ pThis->isRunning = 0; pThis->pszFilePrefix = NULL; pThis->qType = qType; INIT_ATOMIC_HELPER_MUT(pThis->mutQueueSize); INIT_ATOMIC_HELPER_MUT(pThis->mutLogDeq); finalize_it: OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP RETiRet; } /* set default inside queue object suitable for action queues. * This shall be called directly after queue construction. This functions has * been added in support of the new v6 config system. It expect properly pre-initialized * objects, but we need to differentiate between ruleset main and action queues. * In order to avoid unnecessary complexity, we provide the necessary defaults * via specific function calls. */ void qqueueSetDefaultsActionQueue(qqueue_t *pThis) { pThis->qType = QUEUETYPE_DIRECT; /* type of the main message queue above */ pThis->iMaxQueueSize = 1000; /* size of the main message queue above */ pThis->iDeqBatchSize = 128; /* default batch size */ pThis->iMinDeqBatchSize = 0; pThis->toMinDeqBatchSize = 1000; pThis->iHighWtrMrk = -1; /* high water mark for disk-assisted queues */ pThis->iLowWtrMrk = -1; /* low water mark for disk-assisted queues */ pThis->iDiscardMrk = -1; /* begin to discard messages */ pThis->iDiscardSeverity = 8; /* turn off */ pThis->iNumWorkerThreads = 1; /* number of worker threads for the mm queue above */ pThis->iMaxFileSize = 1024 * 1024; pThis->iPersistUpdCnt = 0; /* persist queue info every n updates */ pThis->bSyncQueueFiles = 0; pThis->toQShutdown = loadConf->globals.actq_dflt_toQShutdown; /* queue shutdown */ pThis->toActShutdown = loadConf->globals.actq_dflt_toActShutdown; /* action shutdown (in phase 2) */ pThis->toEnq = loadConf->globals.actq_dflt_toEnq; /* timeout for queue enque */ pThis->toWrkShutdown = loadConf->globals.actq_dflt_toWrkShutdown; /* timeout for worker thread shutdown */ pThis->iMinMsgsPerWrkr = -1; /* minimum messages per worker needed to start a new one */ pThis->bSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ pThis->sizeOnDiskMax = 0; /* unlimited */ pThis->iDeqSlowdown = 0; pThis->iDeqtWinFromHr = 0; pThis->iDeqtWinToHr = 25; /* disable time-windowed dequeuing by default */ pThis->iSmpInterval = 0; /* disable sampling */ } /* set defaults inside queue object suitable for main/ruleset queues. * See queueSetDefaultsActionQueue() for more details and background. */ void qqueueSetDefaultsRulesetQueue(qqueue_t *pThis) { pThis->qType = QUEUETYPE_FIXED_ARRAY; /* type of the main message queue above */ pThis->iMaxQueueSize = 50000; /* size of the main message queue above */ pThis->iDeqBatchSize = 1024; /* default batch size */ pThis->iMinDeqBatchSize = 0; pThis->toMinDeqBatchSize = 1000; pThis->iHighWtrMrk = -1; /* high water mark for disk-assisted queues */ pThis->iLowWtrMrk = -1; /* low water mark for disk-assisted queues */ pThis->iDiscardMrk = -1; /* begin to discard messages */ pThis->iDiscardSeverity = 8; /* turn off */ pThis->iNumWorkerThreads = 1; /* number of worker threads for the mm queue above */ pThis->iMaxFileSize = 16 * 1024 * 1024; pThis->iPersistUpdCnt = 0; /* persist queue info every n updates */ pThis->bSyncQueueFiles = 0; pThis->toQShutdown = ourConf->globals.ruleset_dflt_toQShutdown; pThis->toActShutdown = ourConf->globals.ruleset_dflt_toActShutdown; pThis->toEnq = ourConf->globals.ruleset_dflt_toEnq; pThis->toWrkShutdown = ourConf->globals.ruleset_dflt_toWrkShutdown; pThis->iMinMsgsPerWrkr = -1; /* minimum messages per worker needed to start a new one */ pThis->bSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ pThis->sizeOnDiskMax = 0; /* unlimited */ pThis->iDeqSlowdown = 0; pThis->iDeqtWinFromHr = 0; pThis->iDeqtWinToHr = 25; /* disable time-windowed dequeuing by default */ pThis->iSmpInterval = 0; /* disable sampling */ } /* This function checks if the provided message shall be discarded and does so, if needed. * In DA mode, we do not discard any messages as we assume the disk subsystem is fast enough to * provide real-time creation of spool files. * Note: cached copies of iQueueSize is provided so that no mutex locks are required. * The caller must have obtained them while the mutex was locked. Of course, these values may no * longer be current, but that is OK for the discard check. At worst, the message is either processed * or discarded when it should not have been. As discarding is in itself somewhat racy and erratic, * that is no problems for us. This function MUST NOT lock the queue mutex, it could result in * deadlocks! * If the message is discarded, it can no longer be processed by the caller. So be sure to check * the return state! * rgerhards, 2008-01-24 */ static int qqueueChkDiscardMsg(qqueue_t *pThis, int iQueueSize, smsg_t *pMsg) { DEFiRet; rsRetVal iRetLocal; int iSeverity; ISOBJ_TYPE_assert(pThis, qqueue); if (pThis->iDiscardMrk > 0 && iQueueSize >= pThis->iDiscardMrk) { iRetLocal = MsgGetSeverity(pMsg, &iSeverity); if (iRetLocal == RS_RET_OK && iSeverity >= pThis->iDiscardSeverity) { DBGOPRINT((obj_t *)pThis, "queue nearly full (%d entries), discarded severity %d message\n", iQueueSize, iSeverity); STATSCOUNTER_INC(pThis->ctrNFDscrd, pThis->mutCtrNFDscrd); msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } else { DBGOPRINT((obj_t *)pThis, "queue nearly full (%d entries), but could not drop msg " "(iRet: %d, severity %d)\n", iQueueSize, iRetLocal, iSeverity); } } finalize_it: RETiRet; } /* Finally remove n elements from the queue store. */ static rsRetVal ATTR_NONNULL(1) DoDeleteBatchFromQStore(qqueue_t *const pThis, const int nElem) { int i; off64_t bytesDel = 0; /* keep CLANG static anaylzer happy */ DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); /* now send delete request to storage driver */ if (pThis->qType == QUEUETYPE_DISK) { strmMultiFileSeek(pThis->tVars.disk.pReadDel, pThis->tVars.disk.deqFileNumOut, pThis->tVars.disk.deqOffs, &bytesDel); /* We need to correct the on-disk file size. This time it is a bit tricky: * we free disk space only upon file deletion. So we need to keep track of what we * have read until we get an out-offset that is lower than the in-offset (which * indicates file change). Then, we can subtract the whole thing from the on-disk * size. -- rgerhards, 2008-01-30 */ if (bytesDel != 0) { pThis->tVars.disk.sizeOnDisk -= bytesDel; DBGOPRINT((obj_t *)pThis, "doDeleteBatch: a %lld octet file has been deleted, now %lld " "octets disk space used\n", (long long)bytesDel, pThis->tVars.disk.sizeOnDisk); /* awake possibly waiting enq process */ pthread_cond_signal(&pThis->notFull); /* we hold the mutex while we are in here! */ } } else { /* memory queue */ for (i = 0; i < nElem; ++i) { pThis->qDel(pThis); } } /* iQueueSize is not decremented by qDel(), so we need to do it ourselves */ ATOMIC_SUB(&pThis->iQueueSize, nElem, &pThis->mutQueueSize); #ifdef ENABLE_IMDIAG #ifdef HAVE_ATOMIC_BUILTINS /* mutex is never used due to conditional compilation */ ATOMIC_SUB(&iOverallQueueSize, nElem, &NULL); #else iOverallQueueSize -= nElem; /* racy, but we can't wait for a mutex! */ #endif #endif ATOMIC_SUB(&pThis->nLogDeq, nElem, &pThis->mutLogDeq); DBGPRINTF("doDeleteBatch: delete batch from store, new sizes: log %d, phys %d\n", getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); ++pThis->deqIDDel; /* one more batch dequeued */ if ((pThis->qType == QUEUETYPE_DISK) && (bytesDel != 0)) { qqueuePersist(pThis, QUEUE_CHECKPOINT); /* robustness persist .qi file */ } RETiRet; } typedef enum tdlPhase_e { TDL_EMPTY, TDL_PROCESS_HEAD, TDL_QUEUE } tdlPhase_t; /** * Remove messages from the physical queue store that are fully processed. * * Deletion proceeds through a small state machine governed by the * to-delete list: * - TDL_EMPTY: list is empty, delete the current batch directly. * - TDL_PROCESS_HEAD: pending head elements are removed first, then the * current batch. * - TDL_QUEUE: current batch cannot be deleted and is queued for later. * * The dequeue identifier advances strictly monotonically, ensuring * deterministic order and proper resource release for both disk and * memory queue implementations. */ static rsRetVal DeleteBatchFromQStore(qqueue_t *pThis, batch_t *pBatch) { toDeleteLst_t *pTdl; qDeqID nextID; tdlPhase_t phase; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pBatch != NULL); dbgprintf("rger: deleteBatchFromQStore, nElem %d\n", (int)pBatch->nElem); pTdl = tdlPeek(pThis); /* get current head element */ if (pTdl == NULL) { phase = TDL_EMPTY; } else if (pBatch->deqID == pThis->deqIDDel) { phase = TDL_PROCESS_HEAD; } else { phase = TDL_QUEUE; } switch (phase) { case TDL_EMPTY: DoDeleteBatchFromQStore(pThis, pBatch->nElem); break; case TDL_PROCESS_HEAD: nextID = pThis->deqIDDel; while ((pTdl = tdlPeek(pThis)) != NULL && pTdl->deqID == nextID) { DoDeleteBatchFromQStore(pThis, pTdl->nElemDeq); tdlPop(pThis); ++nextID; } assert(pThis->deqIDDel == nextID); /* old entries deleted, now delete current ones... */ DoDeleteBatchFromQStore(pThis, pBatch->nElem); break; case TDL_QUEUE: /* cannot delete, insert into to-delete list */ DBGPRINTF("not at head of to-delete list, enqueue %d\n", (int)pBatch->deqID); CHKiRet(tdlAdd(pThis, pBatch->deqID, pBatch->nElem)); break; default: /* all phases should be handled above. */ assert(0 && "unhandled tdlPhase_t"); break; } finalize_it: RETiRet; } /* Delete a batch of processed user objects from the queue, which includes * destructing the objects themself. Any entries not marked as finally * processed are enqueued again. The new enqueue is necessary because we have a * rgerhards, 2009-05-13 */ static rsRetVal DeleteProcessedBatch(qqueue_t *pThis, batch_t *pBatch) { int i; smsg_t *pMsg; int nEnqueued = 0; rsRetVal localRet; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pBatch != NULL); for (i = 0; i < pBatch->nElem; ++i) { pMsg = pBatch->pElem[i].pMsg; DBGPRINTF("DeleteProcessedBatch: etry %d state %d\n", i, pBatch->eltState[i]); if (pBatch->eltState[i] == BATCH_STATE_RDY || pBatch->eltState[i] == BATCH_STATE_SUB) { localRet = doEnqSingleObj(pThis, eFLOWCTL_NO_DELAY, MsgAddRef(pMsg)); ++nEnqueued; if (localRet != RS_RET_OK) { DBGPRINTF( "DeleteProcessedBatch: error %d re-enqueuing unprocessed " "data element - discarded\n", localRet); } } msgDestruct(&pMsg); } DBGPRINTF("DeleteProcessedBatch: we deleted %d objects and enqueued %d objects\n", i - nEnqueued, nEnqueued); if (nEnqueued > 0) qqueueChkPersist(pThis, nEnqueued); iRet = DeleteBatchFromQStore(pThis, pBatch); pBatch->nElem = pBatch->nElemDeq = 0; /* reset batch */ // TODO: more fine init, new fields! 2010-06-14 RETiRet; } /* dequeue as many user pointers as are available, until we hit the configured * upper limit of pointers. Note that this function also deletes all processed * objects from the previous batch. However, it is perfectly valid that the * previous batch contained NO objects at all. For example, this happens * immediately after system startup or when a queue was exhausted and the queue * worker needed to wait for new data. * This must only be called when the queue mutex is LOOKED, otherwise serious * malfunction will happen. */ static rsRetVal ATTR_NONNULL() DequeueConsumableElements(qqueue_t *const pThis, wti_t *const pWti, int *const piRemainingQueueSize, int *const pSkippedMsgs) { int nDequeued; int nDiscarded; int nDeleted; int iQueueSize; int keep_running = 1; struct timespec timeout; smsg_t *pMsg; rsRetVal localRet; DEFiRet; nDeleted = pWti->batch.nElemDeq; DeleteProcessedBatch(pThis, &pWti->batch); nDequeued = nDiscarded = 0; if (pThis->qType == QUEUETYPE_DISK) { pThis->tVars.disk.deqFileNumIn = strmGetCurrFileNum(pThis->tVars.disk.pReadDeq); } /* work-around clang static analyzer false positive, we need a const value */ const int iMinDeqBatchSize = pThis->iMinDeqBatchSize; if (iMinDeqBatchSize > 0) { timeoutComp(&timeout, pThis->toMinDeqBatchSize); /* get absolute timeout */ } while ((iQueueSize = getLogicalQueueSize(pThis)) > 0 && nDequeued < pThis->iDeqBatchSize) { int rd_fd = -1; int64_t rd_offs = 0; int wr_fd = -1; int64_t wr_offs = 0; if (pThis->tVars.disk.pReadDeq != NULL) { rd_fd = strmGetCurrFileNum(pThis->tVars.disk.pReadDeq); rd_offs = pThis->tVars.disk.pReadDeq->iCurrOffs; } if (pThis->tVars.disk.pWrite != NULL) { wr_fd = strmGetCurrFileNum(pThis->tVars.disk.pWrite); wr_offs = pThis->tVars.disk.pWrite->iCurrOffs; } if (rd_fd != -1 && rd_fd == wr_fd && rd_offs == wr_offs) { DBGPRINTF( "problem on disk queue '%s': " //"queue size log %d, phys %d, but rd_fd=wr_rd=%d and offs=%lld\n", "queue size log %d, phys %d, but rd_fd=wr_rd=%d and offs=%" PRId64 "\n", obj.GetName((obj_t *)pThis), iQueueSize, pThis->iQueueSize, rd_fd, rd_offs); *pSkippedMsgs = iQueueSize; #ifdef ENABLE_IMDIAG iOverallQueueSize -= iQueueSize; #endif pThis->iQueueSize -= iQueueSize; iQueueSize = 0; break; } localRet = qqueueDeq(pThis, &pMsg); if (localRet == RS_RET_FILE_NOT_FOUND) { DBGPRINTF( "fatal error on disk queue '%s': file '%s' " "not found, queue size said to be %d", obj.GetName((obj_t *)pThis), "...", iQueueSize); } CHKiRet(localRet); /* check if we should discard this element */ localRet = qqueueChkDiscardMsg(pThis, pThis->iQueueSize, pMsg); if (localRet == RS_RET_QUEUE_FULL) { ++nDiscarded; continue; } else if (localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } /* all well, use this element */ pWti->batch.pElem[nDequeued].pMsg = pMsg; pWti->batch.eltState[nDequeued] = BATCH_STATE_RDY; ++nDequeued; if (nDequeued < iMinDeqBatchSize && getLogicalQueueSize(pThis) == 0) { while (!pThis->bShutdownImmediate && keep_running && nDequeued < iMinDeqBatchSize && getLogicalQueueSize(pThis) == 0) { dbgprintf( "%s minDeqBatchSize doing wait, batch is %d messages, " "queue size %d\n", obj.GetName((obj_t *)pThis), nDequeued, getLogicalQueueSize(pThis)); if (wtiWaitNonEmpty(pWti, timeout) == 0) { /* timeout? */ DBGPRINTF("%s minDeqBatchSize timeout, batch is %d messages\n", obj.GetName((obj_t *)pThis), nDequeued); keep_running = 0; } } } if (keep_running) { keep_running = (getLogicalQueueSize(pThis) > 0) && (nDequeued < pThis->iDeqBatchSize); } } if (pThis->qType == QUEUETYPE_DISK) { strm.GetCurrOffset(pThis->tVars.disk.pReadDeq, &pThis->tVars.disk.deqOffs); pThis->tVars.disk.deqFileNumOut = strmGetCurrFileNum(pThis->tVars.disk.pReadDeq); } /* it is sufficient to persist only when the bulk of work is done */ qqueueChkPersist(pThis, nDequeued + nDiscarded + nDeleted); /* If messages where DISCARDED, we need to substract them from the OverallQueueSize */ #ifdef ENABLE_IMDIAG #ifdef HAVE_ATOMIC_BUILTINS ATOMIC_SUB(&iOverallQueueSize, nDiscarded, &NULL); #else iOverallQueueSize -= nDiscarded; /* racy, but we can't wait for a mutex! */ #endif DBGOPRINT((obj_t *)pThis, "dequeued %d discarded %d QueueSize %d consumable elements, szlog %d sz phys %d\n", nDequeued, nDiscarded, iOverallQueueSize, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); #else DBGOPRINT((obj_t *)pThis, "dequeued %d discarded %d consumable elements, szlog %d sz phys %d\n", nDequeued, nDiscarded, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); #endif pWti->batch.nElem = nDequeued; pWti->batch.nElemDeq = nDequeued + nDiscarded; pWti->batch.deqID = getNextDeqID(pThis); *piRemainingQueueSize = iQueueSize; finalize_it: RETiRet; } /* dequeue the queued object for the queue consumers. * rgerhards, 2008-10-21 * I made a radical change - we now dequeue multiple elements, and store these objects in * an array of user pointers. We expect that this increases performance. * rgerhards, 2009-04-22 */ static rsRetVal DequeueConsumable(qqueue_t *pThis, wti_t *pWti, int *const pSkippedMsgs) { DEFiRet; int iQueueSize = 0; /* keep the compiler happy... */ *pSkippedMsgs = 0; /* dequeue element batch (still protected from mutex) */ iRet = DequeueConsumableElements(pThis, pWti, &iQueueSize, pSkippedMsgs); if (*pSkippedMsgs > 0) { LogError(0, RS_RET_ERR, "%s: lost %d messages from diskqueue (invalid .qi file)", obj.GetName((obj_t *)pThis), *pSkippedMsgs); } /* awake some flow-controlled sources if we can do this right now */ /* TODO: this could be done better from a performance point of view -- do it only if * we have someone waiting for the condition (or only when we hit the watermark right * on the nail [exact value]) -- rgerhards, 2008-03-14 * now that we dequeue batches of pointers, this is much less an issue... * rgerhards, 2009-04-22 */ if (iQueueSize < pThis->iFullDlyMrk / 2 || glbl.GetGlobalInputTermState() == 1) { pthread_cond_broadcast(&pThis->belowFullDlyWtrMrk); } if (iQueueSize < pThis->iLightDlyMrk / 2) { pthread_cond_broadcast(&pThis->belowLightDlyWtrMrk); } pthread_cond_signal(&pThis->notFull); /* WE ARE NO LONGER PROTECTED BY THE MUTEX */ if (iRet != RS_RET_OK && iRet != RS_RET_DISCARDMSG) { LogError(0, iRet, "%s: error dequeueing element - ignoring, " "but strange things may happen", obj.GetName((obj_t *)pThis)); } RETiRet; } /* The rate limiter * * IMPORTANT: the rate-limiter MUST unlock and re-lock the queue when * it actually delays processing. Otherwise inputs are stalled. * * Here we may wait if a dequeue time window is defined or if we are * rate-limited. TODO: If we do so, we should also look into the * way new worker threads are spawned. Obviously, it doesn't make much * sense to spawn additional worker threads when none of them can do any * processing. However, it is deemed acceptable to allow this for an initial * implementation of the timeframe/rate limiting feature. * Please also note that these feature could also be implemented at the action * level. However, that would limit them to be used together with actions. We have * taken the broader approach, moving it right into the queue. This is even * necessary if we want to prevent spawning of multiple unnecessary worker * threads as described above. -- rgerhards, 2008-04-02 * * * time window: tCurr is current time; tFrom is start time, tTo is end time (in mil 24h format). * We may have tFrom = 4, tTo = 10 --> run from 4 to 10 hrs. nice and happy * we may also have tFrom= 22, tTo = 4 -> run from 10pm to 4am, which is actually two * windows: 0-4; 22-23:59 * so when to run? Let's assume we have 3am * * if(tTo < tFrom) { * if(tCurr < tTo [3 < 4] || tCurr > tFrom [3 > 22]) * do work * else * sleep for tFrom - tCurr "hours" [22 - 5 --> 17] * } else { * if(tCurr >= tFrom [3 >= 4] && tCurr < tTo [3 < 10]) * do work * else * sleep for tTo - tCurr "hours" [4 - 3 --> 1] * } * * Bottom line: we need to check which type of window we have and need to adjust our * logic accordingly. Of course, sleep calculations need to be done up to the minute, * but you get the idea from the code above. */ static rsRetVal RateLimiter(qqueue_t *pThis) { DEFiRet; int iDelay; int iHrCurr; time_t tCurr; struct tm m; ISOBJ_TYPE_assert(pThis, qqueue); iDelay = 0; if (pThis->iDeqtWinToHr != 25) { /* 25 means disabled */ /* time calls are expensive, so only do them when needed */ datetime.GetTime(&tCurr); localtime_r(&tCurr, &m); iHrCurr = m.tm_hour; if (pThis->iDeqtWinToHr < pThis->iDeqtWinFromHr) { if (iHrCurr < pThis->iDeqtWinToHr || iHrCurr > pThis->iDeqtWinFromHr) { ; /* do not delay */ } else { iDelay = (pThis->iDeqtWinFromHr - iHrCurr) * 3600; /* this time, we are already into the next hour, so we need * to subtract our current minute and seconds. */ iDelay -= m.tm_min * 60; iDelay -= m.tm_sec; } } else { if (iHrCurr >= pThis->iDeqtWinFromHr && iHrCurr < pThis->iDeqtWinToHr) { ; /* do not delay */ } else { if (iHrCurr < pThis->iDeqtWinFromHr) { iDelay = (pThis->iDeqtWinFromHr - iHrCurr - 1) * 3600; /* -1 as we are already in the hour */ iDelay += (60 - m.tm_min) * 60; iDelay += 60 - m.tm_sec; } else { iDelay = (24 - iHrCurr + pThis->iDeqtWinFromHr) * 3600; /* this time, we are already into the next hour, so we need * to subtract our current minute and seconds. */ iDelay -= m.tm_min * 60; iDelay -= m.tm_sec; } } } } if (iDelay > 0) { pthread_mutex_unlock(pThis->mut); DBGOPRINT((obj_t *)pThis, "outside dequeue time window, delaying %d seconds\n", iDelay); srSleep(iDelay, 0); pthread_mutex_lock(pThis->mut); } RETiRet; } /* This dequeues the next batch. Note that this function must not be * cancelled, else it will leave back an inconsistent state. * rgerhards, 2009-05-20 */ static rsRetVal DequeueForConsumer(qqueue_t *pThis, wti_t *pWti, int *const pSkippedMsgs) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); ISOBJ_TYPE_assert(pWti, wti); CHKiRet(DequeueConsumable(pThis, pWti, pSkippedMsgs)); if (pWti->batch.nElem == 0) ABORT_FINALIZE(RS_RET_IDLE); finalize_it: RETiRet; } /* This is called when a batch is processed and the worker does not * ask for another batch (e.g. because it is to be terminated) * Note that we must not be terminated while we delete a processed * batch. Otherwise, we may not complete it, and then the cancel * handler also tries to delete the batch. But then it finds some of * the messages already destructed. This was a bug we have seen, especially * with disk mode, where a delete takes rather long. Anyhow, the coneptual * problem exists in all queue modes. * rgerhards, 2009-05-27 */ static rsRetVal batchProcessed(qqueue_t *pThis, wti_t *pWti) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); ISOBJ_TYPE_assert(pWti, wti); int iCancelStateSave; /* at this spot, we must not be cancelled */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); DeleteProcessedBatch(pThis, &pWti->batch); qqueueChkPersist(pThis, pWti->batch.nElemDeq); pthread_setcancelstate(iCancelStateSave, NULL); RETiRet; } /* This is the queue consumer in the regular (non-DA) case. It is * protected by the queue mutex, but MUST release it as soon as possible. * rgerhards, 2008-01-21 */ static rsRetVal ConsumerReg(qqueue_t *pThis, wti_t *pWti) { int iCancelStateSave; int bNeedReLock = 0; /**< do we need to lock the mutex again? */ int skippedMsgs = 0; /**< did the queue loose any messages (can happen with ** disk queue if .qi file is corrupt */ DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); ISOBJ_TYPE_assert(pWti, wti); iRet = DequeueForConsumer(pThis, pWti, &skippedMsgs); if (iRet == RS_RET_FILE_NOT_FOUND) { /* This is a fatal condition and means the queue is almost unusable */ d_pthread_mutex_unlock(pThis->mut); DBGOPRINT((obj_t *)pThis, "got 'file not found' error %d, queue defunct\n", iRet); iRet = queueSwitchToEmergencyMode(pThis, iRet); // TODO: think about what to return as iRet -- keep RS_RET_FILE_NOT_FOUND? d_pthread_mutex_lock(pThis->mut); } if (iRet != RS_RET_OK) { FINALIZE; } /* we now have a non-idle batch of work, so we can release the queue mutex and process it */ d_pthread_mutex_unlock(pThis->mut); bNeedReLock = 1; /* report errors, now that we are outside of queue lock */ if (skippedMsgs > 0) { LogError(0, 0, "problem on disk queue '%s': " "queue files contain %d messages fewer than specified " "in .qi file -- we lost those messages. That's all we know.", obj.GetName((obj_t *)pThis), skippedMsgs); } /* at this spot, we may be cancelled */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &iCancelStateSave); pWti->pbShutdownImmediate = &pThis->bShutdownImmediate; CHKiRet(pThis->pConsumer(pThis->pAction, &pWti->batch, pWti)); /* we now need to check if we should deliberately delay processing a bit * and, if so, do that. -- rgerhards, 2008-01-30 */ if (pThis->iDeqSlowdown) { DBGOPRINT((obj_t *)pThis, "sleeping %d microseconds as requested by config params\n", pThis->iDeqSlowdown); srSleep(pThis->iDeqSlowdown / 1000000, pThis->iDeqSlowdown % 1000000); } /* but now cancellation is no longer permitted */ pthread_setcancelstate(iCancelStateSave, NULL); finalize_it: DBGPRINTF("regular consumer finished, iret=%d, szlog %d sz phys %d\n", iRet, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); /* now we are done, but potentially need to re-acquire the mutex */ if (bNeedReLock) d_pthread_mutex_lock(pThis->mut); RETiRet; } /* This is a special consumer to feed the disk-queue in disk-assisted mode. * When active, our own queue more or less acts as a memory buffer to the disk. * So this consumer just needs to drain the memory queue and submit entries * to the disk queue. The disk queue will then call the actual consumer from * the app point of view (we chain two queues here). * When this method is entered, the mutex is always locked and needs to be unlocked * as part of the processing. * rgerhards, 2008-01-14 */ static rsRetVal ConsumerDA(qqueue_t *pThis, wti_t *pWti) { int i; int iCancelStateSave; int bNeedReLock = 0; /**< do we need to lock the mutex again? */ int skippedMsgs = 0; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); ISOBJ_TYPE_assert(pWti, wti); CHKiRet(DequeueForConsumer(pThis, pWti, &skippedMsgs)); /* we now have a non-idle batch of work, so we can release the queue mutex and process it */ d_pthread_mutex_unlock(pThis->mut); bNeedReLock = 1; /* at this spot, we may be cancelled */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &iCancelStateSave); /* iterate over returned results and enqueue them in DA queue */ for (i = 0; i < pWti->batch.nElem && !pThis->bShutdownImmediate; i++) { iRet = qqueueEnqMsg(pThis->pqDA, eFLOWCTL_NO_DELAY, MsgAddRef(pWti->batch.pElem[i].pMsg)); if (iRet != RS_RET_OK) { if (iRet == RS_RET_ERR_QUEUE_EMERGENCY) { /* Queue emergency error occurred */ DBGOPRINT((obj_t *)pThis, "ConsumerDA:qqueueEnqMsg caught RS_RET_ERR_QUEUE_EMERGENCY," "aborting loop.\n"); FINALIZE; } else { DBGOPRINT((obj_t *)pThis, "ConsumerDA:qqueueEnqMsg item (%d) returned " "with error state: '%d'\n", i, iRet); } } pWti->batch.eltState[i] = BATCH_STATE_COMM; /* commited to other queue! */ } /* but now cancellation is no longer permitted */ pthread_setcancelstate(iCancelStateSave, NULL); finalize_it: /* Check the last return state of qqueueEnqMsg. If an error was returned, we acknowledge it only. * Unless the error code is RS_RET_ERR_QUEUE_EMERGENCY, we reset the return state to RS_RET_OK. * Otherwise the Caller functions would run into an infinite Loop trying to enqueue the * same messages over and over again. * * However we do NOT overwrite positive return states like * RS_RET_TERMINATE_NOW, * RS_RET_NO_RUN, * RS_RET_IDLE, * RS_RET_TERMINATE_WHEN_IDLE * These return states are important for Queue handling of the upper laying functions. * RGer: Note that checking for iRet < 0 is a bit bold. In theory, positive iRet * values are "OK" states, and things that the caller shall deal with. However, * this has not been done so consistently. Andre convinced me that the current * code is an elegant solution. However, if problems with queue workers and/or * shutdown come up, this code here should be looked at suspiciously. In those * cases it may work out to check all status codes explicitely, just to avoid * a pitfall due to unexpected states being passed on to the caller. */ if (iRet != RS_RET_OK && iRet != RS_RET_ERR_QUEUE_EMERGENCY && iRet < 0) { DBGOPRINT((obj_t *)pThis, "ConsumerDA:qqueueEnqMsg Resetting iRet from %d back to RS_RET_OK\n", iRet); iRet = RS_RET_OK; } else { DBGOPRINT((obj_t *)pThis, "ConsumerDA:qqueueEnqMsg returns with iRet %d\n", iRet); } /* now we are done, but potentially need to re-acquire the mutex */ if (bNeedReLock) d_pthread_mutex_lock(pThis->mut); RETiRet; } /* must only be called when the queue mutex is locked, else results * are not stable! */ static rsRetVal qqueueChkStopWrkrDA(qqueue_t *pThis) { DEFiRet; DBGPRINTF("rger: chkStopWrkrDA called, low watermark %d, log Size %d, phys Size %d, bEnqOnly %d\n", pThis->iLowWtrMrk, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis), pThis->bEnqOnly); if (pThis->bEnqOnly) { iRet = RS_RET_TERMINATE_WHEN_IDLE; } if (getPhysicalQueueSize(pThis) <= pThis->iLowWtrMrk) { iRet = RS_RET_TERMINATE_NOW; } RETiRet; } /* must only be called when the queue mutex is locked, else results * are not stable! * If we are a child, we have done our duty when the queue is empty. In that case, * we can terminate. Version for the regular worker thread. */ static rsRetVal ChkStopWrkrReg(qqueue_t *pThis) { DEFiRet; /*DBGPRINTF("XXXX: chkStopWrkrReg called, low watermark %d, log Size %d, phys Size %d, bEnqOnly %d\n", pThis->iLowWtrMrk, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis), pThis->bEnqOnly);*/ if (pThis->bEnqOnly) { iRet = RS_RET_TERMINATE_NOW; } else if (pThis->pqParent != NULL) { iRet = RS_RET_TERMINATE_WHEN_IDLE; } RETiRet; } /* return the configured "deq max at once" interval * rgerhards, 2009-04-22 */ static rsRetVal GetDeqBatchSize(qqueue_t *pThis, int *pVal) { DEFiRet; assert(pVal != NULL); *pVal = pThis->iDeqBatchSize; RETiRet; } /* start up the queue - it must have been constructed and parameters defined * before. */ rsRetVal qqueueStart(rsconf_t *cnf, qqueue_t *pThis) /* this is the ConstructionFinalizer */ { DEFiRet; uchar pszBuf[64]; uchar pszQIFNam[MAXFNAME]; int wrk; uchar *qName; size_t lenBuf; assert(pThis != NULL); /* do not modify the queue if it's already running(happens when dynamic config reload is invoked * and the queue is used in the new config as well) */ if (pThis->isRunning) FINALIZE; dbgoprint((obj_t *)pThis, "starting queue\n"); if (pThis->pszSpoolDir == NULL) { /* note: we need to pick the path so late as we do not have * the workdir during early config load */ if ((pThis->pszSpoolDir = (uchar *)strdup((char *)glbl.GetWorkDir(cnf))) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pThis->lenSpoolDir = ustrlen(pThis->pszSpoolDir); } /* set type-specific handlers and other very type-specific things * (we can not totally hide it...) */ switch (pThis->qType) { case QUEUETYPE_FIXED_ARRAY: pThis->qConstruct = qConstructFixedArray; pThis->qDestruct = qDestructFixedArray; pThis->qAdd = qAddFixedArray; pThis->qDeq = qDeqFixedArray; pThis->qDel = qDelFixedArray; pThis->MultiEnq = qqueueMultiEnqObjNonDirect; break; case QUEUETYPE_LINKEDLIST: pThis->qConstruct = qConstructLinkedList; pThis->qDestruct = qDestructLinkedList; pThis->qAdd = qAddLinkedList; pThis->qDeq = qDeqLinkedList; pThis->qDel = qDelLinkedList; pThis->MultiEnq = qqueueMultiEnqObjNonDirect; break; case QUEUETYPE_DISK: pThis->qConstruct = qConstructDisk; pThis->qDestruct = qDestructDisk; pThis->qAdd = qAddDisk; pThis->qDeq = qDeqDisk; pThis->qDel = NULL; /* delete for disk handled via special code! */ pThis->MultiEnq = qqueueMultiEnqObjNonDirect; /* pre-construct file name for .qi file */ pThis->lenQIFNam = snprintf((char *)pszQIFNam, sizeof(pszQIFNam), "%s/%s.qi", (char *)pThis->pszSpoolDir, (char *)pThis->pszFilePrefix); pThis->pszQIFNam = ustrdup(pszQIFNam); DBGOPRINT((obj_t *)pThis, ".qi file name is '%s', len %d\n", pThis->pszQIFNam, (int)pThis->lenQIFNam); break; case QUEUETYPE_DIRECT: pThis->qConstruct = qConstructDirect; pThis->qDestruct = qDestructDirect; /* these entry points shall not be used in direct mode * To catch program errors, make us abort if that happens! * rgerhards, 2013-11-05 */ pThis->qAdd = qAddDirect; pThis->MultiEnq = qqueueMultiEnqObjDirect; pThis->qDel = NULL; break; default: // We need to satisfy compiler which does not properly handle enum break; } /* finalize some initializations that could not yet be done because it is * influenced by properties which might have been set after queueConstruct () */ if (pThis->pqParent == NULL) { CHKmalloc(pThis->mut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t))); pthread_mutex_init(pThis->mut, NULL); } else { /* child queue, we need to use parent's mutex */ DBGOPRINT((obj_t *)pThis, "I am a child\n"); pThis->mut = pThis->pqParent->mut; } pthread_mutex_init(&pThis->mutThrdMgmt, NULL); pthread_cond_init(&pThis->notFull, NULL); pthread_cond_init(&pThis->belowFullDlyWtrMrk, NULL); pthread_cond_init(&pThis->belowLightDlyWtrMrk, NULL); /* call type-specific constructor */ CHKiRet(pThis->qConstruct(pThis)); /* this also sets bIsDA */ /* re-adjust some params if required */ if (pThis->bIsDA) { /* if we are in DA mode, we must make sure full delayable messages do not * initiate going to disk! */ wrk = pThis->iHighWtrMrk - (pThis->iHighWtrMrk / 100) * 50; /* 50% of high water mark */ if (wrk < pThis->iFullDlyMrk) pThis->iFullDlyMrk = wrk; } DBGOPRINT((obj_t *)pThis, "params: type %d, enq-only %d, disk assisted %d, spoolDir '%s', maxFileSz %lld, " "maxQSize %d, lqsize %d, pqsize %d, child %d, full delay %d, " "light delay %d, deq batch size %d, min deq batch size %d, " "high wtrmrk %d, low wtrmrk %d, " "discardmrk %d, max wrkr %d, min msgs f. wrkr %d " "takeFlowCtlFromMsg %d\n", pThis->qType, pThis->bEnqOnly, pThis->bIsDA, pThis->pszSpoolDir, pThis->iMaxFileSize, pThis->iMaxQueueSize, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis), pThis->pqParent == NULL ? 0 : 1, pThis->iFullDlyMrk, pThis->iLightDlyMrk, pThis->iDeqBatchSize, pThis->iMinDeqBatchSize, pThis->iHighWtrMrk, pThis->iLowWtrMrk, pThis->iDiscardMrk, (int)pThis->iNumWorkerThreads, (int)pThis->iMinMsgsPerWrkr, pThis->takeFlowCtlFromMsg); pThis->bQueueStarted = 1; if (pThis->qType == QUEUETYPE_DIRECT) FINALIZE; /* with direct queues, we are already finished... */ /* create worker thread pools for regular and DA operation. */ lenBuf = snprintf((char *)pszBuf, sizeof(pszBuf), "%.*s:Reg", (int)(sizeof(pszBuf) - 16), obj.GetName((obj_t *)pThis)); /* leave some room inside the name for suffixes */ if (lenBuf >= sizeof(pszBuf)) { LogError(0, RS_RET_INTERNAL_ERROR, "%s:%d debug header too long: %zd - in " "thory this cannot happen - truncating", __FILE__, __LINE__, lenBuf); lenBuf = sizeof(pszBuf) - 1; pszBuf[lenBuf] = '\0'; } CHKiRet(wtpConstruct(&pThis->pWtpReg)); CHKiRet(wtpSetDbgHdr(pThis->pWtpReg, pszBuf, lenBuf)); CHKiRet(wtpSetpfRateLimiter(pThis->pWtpReg, (rsRetVal(*)(void *pUsr))RateLimiter)); CHKiRet(wtpSetpfChkStopWrkr(pThis->pWtpReg, (rsRetVal(*)(void *pUsr, int))ChkStopWrkrReg)); CHKiRet(wtpSetpfGetDeqBatchSize(pThis->pWtpReg, (rsRetVal(*)(void *pUsr, int *))GetDeqBatchSize)); CHKiRet(wtpSetpfDoWork(pThis->pWtpReg, (rsRetVal(*)(void *pUsr, void *pWti))ConsumerReg)); CHKiRet(wtpSetpfObjProcessed(pThis->pWtpReg, (rsRetVal(*)(void *pUsr, wti_t *pWti))batchProcessed)); CHKiRet(wtpSetpmutUsr(pThis->pWtpReg, pThis->mut)); CHKiRet(wtpSetiNumWorkerThreads(pThis->pWtpReg, pThis->iNumWorkerThreads)); CHKiRet(wtpSettoWrkShutdown(pThis->pWtpReg, pThis->toWrkShutdown)); CHKiRet(wtpSetpUsr(pThis->pWtpReg, pThis)); CHKiRet(wtpConstructFinalize(pThis->pWtpReg)); /* Validate queue configuration before starting */ if (pThis->qType == QUEUETYPE_DISK || pThis->bIsDA) { /* Check that maxDiskSpace is not smaller than maxFileSize */ if (pThis->sizeOnDiskMax > 0 && pThis->iMaxFileSize > 0 && pThis->sizeOnDiskMax < pThis->iMaxFileSize) { LogError(0, RS_RET_CONF_PARAM_INVLD, "queue.maxDiskSpace (%lld) must be larger than queue.maxFileSize (%lld) - " "setting queue.maxDiskSpace to %lld", pThis->sizeOnDiskMax, pThis->iMaxFileSize, pThis->iMaxFileSize); pThis->sizeOnDiskMax = pThis->iMaxFileSize; } } /* set up DA system if we have a disk-assisted queue */ if (pThis->bIsDA) InitDA(pThis, LOCK_MUTEX); /* initiate DA mode */ DBGOPRINT((obj_t *)pThis, "queue finished initialization\n"); /* if the queue already contains data, we need to start the correct number of worker threads. This can be * the case when a disk queue has been loaded. If we did not start it here, it would never start. */ qqueueAdviseMaxWorkers(pThis); /* support statistics gathering */ qName = obj.GetName((obj_t *)pThis); CHKiRet(statsobj.Construct(&pThis->statsobj)); CHKiRet(statsobj.SetName(pThis->statsobj, qName)); CHKiRet(statsobj.SetOrigin(pThis->statsobj, (uchar *)"core.queue")); /* we need to save the queue size, as the stats module initializes it to 0! */ /* iQueueSize is a dual-use counter: no init, no mutex! */ CHKiRet( statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("size"), ctrType_Int, CTR_FLAG_NONE, &pThis->iQueueSize)); STATSCOUNTER_INIT(pThis->ctrEnqueued, pThis->mutCtrEnqueued); CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("enqueued"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &pThis->ctrEnqueued)); STATSCOUNTER_INIT(pThis->ctrFull, pThis->mutCtrFull); CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("full"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &pThis->ctrFull)); STATSCOUNTER_INIT(pThis->ctrFDscrd, pThis->mutCtrFDscrd); CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("discarded.full"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &pThis->ctrFDscrd)); STATSCOUNTER_INIT(pThis->ctrNFDscrd, pThis->mutCtrNFDscrd); CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("discarded.nf"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &pThis->ctrNFDscrd)); pThis->ctrMaxqsize = 0; /* no mutex needed, thus no init call */ CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("maxqsize"), ctrType_Int, CTR_FLAG_NONE, &pThis->ctrMaxqsize)); CHKiRet(statsobj.ConstructFinalize(pThis->statsobj)); finalize_it: if (iRet != RS_RET_OK) { /* note: a child uses it's parent mutex, so do not delete it! */ if (pThis->pqParent == NULL && pThis->mut != NULL) free(pThis->mut); } else { pThis->isRunning = 1; } RETiRet; } /* persist the queue to disk (write the .qi file). If we have something to persist, we first * save the information on the queue properties itself and then we call * the queue-type specific drivers. * Variable bIsCheckpoint is set to 1 if the persist is for a checkpoint, * and 0 otherwise. * rgerhards, 2008-01-10 */ static rsRetVal qqueuePersist(qqueue_t *pThis, int bIsCheckpoint) { DEFiRet; char *tmpQIFName = NULL; strm_t *psQIF = NULL; /* Queue Info File */ char errStr[1024]; assert(pThis != NULL); if (pThis->qType != QUEUETYPE_DISK) { if (getPhysicalQueueSize(pThis) > 0) { /* This error code is OK, but we will probably not implement this any time * The reason is that persistence happens via DA queues. But I would like to * leave the code as is, as we so have a hook in case we need one. * -- rgerhards, 2008-01-28 */ ABORT_FINALIZE(RS_RET_NOT_IMPLEMENTED); } else FINALIZE; /* if the queue is empty, we are happy and done... */ } DBGOPRINT((obj_t *)pThis, "persisting queue to disk, %d entries...\n", getPhysicalQueueSize(pThis)); if ((bIsCheckpoint != QUEUE_CHECKPOINT) && (getPhysicalQueueSize(pThis) == 0)) { if (pThis->bNeedDelQIF) { unlink((char *)pThis->pszQIFNam); pThis->bNeedDelQIF = 0; } /* indicate spool file needs to be deleted */ if (pThis->tVars.disk.pReadDel != NULL) /* may be NULL if we had a startup failure! */ CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 1)); FINALIZE; /* nothing left to do, so be happy */ } int lentmpQIFName; #ifdef _AIX lentmpQIFName = strlen(pThis->pszQIFNam) + strlen(".tmp") + 1; tmpQIFName = malloc(sizeof(char) * lentmpQIFName); if (tmpQIFName == NULL) tmpQIFName = (char *)pThis->pszQIFNam; snprintf(tmpQIFName, lentmpQIFName, "%s.tmp", pThis->pszQIFNam); #else lentmpQIFName = asprintf((char **)&tmpQIFName, "%s.tmp", pThis->pszQIFNam); if (tmpQIFName == NULL) tmpQIFName = (char *)pThis->pszQIFNam; #endif CHKiRet(strm.Construct(&psQIF)); CHKiRet(strm.SettOperationsMode(psQIF, STREAMMODE_WRITE_TRUNC)); CHKiRet(strm.SetbSync(psQIF, pThis->bSyncQueueFiles)); CHKiRet(strm.SetsType(psQIF, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetFName(psQIF, (uchar *)tmpQIFName, lentmpQIFName)); CHKiRet(strm.ConstructFinalize(psQIF)); /* first, write the property bag for ourselfs * And, surprisingly enough, we currently need to persist only the size of the * queue. All the rest is re-created with then-current config parameters when the * queue is re-created. Well, we'll also save the current queue type, just so that * we know when somebody has changed the queue type... -- rgerhards, 2008-01-11 */ CHKiRet(obj.BeginSerializePropBag(psQIF, (obj_t *)pThis)); objSerializeSCALAR(psQIF, iQueueSize, INT); objSerializeSCALAR(psQIF, tVars.disk.sizeOnDisk, INT64); CHKiRet(obj.EndSerialize(psQIF)); /* now persist the stream info */ if (pThis->tVars.disk.pWrite != NULL) CHKiRet(strm.Serialize(pThis->tVars.disk.pWrite, psQIF)); if (pThis->tVars.disk.pReadDel != NULL) CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF)); strm.Destruct(&psQIF); if (tmpQIFName != (char *)pThis->pszQIFNam) { /* pointer, not string comparison! */ if (rename(tmpQIFName, (char *)pThis->pszQIFNam) != 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); DBGOPRINT((obj_t *)pThis, "FATAL error: renaming temporary .qi file failed: %s\n", errStr); ABORT_FINALIZE(RS_RET_RENAME_TMP_QI_ERROR); } } /* tell the input file object that it must not delete the file on close if the queue * is non-empty - but only if we are not during a simple checkpoint */ if (bIsCheckpoint != QUEUE_CHECKPOINT && pThis->tVars.disk.pReadDel != NULL) { CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 0)); } /* we have persisted the queue object. So whenever it comes to an empty queue, * we need to delete the QIF. Thus, we indicte that need. */ pThis->bNeedDelQIF = 1; finalize_it: if (tmpQIFName != (char *)pThis->pszQIFNam) /* pointer, not string comparison! */ free(tmpQIFName); if (psQIF != NULL) strm.Destruct(&psQIF); RETiRet; } /* check if we need to persist the current queue info. If an * error occurs, this should be ignored by caller (but we still * abide to our regular call interface)... * rgerhards, 2008-01-13 * nUpdates is the number of updates since the last call to this function. * It may be > 1 due to batches. -- rgerhards, 2009-05-12 */ static rsRetVal qqueueChkPersist(qqueue_t *const pThis, const int nUpdates) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(nUpdates >= 0); if (nUpdates == 0) FINALIZE; pThis->iUpdsSincePersist += nUpdates; if (pThis->iPersistUpdCnt && pThis->iUpdsSincePersist >= pThis->iPersistUpdCnt) { qqueuePersist(pThis, QUEUE_CHECKPOINT); pThis->iUpdsSincePersist = 0; } finalize_it: RETiRet; } /* persist a queue with all data elements to disk - this is used to handle * bSaveOnShutdown. We utilize the DA worker to do this. This must only * be called after all workers have been shut down and if bSaveOnShutdown * is actually set. Note that this function may potentially run long, * depending on the queue configuration (e.g. store on remote machine). * rgerhards, 2009-05-26 */ static rsRetVal DoSaveOnShutdown(qqueue_t *pThis) { struct timespec tTimeout; rsRetVal iRetLocal; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); /* we reduce the low water mark, otherwise the DA worker would terminate when * it is reached. */ DBGOPRINT((obj_t *)pThis, "bSaveOnShutdown set, restarting DA worker...\n"); pThis->bShutdownImmediate = 0; /* would termiante the DA worker! */ pThis->iLowWtrMrk = 0; wtpSetState(pThis->pWtpDA, wtpState_SHUTDOWN); /* shutdown worker (only) when done (was _IMMEDIATE!) */ wtpAdviseMaxWorkers(pThis->pWtpDA, 1, PERMIT_WORKER_START_DURING_SHUTDOWN); /* restart DA worker */ DBGOPRINT((obj_t *)pThis, "waiting for DA worker to terminate...\n"); timeoutComp(&tTimeout, QUEUE_TIMEOUT_ETERNAL); /* and run the primary queue's DA worker to drain the queue */ iRetLocal = wtpShutdownAll(pThis->pWtpDA, wtpState_SHUTDOWN, &tTimeout); DBGOPRINT((obj_t *)pThis, "end queue persistence run, iRet %d, queue size log %d, phys %d\n", iRetLocal, getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis)); if (iRetLocal != RS_RET_OK) { DBGOPRINT((obj_t *)pThis, "unexpected iRet state %d after trying to shut down primary " "queue in disk save mode, continuing, but results are unpredictable\n", iRetLocal); } RETiRet; } /* destructor for the queue object */ BEGINobjDestruct(qqueue) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(qqueue); DBGOPRINT((obj_t *)pThis, "shutdown: begin to destruct queue\n"); if (ourConf->globals.shutdownQueueDoubleSize) { pThis->iHighWtrMrk *= 2; pThis->iMaxQueueSize *= 2; } if (pThis->bQueueStarted) { /* shut down all workers * We do not need to shutdown workers when we are in enqueue-only mode or we are a * direct queue - because in both cases we have none... ;) * with a child! -- rgerhards, 2008-01-28 */ if (pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL && pThis->pWtpReg != NULL) qqueueShutdownWorkers(pThis); if (pThis->bIsDA && getPhysicalQueueSize(pThis) > 0) { if (pThis->bSaveOnShutdown) { LogMsg(0, RS_RET_TIMED_OUT, LOG_INFO, "%s: queue holds %d messages after shutdown of workers. " "queue.saveonshutdown is set, so data will now be spooled to disk", objGetName((obj_t *)pThis), getPhysicalQueueSize(pThis)); CHKiRet(DoSaveOnShutdown(pThis)); } else { LogMsg(0, RS_RET_TIMED_OUT, LOG_WARNING, "%s: queue holds %d messages after shutdown of workers. " "queue.saveonshutdown is NOT set, so data will be discarded.", objGetName((obj_t *)pThis), getPhysicalQueueSize(pThis)); } } /* finally destruct our (regular) worker thread pool * Note: currently pWtpReg is never NULL, but if we optimize our logic, this may happen, * e.g. when they are not created in enqueue-only mode. We already check the condition * as this may otherwise be very hard to find once we optimize (and have long forgotten * about this condition here ;) * rgerhards, 2008-01-25 */ if (pThis->qType != QUEUETYPE_DIRECT && pThis->pWtpReg != NULL) { wtpDestruct(&pThis->pWtpReg); } /* Now check if we actually have a DA queue and, if so, destruct it. * Note that the wtp must be destructed first, it may be in cancel cleanup handler * *right now* and actually *need* to access the queue object to persist some final * data (re-queueing case). So we need to destruct the wtp first, which will make * sure all workers have terminated. Please note that this also generates a situation * where it is possible that the DA queue has a parent pointer but the parent has * no WtpDA associated with it - which is perfectly legal thanks to this code here. */ if (pThis->pWtpDA != NULL) { wtpDestruct(&pThis->pWtpDA); } if (pThis->pqDA != NULL) { qqueueDestruct(&pThis->pqDA); } /* persist the queue (we always do that - queuePersits() does cleanup if the queue is empty) * This handler is most important for disk queues, it will finally persist the necessary * on-disk structures. In theory, other queueing modes may implement their other (non-DA) * methods of persisting a queue between runs, but in practice all of this is done via * disk queues and DA mode. Anyhow, it doesn't hurt to know that we could extend it here * if need arises (what I doubt...) -- rgerhards, 2008-01-25 */ CHKiRet_Hdlr(qqueuePersist(pThis, QUEUE_NO_CHECKPOINT)) { DBGOPRINT((obj_t *)pThis, "error %d persisting queue - data lost!\n", iRet); } /* finally, clean up some simple things... */ if (pThis->pqParent == NULL) { /* if we are not a child, we allocated our own mutex, which we now need to destroy */ pthread_mutex_destroy(pThis->mut); free(pThis->mut); } pthread_mutex_destroy(&pThis->mutThrdMgmt); pthread_cond_destroy(&pThis->notFull); pthread_cond_destroy(&pThis->belowFullDlyWtrMrk); pthread_cond_destroy(&pThis->belowLightDlyWtrMrk); DESTROY_ATOMIC_HELPER_MUT(pThis->mutQueueSize); DESTROY_ATOMIC_HELPER_MUT(pThis->mutLogDeq); /* type-specific destructor */ iRet = pThis->qDestruct(pThis); } free(pThis->pszFilePrefix); free(pThis->pszSpoolDir); if (pThis->useCryprov) { pThis->cryprov.Destruct(&pThis->cryprovData); obj.ReleaseObj(__FILE__, pThis->cryprovNameFull + 2, pThis->cryprovNameFull, (void *)&pThis->cryprov); free(pThis->cryprovName); free(pThis->cryprovNameFull); } /* some queues do not provide stats and thus have no statsobj! */ if (pThis->statsobj != NULL) statsobj.Destruct(&pThis->statsobj); ENDobjDestruct(qqueue) /* set the queue's spool directory. The directory MUST NOT be NULL. * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. */ rsRetVal qqueueSetSpoolDir(qqueue_t *pThis, uchar *pszSpoolDir, int lenSpoolDir) { DEFiRet; free(pThis->pszSpoolDir); CHKmalloc(pThis->pszSpoolDir = ustrdup(pszSpoolDir)); pThis->lenSpoolDir = lenSpoolDir; finalize_it: RETiRet; } /* set the queue's file prefix * The passed-in string is duplicated. So if the caller does not need * it any longer, it must free it. * rgerhards, 2008-01-09 */ rsRetVal qqueueSetFilePrefix(qqueue_t *pThis, uchar *pszPrefix, size_t iLenPrefix) { DEFiRet; free(pThis->pszFilePrefix); pThis->pszFilePrefix = NULL; if (pszPrefix == NULL) /* just unset the prefix! */ ABORT_FINALIZE(RS_RET_OK); if ((pThis->pszFilePrefix = malloc(iLenPrefix + 1)) == NULL) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); memcpy(pThis->pszFilePrefix, pszPrefix, iLenPrefix + 1); pThis->lenFilePrefix = iLenPrefix; finalize_it: RETiRet; } /* set the queue's maximum file size * rgerhards, 2008-01-09 */ rsRetVal qqueueSetMaxFileSize(qqueue_t *pThis, size_t iMaxFileSize) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); if (iMaxFileSize < 1024) { ABORT_FINALIZE(RS_RET_VALUE_TOO_LOW); } pThis->iMaxFileSize = iMaxFileSize; finalize_it: RETiRet; } /* enqueue a single data object. * Note that the queue mutex MUST already be locked when this function is called. * rgerhards, 2009-06-16 */ static rsRetVal doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, smsg_t *pMsg) { DEFiRet; int err; struct timespec t; STATSCOUNTER_INC(pThis->ctrEnqueued, pThis->mutCtrEnqueued); /* first check if we need to discard this message (which will cause CHKiRet() to exit) */ CHKiRet(qqueueChkDiscardMsg(pThis, pThis->iQueueSize, pMsg)); /* handle flow control * There are two different flow control mechanisms: basic and advanced flow control. * Basic flow control has always been implemented and protects the queue structures * in that it makes sure no more data is enqueued than the queue is configured to * support. Enhanced flow control is being added today. There are some sources which * can easily be stopped, e.g. a file reader. This is the case because it is unlikely * that blocking those sources will have negative effects (after all, the file is * continued to be written). Other sources can somewhat be blocked (e.g. the kernel * log reader or the local log stream reader): in general, nothing is lost if messages * from these sources are not picked up immediately. HOWEVER, they can not block for * an extended period of time, as this either causes message loss or - even worse - some * other bad effects (e.g. unresponsive system in respect to the main system log socket). * Finally, there are some (few) sources which can not be blocked at all. UDP syslog is * a prime example. If a UDP message is not received, it is simply lost. So we can't * do anything against UDP sockets that come in too fast. The core idea of advanced * flow control is that we take into account the different natures of the sources and * select flow control mechanisms that fit these needs. This also means, in the end * result, that non-blockable sources like UDP syslog receive priority in the system. * It's a side effect, but a good one ;) -- rgerhards, 2008-03-14 */ if (unlikely(pThis->takeFlowCtlFromMsg)) { /* recommendation is NOT to use this option */ flowCtlType = pMsg->flowCtlType; } if (flowCtlType == eFLOWCTL_FULL_DELAY) { while (pThis->iQueueSize >= pThis->iFullDlyMrk && !glbl.GetGlobalInputTermState()) { /* We have a problem during shutdown if we block eternally. In that * case, the the input thread cannot be terminated. So we wake up * from time to time to check for termination. * TODO/v6(at earliest): check if we could signal the condition during * shutdown. However, this requires new queue registries and thus is * far to much change for a stable version (and I am still not sure it * is worth the effort, given how seldom this situation occurs and how * few resources the wakeups need). -- rgerhards, 2012-05-03 * In any case, this was the old code (if we do the TODO): * pthread_cond_wait(&pThis->belowFullDlyWtrMrk, pThis->mut); */ DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: FullDelay mark reached for full " "delayable message - blocking, queue size is %d.\n", pThis->iQueueSize); timeoutComp(&t, 1000); err = pthread_cond_timedwait(&pThis->belowLightDlyWtrMrk, pThis->mut, &t); if (err != 0 && err != ETIMEDOUT) { /* Something is really wrong now. Report to debug log and abort the * wait. That keeps us running, even though we may lose messages. */ DBGOPRINT((obj_t *)pThis, "potential program bug: pthread_cond_timedwait()" "/fulldelay returned %d\n", err); break; } DBGPRINTF("wti worker in full delay timed out, checking termination...\n"); } } else if (flowCtlType == eFLOWCTL_LIGHT_DELAY && !glbl.GetGlobalInputTermState()) { if (pThis->iQueueSize >= pThis->iLightDlyMrk) { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: LightDelay mark reached for light " "delayable message - blocking a bit.\n"); timeoutComp(&t, 1000); /* 1000 millisconds = 1 second TODO: make configurable */ err = pthread_cond_timedwait(&pThis->belowLightDlyWtrMrk, pThis->mut, &t); if (err != 0 && err != ETIMEDOUT) { /* Something is really wrong now. Report to debug log */ DBGOPRINT((obj_t *)pThis, "potential program bug: pthread_cond_timedwait()" "/lightdelay returned %d\n", err); } } } /* from our regular flow control settings, we are now ready to enqueue the object. * However, we now need to do a check if the queue permits to add more data. If that * is not the case, basic flow control enters the field, which means we wait for * the queue to become ready or drop the new message. -- rgerhards, 2008-03-14 */ while ((pThis->iMaxQueueSize > 0 && pThis->iQueueSize >= pThis->iMaxQueueSize) || ((pThis->qType == QUEUETYPE_DISK || pThis->bIsDA) && pThis->sizeOnDiskMax != 0 && pThis->tVars.disk.sizeOnDisk > pThis->sizeOnDiskMax)) { STATSCOUNTER_INC(pThis->ctrFull, pThis->mutCtrFull); if (pThis->toEnq == 0 || pThis->bEnqOnly) { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: queue FULL - configured for immediate " "discarding QueueSize=%d MaxQueueSize=%d sizeOnDisk=%lld " "sizeOnDiskMax=%lld\n", pThis->iQueueSize, pThis->iMaxQueueSize, pThis->tVars.disk.sizeOnDisk, pThis->sizeOnDiskMax); STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd); msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } else { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: queue FULL - waiting %dms to drain.\n", pThis->toEnq); if (glbl.GetGlobalInputTermState()) { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: queue FULL, discard due to " "FORCE_TERM.\n"); ABORT_FINALIZE(RS_RET_FORCE_TERM); } timeoutComp(&t, pThis->toEnq); const int r = pthread_cond_timedwait(&pThis->notFull, pThis->mut, &t); if (dbgTimeoutToStderr && r != 0) { fprintf(stderr, "%lld: queue timeout(%dms), error %d%s, " "lost message %s\n", (long long)time(NULL), pThis->toEnq, r, (r == ETIMEDOUT) ? "[ETIMEDOUT]" : "", pMsg->pszRawMsg); } if (r == ETIMEDOUT) { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: cond timeout, dropping message!\n"); STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd); msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } else if (r != 0) { DBGOPRINT((obj_t *)pThis, "doEnqSingleObject: cond error %d, dropping message!\n", r); STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd); msgDestruct(&pMsg); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } dbgoprint((obj_t *)pThis, "doEnqSingleObject: wait solved queue full condition, enqueing\n"); } } /* and finally enqueue the message */ CHKiRet(qqueueAdd(pThis, pMsg)); STATSCOUNTER_SETMAX_NOMUT(pThis->ctrMaxqsize, pThis->iQueueSize); /* check if we had a file rollover and need to persist * the .qi file for robustness reasons. * Note: the n=2 write is required for closing the old file and * the n=1 write is required after opening and writing to the new * file. */ if (pThis->tVars.disk.nForcePersist > 0) { DBGOPRINT((obj_t *)pThis, ".qi file write required for robustness reasons (n=%d)\n", pThis->tVars.disk.nForcePersist); pThis->tVars.disk.nForcePersist--; qqueuePersist(pThis, QUEUE_CHECKPOINT); } finalize_it: RETiRet; } /* ------------------------------ multi-enqueue functions ------------------------------ */ /* enqueue multiple user data elements at once. The aim is to provide a faster interface * for object submission. Uses the multi_submit_t helper object. * Please note that this function is not cancel-safe and consequently * sets the calling thread's cancelibility state to PTHREAD_CANCEL_DISABLE * during its execution. If that is not done, race conditions occur if the * thread is canceled (most important use case is input module termination). * rgerhards, 2009-06-16 * Note: there now exists multiple different functions implementing specially * optimized algorithms for different config cases. -- rgerhards, 2010-06-09 */ /* now the function for all modes but direct */ static rsRetVal qqueueMultiEnqObjNonDirect(qqueue_t *pThis, multi_submit_t *pMultiSub) { int iCancelStateSave; int i; rsRetVal localRet; DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pMultiSub != NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); d_pthread_mutex_lock(pThis->mut); for (i = 0; i < pMultiSub->nElem; ++i) { localRet = doEnqSingleObj(pThis, pMultiSub->ppMsgs[i]->flowCtlType, (void *)pMultiSub->ppMsgs[i]); if (localRet != RS_RET_OK && localRet != RS_RET_QUEUE_FULL) ABORT_FINALIZE(localRet); } qqueueChkPersist(pThis, pMultiSub->nElem); finalize_it: /* make sure at least one worker is running. */ qqueueAdviseMaxWorkers(pThis); /* and release the mutex */ d_pthread_mutex_unlock(pThis->mut); pthread_setcancelstate(iCancelStateSave, NULL); DBGOPRINT((obj_t *)pThis, "MultiEnqObj advised worker start\n"); RETiRet; } /* now, the same function, but for direct mode */ static rsRetVal qqueueMultiEnqObjDirect(qqueue_t *pThis, multi_submit_t *pMultiSub) { int i; wti_t *pWti; DEFiRet; pWti = wtiGetDummy(); pWti->pbShutdownImmediate = &pThis->bShutdownImmediate; for (i = 0; i < pMultiSub->nElem; ++i) { CHKiRet(qAddDirectWithWti(pThis, (void *)pMultiSub->ppMsgs[i], pWti)); } finalize_it: RETiRet; } /* ------------------------------ END multi-enqueue functions ------------------------------ */ /* enqueue a new user data element * Enqueues the new element and awakes worker thread. */ rsRetVal qqueueEnqMsg(qqueue_t *pThis, flowControl_t flowCtlType, smsg_t *pMsg) { DEFiRet; int iCancelStateSave; ISOBJ_TYPE_assert(pThis, qqueue); const int isNonDirectQ = pThis->qType != QUEUETYPE_DIRECT; if (isNonDirectQ) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave); d_pthread_mutex_lock(pThis->mut); } CHKiRet(doEnqSingleObj(pThis, flowCtlType, pMsg)); qqueueChkPersist(pThis, 1); finalize_it: if (isNonDirectQ) { /* make sure at least one worker is running. */ qqueueAdviseMaxWorkers(pThis); /* and release the mutex */ d_pthread_mutex_unlock(pThis->mut); pthread_setcancelstate(iCancelStateSave, NULL); DBGOPRINT((obj_t *)pThis, "EnqueueMsg advised worker start\n"); } RETiRet; } /* are any queue params set at all? 1 - yes, 0 - no * We need to evaluate the param block for this function, which is somewhat * inefficient. HOWEVER, this is only done during config load, so we really * don't care... -- rgerhards, 2013-05-10 */ int queueCnfParamsSet(struct nvlst *lst) { int r; struct cnfparamvals *pvals; pvals = nvlstGetParams(lst, &pblk, NULL); r = cnfparamvalsIsSet(&pblk, pvals); cnfparamvalsDestruct(pvals, &pblk); return r; } static rsRetVal initCryprov(qqueue_t *pThis, struct nvlst *lst) { uchar szDrvrName[1024]; DEFiRet; if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pThis->cryprovName) == sizeof(szDrvrName)) { LogError(0, RS_RET_ERR, "queue: crypto provider " "name is too long: '%s' - encryption disabled", pThis->cryprovName); ABORT_FINALIZE(RS_RET_ERR); } pThis->cryprovNameFull = ustrdup(szDrvrName); pThis->cryprov.ifVersion = cryprovCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean enough. */ if (obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void *)&pThis->cryprov) != RS_RET_OK) { LogError(0, RS_RET_LOAD_ERROR, "queue: could not load " "crypto provider '%s' - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } if (pThis->cryprov.Construct(&pThis->cryprovData) != RS_RET_OK) { LogError(0, RS_RET_CRYPROV_ERR, "queue: error constructing " "crypto provider %s dataset - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } CHKiRet(pThis->cryprov.SetCnfParam(pThis->cryprovData, lst, CRYPROV_PARAMTYPE_DISK)); dbgprintf("loaded crypto provider %s, data instance at %p\n", szDrvrName, pThis->cryprovData); pThis->useCryprov = 1; finalize_it: RETiRet; } /* check the the queue file name is unique. */ static rsRetVal ATTR_NONNULL() checkUniqueDiskFile(qqueue_t *const pThis) { DEFiRet; struct queue_filename *queue_fn_curr = queue_filename_root; struct queue_filename *newetry = NULL; const char *const curr_dirname = (pThis->pszSpoolDir == NULL) ? "" : (char *)pThis->pszSpoolDir; if (pThis->pszFilePrefix == NULL) { FINALIZE; /* no disk queue! */ } while (queue_fn_curr != NULL) { if (!strcmp((const char *)pThis->pszFilePrefix, queue_fn_curr->filename) && !strcmp(curr_dirname, queue_fn_curr->dirname)) { parser_errmsg( "queue directory '%s' and file name prefix '%s' already used. " "This is not possible. Please make it unique.", curr_dirname, pThis->pszFilePrefix); ABORT_FINALIZE(RS_RET_ERR_QUEUE_FN_DUP); } queue_fn_curr = queue_fn_curr->next; } /* name ok, so let's add it to the list */ CHKmalloc(newetry = calloc(1, sizeof(struct queue_filename))); CHKmalloc(newetry->filename = strdup((char *)pThis->pszFilePrefix)); CHKmalloc(newetry->dirname = strdup(curr_dirname)); newetry->next = queue_filename_root; queue_filename_root = newetry; finalize_it: if (iRet != RS_RET_OK) { if (newetry != NULL) { free((void *)newetry->filename); free((void *)newetry); } } RETiRet; } void qqueueCorrectParams(qqueue_t *pThis) { int goodval; /* a "good value" to use for comparisons (different objects) */ if (pThis->iMaxQueueSize < 100 && (pThis->qType == QUEUETYPE_LINKEDLIST || pThis->qType == QUEUETYPE_FIXED_ARRAY)) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "Note: queue.size=\"%d\" is very " "low and can lead to unpredictable results. See also " "https://www.rsyslog.com/lower-bound-for-queue-sizes/", pThis->iMaxQueueSize); } /* we need to do a quick check if our water marks are set plausible. If not, * we correct the most important shortcomings. */ goodval = (pThis->iMaxQueueSize / 100) * 60; if (pThis->iHighWtrMrk != -1 && pThis->iHighWtrMrk < goodval) { LogMsg(0, RS_RET_CONF_PARSE_WARNING, LOG_WARNING, "queue \"%s\": high water mark " "is set quite low at %d. You should only set it below " "60%% (%d) if you have a good reason for this.", obj.GetName((obj_t *)pThis), pThis->iHighWtrMrk, goodval); } if (pThis->iNumWorkerThreads > 1) { goodval = (pThis->iMaxQueueSize / 100) * 10; if (pThis->iMinMsgsPerWrkr != -1 && pThis->iMinMsgsPerWrkr < goodval) { LogMsg(0, RS_RET_CONF_PARSE_WARNING, LOG_WARNING, "queue \"%s\": " "queue.workerThreadMinimumMessage " "is set quite low at %d. You should only set it below " "10%% (%d) if you have a good reason for this.", obj.GetName((obj_t *)pThis), pThis->iMinMsgsPerWrkr, goodval); } } if (pThis->iDiscardMrk > pThis->iMaxQueueSize) { LogError(0, RS_RET_PARAM_ERROR, "error: queue \"%s\": " "queue.discardMark %d is set larger than queue.size", obj.GetName((obj_t *)pThis), pThis->iDiscardMrk); } goodval = (pThis->iMaxQueueSize / 100) * 80; if (pThis->iDiscardMrk != -1 && pThis->iDiscardMrk < goodval) { LogMsg(0, RS_RET_CONF_PARSE_WARNING, LOG_WARNING, "queue \"%s\": queue.discardMark " "is set quite low at %d. You should only set it below " "80%% (%d) if you have a good reason for this.", obj.GetName((obj_t *)pThis), pThis->iDiscardMrk, goodval); } if (pThis->pszFilePrefix != NULL) { /* This means we have a potential DA queue */ if (pThis->iFullDlyMrk != -1 && pThis->iFullDlyMrk < pThis->iHighWtrMrk) { LogMsg(0, RS_RET_CONF_WRN_FULLDLY_BELOW_HIGHWTR, LOG_WARNING, "queue \"%s\": queue.fullDelayMark " "is set below high water mark. This will result in DA mode " " NOT being activated for full delayable messages: In many " "cases this is a configuration error, please check if this " "is really what you want", obj.GetName((obj_t *)pThis)); } } /* now come parameter corrections and defaults */ if (pThis->iHighWtrMrk < 2 || pThis->iHighWtrMrk > pThis->iMaxQueueSize) { pThis->iHighWtrMrk = (pThis->iMaxQueueSize / 100) * 90; if (pThis->iHighWtrMrk == 0) { /* guard against very low max queue sizes! */ pThis->iHighWtrMrk = pThis->iMaxQueueSize; } } if (pThis->iLowWtrMrk < 2 || pThis->iLowWtrMrk > pThis->iMaxQueueSize || pThis->iLowWtrMrk > pThis->iHighWtrMrk) { pThis->iLowWtrMrk = (pThis->iMaxQueueSize / 100) * 70; if (pThis->iLowWtrMrk == 0) { pThis->iLowWtrMrk = 1; } } if ((pThis->iMinMsgsPerWrkr < 1 || pThis->iMinMsgsPerWrkr > pThis->iMaxQueueSize)) { pThis->iMinMsgsPerWrkr = pThis->iMaxQueueSize / pThis->iNumWorkerThreads; } if (pThis->iFullDlyMrk == -1 || pThis->iFullDlyMrk > pThis->iMaxQueueSize) { pThis->iFullDlyMrk = (pThis->iMaxQueueSize / 100) * 97; if (pThis->iFullDlyMrk == 0) { pThis->iFullDlyMrk = (pThis->iMaxQueueSize == 1) ? 1 : pThis->iMaxQueueSize - 1; } } if (pThis->iLightDlyMrk == 0) { pThis->iLightDlyMrk = pThis->iMaxQueueSize; } if (pThis->iLightDlyMrk == -1 || pThis->iLightDlyMrk > pThis->iMaxQueueSize) { pThis->iLightDlyMrk = (pThis->iMaxQueueSize / 100) * 70; if (pThis->iLightDlyMrk == 0) { pThis->iLightDlyMrk = (pThis->iMaxQueueSize == 1) ? 1 : pThis->iMaxQueueSize - 1; } } if (pThis->iDiscardMrk < 1 || pThis->iDiscardMrk > pThis->iMaxQueueSize) { pThis->iDiscardMrk = (pThis->iMaxQueueSize / 100) * 98; if (pThis->iDiscardMrk == 0) { /* for very small queues, we disable this by default */ pThis->iDiscardMrk = pThis->iMaxQueueSize; } } if (pThis->iMaxQueueSize > 0 && pThis->iDeqBatchSize > pThis->iMaxQueueSize) { pThis->iDeqBatchSize = pThis->iMaxQueueSize; } } /* apply all params from param block to queue. Must be called before * finalizing. This supports the v6 config system. Defaults were already * set during queue creation. The pvals object is destructed by this * function. */ rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct nvlst *lst) { int i; struct cnfparamvals *pvals; int n_params_set = 0; DEFiRet; pvals = nvlstGetParams(lst, &pblk, NULL); if (pvals == NULL) { parser_errmsg("error processing queue config parameters"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("queue param blk:\n"); cnfparamsPrint(&pblk, pvals); } for (i = 0; i < pblk.nParams; ++i) { if (!pvals[i].bUsed) continue; n_params_set++; if (!strcmp(pblk.descr[i].name, "queue.filename")) { pThis->pszFilePrefix = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); pThis->lenFilePrefix = es_strlen(pvals[i].val.d.estr); } else if (!strcmp(pblk.descr[i].name, "queue.cry.provider")) { pThis->cryprovName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(pblk.descr[i].name, "queue.spooldirectory")) { free(pThis->pszSpoolDir); pThis->pszSpoolDir = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); pThis->lenSpoolDir = es_strlen(pvals[i].val.d.estr); if (pThis->pszSpoolDir[pThis->lenSpoolDir - 1] == '/') { pThis->pszSpoolDir[pThis->lenSpoolDir - 1] = '\0'; --pThis->lenSpoolDir; parser_errmsg( "queue.spooldirectory must not end with '/', " "corrected to '%s'", pThis->pszSpoolDir); } } else if (!strcmp(pblk.descr[i].name, "queue.size")) { if (pvals[i].val.d.n > 0x7fffffff) { parser_warnmsg( "queue.size higher than maximum (2147483647) - " "corrected to maximum"); pvals[i].val.d.n = 0x7fffffff; } else if (pvals[i].val.d.n > OVERSIZE_QUEUE_WATERMARK) { parser_warnmsg( "queue.size=%d is very large - is this " "really intended? More info at " "https://www.rsyslog.com/avoid-overly-large-in-memory-queues/", (int)pvals[i].val.d.n); } pThis->iMaxQueueSize = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.dequeuebatchsize")) { pThis->iDeqBatchSize = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.mindequeuebatchsize")) { pThis->iMinDeqBatchSize = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.mindequeuebatchsize.timeout")) { pThis->toMinDeqBatchSize = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.maxdiskspace")) { pThis->sizeOnDiskMax = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.highwatermark")) { pThis->iHighWtrMrk = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.lowwatermark")) { pThis->iLowWtrMrk = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.fulldelaymark")) { pThis->iFullDlyMrk = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.lightdelaymark")) { pThis->iLightDlyMrk = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.discardmark")) { pThis->iDiscardMrk = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.discardseverity")) { pThis->iDiscardSeverity = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.checkpointinterval")) { pThis->iPersistUpdCnt = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.syncqueuefiles")) { pThis->bSyncQueueFiles = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.type")) { pThis->qType = (queueType_t)pvals[i].val.d.n; if (pThis->qType == QUEUETYPE_DIRECT) { /* if we have a direct queue, we mimic this param was not set. * Our prime intent is to make sure we detect when "real" params * are set on a direct queue, and the type setting is obviously * not relevant here. */ n_params_set--; } } else if (!strcmp(pblk.descr[i].name, "queue.workerthreads")) { pThis->iNumWorkerThreads = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.timeoutshutdown")) { pThis->toQShutdown = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.timeoutactioncompletion")) { pThis->toActShutdown = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.timeoutenqueue")) { pThis->toEnq = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.timeoutworkerthreadshutdown")) { pThis->toWrkShutdown = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.workerthreadminimummessages")) { pThis->iMinMsgsPerWrkr = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.maxfilesize")) { pThis->iMaxFileSize = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.saveonshutdown")) { pThis->bSaveOnShutdown = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.dequeueslowdown")) { pThis->iDeqSlowdown = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.dequeuetimebegin")) { pThis->iDeqtWinFromHr = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.dequeuetimeend")) { pThis->iDeqtWinToHr = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.samplinginterval")) { pThis->iSmpInterval = pvals[i].val.d.n; } else if (!strcmp(pblk.descr[i].name, "queue.takeflowctlfrommsg")) { pThis->takeFlowCtlFromMsg = pvals[i].val.d.n; } else { DBGPRINTF( "queue: program error, non-handled " "param '%s'\n", pblk.descr[i].name); } } checkUniqueDiskFile(pThis); if (pThis->qType == QUEUETYPE_DIRECT) { if (n_params_set > 0) { LogMsg(0, RS_RET_OK, LOG_WARNING, "warning on queue '%s': " "queue is in direct mode, but parameters have been set. " "These PARAMETERS cannot be applied and WILL BE IGNORED.", obj.GetName((obj_t *)pThis)); } } else if (pThis->qType == QUEUETYPE_DISK) { if (pThis->pszFilePrefix == NULL) { LogError(0, RS_RET_QUEUE_DISK_NO_FN, "error on queue '%s', disk mode selected, but " "no queue file name given; queue type changed to 'linkedList'", obj.GetName((obj_t *)pThis)); pThis->qType = QUEUETYPE_LINKEDLIST; } } if (pThis->pszFilePrefix == NULL && pThis->cryprovName != NULL) { LogError(0, RS_RET_QUEUE_CRY_DISK_ONLY, "error on queue '%s', crypto provider can " "only be set for disk or disk assisted queue - ignored", obj.GetName((obj_t *)pThis)); free(pThis->cryprovName); pThis->cryprovName = NULL; } if (pThis->cryprovName != NULL) { initCryprov(pThis, lst); } cnfparamvalsDestruct(pvals, &pblk); finalize_it: RETiRet; } /* return 1 if the content of two qqueue_t structs equal */ int queuesEqual(qqueue_t *pOld, qqueue_t *pNew) { return (NUM_EQUALS(qType) && NUM_EQUALS(iMaxQueueSize) && NUM_EQUALS(iDeqBatchSize) && NUM_EQUALS(iMinDeqBatchSize) && NUM_EQUALS(toMinDeqBatchSize) && NUM_EQUALS(sizeOnDiskMax) && NUM_EQUALS(iHighWtrMrk) && NUM_EQUALS(iLowWtrMrk) && NUM_EQUALS(iFullDlyMrk) && NUM_EQUALS(iLightDlyMrk) && NUM_EQUALS(iDiscardMrk) && NUM_EQUALS(iDiscardSeverity) && NUM_EQUALS(iPersistUpdCnt) && NUM_EQUALS(bSyncQueueFiles) && NUM_EQUALS(iNumWorkerThreads) && NUM_EQUALS(toQShutdown) && NUM_EQUALS(toActShutdown) && NUM_EQUALS(toEnq) && NUM_EQUALS(toWrkShutdown) && NUM_EQUALS(iMinMsgsPerWrkr) && NUM_EQUALS(iMaxFileSize) && NUM_EQUALS(bSaveOnShutdown) && NUM_EQUALS(iDeqSlowdown) && NUM_EQUALS(iDeqtWinFromHr) && NUM_EQUALS(iDeqtWinToHr) && NUM_EQUALS(iSmpInterval) && NUM_EQUALS(takeFlowCtlFromMsg) && USTR_EQUALS(pszFilePrefix) && USTR_EQUALS(cryprovName)); } /* some simple object access methods * Note: the semicolons behind the macros are actually empty declarations. This is * a work-around for clang-format's missing understanding of generative macros. * Some compilers may flag this empty declarations by a warning. If so, we need * to disable this warning. Alternatively, we could exclude this code from being * reformatted by clang-format; */ DEFpropSetMeth(qqueue, bSyncQueueFiles, int); DEFpropSetMeth(qqueue, iPersistUpdCnt, int); DEFpropSetMeth(qqueue, iDeqtWinFromHr, int); DEFpropSetMeth(qqueue, iDeqtWinToHr, int); DEFpropSetMeth(qqueue, toQShutdown, long); DEFpropSetMeth(qqueue, toActShutdown, long); DEFpropSetMeth(qqueue, toWrkShutdown, long); DEFpropSetMeth(qqueue, toEnq, long); DEFpropSetMeth(qqueue, iHighWtrMrk, int); DEFpropSetMeth(qqueue, iLowWtrMrk, int); DEFpropSetMeth(qqueue, iDiscardMrk, int); DEFpropSetMeth(qqueue, iDiscardSeverity, int); DEFpropSetMeth(qqueue, iLightDlyMrk, int); DEFpropSetMeth(qqueue, iNumWorkerThreads, int); DEFpropSetMeth(qqueue, iMinMsgsPerWrkr, int); DEFpropSetMeth(qqueue, bSaveOnShutdown, int); DEFpropSetMeth(qqueue, pAction, action_t *); DEFpropSetMeth(qqueue, iDeqSlowdown, int); DEFpropSetMeth(qqueue, iDeqBatchSize, int); DEFpropSetMeth(qqueue, iMinDeqBatchSize, int); DEFpropSetMeth(qqueue, sizeOnDiskMax, int64); DEFpropSetMeth(qqueue, iSmpInterval, int); /* This function can be used as a generic way to set properties. Only the subset * of properties required to read persisted property bags is supported. This * functions shall only be called by the property bag reader, thus it is static. * rgerhards, 2008-01-11 */ #define isProp(name) !rsCStrSzStrCmp(pProp->pcsName, (uchar *)name, sizeof(name) - 1) static rsRetVal qqueueSetProperty(qqueue_t *pThis, var_t *pProp) { DEFiRet; ISOBJ_TYPE_assert(pThis, qqueue); assert(pProp != NULL); if (isProp("iQueueSize")) { pThis->iQueueSize = pProp->val.num; #ifdef ENABLE_IMDIAG iOverallQueueSize += pThis->iQueueSize; #endif } else if (isProp("tVars.disk.sizeOnDisk")) { pThis->tVars.disk.sizeOnDisk = pProp->val.num; } else if (isProp("qType")) { if (pThis->qType != pProp->val.num) ABORT_FINALIZE(RS_RET_QTYPE_MISMATCH); } finalize_it: RETiRet; } #undef isProp /* dummy */ static rsRetVal qqueueQueryInterface(interface_t __attribute__((unused)) * i) { return RS_RET_NOT_IMPLEMENTED; } /* Initialize the stream class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-09 */ BEGINObjClassInit(qqueue, 1, OBJ_IS_CORE_MODULE) /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(strm, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); /* now set our own handlers */ OBJSetMethodHandler(objMethod_SETPROPERTY, qqueueSetProperty); ENDObjClassInit(qqueue) rsyslog-8.2512.0/runtime/PaxHeaders/netstrm.c0000644000000000000000000000013215114522477016064 xustar0030 mtime=1764926783.040631981 30 atime=1764926784.239661412 30 ctime=1764935923.352579168 rsyslog-8.2512.0/runtime/netstrm.c0000664000175000017500000003715515114522477015543 0ustar00rgerrger/* netstrm.c * * This class implements a generic netstrmwork stream class. It supports * sending and receiving data streams over a netstrmwork. The class abstracts * the transport, though it is a safe assumption that TCP is being used. * The class has a number of properties, among which are also ones to * select privacy settings, eg by enabling TLS and/or GSSAPI. In the * long run, this class shall provide all stream-oriented netstrmwork * functionality inside rsyslog. * * It is a high-level class, which uses a number of helper objects * to carry out its work (including, and most importantly, transport * drivers). * * Note on processing: * - Initiating a listener may be driver-specific, but in regard to TLS/non-TLS * it actually is not. This is because TLS is negotiated after a connection * has been established. So it is the "acceptConnReq" driver entry where TLS * params need to be applied. * * Work on this module begun 2008-04-17 by Rainer Gerhards. This code * borrows from librelp's tcp.c/.h code. librelp is dual licensed and * Rainer Gerhards and Adiscon GmbH have agreed to permit using the code * under the terms of the GNU Lesser General Public License. * * Copyright 2007-2020 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #include "rsyslog.h" #include "net.h" #include "module-template.h" #include "obj.h" #include "errmsg.h" #include "netstrms.h" #include "netstrm.h" /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(net) DEFobjCurrIf(netstrms) /* Standard-Constructor */ BEGINobjConstruct(netstrm) /* be sure to specify the object type also in END macro! */ ENDobjConstruct (netstrm) /* destructor for the netstrm object */ BEGINobjDestruct(netstrm) /* be sure to specify the object type also in END and CODESTART macros! */ CODESTARTobjDestruct(netstrm); if (pThis->pDrvrData != NULL) iRet = pThis->Drvr.Destruct(&pThis->pDrvrData); ENDobjDestruct (netstrm) /* ConstructionFinalizer */ static rsRetVal netstrmConstructFinalize(netstrm_t *pThis) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.Construct(&pThis->pDrvrData); finalize_it: RETiRet; } /* abort a connection. This is much like Destruct(), but tries * to discard any unsent data. -- rgerhards, 2008-03-24 */ static rsRetVal AbortDestruct(netstrm_t **ppThis) { DEFiRet; NULL_CHECK(ppThis); NULL_CHECK(*ppThis); /* we do NOT exit on error, because that would make things worse */ (*ppThis)->Drvr.Abort((*ppThis)->pDrvrData); iRet = netstrmDestruct(ppThis); finalize_it: RETiRet; } /* accept an incoming connection request * The netstrm instance that had the incoming request must be provided. If * the connection request succeeds, a new netstrm object is created and * passed back to the caller. The caller is responsible for destructing it. * pReq is the nsd_t obj that has the accept request. * rgerhards, 2008-04-21 */ static rsRetVal AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew, char *const connInfo) { nsd_t *pNewNsd = NULL; DEFiRet; NULL_CHECK(pThis); assert(ppNew != NULL); /* accept the new connection */ CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd, connInfo)); /* construct our object so that we can use it... */ CHKiRet(objUse(netstrms, DONT_LOAD_LIB)); /* use netstrms obj if not already done so */ CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew)); (*ppNew)->pDrvrData = pNewNsd; finalize_it: if (iRet != RS_RET_OK) { /* the close may be redundant, but that doesn't hurt... */ if (pNewNsd != NULL) pThis->Drvr.Destruct(&pNewNsd); } RETiRet; } /* make the netstrm listen to specified port and IP. * pLstnIP points to the port to listen to (NULL means "all"), * iMaxSess has the maximum number of sessions permitted (this ist just a hint). * pLstnPort must point to a port name or number. NULL is NOT permitted. * rgerhards, 2008-04-22 */ static rsRetVal ATTR_NONNULL(1, 3, 5) LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal (*fAddLstn)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params) { DEFiRet; const char *ns = cnf_params->pszNetworkNamespace; int netns_fd = -1; ISOBJ_TYPE_assert(pNS, netstrms); assert(fAddLstn != NULL); assert(cnf_params->pszPort != NULL); #ifdef HAVE_SETNS if (ns) { CHKiRet(net.netns_save(&netns_fd)); CHKiRet(net.netns_switch(ns)); } #endif // ndef HAVE_SETNS CHKiRet(pNS->Drvr.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params)); finalize_it: #ifdef HAVE_SETNS if (ns) { // netns_restore will log a message on failure // but there's really nothing we can do about it (void)net.netns_restore(&netns_fd); } #endif // ndef HAVE_SETNS RETiRet; } /* receive data from a tcp socket * The lenBuf parameter must contain the max buffer size on entry and contains * the number of octets read (or -1 in case of error) on exit. This function * never blocks, not even when called on a blocking socket. That is important * for client sockets, which are set to block during send, but should not * block when trying to read data. If *pLenBuf is -1, an error occurred and * oserr holds the exact error cause. * rgerhards, 2008-03-17 */ static rsRetVal Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf, int *const oserr, unsigned *nextIODirection) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.Rcv(pThis->pDrvrData, pBuf, pLenBuf, oserr, nextIODirection); finalize_it: RETiRet; } /* here follows a number of methods that shuffle authentication settings down * to the drivers. Drivers not supporting these settings may return an error * state. * -------------------------------------------------------------------------- */ /* set the driver mode * rgerhards, 2008-04-28 */ static rsRetVal SetDrvrMode(netstrm_t *pThis, int iMode) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetMode(pThis->pDrvrData, iMode); finalize_it: RETiRet; } /* set the driver authentication mode -- rgerhards, 2008-05-16 */ static rsRetVal SetDrvrAuthMode(netstrm_t *pThis, uchar *mode) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetAuthMode(pThis->pDrvrData, mode); finalize_it: RETiRet; } /* set the driver permitexpiredcerts mode -- alorbach, 2018-12-20 */ static rsRetVal SetDrvrPermitExpiredCerts(netstrm_t *pThis, uchar *mode) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetPermitExpiredCerts(pThis->pDrvrData, mode); finalize_it: RETiRet; } /* set the driver's permitted peers -- rgerhards, 2008-05-19 */ static rsRetVal SetDrvrPermPeers(netstrm_t *pThis, permittedPeers_t *pPermPeers) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetPermPeers(pThis->pDrvrData, pPermPeers); finalize_it: RETiRet; } /* Mandate also verification of Extended key usage / purpose field */ static rsRetVal SetDrvrCheckExtendedKeyUsage(netstrm_t *pThis, int ChkExtendedKeyUsage) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetCheckExtendedKeyUsage(pThis->pDrvrData, ChkExtendedKeyUsage); finalize_it: RETiRet; } /* Mandate stricter name checking per RFC 6125 - ignoce CN if any SAN present */ static rsRetVal SetDrvrPrioritizeSAN(netstrm_t *pThis, int prioritizeSan) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetPrioritizeSAN(pThis->pDrvrData, prioritizeSan); finalize_it: RETiRet; } /* tls verify depth */ static rsRetVal SetDrvrTlsVerifyDepth(netstrm_t *pThis, int verifyDepth) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetTlsVerifyDepth(pThis->pDrvrData, verifyDepth); finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCAFile(netstrm_t *const pThis, const uchar *const file) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetTlsCAFile(pThis->pDrvrData, file); finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCRLFile(netstrm_t *const pThis, const uchar *const file) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetTlsCRLFile(pThis->pDrvrData, file); finalize_it: RETiRet; } static rsRetVal SetDrvrTlsKeyFile(netstrm_t *const pThis, const uchar *const file) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetTlsKeyFile(pThis->pDrvrData, file); finalize_it: RETiRet; } static rsRetVal SetDrvrTlsCertFile(netstrm_t *const pThis, const uchar *const file) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetTlsCertFile(pThis->pDrvrData, file); finalize_it: RETiRet; } /* End of methods to shuffle autentication settings to the driver. * -------------------------------------------------------------------------- */ /* send a buffer. On entry, pLenBuf contains the number of octets to * write. On exit, it contains the number of octets actually written. * If this number is lower than on entry, only a partial buffer has * been written. * rgerhards, 2008-03-19 */ static rsRetVal Send(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.Send(pThis->pDrvrData, pBuf, pLenBuf); finalize_it: RETiRet; } /* Enable Keep-Alive handling for those drivers that support it. * rgerhards, 2009-06-02 */ static rsRetVal EnableKeepAlive(netstrm_t *pThis) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.EnableKeepAlive(pThis->pDrvrData); finalize_it: RETiRet; } /* Keep-Alive options */ static rsRetVal SetKeepAliveProbes(netstrm_t *pThis, int keepAliveProbes) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetKeepAliveProbes(pThis->pDrvrData, keepAliveProbes); finalize_it: RETiRet; } /* Keep-Alive options */ static rsRetVal SetKeepAliveTime(netstrm_t *pThis, int keepAliveTime) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetKeepAliveTime(pThis->pDrvrData, keepAliveTime); finalize_it: RETiRet; } /* Keep-Alive options */ static rsRetVal SetKeepAliveIntvl(netstrm_t *pThis, int keepAliveIntvl) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetKeepAliveIntvl(pThis->pDrvrData, keepAliveIntvl); finalize_it: RETiRet; } /* gnutls priority string */ static rsRetVal SetGnutlsPriorityString(netstrm_t *pThis, uchar *gnutlsPriorityString) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.SetGnutlsPriorityString(pThis->pDrvrData, gnutlsPriorityString); finalize_it: RETiRet; } /* check connection - slim wrapper for NSD driver function */ static rsRetVal CheckConnection(netstrm_t *pThis) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.CheckConnection(pThis->pDrvrData); finalize_it: RETiRet; } /* get remote hname - slim wrapper for NSD driver function */ static rsRetVal GetRemoteHName(netstrm_t *pThis, uchar **ppsz) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.GetRemoteHName(pThis->pDrvrData, ppsz); finalize_it: RETiRet; } /* get remote IP - slim wrapper for NSD driver function */ static rsRetVal GetRemoteIP(netstrm_t *pThis, prop_t **ip) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.GetRemoteIP(pThis->pDrvrData, ip); finalize_it: RETiRet; } /* get remote addr - slim wrapper for NSD driver function */ static rsRetVal GetRemAddr(netstrm_t *pThis, struct sockaddr_storage **ppAddr) { DEFiRet; NULL_CHECK(pThis); iRet = pThis->Drvr.GetRemAddr(pThis->pDrvrData, ppAddr); finalize_it: RETiRet; } /* open a connection to a remote host (server). * rgerhards, 2008-03-19 */ static rsRetVal Connect(netstrm_t *pThis, int family, uchar *port, uchar *host, char *device) { DEFiRet; NULL_CHECK(pThis); assert(port != NULL); assert(host != NULL); iRet = pThis->Drvr.Connect(pThis->pDrvrData, family, port, host, device); finalize_it: RETiRet; } /* Provide access to the underlying OS socket. This is dirty * and scheduled to be removed. Does not work with all nsd drivers. * See comment in netstrm interface for details. * rgerhards, 2008-05-05 */ static rsRetVal GetSock(netstrm_t *pThis, int *pSock) { DEFiRet; NULL_CHECK(pThis); NULL_CHECK(pSock); iRet = pThis->Drvr.GetSock(pThis->pDrvrData, pSock); finalize_it: RETiRet; } /* queryInterface function */ BEGINobjQueryInterface(netstrm) CODESTARTobjQueryInterface(netstrm); if (pIf->ifVersion != netstrmCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->Construct = netstrmConstruct; pIf->ConstructFinalize = netstrmConstructFinalize; pIf->Destruct = netstrmDestruct; pIf->AbortDestruct = AbortDestruct; pIf->Rcv = Rcv; pIf->Send = Send; pIf->Connect = Connect; pIf->LstnInit = LstnInit; pIf->AcceptConnReq = AcceptConnReq; pIf->GetRemoteHName = GetRemoteHName; pIf->GetRemoteIP = GetRemoteIP; pIf->GetRemAddr = GetRemAddr; pIf->SetDrvrMode = SetDrvrMode; pIf->SetDrvrAuthMode = SetDrvrAuthMode; pIf->SetDrvrPermitExpiredCerts = SetDrvrPermitExpiredCerts; pIf->SetDrvrPermPeers = SetDrvrPermPeers; pIf->CheckConnection = CheckConnection; pIf->GetSock = GetSock; pIf->EnableKeepAlive = EnableKeepAlive; pIf->SetKeepAliveProbes = SetKeepAliveProbes; pIf->SetKeepAliveTime = SetKeepAliveTime; pIf->SetKeepAliveIntvl = SetKeepAliveIntvl; pIf->SetGnutlsPriorityString = SetGnutlsPriorityString; pIf->SetDrvrCheckExtendedKeyUsage = SetDrvrCheckExtendedKeyUsage; pIf->SetDrvrPrioritizeSAN = SetDrvrPrioritizeSAN; pIf->SetDrvrTlsVerifyDepth = SetDrvrTlsVerifyDepth; pIf->SetDrvrTlsCAFile = SetDrvrTlsCAFile; pIf->SetDrvrTlsCRLFile = SetDrvrTlsCRLFile; pIf->SetDrvrTlsKeyFile = SetDrvrTlsKeyFile; pIf->SetDrvrTlsCertFile = SetDrvrTlsCertFile; finalize_it: ENDobjQueryInterface(netstrm) /* exit our class */ BEGINObjClassExit(netstrm, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(netstrm); /* release objects we no longer need */ objRelease(netstrms, DONT_LOAD_LIB); objRelease(net, LM_NET_FILENAME); ENDObjClassExit(netstrm) /* Initialize the netstrm class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-19 */ BEGINAbstractObjClassInit(netstrm, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(net, LM_NET_FILENAME)); /* set our own handlers */ ENDObjClassInit(netstrm) rsyslog-8.2512.0/runtime/PaxHeaders/nsd.h0000644000000000000000000000013215055605325015157 xustar0030 mtime=1756826325.649800683 30 atime=1764931008.689155943 30 ctime=1764935923.127575723 rsyslog-8.2512.0/runtime/nsd.h0000664000175000017500000001251415055605325014626 0ustar00rgerrger/* The interface definition for "NetStream Drivers" (nsd). * * This is just an abstract driver interface, which needs to be * implemented by concrete classes. As such, no nsd data type itself * is defined. * * Copyright 2008-2025 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_NSD_H #define INCLUDED_NSD_H #include enum nsdsel_waitOp_e { NSDSEL_RD = 1, NSDSEL_WR = 2, NSDSEL_RDWR = 3 }; /**< the operation we wait for */ /* nsd_t is actually obj_t (which is somewhat better than void* but in essence * much the same). */ /* interface */ BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(nsd_t **ppThis); rsRetVal (*Destruct)(nsd_t **ppThis); rsRetVal (*Abort)(nsd_t *pThis); rsRetVal (*Rcv)(nsd_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf, int *oserr, unsigned *nextIODirection); rsRetVal (*Send)(nsd_t *pThis, uchar *pBuf, ssize_t *pLenBuf); rsRetVal (*Connect)(nsd_t *pThis, int family, unsigned char *port, unsigned char *host, char *device); rsRetVal (*AcceptConnReq)(nsd_t *pThis, nsd_t **ppThis, char *connInfo); rsRetVal (*GetRemoteHName)(nsd_t *pThis, uchar **pszName); rsRetVal (*GetRemoteIP)(nsd_t *pThis, prop_t **ip); rsRetVal (*SetMode)(nsd_t *pThis, int mode); /* sets a driver specific mode - see driver doc for details */ rsRetVal (*SetAuthMode)(nsd_t *pThis, uchar *); /* sets a driver specific mode - see driver doc for details */ rsRetVal (*SetPermitExpiredCerts)(nsd_t *pThis, uchar *); /* sets a driver specific permitexpiredcerts mode */ rsRetVal (*SetPermPeers)(nsd_t *pThis, permittedPeers_t *); /* sets driver permitted peers for auth needs */ rsRetVal (*CheckConnection)(nsd_t *pThis); /* This is a trick mostly for plain tcp syslog */ rsRetVal (*GetSock)(nsd_t *pThis, int *pSock); rsRetVal (*SetSock)(nsd_t *pThis, int sock); /* GetSock() and SetSock() return an error if the driver does not use plain * OS sockets. This interface is primarily meant as an internal aid for * those drivers that utilize the nsd_ptcp to do some of their work. */ rsRetVal (*GetRemAddr)(nsd_t *pThis, struct sockaddr_storage **ppAddr); /* getRemAddr() is an aid needed by the legacy ACL system. It exposes the remote * peer's socket addr structure, so that the legacy matching functions can work on * it. Note that this ties netstream drivers to things that can be implemented over * sockets - not really desirable, but not the end of the world... */ /* v5 */ rsRetVal (*EnableKeepAlive)(nsd_t *pThis); /* v8 */ rsRetVal (*SetKeepAliveIntvl)(nsd_t *pThis, int keepAliveIntvl); rsRetVal (*SetKeepAliveProbes)(nsd_t *pThis, int keepAliveProbes); rsRetVal (*SetKeepAliveTime)(nsd_t *pThis, int keepAliveTime); rsRetVal (*SetGnutlsPriorityString)(nsd_t *pThis, uchar *gnutlsPriorityString); /* v12 -- parameter pszLstnPortFileName added to LstnInit()*/ rsRetVal(ATTR_NONNULL(1, 3, 5) * LstnInit)(netstrms_t * pNS, void *pUsr, rsRetVal (*)(void *, netstrm_t *), const int iSessMax, const tcpLstnParams_t *const cnf_params); /* v13 -- two new binary flags added to gtls driver enabling stricter operation */ rsRetVal (*SetCheckExtendedKeyUsage)(nsd_t *pThis, int ChkExtendedKeyUsage); rsRetVal (*SetPrioritizeSAN)(nsd_t *pThis, int prioritizeSan); /* v14 -- Tls functions */ rsRetVal (*SetTlsVerifyDepth)(nsd_t *pThis, int verifyDepth); /* v15 -- Tls functions */ rsRetVal (*SetTlsCAFile)(nsd_t *pThis, const uchar *); rsRetVal (*SetTlsKeyFile)(nsd_t *pThis, const uchar *); rsRetVal (*SetTlsCertFile)(nsd_t *pThis, const uchar *); /* v16 - Tls CRL */ rsRetVal (*SetTlsCRLFile)(nsd_t *pThis, const uchar *); /* v17 - Remote Port */ rsRetVal (*GetRemotePort)(nsd_t *pThis, int *); rsRetVal (*FmtRemotePortStr)(const int port, uchar *const buf, const size_t len); ENDinterface(nsd) #define nsdCURR_IF_VERSION 17 /* increment whenever you change the interface structure! */ /* interface version 4 added GetRemAddr() * interface version 5 added EnableKeepAlive() -- rgerhards, 2009-06-02 * interface version 6 changed return of CheckConnection from void to rsRetVal -- alorbach, 2012-09-06 * interface version 7 changed signature ofGetRempoteIP() -- rgerhards, 2013-01-21 * interface version 8 added keep alive parameter set functions * interface version 9 changed signature of Connect() -- dsa, 2016-11-14 * interface version 10 added SetGnutlsPriorityString() -- PascalWithopf, 2017-08-08 * interface version 11 added oserr to Rcv() signature -- rgerhards, 2017-09-04 */ #endif /* #ifndef INCLUDED_NSD_H */ rsyslog-8.2512.0/runtime/PaxHeaders/zlibw.h0000644000000000000000000000013215055605325015522 xustar0030 mtime=1756826325.654800759 30 atime=1764930980.023678273 30 ctime=1764935923.417580163 rsyslog-8.2512.0/runtime/zlibw.h0000664000175000017500000000362215055605325015171 0ustar00rgerrger/* The zlibw object. It encapsulates the zlib functionality. The primary * purpose of this wrapper class is to enable rsyslogd core to be build without * zlib libraries. * * Copyright 2009-2022 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_ZLIBW_H #define INCLUDED_ZLIBW_H #include #include "errmsg.h" /* interfaces */ BEGINinterface(zlibw) /* name must also be changed in ENDinterface macro! */ int (*DeflateInit)(z_streamp strm, int); int (*DeflateInit2)(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy); int (*Deflate)(z_streamp strm, int); int (*DeflateEnd)(z_streamp strm); rsRetVal (*doStrmWrite)(strm_t *pThis, uchar *const pBuf, const size_t lenBuf, const int bFlush, rsRetVal (*strmPhysWrite)(strm_t *pThis, uchar *pBuf, size_t lenBuf)); rsRetVal (*doCompressFinish)(strm_t *pThis, rsRetVal (*Destruct)(strm_t *pThis, uchar *pBuf, size_t lenBuf)); rsRetVal (*Destruct)(strm_t *pThis); ENDinterface(zlibw) #define zlibwCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */ /* prototypes */ PROTOTYPEObj(zlibw); /* the name of our library binary */ #define LM_ZLIBW_FILENAME "lmzlibw" #endif /* #ifndef INCLUDED_ZLIBW_H */ rsyslog-8.2512.0/runtime/PaxHeaders/msg.c0000644000000000000000000000013215114522477015156 xustar0030 mtime=1764926783.040631981 30 atime=1764926784.238661387 30 ctime=1764935923.161576244 rsyslog-8.2512.0/runtime/msg.c0000664000175000017500000056620515114522477014640 0ustar00rgerrger/* msg.c * The msg object. Implementation of all msg-related functions * * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c) * This file is under development and has not yet arrived at being fully * self-contained and a real object. So far, it is mostly an excerpt * of the "old" message code without any modifications. However, it * helps to have things at the right place one we go to the meat of it. * * Copyright 2007-2023 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * The rsyslog runtime library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The rsyslog runtime library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the rsyslog runtime library. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution. */ #include "config.h" #include #include #include #define SYSLOG_NAMES #include #include #include #include #include #ifdef HAVE_SYSINFO_UPTIME #include #endif #include #include #include #ifdef HAVE_MALLOC_H #include #endif #ifdef USE_LIBUUID #include #endif #include #include "rsyslog.h" #include "srUtils.h" #include "stringbuf.h" #include "template.h" #include "msg.h" #include "datetime.h" #include "glbl.h" #include "regexp.h" #include "atomic.h" #include "unicode-helper.h" #include "ruleset.h" #include "prop.h" #include "net.h" #include "var.h" #include "rsconf.h" #include "parserif.h" #include "errmsg.h" #define DEV_DEBUG 0 /* set to 1 to enable very verbose developer debugging messages */ /* inlines */ extern void msgSetPRI(smsg_t *const __restrict__ pMsg, syslog_pri_t pri); /* TODO: move the global variable root to the config object - had no time to to it * right now before vacation -- rgerhards, 2013-07-22 */ static pthread_mutex_t glblVars_lock; struct json_object *global_var_root = NULL; /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(datetime) DEFobjCurrIf(glbl) DEFobjCurrIf(regexp) DEFobjCurrIf(prop) DEFobjCurrIf(net) DEFobjCurrIf(var) static const char *one_digit[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; static const char *two_digits[100] = { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99"}; static const char *wdayNames[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; /* Table of days in a year, needed for getYearDay */ static const char *daysInYear[366] = { "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", "045", "046", "047", "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", "061", "062", "063", "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", "077", "078", "079", "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", "093", "094", "095", "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362", "363", "364", "365", "366"}; /* The following is a table of supported years. This permits us * to avoid dynamic memory allocation. Note that the time-based * algos need to be upgraded after the year 2099 in any case. * Quite honestly, I don't expect that this is a real problem ;) */ static const char *years[] = { "1967", "1968", "1969", "1970", "1971", "1972", "1973", "1974", "1975", "1976", "1977", "1978", "1979", "1980", "1981", "1982", "1983", "1984", "1985", "1986", "1987", "1988", "1989", "1990", "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026", "2027", "2028", "2029", "2030", "2031", "2032", "2033", "2034", "2035", "2036", "2037", "2038", "2039", "2040", "2041", "2042", "2043", "2044", "2045", "2046", "2047", "2048", "2049", "2050", "2051", "2052", "2053", "2054", "2055", "2056", "2057", "2058", "2059", "2060", "2061", "2062", "2063", "2064", "2065", "2066", "2067", "2068", "2069", "2070", "2071", "2072", "2073", "2074", "2075", "2076", "2077", "2078", "2079", "2080", "2081", "2082", "2083", "2084", "2085", "2086", "2087", "2088", "2089", "2090", "2091", "2092", "2093", "2094", "2095", "2096", "2097", "2098", "2099"}; static struct { uchar *pszName; } syslog_pri_names[200] = { {UCHAR_CONSTANT("0")}, {UCHAR_CONSTANT("1")}, {UCHAR_CONSTANT("2")}, {UCHAR_CONSTANT("3")}, {UCHAR_CONSTANT("4")}, {UCHAR_CONSTANT("5")}, {UCHAR_CONSTANT("6")}, {UCHAR_CONSTANT("7")}, {UCHAR_CONSTANT("8")}, {UCHAR_CONSTANT("9")}, {UCHAR_CONSTANT("10")}, {UCHAR_CONSTANT("11")}, {UCHAR_CONSTANT("12")}, {UCHAR_CONSTANT("13")}, {UCHAR_CONSTANT("14")}, {UCHAR_CONSTANT("15")}, {UCHAR_CONSTANT("16")}, {UCHAR_CONSTANT("17")}, {UCHAR_CONSTANT("18")}, {UCHAR_CONSTANT("19")}, {UCHAR_CONSTANT("20")}, {UCHAR_CONSTANT("21")}, {UCHAR_CONSTANT("22")}, {UCHAR_CONSTANT("23")}, {UCHAR_CONSTANT("24")}, {UCHAR_CONSTANT("25")}, {UCHAR_CONSTANT("26")}, {UCHAR_CONSTANT("27")}, {UCHAR_CONSTANT("28")}, {UCHAR_CONSTANT("29")}, {UCHAR_CONSTANT("30")}, {UCHAR_CONSTANT("31")}, {UCHAR_CONSTANT("32")}, {UCHAR_CONSTANT("33")}, {UCHAR_CONSTANT("34")}, {UCHAR_CONSTANT("35")}, {UCHAR_CONSTANT("36")}, {UCHAR_CONSTANT("37")}, {UCHAR_CONSTANT("38")}, {UCHAR_CONSTANT("39")}, {UCHAR_CONSTANT("40")}, {UCHAR_CONSTANT("41")}, {UCHAR_CONSTANT("42")}, {UCHAR_CONSTANT("43")}, {UCHAR_CONSTANT("44")}, {UCHAR_CONSTANT("45")}, {UCHAR_CONSTANT("46")}, {UCHAR_CONSTANT("47")}, {UCHAR_CONSTANT("48")}, {UCHAR_CONSTANT("49")}, {UCHAR_CONSTANT("50")}, {UCHAR_CONSTANT("51")}, {UCHAR_CONSTANT("52")}, {UCHAR_CONSTANT("53")}, {UCHAR_CONSTANT("54")}, {UCHAR_CONSTANT("55")}, {UCHAR_CONSTANT("56")}, {UCHAR_CONSTANT("57")}, {UCHAR_CONSTANT("58")}, {UCHAR_CONSTANT("59")}, {UCHAR_CONSTANT("60")}, {UCHAR_CONSTANT("61")}, {UCHAR_CONSTANT("62")}, {UCHAR_CONSTANT("63")}, {UCHAR_CONSTANT("64")}, {UCHAR_CONSTANT("65")}, {UCHAR_CONSTANT("66")}, {UCHAR_CONSTANT("67")}, {UCHAR_CONSTANT("68")}, {UCHAR_CONSTANT("69")}, {UCHAR_CONSTANT("70")}, {UCHAR_CONSTANT("71")}, {UCHAR_CONSTANT("72")}, {UCHAR_CONSTANT("73")}, {UCHAR_CONSTANT("74")}, {UCHAR_CONSTANT("75")}, {UCHAR_CONSTANT("76")}, {UCHAR_CONSTANT("77")}, {UCHAR_CONSTANT("78")}, {UCHAR_CONSTANT("79")}, {UCHAR_CONSTANT("80")}, {UCHAR_CONSTANT("81")}, {UCHAR_CONSTANT("82")}, {UCHAR_CONSTANT("83")}, {UCHAR_CONSTANT("84")}, {UCHAR_CONSTANT("85")}, {UCHAR_CONSTANT("86")}, {UCHAR_CONSTANT("87")}, {UCHAR_CONSTANT("88")}, {UCHAR_CONSTANT("89")}, {UCHAR_CONSTANT("90")}, {UCHAR_CONSTANT("91")}, {UCHAR_CONSTANT("92")}, {UCHAR_CONSTANT("93")}, {UCHAR_CONSTANT("94")}, {UCHAR_CONSTANT("95")}, {UCHAR_CONSTANT("96")}, {UCHAR_CONSTANT("97")}, {UCHAR_CONSTANT("98")}, {UCHAR_CONSTANT("99")}, {UCHAR_CONSTANT("100")}, {UCHAR_CONSTANT("101")}, {UCHAR_CONSTANT("102")}, {UCHAR_CONSTANT("103")}, {UCHAR_CONSTANT("104")}, {UCHAR_CONSTANT("105")}, {UCHAR_CONSTANT("106")}, {UCHAR_CONSTANT("107")}, {UCHAR_CONSTANT("108")}, {UCHAR_CONSTANT("109")}, {UCHAR_CONSTANT("110")}, {UCHAR_CONSTANT("111")}, {UCHAR_CONSTANT("112")}, {UCHAR_CONSTANT("113")}, {UCHAR_CONSTANT("114")}, {UCHAR_CONSTANT("115")}, {UCHAR_CONSTANT("116")}, {UCHAR_CONSTANT("117")}, {UCHAR_CONSTANT("118")}, {UCHAR_CONSTANT("119")}, {UCHAR_CONSTANT("120")}, {UCHAR_CONSTANT("121")}, {UCHAR_CONSTANT("122")}, {UCHAR_CONSTANT("123")}, {UCHAR_CONSTANT("124")}, {UCHAR_CONSTANT("125")}, {UCHAR_CONSTANT("126")}, {UCHAR_CONSTANT("127")}, {UCHAR_CONSTANT("128")}, {UCHAR_CONSTANT("129")}, {UCHAR_CONSTANT("130")}, {UCHAR_CONSTANT("131")}, {UCHAR_CONSTANT("132")}, {UCHAR_CONSTANT("133")}, {UCHAR_CONSTANT("134")}, {UCHAR_CONSTANT("135")}, {UCHAR_CONSTANT("136")}, {UCHAR_CONSTANT("137")}, {UCHAR_CONSTANT("138")}, {UCHAR_CONSTANT("139")}, {UCHAR_CONSTANT("140")}, {UCHAR_CONSTANT("141")}, {UCHAR_CONSTANT("142")}, {UCHAR_CONSTANT("143")}, {UCHAR_CONSTANT("144")}, {UCHAR_CONSTANT("145")}, {UCHAR_CONSTANT("146")}, {UCHAR_CONSTANT("147")}, {UCHAR_CONSTANT("148")}, {UCHAR_CONSTANT("149")}, {UCHAR_CONSTANT("150")}, {UCHAR_CONSTANT("151")}, {UCHAR_CONSTANT("152")}, {UCHAR_CONSTANT("153")}, {UCHAR_CONSTANT("154")}, {UCHAR_CONSTANT("155")}, {UCHAR_CONSTANT("156")}, {UCHAR_CONSTANT("157")}, {UCHAR_CONSTANT("158")}, {UCHAR_CONSTANT("159")}, {UCHAR_CONSTANT("160")}, {UCHAR_CONSTANT("161")}, {UCHAR_CONSTANT("162")}, {UCHAR_CONSTANT("163")}, {UCHAR_CONSTANT("164")}, {UCHAR_CONSTANT("165")}, {UCHAR_CONSTANT("166")}, {UCHAR_CONSTANT("167")}, {UCHAR_CONSTANT("168")}, {UCHAR_CONSTANT("169")}, {UCHAR_CONSTANT("170")}, {UCHAR_CONSTANT("171")}, {UCHAR_CONSTANT("172")}, {UCHAR_CONSTANT("173")}, {UCHAR_CONSTANT("174")}, {UCHAR_CONSTANT("175")}, {UCHAR_CONSTANT("176")}, {UCHAR_CONSTANT("177")}, {UCHAR_CONSTANT("178")}, {UCHAR_CONSTANT("179")}, {UCHAR_CONSTANT("180")}, {UCHAR_CONSTANT("181")}, {UCHAR_CONSTANT("182")}, {UCHAR_CONSTANT("183")}, {UCHAR_CONSTANT("184")}, {UCHAR_CONSTANT("185")}, {UCHAR_CONSTANT("186")}, {UCHAR_CONSTANT("187")}, {UCHAR_CONSTANT("188")}, {UCHAR_CONSTANT("189")}, {UCHAR_CONSTANT("190")}, {UCHAR_CONSTANT("191")}, {UCHAR_CONSTANT("192")}, {UCHAR_CONSTANT("193")}, {UCHAR_CONSTANT("194")}, {UCHAR_CONSTANT("195")}, {UCHAR_CONSTANT("196")}, {UCHAR_CONSTANT("197")}, {UCHAR_CONSTANT("198")}, {UCHAR_CONSTANT("199")}}; static char hexdigit[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; #if defined(_AIX) /* AIXPORT : replace facility names with aso and caa only for AIX */ static const char *syslog_fac_names[LOG_NFACILITIES] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "aso", "audit", "alert", "caa", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7", "invld"}; /* length of the facility names string (for optimizatiions) */ static short len_syslog_fac_names[LOG_NFACILITIES] = {4, 4, 4, 6, 4, 6, 3, 4, 4, 4, 8, 3, 3, 5, 5, 3, 6, 6, 6, 6, 6, 6, 6, 6, 5}; #else /*syslog facility names (as of RFC5424) */ static const char *syslog_fac_names[LOG_NFACILITIES] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news", "uucp", "cron", "authpriv", "ftp", "ntp", "audit", "alert", "clock", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7", "invld"}; /* length of the facility names string (for optimizatiions) */ static short len_syslog_fac_names[LOG_NFACILITIES] = {4, 4, 4, 6, 4, 6, 3, 4, 4, 4, 8, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5}; #endif /* table of severity names (in numerical order)*/ static const char *syslog_severity_names[8] = {"emerg", "alert", "crit", "err", "warning", "notice", "info", "debug"}; static short len_syslog_severity_names[8] = {5, 5, 4, 3, 7, 6, 4, 5}; /* numerical values as string - this is the most efficient approach to convert severity * and facility values to a numerical string... -- rgerhars, 2009-06-17 */ static const char *syslog_number_names[LOG_NFACILITIES] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"}; /* global variables */ #if defined(HAVE_MALLOC_TRIM) && !defined(HAVE_ATOMIC_BUILTINS) static pthread_mutex_t mutTrimCtr; /* mutex to handle malloc trim */ #endif /* some forward declarations */ static int getAPPNAMELen(smsg_t *const pM, sbool bLockMutex); static rsRetVal jsonPathFindParent( struct json_object *jroot, uchar *name, uchar *leaf, struct json_object **parent, int bCreate); static uchar *jsonPathGetLeaf(uchar *name, int lenName); static json_bool jsonVarExtract(struct json_object *root, const char *key, struct json_object **value); void getRawMsgAfterPRI(smsg_t *const pM, uchar **pBuf, int *piLen); /* the locking and unlocking implementations: */ static inline void MsgLock(smsg_t *pThis) { #if DEV_DEBUG == 1 dbgprintf("MsgLock(0x%lx)\n", (unsigned long)pThis); #endif pthread_mutex_lock(&pThis->mut); } static inline void MsgUnlock(smsg_t *pThis) { #if DEV_DEBUG == 1 dbgprintf("MsgUnlock(0x%lx)\n", (unsigned long)pThis); #endif pthread_mutex_unlock(&pThis->mut); } /* set RcvFromIP name in msg object WITHOUT calling AddRef. * rgerhards, 2013-01-22 */ static inline void MsgSetRcvFromIPWithoutAddRef(smsg_t *pThis, prop_t *new) { if (pThis->pRcvFromIP != NULL) prop.Destruct(&pThis->pRcvFromIP); pThis->pRcvFromIP = new; } static inline void MsgSetRcvFromPortWithoutAddRef(smsg_t *pThis, prop_t *new) { if (pThis->pRcvFromPort != NULL) prop.Destruct(&pThis->pRcvFromPort); pThis->pRcvFromPort = new; } /* set RcvFrom name in msg object WITHOUT calling AddRef. * rgerhards, 2013-01-22 */ static void MsgSetRcvFromWithoutAddRef(smsg_t *pThis, prop_t *new) { assert(pThis != NULL); if (pThis->msgFlags & NEEDS_DNSRESOL) { if (pThis->rcvFrom.pfrominet != NULL) free(pThis->rcvFrom.pfrominet); pThis->msgFlags &= ~NEEDS_DNSRESOL; } else { if (pThis->rcvFrom.pRcvFrom != NULL) prop.Destruct(&pThis->rcvFrom.pRcvFrom); } pThis->rcvFrom.pRcvFrom = new; } /* rgerhards 2012-04-18: set associated ruleset (by ruleset name) * pRuleset pointer inside msg is updated. If ruleset cannot be found, * no update is done and an error message emitted. */ static void ATTR_NONNULL() MsgSetRulesetByName(smsg_t *const pMsg, cstr_t *const rulesetName) { uchar *const rs_name = rsCStrGetSzStrNoNULL(rulesetName); const rsRetVal localRet = rulesetGetRuleset(runConf, &(pMsg->pRuleset), rs_name); if (localRet != RS_RET_OK) { LogError(0, localRet, "msg: ruleset '%s' could not be found and could not " "be assigned to message object. This possibly leads to the message " "being processed incorrectly. We cannot do anything against this, but " "wanted to let you know.", rs_name); } } /* do a DNS reverse resolution, if not already done, reflect status * rgerhards, 2009-11-16 */ static rsRetVal resolveDNS(smsg_t *const pMsg) { rsRetVal localRet; prop_t *propFromHost = NULL; prop_t *ip; prop_t *localName; prop_t *port = NULL; char portbuf[8]; uint16_t pnum; DEFiRet; MsgLock(pMsg); CHKiRet(objUse(net, CORE_COMPONENT)); if (pMsg->msgFlags & NEEDS_DNSRESOL) { if (pMsg->msgFlags & PRESERVE_CASE) { localRet = net.cvthname(pMsg->rcvFrom.pfrominet, NULL, &localName, &ip); } else { localRet = net.cvthname(pMsg->rcvFrom.pfrominet, &localName, NULL, &ip); } if (localRet == RS_RET_OK) { /* we pass down the props, so no need for AddRef */ MsgSetRcvFromWithoutAddRef(pMsg, localName); MsgSetRcvFromIPWithoutAddRef(pMsg, ip); if (pMsg->pRcvFromPort == NULL) { if (pMsg->rcvFrom.pfrominet->ss_family == AF_INET) pnum = ntohs(((struct sockaddr_in *)pMsg->rcvFrom.pfrominet)->sin_port); else if (pMsg->rcvFrom.pfrominet->ss_family == AF_INET6) pnum = ntohs(((struct sockaddr_in6 *)pMsg->rcvFrom.pfrominet)->sin6_port); else pnum = 0; snprintf(portbuf, sizeof(portbuf), "%u", pnum); CHKiRet(prop.CreateStringProp(&port, (uchar *)portbuf, strlen(portbuf))); MsgSetRcvFromPortWithoutAddRef(pMsg, port); port = NULL; } } } finalize_it: if (iRet != RS_RET_OK) { /* best we can do: remove property */ MsgSetRcvFromStr(pMsg, UCHAR_CONSTANT(""), 0, &propFromHost); prop.Destruct(&propFromHost); } MsgUnlock(pMsg); if (propFromHost != NULL) prop.Destruct(&propFromHost); if (port != NULL) prop.Destruct(&port); RETiRet; } void getInputName(const smsg_t *const pM, uchar **ppsz, int *const plen) { if (pM == NULL || pM->pInputName == NULL) { *ppsz = UCHAR_CONSTANT(""); *plen = 0; } else { prop.GetString(pM->pInputName, ppsz, plen); } } static uchar *getRcvFromIP(smsg_t *const pM) { uchar *psz; int len; if (pM == NULL) { psz = UCHAR_CONSTANT(""); } else { resolveDNS(pM); /* make sure we have a resolved entry */ if (pM->pRcvFromIP == NULL) psz = UCHAR_CONSTANT(""); else prop.GetString(pM->pRcvFromIP, &psz, &len); } return psz; } static uchar *getRcvFromPort(smsg_t *const pM) { uchar *psz; int len; if (pM == NULL) { psz = UCHAR_CONSTANT(""); } else { resolveDNS(pM); if (pM->pRcvFromPort == NULL) psz = UCHAR_CONSTANT(""); else prop.GetString(pM->pRcvFromPort, &psz, &len); } return psz; } /* map a property name (string) to a property ID */ rsRetVal propNameToID(const uchar *const pName, propid_t *const pPropID) { DEFiRet; /* sometimes there are aliases to the original MonitoWare * property names. These come after || in the ifs below. */ if (!strcasecmp((char *)pName, "msg")) { *pPropID = PROP_MSG; } else if (!strcasecmp((char *)pName, "timestamp") || !strcasecmp((char *)pName, "timereported")) { *pPropID = PROP_TIMESTAMP; } else if (!strcasecmp((char *)pName, "hostname") || !strcasecmp((char *)pName, "source")) { *pPropID = PROP_HOSTNAME; } else if (!strcasecmp((char *)pName, "syslogtag")) { *pPropID = PROP_SYSLOGTAG; } else if (!strcasecmp((char *)pName, "rawmsg")) { *pPropID = PROP_RAWMSG; } else if (!strcasecmp((char *)pName, "rawmsg-after-pri")) { *pPropID = PROP_RAWMSG_AFTER_PRI; } else if (!strcasecmp((char *)pName, "inputname")) { *pPropID = PROP_INPUTNAME; } else if (!strcasecmp((char *)pName, "fromhost")) { *pPropID = PROP_FROMHOST; } else if (!strcasecmp((char *)pName, "fromhost-ip")) { *pPropID = PROP_FROMHOST_IP; } else if (!strcasecmp((char *)pName, "fromhost-port")) { *pPropID = PROP_FROMHOST_PORT; } else if (!strcasecmp((char *)pName, "pri")) { *pPropID = PROP_PRI; } else if (!strcasecmp((char *)pName, "pri-text")) { *pPropID = PROP_PRI_TEXT; } else if (!strcasecmp((char *)pName, "iut")) { *pPropID = PROP_IUT; } else if (!strcasecmp((char *)pName, "syslogfacility")) { *pPropID = PROP_SYSLOGFACILITY; } else if (!strcasecmp((char *)pName, "syslogfacility-text")) { *pPropID = PROP_SYSLOGFACILITY_TEXT; } else if (!strcasecmp((char *)pName, "syslogseverity") || !strcasecmp((char *)pName, "syslogpriority")) { *pPropID = PROP_SYSLOGSEVERITY; } else if (!strcasecmp((char *)pName, "syslogseverity-text") || !strcasecmp((char *)pName, "syslogpriority-text")) { *pPropID = PROP_SYSLOGSEVERITY_TEXT; } else if (!strcasecmp((char *)pName, "timegenerated")) { *pPropID = PROP_TIMEGENERATED; } else if (!strcasecmp((char *)pName, "programname")) { *pPropID = PROP_PROGRAMNAME; } else if (!strcasecmp((char *)pName, "protocol-version")) { *pPropID = PROP_PROTOCOL_VERSION; } else if (!strcasecmp((char *)pName, "structured-data")) { *pPropID = PROP_STRUCTURED_DATA; } else if (!strcasecmp((char *)pName, "app-name")) { *pPropID = PROP_APP_NAME; } else if (!strcasecmp((char *)pName, "procid")) { *pPropID = PROP_PROCID; } else if (!strcasecmp((char *)pName, "msgid")) { *pPropID = PROP_MSGID; } else if (!strcasecmp((char *)pName, "jsonmesg")) { *pPropID = PROP_JSONMESG; } else if (!strcasecmp((char *)pName, "parsesuccess")) { *pPropID = PROP_PARSESUCCESS; #ifdef USE_LIBUUID } else if (!strcasecmp((char *)pName, "uuid")) { *pPropID = PROP_UUID; #endif /* here start system properties (those, that do not relate to the message itself */ } else if (!strcasecmp((char *)pName, "$NOW")) { *pPropID = PROP_SYS_NOW; } else if (!strcasecmp((char *)pName, "$YEAR")) { *pPropID = PROP_SYS_YEAR; } else if (!strcasecmp((char *)pName, "$MONTH")) { *pPropID = PROP_SYS_MONTH; } else if (!strcasecmp((char *)pName, "$DAY")) { *pPropID = PROP_SYS_DAY; } else if (!strcasecmp((char *)pName, "$HOUR")) { *pPropID = PROP_SYS_HOUR; } else if (!strcasecmp((char *)pName, "$HHOUR")) { *pPropID = PROP_SYS_HHOUR; } else if (!strcasecmp((char *)pName, "$QHOUR")) { *pPropID = PROP_SYS_QHOUR; } else if (!strcasecmp((char *)pName, "$MINUTE")) { *pPropID = PROP_SYS_MINUTE; } else if (!strcasecmp((char *)pName, "$WDAY")) { *pPropID = PROP_SYS_WDAY; } else if (!strcasecmp((char *)pName, "$now-utc")) { *pPropID = PROP_SYS_NOW_UTC; } else if (!strcasecmp((char *)pName, "$year-utc")) { *pPropID = PROP_SYS_YEAR_UTC; } else if (!strcasecmp((char *)pName, "$month-utc")) { *pPropID = PROP_SYS_MONTH_UTC; } else if (!strcasecmp((char *)pName, "$day-utc")) { *pPropID = PROP_SYS_DAY_UTC; } else if (!strcasecmp((char *)pName, "$hour-utc")) { *pPropID = PROP_SYS_HOUR_UTC; } else if (!strcasecmp((char *)pName, "$hhour-utc")) { *pPropID = PROP_SYS_HHOUR_UTC; } else if (!strcasecmp((char *)pName, "$qhour-utc")) { *pPropID = PROP_SYS_QHOUR_UTC; } else if (!strcasecmp((char *)pName, "$minute-utc")) { *pPropID = PROP_SYS_MINUTE_UTC; } else if (!strcasecmp((char *)pName, "$wday-utc")) { *pPropID = PROP_SYS_WDAY_UTC; } else if (!strcasecmp((char *)pName, "$now-unixtimestamp")) { *pPropID = PROP_SYS_NOW_UXTIMESTAMP; } else if (!strcasecmp((char *)pName, "$MYHOSTNAME")) { *pPropID = PROP_SYS_MYHOSTNAME; } else if (!strcasecmp((char *)pName, "$!all-json")) { *pPropID = PROP_CEE_ALL_JSON; } else if (!strcasecmp((char *)pName, "$!all-json-plain")) { *pPropID = PROP_CEE_ALL_JSON_PLAIN; } else if (!strcasecmp((char *)pName, "$BOM")) { *pPropID = PROP_SYS_BOM; } else if (!strcasecmp((char *)pName, "$UPTIME")) { *pPropID = PROP_SYS_UPTIME; } else if (!strncmp((char *)pName, "$!", 2) || pName[0] == '!') { *pPropID = PROP_CEE; } else if (!strncmp((char *)pName, "$.", 2) || pName[0] == '.') { *pPropID = PROP_LOCAL_VAR; } else if (!strncmp((char *)pName, "$/", 2) || pName[0] == '/') { *pPropID = PROP_GLOBAL_VAR; } else { DBGPRINTF("PROP_INVALID for name '%s'\n", pName); *pPropID = PROP_INVALID; iRet = RS_RET_VAR_NOT_FOUND; } RETiRet; } /* map a property ID to a name string (useful for displaying) */ uchar *propIDToName(propid_t propID) { switch (propID) { case PROP_MSG: return UCHAR_CONSTANT("msg"); case PROP_TIMESTAMP: return UCHAR_CONSTANT("timestamp"); case PROP_HOSTNAME: return UCHAR_CONSTANT("hostname"); case PROP_SYSLOGTAG: return UCHAR_CONSTANT("syslogtag"); case PROP_RAWMSG: return UCHAR_CONSTANT("rawmsg"); case PROP_RAWMSG_AFTER_PRI: return UCHAR_CONSTANT("rawmsg-after-pri"); case PROP_INPUTNAME: return UCHAR_CONSTANT("inputname"); case PROP_FROMHOST: return UCHAR_CONSTANT("fromhost"); case PROP_FROMHOST_IP: return UCHAR_CONSTANT("fromhost-ip"); case PROP_FROMHOST_PORT: return UCHAR_CONSTANT("fromhost-port"); case PROP_PRI: return UCHAR_CONSTANT("pri"); case PROP_PRI_TEXT: return UCHAR_CONSTANT("pri-text"); case PROP_IUT: return UCHAR_CONSTANT("iut"); case PROP_SYSLOGFACILITY: return UCHAR_CONSTANT("syslogfacility"); case PROP_SYSLOGFACILITY_TEXT: return UCHAR_CONSTANT("syslogfacility-text"); case PROP_SYSLOGSEVERITY: return UCHAR_CONSTANT("syslogseverity"); case PROP_SYSLOGSEVERITY_TEXT: return UCHAR_CONSTANT("syslogseverity-text"); case PROP_TIMEGENERATED: return UCHAR_CONSTANT("timegenerated"); case PROP_PROGRAMNAME: return UCHAR_CONSTANT("programname"); case PROP_PROTOCOL_VERSION: return UCHAR_CONSTANT("protocol-version"); case PROP_STRUCTURED_DATA: return UCHAR_CONSTANT("structured-data"); case PROP_APP_NAME: return UCHAR_CONSTANT("app-name"); case PROP_PROCID: return UCHAR_CONSTANT("procid"); case PROP_MSGID: return UCHAR_CONSTANT("msgid"); case PROP_JSONMESG: return UCHAR_CONSTANT("jsonmesg"); case PROP_PARSESUCCESS: return UCHAR_CONSTANT("parsesuccess"); #ifdef USE_LIBUUID case PROP_UUID: return UCHAR_CONSTANT("uuid"); #endif case PROP_SYS_NOW: return UCHAR_CONSTANT("$NOW"); case PROP_SYS_YEAR: return UCHAR_CONSTANT("$YEAR"); case PROP_SYS_MONTH: return UCHAR_CONSTANT("$MONTH"); case PROP_SYS_DAY: return UCHAR_CONSTANT("$DAY"); case PROP_SYS_HOUR: return UCHAR_CONSTANT("$HOUR"); case PROP_SYS_HHOUR: return UCHAR_CONSTANT("$HHOUR"); case PROP_SYS_QHOUR: return UCHAR_CONSTANT("$QHOUR"); case PROP_SYS_MINUTE: return UCHAR_CONSTANT("$MINUTE"); case PROP_SYS_NOW_UTC: return UCHAR_CONSTANT("$NOW-UTC"); case PROP_SYS_YEAR_UTC: return UCHAR_CONSTANT("$YEAR-UTC"); case PROP_SYS_MONTH_UTC: return UCHAR_CONSTANT("$MONTH-UTC"); case PROP_SYS_DAY_UTC: return UCHAR_CONSTANT("$DAY-UTC"); case PROP_SYS_HOUR_UTC: return UCHAR_CONSTANT("$HOUR-UTC"); case PROP_SYS_HHOUR_UTC: return UCHAR_CONSTANT("$HHOUR-UTC"); case PROP_SYS_QHOUR_UTC: return UCHAR_CONSTANT("$QHOUR-UTC"); case PROP_SYS_MINUTE_UTC: return UCHAR_CONSTANT("$MINUTE-UTC"); case PROP_SYS_WDAY: return UCHAR_CONSTANT("$WDAY"); case PROP_SYS_WDAY_UTC: return UCHAR_CONSTANT("$WDAY-UTC"); case PROP_SYS_NOW_UXTIMESTAMP: return UCHAR_CONSTANT("$NOW-UNIXTIMESTAMP"); case PROP_SYS_MYHOSTNAME: return UCHAR_CONSTANT("$MYHOSTNAME"); case PROP_CEE_ALL_JSON: return UCHAR_CONSTANT("$!all-json"); case PROP_CEE_ALL_JSON_PLAIN: return UCHAR_CONSTANT("$!all-json-plain"); case PROP_SYS_BOM: return UCHAR_CONSTANT("$BOM"); case PROP_SYS_UPTIME: return UCHAR_CONSTANT("$UPTIME"); case PROP_CEE: return UCHAR_CONSTANT("*CEE-based property*"); case PROP_LOCAL_VAR: return UCHAR_CONSTANT("*LOCAL_VARIABLE*"); case PROP_GLOBAL_VAR: return UCHAR_CONSTANT("*GLOBAL_VARIABLE*"); default: return UCHAR_CONSTANT("*invalid property id*"); } } /* This is common code for all Constructors. It is defined in an * inline'able function so that we can save a function call in the * actual constructors (otherwise, the msgConstruct would need * to call msgConstructWithTime(), which would require a * function call). Now, both can use this inline function. This * enables us to be optimal, but still have the code just once. * the new object or NULL if no such object could be allocated. * An object constructed via this function should only be destroyed * via "msgDestruct()". This constructor does not query system time * itself but rather uses a user-supplied value. This enables the caller * to do some tricks to save processing time (done, for example, in the * udp input). * NOTE: this constructor does NOT call calloc(), as we have many bytes * inside the structure which do not need to be cleared. bzero() will * heavily thrash the cache, so we do the init manually (which also * is the right thing to do with pointers, as they are not neccessarily * a binary 0 on all machines [but today almost always...]). * rgerhards, 2008-10-06 */ static rsRetVal msgBaseConstruct(smsg_t **ppThis) { DEFiRet; smsg_t *pM; assert(ppThis != NULL); CHKmalloc(pM = malloc(sizeof(smsg_t))); objConstructSetObjInfo(pM); /* initialize object helper entities */ /* initialize members in ORDER they appear in structure (think "cache line"!) */ pM->flowCtlType = 0; pM->bParseSuccess = 0; pM->iRefCount = 1; pM->iSeverity = LOG_DEBUG; pM->iFacility = LOG_INVLD; pM->iLenPROGNAME = -1; pM->offAfterPRI = 0; pM->offMSG = -1; pM->iProtocolVersion = 0; pM->msgFlags = 0; pM->iLenRawMsg = 0; pM->iLenMSG = 0; pM->iLenTAG = 0; pM->iLenHOSTNAME = 0; pM->pszRawMsg = NULL; pM->pszHOSTNAME = NULL; pM->pszRcvdAt3164 = NULL; pM->pszRcvdAt3339 = NULL; pM->pszRcvdAt_MySQL = NULL; pM->pszRcvdAt_PgSQL = NULL; pM->pszTIMESTAMP3164 = NULL; pM->pszTIMESTAMP3339 = NULL; pM->pszTIMESTAMP_MySQL = NULL; pM->pszTIMESTAMP_PgSQL = NULL; pM->pszStrucData = NULL; pM->lenStrucData = 0; pM->pCSAPPNAME = NULL; pM->pCSPROCID = NULL; pM->pCSMSGID = NULL; pM->pInputName = NULL; pM->pRcvFromIP = NULL; pM->pRcvFromPort = NULL; pM->rcvFrom.pRcvFrom = NULL; pM->pRuleset = NULL; pM->json = NULL; pM->localvars = NULL; pM->dfltTZ[0] = '\0'; memset(&pM->tRcvdAt, 0, sizeof(pM->tRcvdAt)); memset(&pM->tTIMESTAMP, 0, sizeof(pM->tTIMESTAMP)); pM->TAG.pszTAG = NULL; pM->pszTimestamp3164[0] = '\0'; pM->pszTimestamp3339[0] = '\0'; pM->pszTIMESTAMP_SecFrac[0] = '\0'; pM->pszRcvdAt_SecFrac[0] = '\0'; pM->pszTIMESTAMP_Unix[0] = '\0'; pM->pszRcvdAt_Unix[0] = '\0'; pM->pszUUID = NULL; pthread_mutex_init(&pM->mut, NULL); #if DEV_DEBUG == 1 dbgprintf("msgConstruct\t0x%x, ref 1\n", (int)pM); #endif *ppThis = pM; finalize_it: RETiRet; } /* "Constructor" for a msg "object". Returns a pointer to * the new object or NULL if no such object could be allocated. * An object constructed via this function should only be destroyed * via "msgDestruct()". This constructor does not query system time * itself but rather uses a user-supplied value. This enables the caller * to do some tricks to save processing time (done, for example, in the * udp input). * rgerhards, 2008-10-06 */ rsRetVal msgConstructWithTime(smsg_t **ppThis, const struct syslogTime *stTime, const time_t ttGenTime) { DEFiRet; CHKiRet(msgBaseConstruct(ppThis)); (*ppThis)->ttGenTime = ttGenTime; memcpy(&(*ppThis)->tRcvdAt, stTime, sizeof(struct syslogTime)); memcpy(&(*ppThis)->tTIMESTAMP, stTime, sizeof(struct syslogTime)); finalize_it: RETiRet; } /* "Constructor" for a msg "object". Returns a pointer to * the new object or NULL if no such object could be allocated. * An object constructed via this function should only be destroyed * via "msgDestruct()". This constructor, for historical reasons, * also sets the two timestamps to the current time. */ rsRetVal msgConstruct(smsg_t **ppThis) { DEFiRet; CHKiRet(msgBaseConstruct(ppThis)); /* we initialize both timestamps to contain the current time, so that they * are consistent. Also, this saves us from doing any further time calls just * to obtain a timestamp. The memcpy() should not really make a difference, * especially as I think there is no codepath currently where it would not be * required (after I have cleaned up the pathes ;)). -- rgerhards, 2008-10-02 */ datetime.getCurrTime(&((*ppThis)->tRcvdAt), &((*ppThis)->ttGenTime), TIME_IN_LOCALTIME); memcpy(&(*ppThis)->tTIMESTAMP, &(*ppThis)->tRcvdAt, sizeof(struct syslogTime)); finalize_it: RETiRet; } /* Special msg constructor, to be used when an object is deserialized. * we do only the base init as we know the properties will be set in * any case by the deserializer. We still do the "inexpensive" inits * just to be on the safe side. The whole process needs to be * refactored together with the msg serialization subsystem. */ rsRetVal msgConstructForDeserializer(smsg_t **ppThis) { return msgBaseConstruct(ppThis); } /* some free handlers for (slightly) complicated cases... All of them may be called * with an empty element. */ static inline void freeTAG(smsg_t *pThis) { if (pThis->iLenTAG >= CONF_TAG_BUFSIZE) free(pThis->TAG.pszTAG); } static inline void freeHOSTNAME(smsg_t *pThis) { if (pThis->iLenHOSTNAME >= CONF_HOSTNAME_BUFSIZE) free(pThis->pszHOSTNAME); } rsRetVal msgDestruct(smsg_t **ppThis) { DEFiRet; smsg_t *pThis; int currRefCount; #ifdef HAVE_MALLOC_TRIM int currCnt; #endif CODESTARTobjDestruct(msg); #if DEV_DEBUG == 1 dbgprintf( "msgDestruct\t0x%lx, " "Ref now: %d\n", (unsigned long)pThis, pThis->iRefCount - 1); #endif #ifdef HAVE_ATOMIC_BUILTINS currRefCount = ATOMIC_DEC_AND_FETCH(&pThis->iRefCount, NULL); #else MsgLock(pThis); currRefCount = --pThis->iRefCount; #endif if (currRefCount == 0) { #if DEV_DEBUG == 1 dbgprintf("msgDestruct\t0x%lx, RefCount now 0, doing DESTROY\n", (unsigned long)pThis); #endif if (pThis->pszRawMsg != pThis->szRawMsg) free(pThis->pszRawMsg); freeTAG(pThis); freeHOSTNAME(pThis); if (pThis->pInputName != NULL) prop.Destruct(&pThis->pInputName); if ((pThis->msgFlags & NEEDS_DNSRESOL) == 0) { if (pThis->rcvFrom.pRcvFrom != NULL) prop.Destruct(&pThis->rcvFrom.pRcvFrom); } else { free(pThis->rcvFrom.pfrominet); } if (pThis->pRcvFromIP != NULL) prop.Destruct(&pThis->pRcvFromIP); if (pThis->pRcvFromPort != NULL) prop.Destruct(&pThis->pRcvFromPort); free(pThis->pszRcvdAt3164); free(pThis->pszRcvdAt3339); free(pThis->pszRcvdAt_MySQL); free(pThis->pszRcvdAt_PgSQL); free(pThis->pszTIMESTAMP_MySQL); free(pThis->pszTIMESTAMP_PgSQL); free(pThis->pszStrucData); if (pThis->iLenPROGNAME >= CONF_PROGNAME_BUFSIZE) free(pThis->PROGNAME.ptr); if (pThis->pCSAPPNAME != NULL) rsCStrDestruct(&pThis->pCSAPPNAME); if (pThis->pCSPROCID != NULL) rsCStrDestruct(&pThis->pCSPROCID); if (pThis->pCSMSGID != NULL) rsCStrDestruct(&pThis->pCSMSGID); if (pThis->json != NULL) json_object_put(pThis->json); if (pThis->localvars != NULL) json_object_put(pThis->localvars); if (pThis->pszUUID != NULL) free(pThis->pszUUID); #ifndef HAVE_ATOMIC_BUILTINS MsgUnlock(pThis); #endif pthread_mutex_destroy(&pThis->mut); /* now we need to do our own optimization. Testing has shown that at least the glibc * malloc() subsystem returns memory to the OS far too late in our case. So we need * to help it a bit, by calling malloc_trim(), which will tell the alloc subsystem * to consolidate and return to the OS. We keep 128K for our use, as a safeguard * to too-frequent reallocs. But more importantly, we call this hook only every * 100,000 messages (which is an approximation, as we do not work with atomic * operations on the counter. --- rgerhards, 2009-06-22. */ #ifdef HAVE_MALLOC_TRIM { /* standard C requires a new block for a new variable definition! * To simplify matters, we use modulo arithmetic and live with the fact * that we trim too often when the counter wraps. */ static unsigned iTrimCtr = 1; currCnt = ATOMIC_INC_AND_FETCH_unsigned(&iTrimCtr, &mutTrimCtr); if (currCnt % 100000 == 0) { malloc_trim(128 * 1024); } } #endif } else { #ifndef HAVE_ATOMIC_BUILTINS MsgUnlock(pThis); #endif pThis = NULL; /* tell framework not to destructing the object! */ } ENDobjDestruct (msg) /* The macros below are used in MsgDup(). I use macros * to keep the fuction code somewhat more readyble. It is my * replacement for inline functions in CPP */ #define tmpCOPYSZ(name) \ if (pOld->psz##name != NULL) { \ if ((pNew->psz##name = srUtilStrDup(pOld->psz##name, pOld->iLen##name)) == NULL) { \ msgDestruct(&pNew); \ return NULL; \ } \ pNew->iLen##name = pOld->iLen##name; \ } /* copy the CStr objects. * if the old value is NULL, we do not need to do anything because we * initialized the new value to NULL via calloc(). */ #define tmpCOPYCSTR(name) \ if (pOld->pCS##name != NULL) { \ if (rsCStrConstructFromCStr(&(pNew->pCS##name), pOld->pCS##name) != RS_RET_OK) { \ msgDestruct(&pNew); \ return NULL; \ } \ cstrFinalize(pNew->pCS##name); \ } /* Constructs a message object by duplicating another one. * Returns NULL if duplication failed. We do not need to lock the * message object here, because a fully-created msg object is never * allowed to be manipulated. For this, MsgDup() must be used, so MsgDup() * can never run into a situation where the message object is being * modified while its content is copied - it's forbidden by definition. * rgerhards, 2007-07-10 */ smsg_t *MsgDup(smsg_t *pOld) { smsg_t *pNew; rsRetVal localRet; assert(pOld != NULL); if (msgConstructWithTime(&pNew, &pOld->tTIMESTAMP, pOld->ttGenTime) != RS_RET_OK) { return NULL; } /* now copy the message properties */ pNew->iRefCount = 1; pNew->iSeverity = pOld->iSeverity; pNew->iFacility = pOld->iFacility; pNew->msgFlags = pOld->msgFlags; pNew->iProtocolVersion = pOld->iProtocolVersion; pNew->tRcvdAt = pOld->tRcvdAt; pNew->offMSG = pOld->offMSG; pNew->iLenRawMsg = pOld->iLenRawMsg; pNew->iLenMSG = pOld->iLenMSG; pNew->iLenTAG = pOld->iLenTAG; pNew->iLenHOSTNAME = pOld->iLenHOSTNAME; if ((pOld->msgFlags & NEEDS_DNSRESOL)) { localRet = msgSetFromSockinfo(pNew, pOld->rcvFrom.pfrominet); if (localRet != RS_RET_OK) { /* if something fails, we accept loss of this property, it is * better than losing the whole message. */ pNew->msgFlags &= ~NEEDS_DNSRESOL; pNew->rcvFrom.pRcvFrom = NULL; /* make sure no dangling values */ } } else { if (pOld->rcvFrom.pRcvFrom != NULL) { pNew->rcvFrom.pRcvFrom = pOld->rcvFrom.pRcvFrom; prop.AddRef(pNew->rcvFrom.pRcvFrom); } } if (pOld->pRcvFromIP != NULL) { pNew->pRcvFromIP = pOld->pRcvFromIP; prop.AddRef(pNew->pRcvFromIP); } if (pOld->pRcvFromPort != NULL) { pNew->pRcvFromPort = pOld->pRcvFromPort; prop.AddRef(pNew->pRcvFromPort); } if (pOld->pInputName != NULL) { pNew->pInputName = pOld->pInputName; prop.AddRef(pNew->pInputName); } if (pOld->iLenTAG > 0) { if (pOld->iLenTAG < CONF_TAG_BUFSIZE) { memcpy(pNew->TAG.szBuf, pOld->TAG.szBuf, pOld->iLenTAG + 1); } else { if ((pNew->TAG.pszTAG = srUtilStrDup(pOld->TAG.pszTAG, pOld->iLenTAG)) == NULL) { msgDestruct(&pNew); return NULL; } pNew->iLenTAG = pOld->iLenTAG; } } if (pOld->pszRawMsg == pOld->szRawMsg) { memcpy(pNew->szRawMsg, pOld->szRawMsg, pOld->iLenRawMsg + 1); pNew->pszRawMsg = pNew->szRawMsg; } else { tmpCOPYSZ(RawMsg); } if (pOld->pszHOSTNAME == NULL) { pNew->pszHOSTNAME = NULL; } else { if (pOld->iLenHOSTNAME < CONF_HOSTNAME_BUFSIZE) { memcpy(pNew->szHOSTNAME, pOld->szHOSTNAME, pOld->iLenHOSTNAME + 1); pNew->pszHOSTNAME = pNew->szHOSTNAME; } else { tmpCOPYSZ(HOSTNAME); } } if (pOld->pszStrucData == NULL) { pNew->pszStrucData = NULL; } else { pNew->pszStrucData = (uchar *)strdup((char *)pOld->pszStrucData); pNew->lenStrucData = pOld->lenStrucData; } tmpCOPYCSTR(APPNAME); tmpCOPYCSTR(PROCID); tmpCOPYCSTR(MSGID); if (pOld->json != NULL) pNew->json = jsonDeepCopy(pOld->json); if (pOld->localvars != NULL) pNew->localvars = jsonDeepCopy(pOld->localvars); /* we do not copy all other cache properties, as we do not even know * if they are needed once again. So we let them re-create if needed. */ return pNew; } #undef tmpCOPYSZ #undef tmpCOPYCSTR /* Return a textual representation of @json. * * The pointer is owned by @json; do NOT free it. * To keep the string beyond the next mutation, serialization call, * or destruction of @json, make a copy (e.g., strdup()). */ static const char *jsonToString(struct json_object *const json) { if (!json) { return NULL; } if (json_object_get_type(json) == json_type_string) { /* Direct pointer to internal string storage. * - Stable across repeated json_object_get_string() calls. * - Invalidated once the object is modified or fjson_object_put(). */ return json_object_get_string(json); } /* Non-string types serialize into json->_pb. * - json->_pb is reset/overwritten on every serialization or mutation. * - The returned pointer becomes invalid immediately after that. */ return json_object_to_json_string_ext(json, glblJsonFormatOpt); } /* This method serializes a message object. That means the whole * object is modified into text form. That text form is suitable for * later reconstruction of the object by calling MsgDeSerialize(). * The most common use case for this method is the creation of an * on-disk representation of the message object. * We do not serialize the cache properties. We re-create them when needed. * This saves us a lot of memory. Performance is no concern, as serializing * is a so slow operation that recration of the caches does not count. Also, * we do not serialize --currently none--, as this is only a helper variable * during msg construction - and never again used later. * rgerhards, 2008-01-03 */ static rsRetVal MsgSerialize(smsg_t *pThis, strm_t *pStrm) { uchar *psz; int len; DEFiRet; assert(pThis != NULL); assert(pStrm != NULL); /* then serialize elements */ CHKiRet(obj.BeginSerialize(pStrm, (obj_t *)pThis)); objSerializeSCALAR(pStrm, iProtocolVersion, SHORT); objSerializeSCALAR(pStrm, iSeverity, SHORT); objSerializeSCALAR(pStrm, iFacility, SHORT); objSerializeSCALAR(pStrm, msgFlags, INT); objSerializeSCALAR(pStrm, ttGenTime, INT); objSerializeSCALAR(pStrm, tRcvdAt, SYSLOGTIME); objSerializeSCALAR(pStrm, tTIMESTAMP, SYSLOGTIME); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszTAG"), PROPTYPE_PSZ, (void *)((pThis->iLenTAG < CONF_TAG_BUFSIZE) ? pThis->TAG.szBuf : pThis->TAG.pszTAG))); objSerializePTR(pStrm, pszRawMsg, PSZ); objSerializePTR(pStrm, pszHOSTNAME, PSZ); getInputName(pThis, &psz, &len); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszInputName"), PROPTYPE_PSZ, (void *)psz)); psz = getRcvFrom(pThis); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRcvFrom"), PROPTYPE_PSZ, (void *)psz)); psz = getRcvFromIP(pThis); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRcvFromIP"), PROPTYPE_PSZ, (void *)psz)); psz = pThis->pszStrucData; CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszStrucData"), PROPTYPE_PSZ, (void *)psz)); if (pThis->json != NULL) { MsgLock(pThis); psz = (uchar *)jsonToString(pThis->json); MsgUnlock(pThis); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("json"), PROPTYPE_PSZ, (void *)psz)); } if (pThis->localvars != NULL) { MsgLock(pThis); psz = (uchar *)jsonToString(pThis->localvars); MsgUnlock(pThis); CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("localvars"), PROPTYPE_PSZ, (void *)psz)); } objSerializePTR(pStrm, pCSAPPNAME, CSTR); objSerializePTR(pStrm, pCSPROCID, CSTR); objSerializePTR(pStrm, pCSMSGID, CSTR); objSerializePTR(pStrm, pszUUID, PSZ); if (pThis->pRuleset != NULL) { CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRuleset"), PROPTYPE_PSZ, rulesetGetName(pThis->pRuleset))); } /* offset must be serialized after pszRawMsg, because we need that to obtain the correct * MSG size. */ objSerializeSCALAR(pStrm, offMSG, INT); CHKiRet(obj.EndSerialize(pStrm)); finalize_it: RETiRet; } /* This is a helper for MsgDeserialize that re-inits the var object. This * whole construct should be replaced, var is really ready to be retired. * But as an interim help during refactoring let's introduce this function * here (and thus NOT as method of var object!). -- rgerhads, 2012-11-06 */ static void reinitVar(var_t *pVar) { rsCStrDestruct(&pVar->pcsName); /* no longer needed */ if (pVar->varType == VARTYPE_STR) { if (pVar->val.pStr != NULL) rsCStrDestruct(&pVar->val.pStr); } } /* deserialize the message again * we deserialize the properties in the same order that we serialized them. Except * for some checks to cover downlevel version, we do not need to do all these * CPU intense name checkings. */ #define isProp(name) !rsCStrSzStrCmp(pVar->pcsName, (uchar *)name, sizeof(name) - 1) rsRetVal MsgDeserialize(smsg_t *const pMsg, strm_t *pStrm) { prop_t *myProp; prop_t *propRcvFrom = NULL; prop_t *propRcvFromIP = NULL; struct json_tokener *tokener; var_t *pVar = NULL; DEFiRet; ISOBJ_TYPE_assert(pStrm, strm); CHKiRet(var.Construct(&pVar)); CHKiRet(var.ConstructFinalize(pVar)); CHKiRet(objDeserializeProperty(pVar, pStrm)); if (isProp("iProtocolVersion")) { setProtocolVersion(pMsg, pVar->val.num); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("iSeverity")) { pMsg->iSeverity = pVar->val.num; reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("iFacility")) { pMsg->iFacility = pVar->val.num; reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("msgFlags")) { pMsg->msgFlags = pVar->val.num; reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("ttGenTime")) { pMsg->ttGenTime = pVar->val.num; reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("tRcvdAt")) { memcpy(&pMsg->tRcvdAt, &pVar->val.vSyslogTime, sizeof(struct syslogTime)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("tTIMESTAMP")) { memcpy(&pMsg->tTIMESTAMP, &pVar->val.vSyslogTime, sizeof(struct syslogTime)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszTAG")) { MsgSetTAG(pMsg, rsCStrGetSzStrNoNULL(pVar->val.pStr), cstrLen(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszRawMsg")) { MsgSetRawMsg(pMsg, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr), cstrLen(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszHOSTNAME")) { MsgSetHOSTNAME(pMsg, rsCStrGetSzStrNoNULL(pVar->val.pStr), rsCStrLen(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszInputName")) { /* we need to create a property */ CHKiRet(prop.Construct(&myProp)); CHKiRet(prop.SetString(myProp, rsCStrGetSzStrNoNULL(pVar->val.pStr), rsCStrLen(pVar->val.pStr))); CHKiRet(prop.ConstructFinalize(myProp)); MsgSetInputName(pMsg, myProp); prop.Destruct(&myProp); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszRcvFrom")) { MsgSetRcvFromStr(pMsg, rsCStrGetSzStrNoNULL(pVar->val.pStr), rsCStrLen(pVar->val.pStr), &propRcvFrom); prop.Destruct(&propRcvFrom); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszRcvFromIP")) { MsgSetRcvFromIPStr(pMsg, rsCStrGetSzStrNoNULL(pVar->val.pStr), rsCStrLen(pVar->val.pStr), &propRcvFromIP); prop.Destruct(&propRcvFromIP); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszStrucData")) { MsgSetStructuredData(pMsg, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("json")) { tokener = json_tokener_new(); pMsg->json = json_tokener_parse_ex(tokener, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr), cstrLen(pVar->val.pStr)); json_tokener_free(tokener); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("localvars")) { tokener = json_tokener_new(); pMsg->localvars = json_tokener_parse_ex(tokener, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr), cstrLen(pVar->val.pStr)); json_tokener_free(tokener); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pCSAPPNAME")) { MsgSetAPPNAME(pMsg, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pCSPROCID")) { MsgSetPROCID(pMsg, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pCSMSGID")) { MsgSetMSGID(pMsg, (char *)rsCStrGetSzStrNoNULL(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszUUID")) { pMsg->pszUUID = ustrdup(rsCStrGetSzStrNoNULL(pVar->val.pStr)); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } if (isProp("pszRuleset")) { MsgSetRulesetByName(pMsg, pVar->val.pStr); reinitVar(pVar); CHKiRet(objDeserializeProperty(pVar, pStrm)); } /* "offMSG" must always be our last field, so we use this as an * indicator if the sequence is correct. This is a bit questionable, * but on the other hand it works decently AND we will probably replace * the whole persisted format soon in any case. -- rgerhards, 2012-11-06 */ if (!isProp("offMSG")) { DBGPRINTF("error property: %s\n", rsCStrGetSzStrNoNULL(pVar->pcsName)); ABORT_FINALIZE(RS_RET_DS_PROP_SEQ_ERR); } MsgSetMSGoffs(pMsg, pVar->val.num); finalize_it: if (pVar != NULL) var.Destruct(&pVar); if (Debug && iRet != RS_RET_OK) { dbgprintf("MsgDeserialize error %d\n", iRet); } RETiRet; } #undef isProp /* Increment reference count - see description of the "msg" * structure for details. As a convenience to developers, * this method returns the msg pointer that is passed to it. * It is recommended that it is called as follows: * * pSecondMsgPointer = MsgAddRef(pOrgMsgPointer); */ smsg_t *MsgAddRef(smsg_t *const pM) { assert(pM != NULL); #ifdef HAVE_ATOMIC_BUILTINS ATOMIC_INC(&pM->iRefCount, NULL); #else MsgLock(pM); pM->iRefCount++; MsgUnlock(pM); #endif #if DEV_DEBUG == 1 dbgprintf("MsgAddRef\t0x%x done, Ref now: %d\n", (int)pM, pM->iRefCount); #endif return (pM); } /* This functions tries to acquire the PROCID from TAG. Its primary use is * when a legacy syslog message has been received and should be forwarded as * syslog-protocol (or the PROCID is requested for any other reason). * In legacy syslog, the PROCID is considered to be the character sequence * between the first [ and the first ]. This usually are digits only, but we * do not check that. However, if there is no closing ], we do not assume we * can obtain a PROCID. Take in mind that not every legacy syslog message * actually has a PROCID. * rgerhards, 2005-11-24 * THIS MUST be called with the message lock locked. */ static rsRetVal acquirePROCIDFromTAG(smsg_t *const pM) { register int i; uchar *pszTag; DEFiRet; assert(pM != NULL); if (pM->pCSPROCID != NULL) return RS_RET_OK; /* we are already done ;) */ if (msgGetProtocolVersion(pM) != 0) return RS_RET_OK; /* we can only emulate if we have legacy format */ pszTag = (uchar *)((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG); /* find first '['... */ i = 0; while ((i < pM->iLenTAG) && (pszTag[i] != '[')) ++i; if (!(i < pM->iLenTAG)) return RS_RET_OK; /* no [, so can not emulate... */ ++i; /* skip '[' */ /* now obtain the PROCID string... */ CHKiRet(cstrConstruct(&pM->pCSPROCID)); while ((i < pM->iLenTAG) && (pszTag[i] != ']')) { CHKiRet(cstrAppendChar(pM->pCSPROCID, pszTag[i])); ++i; } if (!(i < pM->iLenTAG)) { /* oops... it looked like we had a PROCID, but now it has * turned out this is not true. In this case, we need to free * the buffer and simply return. Note that this is NOT an error * case! */ cstrDestruct(&pM->pCSPROCID); FINALIZE; } /* OK, finally we could obtain a PROCID. So let's use it ;) */ cstrFinalize(pM->pCSPROCID); finalize_it: RETiRet; } /* Parse and set the "programname" for a given MSG object. Programname * is a BSD concept, it is the tag without any instance-specific information. * Precisely, the programname is terminated by either (whichever occurs first): * - end of tag * - nonprintable character * - ':' * - '[' * - '/' * The above definition has been taken from the FreeBSD syslogd sources. * * The program name is not parsed by default, because it is infrequently-used. * IMPORTANT: A locked message object must be provided, else a crash will occur. * rgerhards, 2005-10-19 */ static rsRetVal acquireProgramName(smsg_t *const pM) { int i; uchar *pszTag, *pszProgName; DEFiRet; assert(pM != NULL); pszTag = (uchar *)((pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG); for (i = 0; (i < pM->iLenTAG) && isprint((int)pszTag[i]) && (pszTag[i] != '\0') && (pszTag[i] != ':') && (pszTag[i] != '[') && (runConf->globals.parser.bPermitSlashInProgramname || (pszTag[i] != '/')); ++i); /* just search end of PROGNAME */ if (i < CONF_PROGNAME_BUFSIZE) { pszProgName = pM->PROGNAME.szBuf; } else { CHKmalloc(pM->PROGNAME.ptr = malloc(i + 1)); pszProgName = pM->PROGNAME.ptr; } memcpy((char *)pszProgName, (char *)pszTag, i); pszProgName[i] = '\0'; pM->iLenPROGNAME = i; finalize_it: RETiRet; } /* Access methods - dumb & easy, not a comment for each ;) */ void setProtocolVersion(smsg_t *const pM, int iNewVersion) { assert(pM != NULL); if (iNewVersion != 0 && iNewVersion != 1) { dbgprintf("Tried to set unsupported protocol version %d - changed to 0.\n", iNewVersion); iNewVersion = 0; } pM->iProtocolVersion = iNewVersion; } /* note: string is taken from constant pool, do NOT free */ static const char *getProtocolVersionString(smsg_t *const pM) { assert(pM != NULL); return (pM->iProtocolVersion ? "1" : "0"); } void msgSetPRI(smsg_t *const __restrict__ pMsg, syslog_pri_t pri) { if (pri > LOG_MAXPRI) pri = LOG_PRI_INVLD; pMsg->iFacility = pri2fac(pri), pMsg->iSeverity = pri2sev(pri); } #ifdef USE_LIBUUID /* note: libuuid seems not to be thread-safe, so we need * to get some safeguards in place. */ static pthread_mutex_t mutUUID = PTHREAD_MUTEX_INITIALIZER; static void call_uuid_generate(uuid_t uuid) { pthread_mutex_lock(&mutUUID); pthread_cleanup_push(mutexCancelCleanup, &mutUUID); uuid_generate(uuid); pthread_cleanup_pop(1); } static void msgSetUUID(smsg_t *const pM) { size_t lenRes = sizeof(uuid_t) * 2 + 1; char hex_char[] = "0123456789ABCDEF"; unsigned int byte_nbr; uuid_t uuid; dbgprintf("[MsgSetUUID] START, lenRes %llu\n", (long long unsigned)lenRes); assert(pM != NULL); if ((pM->pszUUID = (uchar *)malloc(lenRes)) == NULL) { pM->pszUUID = (uchar *)""; } else { call_uuid_generate(uuid); for (byte_nbr = 0; byte_nbr < sizeof(uuid_t); byte_nbr++) { pM->pszUUID[byte_nbr * 2 + 0] = hex_char[uuid[byte_nbr] >> 4]; pM->pszUUID[byte_nbr * 2 + 1] = hex_char[uuid[byte_nbr] & 15]; } pM->pszUUID[lenRes - 1] = '\0'; dbgprintf("[MsgSetUUID] UUID : %s LEN: %d \n", pM->pszUUID, (int)lenRes); } dbgprintf("[MsgSetUUID] END\n"); } static void getUUID(smsg_t *const pM, uchar **pBuf, int *piLen) { dbgprintf("[getUUID] START\n"); if (pM == NULL) { dbgprintf("[getUUID] pM is NULL\n"); *pBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { if (pM->pszUUID == NULL) { dbgprintf("[getUUID] pM->pszUUID is NULL\n"); MsgLock(pM); /* re-query, things may have changed in the mean time... */ if (pM->pszUUID == NULL) msgSetUUID(pM); MsgUnlock(pM); } else { /* UUID already there we reuse it */ dbgprintf("[getUUID] pM->pszUUID already exists\n"); } *pBuf = pM->pszUUID; *piLen = sizeof(uuid_t) * 2; } dbgprintf("[getUUID] END\n"); } #endif int ATTR_NONNULL() getRawMsgLen(const smsg_t *const pMsg) { return (pMsg->pszRawMsg == NULL) ? 0 : pMsg->iLenRawMsg; } void getRawMsg(const smsg_t *const pM, uchar **pBuf, int *piLen) { if (pM == NULL) { *pBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { if (pM->pszRawMsg == NULL) { *pBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { *pBuf = pM->pszRawMsg; *piLen = pM->iLenRawMsg; } } } void getRawMsgAfterPRI(smsg_t *const pM, uchar **pBuf, int *piLen) { if (pM == NULL) { *pBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { if (pM->pszRawMsg == NULL) { *pBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { /* unfortunately, pM->offAfterPRI seems NOT to be * correct/consistent in all cases. imuxsock and imudp * seem to have other values than imptcp. Testbench * covers some of that. As a work-around, we caluculate * the value ourselfes here. -- rgerhards, 2015-10-09 */ size_t offAfterPRI = 0; if (pM->pszRawMsg[0] == '<') { /* do we have a PRI? */ if (pM->pszRawMsg[2] == '>') offAfterPRI = 3; else if (pM->pszRawMsg[3] == '>') offAfterPRI = 4; else if (pM->pszRawMsg[4] == '>') offAfterPRI = 5; } *pBuf = pM->pszRawMsg + offAfterPRI; *piLen = pM->iLenRawMsg - offAfterPRI; } } } /* note: setMSGLen() is only for friends who really know what they * do. Setting an invalid length can be desasterous! */ void setMSGLen(smsg_t *const pM, int lenMsg) { pM->iLenMSG = lenMsg; } int getMSGLen(smsg_t *const pM) { return ((pM == NULL) ? 0 : pM->iLenMSG); } uchar *getMSG(smsg_t *const pM) { uchar *ret; if (pM == NULL) ret = UCHAR_CONSTANT(""); else { if (pM->iLenMSG == 0) ret = UCHAR_CONSTANT(""); else ret = pM->pszRawMsg + pM->offMSG; } return ret; } /* Get PRI value as integer */ int getPRIi(const smsg_t *const pM) { syslog_pri_t pri = (pM->iFacility << 3) + (pM->iSeverity); if (pri > 191) pri = LOG_PRI_INVLD; return pri; } /* Get PRI value in text form */ const char *getPRI(smsg_t *const pM) { /* PRI is a number in the range 0..191. Thus, we use a simple lookup table to obtain the * string value. It looks a bit clumpsy here in code ;) */ int iPRI; if (pM == NULL) return ""; iPRI = getPRIi(pM); return (iPRI > 191) ? "invld" : (char *)syslog_pri_names[iPRI].pszName; } static const char *formatISOWeekOrYear(enum tplFormatTypes eFmt, struct syslogTime *pTm) { if (pTm->year >= 1970 && pTm->year <= 2099) { int isoWeekYear; int isoWeek; isoWeek = getISOWeek(pTm, &isoWeekYear); if (eFmt == tplFmtISOWeek) { return two_digits[isoWeek]; } else { return years[isoWeekYear - 1967]; } } else { return "YEAR OUT OF RANGE(1970-2099)"; } } const char *getTimeReported(smsg_t *const pM, enum tplFormatTypes eFmt) { if (pM == NULL) return ""; switch (eFmt) { case tplFmtDefault: case tplFmtRFC3164Date: case tplFmtRFC3164BuggyDate: MsgLock(pM); if (pM->pszTIMESTAMP3164 == NULL) { pM->pszTIMESTAMP3164 = pM->pszTimestamp3164; datetime.formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, (eFmt == tplFmtRFC3164BuggyDate)); } MsgUnlock(pM); return (pM->pszTIMESTAMP3164); case tplFmtMySQLDate: MsgLock(pM); if (pM->pszTIMESTAMP_MySQL == NULL) { if ((pM->pszTIMESTAMP_MySQL = malloc(15)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestampToMySQL(&pM->tTIMESTAMP, pM->pszTIMESTAMP_MySQL); } MsgUnlock(pM); return (pM->pszTIMESTAMP_MySQL); case tplFmtPgSQLDate: MsgLock(pM); if (pM->pszTIMESTAMP_PgSQL == NULL) { if ((pM->pszTIMESTAMP_PgSQL = malloc(21)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestampToPgSQL(&pM->tTIMESTAMP, pM->pszTIMESTAMP_PgSQL); } MsgUnlock(pM); return (pM->pszTIMESTAMP_PgSQL); case tplFmtRFC3339Date: MsgLock(pM); if (pM->pszTIMESTAMP3339 == NULL) { pM->pszTIMESTAMP3339 = pM->pszTimestamp3339; datetime.formatTimestamp3339(&pM->tTIMESTAMP, pM->pszTIMESTAMP3339); } MsgUnlock(pM); return (pM->pszTIMESTAMP3339); case tplFmtUnixDate: MsgLock(pM); if (pM->pszTIMESTAMP_Unix[0] == '\0') { datetime.formatTimestampUnix(&pM->tTIMESTAMP, pM->pszTIMESTAMP_Unix); } MsgUnlock(pM); return (pM->pszTIMESTAMP_Unix); case tplFmtSecFrac: if (pM->pszTIMESTAMP_SecFrac[0] == '\0') { MsgLock(pM); /* re-check, may have changed while we did not hold lock */ if (pM->pszTIMESTAMP_SecFrac[0] == '\0') { datetime.formatTimestampSecFrac(&pM->tTIMESTAMP, pM->pszTIMESTAMP_SecFrac); } MsgUnlock(pM); } return (pM->pszTIMESTAMP_SecFrac); case tplFmtWDayName: return wdayNames[getWeekdayNbr(&pM->tTIMESTAMP)]; case tplFmtWDay: return one_digit[getWeekdayNbr(&pM->tTIMESTAMP)]; case tplFmtMonth: return two_digits[(int)pM->tTIMESTAMP.month]; case tplFmtYear: if (pM->tTIMESTAMP.year >= 1967 && pM->tTIMESTAMP.year <= 2099) return years[pM->tTIMESTAMP.year - 1967]; else return "YEAR OUT OF RANGE(1967-2099)"; case tplFmtDay: return two_digits[(int)pM->tTIMESTAMP.day]; case tplFmtHour: return two_digits[(int)pM->tTIMESTAMP.hour]; case tplFmtMinute: return two_digits[(int)pM->tTIMESTAMP.minute]; case tplFmtSecond: return two_digits[(int)pM->tTIMESTAMP.second]; case tplFmtTZOffsHour: return two_digits[(int)pM->tTIMESTAMP.OffsetHour]; case tplFmtTZOffsMin: return two_digits[(int)pM->tTIMESTAMP.OffsetMinute]; case tplFmtTZOffsDirection: return (pM->tTIMESTAMP.OffsetMode == '+') ? "+" : "-"; case tplFmtOrdinal: return daysInYear[getOrdinal(&pM->tTIMESTAMP)]; case tplFmtWeek: return two_digits[getWeek(&pM->tTIMESTAMP)]; case tplFmtISOWeek: case tplFmtISOWeekYear: return formatISOWeekOrYear(eFmt, &pM->tTIMESTAMP); default: return "INVALID eFmt OPTION!"; } } static const char *getTimeUTC(struct syslogTime *const __restrict__ pTmIn, const enum tplFormatTypes eFmt, unsigned short *const __restrict__ pbMustBeFreed) { struct syslogTime tUTC; char *retbuf = NULL; timeConvertToUTC(pTmIn, &tUTC); struct syslogTime *const pTm = &tUTC; switch (eFmt) { case tplFmtDefault: if ((retbuf = malloc(16)) != NULL) { datetime.formatTimestamp3164(pTm, retbuf, 0); } break; case tplFmtMySQLDate: if ((retbuf = malloc(15)) != NULL) { datetime.formatTimestampToMySQL(pTm, retbuf); } break; case tplFmtPgSQLDate: if ((retbuf = malloc(21)) != NULL) { datetime.formatTimestampToPgSQL(pTm, retbuf); } break; case tplFmtRFC3164Date: case tplFmtRFC3164BuggyDate: if ((retbuf = malloc(16)) != NULL) { datetime.formatTimestamp3164(pTm, retbuf, (eFmt == tplFmtRFC3164BuggyDate)); } break; case tplFmtRFC3339Date: if ((retbuf = malloc(33)) != NULL) { datetime.formatTimestamp3339(pTm, retbuf); } break; case tplFmtUnixDate: if ((retbuf = malloc(12)) != NULL) { datetime.formatTimestampUnix(pTm, retbuf); } break; case tplFmtSecFrac: if ((retbuf = malloc(7)) != NULL) { datetime.formatTimestampSecFrac(pTm, retbuf); } break; case tplFmtWDayName: retbuf = strdup(wdayNames[getWeekdayNbr(pTm)]); break; case tplFmtWDay: retbuf = strdup(one_digit[getWeekdayNbr(pTm)]); break; case tplFmtMonth: retbuf = strdup(two_digits[(int)pTm->month]); break; case tplFmtYear: if (pTm->year >= 1967 && pTm->year <= 2099) retbuf = strdup(years[pTm->year - 1967]); else retbuf = strdup("YEAR OUT OF RANGE(1967-2099)"); break; case tplFmtDay: retbuf = strdup(two_digits[(int)pTm->day]); break; case tplFmtHour: retbuf = strdup(two_digits[(int)pTm->hour]); break; case tplFmtMinute: retbuf = strdup(two_digits[(int)pTm->minute]); break; case tplFmtSecond: retbuf = strdup(two_digits[(int)pTm->second]); break; case tplFmtTZOffsHour: retbuf = strdup(two_digits[(int)pTm->OffsetHour]); break; case tplFmtTZOffsMin: retbuf = strdup(two_digits[(int)pTm->OffsetMinute]); break; case tplFmtTZOffsDirection: retbuf = strdup((pTm->OffsetMode == '+') ? "+" : "-"); break; case tplFmtOrdinal: retbuf = strdup(daysInYear[getOrdinal(pTm)]); break; case tplFmtWeek: retbuf = strdup(two_digits[getWeek(pTm)]); break; case tplFmtISOWeek: case tplFmtISOWeekYear: retbuf = strdup(formatISOWeekOrYear(eFmt, pTm)); break; default: // Required to prevent compiler warning C4062 (unhandled enum value). // Unhandled eFmt values are correctly managed by the subsequent if(retbuf == NULL) check. break; } if (retbuf == NULL) { retbuf = (char *)"internal error: invalid eFmt option or malloc problem"; *pbMustBeFreed = 0; } else { *pbMustBeFreed = 1; } return retbuf; } static const char *getTimeGenerated(smsg_t *const __restrict__ pM, const enum tplFormatTypes eFmt) { struct syslogTime *const pTm = &pM->tRcvdAt; if (pM == NULL) return ""; switch (eFmt) { case tplFmtDefault: MsgLock(pM); if (pM->pszRcvdAt3164 == NULL) { if ((pM->pszRcvdAt3164 = malloc(16)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestamp3164(pTm, pM->pszRcvdAt3164, 0); } MsgUnlock(pM); return (pM->pszRcvdAt3164); case tplFmtMySQLDate: MsgLock(pM); if (pM->pszRcvdAt_MySQL == NULL) { if ((pM->pszRcvdAt_MySQL = malloc(15)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestampToMySQL(pTm, pM->pszRcvdAt_MySQL); } MsgUnlock(pM); return (pM->pszRcvdAt_MySQL); case tplFmtPgSQLDate: MsgLock(pM); if (pM->pszRcvdAt_PgSQL == NULL) { if ((pM->pszRcvdAt_PgSQL = malloc(21)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestampToPgSQL(pTm, pM->pszRcvdAt_PgSQL); } MsgUnlock(pM); return (pM->pszRcvdAt_PgSQL); case tplFmtRFC3164Date: case tplFmtRFC3164BuggyDate: MsgLock(pM); if (pM->pszRcvdAt3164 == NULL) { if ((pM->pszRcvdAt3164 = malloc(16)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestamp3164(pTm, pM->pszRcvdAt3164, (eFmt == tplFmtRFC3164BuggyDate)); } MsgUnlock(pM); return (pM->pszRcvdAt3164); case tplFmtRFC3339Date: MsgLock(pM); if (pM->pszRcvdAt3339 == NULL) { if ((pM->pszRcvdAt3339 = malloc(33)) == NULL) { MsgUnlock(pM); return ""; } datetime.formatTimestamp3339(pTm, pM->pszRcvdAt3339); } MsgUnlock(pM); return (pM->pszRcvdAt3339); case tplFmtUnixDate: MsgLock(pM); if (pM->pszRcvdAt_Unix[0] == '\0') { datetime.formatTimestampUnix(pTm, pM->pszRcvdAt_Unix); } MsgUnlock(pM); return (pM->pszRcvdAt_Unix); case tplFmtSecFrac: if (pM->pszRcvdAt_SecFrac[0] == '\0') { MsgLock(pM); /* re-check, may have changed while we did not hold lock */ if (pM->pszRcvdAt_SecFrac[0] == '\0') { datetime.formatTimestampSecFrac(pTm, pM->pszRcvdAt_SecFrac); } MsgUnlock(pM); } return (pM->pszRcvdAt_SecFrac); case tplFmtWDayName: return wdayNames[getWeekdayNbr(pTm)]; case tplFmtWDay: return one_digit[getWeekdayNbr(pTm)]; case tplFmtMonth: return two_digits[(int)pTm->month]; case tplFmtYear: if (pTm->year >= 1967 && pTm->year <= 2099) return years[pTm->year - 1967]; else return "YEAR OUT OF RANGE(1967-2099)"; case tplFmtDay: return two_digits[(int)pTm->day]; case tplFmtHour: return two_digits[(int)pTm->hour]; case tplFmtMinute: return two_digits[(int)pTm->minute]; case tplFmtSecond: return two_digits[(int)pTm->second]; case tplFmtTZOffsHour: return two_digits[(int)pTm->OffsetHour]; case tplFmtTZOffsMin: return two_digits[(int)pTm->OffsetMinute]; case tplFmtTZOffsDirection: return (pTm->OffsetMode == '+') ? "+" : "-"; case tplFmtOrdinal: return daysInYear[getOrdinal(pTm)]; case tplFmtWeek: return two_digits[getWeek(pTm)]; case tplFmtISOWeek: case tplFmtISOWeekYear: return formatISOWeekOrYear(eFmt, pTm); default: return "INVALID eFmt OPTION!"; } } static const char *getSeverity(smsg_t *const pM) { const char *name = NULL; if (pM == NULL) return ""; if (pM->iSeverity > 7) { name = "invld"; } else { name = syslog_number_names[pM->iSeverity]; } return name; } static const char *getSeverityStr(smsg_t *const pM) { const char *name = NULL; if (pM == NULL) return ""; if (pM->iSeverity > 7) { name = "invld"; } else { name = syslog_severity_names[pM->iSeverity]; } return name; } static const char *getFacility(smsg_t *const pM) { const char *name = NULL; if (pM == NULL) return ""; if (pM->iFacility > 23) { name = "invld"; } else { name = syslog_number_names[pM->iFacility]; } return name; } static const char *getFacilityStr(smsg_t *const pM) { const char *name = NULL; if (pM == NULL) return ""; if (pM->iFacility > 23) { name = "invld"; } else { name = syslog_fac_names[pM->iFacility]; } return name; } /* set flow control state (if not called, the default - NO_DELAY - is used) * This needs no locking because it is only done while the object is * not fully constructed (which also means you must not call this * method after the msg has been handed over to a queue). * rgerhards, 2008-03-14 */ rsRetVal MsgSetFlowControlType(smsg_t *const pMsg, flowControl_t eFlowCtl) { DEFiRet; assert(pMsg != NULL); assert(eFlowCtl == eFLOWCTL_NO_DELAY || eFlowCtl == eFLOWCTL_LIGHT_DELAY || eFlowCtl == eFLOWCTL_FULL_DELAY); pMsg->flowCtlType = eFlowCtl; RETiRet; } /* set offset after which PRI in raw msg starts * rgerhards, 2009-06-16 */ rsRetVal MsgSetAfterPRIOffs(smsg_t *const pMsg, int offs) { assert(pMsg != NULL); pMsg->offAfterPRI = offs; return RS_RET_OK; } /* rgerhards 2004-11-24: set APP-NAME in msg object * This is not locked, because it either is called during message * construction (where we need no locking) or later as part of a function * which already obtained the lock. So in general, this function here must * only be called when it it safe to do so without it aquiring a lock. */ rsRetVal ATTR_NONNULL(1, 2) MsgSetAPPNAME(smsg_t *__restrict__ const pMsg, const char *pszAPPNAME) { DEFiRet; assert(pMsg != NULL); if (pszAPPNAME[0] == '\0') { pszAPPNAME = "-"; /* RFC5424 NIL value */ } if (pMsg->pCSAPPNAME == NULL) { /* we need to obtain the object first */ CHKiRet(rsCStrConstruct(&pMsg->pCSAPPNAME)); } /* if we reach this point, we have the object */ CHKiRet(rsCStrSetSzStr(pMsg->pCSAPPNAME, (uchar *)pszAPPNAME)); cstrFinalize(pMsg->pCSAPPNAME); finalize_it: RETiRet; } /* rgerhards 2004-11-24: set PROCID in msg object */ rsRetVal MsgSetPROCID(smsg_t *__restrict__ const pMsg, const char *pszPROCID) { DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); if (pMsg->pCSPROCID == NULL) { /* we need to obtain the object first */ CHKiRet(cstrConstruct(&pMsg->pCSPROCID)); } /* if we reach this point, we have the object */ CHKiRet(rsCStrSetSzStr(pMsg->pCSPROCID, (uchar *)pszPROCID)); cstrFinalize(pMsg->pCSPROCID); finalize_it: RETiRet; } /* check if we have a procid, and, if not, try to acquire/emulate it. * This must be called WITHOUT the message lock being held. * rgerhards, 2009-06-26 */ static void preparePROCID(smsg_t *const pM, sbool bLockMutex) { if (pM->pCSPROCID == NULL) { if (bLockMutex == LOCK_MUTEX) MsgLock(pM); /* re-query, things may have changed in the mean time... */ if (pM->pCSPROCID == NULL) acquirePROCIDFromTAG(pM); if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); } } #if 0 /* rgerhards, 2005-11-24 */ static int getPROCIDLen(smsg_t *pM, sbool bLockMutex) { assert(pM != NULL); preparePROCID(pM, bLockMutex); return (pM->pCSPROCID == NULL) ? 1 : rsCStrLen(pM->pCSPROCID); } #endif /* rgerhards, 2005-11-24 */ char *getPROCID(smsg_t *const pM, sbool bLockMutex) { uchar *pszRet; ISOBJ_TYPE_assert(pM, msg); if (bLockMutex == LOCK_MUTEX) MsgLock(pM); preparePROCID(pM, MUTEX_ALREADY_LOCKED); if (pM->pCSPROCID == NULL) pszRet = UCHAR_CONSTANT("-"); else pszRet = rsCStrGetSzStrNoNULL(pM->pCSPROCID); if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); return (char *)pszRet; } /* rgerhards 2004-11-24: set MSGID in msg object */ rsRetVal MsgSetMSGID(smsg_t *const pMsg, const char *pszMSGID) { DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); if (pMsg->pCSMSGID == NULL) { /* we need to obtain the object first */ CHKiRet(rsCStrConstruct(&pMsg->pCSMSGID)); } /* if we reach this point, we have the object */ CHKiRet(rsCStrSetSzStr(pMsg->pCSMSGID, (uchar *)pszMSGID)); cstrFinalize(pMsg->pCSMSGID); finalize_it: RETiRet; } /* Return state of last parser. If it had success, "OK" is returned, else * "FAIL". All from the constant pool. */ static const char *getParseSuccess(smsg_t *const pM) { return (pM->bParseSuccess) ? "OK" : "FAIL"; } /* al, 2011-07-26: LockMsg to avoid race conditions */ static const char *getMSGID(smsg_t *const pM) { if (pM->pCSMSGID == NULL) { return "-"; } else { MsgLock(pM); char *pszreturn = (char *)rsCStrGetSzStrNoNULL(pM->pCSMSGID); MsgUnlock(pM); return pszreturn; } } /* rgerhards 2012-03-15: set parser success (an integer, acutally bool) */ void MsgSetParseSuccess(smsg_t *const pMsg, int bSuccess) { assert(pMsg != NULL); pMsg->bParseSuccess = bSuccess; } /* return full message as a json string */ const uchar *msgGetJSONMESG(smsg_t *__restrict__ const pMsg) { struct json_object *json; struct json_object *jval; uchar *pRes; /* result pointer */ rs_size_t bufLen = -1; /* length of string or -1, if not known */ json = json_object_new_object(); jval = json_object_new_string((char *)getMSG(pMsg)); json_object_object_add(json, "msg", jval); getRawMsg(pMsg, &pRes, &bufLen); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "rawmsg", jval); pRes = (uchar *)getTimeReported(pMsg, tplFmtRFC3339Date); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "timereported", jval); jval = json_object_new_string(getHOSTNAME(pMsg)); json_object_object_add(json, "hostname", jval); getTAG(pMsg, &pRes, &bufLen, LOCK_MUTEX); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "syslogtag", jval); getInputName(pMsg, &pRes, &bufLen); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "inputname", jval); jval = json_object_new_string((char *)getRcvFrom(pMsg)); json_object_object_add(json, "fromhost", jval); jval = json_object_new_string((char *)getRcvFromIP(pMsg)); json_object_object_add(json, "fromhost-ip", jval); jval = json_object_new_string((char *)getRcvFromPort(pMsg)); json_object_object_add(json, "fromhost-port", jval); jval = json_object_new_string(getPRI(pMsg)); json_object_object_add(json, "pri", jval); jval = json_object_new_string(getFacility(pMsg)); json_object_object_add(json, "syslogfacility", jval); jval = json_object_new_string(getSeverity(pMsg)); json_object_object_add(json, "syslogseverity", jval); pRes = (uchar *)getTimeGenerated(pMsg, tplFmtRFC3339Date); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "timegenerated", jval); jval = json_object_new_string((char *)getProgramName(pMsg, LOCK_MUTEX)); json_object_object_add(json, "programname", jval); jval = json_object_new_string(getProtocolVersionString(pMsg)); json_object_object_add(json, "protocol-version", jval); MsgGetStructuredData(pMsg, &pRes, &bufLen); jval = json_object_new_string((char *)pRes); json_object_object_add(json, "structured-data", jval); jval = json_object_new_string(getAPPNAME(pMsg, LOCK_MUTEX)); json_object_object_add(json, "app-name", jval); jval = json_object_new_string(getPROCID(pMsg, LOCK_MUTEX)); json_object_object_add(json, "procid", jval); jval = json_object_new_string(getMSGID(pMsg)); json_object_object_add(json, "msgid", jval); #ifdef USE_LIBUUID if (pMsg->pszUUID == NULL) { jval = NULL; } else { getUUID(pMsg, &pRes, &bufLen); jval = json_object_new_string((char *)pRes); } json_object_object_add(json, "uuid", jval); #endif json_object_object_add(json, "$!", json_object_get(pMsg->json)); pRes = (uchar *)strdup(jsonToString(json)); json_object_put(json); return pRes; } /* rgerhards 2009-06-12: set associated ruleset */ void MsgSetRuleset(smsg_t *const pMsg, ruleset_t *pRuleset) { assert(pMsg != NULL); pMsg->pRuleset = pRuleset; } /* set TAG in msg object * (rewritten 2009-06-18 rgerhards) */ void MsgSetTAG(smsg_t *__restrict__ const pMsg, const uchar *pszBuf, const size_t lenBuf) { uchar *pBuf; assert(pMsg != NULL); freeTAG(pMsg); pMsg->iLenTAG = lenBuf; if (pMsg->iLenTAG < CONF_TAG_BUFSIZE) { /* small enough: use fixed buffer (faster!) */ pBuf = pMsg->TAG.szBuf; } else { if ((pBuf = (uchar *)malloc(pMsg->iLenTAG + 1)) == NULL) { /* truncate message, better than completely loosing it... */ pBuf = pMsg->TAG.szBuf; pMsg->iLenTAG = CONF_TAG_BUFSIZE - 1; } else { pMsg->TAG.pszTAG = pBuf; } } memcpy(pBuf, pszBuf, pMsg->iLenTAG); pBuf[pMsg->iLenTAG] = '\0'; /* this also works with truncation! */ } /* This function tries to emulate the TAG if none is * set. Its primary purpose is to provide an old-style TAG * when a syslog-protocol message has been received. Then, * the tag is APP-NAME "[" PROCID "]". The function first checks * if there is a TAG and, if not, if it can emulate it. * rgerhards, 2005-11-24 */ static void ATTR_NONNULL(1) tryEmulateTAG(smsg_t *const pM, const sbool bLockMutex) { size_t lenTAG; uchar bufTAG[CONF_TAG_MAXSIZE]; assert(pM != NULL); if (bLockMutex == LOCK_MUTEX) MsgLock(pM); if (pM->iLenTAG > 0) { if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); return; /* done, no need to emulate */ } if (msgGetProtocolVersion(pM) == 1) { if (!strcmp(getPROCID(pM, MUTEX_ALREADY_LOCKED), "-")) { /* no process ID, use APP-NAME only */ MsgSetTAG(pM, (uchar *)getAPPNAME(pM, MUTEX_ALREADY_LOCKED), getAPPNAMELen(pM, MUTEX_ALREADY_LOCKED)); } else { /* now we can try to emulate */ lenTAG = snprintf((char *)bufTAG, CONF_TAG_MAXSIZE, "%s[%s]", getAPPNAME(pM, MUTEX_ALREADY_LOCKED), getPROCID(pM, MUTEX_ALREADY_LOCKED)); bufTAG[sizeof(bufTAG) - 1] = '\0'; /* just to make sure... */ MsgSetTAG(pM, bufTAG, lenTAG); } /* Signal change in TAG for acquireProgramName */ pM->iLenPROGNAME = -1; } if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); } void ATTR_NONNULL(2, 3) getTAG(smsg_t *const pM, uchar **const ppBuf, int *const piLen, const sbool bLockMutex) { if (bLockMutex == LOCK_MUTEX) MsgLock(pM); if (pM == NULL) { *ppBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { if (pM->iLenTAG == 0) tryEmulateTAG(pM, MUTEX_ALREADY_LOCKED); if (pM->iLenTAG == 0) { *ppBuf = UCHAR_CONSTANT(""); *piLen = 0; } else { *ppBuf = (pM->iLenTAG < CONF_TAG_BUFSIZE) ? pM->TAG.szBuf : pM->TAG.pszTAG; *piLen = pM->iLenTAG; } } if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); } int getHOSTNAMELen(smsg_t *const pM) { if (pM == NULL) return 0; else if (pM->pszHOSTNAME == NULL) { resolveDNS(pM); if (pM->rcvFrom.pRcvFrom == NULL) return 0; else return prop.GetStringLen(pM->rcvFrom.pRcvFrom); } else return pM->iLenHOSTNAME; } const char *getHOSTNAME(smsg_t *const pM) { if (pM == NULL) return ""; else if (pM->pszHOSTNAME == NULL) { resolveDNS(pM); if (pM->rcvFrom.pRcvFrom == NULL) { return ""; } else { uchar *psz; int len; prop.GetString(pM->rcvFrom.pRcvFrom, &psz, &len); return (char *)psz; } } else { return (char *)pM->pszHOSTNAME; } } uchar *getRcvFrom(smsg_t *const pM) { uchar *psz; int len; if (pM == NULL) { psz = UCHAR_CONSTANT(""); } else { resolveDNS(pM); if (pM->rcvFrom.pRcvFrom == NULL) psz = UCHAR_CONSTANT(""); else prop.GetString(pM->rcvFrom.pRcvFrom, &psz, &len); } return psz; } /* rgerhards 2004-11-24: set STRUCTURED DATA in msg object */ rsRetVal MsgSetStructuredData(smsg_t *const pMsg, const char *pszStrucData) { DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); free(pMsg->pszStrucData); CHKmalloc(pMsg->pszStrucData = (uchar *)strdup(pszStrucData)); pMsg->lenStrucData = strlen(pszStrucData); finalize_it: RETiRet; } /* get the "STRUCTURED-DATA" as sz string, including length */ void MsgGetStructuredData(smsg_t *const pM, uchar **pBuf, rs_size_t *len) { MsgLock(pM); if (pM->pszStrucData == NULL) { *pBuf = UCHAR_CONSTANT("-"), *len = 1; } else { *pBuf = pM->pszStrucData, *len = pM->lenStrucData; } MsgUnlock(pM); } /* get the "programname" as sz string * rgerhards, 2005-10-19 */ uchar *ATTR_NONNULL(1) getProgramName(smsg_t *const pM, const sbool bLockMutex) { if (bLockMutex == LOCK_MUTEX) { MsgLock(pM); } if (pM->iLenPROGNAME == -1) { if (pM->iLenTAG == 0) { uchar *pRes; rs_size_t bufLen = -1; getTAG(pM, &pRes, &bufLen, MUTEX_ALREADY_LOCKED); } acquireProgramName(pM); } if (bLockMutex == LOCK_MUTEX) { MsgUnlock(pM); } return (pM->iLenPROGNAME < CONF_PROGNAME_BUFSIZE) ? pM->PROGNAME.szBuf : pM->PROGNAME.ptr; } /* check if we have a APPNAME, and, if not, try to acquire/emulate it. * rgerhards, 2009-06-26 */ static void ATTR_NONNULL(1) prepareAPPNAME(smsg_t *const pM, const sbool bLockMutex) { if (pM->pCSAPPNAME == NULL) { if (bLockMutex == LOCK_MUTEX) MsgLock(pM); /* re-query as things might have changed during locking */ if (pM->pCSAPPNAME == NULL) { if (msgGetProtocolVersion(pM) == 0) { /* only then it makes sense to emulate */ MsgSetAPPNAME(pM, (char *)getProgramName(pM, MUTEX_ALREADY_LOCKED)); } } if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); } } /* rgerhards, 2005-11-24 */ char *getAPPNAME(smsg_t *const pM, const sbool bLockMutex) { uchar *pszRet; assert(pM != NULL); if (bLockMutex == LOCK_MUTEX) MsgLock(pM); prepareAPPNAME(pM, MUTEX_ALREADY_LOCKED); if (pM->pCSAPPNAME == NULL) pszRet = UCHAR_CONSTANT(""); else pszRet = rsCStrGetSzStrNoNULL(pM->pCSAPPNAME); if (bLockMutex == LOCK_MUTEX) MsgUnlock(pM); return (char *)pszRet; } /* rgerhards, 2005-11-24 */ static int getAPPNAMELen(smsg_t *const pM, const sbool bLockMutex) { assert(pM != NULL); prepareAPPNAME(pM, bLockMutex); return (pM->pCSAPPNAME == NULL) ? 0 : rsCStrLen(pM->pCSAPPNAME); } /* rgerhards 2008-09-10: set pszInputName in msg object. This calls AddRef() * on the property, because this must be done in all current cases and there * is no case expected where this may not be necessary. * rgerhards, 2009-06-16 */ void MsgSetInputName(smsg_t *pThis, prop_t *inputName) { assert(pThis != NULL); prop.AddRef(inputName); if (pThis->pInputName != NULL) prop.Destruct(&pThis->pInputName); pThis->pInputName = inputName; } /* Set default TZ. Note that at most 7 chars are set, as we would * otherwise overrun our buffer! */ void MsgSetDfltTZ(smsg_t *pThis, char *tz) { strncpy(pThis->dfltTZ, tz, 7); pThis->dfltTZ[7] = '\0'; /* ensure 0-Term in case of overflow! */ } /* Set the pfrominet socket store, so that we can obtain the peer at some * later time. Note that we do not check if pRcvFrom is already set, so this * function must only be called during message creation. * NOTE: msgFlags is NOT set. While this is somewhat a violation of layers, * it is done because it gains us some performance. So the caller must make * sure the message flags are properly maintained. For all current callers, * this is always the case and without extra effort required. * rgerhards, 2009-11-17 */ rsRetVal msgSetFromSockinfo(smsg_t *pThis, struct sockaddr_storage *sa) { DEFiRet; assert(pThis->rcvFrom.pRcvFrom == NULL); CHKmalloc(pThis->rcvFrom.pfrominet = malloc(sizeof(struct sockaddr_storage))); memcpy(pThis->rcvFrom.pfrominet, sa, sizeof(struct sockaddr_storage)); finalize_it: RETiRet; } /* rgerhards 2008-09-10: set RcvFrom name in msg object. This calls AddRef() * on the property, because this must be done in all current cases and there * is no case expected where this may not be necessary. * rgerhards, 2009-06-30 */ void MsgSetRcvFrom(smsg_t *pThis, prop_t *new) { prop.AddRef(new); MsgSetRcvFromWithoutAddRef(pThis, new); } /* This is used to set the property via a string. This function should not be * called if there is a reliable way for a caller to make sure that the * same name can be used across multiple messages. However, if it can not * ensure that, calling this function is the second best thing, because it * will re-use the previously created property if it contained the same * name (but it works only for the immediate previous). * rgerhards, 2009-06-31 */ void MsgSetRcvFromStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp) { assert(pThis != NULL); assert(ppProp != NULL); prop.CreateOrReuseStringProp(ppProp, psz, len); MsgSetRcvFrom(pThis, *ppProp); } /* set RcvFromIP name in msg object. This calls AddRef() * on the property, because this must be done in all current cases and there * is no case expected where this may not be necessary. * rgerhards, 2009-06-30 */ rsRetVal MsgSetRcvFromIP(smsg_t *pThis, prop_t *new) { assert(pThis != NULL); prop.AddRef(new); MsgSetRcvFromIPWithoutAddRef(pThis, new); return RS_RET_OK; } /* This is used to set the property via a string. This function should not be * called if there is a reliable way for a caller to make sure that the * same name can be used across multiple messages. However, if it can not * ensure that, calling this function is the second best thing, because it * will re-use the previously created property if it contained the same * name (but it works only for the immediate previous). * rgerhards, 2009-06-31 */ rsRetVal MsgSetRcvFromIPStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp) { DEFiRet; assert(pThis != NULL); CHKiRet(prop.CreateOrReuseStringProp(ppProp, psz, len)); MsgSetRcvFromIP(pThis, *ppProp); finalize_it: RETiRet; } rsRetVal MsgSetRcvFromPort(smsg_t *pThis, prop_t *new) { assert(pThis != NULL); prop.AddRef(new); MsgSetRcvFromPortWithoutAddRef(pThis, new); return RS_RET_OK; } rsRetVal MsgSetRcvFromPortStr(smsg_t *const pThis, const uchar *psz, const int len, prop_t **ppProp) { DEFiRet; assert(pThis != NULL); CHKiRet(prop.CreateOrReuseStringProp(ppProp, psz, len)); MsgSetRcvFromPort(pThis, *ppProp); finalize_it: RETiRet; } /* rgerhards 2004-11-09: set HOSTNAME in msg object * rgerhards, 2007-06-21: * Does not return anything. If an error occurs, the hostname is * simply not set. I have changed this behaviour. The only problem * we can run into is memory shortage. If we have such, it is better * to loose the hostname than the full message. So we silently ignore * that problem and hope that memory will be available the next time * we need it. The rest of the code already knows how to handle an * unset HOSTNAME. */ void MsgSetHOSTNAME(smsg_t *pThis, const uchar *pszHOSTNAME, const int lenHOSTNAME) { assert(pThis != NULL); freeHOSTNAME(pThis); pThis->iLenHOSTNAME = lenHOSTNAME; if (pThis->iLenHOSTNAME < CONF_HOSTNAME_BUFSIZE) { /* small enough: use fixed buffer (faster!) */ pThis->pszHOSTNAME = pThis->szHOSTNAME; } else if ((pThis->pszHOSTNAME = (uchar *)malloc(pThis->iLenHOSTNAME + 1)) == NULL) { /* truncate message, better than completely loosing it... */ pThis->pszHOSTNAME = pThis->szHOSTNAME; pThis->iLenHOSTNAME = CONF_HOSTNAME_BUFSIZE - 1; } memcpy(pThis->pszHOSTNAME, pszHOSTNAME, pThis->iLenHOSTNAME); pThis->pszHOSTNAME[pThis->iLenHOSTNAME] = '\0'; /* this also works with truncation! */ } /* set the offset of the MSG part into the raw msg buffer * Note that the offset may be higher than the length of the raw message * (exactly by one). This can happen if we have a message that does not * contain any MSG part. */ void MsgSetMSGoffs(smsg_t *const pMsg, int offs) { ISOBJ_TYPE_assert(pMsg, msg); pMsg->offMSG = offs; if (offs > pMsg->iLenRawMsg) { assert((int)offs - 1 == pMsg->iLenRawMsg); pMsg->iLenMSG = 0; } else { pMsg->iLenMSG = pMsg->iLenRawMsg - offs; } } /* replace the MSG part of a message. The update actually takes place inside * rawmsg. * There are two cases: either the new message will be larger than the new msg * or it will be less than or equal. If it is less than or equal, we can utilize * the previous message buffer. If it is larger, we can utilize the smsg_t-included * message buffer if it fits in there. If this is not the case, we need to alloc * a new, larger, chunk and copy over the data to it. Note that this function is * (hopefully) relatively seldom being called, so some performance impact is * uncritical. In any case, pszMSG is copied, so if it was dynamically allocated, * the caller is responsible for freeing it. * rgerhards, 2009-06-23 */ rsRetVal MsgReplaceMSG(smsg_t *pThis, const uchar *pszMSG, int lenMSG) { int lenNew; uchar *bufNew; DEFiRet; ISOBJ_TYPE_assert(pThis, msg); assert(pszMSG != NULL); lenNew = pThis->iLenRawMsg + lenMSG - pThis->iLenMSG; if (lenMSG > pThis->iLenMSG && lenNew >= CONF_RAWMSG_BUFSIZE) { /* we have lost our "bet" and need to alloc a new buffer ;) */ CHKmalloc(bufNew = malloc(lenNew + 1)); memcpy(bufNew, pThis->pszRawMsg, pThis->offMSG); if (pThis->pszRawMsg != pThis->szRawMsg) free(pThis->pszRawMsg); pThis->pszRawMsg = bufNew; } if (lenMSG > 0) memcpy(pThis->pszRawMsg + pThis->offMSG, pszMSG, lenMSG); pThis->pszRawMsg[lenNew] = '\0'; /* this also works with truncation! */ pThis->iLenRawMsg = lenNew; pThis->iLenMSG = lenMSG; finalize_it: RETiRet; } /* truncate the (raw) message to configured max size. * The function makes sure that the stored rawmsg remains * properly terminated by '\0'. */ void ATTR_NONNULL() MsgTruncateToMaxSize(smsg_t *const pThis) { ISOBJ_TYPE_assert(pThis, msg); const int maxMsgSize = glblGetMaxLine(runConf); assert(pThis->iLenRawMsg > maxMsgSize); const int deltaSize = pThis->iLenRawMsg - maxMsgSize; pThis->pszRawMsg[maxMsgSize] = '\0'; pThis->iLenRawMsg = maxMsgSize; if (pThis->iLenMSG < deltaSize) { pThis->iLenMSG = 0; } else { pThis->iLenMSG -= deltaSize; } } /* set raw message in message object. Size of message is provided. * The function makes sure that the stored rawmsg is properly * terminated by '\0'. When a message is replaced, we try to keep * the existing MSG offset valid so that modules modifying only the * raw text do not need to recompute it. * rgerhards, 2009-06-16 */ void ATTR_NONNULL() MsgSetRawMsg(smsg_t *const pThis, const char *const pszRawMsg, const size_t lenMsg) { ISOBJ_TYPE_assert(pThis, msg); int deltaSize; if (pThis->pszRawMsg != pThis->szRawMsg) free(pThis->pszRawMsg); deltaSize = (int)lenMsg - pThis->iLenRawMsg; /* value < 0 in truncation case! */ pThis->iLenRawMsg = lenMsg; if (pThis->iLenRawMsg < CONF_RAWMSG_BUFSIZE) { /* small enough: use fixed buffer (faster!) */ pThis->pszRawMsg = pThis->szRawMsg; } else if ((pThis->pszRawMsg = (uchar *)malloc(pThis->iLenRawMsg + 1)) == NULL) { /* truncate message, better than completely loosing it... */ pThis->pszRawMsg = pThis->szRawMsg; pThis->iLenRawMsg = CONF_RAWMSG_BUFSIZE - 1; } memcpy(pThis->pszRawMsg, pszRawMsg, pThis->iLenRawMsg); pThis->pszRawMsg[pThis->iLenRawMsg] = '\0'; /* this also works with truncation! */ /* * Update cached MSG length. When offMSG already points into the * message (e.g. after initial parsing) adjusting iLenMSG avoids the * need for a costly re-parse in modules like mmexternal which may * replace the raw message text. */ if (pThis->iLenRawMsg > pThis->offMSG) pThis->iLenMSG += deltaSize; else pThis->iLenMSG = 0; } /* set raw message in message object. Size of message is not provided. This * function should only be used when it is unavoidable (and over time we should * try to remove it altogether). * rgerhards, 2009-06-16 */ void MsgSetRawMsgWOSize(smsg_t *const pMsg, char *pszRawMsg) { MsgSetRawMsg(pMsg, pszRawMsg, strlen(pszRawMsg)); } /* create textual representation of facility and severity. * The variable pRes must point to a user-supplied buffer of * at least 20 characters. */ static uchar *textpri(const smsg_t *const __restrict__ pMsg) { int lenfac = len_syslog_fac_names[pMsg->iFacility]; int lensev = len_syslog_severity_names[pMsg->iSeverity]; int totlen = lenfac + 1 + lensev + 1; char *pRes = malloc(totlen); if (pRes != NULL) { memcpy(pRes, syslog_fac_names[pMsg->iFacility], lenfac); pRes[lenfac] = '.'; memcpy(pRes + lenfac + 1, syslog_severity_names[pMsg->iSeverity], lensev + 1 /* for \0! */); } return (uchar *)pRes; } /* This function returns the current date in different * variants. It is used to construct the $NOW series of * system properties. The returned buffer must be freed * by the caller when no longer needed. If the function * can not allocate memory, it returns a NULL pointer. * Added 2007-07-10 rgerhards */ typedef enum ENOWType { NOW_NOW, NOW_YEAR, NOW_MONTH, NOW_DAY, NOW_HOUR, NOW_HHOUR, NOW_QHOUR, NOW_MINUTE, NOW_WDAY } eNOWType; #define tmpBUFSIZE 16 /* size of formatting buffer */ static uchar *getNOW(eNOWType eNow, struct syslogTime *t, const int inUTC) { uchar *pBuf; struct syslogTime tt; if ((pBuf = (uchar *)malloc(tmpBUFSIZE)) == NULL) { return NULL; } if (t == NULL) { /* can happen if called via script engine */ datetime.getCurrTime(&tt, NULL, inUTC); t = &tt; } if (t->year == 0 || t->inUTC != inUTC) { /* not yet set! */ datetime.getCurrTime(t, NULL, inUTC); } switch (eNow) { case NOW_NOW: memcpy(pBuf, two_digits[t->year / 100], 2); memcpy(pBuf + 2, two_digits[t->year % 100], 2); pBuf[4] = '-'; memcpy(pBuf + 5, two_digits[(int)t->month], 2); pBuf[7] = '-'; memcpy(pBuf + 8, two_digits[(int)t->day], 3); break; case NOW_YEAR: memcpy(pBuf, two_digits[t->year / 100], 2); memcpy(pBuf + 2, two_digits[t->year % 100], 3); break; case NOW_MONTH: memcpy(pBuf, two_digits[(int)t->month], 3); break; case NOW_DAY: memcpy(pBuf, two_digits[(int)t->day], 3); break; case NOW_HOUR: memcpy(pBuf, two_digits[(int)t->hour], 3); break; case NOW_HHOUR: memcpy(pBuf, two_digits[t->minute / 30], 3); break; case NOW_QHOUR: memcpy(pBuf, two_digits[t->minute / 15], 3); break; case NOW_MINUTE: memcpy(pBuf, two_digits[(int)t->minute], 3); break; case NOW_WDAY: memcpy(pBuf, one_digit[(int)t->wday], 2); break; default: // We need to satisfy compiler which does not properly handle enum break; } return (pBuf); } #undef tmpBUFSIZE /* clean up */ /* helper function to obtain correct JSON root and mutex depending on * property type (essentially based on the property id. If a non-json * property id is given the function errors out. * Note well: jroot points to a pointer to a (ptr to a) json object. * This is necessary because the caller needs a pointer to where the * json object pointer is stored, that in turn is necessary because * while the address of the actual pointer stays stable, the actual * content is volatile until the caller has locked the variable tree, * which we DO NOT do to keep calling semantics simple. */ static rsRetVal ATTR_NONNULL() getJSONRootAndMutex(smsg_t *const pMsg, const propid_t id, struct json_object ***const jroot, pthread_mutex_t **const mut) { DEFiRet; assert(jroot != NULL); /* asserts also help static analyzer! */ assert(mut != NULL); assert(*mut == NULL); /* caller shall have initialized this one! */ assert(id == PROP_CEE || id == PROP_LOCAL_VAR || id == PROP_GLOBAL_VAR); if (id == PROP_CEE) { *mut = &pMsg->mut; *jroot = &pMsg->json; } else if (id == PROP_LOCAL_VAR) { *mut = &pMsg->mut; *jroot = &pMsg->localvars; } else if (id == PROP_GLOBAL_VAR) { *mut = &glblVars_lock; *jroot = &global_var_root; } else { LogError(0, RS_RET_NON_JSON_PROP, "internal error: " "getJSONRootAndMutex; invalid property id %d", id); iRet = RS_RET_NON_JSON_PROP; } RETiRet; } /* basically same function, but does not use property id, but the the * variable name type indicator (char after starting $, e.g. $!myvar --> CEE) */ static rsRetVal ATTR_NONNULL() getJSONRootAndMutexByVarChar(smsg_t *const pMsg, const char c, struct json_object ***const jroot, pthread_mutex_t **const mut) { DEFiRet; propid_t id; assert(c == '!' || c == '.' || c == '/'); switch (c) { case '!': id = PROP_CEE; break; case '.': id = PROP_LOCAL_VAR; break; case '/': id = PROP_GLOBAL_VAR; break; default: LogError(0, RS_RET_NON_JSON_PROP, "internal error: " "getJSONRootAndMutex; invalid indicator char %c(%2.2x)", c, c); ABORT_FINALIZE(RS_RET_NON_JSON_PROP); break; } iRet = getJSONRootAndMutex(pMsg, id, jroot, mut); finalize_it: RETiRet; } /* Get a JSON-Property as string value (used for various types of JSON-based vars) */ rsRetVal getJSONPropVal( smsg_t *const pMsg, msgPropDescr_t *pProp, uchar **pRes, rs_size_t *buflen, unsigned short *pbMustBeFreed) { uchar *leaf; struct json_object **jroot; struct json_object *parent; struct json_object *field; pthread_mutex_t *mut = NULL; DEFiRet; *pRes = NULL; CHKiRet(getJSONRootAndMutex(pMsg, pProp->id, &jroot, &mut)); pthread_mutex_lock(mut); if (*jroot == NULL) FINALIZE; if (!strcmp((char *)pProp->name, "!")) { field = *jroot; } else { leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); if (jsonVarExtract(parent, (char *)leaf, &field) == FALSE) field = NULL; } if (field != NULL) { *pRes = (uchar *)strdup(jsonToString(field)); *buflen = (int)ustrlen(*pRes); *pbMustBeFreed = 1; } finalize_it: if (mut != NULL) pthread_mutex_unlock(mut); if (*pRes == NULL) { /* could not find any value, so set it to empty */ *pRes = (unsigned char *)""; *pbMustBeFreed = 0; } RETiRet; } /* Get a JSON-based-variable as native json object, except * when it is string type, in which case a string is returned. * This is an optimization to not use JSON when not strictly * necessary. This in turn is helpful, as calling json-c is * *very* expensive due to our need for locking and deep * copies. * The caller needs to check pjson and pcstr: one of them * is non-NULL and contains the return value. Note that * the caller is responsible for freeing the string pointer * it if is being returned. */ rsRetVal msgGetJSONPropJSONorString(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **pjson, uchar **pcstr) { struct json_object **jroot; uchar *leaf; struct json_object *parent; pthread_mutex_t *mut = NULL; DEFiRet; *pjson = NULL, *pcstr = NULL; CHKiRet(getJSONRootAndMutex(pMsg, pProp->id, &jroot, &mut)); pthread_mutex_lock(mut); if (!strcmp((char *)pProp->name, "!")) { *pjson = *jroot; FINALIZE; } if (*jroot == NULL) { ABORT_FINALIZE(RS_RET_NOT_FOUND); } leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); if (jsonVarExtract(parent, (char *)leaf, pjson) == FALSE) { ABORT_FINALIZE(RS_RET_NOT_FOUND); } if (*pjson == NULL) { /* we had a NULL json object and represent this as empty string */ *pcstr = (uchar *)strdup(""); } else { if (json_object_get_type(*pjson) == json_type_string) { *pcstr = (uchar *)strdup(jsonToString(*pjson)); *pjson = NULL; } } finalize_it: /* we need a deep copy, as another thread may modify the object */ if (*pjson != NULL) *pjson = jsonDeepCopy(*pjson); if (mut != NULL) pthread_mutex_unlock(mut); RETiRet; } /* Get a JSON-based-variable as native json object */ rsRetVal msgGetJSONPropJSON(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **pjson) { struct json_object **jroot; uchar *leaf; struct json_object *parent; pthread_mutex_t *mut = NULL; DEFiRet; *pjson = NULL; CHKiRet(getJSONRootAndMutex(pMsg, pProp->id, &jroot, &mut)); pthread_mutex_lock(mut); if (!strcmp((char *)pProp->name, "!")) { *pjson = *jroot; FINALIZE; } leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); if (jsonVarExtract(parent, (char *)leaf, pjson) == FALSE) { ABORT_FINALIZE(RS_RET_NOT_FOUND); } finalize_it: /* we need a deep copy, as another thread may modify the object */ if (*pjson != NULL) *pjson = jsonDeepCopy(*pjson); if (mut != NULL) pthread_mutex_unlock(mut); RETiRet; } /* Helper for jsonAddVal(), to be called onces we know there are actually * json escapes inside the string. If so, this function takes over. * Splitting the functions permits us to make some performance optimizations. * For further details, see jsonAddVal(). */ static rsRetVal ATTR_NONNULL(1, 4) jsonAddVal_escaped(uchar *const pSrc, const unsigned buflen, const unsigned len_none_escaped_head, es_str_t **dst, const int escapeAll) { unsigned char c; es_size_t i; char numbuf[4]; unsigned ni; unsigned char nc; int j; uchar wrkbuf[100000]; size_t dst_realloc_size; size_t dst_size; uchar *dst_base; uchar *dst_w; uchar *newbuf; DEFiRet; assert(len_none_escaped_head <= buflen); /* first copy over unescaped head string */ if (len_none_escaped_head + 10 > sizeof(wrkbuf)) { dst_size = 2 * len_none_escaped_head; CHKmalloc(dst_base = malloc(dst_size)); } else { dst_size = sizeof(wrkbuf); dst_base = wrkbuf; } dst_realloc_size = dst_size - 10; /* some buffer for escaping */ dst_w = dst_base; memcpy(dst_w, pSrc, len_none_escaped_head); dst_w += len_none_escaped_head; /* now do the escaping */ for (i = len_none_escaped_head; i < buflen; ++i) { const size_t dst_offset = dst_w - dst_base; if (dst_offset >= dst_realloc_size) { const size_t new_size = 2 * dst_size; if (dst_base == wrkbuf) { CHKmalloc(newbuf = malloc(new_size)); memcpy(newbuf, dst_base, dst_offset); } else { CHKmalloc(newbuf = realloc(dst_base, new_size)); } dst_size = new_size; dst_realloc_size = new_size - 10; /* some buffer for escaping */ dst_base = newbuf; dst_w = dst_base + dst_offset; } c = pSrc[i]; if ((c >= 0x30 && c <= 0x5b) || (c >= 0x23 && c <= 0x2e) || (c >= 0x5d /* && c <= 0x10FFFF*/) || c == 0x20 || c == 0x21) { /* no need to escape */ *dst_w++ = c; } else { /* we must escape, try RFC4627-defined special sequences first */ switch (c) { case '\0': *dst_w++ = '\\'; *dst_w++ = 'u'; *dst_w++ = '0'; *dst_w++ = '0'; *dst_w++ = '0'; *dst_w++ = '0'; break; case '\"': *dst_w++ = '\\'; *dst_w++ = '"'; break; case '/': *dst_w++ = '\\'; *dst_w++ = '/'; break; case '\\': if (escapeAll == RSFALSE) { ni = i + 1; if (ni <= buflen) { nc = pSrc[ni]; /* Attempt to not double encode */ if (nc == '"' || nc == '/' || nc == '\\' || nc == 'b' || nc == 'f' || nc == 'n' || nc == 'r' || nc == 't' || nc == 'u') { *dst_w++ = c; *dst_w++ = nc; i = ni; break; } } } *dst_w++ = '\\'; *dst_w++ = '\\'; break; case '\010': *dst_w++ = '\\'; *dst_w++ = 'b'; break; case '\014': *dst_w++ = '\\'; *dst_w++ = 'f'; break; case '\n': *dst_w++ = '\\'; *dst_w++ = 'n'; break; case '\r': *dst_w++ = '\\'; *dst_w++ = 'r'; break; case '\t': *dst_w++ = '\\'; *dst_w++ = 't'; break; default: /* TODO : proper Unicode encoding (see header comment) */ for (j = 0; j < 4; ++j) { numbuf[3 - j] = hexdigit[c % 16]; c = c / 16; } *dst_w++ = '\\'; *dst_w++ = 'u'; *dst_w++ = numbuf[0]; *dst_w++ = numbuf[1]; *dst_w++ = numbuf[2]; *dst_w++ = numbuf[3]; break; } } } if (*dst == NULL) { *dst = es_newStrFromBuf((char *)dst_base, dst_w - dst_base); } else { es_addBuf(dst, (const char *)dst_base, dst_w - dst_base); } finalize_it: if (dst_base != wrkbuf) { free(dst_base); } RETiRet; } /* Encode a JSON value and add it to provided string. Note that * the string object may be NULL. In this case, it is created * if and only if escaping is needed. if escapeAll is false, previously * escaped strings are left as is */ static rsRetVal ATTR_NONNULL(1, 3) jsonAddVal(uchar *const pSrc, const unsigned buflen, es_str_t **dst, const int escapeAll) { es_size_t i; DEFiRet; for (i = 0; i < buflen; ++i) { const uchar c = pSrc[i]; if (!((c >= 0x30 && c <= 0x5b) || (c >= 0x23 && c <= 0x2e) || (c >= 0x5d /* && c <= 0x10FFFF*/) || c == 0x20 || c == 0x21)) { iRet = jsonAddVal_escaped(pSrc, buflen, i, dst, escapeAll); FINALIZE; } } if (*dst != NULL) { es_addBuf(dst, (const char *)pSrc, buflen); } finalize_it: RETiRet; } /* encode a property in JSON escaped format. This is a helper * to MsgGetProp. It needs to update all provided parameters. * For performance reasons, we begin to copy the string only * when we recognice that we actually need to do some escaping. * rgerhards, 2012-03-16 */ static rsRetVal jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen, int escapeAll) { unsigned buflen; uchar *pSrc; es_str_t *dst = NULL; DEFiRet; pSrc = *ppRes; buflen = (*pBufLen == -1) ? (int)ustrlen(pSrc) : *pBufLen; CHKiRet(jsonAddVal(pSrc, buflen, &dst, escapeAll)); if (dst != NULL) { /* we updated the string and need to replace the * previous data. */ if (*pbMustBeFreed) free(*ppRes); *ppRes = (uchar *)es_str2cstr(dst, NULL); *pbMustBeFreed = 1; *pBufLen = -1; es_deleteStr(dst); } finalize_it: RETiRet; } /* Format a property as JSON field, that means * "name"="value" * where value is JSON-escaped (here we assume that the name * only contains characters from the valid character set). * Note: this function duplicates code from jsonEncode(). * TODO: these two functions should be combined, at least if * that makes any sense from a performance PoV - definitely * something to consider at a later stage. rgerhards, 2012-04-19 */ static rsRetVal ATTR_NONNULL() jsonField(const struct templateEntry *const pTpe, uchar **const ppRes, unsigned short *const pbMustBeFreed, int *const pBufLen, int escapeAll) { unsigned buflen; uchar *pSrc; es_str_t *dst = NULL; int is_numeric = 1; DEFiRet; pSrc = *ppRes; buflen = (*pBufLen == -1) ? (int)ustrlen(pSrc) : *pBufLen; dbgprintf("jsonEncode: datatype: %u, onEmpty: %u val %*s\n", (unsigned)pTpe->data.field.options.dataType, (unsigned)pTpe->data.field.options.onEmpty, buflen, pSrc); if (buflen == 0) { if (pTpe->data.field.options.onEmpty == TPE_DATAEMPTY_SKIP) { FINALIZE; } is_numeric = 0; } /* we hope we have only few escapes... */ dst = es_newStr(buflen + pTpe->lenFieldName + 15); es_addChar(&dst, '"'); es_addBuf(&dst, (char *)pTpe->fieldName, pTpe->lenFieldName); es_addBufConstcstr(&dst, "\":"); if (buflen == 0 && pTpe->data.field.options.onEmpty == TPE_DATAEMPTY_NULL) { es_addBufConstcstr(&dst, "null"); } else { if (pTpe->data.field.options.dataType == TPE_DATATYPE_AUTO) { for (unsigned i = 0; i < buflen; ++i) { if (pSrc[i] < '0' || pSrc[i] > '9') { is_numeric = 0; break; } } if (!is_numeric) { es_addChar(&dst, '"'); } CHKiRet(jsonAddVal(pSrc, buflen, &dst, escapeAll)); if (!is_numeric) { es_addChar(&dst, '"'); } } else if (pTpe->data.field.options.dataType == TPE_DATATYPE_STRING) { es_addChar(&dst, '"'); CHKiRet(jsonAddVal(pSrc, buflen, &dst, escapeAll)); es_addChar(&dst, '"'); } else if (pTpe->data.field.options.dataType == TPE_DATATYPE_NUMBER) { if (buflen == 0) { es_addChar(&dst, '0'); } else { CHKiRet(jsonAddVal(pSrc, buflen, &dst, escapeAll)); } } else if (pTpe->data.field.options.dataType == TPE_DATATYPE_BOOL) { if (buflen == 1 && *pSrc == '0') { es_addBufConstcstr(&dst, "false"); } else { es_addBufConstcstr(&dst, "true"); } } } if (*pbMustBeFreed) free(*ppRes); /* we know we do not have \0 chars - so the size does not change */ *pBufLen = es_strlen(dst); *ppRes = (uchar *)es_str2cstr(dst, NULL); *pbMustBeFreed = 1; es_deleteStr(dst); finalize_it: RETiRet; } /* This function returns a string-representation of the * requested message property. This is a generic function used * to abstract properties so that these can be easier * queried. Returns NULL if property could not be found. * Actually, this function is a big if..elseif. What it does * is simply to map property names (from MonitorWare) to the * message object data fields. * * In case we need string forms of propertis we do not * yet have in string form, we do a memory allocation that * is sufficiently large (in all cases). Once the string * form has been obtained, it is saved until the Msg object * is finally destroyed. This is so that we save the processing * time in the (likely) case that this property is requested * again. It also saves us a lot of dynamic memory management * issues in the upper layers, because we so can guarantee that * the buffer will remain static AND available during the lifetime * of the object. Please note that both the max size allocation as * well as keeping things in memory might like look like a * waste of memory (some might say it actually is...) - we * deliberately accept this because performance is more important * to us ;) * rgerhards 2004-11-18 * Parameter "bMustBeFreed" is set by this function. It tells the * caller whether or not the string returned must be freed by the * caller itself. It is is 0, the caller MUST NOT free it. If it is * 1, the caller MUST free it. Handling this wrongly leads to either * a memory leak of a program abort (do to double-frees or frees on * the constant memory pool). So be careful to do it right. * rgerhards 2004-11-23 * regular expression support contributed by Andres Riancho merged * on 2005-09-13 * changed so that it now an be called without a template entry (NULL). * In this case, only the (unmodified) property is returned. This will * be used in selector line processing. * rgerhards 2005-09-15 */ /* a quick helper to save some writing: */ #define RET_OUT_OF_MEMORY \ { \ *pbMustBeFreed = 0; \ *pPropLen = sizeof("**OUT OF MEMORY**") - 1; \ return (UCHAR_CONSTANT("**OUT OF MEMORY**")); \ } uchar *MsgGetProp(smsg_t *__restrict__ const pMsg, struct templateEntry *__restrict__ const pTpe, msgPropDescr_t *pProp, rs_size_t *__restrict__ const pPropLen, unsigned short *__restrict__ const pbMustBeFreed, struct syslogTime *const ttNow) { uchar *pRes; /* result pointer */ rs_size_t bufLen = -1; /* length of string or -1, if not known */ uchar *pBufStart; uchar *pBuf; int iLen; short iOffs; enum tplFormatTypes datefmt; int bDateInUTC; assert(pMsg != NULL); assert(pbMustBeFreed != NULL); #ifdef FEATURE_REGEXP /* Variables necessary for regular expression matching */ size_t nmatch = 10; regmatch_t pmatch[10]; #endif *pbMustBeFreed = 0; switch (pProp->id) { case PROP_MSG: pRes = getMSG(pMsg); bufLen = getMSGLen(pMsg); break; case PROP_TIMESTAMP: if (pTpe != NULL) { datefmt = pTpe->data.field.eDateFormat; bDateInUTC = pTpe->data.field.options.bDateInUTC; } else { datefmt = tplFmtDefault; bDateInUTC = 0; } if (bDateInUTC) { pRes = (uchar *)getTimeUTC(&pMsg->tTIMESTAMP, datefmt, pbMustBeFreed); } else { pRes = (uchar *)getTimeReported(pMsg, datefmt); } break; case PROP_HOSTNAME: pRes = (uchar *)getHOSTNAME(pMsg); bufLen = getHOSTNAMELen(pMsg); break; case PROP_SYSLOGTAG: getTAG(pMsg, &pRes, &bufLen, LOCK_MUTEX); break; case PROP_RAWMSG: getRawMsg(pMsg, &pRes, &bufLen); break; case PROP_RAWMSG_AFTER_PRI: getRawMsgAfterPRI(pMsg, &pRes, &bufLen); break; case PROP_INPUTNAME: getInputName(pMsg, &pRes, &bufLen); break; case PROP_FROMHOST: pRes = getRcvFrom(pMsg); break; case PROP_FROMHOST_IP: pRes = getRcvFromIP(pMsg); break; case PROP_FROMHOST_PORT: pRes = getRcvFromPort(pMsg); break; case PROP_PRI: pRes = (uchar *)getPRI(pMsg); break; case PROP_PRI_TEXT: pRes = textpri(pMsg); if (pRes == NULL) RET_OUT_OF_MEMORY; *pbMustBeFreed = 1; break; case PROP_IUT: pRes = UCHAR_CONSTANT("1"); /* always 1 for syslog messages (a MonitorWare thing;)) */ bufLen = 1; break; case PROP_SYSLOGFACILITY: pRes = (uchar *)getFacility(pMsg); break; case PROP_SYSLOGFACILITY_TEXT: pRes = (uchar *)getFacilityStr(pMsg); break; case PROP_SYSLOGSEVERITY: pRes = (uchar *)getSeverity(pMsg); break; case PROP_SYSLOGSEVERITY_TEXT: pRes = (uchar *)getSeverityStr(pMsg); break; case PROP_TIMEGENERATED: if (pTpe != NULL) { datefmt = pTpe->data.field.eDateFormat; bDateInUTC = pTpe->data.field.options.bDateInUTC; } else { datefmt = tplFmtDefault; bDateInUTC = 0; } if (bDateInUTC) { pRes = (uchar *)getTimeUTC(&pMsg->tRcvdAt, datefmt, pbMustBeFreed); } else { pRes = (uchar *)getTimeGenerated(pMsg, datefmt); } break; case PROP_PROGRAMNAME: pRes = getProgramName(pMsg, LOCK_MUTEX); break; case PROP_PROTOCOL_VERSION: pRes = (uchar *)getProtocolVersionString(pMsg); break; case PROP_STRUCTURED_DATA: MsgGetStructuredData(pMsg, &pRes, &bufLen); break; case PROP_APP_NAME: pRes = (uchar *)getAPPNAME(pMsg, LOCK_MUTEX); break; case PROP_PROCID: pRes = (uchar *)getPROCID(pMsg, LOCK_MUTEX); break; case PROP_MSGID: pRes = (uchar *)getMSGID(pMsg); break; case PROP_JSONMESG: pRes = (uchar *)msgGetJSONMESG(pMsg); *pbMustBeFreed = 1; break; #ifdef USE_LIBUUID case PROP_UUID: getUUID(pMsg, &pRes, &bufLen); break; #endif case PROP_PARSESUCCESS: pRes = (uchar *)getParseSuccess(pMsg); break; case PROP_SYS_NOW: if ((pRes = getNOW(NOW_NOW, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 10; } break; case PROP_SYS_YEAR: if ((pRes = getNOW(NOW_YEAR, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 4; } break; case PROP_SYS_MONTH: if ((pRes = getNOW(NOW_MONTH, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_DAY: if ((pRes = getNOW(NOW_DAY, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_HOUR: if ((pRes = getNOW(NOW_HOUR, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_HHOUR: if ((pRes = getNOW(NOW_HHOUR, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_QHOUR: if ((pRes = getNOW(NOW_QHOUR, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_MINUTE: if ((pRes = getNOW(NOW_MINUTE, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_NOW_UTC: if ((pRes = getNOW(NOW_NOW, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 10; } break; case PROP_SYS_YEAR_UTC: if ((pRes = getNOW(NOW_YEAR, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 4; } break; case PROP_SYS_MONTH_UTC: if ((pRes = getNOW(NOW_MONTH, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_DAY_UTC: if ((pRes = getNOW(NOW_DAY, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_HOUR_UTC: if ((pRes = getNOW(NOW_HOUR, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_HHOUR_UTC: if ((pRes = getNOW(NOW_HHOUR, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_QHOUR_UTC: if ((pRes = getNOW(NOW_QHOUR, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_MINUTE_UTC: if ((pRes = getNOW(NOW_MINUTE, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 2; } break; case PROP_SYS_WDAY: if ((pRes = getNOW(NOW_WDAY, ttNow, TIME_IN_LOCALTIME)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 1; } break; case PROP_SYS_WDAY_UTC: if ((pRes = getNOW(NOW_WDAY, ttNow, TIME_IN_UTC)) == NULL) { RET_OUT_OF_MEMORY; } else { *pbMustBeFreed = 1; bufLen = 1; } break; case PROP_SYS_NOW_UXTIMESTAMP: if ((pRes = malloc(16)) == NULL) { RET_OUT_OF_MEMORY; } else { snprintf((char *)pRes, 16 - 1, "%lld", (long long)getTime(NULL)); pRes[16 - 1] = '\0'; *pbMustBeFreed = 1; bufLen = -1; } break; case PROP_SYS_MYHOSTNAME: pRes = glbl.GetLocalHostName(); break; case PROP_CEE_ALL_JSON: case PROP_CEE_ALL_JSON_PLAIN: if (pMsg->json == NULL) { pRes = (uchar *)"{}"; bufLen = 2; *pbMustBeFreed = 0; } else { const char *jstr; MsgLock(pMsg); int jflag = 0; if (pProp->id == PROP_CEE_ALL_JSON) { jflag = JSON_C_TO_STRING_SPACED; } else if (pProp->id == PROP_CEE_ALL_JSON_PLAIN) { jflag = JSON_C_TO_STRING_PLAIN; } jstr = json_object_to_json_string_ext(pMsg->json, jflag); MsgUnlock(pMsg); if (jstr == NULL) { RET_OUT_OF_MEMORY; } pRes = (uchar *)strdup(jstr); if (pRes == NULL) { RET_OUT_OF_MEMORY; } *pbMustBeFreed = 1; } break; case PROP_CEE: case PROP_LOCAL_VAR: case PROP_GLOBAL_VAR: getJSONPropVal(pMsg, pProp, &pRes, &bufLen, pbMustBeFreed); break; case PROP_SYS_BOM: pRes = (uchar *)"\xEF\xBB\xBF"; *pbMustBeFreed = 0; break; case PROP_SYS_UPTIME: #ifndef HAVE_SYSINFO_UPTIME /* An alternative on some systems (eg Solaris) is to scan * /var/adm/utmpx for last boot time. */ pRes = (uchar *)"UPTIME NOT available on this system"; *pbMustBeFreed = 0; #elif defined(__FreeBSD__) { struct timespec tp; if ((pRes = (uchar *)malloc(32)) == NULL) { RET_OUT_OF_MEMORY; } if (clock_gettime(CLOCK_UPTIME, &tp) == -1) { free(pRes); *pPropLen = sizeof("**SYSCALL FAILED**") - 1; return (UCHAR_CONSTANT("**SYSCALL FAILED**")); } *pbMustBeFreed = 1; snprintf((char *)pRes, 32, "%ld", tp.tv_sec); } #else { struct sysinfo s_info; if ((pRes = (uchar *)malloc(32)) == NULL) { RET_OUT_OF_MEMORY; } if (sysinfo(&s_info) < 0) { free(pRes); *pPropLen = sizeof("**SYSCALL FAILED**") - 1; return (UCHAR_CONSTANT("**SYSCALL FAILED**")); } *pbMustBeFreed = 1; snprintf((char *)pRes, 32, "%ld", s_info.uptime); } #endif break; default: /* there is no point in continuing, we may even otherwise render the * error message unreadable. rgerhards, 2007-07-10 */ dbgprintf("invalid property id: '%d'\n", pProp->id); *pbMustBeFreed = 0; *pPropLen = sizeof("**INVALID PROPERTY NAME**") - 1; return UCHAR_CONSTANT("**INVALID PROPERTY NAME**"); } /* If we did not receive a template pointer, we are already done... */ if (pTpe == NULL || !pTpe->bComplexProcessing) { *pPropLen = (bufLen == -1) ? (int)ustrlen(pRes) : bufLen; return pRes; } /* Now check if we need to make "temporary" transformations (these * are transformations that do not go back into the message - * memory must be allocated for them!). */ /* substring extraction */ /* first we check if we need to extract by field number * rgerhards, 2005-12-22 */ if (pTpe->data.field.has_fields == 1) { size_t iCurrFld; uchar *pFld; uchar *pFldEnd; /* first, skip to the field in question. The field separator * is always one character and is stored in the template entry. */ iCurrFld = 1; pFld = pRes; while (*pFld && iCurrFld < pTpe->data.field.iFieldNr) { /* skip fields until the requested field or end of string is found */ while (*pFld && (uchar)*pFld != pTpe->data.field.field_delim) ++pFld; /* skip to field terminator */ if (*pFld == pTpe->data.field.field_delim) { ++pFld; /* eat it */ #ifdef STRICT_GPLV3 if (pTpe->data.field.field_expand != 0) { while (*pFld == pTpe->data.field.field_delim) { ++pFld; } } #endif ++iCurrFld; } } dbgprintf("field requested %d, field found %d\n", pTpe->data.field.iFieldNr, (int)iCurrFld); if (iCurrFld == pTpe->data.field.iFieldNr) { /* field found, now extract it */ /* first of all, we need to find the end */ pFldEnd = pFld; while (*pFldEnd && *pFldEnd != pTpe->data.field.field_delim) ++pFldEnd; --pFldEnd; /* we are already at the delimiter - so we need to * step back a little not to copy it as part of the field. */ /* we got our end pointer, now do the copy */ /* TODO: code copied from below, this is a candidate for a separate function */ iLen = pFldEnd - pFld + 1; /* the +1 is for an actual char, NOT \0! */ pBufStart = pBuf = malloc(iLen + 1); if (pBuf == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } /* now copy */ memcpy(pBuf, pFld, iLen); bufLen = iLen; pBuf[iLen] = '\0'; /* terminate it */ if (*pbMustBeFreed == 1) free(pRes); pRes = pBufStart; *pbMustBeFreed = 1; } else { /* field not found, return error */ if (*pbMustBeFreed == 1) free(pRes); *pbMustBeFreed = 0; *pPropLen = sizeof("**FIELD NOT FOUND**") - 1; return UCHAR_CONSTANT("**FIELD NOT FOUND**"); } #ifdef FEATURE_REGEXP } else { /* Check for regular expressions */ if (pTpe->data.field.has_regex != 0) { if (pTpe->data.field.has_regex == 2) { /* Could not compile regex before! */ if (*pbMustBeFreed == 1) { free(pRes); *pbMustBeFreed = 0; } *pPropLen = sizeof("**NO MATCH** **BAD REGULAR EXPRESSION**") - 1; return UCHAR_CONSTANT("**NO MATCH** **BAD REGULAR EXPRESSION**"); } dbgprintf("string to match for regex is: %s\n", pRes); if (objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { short iTry = 0; uchar bFound = 0; iOffs = 0; /* first see if we find a match, iterating through the series of * potential matches over the string. */ while (!bFound) { int iREstat; iREstat = regexp.regexec(&pTpe->data.field.re, (char *)(pRes + iOffs), nmatch, pmatch, 0); dbgprintf("regexec return is %d\n", iREstat); if (iREstat == 0) { if (pmatch[0].rm_so == -1) { dbgprintf( "oops ... start offset of successful " "regexec is -1\n"); break; } if (iTry == pTpe->data.field.iMatchToUse) { bFound = 1; } else { dbgprintf( "regex found at offset %d, new offset %d, " "tries %d\n", iOffs, (int)(iOffs + pmatch[0].rm_eo), iTry); iOffs += pmatch[0].rm_eo; ++iTry; } } else { break; } } dbgprintf("regex: end search, found %d\n", bFound); if (!bFound) { /* we got no match! */ if (pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) { if (*pbMustBeFreed == 1) { free(pRes); *pbMustBeFreed = 0; } if (pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) { bufLen = sizeof("**NO MATCH**") - 1; pRes = UCHAR_CONSTANT("**NO MATCH**"); } else if (pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_ZERO) { bufLen = 1; pRes = UCHAR_CONSTANT("0"); } else { bufLen = 0; pRes = UCHAR_CONSTANT(""); } } } else { /* Match- but did it match the one we wanted? */ /* we got no match! */ if (pmatch[pTpe->data.field.iSubMatchToUse].rm_so == -1) { if (pTpe->data.field.nomatchAction != TPL_REGEX_NOMATCH_USE_WHOLE_FIELD) { if (*pbMustBeFreed == 1) { free(pRes); *pbMustBeFreed = 0; } if (pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_DFLTSTR) { bufLen = sizeof("**NO MATCH**") - 1; pRes = UCHAR_CONSTANT("**NO MATCH**"); } else if (pTpe->data.field.nomatchAction == TPL_REGEX_NOMATCH_USE_ZERO) { bufLen = 1; pRes = UCHAR_CONSTANT("0"); } else { bufLen = 0; pRes = UCHAR_CONSTANT(""); } } } /* OK, we have a usable match - we now need to malloc pB */ int iLenBuf; uchar *pB; iLenBuf = pmatch[pTpe->data.field.iSubMatchToUse].rm_eo - pmatch[pTpe->data.field.iSubMatchToUse].rm_so; pB = malloc(iLenBuf + 1); if (pB == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } /* Lets copy the matched substring to the buffer */ memcpy(pB, pRes + iOffs + pmatch[pTpe->data.field.iSubMatchToUse].rm_so, iLenBuf); bufLen = iLenBuf; pB[iLenBuf] = '\0'; /* terminate string, did not happen before */ if (*pbMustBeFreed == 1) free(pRes); pRes = pB; *pbMustBeFreed = 1; } } else { /* we could not load regular expression support. This is quite unexpected at * this stage of processing (after all, the config parser found it), but so * it is. We return an error in that case. -- rgerhards, 2008-03-07 */ dbgprintf("could not get regexp object pointer, so regexp can not be evaluated\n"); if (*pbMustBeFreed == 1) { free(pRes); *pbMustBeFreed = 0; } *pPropLen = sizeof("***REGEXP NOT AVAILABLE***") - 1; return UCHAR_CONSTANT("***REGEXP NOT AVAILABLE***"); } } #endif /* #ifdef FEATURE_REGEXP */ } if (pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) { /* we need to obtain a private copy */ int iFrom, iTo; uchar *pSb; iFrom = pTpe->data.field.iFromPos; iTo = pTpe->data.field.iToPos; if (bufLen == -1) bufLen = ustrlen(pRes); if (pTpe->data.field.options.bFromPosEndRelative) { iFrom = (bufLen < iFrom) ? 0 : bufLen - iFrom; iTo = (bufLen < iTo) ? 0 : bufLen - iTo; } else { /* need to zero-base to and from (they are 1-based!) */ if (iFrom > 0) --iFrom; if (iTo > 0) { --iTo; } else if (iTo < 0) { /* note: we ADD negative value, 0-based (-1)! */ iTo = bufLen - 1 + iTo; if (iTo < 0) { iTo = 0; } } } if (iFrom >= bufLen) { DBGPRINTF("msgGetProp: iFrom %d >= buflen %d, returning empty string\n", iFrom, bufLen); if (*pbMustBeFreed == 1) free(pRes); pRes = (uchar *)""; *pbMustBeFreed = 0; bufLen = 0; } else if (iFrom == 0 && iTo >= bufLen && pTpe->data.field.options.bFixedWidth == 0) { /* in this case, the requested string is a superset of what we already have, * so there is no need to do any processing. This is a frequent case for size-limited * fields like TAG in the default forwarding template (so it is a useful optimization * to check for this condition ;)). -- rgerhards, 2009-07-09 */ ; /*DO NOTHING*/ } else { if (iTo >= bufLen) /* iTo is very large, if no to-position is set in the template! */ if (pTpe->data.field.options.bFixedWidth == 0) iTo = bufLen - 1; iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */ pBufStart = pBuf = malloc(iLen + 1); if (pBuf == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } pSb = pRes; if (iFrom) { /* skip to the start of the substring (can't do pointer arithmetic * because the whole string might be smaller!!) */ while (*pSb && iFrom) { --iFrom; ++pSb; } } /* OK, we are at the begin - now let's copy... */ bufLen = iLen; while (iLen) { if (*pSb) { *pBuf++ = *pSb; ++pSb; } else { *pBuf++ = ' '; } --iLen; } *pBuf = '\0'; bufLen -= iLen; /* subtract remaining length if the string was smaller! */ if (*pbMustBeFreed == 1) free(pRes); pRes = pBufStart; *pbMustBeFreed = 1; } } /* now check if we need to do our "SP if first char is non-space" hack logic */ if (*pRes && pTpe->data.field.options.bSPIffNo1stSP) { /* here, we always destruct the buffer and return a new one */ uchar cFirst = *pRes; /* save first char */ if (*pbMustBeFreed == 1) free(pRes); pRes = (cFirst == ' ') ? UCHAR_CONSTANT("") : UCHAR_CONSTANT(" "); bufLen = (cFirst == ' ') ? 0 : 1; *pbMustBeFreed = 0; } if (*pRes) { /* case conversations (should go after substring, because so we are able to * work on the smallest possible buffer). */ if (pTpe->data.field.eCaseConv != tplCaseConvNo) { /* we need to obtain a private copy */ if (bufLen == -1) bufLen = ustrlen(pRes); uchar *pBStart; uchar *pB; uchar *pSrc; pBStart = pB = malloc(bufLen + 1); if (pB == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } pSrc = pRes; while (*pSrc) { *pB++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ? (uchar)toupper((int)*pSrc) : (uchar)tolower((int)*pSrc); /* currently only these two exist */ ++pSrc; } *pB = '\0'; if (*pbMustBeFreed == 1) free(pRes); pRes = pBStart; *pbMustBeFreed = 1; } /* now do control character dropping/escaping/replacement * Only one of these can be used. If multiple options are given, the * result is random (though currently there obviously is an order of * preferrence, see code below. But this is NOT guaranteed. * RGerhards, 2006-11-17 * We must copy the strings if we modify them, because they may either * point to static memory or may point into the message object, in which * case we would actually modify the original property (which of course * is wrong). * This was found and fixed by varmojefkoj on 2007-09-11 */ if (pTpe->data.field.options.bDropCC) { int iLenBuf = 0; uchar *pSrc = pRes; uchar *pDstStart; uchar *pDst; uchar bDropped = 0; while (*pSrc) { if (!iscntrl((int)*pSrc++)) iLenBuf++; else bDropped = 1; } if (bDropped) { pDst = pDstStart = malloc(iLenBuf + 1); if (pDst == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } for (pSrc = pRes; *pSrc; pSrc++) { if (!iscntrl((int)*pSrc)) *pDst++ = *pSrc; } *pDst = '\0'; if (*pbMustBeFreed == 1) free(pRes); pRes = pDstStart; bufLen = iLenBuf; *pbMustBeFreed = 1; } } else if (pTpe->data.field.options.bSpaceCC) { uchar *pSrc; uchar *pDstStart; uchar *pDst; if (*pbMustBeFreed == 1) { /* in this case, we already work on dynamic * memory, so there is no need to copy it - we can * modify it in-place without any harm. This is a * performance optiomization. */ for (pDst = pRes; *pDst; pDst++) { if (iscntrl((int)*pDst)) *pDst = ' '; } } else { if (bufLen == -1) bufLen = ustrlen(pRes); pDst = pDstStart = malloc(bufLen + 1); if (pDst == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } for (pSrc = pRes; *pSrc; pSrc++) { if (iscntrl((int)*pSrc)) *pDst++ = ' '; else *pDst++ = *pSrc; } *pDst = '\0'; pRes = pDstStart; *pbMustBeFreed = 1; } } else if (pTpe->data.field.options.bEscapeCC) { /* we must first count how many control charactes are * present, because we need this to compute the new string * buffer length. While doing so, we also compute the string * length. */ int iNumCC = 0; int iLenBuf = 0; uchar *pSrc; uchar *pB; for (pB = pRes; *pB; ++pB) { ++iLenBuf; if (iscntrl((int)*pB)) ++iNumCC; } if (iNumCC > 0) { /* if 0, there is nothing to escape, so we are done */ /* OK, let's do the escaping... */ uchar *pBStart; uchar szCCEsc[8]; /* buffer for escape sequence */ int i; iLenBuf += iNumCC * 4; pBStart = pB = malloc(iLenBuf + 1); if (pB == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } for (pSrc = pRes; *pSrc; pSrc++) { if (iscntrl((int)*pSrc)) { snprintf((char *)szCCEsc, sizeof(szCCEsc), "#%3.3d", *pSrc); for (i = 0; i < 4; ++i) *pB++ = szCCEsc[i]; } else { *pB++ = *pSrc; } } *pB = '\0'; if (*pbMustBeFreed == 1) free(pRes); pRes = pBStart; bufLen = -1; *pbMustBeFreed = 1; } } } /* Take care of spurious characters to make the property safe * for a path definition */ if (pTpe->data.field.options.bSecPathDrop || pTpe->data.field.options.bSecPathReplace) { if (pTpe->data.field.options.bSecPathDrop) { int iLenBuf = 0; uchar *pSrc = pRes; uchar *pDstStart; uchar *pDst; uchar bDropped = 0; while (*pSrc) { if (*pSrc++ != '/') iLenBuf++; else bDropped = 1; } if (bDropped) { pDst = pDstStart = malloc(iLenBuf + 1); if (pDst == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } for (pSrc = pRes; *pSrc; pSrc++) { if (*pSrc != '/') *pDst++ = *pSrc; } *pDst = '\0'; if (*pbMustBeFreed == 1) free(pRes); pRes = pDstStart; bufLen = -1; /* TODO: can we do better? */ *pbMustBeFreed = 1; } } else { uchar *pSrc; uchar *pDstStart; uchar *pDst; if (*pbMustBeFreed == 1) { /* here, again, we can modify the string as we already obtained * a private buffer. As we do not change the size of that buffer, * in-place modification is possible. This is a performance * enhancement. */ for (pDst = pRes; *pDst; pDst++) { if (*pDst == '/') *pDst++ = '_'; } } else { if (bufLen == -1) bufLen = ustrlen(pRes); pDst = pDstStart = malloc(bufLen + 1); if (pDst == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } for (pSrc = pRes; *pSrc; pSrc++) { if (*pSrc == '/') *pDst++ = '_'; else *pDst++ = *pSrc; } *pDst = '\0'; /* we must NOT check if it needs to be freed, because we have done * this in the if above. So if we come to hear, the pSrc string needs * not to be freed (and we do not need to care about it). */ pRes = pDstStart; *pbMustBeFreed = 1; } } /* check for "." and ".." (note the parenthesis in the if condition!) */ if (*pRes == '\0') { if (*pbMustBeFreed == 1) free(pRes); pRes = UCHAR_CONSTANT("_"); bufLen = 1; *pbMustBeFreed = 0; } else if ((*pRes == '.') && (*(pRes + 1) == '\0' || (*(pRes + 1) == '.' && *(pRes + 2) == '\0'))) { uchar *pTmp = pRes; if (*(pRes + 1) == '\0') pRes = UCHAR_CONSTANT("_"); else pRes = UCHAR_CONSTANT("_."); ; if (*pbMustBeFreed == 1) free(pTmp); *pbMustBeFreed = 0; } } /* Now drop last LF if present (pls note that this must not be done * if bEscapeCC was set)! */ if (pTpe->data.field.options.bDropLastLF && !pTpe->data.field.options.bEscapeCC) { int iLn; uchar *pB; if (bufLen == -1) bufLen = ustrlen(pRes); iLn = bufLen; if (iLn > 0 && *(pRes + iLn - 1) == '\n') { /* we have a LF! */ /* check if we need to obtain a private copy */ if (*pbMustBeFreed == 0) { /* ok, original copy, need a private one */ pB = malloc(iLn + 1); if (pB == NULL) { RET_OUT_OF_MEMORY; } memcpy(pB, pRes, iLn - 1); pRes = pB; *pbMustBeFreed = 1; } *(pRes + iLn - 1) = '\0'; /* drop LF ;) */ --bufLen; } } /* Now everything is squased as much as possible and more or less ready to * go. This is the perfect place to compress any remaining spaces, if so * instructed by the user/config. */ if (pTpe->data.field.options.bCompressSP) { int needCompress = 0; int hadSP = 0; uchar *pB; if (*pbMustBeFreed == 0) { for (pB = pRes; *pB && needCompress == 0; ++pB) { if (*pB == ' ') { if (hadSP) { uchar *const tmp = ustrdup(pRes); if (tmp == NULL) /* better not compress than * loose message. */ break; *pbMustBeFreed = 1; pRes = tmp; needCompress = 1; } else { hadSP = 1; } } } } else { /* If we can modify the buffer in any case, we * do NOT check if we actually need to compress, * but "just do it" - that's the quickest way * to get it done. */ needCompress = 1; } if (needCompress) { hadSP = 0; uchar *pDst = pRes; int needCopy = 0; for (pB = pRes; *pB; ++pB) { if (*pB == ' ') { if (hadSP) { needCopy = 1; } else { hadSP = 1; if (needCopy) *pDst = *pB; ++pDst; } } else { hadSP = 0; if (needCopy) *pDst = *pB; ++pDst; } } *pDst = '\0'; bufLen = pDst - pRes; } } /* finally, we need to check if the property should be formatted in CSV or JSON. * For CSV we use RFC 4180, and always use double quotes. As of this writing, * this should be the last action carried out on the property, but in the * future there may be reasons to change that. -- rgerhards, 2009-04-02 */ if (pTpe->data.field.options.bCSV) { /* we need to obtain a private copy, as we need to at least add the double quotes */ int iBufLen; uchar *pBStart; uchar *pDst; uchar *pSrc; if (bufLen == -1) bufLen = ustrlen(pRes); iBufLen = bufLen; /* the malloc may be optimized, we currently use the worst case... */ pBStart = pDst = malloc(2 * iBufLen + 3); if (pDst == NULL) { if (*pbMustBeFreed == 1) free(pRes); RET_OUT_OF_MEMORY; } pSrc = pRes; *pDst++ = '"'; /* starting quote */ while (*pSrc) { if (*pSrc == '"') *pDst++ = '"'; /* need to add double double quote (see RFC4180) */ *pDst++ = *pSrc++; } *pDst++ = '"'; /* ending quote */ *pDst = '\0'; if (*pbMustBeFreed == 1) free(pRes); pRes = pBStart; bufLen = -1; *pbMustBeFreed = 1; } else if (pTpe->data.field.options.bJSON) { jsonEncode(&pRes, pbMustBeFreed, &bufLen, RSTRUE); } else if (pTpe->data.field.options.bJSONf) { jsonField(pTpe, &pRes, pbMustBeFreed, &bufLen, RSTRUE); } else if (pTpe->data.field.options.bJSONr) { jsonEncode(&pRes, pbMustBeFreed, &bufLen, RSFALSE); } else if (pTpe->data.field.options.bJSONfr) { jsonField(pTpe, &pRes, pbMustBeFreed, &bufLen, RSFALSE); } *pPropLen = (bufLen == -1) ? (int)ustrlen(pRes) : bufLen; return (pRes); } /* Set a single property based on the JSON object provided. The * property name is extracted from the JSON object. */ static rsRetVal msgSetPropViaJSON(smsg_t *__restrict__ const pMsg, const char *name, struct json_object *json, int sharedReference) { const char *psz; int val; prop_t *propFromHost = NULL; prop_t *propRcvFromIP = NULL; int bNeedFree = 1; DEFiRet; /* note: jsonToString() manages the memory of the returned * string. So we MUST NOT free it! */ dbgprintf("DDDD: msgSetPropViaJSON key: '%s'\n", name); if (!strcmp(name, "rawmsg")) { psz = jsonToString(json); MsgSetRawMsg(pMsg, psz, strlen(psz)); } else if (!strcmp(name, "msg")) { psz = jsonToString(json); MsgReplaceMSG(pMsg, (const uchar *)psz, strlen(psz)); } else if (!strcmp(name, "syslogtag")) { psz = jsonToString(json); MsgSetTAG(pMsg, (const uchar *)psz, strlen(psz)); } else if (!strcmp(name, "pri")) { val = json_object_get_int(json); msgSetPRI(pMsg, val); } else if (!strcmp(name, "syslogfacility")) { val = json_object_get_int(json); if (val >= 0 && val <= 24) pMsg->iFacility = val; else DBGPRINTF("mmexternal: invalid fac %d requested -- ignored\n", val); } else if (!strcmp(name, "syslogseverity")) { val = json_object_get_int(json); if (val >= 0 && val <= 7) pMsg->iSeverity = val; else DBGPRINTF("mmexternal: invalid fac %d requested -- ignored\n", val); } else if (!strcmp(name, "procid")) { psz = jsonToString(json); MsgSetPROCID(pMsg, psz); } else if (!strcmp(name, "msgid")) { psz = jsonToString(json); MsgSetMSGID(pMsg, psz); } else if (!strcmp(name, "structured-data")) { psz = jsonToString(json); MsgSetStructuredData(pMsg, psz); } else if (!strcmp(name, "hostname") || !strcmp(name, "source")) { psz = jsonToString(json); MsgSetHOSTNAME(pMsg, (const uchar *)psz, strlen(psz)); } else if (!strcmp(name, "fromhost")) { psz = jsonToString(json); MsgSetRcvFromStr(pMsg, (const uchar *)psz, strlen(psz), &propFromHost); prop.Destruct(&propFromHost); } else if (!strcmp(name, "fromhost-ip")) { psz = jsonToString(json); MsgSetRcvFromIPStr(pMsg, (const uchar *)psz, strlen(psz), &propRcvFromIP); prop.Destruct(&propRcvFromIP); } else if (!strcmp(name, "$!")) { /* msgAddJSON expects that it can keep the object without incremeting * the json reference count. So we MUST NOT free (_put) the object in * this case. -- rgerhards, 2018-09-14 */ bNeedFree = 0; msgAddJSON(pMsg, (uchar *)"!", json, 0, sharedReference); } else { /* we ignore unknown properties */ DBGPRINTF("msgSetPropViaJSON: unkonwn property ignored: %s\n", name); } if (bNeedFree) { json_object_put(json); } RETiRet; } /* set message properties based on JSON string. This function does it all, * including parsing the JSON string. If an error is detected, the operation * is aborted at the time of error. Any modifications made before the * error ocurs are still PERSISTED. * This function is meant to support the external message modifiction module * interface. As such, replacing properties is expressively permited. Note that * properties which were derived from the message during parsing are NOT * updated if the underlying (raw)msg property is changed. */ rsRetVal MsgSetPropsViaJSON(smsg_t *__restrict__ const pMsg, const uchar *__restrict__ const jsonstr) { struct json_tokener *tokener = NULL; struct json_object *json; const char *errMsg; DEFiRet; DBGPRINTF("DDDDDD: JSON string for message mod: '%s'\n", jsonstr); if (!strcmp((char *)jsonstr, "{}")) /* shortcut for a common case */ FINALIZE; tokener = json_tokener_new(); json = json_tokener_parse_ex(tokener, (char *)jsonstr, ustrlen(jsonstr)); if (Debug) { errMsg = NULL; if (json == NULL) { enum json_tokener_error err; err = tokener->err; if (err != json_tokener_continue) errMsg = json_tokener_error_desc(err); else errMsg = "Unterminated input"; } else if (!json_object_is_type(json, json_type_object)) errMsg = "JSON value is not an object"; if (errMsg != NULL) { DBGPRINTF("MsgSetPropsViaJSON: Error parsing JSON '%s': %s\n", jsonstr, errMsg); } } if (json == NULL || !json_object_is_type(json, json_type_object)) { ABORT_FINALIZE(RS_RET_JSON_UNUSABLE); } MsgSetPropsViaJSON_Object(pMsg, json); finalize_it: if (tokener != NULL) json_tokener_free(tokener); RETiRet; } /* Used by MsgSetPropsViaJSON to set properties. * The same as MsgSetPropsViaJSON only that a json object is given and not a string */ rsRetVal MsgSetPropsViaJSON_Object(smsg_t *__restrict__ const pMsg, struct json_object *json) { DEFiRet; if (json == NULL || !json_object_is_type(json, json_type_object)) { DBGPRINTF("MsgSetPropsViaJSON_Object: json NULL or not object type\n"); ABORT_FINALIZE(RS_RET_JSON_UNUSABLE); } struct json_object_iterator it = json_object_iter_begin(json); struct json_object_iterator itEnd = json_object_iter_end(json); while (!json_object_iter_equal(&it, &itEnd)) { struct json_object *child = json_object_iter_peek_value(&it); json_object_get(child); msgSetPropViaJSON(pMsg, json_object_iter_peek_name(&it), child, 0); json_object_iter_next(&it); } json_object_put(json); finalize_it: RETiRet; } /* get the severity - this is an entry point that * satisfies the base object class getSeverity semantics. * rgerhards, 2008-01-14 */ rsRetVal MsgGetSeverity(smsg_t *const pMsg, int *piSeverity) { *piSeverity = pMsg->iSeverity; return RS_RET_OK; } static uchar *jsonPathGetLeaf(uchar *name, int lenName) { int i; for (i = lenName; i >= 0; --i) if (i == 0) { if (name[0] == '!' || name[0] == '.' || name[0] == '/') break; } else { if (name[i] == '!') break; } if (name[i] == '!' || name[i] == '.' || name[i] == '/') ++i; return name + i; } static json_bool jsonVarExtract(struct json_object *root, const char *key, struct json_object **value) { char namebuf[MAX_VARIABLE_NAME_LEN]; int key_len = strlen(key); char *array_idx_start = strstr(key, "["); char *array_idx_end = NULL; char *array_idx_num_end_discovered = NULL; struct json_object *arr = NULL; if (array_idx_start != NULL) { array_idx_end = strstr(array_idx_start, "]"); } if (array_idx_end != NULL && (array_idx_end - key + 1) == key_len) { errno = 0; int idx = (int)strtol(array_idx_start + 1, &array_idx_num_end_discovered, 10); if (errno == 0 && array_idx_num_end_discovered == array_idx_end) { memcpy(namebuf, key, array_idx_start - key); namebuf[array_idx_start - key] = '\0'; json_bool found_obj = json_object_object_get_ex(root, namebuf, &arr); if (found_obj && json_object_is_type(arr, json_type_array)) { int len = json_object_array_length(arr); if (len > idx) { *value = json_object_array_get_idx(arr, idx); if (*value != NULL) return TRUE; } return FALSE; } } } return json_object_object_get_ex(root, key, value); } static rsRetVal jsonPathFindNext( struct json_object *root, uchar *namestart, uchar **name, uchar *leaf, struct json_object **found, int bCreate) { uchar namebuf[MAX_VARIABLE_NAME_LEN]; struct json_object *json; size_t i; uchar *p = *name; DEFiRet; if (*p == '!' || (*name == namestart && (*p == '.' || *p == '/'))) ++p; for (i = 0; *p && !(p == namestart && (*p == '.' || *p == '/')) && *p != '!' && p != leaf && i < sizeof(namebuf) - 1; ++i, ++p) namebuf[i] = *p; if (i > 0) { namebuf[i] = '\0'; if (jsonVarExtract(root, (char *)namebuf, &json) == FALSE) { json = NULL; } } else json = root; if (json == NULL) { if (!bCreate) { ABORT_FINALIZE(RS_RET_JNAME_INVALID); } else { if (json_object_get_type(root) != json_type_object) { DBGPRINTF( "jsonPathFindNext with bCreate: not a container in json path, " "name is '%s'\n", namestart); ABORT_FINALIZE(RS_RET_INVLD_SETOP); } json = json_object_new_object(); json_object_object_add(root, (char *)namebuf, json); } } *name = p; *found = json; finalize_it: RETiRet; } static rsRetVal jsonPathFindParent( struct json_object *jroot, uchar *name, uchar *leaf, struct json_object **parent, const int bCreate) { uchar *namestart; DEFiRet; namestart = name; *parent = jroot; while (name < leaf - 1) { CHKiRet(jsonPathFindNext(*parent, namestart, &name, leaf, parent, bCreate)); } if (*parent == NULL) ABORT_FINALIZE(RS_RET_NOT_FOUND); finalize_it: RETiRet; } static rsRetVal jsonMerge(struct json_object *existing, struct json_object *json) { /* TODO: check & handle duplicate names */ DEFiRet; struct json_object_iterator it = json_object_iter_begin(json); struct json_object_iterator itEnd = json_object_iter_end(json); while (!json_object_iter_equal(&it, &itEnd)) { json_object_object_add(existing, json_object_iter_peek_name(&it), json_object_get(json_object_iter_peek_value(&it))); json_object_iter_next(&it); } /* note: json-c does ref counting. We added all descandants refcounts * in the loop above. So when we now free(_put) the root object, only * root gets freed(). */ json_object_put(json); RETiRet; } /* find a JSON structure element (field or container doesn't matter). */ rsRetVal jsonFind(smsg_t *const pMsg, msgPropDescr_t *pProp, struct json_object **jsonres) { uchar *leaf; struct json_object *parent; struct json_object *field; struct json_object **jroot = NULL; pthread_mutex_t *mut = NULL; DEFiRet; CHKiRet(getJSONRootAndMutex(pMsg, pProp->id, &jroot, &mut)); pthread_mutex_lock(mut); if (*jroot == NULL) { field = NULL; goto finalize_it; } if (!strcmp((char *)pProp->name, "!")) { field = *jroot; } else if (!strcmp((char *)pProp->name, ".")) { field = *jroot; } else { leaf = jsonPathGetLeaf(pProp->name, pProp->nameLen); CHKiRet(jsonPathFindParent(*jroot, pProp->name, leaf, &parent, 0)); if (jsonVarExtract(parent, (char *)leaf, &field) == FALSE) field = NULL; } *jsonres = field; finalize_it: if (mut != NULL) pthread_mutex_unlock(mut); RETiRet; } /* check if JSON variable exists (works on terminal var and container) */ rsRetVal ATTR_NONNULL() msgCheckVarExists(smsg_t *const pMsg, msgPropDescr_t *pProp) { struct json_object *jsonres = NULL; DEFiRet; CHKiRet(jsonFind(pMsg, pProp, &jsonres)); if (jsonres == NULL) { iRet = RS_RET_NOT_FOUND; } finalize_it: RETiRet; } rsRetVal msgAddJSON(smsg_t *const pM, uchar *name, struct json_object *json, int force_reset, int sharedReference) { /* TODO: error checks! This is a quick&dirty PoC! */ struct json_object **jroot; struct json_object *parent, *leafnode; struct json_object *given = NULL; uchar *leaf; pthread_mutex_t *mut = NULL; DEFiRet; CHKiRet(getJSONRootAndMutexByVarChar(pM, name[0], &jroot, &mut)); pthread_mutex_lock(mut); if (name[0] == '/') { /* globl var special handling */ if (sharedReference) { given = json; json = jsonDeepCopy(json); json_object_put(given); } } if (name[1] == '\0') { /* full tree? */ if (*jroot == NULL) *jroot = json; else CHKiRet(jsonMerge(*jroot, json)); } else { if (*jroot == NULL) { /* now we need a root obj */ *jroot = json_object_new_object(); } leaf = jsonPathGetLeaf(name, ustrlen(name)); iRet = jsonPathFindParent(*jroot, name, leaf, &parent, 1); if (unlikely(iRet != RS_RET_OK)) { json_object_put(json); FINALIZE; } if (json_object_get_type(parent) != json_type_object) { DBGPRINTF( "msgAddJSON: not a container in json path," "name is '%s'\n", name); json_object_put(json); ABORT_FINALIZE(RS_RET_INVLD_SETOP); } if (jsonVarExtract(parent, (char *)leaf, &leafnode) == FALSE) leafnode = NULL; /* json-c code indicates we can simply replace a * json type. Unfortunaltely, this is not documented * as part of the interface spec. We still use it, * because it speeds up processing. If it does not work * at some point, use * json_object_object_del(parent, (char*)leaf); * before adding. rgerhards, 2012-09-17 */ if (force_reset || (leafnode == NULL)) { json_object_object_add(parent, (char *)leaf, json); } else { if (json_object_get_type(json) == json_type_object) { CHKiRet(jsonMerge(*jroot, json)); } else { /* TODO: improve the code below, however, the current * state is not really bad */ if (json_object_get_type(leafnode) == json_type_object) { DBGPRINTF( "msgAddJSON: trying to update a container " "node with a leaf, name is %s - " "forbidden", name); json_object_put(json); ABORT_FINALIZE(RS_RET_INVLD_SETOP); } json_object_object_add(parent, (char *)leaf, json); } } } finalize_it: if (mut != NULL) pthread_mutex_unlock(mut); RETiRet; } rsRetVal msgDelJSON(smsg_t *const pM, uchar *name) { struct json_object **jroot; struct json_object *parent, *leafnode; uchar *leaf; pthread_mutex_t *mut = NULL; DEFiRet; CHKiRet(getJSONRootAndMutexByVarChar(pM, name[0], &jroot, &mut)); pthread_mutex_lock(mut); if (*jroot == NULL) { DBGPRINTF("msgDelJSONVar; jroot empty in unset for property %s\n", name); FINALIZE; } if (name[1] == '\0') { /* full tree! Strange, but I think we should permit this. After all, * we trust rsyslog.conf to be written by the admin. */ DBGPRINTF("unsetting JSON root object\n"); json_object_put(*jroot); *jroot = NULL; } else { leaf = jsonPathGetLeaf(name, ustrlen(name)); CHKiRet(jsonPathFindParent(*jroot, name, leaf, &parent, 0)); if (jsonVarExtract(parent, (char *)leaf, &leafnode) == FALSE) leafnode = NULL; if (leafnode == NULL) { DBGPRINTF("unset JSON: could not find '%s'\n", name); ABORT_FINALIZE(RS_RET_JNAME_NOTFOUND); } else { DBGPRINTF( "deleting JSON value path '%s', " "leaf '%s', type %d\n", name, leaf, json_object_get_type(leafnode)); json_object_object_del(parent, (char *)leaf); } } finalize_it: if (mut != NULL) pthread_mutex_unlock(mut); RETiRet; } /* add Metadata to the message. This is stored in a special JSON * container. Note that only string types are currently supported, * what should pose absolutely no problem with the string-ish nature * of rsyslog metadata. * added 2015-01-09 rgerhards */ rsRetVal msgAddMetadata(smsg_t *const __restrict__ pMsg, uchar *const __restrict__ metaname, uchar *const __restrict__ metaval) { DEFiRet; struct json_object *const json = json_object_new_object(); CHKmalloc(json); struct json_object *const jval = json_object_new_string((char *)metaval); if (jval == NULL) { json_object_put(json); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } json_object_object_add(json, (const char *const)metaname, jval); iRet = msgAddJSON(pMsg, (uchar *)"!metadata", json, 0, 0); finalize_it: RETiRet; } rsRetVal msgAddMultiMetadata(smsg_t *const __restrict__ pMsg, const uchar **__restrict__ metaname, const uchar **__restrict__ metaval, const int count) { DEFiRet; int i = 0; struct json_object *const json = json_object_new_object(); CHKmalloc(json); for (i = 0; i < count; i++) { struct json_object *const jval = json_object_new_string((char *)metaval[i]); if (jval == NULL) { json_object_put(json); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } json_object_object_add(json, (const char *const)metaname[i], jval); } iRet = msgAddJSON(pMsg, (uchar *)"!metadata", json, 0, 0); finalize_it: RETiRet; } struct json_object *jsonDeepCopy(struct json_object *src) { struct json_object *dst = NULL, *json; int arrayLen, i; if (src == NULL) goto done; switch (json_object_get_type(src)) { case json_type_boolean: dst = json_object_new_boolean(json_object_get_boolean(src)); break; case json_type_double: dst = json_object_new_double(json_object_get_double(src)); break; case json_type_int: dst = json_object_new_int64(json_object_get_int64(src)); break; case json_type_string: dst = json_object_new_string(jsonToString(src)); break; case json_type_object: dst = json_object_new_object(); struct json_object_iterator it = json_object_iter_begin(src); struct json_object_iterator itEnd = json_object_iter_end(src); while (!json_object_iter_equal(&it, &itEnd)) { json = jsonDeepCopy(json_object_iter_peek_value(&it)); json_object_object_add(dst, json_object_iter_peek_name(&it), json); json_object_iter_next(&it); } break; case json_type_array: arrayLen = json_object_array_length(src); dst = json_object_new_array(); for (i = 0; i < arrayLen; ++i) { json = json_object_array_get_idx(src, i); json = jsonDeepCopy(json); json_object_array_add(dst, json); } break; case json_type_null: default: DBGPRINTF("jsonDeepCopy(): error unknown type %d\n", json_object_get_type(src)); dst = NULL; break; } done: return dst; } rsRetVal msgSetJSONFromVar(smsg_t *const pMsg, uchar *varname, struct svar *v, int force_reset) { struct json_object *json = NULL; char *cstr; DEFiRet; switch (v->datatype) { case 'S': /* string */ cstr = es_str2cstr(v->d.estr, NULL); json = json_object_new_string(cstr); free(cstr); break; case 'N': /* number (integer) */ json = json_object_new_int64(v->d.n); break; case 'J': /* native JSON */ json = jsonDeepCopy(v->d.json); break; default: DBGPRINTF("msgSetJSONFromVar: unsupported datatype %c\n", v->datatype); ABORT_FINALIZE(RS_RET_ERR); } msgAddJSON(pMsg, varname, json, force_reset, 0); finalize_it: RETiRet; } rsRetVal MsgAddToStructuredData(smsg_t *const pMsg, uchar *toadd, rs_size_t len) { uchar *newptr; rs_size_t newlen; int empty; DEFiRet; empty = pMsg->pszStrucData == NULL || pMsg->pszStrucData[0] == '-'; newlen = (empty) ? len : pMsg->lenStrucData + len; CHKmalloc(newptr = (uchar *)realloc(pMsg->pszStrucData, newlen + 1)); if (empty) { memcpy(newptr, toadd, len); } else { memcpy(newptr + pMsg->lenStrucData, toadd, len); } pMsg->pszStrucData = newptr; pMsg->pszStrucData[newlen] = '\0'; pMsg->lenStrucData = newlen; finalize_it: RETiRet; } /* Fill a message propert description. Space must already be alloced * by the caller. This is for efficiency, as we expect this to happen * as part of a larger structure alloc. * Note that CEE/LOCAL_VAR properties can come in either as * "$!xx"/"$.xx" or "!xx"/".xx" - we will unify them here. */ rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen) { propid_t id; int offs; DEFiRet; if (propNameToID(name, &id) != RS_RET_OK) { parser_errmsg("invalid property '%s'", name); /* now try to find some common error causes */ if (!strcasecmp((char *)name, "myhostname")) parser_errmsg( "did you mean '$myhostname' instead of '%s'? " "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "bom")) parser_errmsg( "did you mean '$bom' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "now")) parser_errmsg( "did you mean '$now' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "year")) parser_errmsg( "did you mean '$year' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "month")) parser_errmsg( "did you mean '$month' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "day")) parser_errmsg( "did you mean '$day' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "hour")) parser_errmsg( "did you mean '$hour' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "hhour")) parser_errmsg( "did you mean '$hhour' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "qhour")) parser_errmsg( "did you mean '$qhour' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "minute")) parser_errmsg( "did you mean '$minute' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "now-utc")) parser_errmsg( "did you mean '$now-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "year-utc")) parser_errmsg( "did you mean '$year-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "month-utc")) parser_errmsg( "did you mean '$month-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "day-utc")) parser_errmsg( "did you mean '$day-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "hour-utc")) parser_errmsg( "did you mean '$hour-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "hhour-utc")) parser_errmsg( "did you mean '$hhour-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "qhour-utc")) parser_errmsg( "did you mean '$qhour-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); else if (!strcasecmp((char *)name, "minute-utc")) parser_errmsg( "did you mean '$minute-utc' instead of '%s'?" "See also: https://www.rsyslog.com/rsyslog-info-1/", name); ABORT_FINALIZE(RS_RET_INVLD_PROP); } if (id == PROP_CEE || id == PROP_LOCAL_VAR || id == PROP_GLOBAL_VAR) { /* in these cases, we need the field name for later processing */ /* normalize name: remove $ if present */ offs = (name[0] == '$') ? 1 : 0; pProp->name = ustrdup(name + offs); pProp->nameLen = nameLen - offs; /* we patch the root name, so that support functions do not need to * check for different root chars. */ pProp->name[0] = '!'; } pProp->id = id; finalize_it: RETiRet; } void msgPropDescrDestruct(msgPropDescr_t *pProp) { if (pProp != NULL) { if (pProp->id == PROP_CEE || pProp->id == PROP_LOCAL_VAR || pProp->id == PROP_GLOBAL_VAR) free(pProp->name); } } /* dummy */ static rsRetVal msgQueryInterface(interface_t __attribute__((unused)) * i) { return RS_RET_NOT_IMPLEMENTED; } /* Initialize the message class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-01-04 */ BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE) pthread_mutex_init(&glblVars_lock, NULL); /* request objects we use */ CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(var, CORE_COMPONENT)); /* set our own handlers */ OBJSetMethodHandler(objMethod_SERIALIZE, MsgSerialize); /* some more inits */ #ifdef HAVE_MALLOC_TRIM INIT_ATOMIC_HELPER_MUT(mutTrimCtr); #endif ENDObjClassInit(msg) rsyslog-8.2512.0/runtime/PaxHeaders/errmsg.c0000644000000000000000000000013215071746523015671 xustar0030 mtime=1760021843.861421349 30 atime=1764930987.880809561 30 ctime=1764935923.190576688 rsyslog-8.2512.0/runtime/errmsg.c0000664000175000017500000002151715071746523015343 0ustar00rgerrger/* The errmsg object. * * Module begun 2008-03-05 by Rainer Gerhards, based on some code * from syslogd.c. I converted this module to lgpl and have checked that * all contributors agreed to that step. * Now moving to ASL 2.0, and contributor checks tell that there is no need * to take further case, as the code now boils to be either my own or, a few lines, * of the original BSD-licenses sysklogd code. rgerhards, 2012-01-16 * * Copyright 2008-2018 Adiscon GmbH. * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "obj.h" #include "msg.h" #include "errmsg.h" #include "operatingstate.h" #include "srUtils.h" #include "stringbuf.h" #include "rsconf.h" /* static data */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif static int bHadErrMsgs; /* indicates if we had error messages since reset of this flag * This is used to abort a run if the config is unclean. */ static int fdOversizeMsgLog = -1; static pthread_mutex_t oversizeMsgLogMut = PTHREAD_MUTEX_INITIALIZER; /* ------------------------------ methods ------------------------------ */ /* Resets the error message flag. Must be done before processing config * files. */ void resetErrMsgsFlag(void) { bHadErrMsgs = 0; } int hadErrMsgs(void) { return bHadErrMsgs; } /** @internal * Build and emit a single diagnostic line. * * - If iErrno != 0, append strerror(iErrno). * - If iErrCode is neither NO_ERRCODE nor RS_RET_ERR, append a help URL. * - Truncate to the configured max line length. * - Set the "had error" flag for LOG_ERR. */ static void doLogMsg(const int iErrno, const int iErrCode, const int severity, const char *msg) { char buf[2048]; char errStr[1024]; dbgprintf("Called LogMsg, msg: %s\n", msg); osf_write(OSF_TAG_MSG, msg); if (iErrno != 0) { rs_strerror_r(iErrno, errStr, sizeof(errStr)); if (iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(buf, sizeof(buf), "%s: %s [v%s]", msg, errStr, VERSION); } else { snprintf(buf, sizeof(buf), "%s: %s [v%s try https://www.rsyslog.com/e/%d ]", msg, errStr, VERSION, iErrCode * -1); } } else { if (iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) { snprintf(buf, sizeof(buf), "%s [v%s]", msg, VERSION); } else { snprintf(buf, sizeof(buf), "%s [v%s try https://www.rsyslog.com/e/%d ]", msg, VERSION, iErrCode * -1); } } buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ errno = 0; const int msglen = (int)strlen(buf); if (msglen > glblGetMaxLine(ourConf)) { /* in extreme cases, our error messages may be longer than the configured * max message size. If so, we just truncate without further indication, as * anything else would probably lead to a death loop on error messages. * Note that we do not split, as we really do not anticipate there is * much value in supporting extremely short max message sizes - we assume * it's just a testbench thing. -- rgerhards, 2018-05-11 */ buf[glblGetMaxLine(ourConf)] = '\0'; /* space must be available! */ } glblErrLogger(severity, iErrCode, (uchar *)buf); if (severity == LOG_ERR) bHadErrMsgs = 1; } /* We now receive three parameters: one is the internal error code * which will also become the error message number, the second is * errno - if it is non-zero, the corresponding error message is included * in the text and finally the message text itself. Note that it is not * 100% clean to use the internal errcode, as it may be reached from * multiple actual error causes. However, it is much better than having * no error code at all (and in most cases, a single internal error code * maps to a specific error event). * rgerhards, 2008-06-27 */ void __attribute__((format(printf, 3, 4))) LogError(const int iErrno, const int iErrCode, const char *fmt, ...) { va_list ap; char buf[2048]; int lenBuf; va_start(ap, fmt); lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap); if (lenBuf < 0) { strncpy(buf, "error message lost due to problem with vsnprintf", sizeof(buf)); } va_end(ap); buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ doLogMsg(iErrno, iErrCode, LOG_ERR, buf); } /* We now receive three parameters: one is the internal error code * which will also become the error message number, the second is * errno - if it is non-zero, the corresponding error message is included * in the text and finally the message text itself. Note that it is not * 100% clean to use the internal errcode, as it may be reached from * multiple actual error causes. However, it is much better than having * no error code at all (and in most cases, a single internal error code * maps to a specific error event). * rgerhards, 2008-06-27 */ void __attribute__((format(printf, 4, 5))) LogMsg( const int iErrno, const int iErrCode, const int severity, const char *fmt, ...) { va_list ap; char buf[2048]; int lenBuf; va_start(ap, fmt); lenBuf = vsnprintf(buf, sizeof(buf), fmt, ap); if (lenBuf < 0) { strncpy(buf, "error message lost due to problem with vsnprintf", sizeof(buf)); } va_end(ap); buf[sizeof(buf) - 1] = '\0'; /* just to be on the safe side... */ doLogMsg(iErrno, iErrCode, severity, buf); } /* Write an oversize message to the oversize message error log. * We do NOT handle errors during writing that log other than emitting * yet another error message. The reason is that there really is nothing * else that we could do in that case. * rgerhards, 2018-05-03 */ rsRetVal ATTR_NONNULL() writeOversizeMessageLog(const smsg_t *const pMsg) { struct json_object *json = NULL; char *rendered = NULL; struct json_object *jval; uchar *buf; size_t toWrite; ssize_t wrRet; int dummy; int mutexLocked = 0; DEFiRet; ISOBJ_TYPE_assert(pMsg, msg); if (glblGetOversizeMsgErrorFile(runConf) == NULL) { FINALIZE; } pthread_mutex_lock(&oversizeMsgLogMut); mutexLocked = 1; if (fdOversizeMsgLog == -1) { fdOversizeMsgLog = open((char *)glblGetOversizeMsgErrorFile(runConf), O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fdOversizeMsgLog == -1) { LogError(errno, RS_RET_ERR, "error opening oversize message log file %s", glblGetOversizeMsgErrorFile(runConf)); FINALIZE; } } assert(fdOversizeMsgLog != -1); json = json_object_new_object(); if (json == NULL) { FINALIZE; } getRawMsg(pMsg, &buf, &dummy); jval = json_object_new_string((char *)buf); json_object_object_add(json, "rawmsg", jval); getInputName(pMsg, &buf, &dummy); jval = json_object_new_string((char *)buf); json_object_object_add(json, "input", jval); CHKmalloc(rendered = strdup((char *)fjson_object_to_json_string(json))); toWrite = strlen(rendered) + 1; /* Note: we overwrite the '\0' terminator with '\n' -- so we avoid * calling malloc() -- write() does NOT need '\0'! */ rendered[toWrite - 1] = '\n'; /* NO LONGER A STRING! */ wrRet = write(fdOversizeMsgLog, rendered, toWrite); if (wrRet != (ssize_t)toWrite) { LogError(errno, RS_RET_IO_ERROR, "error writing oversize message log file %s, write returned %lld", glblGetOversizeMsgErrorFile(runConf), (long long)wrRet); } finalize_it: free(rendered); if (mutexLocked) { pthread_mutex_unlock(&oversizeMsgLogMut); } if (json != NULL) { fjson_object_put(json); } RETiRet; } void errmsgDoHUP(void) { pthread_mutex_lock(&oversizeMsgLogMut); if (fdOversizeMsgLog != -1) { close(fdOversizeMsgLog); fdOversizeMsgLog = -1; } pthread_mutex_unlock(&oversizeMsgLogMut); } void errmsgExit(void) { if (fdOversizeMsgLog != -1) { close(fdOversizeMsgLog); } } rsyslog-8.2512.0/runtime/PaxHeaders/hashtable.c0000644000000000000000000000013215055605325016321 xustar0030 mtime=1756826325.645800623 30 atime=1764931000.146013961 30 ctime=1764935923.297578326 rsyslog-8.2512.0/runtime/hashtable.c0000664000175000017500000002541415055605325015773 0ustar00rgerrger/* Copyright (C) 2004 Christopher Clark */ /* taken from http://www.cl.cam.ac.uk/~cwc22/hashtable/ */ #include "hashtable_private.h" #include #include #include #include /* this code has several warnings, but we ignore them because * this seems to work and we do not want to engage in that code body. If * we really run into troubles, it is better to change to libfastjson, which * we should do in the medium to long term anyhow... */ #ifdef __GNUC__ #pragma GCC diagnostic ignored "-Wredundant-decls" #endif /* Credit for primes table: Aaron Krowne http://br.endernet.org/~akrowne/ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html */ static const unsigned int primes[] = {53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741}; const unsigned int prime_table_length = sizeof(primes) / sizeof(primes[0]); #define MAX_LOAD_FACTOR 65 /* to get real factor, divide by 100! */ /* compute max load. We use a constant factor of 0.65, but do * everything times 100, so that we do not need floats. */ static inline unsigned getLoadLimit(unsigned size) { return (unsigned int)((unsigned long long)size * MAX_LOAD_FACTOR) / 100; } /*****************************************************************************/ struct hashtable *create_hashtable(unsigned int minsize, unsigned int (*hashf)(void *), int (*eqf)(void *, void *), void (*dest)(void *)) { struct hashtable *h; unsigned int pindex, size = primes[0]; /* Check requested hashtable isn't too large */ if (minsize > (1u << 30)) return NULL; /* Enforce size as prime */ for (pindex = 0; pindex < prime_table_length; pindex++) { if (primes[pindex] > minsize) { size = primes[pindex]; break; } } h = (struct hashtable *)malloc(sizeof(struct hashtable)); if (NULL == h) return NULL; /*oom*/ h->table = (struct entry **)malloc(sizeof(struct entry *) * size); if (NULL == h->table) { free(h); return NULL; } /*oom*/ memset(h->table, 0, size * sizeof(struct entry *)); h->tablelength = size; h->primeindex = pindex; h->entrycount = 0; h->hashfn = hashf; h->eqfn = eqf; h->dest = dest; h->loadlimit = getLoadLimit(size); return h; } /*****************************************************************************/ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif unsigned int #if defined(__clang__) __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif hash(struct hashtable *h, void *k) { /* Aim to protect against poor hash functions by adding logic here * - logic taken from java 1.4 hashtable source */ unsigned int i = h->hashfn(k); i += ~(i << 9); i ^= ((i >> 14) | (i << 18)); /* >>> */ i += (i << 4); i ^= ((i >> 10) | (i << 22)); /* >>> */ return i; } /*****************************************************************************/ static int hashtable_expand(struct hashtable *h) { /* Double the size of the table to accomodate more entries */ struct entry **newtable; struct entry *e; struct entry **pE; unsigned int newsize, i, idx; /* Check we're not hitting max capacity */ if (h->primeindex == (prime_table_length - 1)) return 0; newsize = primes[++(h->primeindex)]; newtable = (struct entry **)malloc(sizeof(struct entry *) * newsize); if (NULL != newtable) { memset(newtable, 0, newsize * sizeof(struct entry *)); /* This algorithm is not 'stable'. ie. it reverses the list * when it transfers entries between the tables */ for (i = 0; i < h->tablelength; i++) { while (NULL != (e = h->table[i])) { h->table[i] = e->next; idx = indexFor(newsize, e->h); e->next = newtable[idx]; newtable[idx] = e; } } free(h->table); h->table = newtable; } /* Plan B: realloc instead */ else { newtable = (struct entry **)realloc(h->table, newsize * sizeof(struct entry *)); if (NULL == newtable) { (h->primeindex)--; return 0; } h->table = newtable; memset(&newtable[h->tablelength], 0, (newsize - h->tablelength) * sizeof(struct entry *)); for (i = 0; i < h->tablelength; i++) { for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) { idx = indexFor(newsize, e->h); if (idx == i) { pE = &(e->next); } else { *pE = e->next; e->next = newtable[idx]; newtable[idx] = e; } } } } h->tablelength = newsize; h->loadlimit = getLoadLimit(newsize); return -1; } /*****************************************************************************/ unsigned int hashtable_count(struct hashtable *h) { return h->entrycount; } /*****************************************************************************/ int hashtable_insert(struct hashtable *h, void *k, void *v) { /* This method allows duplicate keys - but they shouldn't be used */ unsigned int idx; struct entry *e; if (++(h->entrycount) > h->loadlimit) { /* Ignore the return value. If expand fails, we should * still try cramming just this value into the existing table * -- we may not have memory for a larger table, but one more * element may be ok. Next time we insert, we'll try expanding again.*/ hashtable_expand(h); } e = (struct entry *)malloc(sizeof(struct entry)); if (NULL == e) { --(h->entrycount); return 0; } /*oom*/ e->h = hash(h, k); idx = indexFor(h->tablelength, e->h); e->k = k; e->v = v; e->next = h->table[idx]; h->table[idx] = e; return -1; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_search(struct hashtable *h, void *k) { struct entry *e; unsigned int hashvalue, idx; hashvalue = hash(h, k); idx = indexFor(h->tablelength, hashvalue); e = h->table[idx]; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v; e = e->next; } return NULL; } /*****************************************************************************/ void * /* returns value associated with key */ hashtable_remove(struct hashtable *h, void *k) { /* TODO: consider compacting the table when the load factor drops enough, * or provide a 'compact' method. */ struct entry *e; struct entry **pE; void *v; unsigned int hashvalue, idx; hashvalue = hash(h, k); idx = indexFor(h->tablelength, hash(h, k)); pE = &(h->table[idx]); e = *pE; while (NULL != e) { /* Check hash value to short circuit heavier comparison */ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) { *pE = e->next; h->entrycount--; v = e->v; freekey(e->k); free(e); return v; } pE = &(e->next); e = e->next; } return NULL; } /*****************************************************************************/ /* destroy */ void hashtable_destroy(struct hashtable *h, int free_values) { unsigned int i; struct entry *e, *f; struct entry **table = h->table; if (free_values) { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); if (h->dest == NULL) free(f->v); else h->dest(f->v); free(f); } } } else { for (i = 0; i < h->tablelength; i++) { e = table[i]; while (NULL != e) { f = e; e = e->next; freekey(f->k); free(f); } } } free(h->table); free(h); } /* some generic hash functions */ /* one provided by Aaaron Wiebe based on perl's hashing algorithm * (so probably pretty generic). Not for excessively large strings! */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif unsigned __attribute__((nonnull(1))) int #if defined(__clang__) __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif hash_from_string(void *k) { char *rkey = (char *)k; unsigned hashval = 1; while (*rkey) hashval = hashval * 33 + *rkey++; return hashval; } int key_equals_string(void *key1, void *key2) { /* we must return true IF the keys are equal! */ return !strcmp(key1, key2); } /* * Copyright (c) 2002, Christopher Clark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ rsyslog-8.2512.0/runtime/PaxHeaders/lmcry_ossl.h0000644000000000000000000000013215055605325016561 xustar0030 mtime=1756826325.647800653 30 atime=1764931130.891155354 30 ctime=1764935923.331578846 rsyslog-8.2512.0/runtime/lmcry_ossl.h0000664000175000017500000000242315055605325016226 0ustar00rgerrger/* An implementation of the cryprov interface for openssl. * * * This file is part of the rsyslog runtime library. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef INCLUDED_LMCRY_OSSL_H #define INCLUDED_LMCRY_OSSL_H #include "cryprov.h" /* interface is defined in cryprov.h, we just implement it! */ #define lmcry_gcryCURR_IF_VERSION cryprovCURR_IF_VERSION typedef cryprov_if_t lmcry_ossl_if_t; /* the lmcry_ossl object */ struct lmcry_ossl_s { BEGINobjInstance ; /* Data to implement generic object - MUST be the first data element! */ osslctx ctx; }; typedef struct lmcry_ossl_s lmcry_ossl_t; /* prototypes */ PROTOTYPEObj(lmcry_ossl); #endif /* #ifndef INCLUDED_LMCRY_GCRY_H */ rsyslog-8.2512.0/runtime/PaxHeaders/conf.c0000644000000000000000000000013215055605325015313 xustar0030 mtime=1756826325.643800593 30 atime=1764930981.561703993 30 ctime=1764935923.137575876 rsyslog-8.2512.0/runtime/conf.c0000664000175000017500000004627615055605325014776 0ustar00rgerrger/* The config file handler (not yet a real object) * * This file is based on an excerpt from syslogd.c, which dates back * much later. I began the file on 2008-02-19 as part of the modularization * effort. Over time, a clean abstration will become even more important * because the config file handler will by dynamically be loaded and be * kept in memory only as long as the config file is actually being * processed. Thereafter, it shall be unloaded. -- rgerhards * Please note that the original syslogd.c source was under BSD license * at the time of the rsyslog fork from sysklogd. * * Copyright 2008-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define CFGLNSIZ 64 * 1024 /* the maximum size of a configuration file line, after re-combination */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBGEN_H #ifndef OS_SOLARIS #include #endif #endif #include "rsyslog.h" #include "dirty.h" #include "parse.h" #include "action.h" #include "template.h" #include "cfsysline.h" #include "modules.h" #include "outchannel.h" #include "stringbuf.h" #include "conf.h" #include "stringbuf.h" #include "srUtils.h" #include "errmsg.h" #include "net.h" #include "ruleset.h" #include "rsconf.h" #include "unicode-helper.h" #include "rainerscript.h" #ifdef OS_SOLARIS #define NAME_MAX MAXNAMELEN #endif /* forward definitions */ /* static data */ DEFobjStaticHelpers; DEFobjCurrIf(module) DEFobjCurrIf(net) DEFobjCurrIf(ruleset) int bConfStrictScoping = 0; /* force strict scoping during config processing? */ /* The following module-global variables are used for building * tag and host selector lines during startup and config reload. * This is stored as a global variable pool because of its ease. It is * also fairly compatible with multi-threading as the stratup code must * be run in a single thread anyways. So there can be no race conditions. * rgerhards 2005-10-18 */ EHostnameCmpMode eDfltHostnameCmpMode = HN_NO_COMP; cstr_t *pDfltHostnameCmp = NULL; cstr_t *pDfltProgNameCmp = NULL; /* process a $ModLoad config line. */ static rsRetVal doModLoad(uchar **pp, __attribute__((unused)) void *pVal) { DEFiRet; uchar szName[512]; uchar *pModName; assert(pp != NULL); assert(*pp != NULL); skipWhiteSpace(pp); /* skip over any whitespace */ if (getSubString(pp, (char *)szName, sizeof(szName), ' ') != 0) { LogError(0, RS_RET_NOT_FOUND, "could not extract module name"); ABORT_FINALIZE(RS_RET_NOT_FOUND); } skipWhiteSpace(pp); /* skip over any whitespace */ /* this below is a quick and dirty hack to provide compatibility with the * $ModLoad MySQL forward compatibility statement. This needs to be supported * for legacy format. */ if (!strcmp((char *)szName, "MySQL")) pModName = (uchar *)"ommysql.so"; else pModName = szName; CHKiRet(module.Load(pModName, 1, NULL)); finalize_it: RETiRet; } /* remove leading spaces from name; this "fixes" some anomalies in * getSubString(), but I was not brave enough to fix the former as * it has many other callers... -- rgerhards, 2013-05-27 */ static void ltrim(char *src) { char *dst = src; while (isspace(*src)) ++src; /*SKIP*/ ; if (dst != src) { while (*src != '\0') *dst++ = *src++; *dst = '\0'; } } /* parse and interpret a $-config line that starts with * a name (this is common code). It is parsed to the name * and then the proper sub-function is called to handle * the actual directive. * rgerhards 2004-11-17 * rgerhards 2005-06-21: previously only for templates, now * generalized. */ static rsRetVal doNameLine(uchar **pp, void *pVal) { DEFiRet; uchar *p; enum eDirective eDir; char szName[128]; assert(pp != NULL); p = *pp; assert(p != NULL); PRAGMA_DIAGNOSTIC_PUSH PRAGMA_IGNORE_Wvoid_pointer_to_enum_cast; /* this time, pVal actually is NOT a pointer! It is save to case, as * the enum was written to it, so there can be no loss of bits (ptr is larger). */ eDir = (enum eDirective)pVal; PRAGMA_DIAGNOSTIC_POP if (getSubString(&p, szName, sizeof(szName), ',') != 0) { LogError(0, RS_RET_NOT_FOUND, "Invalid config line: could not extract name - line ignored"); ABORT_FINALIZE(RS_RET_NOT_FOUND); } ltrim(szName); if (*p == ',') ++p; /* comma was eaten */ /* we got the name - now we pass name & the rest of the string * to the subfunction. It makes no sense to do further * parsing here, as this is in close interaction with the * respective subsystem. rgerhards 2004-11-17 */ switch (eDir) { case DIR_TEMPLATE: tplAddLine(loadConf, szName, &p); break; case DIR_OUTCHANNEL: ochAddLine(szName, &p); break; case DIR_ALLOWEDSENDER: net.addAllowedSenderLine(szName, &p); break; default: /* we do this to avoid compiler warning - not all * enum values call this function, so an incomplete list * is quite ok (but then we should not run into this code, * so at least we log a debug warning). */ dbgprintf("INTERNAL ERROR: doNameLine() called with invalid eDir %d.\n", eDir); break; } *pp = p; finalize_it: RETiRet; } /* Parse and interpret a system-directive in the config line * A system directive is one that starts with a "$" sign. It offers * extended configuration parameters. * 2004-11-17 rgerhards */ static rsRetVal cfsysline(uchar *p) { DEFiRet; uchar szCmd[64]; assert(p != NULL); errno = 0; if (getSubString(&p, (char *)szCmd, sizeof(szCmd), ' ') != 0) { LogError(0, RS_RET_NOT_FOUND, "Invalid $-configline " "- could not extract command - line ignored\n"); ABORT_FINALIZE(RS_RET_NOT_FOUND); } /* we now try and see if we can find the command in the registered * list of cfsysline handlers. -- rgerhards, 2007-07-31 */ CHKiRet(processCfSysLineCommand(szCmd, &p)); /* now check if we have some extra characters left on the line - that * should not be the case. Whitespace is OK, but everything else should * trigger a warning (that may be an indication of undesired behaviour). * An exception, of course, are comments (starting with '#'). * rgerhards, 2007-07-04 */ skipWhiteSpace(&p); if (*p && *p != '#') { /* we have a non-whitespace, so let's complain */ LogError(0, NO_ERRCODE, "error: extra characters in config line ignored: '%s'", p); } finalize_it: RETiRet; } /* Helper to cfline() and its helpers. Parses a template name * from an "action" line. Must be called with the Line pointer * pointing to the first character after the semicolon. * rgerhards 2004-11-19 * changed function to work with OMSR. -- rgerhards, 2007-07-27 * the default template is to be used when no template is specified. */ rsRetVal cflineParseTemplateName(uchar **pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName) { uchar *p; uchar *tplName = NULL; cstr_t *pStrB = NULL; DEFiRet; assert(pp != NULL); assert(*pp != NULL); assert(pOMSR != NULL); p = *pp; /* a template must follow - search it and complain, if not found */ skipWhiteSpace(&p); if (*p == ';') ++p; /* eat it */ else if (*p != '\0' && *p != '#') { LogError(0, RS_RET_ERR, "invalid character in selector line - ';template' expected"); ABORT_FINALIZE(RS_RET_ERR); } skipWhiteSpace(&p); /* go to begin of template name */ if (*p == '\0' || *p == '#') { /* no template specified, use the default */ CHKmalloc(tplName = (uchar *)strdup((char *)dfltTplName)); } else { /* template specified, pick it up */ CHKiRet(cstrConstruct(&pStrB)); /* now copy the string */ while (*p && *p != '#' && !isspace((int)*p)) { CHKiRet(cstrAppendChar(pStrB, *p)); ++p; } cstrFinalize(pStrB); CHKiRet(cstrConvSzStrAndDestruct(&pStrB, &tplName, 0)); } CHKiRet(OMSRsetEntry(pOMSR, iEntry, tplName, iTplOpts)); finalize_it: if (iRet != RS_RET_OK) { free(tplName); if (pStrB != NULL) cstrDestruct(&pStrB); } *pp = p; RETiRet; } /* Helper to cfline(). Parses a file name up until the first * comma and then looks for the template specifier. Tries * to find that template. * rgerhards 2004-11-18 * parameter pFileName must point to a buffer large enough * to hold the largest possible filename. * rgerhards, 2007-07-25 * updated to include OMSR pointer -- rgerhards, 2007-07-27 * updated to include template name -- rgerhards, 2008-03-28 * rgerhards, 2010-01-19: file names end at the first space */ rsRetVal cflineParseFileName( uchar *p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *pszTpl) { register uchar *pName; int i; DEFiRet; assert(pOMSR != NULL); pName = pFileName; i = 1; /* we start at 1 so that we reseve space for the '\0'! */ while (*p && *p != ';' && *p != ' ' && i < MAXFNAME) { *pName++ = *p++; ++i; } *pName = '\0'; iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, pszTpl); RETiRet; } /* Decode a traditional PRI filter */ /* GPLv3 - stems back to sysklogd */ rsRetVal DecodePRIFilter(uchar *pline, uchar pmask[]) { uchar *p; register uchar *q; register int i, i2; uchar *bp; int pri; /* this MUST be int, as -1 is used to convey an error state */ int singlpri = 0; int ignorepri = 0; uchar buf[2048]; /* buffer for facility and priority names */ uchar xbuf[200]; DEFiRet; assert(pline != NULL); dbgprintf("Decoding traditional PRI filter '%s'\n", pline); for (i = 0; i <= LOG_NFACILITIES; i++) { pmask[i] = TABLE_NOPRI; } /* scan through the list of selectors */ for (p = pline; *p && *p != '\t' && *p != ' ';) { /* find the end of this facility name list */ for (q = p; *q && *q != '\t' && *q++ != '.';) continue; /* collect priority name */ for (bp = buf; *q && !strchr("\t ,;", *q) && bp < buf + sizeof(buf) - 1;) *bp++ = *q++; *bp = '\0'; /* skip cruft */ if (*q) { while (strchr(",;", *q)) q++; } /* decode priority name */ if (*buf == '!') { ignorepri = 1; /* copy below is ok, we can NOT go off the allocated area */ for (bp = buf; *(bp + 1); bp++) *bp = *(bp + 1); *bp = '\0'; } else { ignorepri = 0; } if (*buf == '=') { singlpri = 1; pri = decodeSyslogName(&buf[1], syslogPriNames); } else { singlpri = 0; pri = decodeSyslogName(buf, syslogPriNames); } if (pri < 0) { snprintf((char *)xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf); LogError(0, RS_RET_ERR, "%s", xbuf); return RS_RET_ERR; } /* scan facilities */ while (*p && !strchr("\t .;", *p)) { for (bp = buf; *p && !strchr("\t ,;.", *p) && bp < buf + sizeof(buf) - 1;) *bp++ = *p++; *bp = '\0'; if (*buf == '*') { for (i = 0; i <= LOG_NFACILITIES; i++) { if (pri == INTERNAL_NOPRI) { if (ignorepri) pmask[i] = TABLE_ALLPRI; else pmask[i] = TABLE_NOPRI; } else if (singlpri) { if (ignorepri) pmask[i] &= ~(1 << pri); else pmask[i] |= (1 << pri); } else { if (pri == TABLE_ALLPRI) { if (ignorepri) pmask[i] = TABLE_NOPRI; else pmask[i] = TABLE_ALLPRI; } else { if (ignorepri) for (i2 = 0; i2 <= pri; ++i2) pmask[i] &= ~(1 << i2); else for (i2 = 0; i2 <= pri; ++i2) pmask[i] |= (1 << i2); } } } } else { i = decodeSyslogName(buf, syslogFacNames); if (i < 0) { snprintf((char *)xbuf, sizeof(xbuf), "unknown facility name \"%s\"", buf); LogError(0, RS_RET_ERR, "%s", xbuf); return RS_RET_ERR; } if (pri == INTERNAL_NOPRI) { if (ignorepri) pmask[i >> 3] = TABLE_ALLPRI; else pmask[i >> 3] = TABLE_NOPRI; } else if (singlpri) { if (ignorepri) pmask[i >> 3] &= ~(1 << pri); else pmask[i >> 3] |= (1 << pri); } else { if (pri == TABLE_ALLPRI) { if (ignorepri) pmask[i >> 3] = TABLE_NOPRI; else pmask[i >> 3] = TABLE_ALLPRI; } else { if (ignorepri) for (i2 = 0; i2 <= pri; ++i2) pmask[i >> 3] &= ~(1 << i2); else for (i2 = 0; i2 <= pri; ++i2) pmask[i >> 3] |= (1 << i2); } } } while (*p == ',' || *p == ' ') p++; } p = q; } RETiRet; } /* process the action part of a selector line * rgerhards, 2007-08-01 */ rsRetVal cflineDoAction(rsconf_t *conf, uchar **p, action_t **ppAction) { modInfo_t *pMod; cfgmodules_etry_t *node; omodStringRequest_t *pOMSR; int bHadWarning = 0; action_t *pAction = NULL; void *pModData; DEFiRet; assert(p != NULL); assert(ppAction != NULL); /* loop through all modules and see if one picks up the line */ node = module.GetNxtCnfType(conf, NULL, eMOD_OUT); /* Note: clang static analyzer reports that node maybe == NULL. However, this is * not possible, because we have the built-in output modules which are always * present. Anyhow, we guard this by an assert. -- rgerhards, 2010-12-16 */ assert(node != NULL); while (node != NULL) { pOMSR = NULL; pMod = node->pMod; iRet = pMod->mod.om.parseSelectorAct(p, &pModData, &pOMSR); dbgprintf("tried selector action for %s: %d\n", module.GetName(pMod), iRet); if (iRet == RS_RET_OK_WARN) { bHadWarning = 1; iRet = RS_RET_OK; } if (iRet == RS_RET_OK) { if ((iRet = addAction(&pAction, pMod, pModData, pOMSR, NULL, NULL)) == RS_RET_OK) { /* here check if the module is compatible with select features * (currently, we have no such features!) */ conf->actions.nbrActions++; /* one more active action! */ } break; } else if (iRet != RS_RET_CONFLINE_UNPROCESSED) { /* In this case, the module would have handled the config * line, but some error occurred while doing so. This error should * already by reported by the module. We do not try any other * modules on this line, because we found the right one. * rgerhards, 2007-07-24 */ dbgprintf("error %d parsing config line\n", (int)iRet); break; } node = module.GetNxtCnfType(conf, node, eMOD_OUT); } *ppAction = pAction; if (iRet == RS_RET_OK && bHadWarning) iRet = RS_RET_OK_WARN; RETiRet; } /* return the current number of active actions * rgerhards, 2008-07-28 */ static rsRetVal GetNbrActActions(rsconf_t *conf, int *piNbrActions) { DEFiRet; assert(piNbrActions != NULL); *piNbrActions = conf->actions.nbrActions; RETiRet; } /* queryInterface function * rgerhards, 2008-02-29 */ BEGINobjQueryInterface(conf) CODESTARTobjQueryInterface(conf); if (pIf->ifVersion != confCURR_IF_VERSION) { /* check for current version, increment on each change */ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED); } /* ok, we have the right interface, so let's fill it * Please note that we may also do some backwards-compatibility * work here (if we can support an older interface version - that, * of course, also affects the "if" above). */ pIf->doNameLine = doNameLine; pIf->cfsysline = cfsysline; pIf->doModLoad = doModLoad; pIf->GetNbrActActions = GetNbrActActions; finalize_it: ENDobjQueryInterface(conf) /* Reset config variables to default values. * rgerhards, 2010-07-23 */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { bConfStrictScoping = 0; return RS_RET_OK; } /* exit our class * rgerhards, 2008-03-11 */ BEGINObjClassExit(conf, OBJ_IS_CORE_MODULE) /* CHANGE class also in END MACRO! */ CODESTARTObjClassExit(conf); /* free no-longer needed module-global variables */ if (pDfltHostnameCmp != NULL) { rsCStrDestruct(&pDfltHostnameCmp); } if (pDfltProgNameCmp != NULL) { rsCStrDestruct(&pDfltProgNameCmp); } /* release objects we no longer need */ objRelease(module, CORE_COMPONENT); objRelease(net, LM_NET_FILENAME); objRelease(ruleset, CORE_COMPONENT); ENDObjClassExit(conf) /* Initialize our class. Must be called as the very first method * before anything else is called inside this class. * rgerhards, 2008-02-29 */ BEGINAbstractObjClassInit(conf, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */ /* request objects we use */ CHKiRet(objUse(module, CORE_COMPONENT)); CHKiRet(objUse(net, LM_NET_FILENAME)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); /* These commands will NOT be supported -- the new v6.3 config system provides * far better methods. We will remove the related code soon. -- rgerhards, 2012-01-09 */ CHKiRet( regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL)); ENDObjClassInit(conf) rsyslog-8.2512.0/PaxHeaders/install-sh0000644000000000000000000000013115114544315014534 xustar0030 mtime=1764935885.473999092 30 atime=1764935888.514045658 29 ctime=1764935920.42453434 rsyslog-8.2512.0/install-sh0000755000175000017500000003577615114544315014224 0ustar00rgerrger#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: rsyslog-8.2512.0/PaxHeaders/NEWS0000644000000000000000000000013215035412264013232 xustar0030 mtime=1752569012.325278836 30 atime=1764931121.545004363 30 ctime=1764935920.413534172 rsyslog-8.2512.0/NEWS0000664000175000017500000000007615035412264012701 0ustar00rgerrgerThis file has been superseded by ChangeLog. Please see there. rsyslog-8.2512.0/PaxHeaders/COPYING0000644000000000000000000000013115035412264013565 xustar0029 mtime=1752569012.32130663 30 atime=1764931121.515003878 30 ctime=1764935920.404534034 rsyslog-8.2512.0/COPYING0000664000175000017500000010451215035412264013235 0ustar00rgerrger GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . rsyslog-8.2512.0/PaxHeaders/contrib0000644000000000000000000000013215114544373014123 xustar0030 mtime=1764935931.688706782 30 atime=1764935934.311746933 30 ctime=1764935931.688706782 rsyslog-8.2512.0/contrib/0000775000175000017500000000000015114544373013644 5ustar00rgerrgerrsyslog-8.2512.0/contrib/PaxHeaders/imhttp0000644000000000000000000000013215114544373015430 xustar0030 mtime=1764935931.508704026 30 atime=1764935934.366747775 30 ctime=1764935931.508704026 rsyslog-8.2512.0/contrib/imhttp/0000775000175000017500000000000015114544373015151 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imhttp/PaxHeaders/Makefile.am0000644000000000000000000000013015055602573017540 xustar0029 mtime=1756824955.96045048 30 atime=1764930927.778798029 29 ctime=1764935931.50370395 rsyslog-8.2512.0/contrib/imhttp/Makefile.am0000664000175000017500000000033215055602573017204 0ustar00rgerrgerpkglib_LTLIBRARIES = imhttp.la imhttp_la_SOURCES = imhttp.c imhttp_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(APU_CFLAGS) imhttp_la_LDFLAGS = -module -avoid-version $(CIVETWEB_LIBS) $(APU_LIBS) rsyslog-8.2512.0/contrib/imhttp/PaxHeaders/imhttp.c0000644000000000000000000000013215103061376017151 xustar0030 mtime=1762419454.837380682 30 atime=1764931117.565939989 30 ctime=1764935931.508704026 rsyslog-8.2512.0/contrib/imhttp/imhttp.c0000664000175000017500000014354615103061376016632 0ustar00rgerrger/* imhttp.c * This is an input module for receiving http input. * * This file is originally contribution to rsyslog. * * Copyright 2025 Adiscon GmbH and Others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "cfsysline.h" /* access to config file objects */ #include "module-template.h" #include "ruleset.h" #include "unicode-helper.h" #include "rsyslog.h" #include "errmsg.h" #include "statsobj.h" #include "ratelimit.h" #include "dirty.h" #include "civetweb.h" #include #include MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imhttp") /* static data */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) DEFobjCurrIf(statsobj) #define CIVETWEB_OPTION_NAME_PORTS "listening_ports" #define CIVETWEB_OPTION_NAME_DOCUMENT_ROOT "document_root" #define MAX_READ_BUFFER_SIZE 16384 #define INIT_SCRATCH_BUF_SIZE 4096 /* General purpose buffer size. */ #define IMHTTP_MAX_BUF_LEN (8192) #define DEFAULT_HEALTH_CHECK_PATH "/healthz" #define DEFAULT_PROM_METRICS_PATH "/metrics" struct option { const char *name; const char *val; }; struct auth_s { char workbuf[IMHTTP_MAX_BUF_LEN]; char *pworkbuf; size_t workbuf_len; char *pszUser; char *pszPasswd; }; struct data_parse_s { sbool content_compressed; sbool bzInitDone; /* did we do an init of zstrm already? */ z_stream zstrm; /* zip stream to use for tcp compression */ // Currently only used for octet specific parsing enum { eAtStrtFram, eInOctetCnt, eInMsg, } inputState; size_t iOctetsRemain; /* Number of Octets remaining in message */ enum { TCP_FRAMING_OCTET_STUFFING, TCP_FRAMING_OCTET_COUNTING } framingMode; }; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ instanceConf_t *root, *tail; struct option ports; struct option docroot; struct option *options; int nOptions; char *pszHealthCheckPath; char *pszMetricsPath; char *pszHealthCheckAuthFile; char *pszMetricsAuthFile; }; struct instanceConf_s { struct instanceConf_s *next; uchar *pszBindRuleset; /* name of ruleset to bind to */ uchar *pszEndpoint; /* endpoint to configure */ uchar *pszBasicAuthFile; /* file containing basic auth users/pass */ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ ratelimit_t *ratelimiter; unsigned int ratelimitInterval; unsigned int ratelimitBurst; uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */ prop_t *pInputName; sbool flowControl; sbool bDisableLFDelim; sbool bSuppOctetFram; sbool bAddMetadata; }; struct conn_wrkr_s { struct data_parse_s parseState; uchar *pMsg; /* msg scratch buffer */ size_t iMsg; /* index of next char to store in msg */ uchar zipBuf[64 * 1024]; multi_submit_t multiSub; smsg_t *pMsgs[CONF_NUM_MULTISUB]; char *pReadBuf; size_t readBufSize; prop_t *propRemoteAddr; const struct mg_request_info *pri; /* do not free me - used to hold a reference only */ char *pScratchBuf; size_t scratchBufSize; }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current load process */ static prop_t *pInputName = NULL; // static size_t s_iMaxLine = 16; /* get maximum size we currently support */ static size_t s_iMaxLine = 16384; /* get maximum size we currently support */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = {{"ports", eCmdHdlrString, 0}, {"documentroot", eCmdHdlrString, 0}, {"liboptions", eCmdHdlrArray, 0}, {"healthcheckpath", eCmdHdlrString, 0}, {"metricspath", eCmdHdlrString, 0}, {"healthcheckbasicauthfile", eCmdHdlrString, 0}, {"metricsbasicauthfile", eCmdHdlrString, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; static struct cnfparamdescr inppdescr[] = {{"endpoint", eCmdHdlrString, 0}, {"basicauthfile", eCmdHdlrString, 0}, {"ruleset", eCmdHdlrString, 0}, {"flowcontrol", eCmdHdlrBinary, 0}, {"disablelfdelimiter", eCmdHdlrBinary, 0}, {"supportoctetcountedframing", eCmdHdlrBinary, 0}, {"name", eCmdHdlrString, 0}, {"ratelimit.interval", eCmdHdlrInt, 0}, {"ratelimit.burst", eCmdHdlrInt, 0}, {"addmetadata", eCmdHdlrBinary, 0}}; #include "im-helper.h" /* must be included AFTER the type definitions! */ static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; static struct { statsobj_t *stats; STATSCOUNTER_DEF(ctrSubmitted, mutCtrSubmitted) STATSCOUNTER_DEF(ctrFailed, mutCtrFailed); STATSCOUNTER_DEF(ctrDiscarded, mutCtrDiscarded); } statsCounter; #include "im-helper.h" /* must be included AFTER the type definitions! */ #define min(a, b) \ ({ \ __typeof__(a) _a = (a); \ __typeof__(b) _b = (b); \ _a < _b ? _a : _b; \ }) #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 #define EXIT_URI "/exit" volatile int exitNow = 0; struct mg_callbacks callbacks; typedef struct httpserv_s { struct mg_context *ctx; struct mg_callbacks callbacks; const char **civetweb_options; size_t civetweb_options_count; } httpserv_t; static httpserv_t *s_httpserv; /* FORWARD DECLARATIONS */ static rsRetVal processData(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len); static rsRetVal createInstance(instanceConf_t **pinst) { instanceConf_t *inst; DEFiRet; CHKmalloc(inst = calloc(1, sizeof(instanceConf_t))); inst->next = NULL; inst->pszBindRuleset = NULL; inst->pBindRuleset = NULL; inst->pszEndpoint = NULL; inst->pszBasicAuthFile = NULL; inst->ratelimiter = NULL; inst->pszInputName = NULL; inst->pInputName = NULL; inst->ratelimitBurst = 10000; /* arbitrary high limit */ inst->ratelimitInterval = 0; /* off */ inst->flowControl = 1; inst->bDisableLFDelim = 0; inst->bSuppOctetFram = 0; inst->bAddMetadata = 0; // construct statsobj /* node created, let's add to config */ if (loadModConf->tail == NULL) { loadModConf->tail = loadModConf->root = inst; } else { loadModConf->tail->next = inst; loadModConf->tail = inst; } *pinst = inst; finalize_it: RETiRet; } static rsRetVal processCivetwebOptions(char *const param, const char **const name, const char **const paramval) { DEFiRet; char *val = strstr(param, "="); if (val == NULL) { LogError(0, RS_RET_PARAM_ERROR, "missing equal sign in " "parameter '%s'", param); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } *val = '\0'; /* terminates name */ ++val; /* now points to begin of value */ CHKmalloc(*name = strdup(param)); CHKmalloc(*paramval = strdup(val)); finalize_it: RETiRet; } static sbool valid_civetweb_option(const struct mg_option *valid_opts, const char *option) { const struct mg_option *pvalid_opts = valid_opts; for (; pvalid_opts != NULL && pvalid_opts->name != NULL; pvalid_opts++) { if (strcmp(pvalid_opts->name, option) == 0) { return TRUE; } } return FALSE; } /* * thread_type: * 0 indicates the master thread * 1 indicates a worker thread handling client connections * 2 indicates an internal helper thread (timer thread) */ static void *init_thread(ATTR_UNUSED const struct mg_context *ctx, int thread_type) { DEFiRet; struct conn_wrkr_s *data = NULL; if (thread_type == 1) { CHKmalloc(data = calloc(1, sizeof(struct conn_wrkr_s))); data->pMsg = NULL; data->iMsg = 0; data->parseState.bzInitDone = 0; data->parseState.content_compressed = 0; data->parseState.inputState = eAtStrtFram; data->parseState.iOctetsRemain = 0; data->multiSub.maxElem = CONF_NUM_MULTISUB; data->multiSub.ppMsgs = data->pMsgs; data->multiSub.nElem = 0; data->pReadBuf = malloc(MAX_READ_BUFFER_SIZE); data->readBufSize = MAX_READ_BUFFER_SIZE; data->parseState.bzInitDone = 0; data->parseState.content_compressed = 0; data->parseState.inputState = eAtStrtFram; data->parseState.iOctetsRemain = 0; CHKmalloc(data->pMsg = calloc(1, 1 + s_iMaxLine)); data->iMsg = 0; data->propRemoteAddr = NULL; data->pScratchBuf = NULL; data->scratchBufSize = 0; } finalize_it: if (iRet != RS_RET_OK) { free(data); return NULL; } return data; } static void exit_thread(ATTR_UNUSED const struct mg_context *ctx, ATTR_UNUSED int thread_type, void *thread_pointer) { if (thread_type == 1) { struct conn_wrkr_s *data = (struct conn_wrkr_s *)thread_pointer; if (data->propRemoteAddr) { prop.Destruct(&data->propRemoteAddr); } if (data->scratchBufSize) { free(data->pScratchBuf); } free(data->pReadBuf); free(data->pMsg); free(data); } } static rsRetVal msgAddMetadataFromHttpHeader(smsg_t *const __restrict__ pMsg, struct conn_wrkr_s *connWrkr) { struct json_object *json = NULL; DEFiRet; const struct mg_request_info *ri = connWrkr->pri; #define MAX_HTTP_HEADERS 64 /* hard limit */ int count = min(ri->num_headers, MAX_HTTP_HEADERS); CHKmalloc(json = json_object_new_object()); for (int i = 0; i < count; i++) { struct json_object *const jval = json_object_new_string(ri->http_headers[i].value); CHKmalloc(jval); /* truncate header names bigger than INIT_SCRATCH_BUF_SIZE */ strncpy(connWrkr->pScratchBuf, ri->http_headers[i].name, connWrkr->scratchBufSize - 1); /* make header lowercase */ char *pname = connWrkr->pScratchBuf; while (pname && *pname != '\0') { *pname = tolower(*pname); pname++; } json_object_object_add(json, (const char *const)connWrkr->pScratchBuf, jval); } CHKiRet(msgAddJSON(pMsg, (uchar *)"!metadata!httpheaders", json, 0, 0)); finalize_it: if (iRet != RS_RET_OK && json) { json_object_put(json); } RETiRet; } static rsRetVal msgAddMetadataFromHttpQueryParams(smsg_t *const __restrict__ pMsg, struct conn_wrkr_s *connWrkr) { struct json_object *json = NULL; DEFiRet; const struct mg_request_info *ri = connWrkr->pri; if (ri && ri->query_string) { strncpy(connWrkr->pScratchBuf, ri->query_string, connWrkr->scratchBufSize - 1); char *pquery_str = connWrkr->pScratchBuf; if (pquery_str) { CHKmalloc(json = json_object_new_object()); char *saveptr = NULL; char *kv_pair = strtok_r(pquery_str, "&;", &saveptr); for (; kv_pair != NULL; kv_pair = strtok_r(NULL, "&;", &saveptr)) { char *saveptr2 = NULL; char *key = strtok_r(kv_pair, "=", &saveptr2); if (key) { char *value = strtok_r(NULL, "=", &saveptr2); struct json_object *const jval = json_object_new_string(value); CHKmalloc(jval); json_object_object_add(json, (const char *)key, jval); } } CHKiRet(msgAddJSON(pMsg, (uchar *)"!metadata!queryparams", json, 0, 0)); } } finalize_it: if (iRet != RS_RET_OK && json) { json_object_put(json); } RETiRet; } static rsRetVal doSubmitMsg(const instanceConf_t *const __restrict__ inst, struct conn_wrkr_s *connWrkr, const uchar *msg, size_t len) { smsg_t *pMsg; DEFiRet; assert(len <= s_iMaxLine); if (len == 0) { DBGPRINTF("discarding zero-sized message\n"); FINALIZE; } CHKiRet(msgConstruct(&pMsg)); MsgSetFlowControlType(pMsg, inst->flowControl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY); if (inst->pInputName) { MsgSetInputName(pMsg, inst->pInputName); } else { MsgSetInputName(pMsg, pInputName); } MsgSetRawMsg(pMsg, (const char *)msg, len); MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ if (connWrkr->propRemoteAddr) { MsgSetRcvFromIP(pMsg, connWrkr->propRemoteAddr); } if (inst) { MsgSetRuleset(pMsg, inst->pBindRuleset); } // TODO: make these flags configurable. pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; if (inst->bAddMetadata) { CHKiRet(msgAddMetadataFromHttpHeader(pMsg, connWrkr)); CHKiRet(msgAddMetadataFromHttpQueryParams(pMsg, connWrkr)); } ratelimitAddMsg(inst->ratelimiter, &connWrkr->multiSub, pMsg); STATSCOUNTER_INC(statsCounter.ctrSubmitted, statsCounter.mutCtrSubmitted); finalize_it: connWrkr->iMsg = 0; if (iRet != RS_RET_OK) { STATSCOUNTER_INC(statsCounter.ctrDiscarded, statsCounter.mutCtrDiscarded); } RETiRet; } static rsRetVal processOctetMsgLen(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, char ch) { DEFiRet; if (connWrkr->parseState.inputState == eAtStrtFram) { if (inst->bSuppOctetFram && isdigit(ch)) { connWrkr->parseState.inputState = eInOctetCnt; connWrkr->parseState.iOctetsRemain = 0; connWrkr->parseState.framingMode = TCP_FRAMING_OCTET_COUNTING; } else { connWrkr->parseState.inputState = eInMsg; connWrkr->parseState.framingMode = TCP_FRAMING_OCTET_STUFFING; } } // parsing character. if (connWrkr->parseState.inputState == eInOctetCnt) { if (isdigit(ch)) { if (connWrkr->parseState.iOctetsRemain <= 200000000) { connWrkr->parseState.iOctetsRemain = connWrkr->parseState.iOctetsRemain * 10 + ch - '0'; } // temporarily save this character into the message buffer if (connWrkr->iMsg + 1 < s_iMaxLine) { connWrkr->pMsg[connWrkr->iMsg++] = ch; } } else { const char *remoteAddr = ""; if (connWrkr->propRemoteAddr) { remoteAddr = (const char *)propGetSzStr(connWrkr->propRemoteAddr); } /* handle space delimeter */ if (ch != ' ') { LogError(0, NO_ERRCODE, "Framing Error in received TCP message " "from peer: (ip) %s: to input: %s, delimiter is not " "SP but has ASCII value %d.", remoteAddr, inst->pszInputName, ch); } if (connWrkr->parseState.iOctetsRemain < 1) { LogError(0, NO_ERRCODE, "Framing Error in received TCP message" " from peer: (ip) %s: delimiter is not " "SP but has ASCII value %d.", remoteAddr, ch); } else if (connWrkr->parseState.iOctetsRemain > s_iMaxLine) { DBGPRINTF("truncating message with %lu octets - max msg size is %lu\n", connWrkr->parseState.iOctetsRemain, s_iMaxLine); LogError(0, NO_ERRCODE, "received oversize message from peer: " "(hostname) (ip) %s: size is %lu bytes, max msg " "size is %lu, truncating...", remoteAddr, connWrkr->parseState.iOctetsRemain, s_iMaxLine); } connWrkr->parseState.inputState = eInMsg; } /* reset msg len for actual message processing */ connWrkr->iMsg = 0; /* retrieve next character */ } RETiRet; } static rsRetVal processOctetCounting(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len) { DEFiRet; const uchar *pbuf = (const uchar *)buf; const uchar *pbufLast = pbuf + len; while (pbuf < pbufLast) { char ch = *pbuf; if (connWrkr->parseState.inputState == eAtStrtFram || connWrkr->parseState.inputState == eInOctetCnt) { processOctetMsgLen(inst, connWrkr, ch); if (connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_COUNTING) { pbuf++; } } else if (connWrkr->parseState.inputState == eInMsg) { if (connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_STUFFING) { if (connWrkr->iMsg < s_iMaxLine) { if (ch == '\n') { doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); connWrkr->parseState.inputState = eAtStrtFram; } else { connWrkr->pMsg[connWrkr->iMsg++] = ch; } } else { doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); connWrkr->parseState.inputState = eAtStrtFram; } pbuf++; } else { assert(connWrkr->parseState.framingMode == TCP_FRAMING_OCTET_COUNTING); /* parsing payload */ size_t remainingBytes = pbufLast - pbuf; // figure out how much is in block size_t count = min(connWrkr->parseState.iOctetsRemain, remainingBytes); if (connWrkr->iMsg + count >= s_iMaxLine) { count = s_iMaxLine - connWrkr->iMsg; } // just copy the bytes if (count) { memcpy(connWrkr->pMsg + connWrkr->iMsg, pbuf, count); pbuf += count; connWrkr->iMsg += count; connWrkr->parseState.iOctetsRemain -= count; } if (connWrkr->parseState.iOctetsRemain == 0) { doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); connWrkr->parseState.inputState = eAtStrtFram; } } } else { // unexpected assert(0); break; } } RETiRet; } static rsRetVal processDisableLF(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len) { DEFiRet; const uchar *pbuf = (const uchar *)buf; size_t remainingBytes = len; const uchar *pbufLast = pbuf + len; while (pbuf < pbufLast) { size_t count = 0; if (connWrkr->iMsg + remainingBytes >= s_iMaxLine) { count = s_iMaxLine - connWrkr->iMsg; } else { count = remainingBytes; } if (count) { memcpy(connWrkr->pMsg + connWrkr->iMsg, pbuf, count); pbuf += count; connWrkr->iMsg += count; remainingBytes -= count; } doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); } RETiRet; } static rsRetVal processDataUncompressed(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len) { const uchar *pbuf = (const uchar *)buf; DEFiRet; if (inst->bDisableLFDelim) { /* do block processing */ iRet = processDisableLF(inst, connWrkr, buf, len); } else if (inst->bSuppOctetFram) { iRet = processOctetCounting(inst, connWrkr, buf, len); } else { const uchar *pbufLast = pbuf + len; while (pbuf < pbufLast) { char ch = *pbuf; if (connWrkr->iMsg < s_iMaxLine) { if (ch == '\n') { doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); } else { connWrkr->pMsg[connWrkr->iMsg++] = ch; } } else { doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); } pbuf++; } } RETiRet; } static rsRetVal processDataCompressed(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len) { DEFiRet; if (!connWrkr->parseState.bzInitDone) { /* allocate deflate state */ connWrkr->parseState.zstrm.zalloc = Z_NULL; connWrkr->parseState.zstrm.zfree = Z_NULL; connWrkr->parseState.zstrm.opaque = Z_NULL; int rc = inflateInit2(&connWrkr->parseState.zstrm, (MAX_WBITS | 16)); if (rc != Z_OK) { dbgprintf("imhttp: error %d returned from zlib/inflateInit()\n", rc); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } connWrkr->parseState.bzInitDone = 1; } connWrkr->parseState.zstrm.next_in = (Bytef *)buf; connWrkr->parseState.zstrm.avail_in = len; /* run inflate() on buffer until everything has been uncompressed */ int outtotal = 0; do { int zRet = 0; int outavail = 0; dbgprintf("imhttp: in inflate() loop, avail_in %d, total_in %ld\n", connWrkr->parseState.zstrm.avail_in, connWrkr->parseState.zstrm.total_in); connWrkr->parseState.zstrm.avail_out = sizeof(connWrkr->zipBuf); connWrkr->parseState.zstrm.next_out = connWrkr->zipBuf; zRet = inflate(&connWrkr->parseState.zstrm, Z_SYNC_FLUSH); dbgprintf("imhttp: inflate(), ret: %d, avail_out: %d\n", zRet, connWrkr->parseState.zstrm.avail_out); outavail = sizeof(connWrkr->zipBuf) - connWrkr->parseState.zstrm.avail_out; if (outavail != 0) { outtotal += outavail; CHKiRet(processDataUncompressed(inst, connWrkr, (const char *)connWrkr->zipBuf, outavail)); } } while (connWrkr->parseState.zstrm.avail_out == 0); dbgprintf("imhttp: processDataCompressed complete, sizes: in %lld, out %llu\n", (long long)len, (long long unsigned)outtotal); finalize_it: RETiRet; } static rsRetVal processData(const instanceConf_t *const inst, struct conn_wrkr_s *connWrkr, const char *buf, size_t len) { DEFiRet; // inst->bDisableLFDelim = 0; if (connWrkr->parseState.content_compressed) { iRet = processDataCompressed(inst, connWrkr, buf, len); } else { iRet = processDataUncompressed(inst, connWrkr, buf, len); } RETiRet; } /* Return 1 on success. Always initializes the auth structure. */ static int parse_auth_header(struct mg_connection *conn, struct auth_s *auth) { if (!auth || !conn) { return 0; } const char *auth_header = NULL; if (((auth_header = mg_get_header(conn, "Authorization")) == NULL) || strncasecmp(auth_header, "Basic ", 6) != 0) { return 0; } /* Parse authorization header */ const char *src = auth_header + 6; size_t len = apr_base64_decode_len((const char *)src); auth->pworkbuf = auth->workbuf; if (len > sizeof(auth->workbuf)) { auth->pworkbuf = calloc(0, len); auth->workbuf_len = len; } len = apr_base64_decode(auth->pworkbuf, src); if (len == 0) { return 0; } char *passwd = NULL, *saveptr = NULL; char *user = strtok_r(auth->pworkbuf, ":", &saveptr); if (user) { passwd = strtok_r(NULL, ":", &saveptr); } auth->pszUser = user; auth->pszPasswd = passwd; return 1; } static int read_auth_file(FILE *filep, struct auth_s *auth) { if (!filep) { return 0; } char workbuf[IMHTTP_MAX_BUF_LEN]; size_t l = 0; char *user; char *passwd; while (fgets(workbuf, sizeof(workbuf), filep)) { l = strnlen(workbuf, sizeof(workbuf)); while (l > 0) { if (isspace(workbuf[l - 1]) || iscntrl(workbuf[l - 1])) { l--; workbuf[l] = 0; } else { break; } } if (l < 1) { continue; } if (workbuf[0] == '#') { continue; } user = workbuf; passwd = strchr(workbuf, ':'); if (!passwd) { continue; } *passwd = '\0'; passwd++; if (!strcasecmp(auth->pszUser, user)) { return (apr_password_validate(auth->pszPasswd, passwd) == APR_SUCCESS); } } return 0; } /* Authorize against the opened passwords file. Return 1 if authorized. */ static int authorize(struct mg_connection *conn, FILE *filep) { if (!conn || !filep) { return 0; } struct auth_s auth = {.workbuf_len = 0, .pworkbuf = NULL, .pszUser = NULL, .pszPasswd = NULL}; if (!parse_auth_header(conn, &auth)) { return 0; } /* validate against htpasswd file */ return read_auth_file(filep, &auth); } /* Provides Basic Authorization handling that validates against a 'htpasswd' file. see also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization */ static int basicAuthHandler(struct mg_connection *conn, void *cbdata) { const char *authFile = (const char *)cbdata; char errStr[512]; FILE *fp = NULL; int ret = 1; if (!authFile) { mg_cry(conn, "warning: auth file not configured for this endpoint.\n"); ret = 0; goto finalize; } fp = fopen(authFile, "r"); if (fp == NULL) { if (strerror_r(errno, errStr, sizeof(errStr)) == 0) { mg_cry(conn, "error: auth file '%s' could not be accessed: %s\n", authFile, errStr); } else { mg_cry(conn, "error: auth file '%s' could not be accessed: %d\n", authFile, errno); } ret = 0; goto finalize; } ret = authorize(conn, fp); finalize: if (!ret) { mg_send_http_error(conn, 401, "WWW-Authenticate: Basic realm=\"User Visible Realm\"\n"); } if (fp) { fclose(fp); } return ret; } /* cbdata should actually contain instance data and we can actually use this instance data * to hold reusable scratch buffer. */ static int postHandler(struct mg_connection *conn, void *cbdata) { int rc = 1; instanceConf_t *inst = (instanceConf_t *)cbdata; const struct mg_request_info *ri = mg_get_request_info(conn); struct conn_wrkr_s *connWrkr = mg_get_thread_pointer(conn); connWrkr->multiSub.nElem = 0; memset(&connWrkr->parseState, 0, sizeof(connWrkr->parseState)); connWrkr->pri = ri; if (inst->bAddMetadata && connWrkr->scratchBufSize == 0) { connWrkr->pScratchBuf = calloc(1, INIT_SCRATCH_BUF_SIZE); if (!connWrkr->pScratchBuf) { mg_cry(conn, "%s() - could not alloc scratch buffer!\n", __FUNCTION__); rc = 500; FINALIZE; } connWrkr->scratchBufSize = INIT_SCRATCH_BUF_SIZE; } if (0 != strcmp(ri->request_method, "POST")) { /* Not a POST request */ int ret = mg_get_request_link(conn, connWrkr->pReadBuf, connWrkr->readBufSize); mg_printf(conn, "HTTP/1.1 405 Method Not Allowed\r\nConnection: close\r\n"); mg_printf(conn, "Content-Type: text/plain\r\n\r\n"); mg_printf(conn, "%s method not allowed in the POST handler\n", ri->request_method); if (ret >= 0) { mg_printf(conn, "use a web tool to send a POST request to %s\n", connWrkr->pReadBuf); } STATSCOUNTER_INC(statsCounter.ctrFailed, statsCounter.mutCtrFailed); rc = 405; FINALIZE; } if (ri->remote_addr[0] != '\0') { size_t len = strnlen(ri->remote_addr, sizeof(ri->remote_addr)); prop.CreateOrReuseStringProp(&connWrkr->propRemoteAddr, (const uchar *)ri->remote_addr, len); } if (ri->content_length >= 0) { /* We know the content length in advance */ if (ri->content_length > (long long)connWrkr->readBufSize) { connWrkr->pReadBuf = realloc(connWrkr->pReadBuf, ri->content_length + 1); if (!connWrkr->pReadBuf) { mg_cry(conn, "%s() - realloc failed!\n", __FUNCTION__); FINALIZE; } connWrkr->readBufSize = ri->content_length + 1; } } else { /* We must read until we find the end (chunked encoding * or connection close), indicated my mg_read returning 0 */ } if (ri->num_headers > 0) { int i; for (i = 0; i < ri->num_headers; i++) { if (!strcasecmp(ri->http_headers[i].name, "content-encoding") && !strcasecmp(ri->http_headers[i].value, "gzip")) { connWrkr->parseState.content_compressed = 1; } } } while (1) { int count = mg_read(conn, connWrkr->pReadBuf, connWrkr->readBufSize); if (count > 0) { processData(inst, connWrkr, (const char *)connWrkr->pReadBuf, count); } else { break; } } /* submit remainder */ doSubmitMsg(inst, connWrkr, connWrkr->pMsg, connWrkr->iMsg); multiSubmitFlush(&connWrkr->multiSub); mg_send_http_ok(conn, "text/plain", 0); rc = 200; finalize_it: if (connWrkr->parseState.bzInitDone) { inflateEnd(&connWrkr->parseState.zstrm); } /* reset */ connWrkr->iMsg = 0; return rc; } /* Health Check Handler */ static int health_check_handler(struct mg_connection *conn, ATTR_UNUSED void *cbdata) { const char *body = "OK\n"; mg_send_http_ok(conn, "text/plain; charset=utf-8", strlen(body)); mg_write(conn, body, strlen(body)); return 200; // CivetWeb expects handler to return HTTP status or specific flags } /* * prometheus_metrics_handler * Export rsyslog statistics in Prometheus text format. */ struct stats_buf { char *buf; size_t len; size_t cap; }; static rsRetVal prom_stats_collect(void *usrptr, const char *line) { struct stats_buf *sb = (struct stats_buf *)usrptr; const size_t line_len = strlen(line); if (sb->len + line_len >= sb->cap) { size_t newcap = sb->cap ? sb->cap * 2 : 1024; while (newcap <= sb->len + line_len) { if (newcap > ((size_t)-1) / 2) { return RS_RET_OUT_OF_MEMORY; } newcap *= 2; } char *tmp = realloc(sb->buf, newcap); if (tmp == NULL) { return RS_RET_OUT_OF_MEMORY; } sb->buf = tmp; sb->cap = newcap; } memcpy(sb->buf + sb->len, line, line_len); sb->len += line_len; sb->buf[sb->len] = '\0'; return RS_RET_OK; } static int prometheus_metrics_handler(struct mg_connection *conn, ATTR_UNUSED void *cbdata) { struct stats_buf sb = {.buf = NULL, .len = 0, .cap = 0}; rsRetVal ret = RS_RET_OK; int http_status = 200; const char *imhttp_up_metric = "# HELP imhttp_up Indicates if the imhttp module is operational (1 for up, 0 for down).\n" "# TYPE imhttp_up gauge\n" "imhttp_up 1\n"; ret = prom_stats_collect(&sb, imhttp_up_metric); if (ret != RS_RET_OK) { LogError(0, RS_RET_OUT_OF_MEMORY, "imhttp: failed to allocate initial buffer for statistics"); http_status = 500; goto finalize; } ret = statsobj.GetAllStatsLines(prom_stats_collect, &sb, statsFmt_Prometheus, 0); if (ret != RS_RET_OK) { LogError(0, ret, "imhttp: failed to retrieve statistics"); http_status = 500; goto finalize; } mg_printf(conn, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain; version=0.0.4; charset=utf-8\r\n" "Content-Length: %zu\r\n" "Connection: close\r\n" "\r\n", sb.len); mg_write(conn, sb.buf, sb.len); finalize: if (http_status != 200) { mg_printf(conn, "HTTP/1.1 500 Internal Server Error\r\nConnection: close\r\n\r\n"); } free(sb.buf); return http_status; } static int runloop(void) { dbgprintf("imhttp started.\n"); /* Register handlers under context lock to avoid civetweb races */ mg_lock_context(s_httpserv->ctx); for (instanceConf_t *inst = runModConf->root; inst != NULL; inst = inst->next) { assert(inst->pszEndpoint); if (inst->pszEndpoint) { dbgprintf("setting request handler: '%s'\n", inst->pszEndpoint); mg_set_request_handler(s_httpserv->ctx, (char *)inst->pszEndpoint, postHandler, inst); if (inst->pszBasicAuthFile) { mg_set_auth_handler(s_httpserv->ctx, (char *)inst->pszEndpoint, basicAuthHandler, inst->pszBasicAuthFile); } } } if (runModConf->pszHealthCheckPath && runModConf->pszHealthCheckPath[0] != '\0') { dbgprintf("imhttp: setting request handler for global health check: '%s'\n", runModConf->pszHealthCheckPath); mg_set_request_handler(s_httpserv->ctx, runModConf->pszHealthCheckPath, health_check_handler, NULL); if (runModConf->pszHealthCheckAuthFile) { mg_set_auth_handler(s_httpserv->ctx, runModConf->pszHealthCheckPath, basicAuthHandler, runModConf->pszHealthCheckAuthFile); } } if (runModConf->pszMetricsPath && runModConf->pszMetricsPath[0] != '\0') { dbgprintf("imhttp: setting request handler for Prometheus metrics: '%s'\n", runModConf->pszMetricsPath); mg_set_request_handler(s_httpserv->ctx, runModConf->pszMetricsPath, prometheus_metrics_handler, NULL /* cbdata, not used */); if (runModConf->pszMetricsAuthFile) { mg_set_auth_handler(s_httpserv->ctx, runModConf->pszMetricsPath, basicAuthHandler, runModConf->pszMetricsAuthFile); } } mg_unlock_context(s_httpserv->ctx); /* Wait until the server should be closed */ while (glbl.GetGlobalInputTermState() == 0) { sleep(1); } return EXIT_SUCCESS; } BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst; int i; CODESTARTnewInpInst; DBGPRINTF("newInpInst (imhttp)\n"); pvals = nvlstGetParams(lst, &inppblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "imhttp: required parameter are missing\n"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("input param blk in imtcp:\n"); cnfparamsPrint(&inppblk, pvals); } CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "endpoint")) { inst->pszEndpoint = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "basicauthfile")) { inst->pszBasicAuthFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "name")) { inst->pszInputName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "ratelimit.burst")) { inst->ratelimitBurst = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "ratelimit.interval")) { inst->ratelimitInterval = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "flowcontrol")) { inst->flowControl = (int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "disablelfdelimiter")) { inst->bDisableLFDelim = (int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "supportoctetcountedframing")) { inst->bSuppOctetFram = (int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "addmetadata")) { inst->bAddMetadata = (int)pvals[i].val.d.n; } else { dbgprintf( "imhttp: program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } if (inst->pszInputName) { CHKiRet(prop.Construct(&inst->pInputName)); CHKiRet(prop.SetString(inst->pInputName, inst->pszInputName, ustrlen(inst->pszInputName))); CHKiRet(prop.ConstructFinalize(inst->pInputName)); } CHKiRet(ratelimitNew(&inst->ratelimiter, "imphttp", NULL)); ratelimitSetLinuxLike(inst->ratelimiter, inst->ratelimitInterval, inst->ratelimitBurst); finalize_it: CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; loadModConf->ports.name = NULL; loadModConf->docroot.name = NULL; loadModConf->nOptions = 0; loadModConf->options = NULL; loadModConf->pszHealthCheckAuthFile = NULL; loadModConf->pszMetricsAuthFile = NULL; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "imhttp: error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for imhttp:\n"); cnfparamsPrint(&modpblk, pvals); } for (int i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "ports")) { assert(loadModConf->ports.name == NULL); assert(loadModConf->ports.val == NULL); loadModConf->ports.name = strdup(CIVETWEB_OPTION_NAME_PORTS); loadModConf->ports.val = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "documentroot")) { assert(loadModConf->docroot.name == NULL); assert(loadModConf->docroot.val == NULL); loadModConf->docroot.name = strdup(CIVETWEB_OPTION_NAME_DOCUMENT_ROOT); loadModConf->docroot.val = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "liboptions")) { loadModConf->nOptions = pvals[i].val.d.ar->nmemb; CHKmalloc(loadModConf->options = malloc(sizeof(struct option) * pvals[i].val.d.ar->nmemb)); for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); CHKiRet(processCivetwebOptions(cstr, &loadModConf->options[j].name, &loadModConf->options[j].val)); free(cstr); } } else if (!strcmp(modpblk.descr[i].name, "healthcheckpath")) { free(loadModConf->pszHealthCheckPath); loadModConf->pszHealthCheckPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "metricspath")) { free(loadModConf->pszMetricsPath); loadModConf->pszMetricsPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "healthcheckbasicauthfile")) { free(loadModConf->pszHealthCheckAuthFile); loadModConf->pszHealthCheckAuthFile = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "metricsbasicauthfile")) { free(loadModConf->pszMetricsAuthFile); loadModConf->pszMetricsAuthFile = es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf( "imhttp: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } /* Set defaults if not configured but enabled */ // TODO: add ability to disable functionality, especially important if we // use this solely for health checking etc if (loadModConf->pszHealthCheckPath == NULL) { CHKmalloc(loadModConf->pszHealthCheckPath = strdup(DEFAULT_HEALTH_CHECK_PATH)); } if (loadModConf->pszMetricsPath == NULL) { CHKmalloc(loadModConf->pszMetricsPath = strdup(DEFAULT_PROM_METRICS_PATH)); } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ ENDendCnfLoad /* function to generate error message if framework does not find requested ruleset */ static inline void std_checkRuleset_genErrMsg(ATTR_UNUSED modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "imhttp: ruleset '%s' for %s not found - " "using default ruleset instead", inst->pszBindRuleset, inst->pszEndpoint); } BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = pModConf->root; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); } /* verify civetweb options are valid */ const struct mg_option *valid_opts = mg_get_valid_options(); for (int i = 0; i < pModConf->nOptions; ++i) { if (!valid_civetweb_option(valid_opts, pModConf->options[i].name)) { LogError(0, RS_RET_CONF_PARSE_WARNING, "imhttp: module loaded, but " "invalid civetweb option found - imhttp may not receive connections."); iRet = RS_RET_CONF_PARSE_WARNING; } } if (pModConf->pszHealthCheckPath == NULL || pModConf->pszHealthCheckPath[0] != '/') { LogError(0, RS_RET_CONF_PARSE_WARNING, "imhttp: healthCheckPath '%s' is invalid, must start with '/'. Using default '%s'.", pModConf->pszHealthCheckPath ? pModConf->pszHealthCheckPath : "(null)", DEFAULT_HEALTH_CHECK_PATH); free(pModConf->pszHealthCheckPath); pModConf->pszHealthCheckPath = strdup(DEFAULT_HEALTH_CHECK_PATH); } if (pModConf->pszMetricsPath == NULL || pModConf->pszMetricsPath[0] != '/') { LogError(0, RS_RET_CONF_PARSE_WARNING, "imhttp: metricsPath '%s' is invalid, must start with '/'. Using default '%s'.", pModConf->pszMetricsPath ? pModConf->pszMetricsPath : "(null)", DEFAULT_PROM_METRICS_PATH); free(pModConf->pszMetricsPath); pModConf->pszMetricsPath = strdup(DEFAULT_PROM_METRICS_PATH); } ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; if (!s_httpserv) { CHKmalloc(s_httpserv = calloc(1, sizeof(httpserv_t))); } /* options represents (key, value) so allocate 2x, and null terminated */ size_t count = 1; if (runModConf->ports.val) { count += 2; } if (runModConf->docroot.val) { count += 2; } count += (2 * runModConf->nOptions); CHKmalloc(s_httpserv->civetweb_options = calloc(count, sizeof(*s_httpserv->civetweb_options))); const char **pcivetweb_options = s_httpserv->civetweb_options; if (runModConf->nOptions) { s_httpserv->civetweb_options_count = count; for (int i = 0; i < runModConf->nOptions; ++i) { *pcivetweb_options = runModConf->options[i].name; pcivetweb_options++; *pcivetweb_options = runModConf->options[i].val; pcivetweb_options++; } } /* append port, docroot */ if (runModConf->ports.val) { *pcivetweb_options = runModConf->ports.name; pcivetweb_options++; *pcivetweb_options = runModConf->ports.val; pcivetweb_options++; } if (runModConf->docroot.val) { *pcivetweb_options = runModConf->docroot.name; pcivetweb_options++; *pcivetweb_options = runModConf->docroot.val; pcivetweb_options++; } const char **option = s_httpserv->civetweb_options; for (; option && *option != NULL; option++) { dbgprintf("imhttp: civetweb option: %s\n", *option); } CHKiRet(statsobj.Construct(&statsCounter.stats)); CHKiRet(statsobj.SetName(statsCounter.stats, UCHAR_CONSTANT("imhttp"))); CHKiRet(statsobj.SetOrigin(statsCounter.stats, UCHAR_CONSTANT("imhttp"))); STATSCOUNTER_INIT(statsCounter.ctrSubmitted, statsCounter.mutCtrSubmitted); CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrSubmitted))); STATSCOUNTER_INIT(statsCounter.ctrFailed, statsCounter.mutCtrFailed); CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("failed"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrFailed))); STATSCOUNTER_INIT(statsCounter.ctrDiscarded, statsCounter.mutCtrDiscarded); CHKiRet(statsobj.AddCounter(statsCounter.stats, UCHAR_CONSTANT("discarded"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(statsCounter.ctrDiscarded))); CHKiRet(statsobj.ConstructFinalize(statsCounter.stats)); /* init civetweb libs and start server w/no input */ mg_init_library(MG_FEATURES_TLS); memset(&callbacks, 0, sizeof(callbacks)); // callbacks.log_message = log_message; // callbacks.init_ssl = init_ssl; callbacks.init_thread = init_thread; callbacks.exit_thread = exit_thread; s_httpserv->ctx = mg_start(&callbacks, NULL, s_httpserv->civetweb_options); /* Check return value: */ if (s_httpserv->ctx == NULL) { LogError(0, RS_RET_INTERNAL_ERROR, "Cannot start CivetWeb - mg_start failed.\n"); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } finalize_it: if (iRet != RS_RET_OK) { free(s_httpserv); s_httpserv = NULL; LogError(0, NO_ERRCODE, "imhttp: error %d trying to activate configuration", iRet); } RETiRet; ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf; for (inst = pModConf->root; inst != NULL;) { if (inst->ratelimiter) { ratelimitDestruct(inst->ratelimiter); } if (inst->pInputName) { prop.Destruct(&inst->pInputName); } free(inst->pszEndpoint); free(inst->pszBasicAuthFile); free(inst->pszBindRuleset); free(inst->pszInputName); del = inst; inst = inst->next; free(del); } for (int i = 0; i < pModConf->nOptions; ++i) { free((void *)pModConf->options[i].name); free((void *)pModConf->options[i].val); } free(pModConf->options); free((void *)pModConf->ports.name); free((void *)pModConf->ports.val); free((void *)pModConf->docroot.name); free((void *)pModConf->docroot.val); free((void *)pModConf->pszHealthCheckPath); free((void *)pModConf->pszMetricsPath); free((void *)pModConf->pszHealthCheckAuthFile); free((void *)pModConf->pszMetricsAuthFile); if (statsCounter.stats) { statsobj.Destruct(&statsCounter.stats); } ENDfreeCnf /* This function is called to gather input. */ BEGINrunInput CODESTARTrunInput; runloop(); ENDrunInput /* initialize and return if will run or not */ BEGINwillRun CODESTARTwillRun; ENDwillRun BEGINafterRun CODESTARTafterRun; if (s_httpserv) { mg_stop(s_httpserv->ctx); mg_exit_library(); free(s_httpserv->civetweb_options); free(s_httpserv); } ENDafterRun BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; // if(eFeat == sFEATURENonCancelInputTermination) // iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINmodExit CODESTARTmodExit; if (pInputName != NULL) { prop.Destruct(&pInputName); } /* release objects we used */ objRelease(statsobj, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imhttp"), sizeof("imhttp") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); ENDmodInit rsyslog-8.2512.0/contrib/imhttp/PaxHeaders/Makefile.in0000644000000000000000000000013115114544315017545 xustar0030 mtime=1764935885.791003947 30 atime=1764935896.970175183 29 ctime=1764935931.50570398 rsyslog-8.2512.0/contrib/imhttp/Makefile.in0000664000175000017500000006310015114544315017212 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imhttp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) imhttp_la_LIBADD = am_imhttp_la_OBJECTS = imhttp_la-imhttp.lo imhttp_la_OBJECTS = $(am_imhttp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imhttp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(imhttp_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imhttp_la-imhttp.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imhttp_la_SOURCES) DIST_SOURCES = $(imhttp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imhttp.la imhttp_la_SOURCES = imhttp.c imhttp_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(APU_CFLAGS) imhttp_la_LDFLAGS = -module -avoid-version $(CIVETWEB_LIBS) $(APU_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imhttp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imhttp/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imhttp.la: $(imhttp_la_OBJECTS) $(imhttp_la_DEPENDENCIES) $(EXTRA_imhttp_la_DEPENDENCIES) $(AM_V_CCLD)$(imhttp_la_LINK) -rpath $(pkglibdir) $(imhttp_la_OBJECTS) $(imhttp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imhttp_la-imhttp.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imhttp_la-imhttp.lo: imhttp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imhttp_la-imhttp.lo -MD -MP -MF $(DEPDIR)/imhttp_la-imhttp.Tpo -c -o imhttp_la-imhttp.lo `test -f 'imhttp.c' || echo '$(srcdir)/'`imhttp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imhttp_la-imhttp.Tpo $(DEPDIR)/imhttp_la-imhttp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imhttp.c' object='imhttp_la-imhttp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imhttp_la-imhttp.lo `test -f 'imhttp.c' || echo '$(srcdir)/'`imhttp.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imhttp_la-imhttp.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imhttp_la-imhttp.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/README0000644000000000000000000000013215035412264015053 xustar0030 mtime=1752569012.326271887 30 atime=1764931121.657006174 30 ctime=1764935920.445534662 rsyslog-8.2512.0/contrib/README0000664000175000017500000000110315035412264014512 0ustar00rgerrgerThis directory contains a number of possibly useful things that do not directly relate to rsyslog. They are not actively supported, but as I said often helpful. Use them with some care, as they may be outdated in respect to the current release of rsyslog. At least some of this stuff has been found by our users and been included after a brief check and possibly an adaptation. If you have something useful you would like to see in contrib, just drop us a note (see https://www.rsyslog.com for how to do that at the time your are reading this document). rgerhards, 2007-08-08 rsyslog-8.2512.0/contrib/PaxHeaders/ffaup0000644000000000000000000000013115114544370015220 xustar0030 mtime=1764935928.394656356 29 atime=1764935930.17368359 30 ctime=1764935928.394656356 rsyslog-8.2512.0/contrib/ffaup/0000775000175000017500000000000015114544370014742 5ustar00rgerrgerrsyslog-8.2512.0/contrib/ffaup/PaxHeaders/Makefile.am0000644000000000000000000000013115055602573017335 xustar0030 mtime=1756824955.959450467 29 atime=1764930927.20978837 30 ctime=1764935928.390656295 rsyslog-8.2512.0/contrib/ffaup/Makefile.am0000664000175000017500000000031415055602573017000 0ustar00rgerrger# # ffaup support # pkglib_LTLIBRARIES = ffaup.la ffaup_la_SOURCES = ffaup.c ffaup_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) ffaup_la_LDFLAGS = -module -avoid-version ffaup_la_LIBADD = $(FAUP_LIBS) rsyslog-8.2512.0/contrib/ffaup/PaxHeaders/ffaup.c0000644000000000000000000000013215055605325016545 xustar0030 mtime=1756826325.610800095 30 atime=1764931146.675409703 30 ctime=1764935928.394656356 rsyslog-8.2512.0/contrib/ffaup/ffaup.c0000664000175000017500000003565115055605325016223 0ustar00rgerrger/* ffaup.c * This is a function module for URL parsing. * * File begun on 2021/10/23 by TBertin * * Copyright 2007-2021 Theo Bertin for Advens * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #ifndef _AIX #include #endif #include #include #include #include #include #include #include "config.h" #include "rsyslog.h" #include "parserif.h" #include "module-template.h" #include "rainerscript.h" MODULE_TYPE_FUNCTION MODULE_TYPE_NOKEEP; DEF_FMOD_STATIC_DATA; faup_options_t *glbOptions = NULL; enum _faup_parse_type_t { FAUP_PARSE_ALL, FAUP_PARSE_SCHEME, FAUP_PARSE_CREDENTIAL, FAUP_PARSE_SUBDOMAIN, FAUP_PARSE_DOMAIN, FAUP_PARSE_DOMAIN_WITHOUT_TLD, FAUP_PARSE_HOST, FAUP_PARSE_TLD, FAUP_PARSE_PORT, FAUP_PARSE_RESOURCE_PATH, FAUP_PARSE_QUERY_STRING, FAUP_PARSE_FRAGMENT }; typedef enum _faup_parse_type_t faup_parse_type_t; static inline sbool check_param_count_faup(unsigned short nParams) { return nParams != 1; } static void ATTR_NONNULL() do_faup_parse(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti, const faup_parse_type_t parse_type) { struct svar srcVal; int bMustFree; cnfexprEval(func->expr[0], &srcVal, usrptr, pWti); char *url = (char *)var2CString(&srcVal, &bMustFree); /* We use the faup_handler_t struct directly instead of calling faup_init to avoid overhead and useless allocations. Using one handler is not possible as the lib is not thread-safe and thread-locale solutions still cause some issues. If the faup_init function changes significantly in the future, it may cause issue. (Validated with faup v1.5 and faup-master fecf768603e713bc903c56c8df0870fae14e3f93) */ faup_handler_t fh = {0}; fh.options = glbOptions; // default, return 0 ret->datatype = 'N'; ret->d.n = 0; if (!faup_decode(&fh, url, strlen(url))) { parser_errmsg("faup: could not parse the value\n"); // No returned error code, so the reason doesn't matter FINALIZE; } switch (parse_type) { case FAUP_PARSE_ALL: ret->datatype = 'J'; ret->d.json = json_object_new_object(); json_object_object_add( ret->d.json, "scheme", json_object_new_string_len(url + faup_get_scheme_pos(&fh), faup_get_scheme_size(&fh))); json_object_object_add( ret->d.json, "credential", json_object_new_string_len(url + faup_get_credential_pos(&fh), faup_get_credential_size(&fh))); json_object_object_add( ret->d.json, "subdomain", json_object_new_string_len(url + faup_get_subdomain_pos(&fh), faup_get_subdomain_size(&fh))); json_object_object_add( ret->d.json, "domain", json_object_new_string_len(url + faup_get_domain_pos(&fh), faup_get_domain_size(&fh))); json_object_object_add(ret->d.json, "domain_without_tld", json_object_new_string_len(url + faup_get_domain_without_tld_pos(&fh), faup_get_domain_without_tld_size(&fh))); json_object_object_add(ret->d.json, "host", json_object_new_string_len(url + faup_get_host_pos(&fh), faup_get_host_size(&fh))); json_object_object_add(ret->d.json, "tld", json_object_new_string_len(url + faup_get_tld_pos(&fh), faup_get_tld_size(&fh))); json_object_object_add(ret->d.json, "port", json_object_new_string_len(url + faup_get_port_pos(&fh), faup_get_port_size(&fh))); json_object_object_add( ret->d.json, "resource_path", json_object_new_string_len(url + faup_get_resource_path_pos(&fh), faup_get_resource_path_size(&fh))); json_object_object_add( ret->d.json, "query_string", json_object_new_string_len(url + faup_get_query_string_pos(&fh), faup_get_query_string_size(&fh))); json_object_object_add( ret->d.json, "fragment", json_object_new_string_len(url + faup_get_fragment_pos(&fh), faup_get_fragment_size(&fh))); break; case FAUP_PARSE_SCHEME: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_scheme_pos(&fh), faup_get_scheme_size(&fh)); break; case FAUP_PARSE_CREDENTIAL: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_credential_pos(&fh), faup_get_credential_size(&fh)); break; case FAUP_PARSE_SUBDOMAIN: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_subdomain_pos(&fh), faup_get_subdomain_size(&fh)); break; case FAUP_PARSE_DOMAIN: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_domain_pos(&fh), faup_get_domain_size(&fh)); break; case FAUP_PARSE_DOMAIN_WITHOUT_TLD: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_domain_without_tld_pos(&fh), faup_get_domain_without_tld_size(&fh)); break; case FAUP_PARSE_HOST: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_host_pos(&fh), faup_get_host_size(&fh)); break; case FAUP_PARSE_TLD: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_tld_pos(&fh), faup_get_tld_size(&fh)); break; case FAUP_PARSE_PORT: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_port_pos(&fh), faup_get_port_size(&fh)); break; case FAUP_PARSE_RESOURCE_PATH: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_resource_path_pos(&fh), faup_get_resource_path_size(&fh)); break; case FAUP_PARSE_QUERY_STRING: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_query_string_pos(&fh), faup_get_query_string_size(&fh)); break; case FAUP_PARSE_FRAGMENT: ret->datatype = 'S'; ret->d.estr = es_newStrFromCStr(url + faup_get_fragment_pos(&fh), faup_get_fragment_size(&fh)); break; default: break; } finalize_it: if (bMustFree) { free(url); } varFreeMembers(&srcVal); } static void ATTR_NONNULL() do_faup_parse_full(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_ALL); } static void ATTR_NONNULL() do_faup_parse_scheme(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_SCHEME); } static void ATTR_NONNULL() do_faup_parse_credential(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_CREDENTIAL); } static void ATTR_NONNULL() do_faup_parse_subdomain(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_SUBDOMAIN); } static void ATTR_NONNULL() do_faup_parse_domain(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_DOMAIN); } static void ATTR_NONNULL() do_faup_parse_domain_without_tld(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_DOMAIN_WITHOUT_TLD); } static void ATTR_NONNULL() do_faup_parse_host(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_HOST); } static void ATTR_NONNULL() do_faup_parse_tld(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_TLD); } static void ATTR_NONNULL() do_faup_parse_port(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_PORT); } static void ATTR_NONNULL() do_faup_parse_resource_path(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_RESOURCE_PATH); } static void ATTR_NONNULL() do_faup_parse_query_string(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_QUERY_STRING); } static void ATTR_NONNULL() do_faup_parse_fragment(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { do_faup_parse(func, ret, usrptr, pWti, FAUP_PARSE_FRAGMENT); } static rsRetVal ATTR_NONNULL(1) initFunc_faup_parse(struct cnffunc *const func) { DEFiRet; // Rsyslog cannot free the funcdata object, // a library-specific freeing function will be used during destruction func->destructable_funcdata = 0; if (check_param_count_faup(func->nParams)) { parser_errmsg("ffaup: ffaup(key) insufficient params.\n"); ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); } finalize_it: RETiRet; } static struct scriptFunct functions[] = { {"faup", 1, 1, do_faup_parse_full, initFunc_faup_parse, NULL}, {"faup_scheme", 1, 1, do_faup_parse_scheme, initFunc_faup_parse, NULL}, {"faup_credential", 1, 1, do_faup_parse_credential, initFunc_faup_parse, NULL}, {"faup_subdomain", 1, 1, do_faup_parse_subdomain, initFunc_faup_parse, NULL}, {"faup_domain", 1, 1, do_faup_parse_domain, initFunc_faup_parse, NULL}, {"faup_domain_without_tld", 1, 1, do_faup_parse_domain_without_tld, initFunc_faup_parse, NULL}, {"faup_host", 1, 1, do_faup_parse_host, initFunc_faup_parse, NULL}, {"faup_tld", 1, 1, do_faup_parse_tld, initFunc_faup_parse, NULL}, {"faup_port", 1, 1, do_faup_parse_port, initFunc_faup_parse, NULL}, {"faup_resource_path", 1, 1, do_faup_parse_resource_path, initFunc_faup_parse, NULL}, {"faup_query_string", 1, 1, do_faup_parse_query_string, initFunc_faup_parse, NULL}, {"faup_fragment", 1, 1, do_faup_parse_fragment, initFunc_faup_parse, NULL}, {NULL, 0, 0, NULL, NULL, NULL} // last element to check end of array }; BEGINgetFunctArray CODESTARTgetFunctArray; dbgprintf("Faup: ffaup\n"); *version = 1; *functArray = functions; ENDgetFunctArray BEGINmodExit CODESTARTmodExit; dbgprintf("ffaup: freeing options\n"); if (glbOptions) { faup_options_free(glbOptions); glbOptions = NULL; } ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_FMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ dbgprintf("ffaup: initializing options\n"); glbOptions = faup_options_new(); if (!glbOptions) { parser_errmsg("ffaup: could not initialize options\n"); ABORT_FINALIZE(RS_RET_FAUP_INIT_OPTIONS_FAILED); } // Don't generate a string output, and don't load LUA modules // This is useful only for the faup executable glbOptions->output = FAUP_OUTPUT_NONE; glbOptions->exec_modules = FAUP_MODULES_NOEXEC; CODEmodInit_QueryRegCFSLineHdlr dbgprintf("rsyslog ffaup init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/ffaup/PaxHeaders/Makefile.in0000644000000000000000000000013015114544315017340 xustar0029 mtime=1764935885.59400093 29 atime=1764935896.23616394 30 ctime=1764935928.392656325 rsyslog-8.2512.0/contrib/ffaup/Makefile.in0000664000175000017500000006306115114544315017014 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/ffaup ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = ffaup_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_ffaup_la_OBJECTS = ffaup_la-ffaup.lo ffaup_la_OBJECTS = $(am_ffaup_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = ffaup_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(ffaup_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ffaup_la-ffaup.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(ffaup_la_SOURCES) DIST_SOURCES = $(ffaup_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # ffaup support # pkglib_LTLIBRARIES = ffaup.la ffaup_la_SOURCES = ffaup.c ffaup_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) ffaup_la_LDFLAGS = -module -avoid-version ffaup_la_LIBADD = $(FAUP_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/ffaup/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/ffaup/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } ffaup.la: $(ffaup_la_OBJECTS) $(ffaup_la_DEPENDENCIES) $(EXTRA_ffaup_la_DEPENDENCIES) $(AM_V_CCLD)$(ffaup_la_LINK) -rpath $(pkglibdir) $(ffaup_la_OBJECTS) $(ffaup_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffaup_la-ffaup.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< ffaup_la-ffaup.lo: ffaup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ffaup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ffaup_la-ffaup.lo -MD -MP -MF $(DEPDIR)/ffaup_la-ffaup.Tpo -c -o ffaup_la-ffaup.lo `test -f 'ffaup.c' || echo '$(srcdir)/'`ffaup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ffaup_la-ffaup.Tpo $(DEPDIR)/ffaup_la-ffaup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ffaup.c' object='ffaup_la-ffaup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ffaup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ffaup_la-ffaup.lo `test -f 'ffaup.c' || echo '$(srcdir)/'`ffaup.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ffaup_la-ffaup.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ffaup_la-ffaup.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmcount0000644000000000000000000000013115114544371015602 xustar0030 mtime=1764935929.899679395 29 atime=1764935930.17368359 30 ctime=1764935929.899679395 rsyslog-8.2512.0/contrib/mmcount/0000775000175000017500000000000015114544371015324 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmcount/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264017710 xustar0029 mtime=1752569012.32825799 30 atime=1764930928.202805226 30 ctime=1764935929.895679334 rsyslog-8.2512.0/contrib/mmcount/Makefile.am0000664000175000017500000000031115035412264017350 0ustar00rgerrgerpkglib_LTLIBRARIES = mmcount.la mmcount_la_SOURCES = mmcount.c mmcount_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmcount_la_LDFLAGS = -module -avoid-version mmcount_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/mmcount/PaxHeaders/mmcount.c0000644000000000000000000000013215055605325017507 xustar0030 mtime=1756826325.612800125 30 atime=1764931151.342484752 30 ctime=1764935929.899679395 rsyslog-8.2512.0/contrib/mmcount/mmcount.c0000664000175000017500000002160315055605325017155 0ustar00rgerrger/* mmcount.c * count messages by priority or json property of given app-name. * * Copyright 2013 Red Hat Inc. * Copyright 2014 Rainer Gerhards * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "hashtable.h" #define JSON_COUNT_NAME "!mmcount" #define SEVERITY_COUNT 8 MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmcount") DEF_OMOD_STATIC_DATA; /* config variables */ typedef struct _instanceData { char *pszAppName; int severity[SEVERITY_COUNT]; char *pszKey; char *pszValue; int valueCounter; struct hashtable *ht; pthread_mutex_t mut; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"appname", eCmdHdlrGetWord, 0}, {"key", eCmdHdlrGetWord, 0}, {"value", eCmdHdlrGetWord, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; pthread_mutex_init(&pData->mut, NULL); ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance static inline void setInstParamDefaults(instanceData *pData) { int i; pData->pszAppName = NULL; for (i = 0; i < SEVERITY_COUNT; i++) pData->severity[i] = 0; pData->pszKey = NULL; pData->pszValue = NULL; pData->valueCounter = 0; pData->ht = NULL; } static unsigned int hash_from_key_fn(void *k) { return *(unsigned int *)k; } static int key_equals_fn(void *k1, void *k2) { return (*(unsigned int *)k1 == *(unsigned int *)k2); } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (mmcount)\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "appname")) { pData->pszAppName = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } if (!strcmp(actpblk.descr[i].name, "key")) { pData->pszKey = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } if (!strcmp(actpblk.descr[i].name, "value")) { pData->pszValue = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } dbgprintf( "mmcount: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } if (pData->pszAppName == NULL) { dbgprintf("mmcount: action requires a appname"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (pData->pszKey != NULL && pData->pszValue == NULL) { if (NULL == (pData->ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL))) { DBGPRINTF("mmcount: error creating hash table!\n"); ABORT_FINALIZE(RS_RET_ERR); } } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume static int *getCounter(struct hashtable *ht, const char *str) { unsigned int key; int *pCounter; unsigned int *pKey; /* we dont store str as key, instead we store hash of the str as key to reduce memory usage */ key = hash_from_string((char *)str); pCounter = hashtable_search(ht, &key); if (pCounter) { return pCounter; } /* counter is not found for the str, so add new entry and return the counter */ if (NULL == (pKey = (unsigned int *)malloc(sizeof(unsigned int)))) { DBGPRINTF("mmcount: memory allocation for key failed\n"); return NULL; } *pKey = key; if (NULL == (pCounter = (int *)malloc(sizeof(int)))) { DBGPRINTF("mmcount: memory allocation for value failed\n"); free(pKey); return NULL; } *pCounter = 0; if (!hashtable_insert(ht, pKey, pCounter)) { DBGPRINTF("mmcount: inserting element into hashtable failed\n"); free(pKey); free(pCounter); return NULL; } return pCounter; } BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; char *appname; struct json_object *json = NULL; struct json_object *keyjson = NULL; const char *pszValue; int *pCounter; instanceData *const pData = pWrkrData->pData; CODESTARTdoAction; appname = getAPPNAME(pMsg, LOCK_MUTEX); pthread_mutex_lock(&pData->mut); if (0 != strcmp(appname, pData->pszAppName)) { /* we are not working for this appname. nothing to do */ ABORT_FINALIZE(RS_RET_OK); } if (!pData->pszKey) { /* no key given for count, so we count severity */ if (pMsg->iSeverity < SEVERITY_COUNT) { pData->severity[pMsg->iSeverity]++; json = json_object_new_int(pData->severity[pMsg->iSeverity]); } ABORT_FINALIZE(RS_RET_OK); } /* key is given, so get the property json */ msgPropDescr_t pProp; msgPropDescrFill(&pProp, (uchar *)pData->pszKey, strlen(pData->pszKey)); rsRetVal localRet = msgGetJSONPropJSON(pMsg, &pProp, &keyjson); msgPropDescrDestruct(&pProp); if (localRet != RS_RET_OK) { /* key not found in the message. nothing to do */ ABORT_FINALIZE(RS_RET_OK); } /* key found, so get the value */ pszValue = (char *)json_object_get_string(keyjson); if (pszValue == NULL) { /* json null object returns NULL! */ pszValue = ""; } if (pData->pszValue) { /* value also given for count */ if (!strcmp(pszValue, pData->pszValue)) { /* count for (value and key and appname) matched */ pData->valueCounter++; json = json_object_new_int(pData->valueCounter); } ABORT_FINALIZE(RS_RET_OK); } /* value is not given, so we count for each value of given key */ pCounter = getCounter(pData->ht, pszValue); if (pCounter) { (*pCounter)++; json = json_object_new_int(*pCounter); } finalize_it: pthread_mutex_unlock(&pData->mut); if (json) { msgAddJSON(pMsg, (uchar *)JSON_COUNT_NAME, json, 0, 0); } ENDdoAction NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmcount: module compiled with rsyslog version %s.\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/mmcount/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017723 xustar0030 mtime=1764935885.941006245 30 atime=1764935896.480167677 30 ctime=1764935929.897679365 rsyslog-8.2512.0/contrib/mmcount/Makefile.in0000664000175000017500000006314715114544315017402 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmcount ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) mmcount_la_DEPENDENCIES = am_mmcount_la_OBJECTS = mmcount_la-mmcount.lo mmcount_la_OBJECTS = $(am_mmcount_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmcount_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(mmcount_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmcount_la-mmcount.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmcount_la_SOURCES) DIST_SOURCES = $(mmcount_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmcount.la mmcount_la_SOURCES = mmcount.c mmcount_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmcount_la_LDFLAGS = -module -avoid-version mmcount_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmcount/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmcount/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmcount.la: $(mmcount_la_OBJECTS) $(mmcount_la_DEPENDENCIES) $(EXTRA_mmcount_la_DEPENDENCIES) $(AM_V_CCLD)$(mmcount_la_LINK) -rpath $(pkglibdir) $(mmcount_la_OBJECTS) $(mmcount_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmcount_la-mmcount.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmcount_la-mmcount.lo: mmcount.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmcount_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmcount_la-mmcount.lo -MD -MP -MF $(DEPDIR)/mmcount_la-mmcount.Tpo -c -o mmcount_la-mmcount.lo `test -f 'mmcount.c' || echo '$(srcdir)/'`mmcount.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmcount_la-mmcount.Tpo $(DEPDIR)/mmcount_la-mmcount.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmcount.c' object='mmcount_la-mmcount.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmcount_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmcount_la-mmcount.lo `test -f 'mmcount.c' || echo '$(srcdir)/'`mmcount.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmcount_la-mmcount.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmcount_la-mmcount.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmsequence0000644000000000000000000000013215114544371016263 xustar0030 mtime=1764935929.989680773 30 atime=1764935930.174683605 30 ctime=1764935929.989680773 rsyslog-8.2512.0/contrib/mmsequence/0000775000175000017500000000000015114544371016004 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmsequence/PaxHeaders/mmsequence.c0000644000000000000000000000013115055605325020646 xustar0029 mtime=1756826325.61380014 30 atime=1764931094.438564738 30 ctime=1764935929.989680773 rsyslog-8.2512.0/contrib/mmsequence/mmsequence.c0000664000175000017500000002620215055605325020315 0ustar00rgerrger/* mmsequence.c * Generate a number based on some sequence. * * Copyright 2013 pavel@levshin.spb.ru. * * Based on: mmcount.c * Copyright 2013 Red Hat Inc. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "hashtable.h" #define JSON_VAR_NAME "$!mmsequence" enum mmSequenceModes { mmSequenceRandom, mmSequencePerInstance, mmSequencePerKey }; MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmsequence") DEF_OMOD_STATIC_DATA; /* config variables */ typedef struct _instanceData { enum mmSequenceModes mode; int valueFrom; int valueTo; int step; unsigned int seed; int value; char *pszKey; char *pszVar; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"mode", eCmdHdlrGetWord, 0}, {"from", eCmdHdlrNonNegInt, 0}, {"to", eCmdHdlrPositiveInt, 0}, {"step", eCmdHdlrNonNegInt, 0}, {"key", eCmdHdlrGetWord, 0}, {"var", eCmdHdlrGetWord, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /* table for key-counter pairs */ static struct hashtable *ght; static pthread_mutex_t ght_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t inst_mutex = PTHREAD_MUTEX_INITIALIZER; BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance static inline void setInstParamDefaults(instanceData *pData) { pData->mode = mmSequencePerInstance; pData->valueFrom = 0; pData->valueTo = INT_MAX; pData->step = 1; pData->pszKey = (char *)""; pData->pszVar = (char *)JSON_VAR_NAME; } BEGINnewActInst struct cnfparamvals *pvals; int i; char *cstr; CODESTARTnewActInst; DBGPRINTF("newActInst (mmsequence)\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "mode")) { if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"random", sizeof("random") - 1)) { pData->mode = mmSequenceRandom; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"instance", sizeof("instance") - 1)) { pData->mode = mmSequencePerInstance; } else if (!es_strbufcmp(pvals[i].val.d.estr, (uchar *)"key", sizeof("key") - 1)) { pData->mode = mmSequencePerKey; } else { cstr = es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_INVLD_MODE, "mmsequence: invalid mode '%s' - ignored", cstr); free(cstr); } continue; } if (!strcmp(actpblk.descr[i].name, "from")) { pData->valueFrom = pvals[i].val.d.n; continue; } if (!strcmp(actpblk.descr[i].name, "to")) { pData->valueTo = pvals[i].val.d.n; continue; } if (!strcmp(actpblk.descr[i].name, "step")) { pData->step = pvals[i].val.d.n; continue; } if (!strcmp(actpblk.descr[i].name, "key")) { pData->pszKey = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } if (!strcmp(actpblk.descr[i].name, "var")) { cstr = es_str2cstr(pvals[i].val.d.estr, NULL); if (strlen(cstr) < 3) { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "mmsequence: valid variable name should be at least " "3 symbols long, got %s", cstr); free(cstr); } else if (cstr[0] != '$') { LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "mmsequence: valid variable name should start with $," "got %s", cstr); free(cstr); } else { pData->pszVar = cstr; } continue; } dbgprintf( "mmsequence: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } switch (pData->mode) { case mmSequenceRandom: pData->seed = (unsigned int)(intptr_t)pData ^ (unsigned int)time(NULL); break; case mmSequencePerInstance: pData->value = pData->valueTo; break; case mmSequencePerKey: if (pthread_mutex_lock(&ght_mutex)) { DBGPRINTF("mmsequence: mutex lock has failed!\n"); ABORT_FINALIZE(RS_RET_ERR); } if (ght == NULL) { if (NULL == (ght = create_hashtable(100, hash_from_string, key_equals_string, NULL))) { pthread_mutex_unlock(&ght_mutex); DBGPRINTF("mmsequence: error creating hash table!\n"); ABORT_FINALIZE(RS_RET_ERR); } } pthread_mutex_unlock(&ght_mutex); break; default: LogError(0, RS_RET_INVLD_MODE, "mmsequence: this mode is not currently implemented"); } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume static int *getCounter(struct hashtable *ht, char *str, int initial) { int *pCounter; char *pStr; pCounter = hashtable_search(ht, str); if (pCounter) { return pCounter; } /* counter is not found for the str, so add new entry and return the counter */ if (NULL == (pStr = strdup(str))) { DBGPRINTF("mmsequence: memory allocation for key failed\n"); return NULL; } if (NULL == (pCounter = (int *)malloc(sizeof(*pCounter)))) { DBGPRINTF("mmsequence: memory allocation for value failed\n"); free(pStr); return NULL; } *pCounter = initial; if (!hashtable_insert(ht, pStr, pCounter)) { DBGPRINTF("mmsequence: inserting element into hashtable failed\n"); free(pStr); free(pCounter); return NULL; } return pCounter; } BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; struct json_object *json; int val = 0; int *pCounter; instanceData *pData; CODESTARTdoAction; pData = pWrkrData->pData; switch (pData->mode) { case mmSequenceRandom: val = pData->valueFrom + (rand_r(&pData->seed) % (pData->valueTo - pData->valueFrom)); break; case mmSequencePerInstance: if (!pthread_mutex_lock(&inst_mutex)) { if (pData->value >= pData->valueTo - pData->step) { pData->value = pData->valueFrom; } else { pData->value += pData->step; } val = pData->value; pthread_mutex_unlock(&inst_mutex); } else { LogError(0, RS_RET_ERR, "mmsequence: mutex lock has failed!"); } break; case mmSequencePerKey: if (!pthread_mutex_lock(&ght_mutex)) { pCounter = getCounter(ght, pData->pszKey, pData->valueTo); if (pCounter) { if (*pCounter >= pData->valueTo - pData->step || *pCounter < pData->valueFrom) { *pCounter = pData->valueFrom; } else { *pCounter += pData->step; } val = *pCounter; } else { LogError(0, RS_RET_NOT_FOUND, "mmsequence: unable to fetch the counter from hash"); } pthread_mutex_unlock(&ght_mutex); } else { LogError(0, RS_RET_ERR, "mmsequence: mutex lock has failed!"); } break; default: LogError(0, RS_RET_NOT_IMPLEMENTED, "mmsequence: this mode is not currently implemented"); } /* finalize_it: */ json = json_object_new_int(val); if (json == NULL) { LogError(0, RS_RET_OBJ_CREATION_FAILED, "mmsequence: unable to create JSON"); } else if (RS_RET_OK != msgAddJSON(pMsg, (uchar *)pData->pszVar + 1, json, 0, 0)) { LogError(0, RS_RET_OBJ_CREATION_FAILED, "mmsequence: unable to pass out the value"); json_object_put(json); } ENDdoAction NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmsequence: module compiled with rsyslog version %s.\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/mmsequence/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020371 xustar0030 mtime=1752569012.329251042 30 atime=1764930928.604812048 30 ctime=1764935929.984680697 rsyslog-8.2512.0/contrib/mmsequence/Makefile.am0000664000175000017500000000033315035412264020034 0ustar00rgerrgerpkglib_LTLIBRARIES = mmsequence.la mmsequence_la_SOURCES = mmsequence.c mmsequence_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmsequence_la_LDFLAGS = -module -avoid-version mmsequence_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/mmsequence/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316020404 xustar0030 mtime=1764935886.084008436 30 atime=1764935896.574169117 30 ctime=1764935929.986680727 rsyslog-8.2512.0/contrib/mmsequence/Makefile.in0000664000175000017500000006342515114544316020062 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmsequence ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) mmsequence_la_DEPENDENCIES = am_mmsequence_la_OBJECTS = mmsequence_la-mmsequence.lo mmsequence_la_OBJECTS = $(am_mmsequence_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmsequence_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(mmsequence_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmsequence_la-mmsequence.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmsequence_la_SOURCES) DIST_SOURCES = $(mmsequence_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmsequence.la mmsequence_la_SOURCES = mmsequence.c mmsequence_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmsequence_la_LDFLAGS = -module -avoid-version mmsequence_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmsequence/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmsequence/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmsequence.la: $(mmsequence_la_OBJECTS) $(mmsequence_la_DEPENDENCIES) $(EXTRA_mmsequence_la_DEPENDENCIES) $(AM_V_CCLD)$(mmsequence_la_LINK) -rpath $(pkglibdir) $(mmsequence_la_OBJECTS) $(mmsequence_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmsequence_la-mmsequence.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmsequence_la-mmsequence.lo: mmsequence.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmsequence_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmsequence_la-mmsequence.lo -MD -MP -MF $(DEPDIR)/mmsequence_la-mmsequence.Tpo -c -o mmsequence_la-mmsequence.lo `test -f 'mmsequence.c' || echo '$(srcdir)/'`mmsequence.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmsequence_la-mmsequence.Tpo $(DEPDIR)/mmsequence_la-mmsequence.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmsequence.c' object='mmsequence_la-mmsequence.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmsequence_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmsequence_la-mmsequence.lo `test -f 'mmsequence.c' || echo '$(srcdir)/'`mmsequence.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmsequence_la-mmsequence.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmsequence_la-mmsequence.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/imtuxedoulog0000644000000000000000000000013215114544373016650 xustar0030 mtime=1764935931.332701332 30 atime=1764935934.366747775 30 ctime=1764935931.332701332 rsyslog-8.2512.0/contrib/imtuxedoulog/0000775000175000017500000000000015114544373016371 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imtuxedoulog/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264020753 xustar0029 mtime=1752569012.32825799 30 atime=1764930928.116803766 30 ctime=1764935931.325701225 rsyslog-8.2512.0/contrib/imtuxedoulog/Makefile.am0000664000175000017500000000043315035412264020420 0ustar00rgerrgerpkglib_LTLIBRARIES = imtuxedoulog.la imtuxedoulog_la_SOURCES = imtuxedoulog.c imtuxedoulog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imtuxedoulog_la_LDFLAGS = -module -avoid-version imtuxedoulog_la_LIBADD = if OS_AIX imtuxedoulog_la_CPPFLAGS += -ma endif rsyslog-8.2512.0/contrib/imtuxedoulog/PaxHeaders/imtuxedoulog.c0000644000000000000000000000013215055605325021615 xustar0030 mtime=1756826325.612800125 30 atime=1764931155.619553467 30 ctime=1764935931.332701332 rsyslog-8.2512.0/contrib/imtuxedoulog/imtuxedoulog.c0000664000175000017500000006700115055605325021265 0ustar00rgerrger/* imtuxedoulog.c * * This is the input module for reading Tuxedo ULOG files. The particularity of this file * is that the timestamp is split between the filename (date) and the log line (time). * So this module switches on the date base betwwen files to open only the current file. * The log line is parsed according to the Tuxedo format. The ECID is extracted as a * structured data attribute. * * Work originally begun on 2019-01-11 by Philippe Duveau * * This file is contribution of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include /* do NOT remove: will soon be done by the module generation macros */ #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef _AIX #include #endif #include "rsyslog.h" /* error codes etc... */ #include "dirty.h" #include "cfsysline.h" /* access to config file objects */ #include "module-template.h" /* generic module interface code - very important, read it! */ #include "srUtils.h" /* some utility functions */ #include "msg.h" #include "stream.h" #include "errmsg.h" #include "glbl.h" #include "unicode-helper.h" #include "prop.h" #include "stringbuf.h" #include "ruleset.h" #include "ratelimit.h" struct instanceConf_s { uchar *pszUlogBaseName; uchar *pszCurrFName; struct tm currTm; uchar *pszTag; size_t lenTag; uchar *pszStateFile; uchar *pszBindRuleset; int nMultiSub; int iPersistStateInterval; int iFacility; int iSeverity; strm_t *pStrm; /* its stream (NULL if not assigned) */ int maxLinesAtOnce; ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ ratelimit_t *ratelimiter; multi_submit_t multiSub; int nRecords; struct instanceConf_s *next; struct instanceConf_s *prev; }; /* config variables */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static instanceConf_t *confRoot = NULL; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for run process */ MODULE_TYPE_INPUT /* must be present for input modules, do not remove */ MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imtuxedoulog") /* defines */ /* Module static data */ DEF_IMOD_STATIC_DATA /* must be present, starts static data */ DEFobjCurrIf(glbl) DEFobjCurrIf(strm) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) #define NUM_MULTISUB 1024 /* default max number of submits */ #define DFLT_PollInterval 10 int iPollInterval = DFLT_PollInterval; int iPersistStateInterval = 0; /* how often if state file to be persisted? (default 0->never) */ struct syslogTime syslogTz; static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this input */ /* module-global parameters */ /* input instance parameters */ static struct cnfparamdescr inppdescr[] = {{"ulogbase", eCmdHdlrString, CNFPARAM_REQUIRED}, {"tag", eCmdHdlrString, CNFPARAM_REQUIRED}, {"severity", eCmdHdlrSeverity, 0}, {"facility", eCmdHdlrFacility, 0}, {"ruleset", eCmdHdlrString, 0}, {"maxlinesatonce", eCmdHdlrInt, 0}, {"persiststateinterval", eCmdHdlrInt, 0}, {"maxsubmitatonce", eCmdHdlrInt, 0}}; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; #include "im-helper.h" /* must be included AFTER the type definitions! */ static uchar *mkFileNameWithTime(instanceConf_t *in) { uchar out[MAXFNAME]; struct timeval tp; #if defined(__hpux) struct timezone tz; gettimeofday(&tp, &tz); #else gettimeofday(&tp, NULL); #endif localtime_r(&tp.tv_sec, &(in->currTm)); snprintf((char *)out, MAXFNAME, "%s.%02d%02d%02d", (char *)in->pszUlogBaseName, in->currTm.tm_mon + 1, in->currTm.tm_mday, in->currTm.tm_year % 100); return ustrdup(out); } /* * Helper function to combine statefile and workdir */ static int getFullStateFileName(uchar *pszstatefile, uchar *pszout, int ilenout) { int lenout; const uchar *pszworkdir; /* Get Raw Workdir, if it is NULL we need to propper handle it */ pszworkdir = glblGetWorkDirRaw(runModConf->pConf); /* Construct file name */ lenout = snprintf((char *)pszout, ilenout, "%s/%s", (char *)(pszworkdir == NULL ? "." : (char *)pszworkdir), (char *)pszstatefile); /* return out length */ return lenout; } /* this generates a state file name suitable for the current file. To avoid * malloc calls, it must be passed a buffer which should be MAXFNAME large. * Note: the buffer is not necessarily populated ... always ONLY use the * RETURN VALUE! */ static uchar *ATTR_NONNULL(2) getStateFileName(instanceConf_t *const __restrict__ pInst, uchar *const __restrict__ buf, size_t lenbuf, const uchar *pszFileName) { uchar *ret; /* Use pszFileName parameter if set */ pszFileName = pszFileName == NULL ? pInst->pszUlogBaseName : pszFileName; DBGPRINTF("getStateFileName for '%s'\n", pszFileName); if (pInst == NULL || pInst->pszStateFile == NULL) { lenbuf = snprintf((char *)buf, lenbuf - 1, "imtuxedoulog-state:%s", pszFileName); buf[lenbuf] = '\0'; /* be on the safe side... */ uchar *p = buf; for (; *p; ++p) { if (*p == '/') *p = '-'; } ret = buf; } else { ret = pInst->pszStateFile; } return ret; } /* this func parses the line according to samples described in README.md */ static rsRetVal parseMsg(smsg_t *pMsg, char *rawMsg, size_t msgLen, instanceConf_t *const __restrict__ pInst) { char *prog, *host, *text = NULL, *strtData = NULL, *tmp; int hour, min, sec; rsRetVal ret; hour = (rawMsg[0] ^ 0x30) * 10 + (rawMsg[1] ^ 0x30); min = (rawMsg[2] ^ 0x30) * 10 + (rawMsg[3] ^ 0x30); sec = (rawMsg[4] ^ 0x30) * 10 + (rawMsg[5] ^ 0x30); if (hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || sec > 59) return RS_RET_COULD_NOT_PARSE; host = rawMsg + ((rawMsg[10] == '.') ? 11 : 10); prog = memchr(host, '!', msgLen - (host - rawMsg)); if (prog == NULL) return RS_RET_COULD_NOT_PARSE; prog++; strtData = memchr(prog, ':', msgLen - (prog - rawMsg)); if (strtData == NULL) return RS_RET_COULD_NOT_PARSE; pMsg->tTIMESTAMP.year = pInst->currTm.tm_year + 1900; pMsg->tTIMESTAMP.month = pInst->currTm.tm_mon + 1; pMsg->tTIMESTAMP.day = pInst->currTm.tm_mday; pMsg->tTIMESTAMP.hour = hour; pMsg->tTIMESTAMP.minute = min; pMsg->tTIMESTAMP.second = sec; pMsg->tTIMESTAMP.OffsetMode = syslogTz.OffsetMode; pMsg->tTIMESTAMP.OffsetHour = syslogTz.OffsetHour; pMsg->tTIMESTAMP.OffsetMinute = syslogTz.OffsetMinute; pMsg->tTIMESTAMP.secfrac = atoi(rawMsg + 7); /* secfracprecision depends on the char on position 9 (case 1 or case 2) */ pMsg->tTIMESTAMP.secfracPrecision = (rawMsg[9] == '.') ? 2 : 3; for (tmp = strtData; prog < tmp && *tmp != '.'; tmp--); if (tmp > prog) *tmp = '\0'; else *strtData = '\0'; strtData = strtData + 2; /* Case 4 */ if (memcmp(strtData, "gtrid", 5) == 0) { strtData = memchr(strtData, ':', msgLen - (strtData - rawMsg)); if (strtData != NULL) strtData += 2; } text = strtData; /* ecid point to message text or the word ECID */ if (strtData != NULL && memcmp(strtData, "ECID", 4) == 0) { text = memchr(strtData + 6, '>', msgLen - (strtData - rawMsg)); /* case 3 : we have the word ECID */ if (text != NULL) { *(--strtData) = '['; strtData[5] = '='; strtData[6] = '\"'; *text++ = '\"'; *text++ = ']'; text++; ret = MsgAddToStructuredData(pMsg, (uchar *)strtData, text - strtData); if (ret != RS_RET_OK) LogMsg(0, ret, LOG_WARNING, "Add StructuredData to message failed."); } } /* now compute the new length */ msgLen -= text - rawMsg; if (text != NULL) MsgSetRawMsg(pMsg, text, msgLen); MsgSetMSGoffs(pMsg, 0); /* set hostname */ MsgSetHOSTNAME(pMsg, (const uchar *)host, prog - host - 1); if (*prog == '\0') return 0; /* set procid */ ret = MsgSetPROCID(pMsg, prog); if (ret != RS_RET_OK) LogMsg(0, ret, LOG_WARNING, "Set PROCID to message failed."); return RS_RET_OK; } /* enqueue the read file line as a message. The provided string is * not freed - this must be done by the caller. */ #define MAX_OFFSET_REPRESENTATION_NUM_BYTES 20 static rsRetVal enqLine(instanceConf_t *const __restrict__ pInst, cstr_t *const __restrict__ cstrLine) { DEFiRet; smsg_t *pMsg; const size_t msgLen = cstrLen(cstrLine); rsRetVal ret; if (msgLen == 0) { /* we do not process empty lines */ FINALIZE; } CHKiRet(msgConstruct(&pMsg)); if (parseMsg(pMsg, (char *)rsCStrGetSzStrNoNULL(cstrLine), msgLen, pInst) != RS_RET_OK) { if ((ret = msgDestruct(&pMsg)) != RS_RET_OK) LogMsg(0, ret, LOG_ERR, "msgDestruct failed."); FINALIZE; } MsgSetInputName(pMsg, pInputName); MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); msgSetPRI(pMsg, pInst->iFacility | pInst->iSeverity); MsgSetRuleset(pMsg, pInst->pBindRuleset); if ((ret = MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY)) != RS_RET_OK) LogMsg(0, ret, LOG_WARNING, "Set Flow Control to message failed."); if ((ret = MsgSetAPPNAME(pMsg, (const char *)pInst->pszTag)) != RS_RET_OK) LogMsg(0, ret, LOG_WARNING, "Set APPNAME to message failed."); if ((iRet = ratelimitAddMsg(pInst->ratelimiter, &pInst->multiSub, pMsg)) != RS_RET_OK) { if ((ret = msgDestruct(&pMsg)) != RS_RET_OK) LogMsg(0, ret, LOG_ERR, "msgDestruct failed."); } finalize_it: RETiRet; } /* try to open a file which has a state file. If the state file does not * exist or cannot be read, an error is returned. */ static rsRetVal ATTR_NONNULL(1) openFileWithStateFile(instanceConf_t *const __restrict__ pInst) { DEFiRet; strm_t *psSF = NULL; uchar pszSFNam[MAXFNAME]; size_t lenSFNam; struct stat stat_buf; uchar statefile[MAXFNAME]; uchar *const statefn = getStateFileName(pInst, statefile, sizeof(statefile), NULL); DBGPRINTF("trying to open state for '%s', state file '%s'\n", pInst->pszUlogBaseName, statefn); /* Get full path and file name */ lenSFNam = getFullStateFileName(statefn, pszSFNam, sizeof(pszSFNam)); /* check if the file exists */ if (stat((char *)pszSFNam, &stat_buf) == -1) { if (errno == ENOENT) { DBGPRINTF("NO state file (%s) exists for '%s'\n", pszSFNam, pInst->pszUlogBaseName); ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); } else { char errStr[1024]; rs_strerror_r(errno, errStr, sizeof(errStr)); DBGPRINTF("error trying to access state file for '%s':%s\n", pInst->pszUlogBaseName, errStr); ABORT_FINALIZE(RS_RET_IO_ERROR); } } /* If we reach this point, we have a state file */ CHKiRet(strm.Construct(&psSF)); CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_READ)); CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetFName(psSF, pszSFNam, lenSFNam)); CHKiRet(strm.SetFileNotFoundError(psSF, 1)); CHKiRet(strm.ConstructFinalize(psSF)); /* read back in the object */ CHKiRet(obj.Deserialize(&pInst->pStrm, (uchar *)"strm", psSF, NULL, pInst)); DBGPRINTF( "deserialized state file, state file base name '%s', " "configured base name '%s'\n", pInst->pStrm->pszFName, pInst->pszUlogBaseName); if (ustrcmp(pInst->pStrm->pszFName, pInst->pszCurrFName)) { LogError(0, RS_RET_STATEFILE_WRONG_FNAME, "imtuxedoulog: state file '%s' " "contains file name '%s', but is used for file '%s'. State " "file deleted, starting from begin of file.", pszSFNam, pInst->pStrm->pszFName, pInst->pszCurrFName); unlink((char *)pszSFNam); ABORT_FINALIZE(RS_RET_STATEFILE_WRONG_FNAME); } strm.CheckFileChange(pInst->pStrm); CHKiRet(strm.SeekCurrOffs(pInst->pStrm)); /* note: we do not delete the state file, so that the last position remains * known even in the case that rsyslogd aborts for some reason (like powerfail) */ finalize_it: if (psSF != NULL) strm.Destruct(&psSF); RETiRet; } /* try to open a file for which no state file exists. This function does NOT * check if a state file actually exists or not -- this must have been * checked before calling it. */ static rsRetVal openFileWithoutStateFile(instanceConf_t *const __restrict__ pInst) { DEFiRet; DBGPRINTF("clean startup withOUT state file for '%s'\n", pInst->pszUlogBaseName); if (pInst->pStrm != NULL) strm.Destruct(&pInst->pStrm); CHKiRet(strm.Construct(&pInst->pStrm)); CHKiRet(strm.SettOperationsMode(pInst->pStrm, STREAMMODE_READ)); CHKiRet(strm.SetsType(pInst->pStrm, STREAMTYPE_FILE_MONITOR)); CHKiRet(strm.SetFName(pInst->pStrm, pInst->pszCurrFName, strlen((char *)pInst->pszCurrFName))); CHKiRet(strm.SetFileNotFoundError(pInst->pStrm, 1)); CHKiRet(strm.ConstructFinalize(pInst->pStrm)); finalize_it: RETiRet; } /* try to open a file. This involves checking if there is a status file and, * if so, reading it in. Processing continues from the last known location. */ static rsRetVal openFile(instanceConf_t *const __restrict__ pInst) { DEFiRet; CHKiRet_Hdlr(openFileWithStateFile(pInst)) { CHKiRet(openFileWithoutStateFile(pInst)); } CHKiRet(strm.SetbReopenOnTruncate(pInst->pStrm, 1)); finalize_it: RETiRet; } /* This function persists information for a specific file being monitored. * To do so, it simply persists the stream object. We do NOT abort on error * iRet as that makes matters worse (at least we can try persisting the others...). * rgerhards, 2008-02-13 */ static void persistStrmState(instanceConf_t *pInst) { DEFiRet; strm_t *psSF = NULL; /* state file (stream) */ size_t lenDir; uchar statefile[MAXFNAME]; uchar *const statefn = getStateFileName(pInst, statefile, sizeof(statefile), NULL); DBGPRINTF("persisting state for '%s' to file '%s'\n", pInst->pszUlogBaseName, statefn); CHKiRet(strm.Construct(&psSF)); lenDir = ustrlen(glbl.GetWorkDir(runModConf->pConf)); if (lenDir > 0) CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(runModConf->pConf), lenDir)); CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_WRITE_TRUNC)); CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetFName(psSF, statefn, strlen((char *)statefn))); CHKiRet(strm.SetFileNotFoundError(psSF, 1)); CHKiRet(strm.ConstructFinalize(psSF)); CHKiRet(strm.Serialize(pInst->pStrm, psSF)); CHKiRet(strm.Flush(psSF)); CHKiRet(strm.Destruct(&psSF)); finalize_it: if (psSF != NULL) strm.Destruct(&psSF); if (iRet != RS_RET_OK) { LogError(0, iRet, "imtuxedoulog: could not persist state " "file %s - data may be repeated on next " "startup. Is WorkDirectory set?", statefn); } } /* The following is a cancel cleanup handler for strmReadLine(). It is necessary in case * strmReadLine() is cancelled while processing the stream. -- rgerhards, 2008-03-27 */ static void pollFileCancelCleanup(void *pArg) { cstr_t **ppCStr = (cstr_t **)pArg; if (*ppCStr != NULL) { rsCStrDestruct(ppCStr); } } static void pollFileReal(instanceConf_t *pInst, int *pbHadFileData, cstr_t **ppCStr) { DEFiRet; int nProcessed = 0; if (pInst->pStrm == NULL) { CHKiRet(openFile(pInst)); /* open file */ } /* loop below will be exited when strmReadLine() returns EOF */ while (glbl.GetGlobalInputTermState() == 0) { if (pInst->maxLinesAtOnce != 0 && nProcessed >= pInst->maxLinesAtOnce) break; CHKiRet(strm.ReadLine(pInst->pStrm, ppCStr, 0, 0, NULL, -1, NULL)); ++nProcessed; if (pbHadFileData != NULL) *pbHadFileData = 1; /* this is just a flag, so set it and forget it */ CHKiRet(enqLine(pInst, *ppCStr)); /* process line */ rsCStrDestruct(ppCStr); /* discard string (must be done by us!) */ if (pInst->iPersistStateInterval > 0 && ++pInst->nRecords >= pInst->iPersistStateInterval) { persistStrmState(pInst); pInst->nRecords = 0; } } finalize_it: multiSubmitFlush(&pInst->multiSub); if (*ppCStr != NULL) { rsCStrDestruct(ppCStr); } } /* poll a file, need to check file rollover etc. open file if not open */ static void pollFile(instanceConf_t *pInst, int *pbHadFileData) { cstr_t *pCStr = NULL; /* Note: we must do pthread_cleanup_push() immediately, because the POSIX macros * otherwise do not work if I include the _cleanup_pop() inside an if... -- rgerhards, 2008-08-14 */ pthread_cleanup_push(pollFileCancelCleanup, &pCStr); pollFileReal(pInst, pbHadFileData, &pCStr); pthread_cleanup_pop(0); } /* create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal ATTR_NONNULL(1) createInstance(instanceConf_t **const pinst) { instanceConf_t *inst; DEFiRet; CHKmalloc(inst = malloc(sizeof(instanceConf_t))); inst->next = NULL; inst->pBindRuleset = NULL; inst->ratelimiter = NULL; inst->pStrm = NULL; inst->multiSub.ppMsgs = NULL; inst->pszBindRuleset = NULL; inst->pszUlogBaseName = NULL; inst->pszCurrFName = NULL; inst->pszTag = NULL; inst->pszStateFile = NULL; inst->nMultiSub = NUM_MULTISUB; inst->iSeverity = 5; inst->iFacility = 128; inst->maxLinesAtOnce = 0; inst->iPersistStateInterval = 0; inst->nRecords = 0; *pinst = inst; finalize_it: RETiRet; } /* This adds a new listener object to the bottom of the list, but * it does NOT initialize any data members except for the list * pointers themselves. */ static rsRetVal ATTR_NONNULL() lstnAdd(instanceConf_t *pInst) { DEFiRet; CHKiRet(ratelimitNew(&pInst->ratelimiter, "imtuxedoulog", (char *)pInst->pszUlogBaseName)); CHKmalloc(pInst->multiSub.ppMsgs = malloc(pInst->nMultiSub * sizeof(smsg_t *))); pInst->multiSub.maxElem = pInst->nMultiSub; pInst->multiSub.nElem = 0; /* insert it at the begin of the list */ pInst->prev = NULL; pInst->next = confRoot; if (confRoot != NULL) confRoot->prev = pInst; confRoot = pInst; finalize_it: RETiRet; } /* delete a listener object */ static void ATTR_NONNULL(1) lstnDel(instanceConf_t *pInst) { DBGPRINTF("lstnDel called for %s\n", pInst->pszUlogBaseName); if (pInst->pStrm != NULL) { /* stream open? */ persistStrmState(pInst); strm.Destruct(&(pInst->pStrm)); } if (pInst->ratelimiter != NULL) ratelimitDestruct(pInst->ratelimiter); if (pInst->multiSub.ppMsgs != NULL) free(pInst->multiSub.ppMsgs); free(pInst->pszUlogBaseName); if (pInst->pszCurrFName != NULL) free(pInst->pszCurrFName); if (pInst->pszTag) free(pInst->pszTag); if (pInst->pszStateFile) free(pInst->pszStateFile); if (pInst->pszBindRuleset != NULL) free(pInst->pszBindRuleset); free(pInst); } /* Monitor files in traditional polling mode. */ static void do_polling(void) { int bHadFileData; /* were there at least one file with data during this run? */ struct stat sb; while (glbl.GetGlobalInputTermState() == 0) { do { instanceConf_t *pInst; bHadFileData = 0; for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { uchar *temp = mkFileNameWithTime(pInst); DBGPRINTF("imtuxedoulog: do_polling start '%s' / '%s'\n", pInst->pszUlogBaseName, temp); /* * Is the file name is different : a rotation time is reached * If so, then it the new file exists ? and is a file ? */ if (temp && stat((const char *)temp, &sb) == 0 && S_ISREG(sb.st_mode) && (pInst->pszCurrFName == NULL || strcmp((char *)temp, (char *)pInst->pszCurrFName) != 0)) { DBGPRINTF( "imtuxedoulog: timed file : rotation reach " "switching form '%s' to '%s' !", (char *)pInst->pszUlogBaseName, temp); /* first of all change the listener datas */ if (pInst->pszCurrFName != NULL) { free(pInst->pszCurrFName); strm.Destruct(&pInst->pStrm); } pInst->pszCurrFName = temp; temp = NULL; /* And finish by destroy the stream object, so the next polling will recreate * it based on new data. */ if (glbl.GetGlobalInputTermState() == 1) break; /* terminate input! */ } if (temp) free(temp); /* let's poll the file */ if (pInst->pszCurrFName != NULL) pollFile(pInst, &bHadFileData); DBGPRINTF("imtuxedoulog: do_polling end for '%s'\n", pInst->pszUlogBaseName); if (pInst->iPersistStateInterval == -1) persistStrmState(pInst); } } while (bHadFileData == 1 && glbl.GetGlobalInputTermState() == 0); /* Note: the additional 10ns wait is vitally important. It guards rsyslog * against totally hogging the CPU if the users selects a polling interval * of 0 seconds. It doesn't hurt any other valid scenario. So do not remove. * rgerhards, 2008-02-14 */ if (glbl.GetGlobalInputTermState() == 0) srSleep(iPollInterval, 10); } } BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst; int i; CODESTARTnewInpInst; DBGPRINTF("newInpInst (imtuxedoulog)\n"); pvals = nvlstGetParams(lst, &inppblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { DBGPRINTF("input param blk in imtuxedoulog:\n"); cnfparamsPrint(&inppblk, pvals); } CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "ulogbase")) { inst->pszUlogBaseName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "tag")) { inst->pszTag = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); inst->lenTag = es_strlen(pvals[i].val.d.estr); } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "severity")) { inst->iSeverity = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "facility")) { inst->iFacility = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "maxlinesatonce")) { inst->maxLinesAtOnce = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "persiststateinterval")) { inst->iPersistStateInterval = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "maxsubmitatonce")) { inst->nMultiSub = pvals[i].val.d.n; } else { DBGPRINTF( "program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } if (inst->pszUlogBaseName == NULL) { lstnDel(inst); LogError(0, RS_RET_FILE_NOT_SPECIFIED, "ulogbase is not configured - no input will be gathered"); ABORT_FINALIZE(RS_RET_FILE_NOT_SPECIFIED); } if ((iRet = lstnAdd(inst)) != RS_RET_OK) { LogError(0, iRet, "add input %s to list failed", inst->pszUlogBaseName); lstnDel(inst); ABORT_FINALIZE(iRet); } finalize_it: CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = confRoot; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); } ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINrunInput CODESTARTrunInput; do_polling(); DBGPRINTF("terminating upon request of rsyslog core\n"); ENDrunInput BEGINwillRun CODESTARTwillRun; /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imtuxedoulog"), sizeof("imtuxedoulog") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); finalize_it: ENDwillRun BEGINafterRun CODESTARTafterRun; while (confRoot != NULL) { instanceConf_t *inst = confRoot; confRoot = confRoot->next; lstnDel(inst); } if (pInputName != NULL) prop.Destruct(&pInputName); ENDafterRun BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINmodExit CODESTARTmodExit; /* release objects we used */ objRelease(strm, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "imtuxedoulog: ruleset '%s' for ULOG base %s not found - " "using default ruleset instead", inst->pszBindRuleset, inst->pszUlogBaseName); } BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(strm, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/imtuxedoulog/PaxHeaders/README.md0000644000000000000000000000013115035412264020176 xustar0029 mtime=1752569012.32825799 30 atime=1764865110.875065461 30 ctime=1764935931.330701301 rsyslog-8.2512.0/contrib/imtuxedoulog/README.md0000664000175000017500000000410115035412264017637 0ustar00rgerrger# imtuxedoulog : Tuxedo ULOG input module ### Module summary This module is created to consume Tuxedo ULOG file. This file has the following characteristics : - the file name is compose of a prefix and the date of the file. - the lines of logs are produced by call to userlog() tuxedo method. - Tuxedo server based on JAVA writes java's exceptions as log lines in ULOG file. This version of the module ignores those lines. - The ECID (Execution Context ID) is extracted and placed as a structured data named ECID. ### Why this module instead of using imfile As the file name is a rotation base of the current date, imfile must use a glob to manage this rotation. Imfile must use fs notify implement of the OS. This interface is implemented in imfile for Linux and Solaris but not AIX. Like imfile does, this module is using the same rsyslog core stream and then gets advantages its evolves. Primary we tried to integrating in imfile a "glob like" in polling mode, it increased the module complexity and make it unmaintainable. So imfile could not be a valid candidate on none fs notification OS like AIX. ### Ulog log samples This are different case of logs in the ULOG file according to the usage. Case 1: second fraction precision = 2 ``` 105211.70.sic-in2-tmsl1!IMSproxiCSFI4EC.26607818.1.0: TSAM_CAT:305:4563628752 ; I ;TPSUCCESS service ^host ^prog lprog> ^text ``` Case 2: second fraction precision = 3 ``` 011458.705.sic-tst-tmsl1!LMS.5243392.772.3: TSAM_CAT:305: WARN: (23498) times logon TSAM Plus manager ^host ^prog lprog> ^text ``` Case 3: with ECID ``` 105211.704.sic-in2-tmsl1!IMSproxiCSFI4EC.26607818.1.0: ECID <000003GBORvD4iopwSXBiW01xG2M00001n>: 4563628752 ^host ^prog lprog> ^ecid ^text ``` Case 4: with gtrid & ECID ``` 164313.151.sic-tst-tmsm1!ARTIMPP_UDB.42722.1.0: gtrid x0 ... a0f: ECID <000001833^5pVl3iY00f003UF^>: TRACE:at ^host ^prog lprog> ^ecid ^text ``` rsyslog-8.2512.0/contrib/imtuxedoulog/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315020766 xustar0030 mtime=1764935885.912005801 30 atime=1764935896.910174263 30 ctime=1764935931.328701271 rsyslog-8.2512.0/contrib/imtuxedoulog/Makefile.in0000664000175000017500000006371615114544315020447 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @OS_AIX_TRUE@am__append_1 = -ma subdir = contrib/imtuxedoulog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) imtuxedoulog_la_DEPENDENCIES = am_imtuxedoulog_la_OBJECTS = imtuxedoulog_la-imtuxedoulog.lo imtuxedoulog_la_OBJECTS = $(am_imtuxedoulog_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imtuxedoulog_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(imtuxedoulog_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imtuxedoulog_la_SOURCES) DIST_SOURCES = $(imtuxedoulog_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imtuxedoulog.la imtuxedoulog_la_SOURCES = imtuxedoulog.c imtuxedoulog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) \ $(RSRT_CFLAGS) $(am__append_1) imtuxedoulog_la_LDFLAGS = -module -avoid-version imtuxedoulog_la_LIBADD = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imtuxedoulog/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imtuxedoulog/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imtuxedoulog.la: $(imtuxedoulog_la_OBJECTS) $(imtuxedoulog_la_DEPENDENCIES) $(EXTRA_imtuxedoulog_la_DEPENDENCIES) $(AM_V_CCLD)$(imtuxedoulog_la_LINK) -rpath $(pkglibdir) $(imtuxedoulog_la_OBJECTS) $(imtuxedoulog_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imtuxedoulog_la-imtuxedoulog.lo: imtuxedoulog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imtuxedoulog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imtuxedoulog_la-imtuxedoulog.lo -MD -MP -MF $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Tpo -c -o imtuxedoulog_la-imtuxedoulog.lo `test -f 'imtuxedoulog.c' || echo '$(srcdir)/'`imtuxedoulog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Tpo $(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imtuxedoulog.c' object='imtuxedoulog_la-imtuxedoulog.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imtuxedoulog_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imtuxedoulog_la-imtuxedoulog.lo `test -f 'imtuxedoulog.c' || echo '$(srcdir)/'`imtuxedoulog.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imtuxedoulog_la-imtuxedoulog.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omczmq0000644000000000000000000000013115114544366015432 xustar0030 mtime=1764935926.640629505 29 atime=1764935930.17368359 30 ctime=1764935926.640629505 rsyslog-8.2512.0/contrib/omczmq/0000775000175000017500000000000015114544366015154 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omczmq/PaxHeaders/README0000644000000000000000000000013215035412264016361 xustar0030 mtime=1752569012.329251042 30 atime=1764931141.219321876 30 ctime=1764935926.638629474 rsyslog-8.2512.0/contrib/omczmq/README0000664000175000017500000000557315035412264016037 0ustar00rgerrgerCZMQ Output Plugin REQUIREMENTS: * libsodium ( https://github.com/jedisct1/libsodium ) * zeromq built with libsodium support ( http://zeromq.org/ ) * czmq ( http://czmq.zeromq.org/ ) EXPLANATION OF OPTIONS Module ------ servercertpath: path to server cert if using CURVE clientcertpath: path to client cert(s) if using CURVE authtype: CURVESERVER, CURVECLIENT (omit for no auth) authenticator: whether to start an authenticator thread Action ------ type: type of action (omczmq for this plugin) endpoints: comma delimited list of zeromq endpoints (see zeromq documentation) socktype: zeromq socket type (currently supports PUSH, PUB, DEALER, RADIO, CLIENT, SCATTER) sendtimeout: timeout in ms before send errors sendhwm: number of messages to store in internal buffer before discarding (defaults to 1000) connecttimeout: connection timeout in ms(requires libzmq 4.2 or higher) heartbeativl: time in ms between sending heartbeat PING messages (requires libzmq 4.2 or higher) heartbeattimeout: time in milliseconds to wait for a PING response before disconnect(libzmq 4.2 or higher) heartbeatttl: time remote peer should wait between PINGs before disconnect (libzmq 4.2 or higher) topicframe: "on" to send topic as separate frame if PUB socket topics: comma delimited list of topics or templates to make topics from if PUB or RADIO socket dynatopic: if "on" topics list is treated as list of template names template: template to use for message (defaults to RSYSLOG_ForwardFormat) EXAMPLE CONFIGURATION This configuration sets up an omczmq endpoint as a ZMQ_PUB socket with CURVE authentication. Clients whose certificates are in the '/etc/curve.d/allowed_clients/' directory will be allowed to connect. Each message is published on two topics ( "hostname.programname" and "programname.hostname" ) which are constructed from properties of the log message. For instance, a log from sshd from host.example.com will be published on two topics: * host.example.com.sshd * sshd.host.example.com In this configuration, the output is configured to send each message as a two frame message, with the topic in the first flame and the rsyslog message in the second. ------------------------------------------------------------------------------- module( load="omczmq" servercertpath="/etc/curve.d/example_server" clientcertpath="/etc/curve.d/allowed_clients" authtype="CURVESERVER" authenticator="on" ) template(name="host_program_topic" type="list") { property(name="hostname") constant(value=".") property(name="programname") } template(name="program_host_topic" type="list") { property(name="programname") constant(value=".") property(name="hostname") } action( name="to_zeromq" type="omczmq" socktype="PUB" endpoints="@tcp://*:31338" topics="host_program_topic,program_host_topic" dynatopic="on" topicframe="on" ) ------------------------------------------------------------------------------- rsyslog-8.2512.0/contrib/omczmq/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017535 xustar0030 mtime=1752569012.329251042 30 atime=1764930928.847816172 30 ctime=1764935926.633629397 rsyslog-8.2512.0/contrib/omczmq/Makefile.am0000664000175000017500000000033715035412264017204 0ustar00rgerrgerpkglib_LTLIBRARIES = omczmq.la omczmq_la_SOURCES = omczmq.c omczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) omczmq_la_LDFLAGS = -module -avoid-version omczmq_la_LIBADD = $(CZMQ_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/omczmq/PaxHeaders/omczmq.c0000644000000000000000000000013115055605325017156 xustar0029 mtime=1756826325.61380014 30 atime=1764931141.227322005 30 ctime=1764935926.640629505 rsyslog-8.2512.0/contrib/omczmq/omczmq.c0000664000175000017500000005442315055605325016633 0ustar00rgerrger/** * @file omczmq.c * @brief Output module for sending messages over ZeroMQ. * * This module uses the CZMQ high-level API to create and manage ZeroMQ * sockets. Messages are formatted using rsyslog templates and published * according to the configured socket type and topic list, which may be * static or generated dynamically from templates. CURVE * authentication and heartbeat settings are supported when available. * * Copyright (C) 2016 Brian Knox * Copyright (C) 2014 Rainer Gerhards * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omczmq") DEF_OMOD_STATIC_DATA; static pthread_mutex_t mutDoAct = PTHREAD_MUTEX_INITIALIZER; static struct cnfparamdescr modpdescr[] = {{"authenticator", eCmdHdlrBinary, 0}, {"authtype", eCmdHdlrGetWord, 0}, {"clientcertpath", eCmdHdlrGetWord, 0}, {"servercertpath", eCmdHdlrGetWord, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; struct modConfData_s { rsconf_t *pConf; uchar *tplName; int authenticator; char *authType; char *serverCertPath; char *clientCertPath; }; static modConfData_t *runModConf = NULL; static zactor_t *authActor; typedef struct _instanceData { zsock_t *sock; bool serverish; int sendTimeout; zlist_t *topics; bool sendError; char *sockEndpoints; int sockType; int sendHWM; #if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MINOR >= 2) int heartbeatIvl; int heartbeatTimeout; int heartbeatTTL; int connectTimeout; #endif uchar *tplName; sbool topicFrame; sbool dynaTopic; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; static struct cnfparamdescr actpdescr[] = { {"endpoints", eCmdHdlrGetWord, 1}, {"socktype", eCmdHdlrGetWord, 1}, {"sendhwm", eCmdHdlrGetWord, 0}, #if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MINOR >= 2) {"heartbeatttl", eCmdHdlrGetWord, 0}, {"heartbeativl", eCmdHdlrGetWord, 0}, {"heartbeattimeout", eCmdHdlrGetWord, 0}, {"connecttimeout", eCmdHdlrGetWord, 0}, #endif {"sendtimeout", eCmdHdlrGetWord, 0}, {"template", eCmdHdlrGetWord, 0}, {"topics", eCmdHdlrGetWord, 0}, {"topicframe", eCmdHdlrGetWord, 0}, {"dynatopic", eCmdHdlrBinary, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /** * @brief Initialize the CZMQ socket for an action instance. * * Creates the socket of the configured type, applies optional CURVE * authentication and heartbeat parameters and attaches it to the * configured endpoints. The @a serverish flag is set according to * the socket type to control how CZMQ connects or binds the socket. * * @param pData action instance configuration * @retval RS_RET_OK on success * @retval RS_RET_SUSPENDED on initialization failure */ static rsRetVal initCZMQ(instanceData *pData) { DEFiRet; int rc; putenv((char *)"ZSYS_SIGHANDLER=false"); pData->sock = zsock_new(pData->sockType); if (!pData->sock) { LogError(0, RS_RET_NO_ERRCODE, "omczmq: new socket failed for endpoints: %s", pData->sockEndpoints); ABORT_FINALIZE(RS_RET_SUSPENDED); } zsock_set_sndtimeo(pData->sock, pData->sendTimeout); #if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MINOR >= 2) if (pData->heartbeatIvl > 0 && pData->heartbeatTimeout > 0 && pData->heartbeatTTL > 0) { zsock_set_heartbeat_ivl(pData->sock, pData->heartbeatIvl); zsock_set_heartbeat_timeout(pData->sock, pData->heartbeatTimeout); zsock_set_heartbeat_ttl(pData->sock, pData->heartbeatTTL); } #endif if (runModConf->authType) { if (!strcmp(runModConf->authType, "CURVESERVER")) { zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if (!serverCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } zsock_set_zap_domain(pData->sock, "global"); zsock_set_curve_server(pData->sock, 1); zcert_apply(serverCert, pData->sock); zcert_destroy(&serverCert); } else if (!strcmp(runModConf->authType, "CURVECLIENT")) { zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if (!serverCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } const char *server_key = zcert_public_txt(serverCert); zcert_destroy(&serverCert); zsock_set_curve_serverkey(pData->sock, server_key); zcert_t *clientCert = zcert_load(runModConf->clientCertPath); if (!clientCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->clientCertPath); ABORT_FINALIZE(RS_RET_ERR); } zcert_apply(clientCert, pData->sock); zcert_destroy(&clientCert); } } switch (pData->sockType) { case ZMQ_PUB: #if defined(ZMQ_RADIO) case ZMQ_RADIO: #endif pData->serverish = true; break; case ZMQ_PUSH: #if defined(ZMQ_SCATTER) case ZMQ_SCATTER: #endif case ZMQ_DEALER: #if defined(ZMQ_CLIENT) case ZMQ_CLIENT: #endif pData->serverish = false; break; default: break; } rc = zsock_attach(pData->sock, pData->sockEndpoints, pData->serverish); if (rc == -1) { LogError(0, NO_ERRCODE, "zsock_attach to %s failed", pData->sockEndpoints); ABORT_FINALIZE(RS_RET_SUSPENDED); } finalize_it: RETiRet; } /** * @brief Send a formatted message through the configured CZMQ socket. * * For PUB or RADIO sockets a list of topics can be configured. Each * topic triggers a send operation. When @c topicFrame is true on PUB * sockets, the topic is transmitted in a separate frame, otherwise it * is prepended to the message. RADIO sockets instead set the frame's * group name to the topic. When @c dynaTopic is enabled, template * results beyond index @c 0 provide the topic strings. Other socket * types simply transmit the message stored in @c ppString[0]. * * @param ppString array of template results; message text is in * @c ppString[0] and additional elements may hold topics * @param pData action instance data * @retval RS_RET_OK on success * @retval RS_RET_SUSPENDED if transmission fails */ static rsRetVal outputCZMQ(uchar **ppString, instanceData *pData) { DEFiRet; if (NULL == pData->sock) { CHKiRet(initCZMQ(pData)); } /* if we are using a PUB (or RADIO) socket and we have a topic list then we * need some special care and attention */ #if defined(ZMQ_RADIO) DBGPRINTF("omczmq: ZMQ_RADIO is defined...\n"); if ((pData->sockType == ZMQ_PUB || pData->sockType == ZMQ_RADIO) && pData->topics) { #else DBGPRINTF("omczmq: ZMQ_RADIO is NOT defined...\n"); if (pData->sockType == ZMQ_PUB && pData->topics) { #endif int templateIndex = 1; const char *topic = (const char *)zlist_first(pData->topics); while (topic) { int rc; /* if dynaTopic is true, the topic is constructed by rsyslog * by applying the supplied template to the message properties */ if (pData->dynaTopic) topic = (const char *)ppString[templateIndex]; if (pData->sockType == ZMQ_PUB) { /* if topicFrame is true, send the topic as a separate zmq frame */ if (pData->topicFrame) { rc = zstr_sendx(pData->sock, topic, (char *)ppString[0], NULL); } /* if topicFrame is false, concatenate the topic with the * message in the same frame */ else { rc = zstr_sendf(pData->sock, "%s%s", topic, (char *)ppString[0]); } /* if we have a send error notify rsyslog */ if (rc != 0) { pData->sendError = true; ABORT_FINALIZE(RS_RET_SUSPENDED); } } #if defined(ZMQ_RADIO) else if (pData->sockType == ZMQ_RADIO) { DBGPRINTF("omczmq: sending on RADIO socket...\n"); zframe_t *frame = zframe_from((char *)ppString[0]); if (!frame) { DBGPRINTF("omczmq: failed to create frame...\n"); pData->sendError = true; ABORT_FINALIZE(RS_RET_SUSPENDED); } rc = zframe_set_group(frame, topic); if (rc != 0) { DBGPRINTF("omczmq: failed to set group '%d'...\n", rc); pData->sendError = true; ABORT_FINALIZE(RS_RET_SUSPENDED); } DBGPRINTF("omczmq: set RADIO group to '%s'\n", topic); rc = zframe_send(&frame, pData->sock, 0); if (rc != 0) { pData->sendError = true; ABORT_FINALIZE(RS_RET_SUSPENDED); } } #endif /* get the next topic from the list, and increment * our topic index */ topic = zlist_next(pData->topics); templateIndex++; } } /* we aren't a PUB socket and we don't have a topic list - this means * we can just send the message using the rsyslog template */ else { int rc = zstr_send(pData->sock, (char *)ppString[0]); if (rc != 0) { pData->sendError = true; DBGPRINTF("omczmq: send error: %d", rc); ABORT_FINALIZE(RS_RET_SUSPENDED); } } finalize_it: RETiRet; } static inline void setInstParamDefaults(instanceData *pData) { pData->sockEndpoints = NULL; pData->sock = NULL; pData->sendError = false; pData->serverish = false; pData->tplName = NULL; pData->sockType = -1; pData->sendTimeout = -1; pData->topics = NULL; pData->topicFrame = false; #if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MINOR >= 2) pData->heartbeatIvl = 0; pData->heartbeatTimeout = 0; pData->heartbeatTTL = 0; #endif } BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) { iRet = RS_RET_OK; } ENDisCompatibleWithFeature BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINfreeInstance CODESTARTfreeInstance; zlist_destroy(&pData->topics); zsock_destroy(&pData->sock); free(pData->sockEndpoints); free(pData->tplName); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINtryResume instanceData *pData; CODESTARTtryResume; pthread_mutex_lock(&mutDoAct); pData = pWrkrData->pData; DBGPRINTF("omczmq: trying to resume...\n"); zsock_destroy(&pData->sock); iRet = initCZMQ(pData); pthread_mutex_unlock(&mutDoAct); ENDtryResume BEGINbeginCnfLoad CODESTARTbeginCnfLoad; runModConf = pModConf; runModConf->pConf = pConf; runModConf->authenticator = 0; runModConf->authType = NULL; runModConf->serverCertPath = NULL; runModConf->clientCertPath = NULL; ENDbeginCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; if (runModConf->authenticator == 1) { if (!authActor) { DBGPRINTF("omczmq: starting authActor\n"); authActor = zactor_new(zauth, NULL); if (!strcmp(runModConf->clientCertPath, "*")) { zstr_sendx(authActor, "CURVE", CURVE_ALLOW_ANY, NULL); } else { zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); } zsock_wait(authActor); } } ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free(pModConf->tplName); free(pModConf->authType); free(pModConf->serverCertPath); free(pModConf->clientCertPath); DBGPRINTF("omczmq: stopping authActor\n"); zactor_destroy(&authActor); ENDfreeCnf BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { DBGPRINTF("omczmq: pvals[i].bUSed continuing\n"); continue; } if (!strcmp(modpblk.descr[i].name, "authenticator")) { runModConf->authenticator = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "authtype")) { runModConf->authType = es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: authtype set to %s\n", runModConf->authType); } else if (!strcmp(modpblk.descr[i].name, "servercertpath")) { runModConf->serverCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: serverCertPath set to %s\n", runModConf->serverCertPath); } else if (!strcmp(modpblk.descr[i].name, "clientcertpath")) { runModConf->clientCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: clientCertPath set to %s\n", runModConf->clientCertPath); } else { LogError(0, RS_RET_INVALID_PARAMS, "omczmq: config error, unknown " "param %s in setModCnf\n", modpblk.descr[i].name); } } DBGPRINTF("omczmq: authenticator set to %d\n", runModConf->authenticator); DBGPRINTF("omczmq: authType set to %s\n", runModConf->authType); DBGPRINTF("omczmq: serverCertPath set to %s\n", runModConf->serverCertPath); DBGPRINTF("omczmq: clientCertPath set to %s\n", runModConf->clientCertPath); finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; runModConf = NULL; ENDendCnfLoad BEGINdoAction instanceData *pData; CODESTARTdoAction; pthread_mutex_lock(&mutDoAct); pData = pWrkrData->pData; iRet = outputCZMQ(ppString, pData); pthread_mutex_unlock(&mutDoAct); ENDdoAction BEGINnewActInst struct cnfparamvals *pvals; int i; int iNumTpls; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } if (!strcmp(actpblk.descr[i].name, "endpoints")) { pData->sockEndpoints = es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: sockEndPoints set to '%s'\n", pData->sockEndpoints); } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: template set to '%s'\n", pData->tplName); } else if (!strcmp(actpblk.descr[i].name, "dynatopic")) { pData->dynaTopic = pvals[i].val.d.n; DBGPRINTF("omczmq: dynaTopic set to %s\n", pData->dynaTopic ? "true" : "false"); } else if (!strcmp(actpblk.descr[i].name, "sendtimeout")) { pData->sendTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); DBGPRINTF("omczmq: sendTimeout set to %d\n", pData->sendTimeout); } else if (!strcmp(actpblk.descr[i].name, "sendhwm")) { pData->sendTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); DBGPRINTF("omczmq: sendHWM set to %d\n", pData->sendHWM); } #if (CZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MAJOR >= 4 && ZMQ_VERSION_MINOR >= 2) else if (!strcmp(actpblk.descr[i].name, "heartbeativl")) { pData->heartbeatIvl = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); DBGPRINTF("omczmq: heartbeatbeatIvl set to %d\n", pData->heartbeatIvl); } else if (!strcmp(actpblk.descr[i].name, "heartbeattimeout")) { pData->heartbeatTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); DBGPRINTF("omczmq: heartbeatTimeout set to %d\n", pData->heartbeatTimeout); } else if (!strcmp(actpblk.descr[i].name, "heartbeatttl")) { pData->heartbeatTimeout = atoi(es_str2cstr(pvals[i].val.d.estr, NULL)); DBGPRINTF("omczmq: heartbeatTTL set to %d\n", pData->heartbeatTTL); } #endif else if (!strcmp(actpblk.descr[i].name, "socktype")) { char *stringType = es_str2cstr(pvals[i].val.d.estr, NULL); if (stringType != NULL) { if (!strcmp("PUB", stringType)) { pData->sockType = ZMQ_PUB; DBGPRINTF("omczmq: sockType set to ZMQ_PUB\n"); } #if defined(ZMQ_RADIO) else if (!strcmp("RADIO", stringType)) { pData->sockType = ZMQ_RADIO; DBGPRINTF("omczmq: sockType set to ZMQ_RADIO\n"); } #endif else if (!strcmp("PUSH", stringType)) { pData->sockType = ZMQ_PUSH; DBGPRINTF("omczmq: sockType set to ZMQ_PUSH\n"); } #if defined(ZMQ_SCATTER) else if (!strcmp("SCATTER", stringType)) { pData->sockType = ZMQ_SCATTER; DBGPRINTF("omczmq: sockType set to ZMQ_SCATTER\n"); } #endif else if (!strcmp("DEALER", stringType)) { pData->sockType = ZMQ_DEALER; DBGPRINTF("omczmq: sockType set to ZMQ_DEALER\n"); } #if defined(ZMQ_CLIENT) else if (!strcmp("CLIENT", stringType)) { pData->sockType = ZMQ_CLIENT; DBGPRINTF("omczmq: sockType set to ZMQ_CLIENT\n"); } #endif free(stringType); } else { LogError(0, RS_RET_OUT_OF_MEMORY, "omczmq: out of memory"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } } else if (!strcmp(actpblk.descr[i].name, "topicframe")) { pData->topicFrame = pvals[i].val.d.n; DBGPRINTF("omczmq: topicFrame set to %s\n", pData->topicFrame ? "true" : "false"); } else if (!strcmp(actpblk.descr[i].name, "topics")) { pData->topics = zlist_new(); char *topics = es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("omczmq: topics set to %s\n", topics); char *topics_org = topics; char topic[256]; if (topics == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "out of memory"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } while (*topics) { char *delimiter = strchr(topics, ','); if (!delimiter) { delimiter = topics + strlen(topics); } memcpy(topic, topics, delimiter - topics); topic[delimiter - topics] = 0; char *current_topic = strdup(topic); zlist_append(pData->topics, current_topic); if (*delimiter == 0) { break; } topics = delimiter + 1; } free(topics_org); } else { LogError(0, NO_ERRCODE, "omczmq: config error - '%s' is not a valid option", actpblk.descr[i].name); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } iNumTpls = 1; if (pData->dynaTopic) { iNumTpls = zlist_size(pData->topics) + iNumTpls; } CODE_STD_STRING_REQUESTnewActInst(iNumTpls); if (pData->tplName == NULL) { CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)strdup("RSYSLOG_ForwardFormat"), OMSR_NO_RQD_TPL_OPTS)); } else { CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)pData->tplName, OMSR_NO_RQD_TPL_OPTS)); } i = 1; if (pData->dynaTopic) { char *topic = zlist_first(pData->topics); while (topic) { CHKiRet(OMSRsetEntry(*ppOMSR, i, (uchar *)strdup(topic), OMSR_NO_RQD_TPL_OPTS)); i++; topic = zlist_next(pData->topics); } } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINinitConfVars CODESTARTinitConfVars; ENDinitConfVars NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); DBGPRINTF("omczmq: module compiled with rsyslog version %s.\n", VERSION); INITLegCnfVars; ENDmodInit rsyslog-8.2512.0/contrib/omczmq/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316017550 xustar0030 mtime=1764935886.171009768 30 atime=1764935896.512168168 30 ctime=1764935926.636629443 rsyslog-8.2512.0/contrib/omczmq/Makefile.in0000664000175000017500000006317215114544316017225 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omczmq ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omczmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_omczmq_la_OBJECTS = omczmq_la-omczmq.lo omczmq_la_OBJECTS = $(am_omczmq_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omczmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omczmq_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omczmq_la-omczmq.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omczmq_la_SOURCES) DIST_SOURCES = $(omczmq_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omczmq.la omczmq_la_SOURCES = omczmq.c omczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) omczmq_la_LDFLAGS = -module -avoid-version omczmq_la_LIBADD = $(CZMQ_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omczmq/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omczmq/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omczmq.la: $(omczmq_la_OBJECTS) $(omczmq_la_DEPENDENCIES) $(EXTRA_omczmq_la_DEPENDENCIES) $(AM_V_CCLD)$(omczmq_la_LINK) -rpath $(pkglibdir) $(omczmq_la_OBJECTS) $(omczmq_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omczmq_la-omczmq.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omczmq_la-omczmq.lo: omczmq.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omczmq_la-omczmq.lo -MD -MP -MF $(DEPDIR)/omczmq_la-omczmq.Tpo -c -o omczmq_la-omczmq.lo `test -f 'omczmq.c' || echo '$(srcdir)/'`omczmq.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omczmq_la-omczmq.Tpo $(DEPDIR)/omczmq_la-omczmq.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omczmq.c' object='omczmq_la-omczmq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omczmq_la-omczmq.lo `test -f 'omczmq.c' || echo '$(srcdir)/'`omczmq.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omczmq_la-omczmq.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omczmq_la-omczmq.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omrabbitmq0000644000000000000000000000013115114544366016261 xustar0030 mtime=1764935926.727630836 29 atime=1764935930.17368359 30 ctime=1764935926.727630836 rsyslog-8.2512.0/contrib/omrabbitmq/0000775000175000017500000000000015114544366016003 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omrabbitmq/PaxHeaders/omrabbitmq.c0000644000000000000000000000013215055605325020635 xustar0030 mtime=1756826325.614800155 30 atime=1764931062.027035598 30 ctime=1764935926.727630836 rsyslog-8.2512.0/contrib/omrabbitmq/omrabbitmq.c0000664000175000017500000014537415055605325020317 0ustar00rgerrger/* omrabbitmq.c * * This output plugin enables rsyslog to send messages to the RabbitMQ. * * Copyright 2012-2013 Vaclav Tomec * Copyright 2014 Rainer Gerhards * Copyright 2022 Hamid Maadani * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . * * Author: Vaclav Tomec * * * TLS & AMQP heartbeat support added by: * Hamid Maadani * * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "debug.h" #include "datetime.h" #include "rsconf.h" #include #include "amqp.h" #include "amqp_framing.h" #include "amqp_tcp_socket.h" #include "amqp_ssl_socket.h" #if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 4) #error "rabbitmq-c version must be >= 0.4.0" #endif #define RABBITMQ_CHANNEL 1 MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omrabbitmq") /* * internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) static int instance_counter = 0; static int mode_test = 0; typedef struct { char *host; /* rabbitmq server fqdn or IP */ int port; /* rabbitmq server port */ } server_t; typedef struct { server_t s; /* rabbitmq server */ int failures; /* rabbitmq server failures */ } server_wrk_t; typedef struct { time_t return_check_interval; /* time interval between usual server health checks */ time_t half_return_check_interval; /* for computing */ time_t quick_oscillation_interval; /* time interval below which the service is not stable */ int quick_oscillation_max; /* number of quick oscillation after which the connection is kept on backup */ time_t graceful_interval; /* time interval the connection is kept on backup after which the usual server * check restarts */ int quick_oscillation_count; /* current number of simultaneous quick oscillation detected */ } recover_t; typedef struct _instanceData { /* here you need to define all action-specific data. A record of type * instanceData will be handed over to each instance of the action. Keep * in mind that there may be several invocations of the same type of action * inside rsyslog.conf, and this is what keeps them apart. Do NOT use * static data for this! */ amqp_bytes_t exchange; /* exchange to send message to */ amqp_bytes_t routing_key; /* fixed routing_key to use */ uchar *routing_key_template; /* routing_key template */ int idx_routing_key_template; /* routing_key template index in doAction tab */ sbool populate_properties; /* populates message properties */ int delivery_mode; /* delivery mode transient or persistent message */ amqp_bytes_t expiration; /* message expiration */ uchar *body_template; /* body template */ int idx_body_template; /* body template index in doAction tab */ amqp_basic_properties_t amqp_props_tpl_type; /* */ char *content_type; /* */ amqp_basic_properties_t amqp_props_plaintext; /* */ char *exchange_type; /* */ int durable; /* */ int auto_delete; /* */ int iidx; int nbWrkr; server_t server1; /* first rabbitmq server */ server_t server2; /* second rabbitmq server */ char *vhost; /* rabbitmq server vhost */ char *user; /* rabbitmq username */ char *password; /* rabbitmq username's password */ int ssl; /* should amqp connection be made over TLS? */ int initOpenSSL; /* should rabbitmq-c initialize OpenSSL? */ int verifyPeer; /* should peer be verified for TLS? */ int verifyHostname; /* should hostname be verified for TLS? */ int heartbeat; /* AMQP heartbeat interval in seconds (0 means disabled, which is default) */ char *caCert; /* CA certificate to be used for TLS connection */ recover_t recover_policy; } instanceData; typedef struct wrkrInstanceData { amqp_connection_state_t a_conn; /* amqp connection */ int connected; int channel_opened; pthread_t thread; /* */ short thread_running; /* */ pthread_mutex_t send_mutex; /* */ pthread_cond_t cond; /* */ rsRetVal state; /* state of the connection */ server_wrk_t serverPrefered; /* usual rabbitmq server */ server_wrk_t serverBackup; /* backup rabbitmq server */ server_wrk_t *serverActive; /* active rabbitmq server */ instanceData *pData; recover_t recover_policy; time_t last_failback; int iidx; int widx; int go_on; } wrkrInstanceData_t; typedef struct _msg2amqp_props_ { propid_t id; const char *name; amqp_bytes_t *standardprop; int flag; } msg2amqp_props_t; /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"host", eCmdHdlrString, 0}, {"port", eCmdHdlrInt, 0}, {"virtual_host", eCmdHdlrGetWord, 0}, {"heartbeat_interval", eCmdHdlrNonNegInt, 0}, {"user", eCmdHdlrGetWord, 0}, {"password", eCmdHdlrGetWord, 0}, {"ssl", eCmdHdlrBinary, 0}, {"init_openssl", eCmdHdlrBinary, 0}, {"verify_peer", eCmdHdlrBinary, 0}, {"verify_hostname", eCmdHdlrBinary, 0}, {"ca_cert", eCmdHdlrGetWord, 0}, {"exchange", eCmdHdlrGetWord, 0}, {"routing_key", eCmdHdlrGetWord, 0}, {"routing_key_template", eCmdHdlrGetWord, 0}, {"delivery_mode", eCmdHdlrGetWord, 0}, {"expiration", eCmdHdlrNonNegInt, 0}, {"populate_properties", eCmdHdlrBinary, 0}, {"body_template", eCmdHdlrGetWord, 0}, {"content_type", eCmdHdlrGetWord, 0}, {"recover_policy", eCmdHdlrString, 0}, {"exchange_type", eCmdHdlrGetWord, 0}, {"durable", eCmdHdlrBinary, 0}, {"auto_delete", eCmdHdlrBinary, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; static amqp_bytes_t cstring_bytes(const char *str) { return str ? amqp_cstring_bytes(str) : amqp_empty_bytes; } /* Initialize recover structure from the configuration string */ static void init_recover(recover_t *fb, char *str) { time_t value[4] = {0, 0, 0, 0}; if (str && *str) { int i = -1; do { value[++i] = strtoul(str, &str, 10); if (*str) str++; } while (i < 3 && value[i] && *str); } fb->return_check_interval = (value[0]) ? value[0] : 60; fb->half_return_check_interval = fb->return_check_interval / 2; fb->quick_oscillation_interval = (value[1]) ? value[1] : (fb->return_check_interval / 10); fb->quick_oscillation_max = (value[2]) ? (int)(value[2]) : 3; fb->graceful_interval = (value[3]) ? value[3] : (fb->return_check_interval * 10) - fb->half_return_check_interval; fb->quick_oscillation_count = 0; } /* this method compute the delay before next reconnection attempt according */ static unsigned long next_check(recover_t *fb, time_t last_failback) { time_t now = time(NULL); srandom(now); if (now - last_failback < fb->quick_oscillation_interval) { /* quick oscillation detected */ fb->quick_oscillation_count++; if (fb->quick_oscillation_count > fb->quick_oscillation_max) { /* too much oscillation inserting a graceful sleep */ fb->quick_oscillation_count = 0; return fb->graceful_interval + fb->return_check_interval * random() / RAND_MAX; } } else fb->quick_oscillation_count = 0; /* returning a standard delay between 0,5 and 1,5 * return_check_interval */ return fb->half_return_check_interval + fb->return_check_interval * random() / RAND_MAX; } /* authenticate to rabbitmq server and set connection parameter according to rsyslog configuration */ static int amqp_authenticate(wrkrInstanceData_t *self, amqp_connection_state_t a_conn) { amqp_rpc_reply_t ret; /* define the frame size */ int frame_size = (glbl.GetMaxLine(runConf) < 130000) ? 131072 : (glbl.GetMaxLine(runConf) + 1072); /* authenticate */ ret = amqp_login(a_conn, (char const *)self->pData->vhost, 1, frame_size, self->pData->heartbeat, AMQP_SASL_METHOD_PLAIN, self->pData->user, self->pData->password); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LogError(0, RS_RET_RABBITMQ_LOGIN_ERR, "omrabbitmq module %d/%d: login to AMQP " "server %s failed. (%d / %s)", self->iidx, self->widx, self->serverActive->s.host, ret.reply_type, amqp_error_string2(ret.library_error)); return 0; } /* open the communication channel */ amqp_channel_open(a_conn, 1); if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) { LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: open channel failed.", self->iidx, self->widx); return 0; } if (self->pData->exchange_type) { /* we declare the exchange according to specifications */ amqp_table_t props = {0, NULL}; #if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 6) amqp_exchange_declare(a_conn, 1, self->pData->exchange, cstring_bytes(self->pData->exchange_type), 0, self->pData->durable, props); #else amqp_exchange_declare(a_conn, 1, self->pData->exchange, cstring_bytes(self->pData->exchange_type), 0, self->pData->durable, self->pData->auto_delete, 0, props); #endif if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) { /* if a problem occurs on declaring the exchange we receive a channel_close with the * error then we can log the error, respond a channel_close_ok and reopen it * so we can work with the existing exchange. */ amqp_channel_close_ok_t chan_cls_ok; amqp_channel_close_t *chan_cls = (amqp_channel_close_t *)amqp_get_rpc_reply(a_conn).reply.decoded; if (amqp_get_rpc_reply(a_conn).reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION) { LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: disconnected while exchange declare (%d)", self->iidx, self->widx, amqp_get_rpc_reply(a_conn).library_error); return 0; } LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: exchange declare failed %.*s.", self->iidx, self->widx, (int)chan_cls->reply_text.len, (char *)chan_cls->reply_text.bytes); chan_cls_ok.dummy = '\0'; amqp_send_method(a_conn, 1, AMQP_CHANNEL_CLOSE_OK_METHOD, &chan_cls_ok); /* reopen the communication channel in case of error it should be close by server*/ amqp_channel_open(a_conn, 1); if (amqp_get_rpc_reply(a_conn).reply_type != AMQP_RESPONSE_NORMAL) { LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: " "open channel failed.", self->iidx, self->widx); return 0; } } } /* release the buffers if possible */ amqp_maybe_release_buffers(a_conn); return 1; } /* This method establish a new connection * @self pointer on the worker datas * @server pointer on the server datas (preferred or backup) * @return the connection state or NULL on error */ static amqp_connection_state_t tryConnection(wrkrInstanceData_t *self, server_t *server) { int retconn = 0; struct timeval delay; delay.tv_sec = 1; delay.tv_usec = 0; amqp_socket_t *sockfd = NULL; amqp_connection_state_t a_conn = amqp_new_connection(); if (a_conn) { if (self->pData->ssl) { if (!self->pData->initOpenSSL) { // prevent OpenSSL double initialization amqp_set_initialize_ssl_library(0); } sockfd = amqp_ssl_socket_new(a_conn); } else { sockfd = amqp_tcp_socket_new(a_conn); } } if (sockfd) { if (self->pData->ssl) { #if (AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR < 8) amqp_ssl_socket_set_verify(sockfd, self->pData->verifyPeer); #else amqp_ssl_socket_set_verify_peer(sockfd, self->pData->verifyPeer); amqp_ssl_socket_set_verify_hostname(sockfd, self->pData->verifyHostname); #endif if (self->pData->caCert) { amqp_ssl_socket_set_cacert(sockfd, self->pData->caCert); } } LogError(0, RS_RET_RABBITMQ_CHANNEL_ERR, "omrabbitmq module %d/%d: server %s port %d.", self->iidx, self->widx, server->host, server->port); #if defined(_AIX) retconn = amqp_socket_open(sockfd, server->host, server->port); #else retconn = amqp_socket_open_noblock(sockfd, (const char *)server->host, server->port, &delay); #endif } if (retconn == AMQP_STATUS_OK && amqp_authenticate(self, a_conn)) return a_conn; /* the connection failed so free it and return NULL */ amqp_connection_close(a_conn, 200); amqp_destroy_connection(a_conn); #if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) if (self->pData->ssl && self->pData->initOpenSSL) { amqp_uninitialize_ssl_library(); } #endif return NULL; } static int manage_connection(wrkrInstanceData_t *self, amqp_frame_t *pFrame) { int result; pthread_mutex_unlock(&self->send_mutex); do { if (self->serverActive == &self->serverBackup) { amqp_connection_state_t new_conn; struct timeval delay; /* The worker is connected to the backup server. * next_check function compute the delay before trying to recover * the connection to the preferred server according to recover_policy */ delay.tv_sec = next_check(&self->recover_policy, self->last_failback); delay.tv_usec = 0; result = amqp_simple_wait_frame_noblock(self->a_conn, pFrame, &delay); /* if connected to backup server then check if usual server is alive. * if so then disconnect from backup */ if (result == AMQP_STATUS_TIMEOUT && (new_conn = tryConnection(self, &(self->serverPrefered.s))) != NULL) { /* connection is re-established to preferred server so * swap connections */ amqp_connection_state_t old_conn = self->a_conn; /* now lock to avoid message publishing. */ pthread_mutex_lock(&self->send_mutex); self->a_conn = new_conn; self->serverActive = &self->serverPrefered; self->serverActive->failures = 0; pthread_mutex_unlock(&self->send_mutex); /* back to unlock mode */ DBGPRINTF("omrabbitmq module %d: reconnects to usual server.\n", self->iidx); amqp_connection_close(old_conn, 200); amqp_destroy_connection(old_conn); #if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) if (self->pData->ssl && self->pData->initOpenSSL) { amqp_uninitialize_ssl_library(); } #endif } } else { result = amqp_simple_wait_frame(self->a_conn, pFrame); } } while (result == AMQP_STATUS_TIMEOUT); /* now lock the mutex to avoid message publishing. */ pthread_mutex_lock(&self->send_mutex); return result; } static void send_connection_close(amqp_connection_state_t state) { amqp_connection_close_t *req = malloc(sizeof(amqp_connection_close_t)); memset(req, 0, sizeof(amqp_connection_close_t)); req->reply_code = 200; req->reply_text.bytes = (void *)"200"; req->reply_text.len = 3; req->class_id = (uint16_t)(AMQP_CONNECTION_CLOSE_METHOD >> 16); req->method_id = (uint16_t)(AMQP_CONNECTION_CLOSE_METHOD & 0xFFFF); amqp_send_method(state, 0, AMQP_CONNECTION_CLOSE_METHOD, req); free(req); } static void send_channel_close(amqp_connection_state_t state, amqp_channel_t ch) { amqp_channel_close_t *req = malloc(sizeof(amqp_channel_close_t)); memset(req, 0, sizeof(amqp_channel_close_t)); req->reply_code = 200; req->reply_text.bytes = (void *)"200"; req->reply_text.len = 3; req->class_id = (uint16_t)(AMQP_CHANNEL_CLOSE_METHOD >> 16); req->method_id = (uint16_t)(AMQP_CHANNEL_CLOSE_METHOD & 0xFFFF); amqp_send_method(state, ch, AMQP_CHANNEL_CLOSE_METHOD, req); free(req); } static void send_connection_close_ok(amqp_connection_state_t state) { amqp_connection_close_ok_t *req = malloc(sizeof(amqp_connection_close_ok_t)); memset(req, 0, sizeof(amqp_connection_close_ok_t)); req->dummy = '\0'; amqp_send_method(state, 0, AMQP_CONNECTION_CLOSE_OK_METHOD, req); free(req); } static void send_channel_close_ok(amqp_connection_state_t state, amqp_channel_t ch) { amqp_channel_close_ok_t *req = malloc(sizeof(amqp_channel_close_ok_t)); memset(req, 0, sizeof(amqp_channel_close_ok_t)); req->dummy = '\0'; amqp_send_method(state, ch, AMQP_CHANNEL_CLOSE_OK_METHOD, req); free(req); } /* run_connection_routine is the thread monitoring of the rabbitmq connection. * This method manage reconnection to preferred and backup servers apply the recover_policy */ static void *run_connection_routine(void *arg) { wrkrInstanceData_t *self = (wrkrInstanceData_t *)arg; amqp_frame_t frm; int result; self->connected = 0; self->channel_opened = 0; rsRetVal state_out = RS_RET_SUSPENDED; dbgSetThrdName((uchar *)"amqp connection"); /* now lock to avoid message publishing during part of the thread loop */ pthread_mutex_lock(&self->send_mutex); self->thread_running = 1; self->state = RS_RET_OK; srSleep(0, 100); DBGPRINTF("omrabbitmq module %d/%d: connection thread started\n", self->iidx, self->widx); int go_on = self->go_on; while (go_on) // this loop is used to reconnect on connection failure { if (self->a_conn != NULL) { amqp_connection_close(self->a_conn, 200); amqp_destroy_connection(self->a_conn); #if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) if (self->pData->ssl && self->pData->initOpenSSL) { amqp_uninitialize_ssl_library(); } #endif } self->a_conn = NULL; if (!self->go_on) { go_on = 0; state_out = RS_RET_DISABLE_ACTION; continue; /* lets go back to wile (go_on) and leave cleanly */ } if (self->serverActive == &self->serverBackup) { self->serverBackup.failures = 0; self->serverPrefered.failures = 0; self->serverActive = &self->serverPrefered; } do { /* this loop tries 3 times per server before switching servers */ if ((self->a_conn = tryConnection(self, &(self->serverActive->s))) != NULL) { self->serverActive->failures = 0; } else { /* set 1 second before retry */ struct timeval delay; delay.tv_sec = 1; delay.tv_usec = 0; self->serverActive->failures++; /* if 3 tries */ if (self->serverActive->failures == 3) { if (!self->serverBackup.s.host || self->serverBackup.failures == 3) { LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module connection " "failed 3 times on each server."); } if (self->serverActive == &self->serverBackup) { self->serverBackup.failures = 0; self->serverPrefered.failures = 0; self->serverActive = &self->serverPrefered; } else { /* on usual server switch to backup server */ if (self->serverBackup.s.host) self->serverActive = &self->serverBackup; else self->serverPrefered.failures = 0; } /* set 5 second before new round trip */ delay.tv_sec = 5; } select(0, NULL, NULL, NULL, &delay); } } while (self->a_conn == NULL && self->go_on); if (!self->go_on) { go_on = 0; state_out = RS_RET_DISABLE_ACTION; continue; /* lets go back to wile (go_on) and leave cleanly */ } /* signal that the thread is started */ pthread_cond_signal(&self->cond); self->connected = 1; self->channel_opened = 1; DBGPRINTF("omrabbitmq module %d: connected.\n", self->iidx); self->state = RS_RET_OK; if (self->serverActive == &self->serverBackup) self->last_failback = time(NULL); while (self->connected) // this loop is used to manage an established connection { result = manage_connection(self, &frm); switch (result) { case AMQP_STATUS_NO_MEMORY: LogError(0, RS_RET_OUT_OF_MEMORY, "omrabbitmq module %d/%d: no memory " ": aborting module.", self->iidx, self->widx); go_on = 0; /* non recoverable error let's go out */ self->connected = 0; state_out = RS_RET_DISABLE_ACTION; break; case AMQP_STATUS_BAD_AMQP_DATA: LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module %d/%d: bad " "data received : reconnect.", self->iidx, self->widx); self->connected = 0; break; case AMQP_STATUS_SOCKET_ERROR: LogError(0, RS_RET_RABBITMQ_CONN_ERR, "omrabbitmq module %d/%d: Socket" " error : reconnect.", self->iidx, self->widx); self->connected = 0; break; case AMQP_STATUS_CONNECTION_CLOSED: LogError(0, RS_RET_OUT_OF_MEMORY, "omrabbitmq module %d/%d: Connection" " closed : reconnect.", self->iidx, self->widx); self->connected = 0; break; case AMQP_STATUS_OK: /* perhaps not a frame type so ignore it */ if (frm.frame_type == AMQP_FRAME_METHOD) { amqp_method_number_t id = frm.payload.method.id; /* now handle frames from the server */ switch (id) { case AMQP_CONNECTION_CLOSE_OK_METHOD: /* We asked to close the connection and server has responded to us */ self->connected = 0; go_on = 0; break; case AMQP_CHANNEL_CLOSE_OK_METHOD: /* We asked to close the channel and server has responded to us */ send_connection_close(self->a_conn); self->channel_opened = 0; break; case AMQP_CHANNEL_CLOSE_METHOD: /* the server wants to close the channel then the connection */ LogMsg(0, RS_RET_OK, LOG_WARNING, "omrabbitmq module %d/%d: " "Close Channel Received (%X).", self->iidx, self->widx, id); /* answer the server request & send the method */ send_channel_close_ok(self->a_conn, frm.channel); self->channel_opened = 0; break; case AMQP_CONNECTION_CLOSE_METHOD: /* the server want to close the connection */ LogMsg(0, RS_RET_OK, LOG_WARNING, "omrabbitmq module %d/%d: " "Close Connection Received (%X).", self->iidx, self->widx, id); /* answer the server request */ send_connection_close_ok(self->a_conn); self->connected = 0; break; default: LogMsg(0, RS_RET_OK, LOG_WARNING, "omrabbitmq module %d/%d: " "Unmanaged amqp method received (%X) : ignored.", self->iidx, self->widx, id); } /* switch (frm.payload.method.id) */ } /* if (frm.frame_type == AMQP_FRAME_METHOD) */ break; default: // No action needed for other cases break; } /* switch (result) */ } } self->state = state_out; /* The core ask to die so let's disconnect */ if (self->a_conn != NULL) { if (self->channel_opened) amqp_channel_close(self->a_conn, 1, 200); if (self->connected) amqp_connection_close(self->a_conn, 200); amqp_destroy_connection(self->a_conn); self->a_conn = NULL; #if ((AMQP_VERSION_MAJOR == 0) && (AMQP_VERSION_MINOR > 8)) || (AMQP_VERSION_MAJOR > 0) if (self->pData->ssl && self->pData->initOpenSSL) { amqp_uninitialize_ssl_library(); } #endif } self->thread_running = 0; /* Finishing by unlocking before the end of the thread */ pthread_mutex_unlock(&self->send_mutex); /* Now notify the worker that this thread is stopping */ pthread_cond_signal(&self->cond); return NULL; } /* ============================================================================================ * Main thread * ============================================================================================ */ static rsRetVal startAMQPConnection(wrkrInstanceData_t *self) { DEFiRet; pthread_mutex_lock(&self->send_mutex); self->go_on = 1; if (self->thread_running == 0) { if (!pthread_create(&self->thread, NULL, run_connection_routine, self)) { pthread_cond_wait(&self->cond, &self->send_mutex); iRet = self->state; } else { iRet = RS_RET_DISABLE_ACTION; } } pthread_mutex_unlock(&self->send_mutex); RETiRet; } static void closeAMQPConnection(wrkrInstanceData_t *self) { if (!self || !self->a_conn) return; void *ret; /* Now locks to allow exclusive access to sock */ pthread_mutex_lock(&self->send_mutex); self->go_on = 0; /* send the method */ if (self->a_conn) { if (self->channel_opened) { send_channel_close(self->a_conn, 0); } else { send_connection_close(self->a_conn); } } /* Release the lock */ pthread_mutex_unlock(&self->send_mutex); /* Now wvait for the thread to stop */ pthread_join(self->thread, &ret); } /* * Report general error */ static int manage_error(int x, char const *context) { int retVal = 0; // false if (x < 0) { #if (AMQP_VERSION_MINOR >= 4) const char *errstr = amqp_error_string2(-x); LogError(0, RS_RET_ERR, "omrabbitmq: %s: %s", context, errstr); #else char *errstr = amqp_error_string(-x); LogError(0, RS_RET_ERR, "omrabbitmq: %s: %s", context, errstr); free(errstr); #endif retVal = 1; // true } return retVal; } static rsRetVal publishRabbitMQ(wrkrInstanceData_t *self, amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_basic_properties_t *p_amqp_props, amqp_bytes_t body_bytes) { DEFiRet; /* locks to allow exclusive access to connection */ if (mode_test > 0) { struct timeval tv; tv.tv_sec = mode_test / 1000; tv.tv_usec = mode_test % 1000 * 1000; select(0, NULL, NULL, NULL, &tv); } pthread_mutex_lock(&self->send_mutex); if (self->state != RS_RET_OK) ABORT_FINALIZE(self->state); if (!self->a_conn) { ABORT_FINALIZE(RS_RET_RABBITMQ_CONN_ERR); } if (manage_error(amqp_basic_publish(self->a_conn, 1, exchange, routing_key, 0, 0, p_amqp_props, body_bytes), "amqp_basic_publish")) { /* error already notified */ FINALIZE; } finalize_it: /* release exclusive access to connection */ pthread_mutex_unlock(&self->send_mutex); RETiRet; } BEGINdoAction int iLen; CODESTARTdoAction; /* The first element is a smsg_t pointer */ smsg_t **pMsg = (smsg_t **)pMsgData; smsg_t *msg = pMsg[0]; amqp_bytes_t body_bytes; amqp_basic_properties_t *amqp_props_msg; if (!pWrkrData->pData->idx_body_template) { /* No body template so send it as rawmsg */ getRawMsg(msg, (uchar **)(&body_bytes.bytes), &iLen); body_bytes.len = (size_t)iLen; amqp_props_msg = &pWrkrData->pData->amqp_props_plaintext; } else { /* we have a body template */ body_bytes = cstring_bytes((char *)ppString[pWrkrData->pData->idx_body_template]); amqp_props_msg = &pWrkrData->pData->amqp_props_tpl_type; } if (pWrkrData->pData->populate_properties) { /* populate amqp message properties */ msgPropDescr_t pProp; int i, custom = 0; amqp_basic_properties_t amqp_props; memcpy(&amqp_props, amqp_props_msg, sizeof(amqp_basic_properties_t)); /* list and mapping of smsg to amqp properties */ msg2amqp_props_t prop_list[] = {{PROP_SYSLOGFACILITY_TEXT, "facility", NULL, 0}, {PROP_SYSLOGSEVERITY_TEXT, "severity", NULL, 0}, {PROP_HOSTNAME, "hostname", NULL, 0}, {PROP_FROMHOST, "fromhost", NULL, 0}, {PROP_SYSLOGTAG, NULL, &(amqp_props.app_id), AMQP_BASIC_APP_ID_FLAG}}; int len = sizeof(prop_list) / sizeof(msg2amqp_props_t); uchar *val[sizeof(prop_list) / sizeof(msg2amqp_props_t)]; rs_size_t valLen[sizeof(prop_list) / sizeof(msg2amqp_props_t)]; unsigned short mustBeFreed[sizeof(prop_list) / sizeof(msg2amqp_props_t)]; struct amqp_table_entry_t_ tab_entries[sizeof(prop_list) / sizeof(msg2amqp_props_t)]; amqp_props.headers.entries = tab_entries; amqp_props.timestamp = (uint64_t)datetime.syslogTime2time_t(&msg->tTIMESTAMP); amqp_props._flags |= AMQP_BASIC_TIMESTAMP_FLAG; for (i = 0; i < len; i++) { /* for each msg property in list get the value and initialize flags */ pProp.id = prop_list[i].id; valLen[i] = 0; mustBeFreed[i] = 0; val[i] = (uchar *)MsgGetProp(msg, NULL, &pProp, &(valLen[i]), &(mustBeFreed[i]), NULL); if (val[i] && *val[i]) { if (prop_list[i].name) { /* custom amqp properties */ tab_entries[custom].key = amqp_cstring_bytes(prop_list[i].name); tab_entries[custom].value.kind = AMQP_FIELD_KIND_UTF8; tab_entries[custom].value.value.bytes = amqp_cstring_bytes((char *)val[i]); amqp_props._flags |= AMQP_BASIC_HEADERS_FLAG; custom++; } else { /* standard amqp properties*/ prop_list[i].standardprop->bytes = val[i]; prop_list[i].standardprop->len = (size_t)valLen[i]; amqp_props._flags |= prop_list[i].flag; } } } amqp_props.headers.num_entries = custom; /* CHKiRet could not be used because we need to release allocations */ iRet = publishRabbitMQ(pWrkrData, pWrkrData->pData->exchange, (pWrkrData->pData->routing_key_template) ? cstring_bytes((char *)ppString[pWrkrData->pData->idx_routing_key_template]) : pWrkrData->pData->routing_key, &amqp_props, body_bytes); for (i = 0; i < len; i++) if (mustBeFreed[i]) free(val[i]); } else { /* As CHKiRet could not be used earlier, iRet is directly used again */ iRet = publishRabbitMQ(pWrkrData, pWrkrData->pData->exchange, (pWrkrData->pData->routing_key_template) ? cstring_bytes((char *)ppString[pWrkrData->pData->idx_routing_key_template]) : pWrkrData->pData->routing_key, amqp_props_msg, body_bytes); } ENDdoAction BEGINtryResume CODESTARTtryResume; iRet = startAMQPConnection(pWrkrData); ENDtryResume BEGINcreateInstance void *env_var; CODESTARTcreateInstance; if ((env_var = getenv("OMRABBITMQ_TEST")) != NULL) mode_test = atoi(env_var); memset(pData, 0, sizeof(instanceData)); pData->iidx = ++instance_counter; pData->delivery_mode = 2; pData->exchange_type = NULL; pData->durable = 0; pData->auto_delete = 1; pData->ssl = 0; pData->initOpenSSL = 0; pData->verifyPeer = 0; pData->verifyHostname = 0; pData->caCert = NULL; pData->heartbeat = 0; ENDcreateInstance BEGINfreeInstance CODESTARTfreeInstance; /* this is a cleanup callback. All dynamically-allocated resources * in instance data must be cleaned up here. Prime examples are * malloc()ed memory, file & database handles and the like. */ if (pData->exchange.bytes) free(pData->exchange.bytes); if (pData->routing_key.bytes) free(pData->routing_key.bytes); if (pData->routing_key_template) free(pData->routing_key_template); if (pData->body_template) free(pData->body_template); if (pData->expiration.bytes) free(pData->expiration.bytes); if (pData->content_type) free(pData->content_type); if (pData->vhost) free(pData->vhost); if (pData->user) free(pData->user); if (pData->password) free(pData->password); if (pData->exchange_type) free(pData->exchange_type); if (pData->server1.host) free(pData->server1.host); if (pData->caCert) free(pData->caCert); ENDfreeInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; /* use this to specify if select features are supported by this * plugin. If not, the framework will handle that. Currently, only * RepeatedMsgReduction ("last message repeated n times") is optional. */ if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; /* permits to spit out some debug info */ dbgprintf("omrabbitmq instance : %d\n", pData->iidx); if (pData->server2.host) { dbgprintf("\thost1='%s' \n", pData->server1.host); dbgprintf("\tport1=%d\n", pData->server1.port); dbgprintf("\thost2='%s' \n", pData->server2.host); dbgprintf("\tport2=%d\n", pData->server2.port); dbgprintf("\tfailback policy :"); dbgprintf("\t\tusual server check interval=%ld s", pData->recover_policy.return_check_interval); dbgprintf("\t\tquick oscillation limit=%ld s", pData->recover_policy.quick_oscillation_interval); dbgprintf("\t\tmax number of oscillation=%d s", pData->recover_policy.quick_oscillation_max); dbgprintf("\t\tgraceful interval after quick oscillation detection=%ld s", pData->recover_policy.graceful_interval); } else { dbgprintf("\thost='%s' \n", pData->server1.host); dbgprintf("\tport=%d\n", pData->server1.port); } dbgprintf("\tvirtual_host='%s'\n", pData->vhost); dbgprintf("\tuser='%s'\n", pData->user == NULL ? "(not configured)" : pData->user); dbgprintf("\tpassword=(%sconfigured)\n", pData->password == NULL ? "not " : ""); dbgprintf("\tssl=%d\n", pData->ssl); dbgprintf("\tinit_openssl=%d\n", pData->initOpenSSL); dbgprintf("\tverify_peer=%d\n", pData->verifyPeer); dbgprintf("\tverify_hostname=%d\n", pData->verifyHostname); dbgprintf("\tca_cert='%s'\n", pData->caCert); dbgprintf("\theartbeat_interval=%d\n", pData->heartbeat); dbgprintf("\texchange='%*s'\n", (int)pData->exchange.len, (char *)pData->exchange.bytes); dbgprintf("\trouting_key='%*s'\n", (int)pData->routing_key.len, (char *)pData->routing_key.bytes); dbgprintf("\trouting_key_template='%s'\n", pData->routing_key_template); dbgprintf("\tbody_template='%s'\n", pData->body_template); dbgprintf("\texchange_type='%s'\n", pData->exchange_type); dbgprintf("\tauto_delete=%d\n", pData->auto_delete); dbgprintf("\tdurable=%d\n", pData->durable); dbgprintf("\tpopulate_properties=%s\n", (pData->populate_properties) ? "ON" : "OFF"); dbgprintf((pData->delivery_mode == 1) ? "\tdelivery_mode=TRANSIENT\n" : "\tdelivery_mode=PERSISTENT\n"); if (pData->expiration.len == 0) { dbgprintf("\texpiration=UNLIMITED\n"); } else { dbgprintf("\texpiration=%*s\n", (int)pData->expiration.len, (char *)pData->expiration.bytes); } ENDdbgPrintInstInfo BEGINnewActInst struct cnfparamvals *pvals; int i; char *host = NULL, *vhost = NULL, *user = NULL, *password = NULL, *recover = NULL; int port = 0; long long expiration = 0; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); /* let read parameters */ for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "host")) { host = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "recover_policy")) { recover = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "port")) { port = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "virtual_host")) { vhost = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "user")) { user = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "password")) { password = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "ssl")) { pData->ssl = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ca_cert")) { pData->caCert = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "heartbeat_interval")) { pData->heartbeat = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "init_openssl")) { pData->initOpenSSL = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "verify_peer")) { pData->verifyPeer = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "verify_hostname")) { pData->verifyHostname = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "exchange")) { pData->exchange = cstring_bytes(es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(actpblk.descr[i].name, "routing_key")) { pData->routing_key = cstring_bytes(es_str2cstr(pvals[i].val.d.estr, NULL)); } else if (!strcmp(actpblk.descr[i].name, "routing_key_template")) { pData->routing_key_template = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "populate_properties")) { pData->populate_properties = (sbool)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "delivery_mode")) { char *temp = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); if (temp) { if (!strcasecmp(temp, "TRANSIENT") || !strcmp(temp, "1")) { pData->delivery_mode = 1; } else { if (!strcasecmp(temp, "PERSISTENT") || !strcmp(temp, "2")) { pData->delivery_mode = 2; } else { pData->delivery_mode = 0; } } free(temp); } } else if (!strcmp(actpblk.descr[i].name, "expiration")) { expiration = pvals[i].val.d.n; if (expiration > 0) { char buf[40]; snprintf(buf, 40, "%lld", expiration); #ifndef __clang_analyzer__ pData->expiration = cstring_bytes(strdup(buf)); #endif } } else if (!strcmp(actpblk.descr[i].name, "body_template")) { pData->body_template = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "content_type")) { pData->content_type = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "exchange_type")) { pData->exchange_type = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "auto_delete")) { pData->auto_delete = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "durable")) { pData->durable = (int)pvals[i].val.d.n; } else { LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d: program error, non-handled param '%s'\n", pData->iidx, actpblk.descr[i].name); } } /* let's check config validity */ if (host == NULL) { LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: parameter " "host must be specified", pData->iidx); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* first if a template for routing_key is set let verify its existence */ if (pData->routing_key_template && tplFind(ourConf, (char *)pData->routing_key_template, strlen((char *)pData->routing_key_template)) == NULL) { LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d : template '%s'" " used for routing key does not exist !", pData->iidx, pData->routing_key_template); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* an exchange must be defined */ if (pData->exchange.bytes == NULL) { LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: parameter " "exchange must be specified", pData->iidx); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* a static or a template's routing_key must be defined */ if (pData->routing_key.bytes == NULL && pData->routing_key_template == NULL) { LogError(0, RS_RET_INVALID_PARAMS, "omrabbitmq module %d disabled: " "one of parameters routing_key or " "routing_key_template must be specified", pData->iidx); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* a valid delivery mode must be defined : a 0 means that an invalid value * has been done */ if (!pData->delivery_mode) { LogError(0, RS_RET_CONF_PARAM_INVLD, "omrabbitmq module %d disabled: " "parameter delivery_mode must be " "TRANSIENT or PERSISTENT (default)", pData->iidx); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* first if a template for message body is set let verify its existence */ if (pData->body_template && *pData->body_template && tplFind(ourConf, (char *)pData->body_template, strlen((char *)pData->body_template)) == NULL) { LogError(0, RS_RET_CONF_PARAM_INVLD, "omrabbitmq module %d : template '%s'" " used for body does not exist !", pData->iidx, pData->body_template); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* Let's define the size of the doAction tab */ CODE_STD_STRING_REQUESTnewActInst(1 + ((pData->routing_key_template) ? 1 : 0) + ((pData->body_template && *pData->body_template == '\0') ? 0 : 1)); /* Set the plain text message props */ memset(&pData->amqp_props_plaintext, 0, sizeof(amqp_basic_properties_t)); pData->amqp_props_plaintext._flags = AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_CONTENT_TYPE_FLAG; pData->amqp_props_plaintext.delivery_mode = pData->delivery_mode; /* persistent delivery mode */ pData->amqp_props_plaintext.content_type = amqp_cstring_bytes("plain/text"); if (pData->expiration.len) { pData->amqp_props_plaintext._flags |= AMQP_BASIC_EXPIRATION_FLAG; pData->amqp_props_plaintext.expiration = pData->expiration; } memcpy(&pData->amqp_props_tpl_type, &pData->amqp_props_plaintext, sizeof(amqp_basic_properties_t)); /* The first position of doAction tab will contain the internal message */ CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); // RabbitMQ properties initialization if (pData->routing_key_template) { pData->idx_routing_key_template = 1; CHKiRet( OMSRsetEntry(*ppOMSR, 1, (uchar *)strdup((const char *)pData->routing_key_template), OMSR_NO_RQD_TPL_OPTS)); } /* if pData->body_template is NULL (not defined) then let's use former * json format if pData->body_template is not an empty string then let's * use it. In this case the content type is defined either * by the template name or the user defined content_type if set * otherwise raw data (unformatted) are sent this is done setting * pData->idx_body_template to 0 */ if (pData->body_template == NULL) { /* no template */ DBGPRINTF("Body_template is using default StdJSONFmt definition.\n"); pData->idx_body_template = pData->idx_routing_key_template + 1; CHKiRet(OMSRsetEntry(*ppOMSR, pData->idx_body_template, (uchar *)strdup(" StdJSONFmt"), OMSR_NO_RQD_TPL_OPTS)); pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes("application/json"); } else if (*pData->body_template) { pData->idx_body_template = pData->idx_routing_key_template + 1; CHKiRet(OMSRsetEntry(*ppOMSR, pData->idx_body_template, (uchar *)strdup((const char *)pData->body_template), OMSR_NO_RQD_TPL_OPTS)); pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes((pData->content_type) ? pData->content_type : (char *)pData->body_template); } else { pData->idx_body_template = 0; pData->amqp_props_tpl_type.content_type = amqp_cstring_bytes((pData->content_type) ? pData->content_type : "raw"); } /* treatment of the server parameter * first the default port */ pData->server2.port = pData->server1.port = port ? port : 5672; char *temp; int p; pData->server1.host = host; /* Is there more than one server in parameter */ if ((pData->server2.host = strchr(pData->server1.host, ' ')) != NULL) { *pData->server2.host++ = '\0'; /* is there a port with the second server */ if ((temp = strchr(pData->server2.host, ':')) != NULL) { *temp++ = '\0'; p = atoi(temp); if (p) pData->server2.port = p; } } /* is there a port with the first/unique server */ if ((temp = strchr(pData->server1.host, ':')) != NULL) { *temp++ = '\0'; p = atoi(temp); if (p) pData->server1.port = p; } pData->vhost = vhost ? vhost : strdup("/"); pData->user = user ? user : strdup(""); pData->password = password ? password : strdup(""); init_recover(&pData->recover_policy, recover); if (recover) free(recover); dbgPrintInstInfo(pData); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; memset(pWrkrData, 0, sizeof(wrkrInstanceData_t)); pWrkrData->pData = pData; pthread_mutex_init(&pWrkrData->send_mutex, NULL); pthread_cond_init(&pWrkrData->cond, NULL); pWrkrData->state = RS_RET_SUSPENDED; pWrkrData->iidx = pData->iidx; pWrkrData->widx = ++pData->nbWrkr; memcpy(&(pWrkrData->recover_policy), &(pData->recover_policy), sizeof(recover_t)); if (pData->server2.host && *pData->server2.host) { time_t odd = time(NULL) % 2; memcpy(&(pWrkrData->serverPrefered.s), (odd) ? &pData->server1 : &pData->server2, sizeof(server_t)); memcpy(&(pWrkrData->serverBackup.s), (odd) ? &pData->server2 : &pData->server1, sizeof(server_t)); } else { memcpy(&(pWrkrData->serverPrefered.s), &pData->server1, sizeof(server_t)); } pWrkrData->serverActive = &pWrkrData->serverPrefered; startAMQPConnection(pWrkrData); ENDcreateWrkrInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; if (pWrkrData != NULL) { closeAMQPConnection(pWrkrData); pthread_mutex_destroy(&(pWrkrData->send_mutex)); pthread_cond_destroy(&(pWrkrData->cond)); } ENDfreeWrkrInstance BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/omrabbitmq/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020364 xustar0030 mtime=1752569012.330244093 30 atime=1764930929.255823095 30 ctime=1764935926.723630775 rsyslog-8.2512.0/contrib/omrabbitmq/Makefile.am0000664000175000017500000000037415035412264020034 0ustar00rgerrgerpkglib_LTLIBRARIES = omrabbitmq.la omrabbitmq_la_SOURCES = omrabbitmq.c omrabbitmq_la_CPPFLAGS = $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) omrabbitmq_la_LDFLAGS = -module -avoid-version omrabbitmq_la_LIBADD = $(RABBITMQ_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/omrabbitmq/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316020377 xustar0030 mtime=1764935886.315011974 30 atime=1764935896.388166268 30 ctime=1764935926.725630806 rsyslog-8.2512.0/contrib/omrabbitmq/Makefile.in0000664000175000017500000006354315114544316020056 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omrabbitmq ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omrabbitmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_omrabbitmq_la_OBJECTS = omrabbitmq_la-omrabbitmq.lo omrabbitmq_la_OBJECTS = $(am_omrabbitmq_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omrabbitmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omrabbitmq_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omrabbitmq_la_SOURCES) DIST_SOURCES = $(omrabbitmq_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omrabbitmq.la omrabbitmq_la_SOURCES = omrabbitmq.c omrabbitmq_la_CPPFLAGS = $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) omrabbitmq_la_LDFLAGS = -module -avoid-version omrabbitmq_la_LIBADD = $(RABBITMQ_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omrabbitmq/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omrabbitmq/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omrabbitmq.la: $(omrabbitmq_la_OBJECTS) $(omrabbitmq_la_DEPENDENCIES) $(EXTRA_omrabbitmq_la_DEPENDENCIES) $(AM_V_CCLD)$(omrabbitmq_la_LINK) -rpath $(pkglibdir) $(omrabbitmq_la_OBJECTS) $(omrabbitmq_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omrabbitmq_la-omrabbitmq.lo: omrabbitmq.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omrabbitmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omrabbitmq_la-omrabbitmq.lo -MD -MP -MF $(DEPDIR)/omrabbitmq_la-omrabbitmq.Tpo -c -o omrabbitmq_la-omrabbitmq.lo `test -f 'omrabbitmq.c' || echo '$(srcdir)/'`omrabbitmq.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omrabbitmq_la-omrabbitmq.Tpo $(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omrabbitmq.c' object='omrabbitmq_la-omrabbitmq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omrabbitmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omrabbitmq_la-omrabbitmq.lo `test -f 'omrabbitmq.c' || echo '$(srcdir)/'`omrabbitmq.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omrabbitmq_la-omrabbitmq.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/improg0000644000000000000000000000013215114544373015420 xustar0030 mtime=1764935931.418702649 30 atime=1764935934.366747775 30 ctime=1764935931.418702649 rsyslog-8.2512.0/contrib/improg/0000775000175000017500000000000015114544373015141 5ustar00rgerrgerrsyslog-8.2512.0/contrib/improg/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264017523 xustar0029 mtime=1752569012.32825799 30 atime=1764930928.037802426 30 ctime=1764935931.414702587 rsyslog-8.2512.0/contrib/improg/Makefile.am0000664000175000017500000000050715035412264017172 0ustar00rgerrgerpkglib_LTLIBRARIES = improg.la improg_la_SOURCES = improg.c improg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) improg_la_LDFLAGS = -module -avoid-version improg_la_LIBADD = if ENABLE_LIBLOGGING_STDLOG improg_la_CPPFLAGS += $(LIBLOGGING_STDLOG_CFLAGS) improg_la_LDFLAGS += $(LIBLOGGING_STDLOG_LIBS) endif rsyslog-8.2512.0/contrib/improg/PaxHeaders/improg.c0000644000000000000000000000013215055605325017135 xustar0030 mtime=1756826325.612800125 30 atime=1764931116.439921762 30 ctime=1764935931.418702649 rsyslog-8.2512.0/contrib/improg/improg.c0000664000175000017500000005332115055605325016605 0ustar00rgerrger/* improg.c * This input plugin enables rsyslog to execute a program and * receive from it the message stream as standard input. * One message per line with a maximum size * * NOTE: read comments in module-template.h for more specifics! * * File begun on 2009-04-01 by RGerhards * File copied and adjust from improg.c on 2019-02-07 by Ph. Duveau * * Copyright 2009-2018 Adiscon GmbH. * * This file is contribution of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Very strange error on solaris 11 LOG_CRON already defined here. * It is redefined in rsyslog.h * The error also appeared with module omprog but the warning is * accepted without generated an error */ #ifdef LOG_CRON #undef LOG_CRON #endif #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "unicode-helper.h" #include "errmsg.h" #include "cfsysline.h" #include "glbl.h" #include "prop.h" #include "ruleset.h" #include "ratelimit.h" #include "stringbuf.h" MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("improg") struct instanceConf_s { uchar *pszBinary; /* name of external program to call */ char **aParams; /* optional parameters to pass to external program */ int iParams; /* holds the count of parameters if set */ uchar *pszTag; size_t lenTag; int iFacility; int iSeverity; int bConfirmMessages; /* does the program provide feedback via stdout? */ int bSignalOnClose; /* should send SIGTERM to program before closing pipe? */ long lCloseTimeout; /* how long to wait for program to terminate after closing pipe (ms) */ int bKillUnresponsive; /* should send SIGKILL if closeTimeout is reached? */ cstr_t *ppCStr; int bIsRunning; /* is program currently running? 0-no, 1-yes */ pid_t pid; /* pid of currently running child process */ int fdPipeToChild; /* fd for sending data to the program */ int fdPipeFromChild; /* fd for receiving messages from the program, or -1 */ uchar *pszBindRuleset; ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ ratelimit_t *ratelimiter; struct instanceConf_s *next; struct instanceConf_s *prev; }; /* config variables */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) static prop_t *pInputName = NULL; #define NO_HUP_FORWARD -1 /* indicates that HUP should NOT be forwarded */ #define DEFAULT_CONFIRM_TIMEOUT_MS 10000 #define DEFAULT_CLOSE_TIMEOUT_MS 5000 #define RESPONSE_LINE_BUFFER_SIZE 4096 #define OUTPUT_CAPTURE_BUFFER_SIZE 4096 #define MAX_FD_TO_CLOSE 65535 static instanceConf_t *confRoot = NULL; static fd_set rfds; static int nfds = 0; extern char **environ; /* POSIX environment ptr, by std not in a header... (see man 7 environ) */ static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *pInst) { LogError(0, NO_ERRCODE, "improg: ruleset '%s' for binary %s not found - " "using default ruleset instead", pInst->pszBindRuleset, pInst->pszBinary); } #include "im-helper.h" /* must be included AFTER the type definitions! */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr inppdescr[] = {{"binary", eCmdHdlrString, CNFPARAM_REQUIRED}, {"tag", eCmdHdlrString, CNFPARAM_REQUIRED}, {"severity", eCmdHdlrSeverity, 0}, {"facility", eCmdHdlrFacility, 0}, {"ruleset", eCmdHdlrString, 0}, {"confirmmessages", eCmdHdlrBinary, 0}, {"signalonclose", eCmdHdlrBinary, 0}, {"closetimeout", eCmdHdlrInt, 0}, {"killunresponsive", eCmdHdlrBinary, 0}}; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; /* execute the external program (must be called in child context after fork). */ static __attribute__((noreturn)) void execBinary(const instanceConf_t *pInst, int pipeToParent, int pipeFromParent) { int maxFd, fd, sigNum; struct sigaction sigAct; sigset_t sigSet; char errStr[1024]; if (dup2(pipeToParent, STDOUT_FILENO) == -1) { goto failed; } if (pipeFromParent != -1) { if (dup2(pipeFromParent, STDIN_FILENO) == -1) { goto failed; } } /* close the file handles the child process doesn't need (all above STDERR). * The following way is simple and portable, though not perfect. * See https://stackoverflow.com/a/918469 for alternatives. */ maxFd = sysconf(_SC_OPEN_MAX); if (maxFd < 0 || maxFd > MAX_FD_TO_CLOSE) { maxFd = MAX_FD_TO_CLOSE; } #ifdef VALGRIND else { maxFd -= 10; } #endif for (fd = STDERR_FILENO + 1; fd <= maxFd; ++fd) { close(fd); } /* reset signal handlers to default */ memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = SIG_DFL; for (sigNum = 1; sigNum < NSIG; ++sigNum) { sigaction(sigNum, &sigAct, NULL); } /* we need to block SIGINT, otherwise our program is cancelled when we are * stopped in debug mode. */ sigAct.sa_handler = SIG_IGN; sigaction(SIGINT, &sigAct, NULL); sigemptyset(&sigSet); sigprocmask(SIG_SETMASK, &sigSet, NULL); alarm(0); /* finally exec program */ execve((char *)pInst->pszBinary, pInst->aParams, environ); failed: /* an error occurred: log it and exit the child process. We use the * 'syslog' system call to log the error (we cannot use LogMsg/LogError, * since these functions add directly to the rsyslog input queue). */ rs_strerror_r(errno, errStr, sizeof(errStr)); DBGPRINTF("improg: failed to execute program '%s': %s\n", pInst->pszBinary, errStr); openlog("rsyslogd", 0, LOG_SYSLOG); syslog(LOG_ERR, "improg: failed to execute program '%s': %s\n", pInst->pszBinary, errStr); /* let's print the error to stderr for test bench purposes */ fprintf(stderr, "improg: failed to execute program '%s': %s\n", pInst->pszBinary, errStr); exit(1); } /* creates a pipe and starts program, uses pipe as stdin for program. * rgerhards, 2009-04-01 */ static rsRetVal openPipe(instanceConf_t *pInst) { int pipeFromChild[2] = {-1, -1}; int pipeToChild[2] = {-1, -1}; pid_t cpid; DEFiRet; /* if the 'confirmMessages' setting is enabled, open a pipe to send message confirmations to the program */ if (pInst->bConfirmMessages && pipe(pipeToChild) == -1) { ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE); } /* open a pipe to receive messages to the program */ if (pipe(pipeFromChild) == -1) { ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE); } DBGPRINTF("improg: executing program '%s' with '%d' parameters\n", pInst->pszBinary, pInst->iParams); cpid = fork(); if (cpid == -1) { ABORT_FINALIZE(RS_RET_ERR_FORK); } if (cpid == 0) { /* we are now the child process: execute the program */ /* close the pipe ends that the child doesn't need */ close(pipeFromChild[0]); if (pipeToChild[1] != -1) { close(pipeToChild[1]); } execBinary(pInst, pipeFromChild[1], pipeToChild[0]); /* NO CODE HERE - WILL NEVER BE REACHED! */ } DBGPRINTF("improg: child has pid %ld\n", (long int)cpid); /* close the pipe ends that the parent doesn't need */ close(pipeFromChild[1]); if (pipeToChild[0] != -1) { close(pipeToChild[0]); } pInst->fdPipeToChild = pipeToChild[1]; /* we'll send messages confirmations to the program via this fd */ pInst->fdPipeFromChild = pipeFromChild[0]; /* we'll receive message via this fd */ FD_SET(pInst->fdPipeFromChild, &rfds); /* manage select read fd set */ nfds = (nfds > pInst->fdPipeFromChild) ? nfds : pInst->fdPipeFromChild + 1; pInst->pid = cpid; pInst->bIsRunning = 1; finalize_it: if (iRet != RS_RET_OK) { if (pipeFromChild[0] != -1) { close(pipeFromChild[0]); close(pipeFromChild[1]); } if (pipeToChild[0] != -1) { close(pipeToChild[0]); close(pipeToChild[1]); } } RETiRet; } static void waitForChild(instanceConf_t *pInst) { int status; int ret; long counter; counter = pInst->lCloseTimeout / 10; while ((ret = waitpid(pInst->pid, &status, WNOHANG)) == 0 && counter > 0) { srSleep(0, 10000); /* 0 seconds, 10 milliseconds */ --counter; } if (ret == 0) { /* timeout reached */ if (!pInst->bKillUnresponsive) { LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: program '%s' (pid %ld) did not terminate " "within timeout (%ld ms); ignoring it", pInst->pszBinary, (long int)pInst->pid, pInst->lCloseTimeout); return; } LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: program '%s' (pid %ld) did not terminate " "within timeout (%ld ms); killing it", pInst->pszBinary, (long int)pInst->pid, pInst->lCloseTimeout); if (kill(pInst->pid, SIGKILL) == -1) { LogError(errno, RS_RET_SYS_ERR, "improg: could not send SIGKILL to child process"); return; } ret = waitpid(pInst->pid, &status, 0); } /* waitpid will fail with errno == ECHILD if the child process has already been reaped by the rsyslogd main loop (see rsyslogd.c) */ if (ret == pInst->pid) { glblReportChildProcessExit(runConf, pInst->pszBinary, pInst->pid, status); } } /* Send SIGTERM to child process if configured to do so, close pipe * and wait for child to terminate. */ static void terminateChild(instanceConf_t *pInst) { if (pInst->bIsRunning) { if (pInst->fdPipeFromChild != -1) { close(pInst->fdPipeFromChild); FD_CLR(pInst->fdPipeFromChild, &rfds); pInst->fdPipeFromChild = -1; } if (pInst->fdPipeToChild != -1) { close(pInst->fdPipeToChild); pInst->fdPipeToChild = -1; } /* wait for the child AFTER closing the pipe, so it receives EOF */ waitForChild(pInst); pInst->bIsRunning = 0; } } static rsRetVal startChild(instanceConf_t *pInst) { DEFiRet; if (!pInst->bIsRunning) CHKiRet(openPipe(pInst)); finalize_it: if (iRet != RS_RET_OK && pInst->bIsRunning) { /* if initialization has failed, terminate program */ terminateChild(pInst); } RETiRet; } static rsRetVal enqLine(instanceConf_t *const __restrict__ pInst) { DEFiRet; smsg_t *pMsg; if (cstrLen(pInst->ppCStr) == 0) { /* we do not process empty lines */ FINALIZE; } CHKiRet(msgConstruct(&pMsg)); MsgSetMSGoffs(pMsg, 0); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY); MsgSetInputName(pMsg, pInputName); MsgSetAPPNAME(pMsg, (const char *)pInst->pszTag); MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); msgSetPRI(pMsg, pInst->iFacility | pInst->iSeverity); MsgSetRawMsg(pMsg, (const char *)rsCStrGetBufBeg(pInst->ppCStr), cstrLen(pInst->ppCStr)); MsgSetRuleset(pMsg, pInst->pBindRuleset); ratelimitAddMsg(pInst->ratelimiter, NULL, pMsg); finalize_it: RETiRet; } /* read line(s) from the external program and sent them when they are complete */ static rsRetVal readChild(instanceConf_t *const pInst) { char c; int retval; while ((retval = read(pInst->fdPipeFromChild, &c, 1)) == 1) { if (c == '\n') { enqLine(pInst); /* if confirm required then send an ACK to the program */ if (pInst->bConfirmMessages) { if (write(pInst->fdPipeToChild, "ACK\n", sizeof("ACK\n") - 1) <= 0) LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: pipe to child seems to be closed."); } rsCStrTruncate(pInst->ppCStr, rsCStrLen(pInst->ppCStr)); } else { cstrAppendChar(pInst->ppCStr, c); } } return (retval == 0) ? RS_RET_OK : RS_RET_IO_ERROR; } /* create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal ATTR_NONNULL(1) createInstance(instanceConf_t **const ppInst) { instanceConf_t *pInst; DEFiRet; CHKmalloc(pInst = malloc(sizeof(instanceConf_t))); pInst->next = NULL; pInst->pszBindRuleset = NULL; pInst->pBindRuleset = NULL; pInst->ratelimiter = NULL; pInst->iSeverity = 5; pInst->iFacility = 128; pInst->pszTag = NULL; pInst->lenTag = 0; pInst->bIsRunning = 0; pInst->pid = -1; pInst->fdPipeToChild = -1; pInst->fdPipeFromChild = -1; pInst->pszBinary = NULL; pInst->aParams = NULL; pInst->iParams = 0; pInst->bConfirmMessages = 1; pInst->bSignalOnClose = 0; pInst->lCloseTimeout = 200; pInst->bKillUnresponsive = 1; *ppInst = pInst; finalize_it: RETiRet; } /* This adds a new listener object to the bottom of the list, but * it does NOT initialize any data members except for the list * pointers themselves. */ static rsRetVal ATTR_NONNULL() lstnAdd(instanceConf_t *pInst) { DEFiRet; CHKiRet(ratelimitNew(&pInst->ratelimiter, "improg", (char *)pInst->pszBinary)); /* insert it at the begin of the list */ pInst->prev = NULL; pInst->next = confRoot; if (confRoot != NULL) confRoot->prev = pInst; confRoot = pInst; finalize_it: RETiRet; } /* delete a listener object */ static void ATTR_NONNULL(1) lstnFree(instanceConf_t *pInst) { DBGPRINTF("lstnFree called for %s\n", pInst->pszBinary); if (pInst->ratelimiter != NULL) ratelimitDestruct(pInst->ratelimiter); if (pInst->pszBinary != NULL) free(pInst->pszBinary); if (pInst->pszTag) free(pInst->pszTag); if (pInst->pszBindRuleset != NULL) free(pInst->pszBindRuleset); if (pInst->aParams) { int i; for (i = 0; pInst->aParams[i]; i++) free(pInst->aParams[i]); free(pInst->aParams); } if (pInst->ppCStr) rsCStrDestruct(&pInst->ppCStr); free(pInst); } /* read */ BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *pInst = NULL; int i; CODESTARTnewInpInst; DBGPRINTF("newInpInst (improg)\n"); pvals = nvlstGetParams(lst, &inppblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { DBGPRINTF("input param blk in improg:\n"); cnfparamsPrint(&inppblk, pvals); } CHKiRet(createInstance(&pInst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "binary")) { CHKiRet(split_binary_parameters(&pInst->pszBinary, &pInst->aParams, &pInst->iParams, pvals[i].val.d.estr)); } else if (!strcmp(inppblk.descr[i].name, "tag")) { pInst->pszTag = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); pInst->lenTag = es_strlen(pvals[i].val.d.estr); } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { pInst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "severity")) { pInst->iSeverity = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "facility")) { pInst->iFacility = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "confirmmessages")) { pInst->bConfirmMessages = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "signalonclose")) { pInst->bSignalOnClose = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "closetimeout")) { pInst->lCloseTimeout = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "killunresponsive")) { pInst->bKillUnresponsive = pvals[i].val.d.n; } else { DBGPRINTF( "program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } if (pInst->pszBinary == NULL) { LogError(0, RS_RET_FILE_NOT_SPECIFIED, "ulogbase is not configured - no input will be gathered"); ABORT_FINALIZE(RS_RET_FILE_NOT_SPECIFIED); } CHKiRet(cstrConstruct(&pInst->ppCStr)); if ((iRet = lstnAdd(pInst)) != RS_RET_OK) { ABORT_FINALIZE(iRet); } finalize_it: CODE_STD_FINALIZERnewInpInst if (pInst && iRet != RS_RET_OK) lstnFree(pInst); cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINwillRun CODESTARTwillRun; /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("improg"), sizeof("improg") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); finalize_it: ENDwillRun BEGINrunInput struct timeval tv; int retval; instanceConf_t *pInst; CODESTARTrunInput; FD_ZERO(&rfds); for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { startChild(pInst); } for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { if (pInst->bIsRunning && pInst->fdPipeToChild > 0) { if (write(pInst->fdPipeToChild, "START\n", sizeof("START\n") - 1) <= 0) LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: pipe to child seems to be closed."); DBGPRINTF("Sending START to %s\n", pInst->pszBinary); } } /* main module loop */ tv.tv_usec = 1000; while (glbl.GetGlobalInputTermState() == 0) { fd_set temp; memcpy(&temp, &rfds, sizeof(fd_set)); tv.tv_sec = 0; /* wait for external data or 0.1 second */ retval = select(nfds, &temp, NULL, NULL, &tv); /* retval is the number of fd with data to read */ while (retval > 0) { for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { if (FD_ISSET(pInst->fdPipeFromChild, &temp)) { DBGPRINTF("read child %s\n", pInst->pszBinary); readChild(pInst); retval--; } } } tv.tv_usec = 100000; } DBGPRINTF("terminating upon request of rsyslog core\n"); ENDrunInput /* This function is called by the framework after runInput() has been terminated. It * shall free any resources and prepare the module for unload. * CODEqueryEtryPt_STD_IMOD_QUERIES */ BEGINafterRun CODESTARTafterRun; instanceConf_t *pInst = confRoot, *nextInst; confRoot = NULL; DBGPRINTF("afterRun\n"); while (pInst != NULL) { nextInst = pInst->next; if (pInst->bIsRunning) { if (pInst->bSignalOnClose) { kill(pInst->pid, SIGTERM); LogMsg(0, NO_ERRCODE, LOG_INFO, "%s SIGTERM signaled.", pInst->aParams[0]); } if (pInst->fdPipeToChild > 0) { if (write(pInst->fdPipeToChild, "STOP\n", strlen("STOP\n")) <= 0 && !pInst->bSignalOnClose) LogMsg(0, NO_ERRCODE, LOG_WARNING, "improg: pipe to child seems to be closed."); } terminateChild(pInst); } lstnFree(pInst); pInst = nextInst; } if (pInputName != NULL) prop.Destruct(&pInputName); ENDafterRun BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) { iRet = RS_RET_OK; } ENDisCompatibleWithFeature BEGINbeginCnfLoad CODESTARTbeginCnfLoad; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf instanceConf_t *pInst; CODESTARTcheckCnf; for (pInst = confRoot; pInst != NULL; pInst = pInst->next) { std_checkRuleset(pModConf, pInst); } ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINmodExit CODESTARTmodExit; objRelease(ruleset, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/improg/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017536 xustar0030 mtime=1764935885.883005357 30 atime=1764935896.940174723 30 ctime=1764935931.416702618 rsyslog-8.2512.0/contrib/improg/Makefile.in0000664000175000017500000006334415114544315017214 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_1 = $(LIBLOGGING_STDLOG_CFLAGS) @ENABLE_LIBLOGGING_STDLOG_TRUE@am__append_2 = $(LIBLOGGING_STDLOG_LIBS) subdir = contrib/improg ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) improg_la_DEPENDENCIES = am_improg_la_OBJECTS = improg_la-improg.lo improg_la_OBJECTS = $(am_improg_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = improg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(improg_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/improg_la-improg.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(improg_la_SOURCES) DIST_SOURCES = $(improg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = improg.la improg_la_SOURCES = improg.c improg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) \ $(am__append_1) improg_la_LDFLAGS = -module -avoid-version $(am__append_2) improg_la_LIBADD = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/improg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/improg/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } improg.la: $(improg_la_OBJECTS) $(improg_la_DEPENDENCIES) $(EXTRA_improg_la_DEPENDENCIES) $(AM_V_CCLD)$(improg_la_LINK) -rpath $(pkglibdir) $(improg_la_OBJECTS) $(improg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improg_la-improg.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< improg_la-improg.lo: improg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(improg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT improg_la-improg.lo -MD -MP -MF $(DEPDIR)/improg_la-improg.Tpo -c -o improg_la-improg.lo `test -f 'improg.c' || echo '$(srcdir)/'`improg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/improg_la-improg.Tpo $(DEPDIR)/improg_la-improg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='improg.c' object='improg_la-improg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(improg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o improg_la-improg.lo `test -f 'improg.c' || echo '$(srcdir)/'`improg.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/improg_la-improg.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/improg_la-improg.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/pmaixforwardedfrom0000644000000000000000000000013215114544365020024 xustar0030 mtime=1764935925.937618742 30 atime=1764935930.172683575 30 ctime=1764935925.937618742 rsyslog-8.2512.0/contrib/pmaixforwardedfrom/0000775000175000017500000000000015114544365017545 5ustar00rgerrgerrsyslog-8.2512.0/contrib/pmaixforwardedfrom/PaxHeaders/pmaixforwardedfrom.c0000644000000000000000000000013215055605325024143 xustar0030 mtime=1756826325.614800155 30 atime=1764931055.290925128 30 ctime=1764935925.937618742 rsyslog-8.2512.0/contrib/pmaixforwardedfrom/pmaixforwardedfrom.c0000664000175000017500000001373415055605325023617 0ustar00rgerrger/* pmaixforwardedfrom.c * * this cleans up messages forwarded from AIX * * instead of actually parsing the message, this modifies the message and then falls through to allow a * later parser to handle the now modified message * * created 2010-12-13 by David Lang based on pmlastmsg * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" #include "rsconf.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.aixforwardedfrom") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINparse uchar *p2parse; int lenMsg; int skipLen = 0; #define OpeningText "Message forwarded from " #define OpeningText2 "From " CODESTARTparse; dbgprintf("Message will now be parsed by fix AIX Forwarded From parser.\n"); assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* check if this message is of the type we handle in this (very limited) parser */ /* first, we permit SP */ while (lenMsg && *p2parse == ' ') { --lenMsg; ++p2parse; } if ((unsigned)lenMsg < 24) { /* too short, can not be "our" message */ /* minimum message, 16 character timestamp, 'From ", 1 character name, ': '*/ ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* skip over timestamp */ lenMsg -= 16; p2parse += 16; /* if there is the string "Message forwarded from " were the hostname should be */ if (!strncasecmp((char *)p2parse, OpeningText, sizeof(OpeningText) - 1)) skipLen = 23; /* or "From " */ if (!strncasecmp((char *)p2parse, OpeningText2, sizeof(OpeningText2) - 1)) skipLen = 5; DBGPRINTF("pmaixforwardedfrom: skipLen %d\n", skipLen); if (!skipLen) { /* wrong opening text */ DBGPRINTF("not a AIX message forwarded from mangled log!\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* bump the message portion up by skipLen(23 or 5) characters to overwrite the "Message forwarded from " or "From " with the hostname */ lenMsg -= skipLen; if (lenMsg < 2) { dbgprintf("not a AIX message forwarded from message has nothing after header\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } memmove(p2parse, p2parse + skipLen, lenMsg); *(p2parse + lenMsg) = '\n'; *(p2parse + lenMsg + 1) = '\0'; pMsg->iLenRawMsg -= skipLen; pMsg->iLenMSG -= skipLen; /* now look for the : after the hostname to walk past the hostname, also watch for a space in case this isn't really an AIX log, but has a similar preamble */ while (lenMsg && *p2parse != ' ' && *p2parse != ':') { --lenMsg; ++p2parse; } if (lenMsg < 1) { dbgprintf( "not a AIX message forwarded from message has nothing after colon " "or no colon at all\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } if (lenMsg && *p2parse != ':') { DBGPRINTF( "not a AIX message forwarded from mangled log but similar enough that the preamble has " "been removed\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* bump the message portion up by one character to overwrite the extra : */ lenMsg -= 1; memmove(p2parse, p2parse + 1, lenMsg); *(p2parse + lenMsg) = '\n'; *(p2parse + lenMsg + 1) = '\0'; pMsg->iLenRawMsg -= 1; pMsg->iLenMSG -= 1; /* now, claim to abort so that something else can parse the now modified message */ DBGPRINTF("pmaixforwardedfrom: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); finalize_it: ENDparse BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); DBGPRINTF("aixforwardedfrom parser init called, compiled with version %s\n", VERSION); bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); /* cache value, is set only during rsyslogd option processing */ ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/contrib/pmaixforwardedfrom/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264022126 xustar0030 mtime=1752569012.331237145 29 atime=1764930929.40582564 30 ctime=1764935925.932618666 rsyslog-8.2512.0/contrib/pmaixforwardedfrom/Makefile.am0000664000175000017500000000044215035412264021573 0ustar00rgerrgerpkglib_LTLIBRARIES = pmaixforwardedfrom.la pmaixforwardedfrom_la_SOURCES = pmaixforwardedfrom.c pmaixforwardedfrom_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmaixforwardedfrom_la_LDFLAGS = -module -avoid-version pmaixforwardedfrom_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/pmaixforwardedfrom/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316022142 xustar0030 mtime=1764935886.373012863 30 atime=1764935896.328165349 30 ctime=1764935925.935618712 rsyslog-8.2512.0/contrib/pmaixforwardedfrom/Makefile.in0000664000175000017500000006437715114544316021627 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/pmaixforwardedfrom ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) pmaixforwardedfrom_la_DEPENDENCIES = am_pmaixforwardedfrom_la_OBJECTS = \ pmaixforwardedfrom_la-pmaixforwardedfrom.lo pmaixforwardedfrom_la_OBJECTS = $(am_pmaixforwardedfrom_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pmaixforwardedfrom_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(pmaixforwardedfrom_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pmaixforwardedfrom_la_SOURCES) DIST_SOURCES = $(pmaixforwardedfrom_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = pmaixforwardedfrom.la pmaixforwardedfrom_la_SOURCES = pmaixforwardedfrom.c pmaixforwardedfrom_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmaixforwardedfrom_la_LDFLAGS = -module -avoid-version pmaixforwardedfrom_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmaixforwardedfrom/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pmaixforwardedfrom/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pmaixforwardedfrom.la: $(pmaixforwardedfrom_la_OBJECTS) $(pmaixforwardedfrom_la_DEPENDENCIES) $(EXTRA_pmaixforwardedfrom_la_DEPENDENCIES) $(AM_V_CCLD)$(pmaixforwardedfrom_la_LINK) -rpath $(pkglibdir) $(pmaixforwardedfrom_la_OBJECTS) $(pmaixforwardedfrom_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pmaixforwardedfrom_la-pmaixforwardedfrom.lo: pmaixforwardedfrom.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmaixforwardedfrom_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmaixforwardedfrom_la-pmaixforwardedfrom.lo -MD -MP -MF $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Tpo -c -o pmaixforwardedfrom_la-pmaixforwardedfrom.lo `test -f 'pmaixforwardedfrom.c' || echo '$(srcdir)/'`pmaixforwardedfrom.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Tpo $(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmaixforwardedfrom.c' object='pmaixforwardedfrom_la-pmaixforwardedfrom.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmaixforwardedfrom_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmaixforwardedfrom_la-pmaixforwardedfrom.lo `test -f 'pmaixforwardedfrom.c' || echo '$(srcdir)/'`pmaixforwardedfrom.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pmaixforwardedfrom_la-pmaixforwardedfrom.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmrfc5424addhmac0000644000000000000000000000013115114544372017046 xustar0030 mtime=1764935930.548689331 29 atime=1764935934.36574776 30 ctime=1764935930.548689331 rsyslog-8.2512.0/contrib/mmrfc5424addhmac/0000775000175000017500000000000015114544372016570 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmrfc5424addhmac/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264021154 xustar0030 mtime=1752569012.329251042 30 atime=1764930928.517810572 30 ctime=1764935930.543689254 rsyslog-8.2512.0/contrib/mmrfc5424addhmac/Makefile.am0000664000175000017500000000044115035412264020617 0ustar00rgerrgerpkglib_LTLIBRARIES = mmrfc5424addhmac.la mmrfc5424addhmac_la_SOURCES = mmrfc5424addhmac.c mmrfc5424addhmac_la_CPPFLAGS = $(OPENSSL_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmrfc5424addhmac_la_LDFLAGS = -module -avoid-version mmrfc5424addhmac_la_LIBADD = $(OPENSSL_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/mmrfc5424addhmac/PaxHeaders/mmrfc5424addhmac.c0000644000000000000000000000013115055605325022214 xustar0029 mtime=1756826325.61380014 30 atime=1764931153.277515848 30 ctime=1764935930.549689346 rsyslog-8.2512.0/contrib/mmrfc5424addhmac/mmrfc5424addhmac.c0000664000175000017500000002324215055605325021664 0ustar00rgerrger/* mmrfc5424addhmac.c * custom module: add hmac to RFC5424 messages * * Note on important design decision: This module is fully self-contained. * Most importantly, it does not rely on mmpstrucdata to populate the * structured data portion of the messages JSON. There are two reasons * for this: * 1. robustness * - this guard against misconfiguration * - it permits us to be more liberal in regard to malformed * structured data * - it permits us to handle border-cases (like duplicate * SD-IDs) with much less complexity * 2. performance * With being "on the spot" of what we need we can reduce memory * reads and writes. This is a considerable save if the JSON representation * is not otherwise needed. * * Note that the recommended calling sequence if both of these modules * are used is * * 1. mmrfc5424addhmac * 2. mmpstrucdata * * This sequence permits mmpstrucdata to pick up the modifications we * made in this module here. * * Copyright 2013 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmrfc5424addhmac") DEF_OMOD_STATIC_DATA; /* config variables */ typedef struct _instanceData { uchar *key; int16_t keylen; /* cached length of key, to avoid recomputation */ uchar *sdid; /* SD-ID to be used to persist the hmac */ int16_t sdidLen; const EVP_MD *algo; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"key", eCmdHdlrString, 1}, {"hashfunction", eCmdHdlrString, 1}, {"sd_id", eCmdHdlrGetWord, 1}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance static inline void setInstParamDefaults(instanceData *pData) { pData->key = NULL; } BEGINnewActInst struct cnfparamvals *pvals; char *ciphername; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (mmrfc5424addhmac)\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "key")) { pData->key = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); pData->keylen = es_strlen(pvals[i].val.d.estr); } else if (!strcmp(actpblk.descr[i].name, "hashfunction")) { ciphername = es_str2cstr(pvals[i].val.d.estr, NULL); pData->algo = EVP_get_digestbyname(ciphername); if (pData->algo == NULL) { LogError(0, RS_RET_CRY_INVLD_ALGO, "hashFunction '%s' unknown to openssl - " "cannot continue", ciphername); free(ciphername); ABORT_FINALIZE(RS_RET_CRY_INVLD_ALGO); } free(ciphername); } else if (!strcmp(actpblk.descr[i].name, "sd_id")) { pData->sdid = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); pData->sdidLen = es_strlen(pvals[i].val.d.estr); } else { dbgprintf( "mmrfc5424addhmac: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume /* turn the binary data in bin of length len into a * printable hex string. "print" must be 2*len+1 (for \0) */ static void hexify(uchar *bin, int len, uchar *print) { static const char hexchars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; int iSrc, iDst; for (iSrc = iDst = 0; iSrc < len; ++iSrc) { print[iDst++] = hexchars[bin[iSrc] >> 4]; print[iDst++] = hexchars[bin[iSrc] & 0x0f]; } print[iDst] = '\0'; } /* skip to end of current SD-ID. This function can be improved * in regard to fully parsing based on RFC5424, HOWEVER, this would * also reduce performance. So we consider the current implementation * to be superior. */ static void skipSDID(uchar *sdbuf, int sdlen, int *rootIdx) { int i; i = *rootIdx; while (i < sdlen) { if (sdbuf[i] == ']') { if (i > *rootIdx && sdbuf[i - 1] == '\\') { ; /* escaped, nothing to do! */ } else { ++i; /* eat ']' */ break; } } ++i; } *rootIdx = i; } static void getSDID(uchar *sdbuf, int sdlen, int *rootIdx, uchar *sdid) { int i, j; i = *rootIdx; j = 0; if (sdbuf[i] != '[') { ++i; goto done; } ++i; while (i < sdlen && sdbuf[i] != '=' && sdbuf[i] != ' ' && sdbuf[i] != ']' && sdbuf[i] != '"') { sdid[j++] = sdbuf[i++]; } done: sdid[j] = '\0'; *rootIdx = i; } /* check if "our" hmac is already present */ static sbool isHmacPresent(instanceData *pData, smsg_t *pMsg) { uchar *sdbuf; rs_size_t sdlen; sbool found; int i; uchar sdid[33]; /* RFC-based size limit */ MsgGetStructuredData(pMsg, &sdbuf, &sdlen); found = 0; if (sdbuf[0] == '-') /* RFC: struc data is empty! */ goto done; i = 0; while (i < sdlen && !found) { getSDID(sdbuf, sdlen, &i, sdid); if (!strcmp((char *)pData->sdid, (char *)sdid)) { found = 1; break; } skipSDID(sdbuf, sdlen, &i); } done: return found; } static rsRetVal hashMsg(instanceData *pData, smsg_t *pMsg) { uchar *pRawMsg; int lenRawMsg; uchar *sdbuf; rs_size_t sdlen; unsigned int hashlen; uchar hash[EVP_MAX_MD_SIZE]; uchar hashPrintable[2 * EVP_MAX_MD_SIZE + 1]; uchar newsd[64 * 1024]; /* we assume this is sufficient... */ int lenNewsd; DEFiRet; MsgGetStructuredData(pMsg, &sdbuf, &sdlen); getRawMsg(pMsg, &pRawMsg, &lenRawMsg); HMAC(pData->algo, pData->key, pData->keylen, pRawMsg, lenRawMsg, hash, &hashlen); hexify(hash, hashlen, hashPrintable); lenNewsd = snprintf((char *)newsd, sizeof(newsd), "[%s hash=\"%s\"]", (char *)pData->sdid, (char *)hashPrintable); MsgAddToStructuredData(pMsg, newsd, lenNewsd); RETiRet; } BEGINdoAction instanceData *pData = pWrkrData->pData; smsg_t *pMsg; CODESTARTdoAction; pMsg = (smsg_t *)ppString[0]; if (msgGetProtocolVersion(pMsg) == MSG_RFC5424_PROTOCOL && !isHmacPresent(pData, pMsg)) { hashMsg(pData, pMsg); } else { if (Debug) { uchar *pRawMsg; int lenRawMsg; getRawMsg(pMsg, &pRawMsg, &lenRawMsg); dbgprintf( "mmrfc5424addhmac: non-rfc5424 or HMAC already " "present: %.256s\n", pRawMsg); } } ENDdoAction NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; EVP_cleanup(); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmrfc5424addhmac: module compiled with rsyslog version %s.\n", VERSION); OpenSSL_add_all_digests(); ENDmodInit rsyslog-8.2512.0/contrib/mmrfc5424addhmac/PaxHeaders/Makefile.in0000644000000000000000000000013015114544316021165 xustar0030 mtime=1764935886.055007991 30 atime=1764935896.606169608 28 ctime=1764935930.5466893 rsyslog-8.2512.0/contrib/mmrfc5424addhmac/Makefile.in0000664000175000017500000006431115114544316020640 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmrfc5424addhmac ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = mmrfc5424addhmac_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_mmrfc5424addhmac_la_OBJECTS = \ mmrfc5424addhmac_la-mmrfc5424addhmac.lo mmrfc5424addhmac_la_OBJECTS = $(am_mmrfc5424addhmac_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmrfc5424addhmac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(mmrfc5424addhmac_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmrfc5424addhmac_la_SOURCES) DIST_SOURCES = $(mmrfc5424addhmac_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmrfc5424addhmac.la mmrfc5424addhmac_la_SOURCES = mmrfc5424addhmac.c mmrfc5424addhmac_la_CPPFLAGS = $(OPENSSL_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmrfc5424addhmac_la_LDFLAGS = -module -avoid-version mmrfc5424addhmac_la_LIBADD = $(OPENSSL_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmrfc5424addhmac/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmrfc5424addhmac/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmrfc5424addhmac.la: $(mmrfc5424addhmac_la_OBJECTS) $(mmrfc5424addhmac_la_DEPENDENCIES) $(EXTRA_mmrfc5424addhmac_la_DEPENDENCIES) $(AM_V_CCLD)$(mmrfc5424addhmac_la_LINK) -rpath $(pkglibdir) $(mmrfc5424addhmac_la_OBJECTS) $(mmrfc5424addhmac_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmrfc5424addhmac_la-mmrfc5424addhmac.lo: mmrfc5424addhmac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmrfc5424addhmac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmrfc5424addhmac_la-mmrfc5424addhmac.lo -MD -MP -MF $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Tpo -c -o mmrfc5424addhmac_la-mmrfc5424addhmac.lo `test -f 'mmrfc5424addhmac.c' || echo '$(srcdir)/'`mmrfc5424addhmac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Tpo $(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmrfc5424addhmac.c' object='mmrfc5424addhmac_la-mmrfc5424addhmac.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmrfc5424addhmac_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmrfc5424addhmac_la-mmrfc5424addhmac.lo `test -f 'mmrfc5424addhmac.c' || echo '$(srcdir)/'`mmrfc5424addhmac.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmrfc5424addhmac_la-mmrfc5424addhmac.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmdarwin0000644000000000000000000000013115114544372015737 xustar0030 mtime=1764935930.176683636 29 atime=1764935934.36574776 30 ctime=1764935930.176683636 rsyslog-8.2512.0/contrib/mmdarwin/0000775000175000017500000000000015114544372015461 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmdarwin/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264020044 xustar0029 mtime=1752569012.32825799 30 atime=1764930928.281806567 30 ctime=1764935930.169683529 rsyslog-8.2512.0/contrib/mmdarwin/Makefile.am0000664000175000017500000000033015035412264017505 0ustar00rgerrgerpkglib_LTLIBRARIES = mmdarwin.la mmdarwin_la_SOURCES = mmdarwin.c protocol.h mmdarwin_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmdarwin_la_LDFLAGS = -module -avoid-version mmdarwin_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/mmdarwin/PaxHeaders/mmdarwin.c0000644000000000000000000000013215055605325017777 xustar0030 mtime=1756826325.612800125 30 atime=1764931096.642600581 30 ctime=1764935930.174683605 rsyslog-8.2512.0/contrib/mmdarwin/mmdarwin.c0000664000175000017500000007212315055605325017450 0ustar00rgerrger/* Copyright 2019 Advens * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "parserif.h" #include #include #include #include #include #include #include #include "protocol.h" /* custom file written for Darwin */ #define JSON_DEFAULT_CONTAINER "!mmdarwin" #define JSON_DARWIN_ID "darwin_id" #define INVLD_SOCK -1 #define INITIAL_BUFFER_SIZE 32 #define BUFFER_DEFAULT_MAX_SIZE 65536 MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmdarwin") DEFobjCurrIf(glbl) DEF_OMOD_STATIC_DATA; typedef struct dyn_buffer_t { char *buffer; size_t bufferAllocSize; size_t bufferMsgSize; size_t bufferMaxSize; } dyn_buffer; /* config variables */ typedef struct _instanceData { char *pUUIDKey; /* the key to the UUID generated by an mmdarwin instance */ char *pCertitudeKey; /* the key name to save in the enriched log line the certitude obtained from Darwin */ uchar *pSockName; /* the socket path of the filter which will be used by Darwin */ unsigned long long int filterCode; /* the filter code associated to the filter which will be used by Darwin */ enum darwin_filter_response_type response; /* the type of response for Darwin: no / back / darwin / both */ struct { int nmemb; char **name; char **varname; } fieldList; /* our keys (fields) to be extracted from the JSON-parsed log line */ unsigned int socketMaxUse; sbool sendPartial; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; int sock; /* the socket of the filter which will be used by Darwin */ struct sockaddr_un addr; /* the sockaddr_un used to connect to the Darwin filter */ uint8_t pktSentSocket; dyn_buffer darwinBody; /* the body object used (and reused) to hold data to send to Darwin */ dyn_buffer fieldBuffer; } wrkrInstanceData_t; struct modConfData_s { /* our overall config object */ rsconf_t *pConf; const char *container; }; /* modConf ptr to use for the current load process */ static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current exec process */ static modConfData_t *runModConf = NULL; /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"container", eCmdHdlrGetWord, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* tables for interfacing with the v6 config system * action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"key", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"socketpath", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"fields", eCmdHdlrArray, CNFPARAM_REQUIRED}, {"filtercode", eCmdHdlrGetWord, 0}, /* optional parameter */ {"response", eCmdHdlrGetWord, 0}, /* optional parameter */ {"send_partial", eCmdHdlrBinary, 0}, /* optional parameter */ {"socket_max_use", eCmdHdlrNonNegInt, 0}, /* optional parameter - will disappear in future updates */ }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /* custom functions */ #define min(a, b) \ ({ \ __typeof__(a) _a = (a); \ __typeof__(b) _b = (b); \ _a < _b ? _a : _b; \ }) static rsRetVal openSocket(wrkrInstanceData_t *pWrkrData); static rsRetVal closeSocket(wrkrInstanceData_t *pWrkrData); static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData); static rsRetVal sendMsg(wrkrInstanceData_t *pWrkrData, void *msg, size_t len); static rsRetVal receiveMsg(wrkrInstanceData_t *pWrkrData, void *response, size_t len); const char *get_uuid_object(smsg_t *const pMsg); int get_field(smsg_t *const pMsg, const char *pFieldName, char **ppRetString); int expand_buffer(dyn_buffer *pBody, size_t new_size); int add_field_to_body(dyn_buffer *pBody, const char *field, size_t size); int start_new_line(dyn_buffer *pBody); int end_body(dyn_buffer *pBody); /* open socket to remote system */ static rsRetVal openSocket(wrkrInstanceData_t *pWrkrData) { DEFiRet; assert(pWrkrData->sock == INVLD_SOCK); if ((pWrkrData->sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { char errStr[1024]; int eno = errno; DBGPRINTF("mmdarwin::openSocket:: error %d creating AF_UNIX/SOCK_STREAM: %s.\n", eno, rs_strerror_r(eno, errStr, sizeof(errStr))); pWrkrData->sock = INVLD_SOCK; ABORT_FINALIZE(RS_RET_NO_SOCKET); } memset(&pWrkrData->addr, 0, sizeof(struct sockaddr_un)); pWrkrData->addr.sun_family = AF_UNIX; strncpy(pWrkrData->addr.sun_path, (char *)pWrkrData->pData->pSockName, sizeof(pWrkrData->addr.sun_path) - 1); DBGPRINTF("mmdarwin::openSocket:: connecting to Darwin...\n"); if (connect(pWrkrData->sock, (struct sockaddr *)&pWrkrData->addr, sizeof(struct sockaddr_un)) == -1) { LogError(errno, RS_RET_NO_SOCKET, "mmdarwin::openSocket:: error connecting to Darwin " "via socket '%s'", pWrkrData->pData->pSockName); pWrkrData->sock = INVLD_SOCK; ABORT_FINALIZE(RS_RET_NO_SOCKET); } DBGPRINTF("mmdarwin::openSocket:: connected !\n"); finalize_it: if (iRet != RS_RET_OK) { closeSocket(pWrkrData); } RETiRet; } /* close socket to remote system */ static rsRetVal closeSocket(wrkrInstanceData_t *pWrkrData) { DEFiRet; if (pWrkrData->sock != INVLD_SOCK) { if (close(pWrkrData->sock) != 0) { char errStr[1024]; int eno = errno; DBGPRINTF("mmdarwin::closeSocket:: error %d closing the socket: %s.\n", eno, rs_strerror_r(eno, errStr, sizeof(errStr))); } pWrkrData->sock = INVLD_SOCK; } RETiRet; } /* try to resume connection if it is not ready */ static rsRetVal doTryResume(wrkrInstanceData_t *pWrkrData) { DEFiRet; DBGPRINTF("mmdarwin::doTryResume:: trying to resume\n"); closeSocket(pWrkrData); iRet = openSocket(pWrkrData); if (iRet != RS_RET_OK) { iRet = RS_RET_SUSPENDED; } RETiRet; } /* send a message via TCP * inspired by rgehards, 2007-12-20 */ static rsRetVal sendMsg(wrkrInstanceData_t *pWrkrData, void *msg, size_t len) { DEFiRet; DBGPRINTF("mmdarwin::sendMsg:: sending message to Darwin...\n"); if (pWrkrData->sock == INVLD_SOCK) { CHKiRet(doTryResume(pWrkrData)); } if (pWrkrData->sock != INVLD_SOCK) { if (send(pWrkrData->sock, msg, len, 0) == -1) { char errStr[1024]; DBGPRINTF("mmdarwin::sendData:: error while sending data: error[%d] -> %s\n", errno, rs_strerror_r(errno, errStr, sizeof(errStr))); iRet = RS_RET_SUSPENDED; } } finalize_it: RETiRet; } /* receive a message via TCP * inspired by rgehards, 2007-12-20 */ static rsRetVal receiveMsg(wrkrInstanceData_t *pWrkrData, void *response, size_t len) { DEFiRet; DBGPRINTF("mmdarwin::receiveMsg:: receiving message from Darwin...\n"); if (pWrkrData->sock == INVLD_SOCK) { CHKiRet(doTryResume(pWrkrData)); } if (pWrkrData->sock != INVLD_SOCK) { if (recv(pWrkrData->sock, response, len, MSG_WAITALL) <= 0) { char errStr[1024]; DBGPRINTF("mmdarwin::receiveMsg:: error while receiving data: error[%d] -> %s\n", errno, rs_strerror_r(errno, errStr, sizeof(errStr))); iRet = RS_RET_NONE; } } finalize_it: RETiRet; } /** * Get the string corresponding to a field supposedly present in the provided message * * params: * - pMsg: a pointer to the rsyslog message where the field should be * - pFieldName: a nul-terminated pointer to string representing the name of the field to search for * - ppRetString: the pointer to contain the potential return string * * return: 1 if a string was put in ppRetString, 0 otherwise * * note: the string placed in ppRetString should be freed by the caller */ int get_field(smsg_t *const pMsg, const char *pFieldName, char **ppRetString) { DBGPRINTF("mmdarwin::get_field:: getting key '%s' in msg\n", pFieldName); struct json_object *pJson = NULL; char *pFieldString = NULL; int retVal = 0; msgPropDescr_t propDesc; msgPropDescrFill(&propDesc, (uchar *)pFieldName, strlen(pFieldName)); msgGetJSONPropJSONorString(pMsg, &propDesc, &pJson, (uchar **)&pFieldString); if (pFieldString) { *ppRetString = pFieldString; DBGPRINTF("mmdarwin::get_field:: got string\n"); retVal = 1; } else if (pJson) { pFieldString = (char *)json_object_get_string(pJson); if (pFieldString) { *ppRetString = strdup(pFieldString); retVal = 1; DBGPRINTF("mmdarwin::get_field:: got string from json\n"); json_object_put(pJson); } } msgPropDescrDestruct(&propDesc); return retVal; } /** * expands the buffer object in the dyn_buffer object * * params: * - pBody: a pointer to the concerned structure to expand * - new_size: the new size to give to the underlying buffer * * return: 0 if the expansion was successful, -1 otherwise */ int expand_buffer(dyn_buffer *pBody, size_t new_size) { /* return error if new_size tries to exceed max defined size */ if (new_size > pBody->bufferMaxSize) return -1; while (pBody->bufferAllocSize < new_size) pBody->bufferAllocSize += INITIAL_BUFFER_SIZE; DBGPRINTF("mmdarwin::expand_buffer:: expanding buffer to %zu\n", pBody->bufferAllocSize); char *tmp = realloc(pBody->buffer, pBody->bufferAllocSize * sizeof(char)); if (!tmp) { DBGPRINTF("mmdarwin::expand_buffer:: could not resize buffer\n"); return -1; } pBody->buffer = tmp; return 0; } /** * adds a field to the dyn_buffer buffer * * params: * - pBody: the pointer on the dyn_buffer structure * - field: the potentially not null-terminated string to add as a field to the dyn_buffer * - size: the size of the string (without the '\0' character) * * return: 0 if the field was indeed added to the dyn_buffer, -1 otherwise */ int add_field_to_body(dyn_buffer *pBody, const char *field, size_t size) { /* get required additional size for field, quotes, colon, and \0 and potentially also for the beginning of the message structure */ int beginning = (pBody->bufferMsgSize == 0) ? 2 : 0; size_t requiredBodySize = pBody->bufferMsgSize + size + 4 + beginning; /* resize body buffer if necessary */ if (requiredBodySize > pBody->bufferAllocSize) { if (expand_buffer(pBody, requiredBodySize) != 0) { return -1; } } /* add message structure beginning if current message is empty */ if (!pBody->bufferMsgSize) { pBody->buffer[0] = '['; pBody->buffer[1] = '['; pBody->bufferMsgSize += 2; } /* add field with quotes and colon */ pBody->buffer[pBody->bufferMsgSize++] = '\"'; memcpy((void *)&pBody->buffer[pBody->bufferMsgSize], (const void *)field, size); pBody->bufferMsgSize += size; pBody->buffer[pBody->bufferMsgSize++] = '\"'; pBody->buffer[pBody->bufferMsgSize++] = ','; return 0; } /** * small helper function to start a new input line (used for bulk-calls) in the dyn_buffer. * will close current line with a ']' and start the next with a '['. * will also remove leading ',' in fields list. * * params: * - pBody: the pointer on the dyn_buffer on which to start a new input line * * return: 0 if successful, -1 otherwise */ int start_new_line(dyn_buffer *pBody) { /* don't if the message is empty */ if (!pBody->bufferMsgSize) { return -1; } DBGPRINTF("mmdarwin::start_new_line:: starting new line entry in body\n"); if (pBody->bufferAllocSize < pBody->bufferMsgSize + 2) { if (expand_buffer(pBody, pBody->bufferAllocSize + 2) != 0) { return -1; } } pBody->buffer[pBody->bufferMsgSize - 1] = ']'; pBody->buffer[pBody->bufferMsgSize++] = ','; pBody->buffer[pBody->bufferMsgSize++] = '['; return 0; } /** * small helper function to close the dyn_buffer structure. * will close the line list with two ']' and will remove the leading ',' in the fields list * * params: * - pBody: the pointer on the dyn_buffer on which to start a new input line * * return: 0 if successful, -1 otherwise */ int end_body(dyn_buffer *pBody) { /* don't if the message is empty */ if (!pBody->bufferMsgSize) { return -1; } DBGPRINTF("mmdarwin::end_body:: finishing body structure\n"); if (pBody->bufferAllocSize < pBody->bufferMsgSize + 2) { if (expand_buffer(pBody, pBody->bufferAllocSize + 2) != 0) { return -1; } } pBody->buffer[pBody->bufferMsgSize - 1] = ']'; pBody->buffer[pBody->bufferMsgSize++] = ']'; pBody->buffer[pBody->bufferMsgSize++] = '\0'; return 0; } /** * Get the potential existing uuid put by previous mmdarwin call in a json * * params: * - pJson: the pointer on the json * * return: a valid json_object pointer if found, NULL otherwise */ const char *get_uuid_object(smsg_t *const pMsg) { struct json_object *mmdarwin_object = NULL; const char *result = NULL, *key = NULL; msgPropDescr_t propDesc; msgPropDescrFill(&propDesc, (uchar *)runModConf->container, strlen(runModConf->container)); msgGetJSONPropJSON(pMsg, &propDesc, &mmdarwin_object); if (mmdarwin_object) { struct json_object_iterator it = json_object_iter_begin(mmdarwin_object); struct json_object_iterator itEnd = json_object_iter_end(mmdarwin_object); while (!json_object_iter_equal(&it, &itEnd)) { key = json_object_iter_peek_name(&it); if (!strcmp(key, JSON_DARWIN_ID)) { // should always be a (non-empty) null-terminated string, safe to use with strdup() result = strdup(json_object_get_string(json_object_iter_peek_value(&it))); break; } json_object_iter_next(&it); } json_object_put(mmdarwin_object); } msgPropDescrDestruct(&propDesc); return result; } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free((void *)pModConf->container); ENDfreeCnf BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; DBGPRINTF("%s\n", pData->pSockName); ENDdbgPrintInstInfo BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; pWrkrData->pktSentSocket = 0; pWrkrData->darwinBody.bufferAllocSize = 0; pWrkrData->darwinBody.bufferMaxSize = BUFFER_DEFAULT_MAX_SIZE; pWrkrData->darwinBody.bufferMsgSize = 0; pWrkrData->sock = INVLD_SOCK; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; if (pData->fieldList.name != NULL) { for (int i = 0; i < pData->fieldList.nmemb; ++i) { free(pData->fieldList.name[i]); free(pData->fieldList.varname[i]); } free(pData->fieldList.name); free(pData->fieldList.varname); } free(pData->pUUIDKey); free(pData->pCertitudeKey); free(pData->pSockName); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; closeSocket(pWrkrData); free(pWrkrData->darwinBody.buffer); ENDfreeWrkrInstance BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; loadModConf->container = NULL; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "mmdarwin: error processing module config parameters missing [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { DBGPRINTF("mmdarwin::setModCnf:: module (global) param blk for mmdarwin:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "container")) { loadModConf->container = es_str2cstr(pvals[i].val.d.estr, NULL); if (loadModConf->container[0] != '!' && loadModConf->container[0] != '.') { LogError(0, RS_RET_INVALID_PARAMS, "mmdarwin: container should either" " begin with '!' or '.'\n"); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } } else { DBGPRINTF( "mmdarwin::setModCnf:: program error, non-handled " "param '%s'\n", modpblk.descr[i].name); } } if (loadModConf->container == NULL) { CHKmalloc(loadModConf->container = strdup(JSON_DEFAULT_CONTAINER)); } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf static inline void setInstParamDefaults(instanceData *pData) { DBGPRINTF("mmdarwin::setInstParamDefaults::\n"); pData->pUUIDKey = NULL; pData->pCertitudeKey = NULL; pData->pSockName = NULL; pData->fieldList.nmemb = 0; pData->filterCode = DARWIN_FILTER_CODE_NO; pData->response = DARWIN_RESPONSE_SEND_NO; pData->socketMaxUse = 0; pData->sendPartial = 0; } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; DBGPRINTF("mmdarwin::newActInst::\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "key")) { char *key = es_str2cstr(pvals[i].val.d.estr, NULL); char vnamebuf[1024]; snprintf(vnamebuf, sizeof(vnamebuf), "%s!%s", loadModConf->container, key); CHKmalloc(pData->pCertitudeKey = strdup(vnamebuf)); free(key); DBGPRINTF("mmdarwin::newActInst:: certitudeKey is %s\n", pData->pCertitudeKey); } else if (!strcmp(actpblk.descr[i].name, "socketpath")) { pData->pSockName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); DBGPRINTF("mmdarwin::newActInst:: sockName is %s\n", pData->pSockName); } else if (!strcmp(actpblk.descr[i].name, "socket_max_use")) { pData->socketMaxUse = (uint32_t)pvals[i].val.d.n; DBGPRINTF("mmdarwin::newActInst:: socketMaxUse is %d\n", pData->socketMaxUse); } else if (!strcmp(actpblk.descr[i].name, "send_partial")) { pData->sendPartial = (sbool)pvals[i].val.d.n; if (pData->sendPartial) { DBGPRINTF("mmdarwin::newActInst:: sending bodies even if fields are missing\n"); } else { DBGPRINTF("mmdarwin::newActInst:: only sending complete bodies\n"); } } else if (!strcmp(actpblk.descr[i].name, "response")) { char *response = es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcmp(response, "no")) { pData->response = DARWIN_RESPONSE_SEND_NO; DBGPRINTF("mmdarwin::newActInst:: response type is 'no'\n"); } else if (!strcmp(response, "back")) { pData->response = DARWIN_RESPONSE_SEND_BACK; DBGPRINTF("mmdarwin::newActInst:: response type is 'back'\n"); } else if (!strcmp(response, "darwin")) { pData->response = DARWIN_RESPONSE_SEND_DARWIN; DBGPRINTF("mmdarwin::newActInst:: response type is 'darwin'\n"); } else if (!strcmp(response, "both")) { pData->response = DARWIN_RESPONSE_SEND_BOTH; DBGPRINTF("mmdarwin::newActInst:: response type is 'both'\n"); } else { DBGPRINTF("mmdarwin::newActInst:: invalid 'response' value: %s. 'No response' set.\n", response); pData->response = DARWIN_RESPONSE_SEND_NO; DBGPRINTF("mmdarwin::newActInst:: response type is 'no'\n"); } free(response); } else if (!strcmp(actpblk.descr[i].name, "filtercode")) { char *filterCode = es_str2cstr(pvals[i].val.d.estr, NULL); pData->filterCode = strtoull(filterCode, NULL, 16); free(filterCode); } else if (!strcmp(actpblk.descr[i].name, "fields")) { pData->fieldList.nmemb = pvals[i].val.d.ar->nmemb; CHKmalloc(pData->fieldList.name = calloc(pData->fieldList.nmemb, sizeof(char *))); CHKmalloc(pData->fieldList.varname = calloc(pData->fieldList.nmemb, sizeof(char *))); for (int j = 0; j < pData->fieldList.nmemb; ++j) { char *const param = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); char *varname = NULL; char *name; if (*param == ':') { char *b = strchr(param + 1, ':'); if (b == NULL) { parser_errmsg("mmdarwin::newActInst:: missing closing colon: '%s'", param); ABORT_FINALIZE(RS_RET_ERR); } *b = '\0'; /* split name & varname */ varname = param + 1; name = b + 1; } else { name = param; } CHKmalloc(pData->fieldList.name[j] = strdup(name)); char vnamebuf[1024]; snprintf(vnamebuf, sizeof(vnamebuf), "%s!%s", loadModConf->container, (varname == NULL) ? name : varname); CHKmalloc(pData->fieldList.varname[j] = strdup(vnamebuf)); free(param); DBGPRINTF("mmdarwin::newActInst:: will look for field %s\n", pData->fieldList.name[j]); } } else { DBGPRINTF("mmdarwin::newActInst:: program error, non-handled param '%s'\n", actpblk.descr[i].name); } } // reserve space for 'container!key\0' size_t sizeKey = strlen(loadModConf->container) + strlen(JSON_DARWIN_ID) + 2; pData->pUUIDKey = malloc(sizeKey); snprintf(pData->pUUIDKey, sizeKey, "%s!%s", loadModConf->container, JSON_DARWIN_ID); DBGPRINTF("mmdarwin:: uuid key is %s\n", pData->pUUIDKey); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINtryResume CODESTARTtryResume; iRet = doTryResume(pWrkrData); ENDtryResume BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; /* the raw data */ smsg_t *pMsg = ppMsg[0]; /* the raw log line */ instanceData *pData = pWrkrData->pData; /* the parameters given for the plugin */ char *pFieldValue = NULL; /* ponter to the found field value */ int fieldsNum = 0; /* number of fields retrieved */ CODESTARTdoAction; DBGPRINTF("mmdarwin::doAction:: beggining action\n"); pWrkrData->darwinBody.bufferMsgSize = 0; fieldsNum = 0; for (int i = 0; i < pData->fieldList.nmemb; i++) { DBGPRINTF("mmdarwin::doAction:: processing field '%s'\n", pData->fieldList.name[i]); pFieldValue = NULL; /* case 1: static field. We simply forward it to Darwin */ if (pData->fieldList.name[i][0] != '!' && pData->fieldList.name[i][0] != '.') { pFieldValue = strdup(pData->fieldList.name[i]); } /* case 2: dynamic field. We retrieve its value from the JSON logline and forward it to * Darwin */ else { if (!get_field(pMsg, pData->fieldList.name[i], &pFieldValue)) { DBGPRINTF( "mmdarwin::doAction:: \ could not extract field '%s' from message\n", pData->fieldList.name[i]); continue; } } DBGPRINTF("mmdarwin::doAction:: got value of field '%s': '%s'\n", pData->fieldList.name[i], pFieldValue); if (add_field_to_body(&(pWrkrData->darwinBody), pFieldValue, strlen(pFieldValue)) != 0) { DBGPRINTF("mmdarwin::doAction:: could not add field to body, aborting\n"); free(pFieldValue); ABORT_FINALIZE(RS_RET_ERR); } fieldsNum++; free(pFieldValue); } if (fieldsNum) { if (!pData->sendPartial && fieldsNum != pData->fieldList.nmemb) { DBGPRINTF( "mmdarwin::doAction:: not all fields could be retrieved, not sending partial message." " (if you wish to send partial messages anyway, set 'send_partial' to 'on' in instance parameters)\n"); FINALIZE; } if (end_body(&(pWrkrData->darwinBody)) != 0) ABORT_FINALIZE(RS_RET_ERR); } else { DBGPRINTF("mmdarwin::doAction:: no fields retrieved, finalizing\n"); FINALIZE; } DBGPRINTF("mmdarwin::doAction:: body to send: '%s'\n", pWrkrData->darwinBody.buffer); if (pData->socketMaxUse) { /* need to rotate socket connections */ if (!pWrkrData->pktSentSocket) { DBGPRINTF("mmdarwin::doAction:: opening a new connection\n"); CHKiRet(doTryResume(pWrkrData)); } pWrkrData->pktSentSocket = (pWrkrData->pktSentSocket + 1) % pData->socketMaxUse; } /* the Darwin header to be sent to the filter */ darwin_filter_packet_t header = {.type = DARWIN_PACKET_OTHER, .response = pData->response, .filter_code = pData->filterCode, .body_size = pWrkrData->darwinBody.bufferMsgSize}; const char *uuid = get_uuid_object(pMsg); if (uuid) { DBGPRINTF("mmdarwin: using existing UUID = %s\n", uuid); if (uuid_parse(uuid, header.evt_id)) LogError(0, RS_RET_ERR, "mmdarwin:: failed to parse existing UUID: %s\n", uuid); free((void *)uuid); } else { uuid_generate(header.evt_id); char uuidStr[40]; uuid_unparse(header.evt_id, uuidStr); DBGPRINTF("mmdarwin: generated new UUID = %s\n", uuidStr); msgAddJSON(pMsg, (uchar *)pData->pUUIDKey, json_object_new_string(uuidStr), 0, 0); } DBGPRINTF("mmdarwin::doAction:: sending header to Darwin\n"); CHKiRet(sendMsg(pWrkrData, &header, sizeof(darwin_filter_packet_t))); DBGPRINTF("mmdarwin::doAction:: sending body to Darwin\n"); CHKiRet(sendMsg(pWrkrData, (void *)(pWrkrData->darwinBody.buffer), pWrkrData->darwinBody.bufferMsgSize)); /* there is no need to wait for a response that will never come */ if (pData->response == DARWIN_RESPONSE_SEND_NO || pData->response == DARWIN_RESPONSE_SEND_DARWIN) { DBGPRINTF( "mmdarwin::doAction:: no response will be sent back " "(darwin response type is set to 'no' or 'darwin')\n"); goto finalize_it; } darwin_filter_packet_t response; memset(&response, 0, sizeof(response)); DBGPRINTF("mmdarwin::doAction:: receiving from Darwin\n"); CHKiRet(receiveMsg(pWrkrData, &response, sizeof(response))); unsigned int certitude = response.certitude_list[0]; DBGPRINTF("mmdarwin::doAction:: end of the transaction, certitude is %d\n", certitude); msgAddJSON(pMsg, (uchar *)pData->pCertitudeKey, json_object_new_int(certitude), 0, 0); finalize_it: DBGPRINTF("mmdarwin::doAction:: finished processing log line\n"); ENDdoAction NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; objRelease(glbl, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; /* we only support the current interface specification */ *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmdarwin::modInit:: module compiled with rsyslog version %s.\n", VERSION); CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/mmdarwin/PaxHeaders/protocol.h0000644000000000000000000000013215055605325020027 xustar0030 mtime=1756826325.612800125 30 atime=1764931096.754602402 30 ctime=1764935930.176683636 rsyslog-8.2512.0/contrib/mmdarwin/protocol.h0000664000175000017500000000452515055605325017501 0ustar00rgerrger/* Copyright 2019 Advens * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef DARWIN_PROTOCOL_H #define DARWIN_PROTOCOL_H #ifdef __cplusplus extern "C" { #endif #include #include #define DARWIN_FILTER_CODE_NO 0x00000000 // the default certitude list size, which is 1, to allow FMAs (see flexible array members on C99) for both C and C++ // code #define DEFAULT_CERTITUDE_LIST_SIZE 1 /// Represent the receiver of the results. /// /// \enum darwin_response_type enum darwin_filter_response_type { DARWIN_RESPONSE_SEND_NO = 0, //!< Don't send results to anybody. DARWIN_RESPONSE_SEND_BACK, //!< Send results back to caller. DARWIN_RESPONSE_SEND_DARWIN, //!< Send results to the next filter. DARWIN_RESPONSE_SEND_BOTH, //!< Send results to both caller and the next filter. }; /// Represent the type of information sent. /// /// \enum darwin_packet_type enum darwin_packet_type { DARWIN_PACKET_OTHER = 0, //!< Information sent by something else. DARWIN_PACKET_FILTER, //!< Information sent by another filter. }; /// First packet to be sent to a filter. /// /// \struct darwin_filter_packet_t typedef struct { enum darwin_packet_type type; //!< The type of information sent. enum darwin_filter_response_type response; //!< Whom the response will be sent to. long filter_code; //!< The unique identifier code of a filter. size_t body_size; //!< The complete size of the the parameters to be sent unsigned char evt_id[16]; //!< An array containing the event ID size_t certitude_size; //!< The size of the list containing the certitudes. unsigned int certitude_list[DEFAULT_CERTITUDE_LIST_SIZE]; //!< The scores or the certitudes of the module. May be used to pass other info in specific cases. } darwin_filter_packet_t; #ifdef __cplusplus }; #endif #endif /* !DARWIN_PROTOCOL_H */ rsyslog-8.2512.0/contrib/mmdarwin/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315020057 xustar0030 mtime=1764935885.969006674 30 atime=1764935896.085161627 30 ctime=1764935930.172683575 rsyslog-8.2512.0/contrib/mmdarwin/Makefile.in0000664000175000017500000006325415114544315017535 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmdarwin ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) mmdarwin_la_DEPENDENCIES = am_mmdarwin_la_OBJECTS = mmdarwin_la-mmdarwin.lo mmdarwin_la_OBJECTS = $(am_mmdarwin_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmdarwin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(mmdarwin_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmdarwin_la_SOURCES) DIST_SOURCES = $(mmdarwin_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmdarwin.la mmdarwin_la_SOURCES = mmdarwin.c protocol.h mmdarwin_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmdarwin_la_LDFLAGS = -module -avoid-version mmdarwin_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmdarwin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmdarwin/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmdarwin.la: $(mmdarwin_la_OBJECTS) $(mmdarwin_la_DEPENDENCIES) $(EXTRA_mmdarwin_la_DEPENDENCIES) $(AM_V_CCLD)$(mmdarwin_la_LINK) -rpath $(pkglibdir) $(mmdarwin_la_OBJECTS) $(mmdarwin_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmdarwin_la-mmdarwin.lo: mmdarwin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmdarwin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmdarwin_la-mmdarwin.lo -MD -MP -MF $(DEPDIR)/mmdarwin_la-mmdarwin.Tpo -c -o mmdarwin_la-mmdarwin.lo `test -f 'mmdarwin.c' || echo '$(srcdir)/'`mmdarwin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmdarwin_la-mmdarwin.Tpo $(DEPDIR)/mmdarwin_la-mmdarwin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmdarwin.c' object='mmdarwin_la-mmdarwin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmdarwin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmdarwin_la-mmdarwin.lo `test -f 'mmdarwin.c' || echo '$(srcdir)/'`mmdarwin.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmdarwin_la-mmdarwin.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/imbatchreport0000644000000000000000000000013215114544372016765 xustar0030 mtime=1764935930.918694994 30 atime=1764935934.366747775 30 ctime=1764935930.918694994 rsyslog-8.2512.0/contrib/imbatchreport/0000775000175000017500000000000015114544372016506 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imbatchreport/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264021072 xustar0030 mtime=1752569012.326271887 30 atime=1764930927.453792512 30 ctime=1764935930.913694918 rsyslog-8.2512.0/contrib/imbatchreport/Makefile.am0000664000175000017500000000035515035412264020541 0ustar00rgerrgerpkglib_LTLIBRARIES = imbatchreport.la imbatchreport_la_SOURCES = imbatchreport.c imbatchreport_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imbatchreport_la_LDFLAGS = -module -avoid-version imbatchreport_la_LIBADD = rsyslog-8.2512.0/contrib/imbatchreport/PaxHeaders/imbatchreport.c0000644000000000000000000000013215055605325022051 xustar0030 mtime=1756826325.610800095 30 atime=1764931104.595729773 30 ctime=1764935930.918694994 rsyslog-8.2512.0/contrib/imbatchreport/imbatchreport.c0000664000175000017500000010142215055605325021515 0ustar00rgerrger/* imbatchreport.c * * This is the input module for reading full text file data. A text file is a * non-binary file who's lines are delimited by the \n character. The file is * treated as a single message. An optional structured data can be written at * the end of the file. * * No state file are used as it should only grow with time. Instead the state * is managed using the name of the file. A "glob" allows the module to identify * "to be treated" files. The module can be configured either to deleted the * the file on success either to rename the file on success. The size limit is * fixed by rsyslog max message size global parameter. All files larger than this * limit produce a message which references it as "too large" and its new location * The "too large" files are also renamed to keep them available. * * This modules allows one to centralize batch reports with other standard logs and * performance monitoring in a single repository (ElasticSearch, HDFS, ...). This * centralization helps to identify cause of global performance issues. * * Work originally begun on 2014-07-01 by Philippe Duveau @ Pari Mutuel Urbain * * This file is contribution of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include /* do NOT remove: will soon be done by the module generation macros */ #include #include #include #include #ifdef HAVE_SYS_STAT_H #include #endif #include "rsyslog.h" /* error codes etc... */ #include "dirty.h" #include "cfsysline.h" /* access to config file objects */ #include "module-template.h" #include "srUtils.h" /* some utility functions */ #include "msg.h" #include "errmsg.h" #include "glbl.h" #include "datetime.h" #include "unicode-helper.h" #include "prop.h" #include "stringbuf.h" #include "ruleset.h" #include "ratelimit.h" #include MODULE_TYPE_INPUT /* must be present for input modules, do not remove */ MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imbatchreport") /* defines for freebsd */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif /* Module static data */ DEF_IMOD_STATIC_DATA /* must be present, starts static data */ DEFobjCurrIf(glbl) DEFobjCurrIf(ruleset) DEFobjCurrIf(datetime) DEFobjCurrIf(prop) #define SRUCTDATA_BUFFER_LEN 150 #define READ_BUFFER_LEN 512 #define FILE_TOO_LARGE "File too large : " #define FILE_TOO_LARGE_LEN sizeof(FILE_TOO_LARGE) - 1 #define DFLT_PollInterval 10 #define ADD_METADATA_UNSPECIFIED -1 typedef enum action_batchreport_t { action_nothing, action_rename, action_delete } action_batchreport_t; struct instanceConf_s { uchar *pszFollow_glob; uchar *pszDirName; uchar *pszFileBaseName; uchar *pszTag; int lenTag; uchar *pszTSk; int lenTSk; uchar *pszProgk; int lenProgk; int must_stop; uchar *pszBindRuleset; int bDedupSpace; int iFacility; int iSeverity; char *ff_regex; /* Full treatment : this should contain a regex applied on filename. The matching part is then replaced with ff_replace to put the file out of scan criteria */ regex_t ff_preg; char *ff_rename; int len_rename; char *ff_reject; int len_reject; int filename_oversize; ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ ratelimit_t *ratelimiter; struct instanceConf_s *next; action_batchreport_t action; char *pszNewFName; int fd; sbool goon; }; /* global configuration variables */ static struct { uchar *hostname; size_t lhostname; char *msg_buffer; size_t max_msg_size; instanceConf_t *root; /* number of seconds to sleep when there was no file activity */ int iPollInterval; } fixedModConf; /* config variables */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this input */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"pollinginterval", eCmdHdlrPositiveInt, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* input instance parameters */ static struct cnfparamdescr inppdescr[] = { {"reports", eCmdHdlrString, CNFPARAM_REQUIRED}, {"tag", eCmdHdlrString, CNFPARAM_REQUIRED}, {"programkey", eCmdHdlrString, 0}, {"timestampkey", eCmdHdlrString, 0}, {"deduplicatespace", eCmdHdlrBinary, 0}, {"rename", eCmdHdlrString, 0}, {"delete", eCmdHdlrString, 0}, {"severity", eCmdHdlrSeverity, 0}, {"facility", eCmdHdlrFacility, 0}, {"ruleset", eCmdHdlrString, 0}, }; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; #include "im-helper.h" /* must be included AFTER the type definitions! */ /* enqueue the read file line as a message. The provided string is * not freed - thuis must be done by the caller. */ static rsRetVal enqMsg(instanceConf_t *pInst, smsg_t *pMsg) { DEFiRet; MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY); MsgSetInputName(pMsg, pInputName); MsgSetHOSTNAME(pMsg, fixedModConf.hostname, (const int)fixedModConf.lhostname); MsgSetTAG(pMsg, pInst->pszTag, pInst->lenTag); MsgSetPROCID(pMsg, "-"); MsgSetMSGID(pMsg, "-"); pMsg->iFacility = pInst->iFacility >> 3; pMsg->iSeverity = pInst->iSeverity; MsgSetRuleset(pMsg, pInst->pBindRuleset); CHKiRet(ratelimitAddMsg(pInst->ratelimiter, NULL, pMsg)); finalize_it: RETiRet; } /* The following is a cancel cleanup handler for strmReadLine(). It is necessary in case * strmReadLine() is cancelled while processing the stream. -- rgerhards, 2008-03-27 */ static void pollFileCancelCleanup(void *pArg) { instanceConf_t *ppInst = (instanceConf_t *)pArg; if (ppInst->fd > 0) close(ppInst->fd); if (ppInst->pszNewFName) free(ppInst->pszNewFName); } /* readAndSendFile try to read the file and send the message. * @param pInst point to instance * @param filename the file name * @param fstate the file stat */ static rsRetVal readAndSendFile(instanceConf_t *pInst, char *filename, char *fpath, struct stat *fstat) { smsg_t *pMsg = NULL; size_t file_len, read_len = 0, sd_buf_l, msg_len = 0, idx = 0; int last_is_space = 0; struct timeval tvm; uchar sd_buffer[SRUCTDATA_BUFFER_LEN]; uchar read_buffer[READ_BUFFER_LEN]; DEFiRet; CHKiRet(msgConstruct(&pMsg)); msgAddMetadata(pMsg, (uchar *)"filename", (uchar *)filename); /* get the file modification time : end of the batch*/ tvm.tv_sec = fstat->st_mtime; tvm.tv_usec = 0; file_len = lseek(pInst->fd, 0, SEEK_END); MsgSetStructuredData(pMsg, "-"); /* Let's read the end of the file first and put it in the buffer for structuredData * This will help to find the real end of the message */ sd_buf_l = (file_len < SRUCTDATA_BUFFER_LEN) ? file_len : SRUCTDATA_BUFFER_LEN; if (lseek(pInst->fd, file_len - sd_buf_l, SEEK_SET) >= 0) { uchar *sdp = sd_buffer + sd_buf_l - 1; int nb_rm = 0; /* number of space chars removed */ size_t stdata_len = 0, t; char *tmp; if ((t = read(pInst->fd, sd_buffer, sd_buf_l)) != sd_buf_l) { LogError(0, RS_RET_READ_ERR, "read end of file for structured data failed (%zu / %zu)", t, sd_buf_l); return RS_RET_READ_ERR; } /* let's trim the end */ for (; sdp > sd_buffer && (*sdp == '\n' || *sdp == '\t' || *sdp == ' '); sdp--, sd_buf_l--) file_len--; if (sd_buf_l > 1 && *sdp == ']') { stdata_len = 1; /* it seems that we have structured data let find the begin */ for (; sdp > sd_buffer && *sdp != '['; sdp--, stdata_len++) { if (*sdp == '\n') { /* line feed not supported in structured data */ stdata_len--; memmove(sdp, sdp + 1, stdata_len); nb_rm++; } } if (*sdp == '[') { /* we got a structured data */ DBGPRINTF("structured data : %.*s\n", (int)stdata_len, sdp); MsgAddToStructuredData(pMsg, sdp, stdata_len); /* extracting timestamp from structured data overwrite the file creation time */ if (pInst->pszTSk) { uchar *field = (uchar *)strstr((char *)sdp, (char *)pInst->pszTSk), v; if (field != NULL) { tvm.tv_sec = 0; tvm.tv_usec = 0; for (field += pInst->lenTSk; (v = *field ^ 0x30) <= 9; field++) tvm.tv_sec = tvm.tv_sec * 10 + v; } } /* extracting program from structured data */ if (pInst->pszProgk) { char *field = strstr((char *)sdp, (char *)pInst->pszProgk); if (field != NULL) { tmp = field + pInst->lenProgk; if ((field = strchr(tmp, '\"')) != NULL) { *field = '\0'; MsgSetAPPNAME(pMsg, tmp); } } } /* let's trim until useful message end */ for (sdp--; sdp > sd_buffer && (*sdp == '\n' || *sdp == '\t' || *sdp == ' '); sdp--) nb_rm++; } } /* computing the new file_len */ file_len -= nb_rm + stdata_len; } datetime.timeval2syslogTime(&tvm, &pMsg->tTIMESTAMP, TIME_IN_UTC); pMsg->ttGenTime = tvm.tv_sec; /* go back to beginning */ if (lseek(pInst->fd, 0, SEEK_SET) < 0) { LogError(0, RS_RET_READ_ERR, "readAndSendFile : error while seeking to beginning."); return RS_RET_READ_ERR; } /* Now read the file */ msg_len = 0; while (msg_len < fixedModConf.max_msg_size && (read_len = read(pInst->fd, read_buffer, (file_len > READ_BUFFER_LEN) ? READ_BUFFER_LEN : file_len)) > 0) { file_len -= read_len; idx = 0; while (read_len > 0 && msg_len < fixedModConf.max_msg_size) { switch (read_buffer[idx]) { case '\t': case ' ': /* this is to reduce consecutive spaces to only one */ if (!last_is_space) fixedModConf.msg_buffer[msg_len++] = ' '; /* if pInst->bDedupSpace is off last_is_space will never be true */ last_is_space = pInst->bDedupSpace; break; case '\n': /* this is for trailing spaces */ if (last_is_space) msg_len--; fixedModConf.msg_buffer[msg_len++] = '\\'; /* risk of overflow is managed by making buffer one char longer * than fixedModConf.max_msg_size */ fixedModConf.msg_buffer[msg_len++] = 'n'; break; default: fixedModConf.msg_buffer[msg_len++] = read_buffer[idx]; last_is_space = 0; } idx++; read_len--; } } close(pInst->fd); pInst->fd = 0; if (file_len > 0 || read_len > 0) { /* file is too large to be stored in one message */ memcpy(fixedModConf.msg_buffer, FILE_TOO_LARGE, FILE_TOO_LARGE_LEN); msg_len = strlen(fpath); memcpy(fixedModConf.msg_buffer + FILE_TOO_LARGE_LEN, fpath, msg_len); msg_len += FILE_TOO_LARGE_LEN; } /* file is stored in the message */ MsgSetRawMsg(pMsg, fixedModConf.msg_buffer, msg_len); MsgSetMSGoffs(pMsg, 0); if ((iRet = enqMsg(pInst, pMsg)) == RS_RET_OK && (file_len > 0 || read_len > 0)) iRet = RS_RET_FILE_TOO_LARGE; finalize_it: RETiRet; } /* poll a glob */ static void pollFile(instanceConf_t *pInst) { pInst->fd = 0; glob_t glob_res; pthread_cleanup_push(pollFileCancelCleanup, pInst); DBGPRINTF("polling files : %s\n", pInst->pszFollow_glob); /* We "glob" to find candidate regular file (or other) */ if (glob((char *)pInst->pszFollow_glob, GLOB_NOSORT, 0, &glob_res) != 0) FINALIZE; for (size_t i = 0; i < glob_res.gl_pathc && glbl.GetGlobalInputTermState() == 0; i++) { struct stat fstat; rsRetVal ret; char *filename = strrchr(glob_res.gl_pathv[i], '/'); if (filename) filename++; else filename = glob_res.gl_pathv[i]; char *fpath = glob_res.gl_pathv[i]; /* let's verify that the file is a regular one */ if (!stat(fpath, &fstat) && S_ISREG(fstat.st_mode)) { regmatch_t matches[1]; int toolargeOrFailure = 0; DBGPRINTF("Regular file found '%s')\n", fpath); /* With this test we verify that we have conditions to remove the * file from glob scope. If the regular expression not apply we * can not rename it */ if (regexec(&pInst->ff_preg, fpath, 1, matches, 0)) { pInst->must_stop = 1; FINALIZE; } pInst->fd = open(fpath, O_NOCTTY | O_RDONLY | O_NONBLOCK | O_LARGEFILE, 0); if (pInst->fd <= 0) { /* file could be open unfortunately we will try each polling */ char errStr[512]; int eno = errno; rs_strerror_r(eno, errStr, sizeof(errStr)); LogError(0, RS_RET_READ_ERR, "open the file %s failed with error %s", fpath, errStr); continue; } /* let's read the file and send it to output */ ret = readAndSendFile(pInst, filename, fpath, &fstat); /* is the file to large to be sent */ toolargeOrFailure = ret == RS_RET_FILE_TOO_LARGE; if (ret != RS_RET_OK && ret != RS_RET_FILE_TOO_LARGE) { LogError(0, ret, "The module could not manage the file %s", fpath); toolargeOrFailure = 1; } if (pInst->action == action_rename || toolargeOrFailure) { pInst->pszNewFName = (char *)malloc(strlen(fpath) + pInst->filename_oversize); memcpy(pInst->pszNewFName, fpath, matches[0].rm_so); strcpy((char *)pInst->pszNewFName + matches[0].rm_so, (toolargeOrFailure) ? pInst->ff_reject : pInst->ff_rename); if (rename(fpath, pInst->pszNewFName)) { /* if the module can not rename the file, it must stop to avoid flooding * but it keep chance to manage max files as possible */ LogError(0, RS_RET_STREAM_DISABLED, "module stopped : was unable" " to rename form %s to %s.", fpath, pInst->pszNewFName); pInst->must_stop = 1; } else DBGPRINTF("file %s sent and renamed to %s.\n", fpath, pInst->pszNewFName); free(pInst->pszNewFName); pInst->pszNewFName = NULL; } else { if (unlink(fpath)) { /* if the module can not remove the file, it must stop to avoid flooding * but it keep chance to manage max files as possible */ LogError(0, RS_RET_STREAM_DISABLED, "module stopped : unable to delete %s.", fpath); pInst->must_stop = 1; } else DBGPRINTF("file %s sent and deleted\n", fpath); } } /* if stat */ } /* for */ finalize_it: globfree(&glob_res); pthread_cleanup_pop(0); } static void addInstance(instanceConf_t *inst) { if (fixedModConf.root == NULL) { fixedModConf.root = inst; } else { fixedModConf.root->next = inst; fixedModConf.root = inst; } } /* create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal createInstance(instanceConf_t **pinst) { instanceConf_t *inst; DEFiRet; *pinst = NULL; CHKmalloc(inst = (instanceConf_t *)malloc(sizeof(instanceConf_t))); inst->next = NULL; inst->pBindRuleset = NULL; inst->pszBindRuleset = NULL; inst->pszFollow_glob = NULL; inst->pszDirName = NULL; inst->pszFileBaseName = NULL; inst->pszTag = NULL; inst->pszTSk = NULL; inst->pszProgk = NULL; inst->ff_regex = NULL; inst->ff_rename = NULL; inst->ff_reject = NULL; inst->iSeverity = LOG_NOTICE; inst->iFacility = LOG_LOCAL0; inst->len_rename = 0; inst->len_reject = 0; inst->bDedupSpace = 1; inst->goon = 0; inst->ratelimiter = NULL; inst->action = action_nothing; inst->must_stop = 0; *pinst = inst; finalize_it: RETiRet; } /* the basen(ame) buffer must be of size MAXFNAME * returns the index of the slash in front of basename */ static int getBasename(uchar *const __restrict__ basen, uchar *const __restrict__ path) { int i; const int lenName = ustrlen(path); for (i = lenName; i >= 0; --i) { if (path[i] == '/') { if (i == lenName) basen[0] = '\0'; else { memcpy(basen, path + i + 1, lenName - i); } break; } } if (i == -1) { memcpy(basen, path, lenName); i = 0; } return i; } /* this function checks instance parameters and does some required pre-processing * (e.g. split filename in path and actual name) * Note: we do NOT use dirname()/basename() as they have portability problems. */ static rsRetVal checkInstance(instanceConf_t *inst) { char dirn[MAXFNAME]; uchar basen[MAXFNAME]; int i; struct stat sb; int r; int eno; char errStr[512], *s, *d; regmatch_t matches[1]; DEFiRet; i = getBasename(basen, inst->pszFollow_glob); memcpy(dirn, inst->pszFollow_glob, i); dirn[i] = '\0'; CHKmalloc(inst->pszFileBaseName = (uchar *)strdup((char *)basen)); CHKmalloc(inst->pszDirName = (uchar *)strdup(dirn)); if (dirn[0] == '\0') { dirn[0] = '.'; dirn[1] = '\0'; } r = stat(dirn, &sb); if (r != 0) { eno = errno; rs_strerror_r(eno, errStr, sizeof(errStr)); LogError(0, RS_RET_CONFIG_ERROR, "Configured directory can not be stated '%s': %s", dirn, errStr); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (!S_ISDIR(sb.st_mode)) { LogError(0, RS_RET_CONFIG_ERROR, "Configured directory is NOT a directory : '%s'", dirn); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (stat((char *)inst->pszFollow_glob, &sb) == 0 && !S_ISREG(sb.st_mode)) { LogError(0, RS_RET_CONFIG_ERROR, "Configured report is not a glob or a regular file."); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } for (s = (char *)inst->pszFollow_glob, d = dirn; *s; s++, d++) *d = (*s != '*' && *s != '?') ? *s : '~'; *d = '\0'; if (regexec(&inst->ff_preg, dirn, 1, matches, 0)) { LogError(0, RS_RET_CONFIG_ERROR, "Regex does not match globed filenames: Instance ignored to avoid loops."); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (inst->action == action_rename) { strcpy(dirn + matches[0].rm_so, inst->ff_rename); if (fnmatch((char *)inst->pszFollow_glob, dirn, FNM_PATHNAME) == 0) { LogError(0, RS_RET_INVALID_PARAMS, "Normal renaming leaves files in glob scope: Instance ignored to avoid loops."); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } strcpy(dirn + matches[0].rm_so, inst->ff_reject); if (fnmatch((char *)inst->pszFollow_glob, dirn, FNM_PATHNAME) == 0) { LogError(0, RS_RET_INVALID_PARAMS, "Reject renaming leaves files in glob scope: Instance ignored to avoid loops."); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } dbgprintf("instance checked"); finalize_it: RETiRet; } static void freeInstance(instanceConf_t *inst) { if (inst == NULL) return; if (inst->pszBindRuleset) free(inst->pszBindRuleset); if (inst->pszFollow_glob) free(inst->pszFollow_glob); if (inst->pszDirName) free(inst->pszDirName); if (inst->pszFileBaseName) free(inst->pszFileBaseName); if (inst->pszTag) free(inst->pszTag); if (inst->pszTSk) free(inst->pszTSk); if (inst->pszProgk) free(inst->pszProgk); if (inst->len_reject) regfree(&inst->ff_preg); if (inst->ff_regex) free(inst->ff_regex); if (inst->ff_rename) free(inst->ff_rename); if (inst->ff_reject) free(inst->ff_reject); if (inst->ratelimiter) ratelimitDestruct(inst->ratelimiter); free(inst); } BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst = NULL; int i; char *temp; CODESTARTnewInpInst; DBGPRINTF("newInpInst (imbatchreport)\n"); pvals = nvlstGetParams(lst, &inppblk, NULL); if (pvals == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } DBGPRINTF("input param blk in imbatchreport:\n"); if (Debug) cnfparamsPrint(&inppblk, pvals); CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "reports")) { inst->pszFollow_glob = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "tag")) { inst->pszTag = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); inst->lenTag = ustrlen(inst->pszTag); } else if (!strcmp(inppblk.descr[i].name, "programkey")) { inst->pszProgk = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); inst->lenProgk = ustrlen(inst->pszProgk) + 2; } else if (!strcmp(inppblk.descr[i].name, "timestampkey")) { inst->pszTSk = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); inst->lenTSk = ustrlen(inst->pszTSk) + 1; } else if (!strcmp(inppblk.descr[i].name, "deduplicatespace")) { inst->bDedupSpace = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "severity")) { inst->iSeverity = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "facility")) { inst->iFacility = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "rename")) { if (inst->action == action_delete) { LogError(0, RS_RET_PARAM_ERROR, "'rename' and 'delete' are exclusive !"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } inst->ff_regex = es_str2cstr(pvals[i].val.d.estr, NULL); while ((temp = strchr(inst->ff_regex, '\t')) != NULL) *temp = ' '; inst->len_reject = 0; if ((inst->ff_rename = strchr(inst->ff_regex, ' ')) != NULL) { *inst->ff_rename++ = '\0'; while (*inst->ff_rename == ' ') inst->ff_rename++; if ((inst->ff_reject = strchr(inst->ff_rename, ' ')) != NULL) { *inst->ff_reject++ = '\0'; while (*inst->ff_reject == ' ') inst->ff_reject++; temp = strchr(inst->ff_reject, ' '); if (temp) *temp = '\0'; if (strcmp(inst->ff_rename, "-")) { inst->ff_rename = strdup(inst->ff_rename); inst->len_rename = strlen(inst->ff_rename); } else { inst->ff_rename = strdup(""); inst->len_rename = 0; } inst->ff_reject = strdup(inst->ff_reject); inst->len_reject = strlen(inst->ff_reject); if (inst->len_reject && regcomp(&inst->ff_preg, (char *)inst->ff_regex, REG_EXTENDED)) { inst->len_reject = 0; LogError(0, RS_RET_SYNTAX_ERROR, "The first part of 'rename' " "parameter does not contain a valid regex"); ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); } } } if (inst->len_reject == 0) { LogError(0, RS_RET_PARAM_ERROR, "'rename' must specify THREE " "parameters separated by spaces or tabs ! The second " "parameter can be a null string to get this use a '-'."); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } inst->action = action_rename; } else if (!strcmp(inppblk.descr[i].name, "delete")) { if (inst->action == action_rename) { LogError(0, RS_RET_PARAM_ERROR, "'rename' and 'delete' are exclusive !"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } inst->ff_regex = es_str2cstr(pvals[i].val.d.estr, NULL); while ((temp = strchr(inst->ff_regex, '\t')) != NULL) *temp = ' '; inst->len_reject = 0; if ((inst->ff_reject = strchr(inst->ff_regex, ' ')) != NULL) { *inst->ff_reject++ = '\0'; while (*inst->ff_reject == ' ') inst->ff_reject++; temp = strchr(inst->ff_reject, ' '); if (temp) *temp = '\0'; inst->ff_reject = strdup(inst->ff_reject); inst->len_reject = strlen(inst->ff_reject); if (regcomp(&inst->ff_preg, (char *)inst->ff_regex, REG_EXTENDED)) { inst->len_reject = 0; LogError(0, RS_RET_SYNTAX_ERROR, "The first part of 'delete' parameter does not contain a valid regex"); ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); } } if (inst->len_reject == 0) { LogError(0, RS_RET_PARAM_ERROR, "'delete' must specify TWO parameters separated by spaces or tabs !"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } inst->action = action_delete; } else { dbgprintf("Configuration param '%s' non-handled\n", inppblk.descr[i].name); } } if (inst->action == action_nothing) { LogError(0, RS_RET_PARAM_NOT_PERMITTED, "either 'rename' or 'delete' must be set"); ABORT_FINALIZE(RS_RET_PARAM_NOT_PERMITTED); } inst->filename_oversize = (inst->len_rename > inst->len_reject) ? inst->len_rename : inst->len_reject; CHKiRet(ratelimitNew(&inst->ratelimiter, "imbatchreport", (char *)inst->pszFollow_glob)); inst->goon = 1; CHKiRet(checkInstance(inst)); finalize_it: CODE_STD_FINALIZERnewInpInst if (iRet == RS_RET_OK) addInstance(inst); else freeInstance(inst); cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINbeginCnfLoad CODESTARTbeginCnfLoad; pModConf->pConf = pConf; fixedModConf.iPollInterval = DFLT_PollInterval; fixedModConf.msg_buffer = NULL; fixedModConf.root = NULL; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for imbatchreport:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "pollinginterval")) { fixedModConf.iPollInterval = (int)pvals[i].val.d.n; } else { dbgprintf( "program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; dbgprintf("polling interval is %d\n", fixedModConf.iPollInterval); ENDendCnfLoad BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = fixedModConf.root; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); } if (fixedModConf.root == NULL) { LogError(0, RS_RET_NO_LISTNERS, "no files configured to be monitored - no input will be gathered"); iRet = RS_RET_NO_LISTNERS; } ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf; for (inst = fixedModConf.root; inst != NULL;) { del = inst; inst = inst->next; freeInstance(del); } ENDfreeCnf BEGINwillRun CODESTARTwillRun; CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imbatchreport"), sizeof("imbatchreport") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); fixedModConf.max_msg_size = glbl.GetMaxLine(runConf); DBGPRINTF("Max message len %zu\n", fixedModConf.max_msg_size); CHKmalloc(fixedModConf.msg_buffer = (char *)malloc(fixedModConf.max_msg_size + 1)); finalize_it: ENDwillRun BEGINrunInput CODESTARTrunInput; fixedModConf.hostname = glbl.GetLocalHostName(); fixedModConf.lhostname = ustrlen(fixedModConf.hostname); while (glbl.GetGlobalInputTermState() == 0) { instanceConf_t *pInst; for (pInst = fixedModConf.root; pInst != NULL; pInst = pInst->next) { if (pInst->goon) { if (glbl.GetGlobalInputTermState() == 1) break; pollFile(pInst); /* We got a major problem so */ pInst->goon = !pInst->must_stop; } } if (glbl.GetGlobalInputTermState() == 0) srSleep(fixedModConf.iPollInterval, 10); } DBGPRINTF("terminating upon request of rsyslog core\n"); RETiRet; ENDrunInput /* This function is called by the framework after runInput() has been terminated. It * shall free any resources and prepare the module for unload. */ BEGINafterRun CODESTARTafterRun; if (fixedModConf.msg_buffer) free(fixedModConf.msg_buffer); if (pInputName != NULL) prop.Destruct(&pInputName); ENDafterRun BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) iRet = RS_RET_OK; ENDisCompatibleWithFeature /* The following entry points are defined in module-template.h. * In general, they need to be present, but you do NOT need to provide * any code here. */ BEGINmodExit CODESTARTmodExit; objRelease(datetime, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt /* modInit() is called once the module is loaded. It must perform all module-wide * initialization tasks. There are also a number of housekeeping tasks that the * framework requires. These are handled by the macros. Please note that the * complexity of processing is depending on the actual module. However, only * thing absolutely necessary should be done here. Actual app-level processing * is to be performed in runInput(). A good sample of what to do here may be to * set some variable defaults. */ BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); ENDmodInit static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "ruleset '%s' for %s not found - " "using default ruleset instead", inst->pszBindRuleset, inst->pszFollow_glob); } rsyslog-8.2512.0/contrib/imbatchreport/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315021104 xustar0030 mtime=1764935885.677002201 30 atime=1764935896.787172379 30 ctime=1764935930.915694949 rsyslog-8.2512.0/contrib/imbatchreport/Makefile.in0000664000175000017500000006371015114544315020557 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imbatchreport ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) imbatchreport_la_DEPENDENCIES = am_imbatchreport_la_OBJECTS = imbatchreport_la-imbatchreport.lo imbatchreport_la_OBJECTS = $(am_imbatchreport_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imbatchreport_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(imbatchreport_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imbatchreport_la_SOURCES) DIST_SOURCES = $(imbatchreport_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imbatchreport.la imbatchreport_la_SOURCES = imbatchreport.c imbatchreport_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imbatchreport_la_LDFLAGS = -module -avoid-version imbatchreport_la_LIBADD = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imbatchreport/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imbatchreport/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imbatchreport.la: $(imbatchreport_la_OBJECTS) $(imbatchreport_la_DEPENDENCIES) $(EXTRA_imbatchreport_la_DEPENDENCIES) $(AM_V_CCLD)$(imbatchreport_la_LINK) -rpath $(pkglibdir) $(imbatchreport_la_OBJECTS) $(imbatchreport_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imbatchreport_la-imbatchreport.lo: imbatchreport.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imbatchreport_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imbatchreport_la-imbatchreport.lo -MD -MP -MF $(DEPDIR)/imbatchreport_la-imbatchreport.Tpo -c -o imbatchreport_la-imbatchreport.lo `test -f 'imbatchreport.c' || echo '$(srcdir)/'`imbatchreport.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imbatchreport_la-imbatchreport.Tpo $(DEPDIR)/imbatchreport_la-imbatchreport.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imbatchreport.c' object='imbatchreport_la-imbatchreport.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imbatchreport_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imbatchreport_la-imbatchreport.lo `test -f 'imbatchreport.c' || echo '$(srcdir)/'`imbatchreport.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imbatchreport_la-imbatchreport.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omamqp10000644000000000000000000000013215114544372015475 xustar0030 mtime=1764935930.826693586 30 atime=1764935934.366747775 30 ctime=1764935930.826693586 rsyslog-8.2512.0/contrib/omamqp1/0000775000175000017500000000000015114544372015216 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omamqp1/PaxHeaders/Makefile.am0000644000000000000000000000013215055603742017607 xustar0030 mtime=1756825570.243068166 30 atime=1764930928.767814814 30 ctime=1764935930.819693479 rsyslog-8.2512.0/contrib/omamqp1/Makefile.am0000664000175000017500000000110715055603742017252 0ustar00rgerrgerpkglib_LTLIBRARIES = omamqp1.la omamqp1_la_SOURCES = omamqp1.c if ENABLE_QPIDPROTON_STATIC omamqp1_la_LDFLAGS = -module -avoid-version -Wl,-whole-archive -l:libqpid-proton-proactor-static.a -l:libqpid-proton-core-static.a -Wl,--no-whole-archive $(PTHREADS_LIBS) $(OPENSSL_LIBS) ${RT_LIBS} -lsasl2 omamqp1_la_LIBADD = else omamqp1_la_LDFLAGS = -module -avoid-version $(PROTON_PROACTOR_LIBS) $(PTHREADS_LIBS) $(OPENSSL_LIBS) -lm omamqp1_la_LIBADD = endif omamqp1_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(PROTON_PROACTOR_CFLAGS) -Wno-error=switch EXTRA_DIST = rsyslog-8.2512.0/contrib/omamqp1/PaxHeaders/README.md0000644000000000000000000000013115035412264017024 xustar0030 mtime=1752569012.329251042 30 atime=1764865110.805064305 29 ctime=1764935930.82369354 rsyslog-8.2512.0/contrib/omamqp1/README.md0000664000175000017500000002552215035412264016477 0ustar00rgerrger# AMQP 1.0 Output Module # The omamqp1 output module can be used to send log messages via an AMQP 1.0-compatible messaging bus. This module requires the Apache QPID Proton python library, version 0.10+. This should be installed on the system that is running rsyslogd. ## Message Format ## Messages sent from this module to the message bus contain a list of strings. Each string is a separate log message. The list is ordered such that the oldest log appears at the front of the list, whilst the most recent log is at the end of the list. ## Configuration ## This module is configured via the rsyslog.conf configuration file. To use this module it must first be imported. Example: module(load="omamqp1") Actions can then be created using this module. Example: action(type="omamqp1" host="localhost:5672" target="amq.topic") The following parameters are recognized by the module: * host - The address of the message bus. Optionally a port can be included, separated by a ':'. Example: "localhost:5672" * target - The destination for the generated messages. This can be the name of a queue or topic. On some messages buses it may be necessary to create this target manually. Example: "amq.topic" * username - Optional. Used by SASL to authenticate with the message bus. * password - Optional. Used by SASL to authenticate with the message bus. * template - Template to use to format the record. Defaults to `RSYSLOG_FileFormat` * idleTimeout - The idle timeout in seconds. This enables connection heartbeats and is used to detect a failed connection to the message bus. Set to zero to disable. * maxResend - number of times an undeliverable message is re-sent to the message bus before it is dropped. This is unrelated to rsyslog's action.resumeRetryCount. Once the connection to the message bus is active this module is ready to receive log messages from rsyslog (i.e. the module has 'resumed'). Even though the connection is active, any particular message may be rejected by the message bus (e.g. 'unrouteable'). The module will retry (e.g. 'suspend') for up to maxResend attempts before discarding the message as undeliverable. Setting this to zero disables the limit and unrouteable messages will be retried as long as the connection stays up. You probably do not want that to happen. The default is 10. * reconnectDelay - The time in seconds this module will delay before attempting to re-established a failed connection (default 5 seconds). * disableSASL - Setting this to a non-zero value will disable SASL negotiation. Only necessary if the message bus does not offer SASL. ## Dependencies ## The package is dependent on the QPID Proton AMQP 1.0 library. To build this package you must also have the QPID Proton C headers installed. Pre-built packages are available for Fedora 22+ via the base Fedora repos. Packages for RHEL/Centos based systems can be obtained via [EPEL](https://fedoraproject.org/wiki/EPEL). In order to build the module, install the _qpid-proton-c-devel_ package. Pre-built packages from most Ubuntu/Debian systems are available via the [QPID project's PPA on Launchpad](https://launchpad.net/~qpid). For example, to install the latest version of the Proton packages (as of this writing): $ sudo add-apt-repository ppa:qpid/released $ sudo apt-get update $ sudo apt-get install libqpid-proton3 libqpid-proton3-dev Check your distribution for the availability of Proton packages. Alternatively, you can pull down the Proton code from the [project website](http://qpid.apache.org/) and build it yourself. ## Debugging ## Debug logging can be enabled using the environment variables `RSYSLOG_DEBUG` and `RSYSLOG_DEBUGLOG`, export RSYSLOG_DEBUG=debug export RSYSLOG_DEBUGLOG=/tmp/rsyslog.debug.log or with the old-style rsyslog debug configuration settings. For example: $DebugFile /tmp/omamqp1-debug.txt $DebugLevel 2 There are a number of tracepoints within the omamqp1.c code. ---- ## Notes on use with the QPID C++ broker (qpidd) ## _Note well: These notes assume use of version 0.34 of the QPID C++ broker. Previous versions may not be fully compatible_ To use the Apache QPID C++ broker _qpidd_ as the message bus, a version of qpidd that supports the AMQP 1.0 protocol must be used. Since qpidd can be packaged without AMQP 1.0 support you should verify AMQP 1.0 has been enabled by checking for AMQP 1.0 related options in the qpidd help text. For example: qpidd --help ... AMQP 1.0 Options: --domain DOMAIN Domain of this broker --queue-patterns PATTERN Pattern for on-demand queues --topic-patterns PATTERN Pattern for on-demand topics If no AMQP 1.0 related options appear in the help output, then AMQP 1.0 has not been included with your qpidd. The destination for message (target) must be created before log messages arrive. This can be done using the qpid-config tool. Example: qpid-config add queue rsyslogd Alternatively, the target can be created on demand by configuring a queue-pattern (or topic-pattern) that matches the target. To do this, add a _queue-patterns_ (or _topic_patterns_) directive to the qpidd configuration file /etc/qpid/qpidd.conf. For example, to have qpidd automatically create a queue named _rsyslogd_, add the following to the qpidd configuration file: queue-patterns=rsyslogd or, if a topic is desired instead of a queue: topic-patterns=rsyslogd These dynamic targets are auto-delete and will be destroyed once there are no longer any subscribers or queue-bound messages. Versions of qpidd <= 0.34 also need to have the SASL service name set to 'amqp'. Add this to the qpidd.conf file: sasl-service-name=amqp ---- ## Notes on use with the QPID Dispatch Router (qdrouterd) ## _Note well: These notes assume use of version 0.5 of the QPID Dispatch Router Previous versions may not be fully compatible_ The default qdrouterd configuration does not have SASL authentication turned on. You must set up SASL in the qdrouter configuration file /etc/qpid-dispatch/qdrouterd.conf First create a SASL configuration file for qdrouterd. This configuration file is usually /etc/sasl2/qdrouterd.conf, but its default location may vary depending on your platform's configuration. This document assumes you understand how to properly configure SASL. Here is an example qdrouterd SASL configuration file that allows the client to use the DIGEST-MD5 or PLAIN authentication mechanisms, plus a SASL user database: pwcheck_method: auxprop auxprop_plugin: sasldb sasldb_path: /var/lib/qdrouterd/qdrouterd.sasldb mech_list: DIGEST-MD5 PLAIN Once a SASL configuration file has been set up for qdrouterd the path to the directory holding the configuration file and the basename of the configuration file (sas '.conf') must be added to the /etc/qpid-dispatch/qdrouterd.conf configuration file. This is done by adding _saslConfigPath_ and _saslConfigName_ to the _container_ section of the configuration file. For example, assuming the file /etc/sasl2/qdrouter.conf holds the qdrouterd SASL configuration: container { workerThreads: 4 containerName: Qpid.Dispatch.Router.A saslConfigPath: /etc/sasl2 saslConfigName: qdrouterd } In addition, the address used by the omamqp1 module to connect to qdrouterd must have SASL authentication turned on. This is done by adding the _authenticatePeer_ attribute set to 'yes' to the corresponding _listener_ entry: listener { addr: 0.0.0.0 port: amqp authenticatePeer: yes } This should complete the SASL setup needed by qdrouterd. The target address used as the destination for the log messages must be picked with care. qdrouterd uses the prefix of the target address to determine the forwarding pattern used for messages sent using that target address. Addresses starting with the prefix _queue_ are distributed to only one message receiver. If there are multiple message consumers listening to that target address, only one listener will receive the message. In this case, qdrouterd will load balance messages across the multiple consumers - much like a queue with competing subscribers. For example: "queue/rsyslogd" If a multicast pattern is desired - where all active listeners receive their own copy of the message - the target address prefix _multicast_ may be used. For example: "multicast/rsyslogd" Note well: if there are _no_ active receivers for the log messages, messages will be rejected the qdrouterd. In this case the omamqp1 module will return a _SUSPENDED_ result to the rsyslogd main task. rsyslogd may then re-submit the rejected log messages to the module, which will attempt to send them again. This retry option is configured via rsyslogd - it is not part of this module. Refer to the rsyslogd actions documentation. ---- ### Using qdrouterd in combination with qpidd ### A qdrouterd-based message bus can use a broker as a message storage mechanism for those that require broker-based message services (such as a message store). This section explains how to configure qdrouterd and qpidd for this type of deployment. Please read the notes for deploying qpidd and qdrouterd first. Each qdrouterd instance that is to connect the broker to the message bus must define a _connector_ section in the qdrouterd.conf file. This connector contains the addressing information necessary to have the message bus set up a connection to the broker. For example, if a broker is available on host broker.host.com at port 5672: connector { name: mybroker role: on-demand addr: broker.host.com port: 5672 } In order to route messages to and from the broker, a static _link route_ must be configured on qdrouterd. This link route contains a target address prefix and the name of the connector to use for forwarding matching messages. For example, to have qdrouterd forward messages that have a target address prefixed by 'Broker' to the connector defined above, the following link pattern must be added to the qdrouterd.conf configuration: linkRoutePattern { prefix: /Broker/ connector: mybroker } A queue must then be created on the broker. The name of the queue must be prefixed by the same prefix specified in the linkRoutePattern entry. For example: $ qpid-config add queue Broker/rsyslogd Lastly, use the name of the queue for the target address used by the omamqp module. For example, assuming qdrouterd is listening on local port 5672: action(type="omamqp1" host="localhost:5672" target="Broker/rsyslogd") # Tests ## Valgrind For investigating leaks, valgrind will not give you the full symbols in the stack because rsyslog unloads the module before the leak checker finishes. The test adds the following using `add_conf` add_conf ' global(debug.unloadModules="off") ' Then you should get a full stacktrace with full symbols. rsyslog-8.2512.0/contrib/omamqp1/PaxHeaders/omamqp1.c0000644000000000000000000000013215062756615017300 xustar0030 mtime=1758190989.168640652 30 atime=1764931103.304708817 30 ctime=1764935930.826693586 rsyslog-8.2512.0/contrib/omamqp1/omamqp1.c0000664000175000017500000007577415062756615016770 0ustar00rgerrger/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * * omamqp1.c * * This output plugin enables rsyslog to send messages to an AMQP 1.0 protocol * compliant message bus. * * AMQP glue code Copyright (C) 2015-2016 Kenneth A. Giusti * */ /** * @file omamqp1.c * @brief rsyslog output plugin for AMQP 1.0 via Qpid Proton. * * Each action instance spawns a dedicated protocol thread that manages the * AMQP connection. Worker threads batch log messages and send them to this * thread through a small command queue for asynchronous transmission. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* work-around issues in this contributed module */ #pragma GCC diagnostic ignored "-Wswitch-enum" #pragma GCC diagnostic ignored "-Wdeprecated-declarations" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omamqp1") /* internal structures */ DEF_OMOD_STATIC_DATA; /* Settings for the action */ typedef struct _configSettings { pn_url_t *url; /* address of message bus */ uchar *username; /* authentication credentials */ uchar *password; uchar *target; /* endpoint for sent log messages */ uchar *templateName; int bDisableSASL; /* do not enable SASL? 0-enable 1-disable */ int idleTimeout; /* disconnect idle connection (seconds) */ int reconnectDelay; /* pause before re-connecting (seconds) */ int maxRetries; /* drop unrouteable messages after maxRetries attempts */ } configSettings_t; /* Control for communicating with the protocol engine thread */ typedef enum { // commands sent to protocol thread COMMAND_DONE, // marks command complete COMMAND_SEND, // send a message to the message bus COMMAND_IS_READY, // is the connection to the message bus active? COMMAND_SHUTDOWN // cleanup and terminate protocol thread. } commands_t; typedef struct _threadIPC { pthread_mutex_t lock; pthread_cond_t condition; commands_t command; rsRetVal result; // of command pn_message_t *message; uint64_t tag; // per message id } threadIPC_t; /* per-instance data */ typedef struct _instanceData { configSettings_t config; threadIPC_t ipc; int bThreadRunning; pthread_t thread_id; pn_reactor_t *reactor; pn_handler_t *handler; pn_message_t *message; int log_count; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; /* glue code */ typedef void dispatch_t(pn_handler_t *, pn_event_t *, pn_event_type_t); static void _init_thread_ipc(threadIPC_t *pIPC); static void _clean_thread_ipc(threadIPC_t *ipc); static void _init_config_settings(configSettings_t *pConfig); static void _clean_config_settings(configSettings_t *pConfig); static rsRetVal _shutdown_thread(instanceData *pData); static rsRetVal _new_handler( pn_handler_t **handler, pn_reactor_t *reactor, dispatch_t *dispatcher, configSettings_t *config, threadIPC_t *ipc); static void _del_handler(pn_handler_t *handler); static rsRetVal _launch_protocol_thread(instanceData *pData); static rsRetVal _shutdown_thread(instanceData *pData); static rsRetVal _issue_command(threadIPC_t *ipc, pn_reactor_t *reactor, commands_t command, pn_message_t *message); static void dispatcher(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type); /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"host", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"target", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"username", eCmdHdlrGetWord, 0}, {"password", eCmdHdlrGetWord, 0}, {"template", eCmdHdlrGetWord, 0}, {"idleTimeout", eCmdHdlrNonNegInt, 0}, {"reconnectDelay", eCmdHdlrPositiveInt, 0}, {"maxRetries", eCmdHdlrNonNegInt, 0}, {"disableSASL", eCmdHdlrInt, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; { if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; } ENDisCompatibleWithFeature BEGINcreateInstance CODESTARTcreateInstance; { memset(pData, 0, sizeof(instanceData)); _init_config_settings(&pData->config); _init_thread_ipc(&pData->ipc); } ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINfreeInstance CODESTARTfreeInstance; { _shutdown_thread(pData); _clean_config_settings(&pData->config); _clean_thread_ipc(&pData->ipc); if (pData->reactor) pn_reactor_free(pData->reactor); if (pData->handler) pn_handler_free(pData->handler); if (pData->message) pn_message_free(pData->message); } ENDfreeInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; { configSettings_t *cfg = &pData->config; dbgprintf("omamqp1:\n"); dbgprintf(" host=%s\n", pn_url_str(cfg->url)); dbgprintf(" username=%s\n", cfg->username); // dbgprintf(" password=%s\n", pData->password); dbgprintf(" target=%s\n", cfg->target); dbgprintf(" template=%s\n", cfg->templateName); dbgprintf(" disableSASL=%d\n", cfg->bDisableSASL); dbgprintf(" idleTimeout=%d\n", cfg->idleTimeout); dbgprintf(" reconnectDelay=%d\n", cfg->reconnectDelay); dbgprintf(" maxRetries=%d\n", cfg->maxRetries); dbgprintf(" running=%d\n", pData->bThreadRunning); } ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; { // is the link active? instanceData *pData = pWrkrData->pData; iRet = _issue_command(&pData->ipc, pData->reactor, COMMAND_IS_READY, NULL); } ENDtryResume /** * @brief Initialize a new batch of log records. * * beginTransaction() prepares a Proton message and opens a list container * that will hold each formatted log message added by doAction(). */ BEGINbeginTransaction CODESTARTbeginTransaction; { DBGPRINTF("omamqp1: beginTransaction\n"); instanceData *pData = pWrkrData->pData; pData->log_count = 0; if (pData->message) pn_message_free(pData->message); pData->message = pn_message(); CHKmalloc(pData->message); pn_data_t *body = pn_message_body(pData->message); pn_data_put_list(body); pn_data_enter(body); } finalize_it: ENDbeginTransaction /** * @brief Append a formatted message to the current batch. * * This function is invoked for each log record emitted by rsyslog. The * formatted string provided by the template is stored in the Proton * message created in beginTransaction(). * * The actual transmission is deferred until endTransaction() issues a * COMMAND_SEND to the protocol thread. */ BEGINdoAction CODESTARTdoAction; { DBGPRINTF("omamqp1: doAction\n"); instanceData *pData = pWrkrData->pData; if (!pData->message) ABORT_FINALIZE(RS_RET_OK); pn_bytes_t msg = pn_bytes(strlen((const char *)ppString[0]), (const char *)ppString[0]); pn_data_t *body = pn_message_body(pData->message); pn_data_put_string(body, msg); pData->log_count++; iRet = RS_RET_DEFER_COMMIT; } finalize_it: ENDdoAction /** * @brief Finalize the batch and forward it to the protocol thread. * * Closes the list started in beginTransaction() and hands the assembled * message to amqp1_thread via COMMAND_SEND. If no messages were queued the * Proton message is discarded. */ BEGINendTransaction CODESTARTendTransaction; { DBGPRINTF("omamqp1: endTransaction\n"); instanceData *pData = pWrkrData->pData; if (!pData->message) ABORT_FINALIZE(RS_RET_OK); pn_data_t *body = pn_message_body(pData->message); pn_data_exit(body); pn_message_t *message = pData->message; pData->message = NULL; if (pData->log_count > 0) { DBGPRINTF("omamqp1: sending [%d] records\n", pData->log_count); CHKiRet(_issue_command(&pData->ipc, pData->reactor, COMMAND_SEND, message)); } else { DBGPRINTF("omamqp1: no log messages to send\n"); pn_message_free(message); } } finalize_it: ENDendTransaction BEGINnewActInst struct cnfparamvals *pvals; int i; configSettings_t *cs; CODESTARTnewActInst; { if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); cs = &pData->config; CODE_STD_STRING_REQUESTnewActInst(1); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "host")) { char *u = es_str2cstr(pvals[i].val.d.estr, NULL); cs->url = pn_url_parse(u); if (!cs->url) { LogError(0, RS_RET_CONF_PARSE_ERROR, "omamqp1: Invalid host URL configured: '%s'", u); free(u); ABORT_FINALIZE(RS_RET_CONF_PARSE_ERROR); } free(u); } else if (!strcmp(actpblk.descr[i].name, "template")) { cs->templateName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "target")) { cs->target = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "username")) { cs->username = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "password")) { cs->password = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "reconnectDelay")) { cs->reconnectDelay = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "idleTimeout")) { cs->idleTimeout = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "maxRetries")) { cs->maxRetries = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "disableSASL")) { cs->bDisableSASL = (int)pvals[i].val.d.n; } else { dbgprintf("omamqp1: program error, unrecognized param '%s', ignored.\n", actpblk.descr[i].name); } } CHKiRet(OMSRsetEntry( *ppOMSR, 0, (uchar *)strdup((cs->templateName == NULL) ? "RSYSLOG_FileFormat" : (char *)cs->templateName), OMSR_NO_RQD_TPL_OPTS)); // once configuration is known, start the protocol engine thread pData->reactor = pn_reactor(); CHKmalloc(pData->reactor); CHKiRet(_new_handler(&pData->handler, pData->reactor, dispatcher, &pData->config, &pData->ipc)); CHKiRet(_launch_protocol_thread(pData)); } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_TXIF_OMOD_QUERIES /* use transaction interface */ CODEqueryEtryPt_STD_OMOD8_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; { *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); DBGPRINTF("omamqp1: module compiled with rsyslog version %s.\n", VERSION); DBGPRINTF("omamqp1: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); } ENDmodInit /////////////////////////////////////// // All the Proton-specific glue code // /////////////////////////////////////// /* state maintained by the protocol thread */ typedef struct { const configSettings_t *config; threadIPC_t *ipc; pn_reactor_t *reactor; // AMQP 1.0 protocol engine pn_connection_t *conn; pn_link_t *sender; pn_delivery_t *delivery; char *encode_buffer; size_t buffer_size; uint64_t tag; int msgs_sent; int msgs_settled; int retries; sbool stopped; } protocolState_t; // protocolState_t is embedded in the engine handler #define PROTOCOL_STATE(eh) ((protocolState_t *)pn_handler_mem(eh)) static void _init_config_settings(configSettings_t *pConfig) { memset(pConfig, 0, sizeof(configSettings_t)); pConfig->reconnectDelay = 5; pConfig->maxRetries = 10; } static void _clean_config_settings(configSettings_t *pConfig) { if (pConfig->url) pn_url_free(pConfig->url); if (pConfig->username) free(pConfig->username); if (pConfig->password) free(pConfig->password); if (pConfig->target) free(pConfig->target); if (pConfig->templateName) free(pConfig->templateName); memset(pConfig, 0, sizeof(configSettings_t)); } static void _init_thread_ipc(threadIPC_t *pIPC) { memset(pIPC, 0, sizeof(threadIPC_t)); pthread_mutex_init(&pIPC->lock, NULL); pthread_cond_init(&pIPC->condition, NULL); pIPC->command = COMMAND_DONE; pIPC->result = RS_RET_OK; } static void _clean_thread_ipc(threadIPC_t *ipc) { pthread_cond_destroy(&ipc->condition); pthread_mutex_destroy(&ipc->lock); } // create a new handler for the engine and set up the protocolState static rsRetVal _new_handler( pn_handler_t **handler, pn_reactor_t *reactor, dispatch_t *dispatch, configSettings_t *config, threadIPC_t *ipc) { DEFiRet; *handler = pn_handler_new(dispatch, sizeof(protocolState_t), _del_handler); CHKmalloc(*handler); pn_handler_add(*handler, pn_handshaker()); protocolState_t *pState = PROTOCOL_STATE(*handler); memset(pState, 0, sizeof(protocolState_t)); pState->buffer_size = 64; // will grow if not enough pState->encode_buffer = (char *)malloc(pState->buffer_size); CHKmalloc(pState->encode_buffer); pState->reactor = reactor; pState->stopped = false; // these are _references_, don't free them: pState->config = config; pState->ipc = ipc; finalize_it: RETiRet; } // in case existing buffer too small static rsRetVal _grow_buffer(protocolState_t *pState) { DEFiRet; size_t new_size = pState->buffer_size * 2; char *new_buf = realloc(pState->encode_buffer, new_size); CHKmalloc(new_buf); pState->encode_buffer = new_buf; pState->buffer_size = new_size; finalize_it: RETiRet; } /* release the pn_handler_t instance. Do not call this directly, * it will be called by the reactor when all references to the * handler have been released. */ static void _del_handler(pn_handler_t *handler) { protocolState_t *pState = PROTOCOL_STATE(handler); if (pState->encode_buffer) free(pState->encode_buffer); } // Close the sender and its parent session and connection static void _close_connection(protocolState_t *ps) { if (ps->sender) { pn_link_close(ps->sender); pn_session_close(pn_link_session(ps->sender)); } if (ps->conn) pn_connection_close(ps->conn); } static void _abort_command(protocolState_t *ps) { threadIPC_t *ipc = ps->ipc; pthread_mutex_lock(&ipc->lock); switch (ipc->command) { case COMMAND_SEND: dbgprintf("omamqp1: aborted the message send in progress\n"); CASE_FALLTHROUGH case COMMAND_IS_READY: ipc->result = RS_RET_SUSPENDED; ipc->command = COMMAND_DONE; pthread_cond_signal(&ipc->condition); break; case COMMAND_SHUTDOWN: // cannot be aborted case COMMAND_DONE: break; default: // No action needed for other cases break; } pthread_mutex_unlock(&ipc->lock); } // log a protocol error received from the message bus static void _log_error(const char *message, pn_condition_t *cond) { const char *name = pn_condition_get_name(cond); const char *desc = pn_condition_get_description(cond); dbgprintf("omamqp1: %s %s:%s\n", message, (name) ? name : "", (desc) ? desc : ""); } /* is the link ready to send messages? */ static sbool _is_ready(pn_link_t *link) { return (link && pn_link_state(link) == (PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE) && pn_link_credit(link) > 0); } /* Process each event emitted by the protocol engine */ static void dispatcher(pn_handler_t *handler, pn_event_t *event, pn_event_type_t type) { protocolState_t *ps = PROTOCOL_STATE(handler); const configSettings_t *cfg = ps->config; // DBGPRINTF("omamqp1: Event received: %s\n", pn_event_type_name(type)); switch (type) { case PN_LINK_REMOTE_OPEN: DBGPRINTF("omamqp1: Message bus opened link.\n"); break; case PN_DELIVERY: // has the message been delivered to the message bus? if (ps->delivery) { assert(ps->delivery == pn_event_delivery(event)); if (pn_delivery_updated(ps->delivery)) { rsRetVal result = RS_RET_IDLE; uint64_t rs = pn_delivery_remote_state(ps->delivery); switch (rs) { case PN_ACCEPTED: DBGPRINTF("omamqp1: Message ACCEPTED by message bus\n"); result = RS_RET_OK; break; case PN_REJECTED: dbgprintf("omamqp1: message bus rejected log message: invalid message - dropping\n"); // message bus considers this a 'bad message'. Cannot be redelivered. // Likely a configuration error. Drop the message by returning OK result = RS_RET_OK; break; case PN_RELEASED: case PN_MODIFIED: // the message bus cannot accept the message. This may be temporary - retry // up to maxRetries before dropping if (++ps->retries >= cfg->maxRetries) { dbgprintf("omamqp1: message bus failed to accept message - dropping\n"); result = RS_RET_OK; } else { dbgprintf("omamqp1: message bus cannot accept message, retrying\n"); result = RS_RET_SUSPENDED; } break; case PN_RECEIVED: // not finished yet, wait for next delivery update break; default: // no other terminal states defined, so ignore anything else dbgprintf("omamqp1: unknown delivery state=0x%lX, assuming message accepted\n", (unsigned long)pn_delivery_remote_state(ps->delivery)); result = RS_RET_OK; break; } if (result != RS_RET_IDLE) { // the command is complete threadIPC_t *ipc = ps->ipc; pthread_mutex_lock(&ipc->lock); assert(ipc->command == COMMAND_SEND); ipc->result = result; ipc->command = COMMAND_DONE; pthread_cond_signal(&ipc->condition); pthread_mutex_unlock(&ipc->lock); pn_delivery_settle(ps->delivery); ps->delivery = NULL; if (result == RS_RET_OK) { ps->retries = 0; } } } } break; case PN_CONNECTION_BOUND: if (!cfg->bDisableSASL) { // force use of SASL, even allowing PLAIN authentication pn_sasl_t *sasl = pn_sasl(pn_event_transport(event)); #if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 10 pn_sasl_set_allow_insecure_mechs(sasl, true); #else // proton version <= 0.9 only supports PLAIN authentication const char *user = cfg->username ? (char *)cfg->username : pn_url_get_username(cfg->url); if (user) { pn_sasl_plain(sasl, user, (cfg->password ? (char *)cfg->password : pn_url_get_password(cfg->url))); } #endif } if (cfg->idleTimeout) { // configured as seconds, set as milliseconds pn_transport_set_idle_timeout(pn_event_transport(event), cfg->idleTimeout * 1000); } break; case PN_CONNECTION_UNBOUND: DBGPRINTF("omamqp1: cleaning up connection resources\n"); pn_connection_release(pn_event_connection(event)); ps->conn = NULL; ps->sender = NULL; ps->delivery = NULL; break; case PN_TRANSPORT_ERROR: { // TODO: if auth failure, does it make sense to retry??? pn_transport_t *tport = pn_event_transport(event); pn_condition_t *cond = pn_transport_condition(tport); if (pn_condition_is_set(cond)) { _log_error("transport failure", cond); } dbgprintf("omamqp1: network transport failed, reconnecting...\n"); // the protocol thread will attempt to reconnect if it is not // being shut down } break; default: break; } } /** * @brief Send a control command to the protocol thread. * * The calling worker thread populates the shared IPC structure with the * command and optional message payload, wakes the Proton reactor and waits * on the condition variable until amqp1_thread processes the request. */ static rsRetVal _issue_command(threadIPC_t *ipc, pn_reactor_t *reactor, commands_t command, pn_message_t *message) { DEFiRet; DBGPRINTF("omamqp1: Sending command %d to protocol thread\n", command); pthread_mutex_lock(&ipc->lock); if (message) { assert(ipc->message == NULL); ipc->message = message; } assert(ipc->command == COMMAND_DONE); ipc->command = command; pn_reactor_wakeup(reactor); while (ipc->command != COMMAND_DONE) { pthread_cond_wait(&ipc->condition, &ipc->lock); } iRet = ipc->result; if (ipc->message) { pn_message_free(ipc->message); ipc->message = NULL; } pthread_mutex_unlock(&ipc->lock); DBGPRINTF("omamqp1: Command %d completed, status=%d\n", command, iRet); RETiRet; } /** * @brief Check for and execute pending commands from the main thread. * * Invoked by the protocol thread between reactor events to handle requests * like message send, readiness queries or shutdown. */ static void _poll_command(protocolState_t *ps) { if (ps->stopped) return; threadIPC_t *ipc = ps->ipc; pthread_mutex_lock(&ipc->lock); switch (ipc->command) { case COMMAND_SHUTDOWN: DBGPRINTF("omamqp1: Protocol thread processing shutdown command\n"); ps->stopped = true; _close_connection(ps); // wait for the shutdown to complete before ack'ing this command break; case COMMAND_IS_READY: DBGPRINTF("omamqp1: Protocol thread processing ready query command\n"); ipc->result = _is_ready(ps->sender) ? RS_RET_OK : RS_RET_SUSPENDED; ipc->command = COMMAND_DONE; pthread_cond_signal(&ipc->condition); break; case COMMAND_SEND: if (ps->delivery) break; // currently processing this command DBGPRINTF("omamqp1: Protocol thread processing send message command\n"); if (!_is_ready(ps->sender)) { ipc->result = RS_RET_SUSPENDED; ipc->command = COMMAND_DONE; pthread_cond_signal(&ipc->condition); break; } // send the message ++ps->tag; ps->delivery = pn_delivery(ps->sender, pn_dtag((const char *)&ps->tag, sizeof(ps->tag))); pn_message_t *message = ipc->message; assert(message); int rc = 0; size_t len = ps->buffer_size; do { rc = pn_message_encode(message, ps->encode_buffer, &len); if (rc == PN_OVERFLOW) { _grow_buffer(ps); len = ps->buffer_size; } } while (rc == PN_OVERFLOW); pn_link_send(ps->sender, ps->encode_buffer, len); pn_link_advance(ps->sender); ++ps->msgs_sent; // command completes when remote updates the delivery (see PN_DELIVERY) break; case COMMAND_DONE: break; default: // No action needed for other cases break; } pthread_mutex_unlock(&ipc->lock); } /** * @brief Worker thread driving the Proton reactor. * * This thread owns the AMQP connection and processes commands issued via * _issue_command(). It reconnects on failure and periodically polls for * shutdown requests. */ static void *amqp1_thread(void *arg) { pn_handler_t *handler = (pn_handler_t *)arg; protocolState_t *ps = PROTOCOL_STATE(handler); const configSettings_t *cfg = ps->config; // have pn_reactor_process() exit after 5 sec to poll for commands pn_reactor_set_timeout(ps->reactor, 5000); pn_reactor_start(ps->reactor); while (!ps->stopped) { // setup a connection: const char *host = pn_url_get_host(cfg->url); const char *port = pn_url_get_port(cfg->url); if (!port) port = "5672"; #if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 13 ps->conn = pn_reactor_connection_to_host(ps->reactor, host, port, handler); pn_connection_set_hostname(ps->conn, host); #else { char host_addr[300]; ps->conn = pn_reactor_connection(ps->reactor, handler); snprintf(host_addr, sizeof(host_addr), "%s:%s", host, port); pn_connection_set_hostname(ps->conn, host_addr); } #endif pn_connection_set_container(ps->conn, "rsyslogd-omamqp1"); #if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR >= 10 // proton version <= 0.9 did not support Cyrus SASL const char *user = cfg->username ? (char *)cfg->username : pn_url_get_username(cfg->url); if (user) pn_connection_set_user(ps->conn, user); const char *pword = cfg->password ? (char *)cfg->password : pn_url_get_password(cfg->url); if (pword) pn_connection_set_password(ps->conn, pword); #endif pn_connection_open(ps->conn); pn_session_t *ssn = pn_session(ps->conn); pn_session_open(ssn); ps->sender = pn_sender(ssn, (char *)cfg->target); pn_link_set_snd_settle_mode(ps->sender, PN_SND_UNSETTLED); char *addr = (char *)ps->config->target; pn_terminus_set_address(pn_link_target(ps->sender), addr); pn_terminus_set_address(pn_link_source(ps->sender), addr); pn_link_open(ps->sender); // run the protocol engine until the connection closes or thread is shut down sbool engine_running = true; while (engine_running) { engine_running = pn_reactor_process(ps->reactor); _poll_command(ps); } _abort_command(ps); // unblock main thread if necessary // delay reconnectDelay seconds before re-connecting: int delay = ps->config->reconnectDelay; while (delay-- > 0 && !ps->stopped) { /* Sleep in one-second increments to pace reconnect attempts and * still allow _poll_command() to observe shutdown requests. */ srSleep(1, 0); _poll_command(ps); } } pn_reactor_stop(ps->reactor); // stop command is now done: threadIPC_t *ipc = ps->ipc; pthread_mutex_lock(&ipc->lock); ipc->result = RS_RET_OK; ipc->command = COMMAND_DONE; pthread_cond_signal(&ipc->condition); pthread_mutex_unlock(&ipc->lock); DBGPRINTF("omamqp1: Protocol thread stopped\n"); return 0; } /** * @brief Spawn the protocol thread that manages the AMQP connection. * * The thread executes amqp1_thread() using the instance's handler and * sets the bThreadRunning flag on success. */ static rsRetVal _launch_protocol_thread(instanceData *pData) { int rc; DBGPRINTF("omamqp1: Starting protocol thread\n"); do { rc = pthread_create(&pData->thread_id, NULL, amqp1_thread, pData->handler); if (!rc) { pData->bThreadRunning = true; return RS_RET_OK; } } while (rc == EAGAIN); LogError(0, RS_RET_SYS_ERR, "omamqp1: thread create failed: %d", rc); return RS_RET_SYS_ERR; } /** * @brief Request protocol thread termination and wait for completion. */ static rsRetVal _shutdown_thread(instanceData *pData) { DEFiRet; if (pData->bThreadRunning) { DBGPRINTF("omamqp1: shutting down thread...\n"); CHKiRet(_issue_command(&pData->ipc, pData->reactor, COMMAND_SHUTDOWN, NULL)); pthread_join(pData->thread_id, NULL); pData->bThreadRunning = false; DBGPRINTF("omamqp1: thread shutdown complete\n"); } finalize_it: RETiRet; } /* vi:set ai: */ rsyslog-8.2512.0/contrib/omamqp1/PaxHeaders/Makefile.in0000644000000000000000000000013115114544316017614 xustar0030 mtime=1764935886.143009339 30 atime=1764935896.726171445 29 ctime=1764935930.82169351 rsyslog-8.2512.0/contrib/omamqp1/Makefile.in0000664000175000017500000006411515114544316017270 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omamqp1 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) omamqp1_la_DEPENDENCIES = am_omamqp1_la_OBJECTS = omamqp1_la-omamqp1.lo omamqp1_la_OBJECTS = $(am_omamqp1_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omamqp1_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omamqp1_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omamqp1_la-omamqp1.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omamqp1_la_SOURCES) DIST_SOURCES = $(omamqp1_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omamqp1.la omamqp1_la_SOURCES = omamqp1.c @ENABLE_QPIDPROTON_STATIC_FALSE@omamqp1_la_LDFLAGS = -module -avoid-version $(PROTON_PROACTOR_LIBS) $(PTHREADS_LIBS) $(OPENSSL_LIBS) -lm @ENABLE_QPIDPROTON_STATIC_TRUE@omamqp1_la_LDFLAGS = -module -avoid-version -Wl,-whole-archive -l:libqpid-proton-proactor-static.a -l:libqpid-proton-core-static.a -Wl,--no-whole-archive $(PTHREADS_LIBS) $(OPENSSL_LIBS) ${RT_LIBS} -lsasl2 @ENABLE_QPIDPROTON_STATIC_FALSE@omamqp1_la_LIBADD = @ENABLE_QPIDPROTON_STATIC_TRUE@omamqp1_la_LIBADD = omamqp1_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(PROTON_PROACTOR_CFLAGS) -Wno-error=switch EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omamqp1/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omamqp1/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omamqp1.la: $(omamqp1_la_OBJECTS) $(omamqp1_la_DEPENDENCIES) $(EXTRA_omamqp1_la_DEPENDENCIES) $(AM_V_CCLD)$(omamqp1_la_LINK) -rpath $(pkglibdir) $(omamqp1_la_OBJECTS) $(omamqp1_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omamqp1_la-omamqp1.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omamqp1_la-omamqp1.lo: omamqp1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omamqp1_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omamqp1_la-omamqp1.lo -MD -MP -MF $(DEPDIR)/omamqp1_la-omamqp1.Tpo -c -o omamqp1_la-omamqp1.lo `test -f 'omamqp1.c' || echo '$(srcdir)/'`omamqp1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omamqp1_la-omamqp1.Tpo $(DEPDIR)/omamqp1_la-omamqp1.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omamqp1.c' object='omamqp1_la-omamqp1.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omamqp1_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omamqp1_la-omamqp1.lo `test -f 'omamqp1.c' || echo '$(srcdir)/'`omamqp1.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omamqp1_la-omamqp1.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omamqp1_la-omamqp1.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmkubernetes0000644000000000000000000000013215114544373016624 xustar0030 mtime=1764935931.108697903 30 atime=1764935934.366747775 30 ctime=1764935931.108697903 rsyslog-8.2512.0/contrib/mmkubernetes/0000775000175000017500000000000015114544373016345 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmkubernetes/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020730 xustar0030 mtime=1752569012.329251042 30 atime=1764930928.439809248 30 ctime=1764935931.097697735 rsyslog-8.2512.0/contrib/mmkubernetes/Makefile.am0000664000175000017500000000053215035412264020374 0ustar00rgerrgerpkglib_LTLIBRARIES = mmkubernetes.la mmkubernetes_la_SOURCES = mmkubernetes.c mmkubernetes_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBLOGNORM_CFLAGS) mmkubernetes_la_LDFLAGS = -module -avoid-version mmkubernetes_la_LIBADD = $(CURL_LIBS) $(LIBLOGNORM_LIBS) EXTRA_DIST = k8s_filename.rulebase k8s_container_name.rulebase rsyslog-8.2512.0/contrib/mmkubernetes/PaxHeaders/mmkubernetes.c0000644000000000000000000000013115055605325021544 xustar0029 mtime=1756826325.61380014 30 atime=1764931106.893767062 30 ctime=1764935931.102697811 rsyslog-8.2512.0/contrib/mmkubernetes/mmkubernetes.c0000664000175000017500000025654715055605325021234 0ustar00rgerrger/* mmkubernetes.c * This is a message modification module. It uses metadata obtained * from the message to query Kubernetes and obtain additional metadata * relating to the container instance. * * Inspired by: * https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter * * NOTE: read comments in module-template.h for details on the calling interface! * * Copyright 2016 Red Hat Inc. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* needed for asprintf */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "module-template.h" #include "errmsg.h" #include "statsobj.h" #include "regexp.h" #include "hashtable.h" #include "hashtable_itr.h" #include "srUtils.h" #include "unicode-helper.h" #include "datetime.h" /* static data */ MODULE_TYPE_OUTPUT /* this is technically an output plugin */ MODULE_TYPE_KEEP /* releasing the module would cause a leak through libcurl */ MODULE_CNFNAME("mmkubernetes") DEF_OMOD_STATIC_DATA; DEFobjCurrIf(regexp) DEFobjCurrIf(statsobj) DEFobjCurrIf(datetime) #define HAVE_LOADSAMPLESFROMSTRING 1 #if defined(NO_LOADSAMPLESFROMSTRING) #undef HAVE_LOADSAMPLESFROMSTRING #endif /* original from fluentd plugin: * 'var\.log\.containers\.(?[a-z0-9]([-a-z0-9]*[a-z0-9])?\ * (\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?[^_]+)_\ * (?.+)-(?[a-z0-9]{64})\.log$' * this is for _tag_ match, not actual filename match - in_tail turns filename * into a fluentd tag */ #define DFLT_FILENAME_LNRULES \ "rule=:/var/log/containers/%pod_name:char-to:_%_" \ "%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log" #define DFLT_FILENAME_RULEBASE "/etc/rsyslog.d/k8s_filename.rulebase" /* original from fluentd plugin: * '^(?[^_]+)_(?[^\._]+)\ * (\.(?[^_]+))?_(?[^_]+)_\ * (?[^_]+)_[^_]+_[^_]+$' */ #define DFLT_CONTAINER_LNRULES \ "rule=:%k8s_prefix:char-to:_%_%container_name:char-to:.%." \ "%container_hash:char-to:_%_" \ "%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest%\n" \ "rule=:%k8s_prefix:char-to:_%_%container_name:char-to:_%_" \ "%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest%" #define DFLT_CONTAINER_RULEBASE "/etc/rsyslog.d/k8s_container_name.rulebase" #define DFLT_SRCMD_PATH "$!metadata!filename" #define DFLT_DSTMD_PATH "$!" #define DFLT_DE_DOT 1 /* true */ #define DFLT_DE_DOT_SEPARATOR "_" #define DFLT_CONTAINER_NAME "$!CONTAINER_NAME" /* name of variable holding CONTAINER_NAME value */ #define DFLT_CONTAINER_ID_FULL "$!CONTAINER_ID_FULL" /* name of variable holding CONTAINER_ID_FULL value */ #define DFLT_KUBERNETES_URL "https://kubernetes.default.svc.cluster.local:443" #define DFLT_BUSY_RETRY_INTERVAL 5 /* retry every 5 seconds */ #define DFLT_SSL_PARTIAL_CHAIN 0 /* disallow X509_V_FLAG_PARTIAL_CHAIN by default */ #define DFLT_CACHE_ENTRY_TTL 3600 /* delete entries from the cache older than 3600 seconds */ #define DFLT_CACHE_EXPIRE_INTERVAL \ -1 /* delete all expired entries from the cache every N seconds \ -1 disables cache expiration/ttl checking \ 0 means - run cache expiration for every record */ /* only support setting the partial chain flag on openssl platforms that have the define */ #if defined(ENABLE_OPENSSL) && defined(X509_V_FLAG_PARTIAL_CHAIN) #define SUPPORT_SSL_PARTIAL_CHAIN 1 #endif struct cache_entry_s { time_t ttl; /* when this entry should expire */ void *data; /* the user data */ }; static struct cache_s { const uchar *kbUrl; struct hashtable *mdHt; struct hashtable *nsHt; pthread_mutex_t *cacheMtx; time_t lastBusyTime; /* when we got the last busy response from kubernetes */ time_t expirationTime; /* if cache expiration checking is enable, time to check for expiration */ } **caches; typedef struct { int nmemb; uchar **patterns; regex_t *regexps; } annotation_match_t; /* module configuration data */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ uchar *kubernetesUrl; /* scheme, host, port, and optional path prefix for Kubernetes API lookups */ uchar *srcMetadataPath; /* where to get data for kubernetes queries */ uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */ uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */ sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */ sbool skipVerifyHost; /* For testing/debugging - skip cert hostname verify (CURLOPT_SSL_VERIFYHOST FALSE) */ uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */ uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */ sbool de_dot; /* If true (default), convert '.' characters in labels & annotations to de_dot_separator */ uchar *de_dot_separator; /* separator character (default '_') to use for de_dotting */ size_t de_dot_separator_len; /* length of separator character */ annotation_match_t annotation_match; /* annotation keys must match these to be included in record */ char *fnRules; /* lognorm rules for container log filename match */ uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */ char *contRules; /* lognorm rules for CONTAINER_NAME value match */ uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */ int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */ sbool sslPartialChain; /* if true, allow using intermediate certs without root certs */ int cacheEntryTTL; /* delete entries from the cache if they are older than this many seconds */ int cacheExpireInterval; /* delete all expired entries from the cache every this many seconds */ }; /* action (instance) configuration data */ typedef struct _instanceData { uchar *kubernetesUrl; /* scheme, host, port, and optional path prefix for Kubernetes API lookups */ msgPropDescr_t *srcMetadataDescr; /* where to get data for kubernetes queries */ uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */ uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */ sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */ sbool skipVerifyHost; /* For testing/debugging - skip cert hostname verify (CURLOPT_SSL_VERIFYHOST FALSE) */ uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */ uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */ sbool de_dot; /* If true (default), convert '.' characters in labels & annotations to de_dot_separator */ uchar *de_dot_separator; /* separator character (default '_') to use for de_dotting */ size_t de_dot_separator_len; /* length of separator character */ annotation_match_t annotation_match; /* annotation keys must match these to be included in record */ char *fnRules; /* lognorm rules for container log filename match */ uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */ ln_ctx fnCtxln; /**< context to be used for liblognorm */ char *contRules; /* lognorm rules for CONTAINER_NAME value match */ uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */ ln_ctx contCtxln; /**< context to be used for liblognorm */ msgPropDescr_t *contNameDescr; /* CONTAINER_NAME field */ msgPropDescr_t *contIdFullDescr; /* CONTAINER_ID_FULL field */ struct cache_s *cache; int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */ sbool sslPartialChain; /* if true, allow using intermediate certs without root certs */ int cacheEntryTTL; /* delete entries from the cache if they are older than this many seconds */ int cacheExpireInterval; /* delete all expired entries from the cache every this many seconds */ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; CURL *curlCtx; struct curl_slist *curlHdr; char *curlRply; size_t curlRplyLen; statsobj_t *stats; /* stats for this instance */ STATSCOUNTER_DEF(k8sRecordSeen, mutK8sRecordSeen); STATSCOUNTER_DEF(namespaceMetadataSuccess, mutNamespaceMetadataSuccess); STATSCOUNTER_DEF(namespaceMetadataNotFound, mutNamespaceMetadataNotFound); STATSCOUNTER_DEF(namespaceMetadataBusy, mutNamespaceMetadataBusy); STATSCOUNTER_DEF(namespaceMetadataError, mutNamespaceMetadataError); STATSCOUNTER_DEF(podMetadataSuccess, mutPodMetadataSuccess); STATSCOUNTER_DEF(podMetadataNotFound, mutPodMetadataNotFound); STATSCOUNTER_DEF(podMetadataBusy, mutPodMetadataBusy); STATSCOUNTER_DEF(podMetadataError, mutPodMetadataError); STATSCOUNTER_DEF(podCacheNumEntries, mutPodCacheNumEntries); STATSCOUNTER_DEF(namespaceCacheNumEntries, mutNamespaceCacheNumEntries); STATSCOUNTER_DEF(podCacheHits, mutPodCacheHits); STATSCOUNTER_DEF(namespaceCacheHits, mutNamespaceCacheHits); /* cache misses should correspond to metadata success, busy, etc. k8s api calls */ STATSCOUNTER_DEF(podCacheMisses, mutPodCacheMisses); STATSCOUNTER_DEF(namespaceCacheMisses, mutNamespaceCacheMisses); } wrkrInstanceData_t; /* module parameters (v6 config format) */ static struct cnfparamdescr modpdescr[] = {{"kubernetesurl", eCmdHdlrString, 0}, {"srcmetadatapath", eCmdHdlrString, 0}, {"dstmetadatapath", eCmdHdlrString, 0}, {"tls.cacert", eCmdHdlrString, 0}, {"tls.mycert", eCmdHdlrString, 0}, {"tls.myprivkey", eCmdHdlrString, 0}, {"allowunsignedcerts", eCmdHdlrBinary, 0}, {"skipverifyhost", eCmdHdlrBinary, 0}, {"token", eCmdHdlrString, 0}, {"tokenfile", eCmdHdlrString, 0}, {"annotation_match", eCmdHdlrArray, 0}, {"de_dot", eCmdHdlrBinary, 0}, {"de_dot_separator", eCmdHdlrString, 0}, {"filenamerulebase", eCmdHdlrString, 0}, {"containerrulebase", eCmdHdlrString, 0}, {"busyretryinterval", eCmdHdlrInt, 0}, {"sslpartialchain", eCmdHdlrBinary, 0}, {"cacheentryttl", eCmdHdlrInt, 0}, {"cacheexpireinterval", eCmdHdlrInt, 0} #if HAVE_LOADSAMPLESFROMSTRING == 1 , {"filenamerules", eCmdHdlrArray, 0}, {"containerrules", eCmdHdlrArray, 0} #endif }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* action (instance) parameters (v6 config format) */ static struct cnfparamdescr actpdescr[] = {{"kubernetesurl", eCmdHdlrString, 0}, {"srcmetadatapath", eCmdHdlrString, 0}, {"dstmetadatapath", eCmdHdlrString, 0}, {"tls.cacert", eCmdHdlrString, 0}, {"tls.mycert", eCmdHdlrString, 0}, {"tls.myprivkey", eCmdHdlrString, 0}, {"allowunsignedcerts", eCmdHdlrBinary, 0}, {"skipverifyhost", eCmdHdlrBinary, 0}, {"token", eCmdHdlrString, 0}, {"tokenfile", eCmdHdlrString, 0}, {"annotation_match", eCmdHdlrArray, 0}, {"de_dot", eCmdHdlrBinary, 0}, {"de_dot_separator", eCmdHdlrString, 0}, {"filenamerulebase", eCmdHdlrString, 0}, {"containerrulebase", eCmdHdlrString, 0}, {"busyretryinterval", eCmdHdlrInt, 0}, {"sslpartialchain", eCmdHdlrBinary, 0}, {"cacheentryttl", eCmdHdlrInt, 0}, {"cacheexpireinterval", eCmdHdlrInt, 0} #if HAVE_LOADSAMPLESFROMSTRING == 1 , {"filenamerules", eCmdHdlrArray, 0}, {"containerrules", eCmdHdlrArray, 0} #endif }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ static void free_annotationmatch(annotation_match_t *match) { if (match) { for (int ii = 0; ii < match->nmemb; ++ii) { if (match->patterns) free(match->patterns[ii]); if (match->regexps) regexp.regfree(&match->regexps[ii]); } free(match->patterns); match->patterns = NULL; free(match->regexps); match->regexps = NULL; match->nmemb = 0; } } static int init_annotationmatch(annotation_match_t *match, struct cnfarray *ar) { DEFiRet; match->nmemb = ar->nmemb; CHKmalloc(match->patterns = calloc(match->nmemb, sizeof(uchar *))); CHKmalloc(match->regexps = calloc(match->nmemb, sizeof(regex_t))); for (int jj = 0; jj < ar->nmemb; ++jj) { int rexret = 0; match->patterns[jj] = (uchar *)es_str2cstr(ar->arr[jj], NULL); rexret = regexp.regcomp(&match->regexps[jj], (char *)match->patterns[jj], REG_EXTENDED | REG_NOSUB); if (0 != rexret) { char errMsg[512]; regexp.regerror(rexret, &match->regexps[jj], errMsg, sizeof(errMsg)); iRet = RS_RET_CONFIG_ERROR; LogError(0, iRet, "error: could not compile annotation_match string [%s]" " into an extended regexp - %d: %s\n", match->patterns[jj], rexret, errMsg); break; } } finalize_it: if (iRet) free_annotationmatch(match); RETiRet; } static int copy_annotationmatch(annotation_match_t *src, annotation_match_t *dest) { DEFiRet; dest->nmemb = src->nmemb; CHKmalloc(dest->patterns = malloc(sizeof(uchar *) * dest->nmemb)); CHKmalloc(dest->regexps = calloc(dest->nmemb, sizeof(regex_t))); for (int jj = 0; jj < src->nmemb; ++jj) { CHKmalloc(dest->patterns[jj] = (uchar *)strdup((char *)src->patterns[jj])); /* assumes was already successfully compiled */ regexp.regcomp(&dest->regexps[jj], (char *)dest->patterns[jj], REG_EXTENDED | REG_NOSUB); } finalize_it: if (iRet) free_annotationmatch(dest); RETiRet; } /* takes a hash of annotations and returns another json object hash containing only the * keys that match - this logic is taken directly from fluent-plugin-kubernetes_metadata_filter * except that we do not add the key multiple times to the object to be returned */ static struct json_object *match_annotations(annotation_match_t *match, struct json_object *annotations) { struct json_object *ret = NULL; for (int jj = 0; jj < match->nmemb; ++jj) { struct json_object_iterator it = json_object_iter_begin(annotations); struct json_object_iterator itEnd = json_object_iter_end(annotations); for (; !json_object_iter_equal(&it, &itEnd); json_object_iter_next(&it)) { const char *const key = json_object_iter_peek_name(&it); if (!ret || !fjson_object_object_get_ex(ret, key, NULL)) { if (!regexp.regexec(&match->regexps[jj], key, 0, NULL, 0)) { if (!ret) { ret = json_object_new_object(); } json_object_object_add(ret, key, json_object_get(json_object_iter_peek_value(&it))); } } } } return ret; } /* This will take a hash of labels or annotations and will de_dot the keys. * It will return a brand new hash. AFAICT, there is no safe way to * iterate over the hash while modifying it in place. */ static struct json_object *de_dot_json_object(struct json_object *jobj, const char *delim, size_t delim_len) { struct json_object *ret = NULL; struct json_object_iterator it = json_object_iter_begin(jobj); struct json_object_iterator itEnd = json_object_iter_end(jobj); es_str_t *new_es_key = NULL; DEFiRet; ret = json_object_new_object(); while (!json_object_iter_equal(&it, &itEnd)) { const char *const key = json_object_iter_peek_name(&it); const char *cc = strstr(key, "."); if (NULL == cc) { json_object_object_add(ret, key, json_object_get(json_object_iter_peek_value(&it))); } else { char *new_key = NULL; const char *prevcc = key; new_es_key = es_newStrFromCStr(key, (es_size_t)(cc - prevcc)); while (cc) { if (es_addBuf(&new_es_key, (char *)delim, (es_size_t)delim_len)) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); cc += 1; /* one past . */ prevcc = cc; /* beginning of next substring */ if ((cc = strstr(prevcc, ".")) || (cc = strchr(prevcc, '\0'))) { if (es_addBuf(&new_es_key, (char *)prevcc, (es_size_t)(cc - prevcc))) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); if (!*cc) cc = NULL; /* EOS - done */ } } new_key = es_str2cstr(new_es_key, NULL); es_deleteStr(new_es_key); new_es_key = NULL; json_object_object_add(ret, new_key, json_object_get(json_object_iter_peek_value(&it))); free(new_key); } json_object_iter_next(&it); } finalize_it: if (iRet != RS_RET_OK) { json_object_put(ret); ret = NULL; } if (new_es_key) es_deleteStr(new_es_key); return ret; } /* given a "metadata" object field, do * - make sure "annotations" field has only the matching keys * - de_dot the "labels" and "annotations" fields keys * This modifies the jMetadata object in place */ static void parse_labels_annotations( struct json_object *jMetadata, annotation_match_t *match, sbool de_dot, const char *delim, size_t delim_len) { struct json_object *jo = NULL; if (fjson_object_object_get_ex(jMetadata, "annotations", &jo)) { if ((jo = match_annotations(match, jo))) json_object_object_add(jMetadata, "annotations", jo); else json_object_object_del(jMetadata, "annotations"); } /* dedot labels and annotations */ if (de_dot) { struct json_object *jo2 = NULL; if (fjson_object_object_get_ex(jMetadata, "annotations", &jo)) { if ((jo2 = de_dot_json_object(jo, delim, delim_len))) { json_object_object_add(jMetadata, "annotations", jo2); } } if (fjson_object_object_get_ex(jMetadata, "labels", &jo)) { if ((jo2 = de_dot_json_object(jo, delim, delim_len))) { json_object_object_add(jMetadata, "labels", jo2); } } } } #if HAVE_LOADSAMPLESFROMSTRING == 1 static int array_to_rules(struct cnfarray *ar, char **rules) { DEFiRet; es_str_t *tmpstr = NULL; es_size_t size = 0; if (rules == NULL) FINALIZE; *rules = NULL; if (!ar->nmemb) FINALIZE; for (int jj = 0; jj < ar->nmemb; jj++) size += es_strlen(ar->arr[jj]); if (!size) FINALIZE; CHKmalloc(tmpstr = es_newStr(size)); CHKiRet((es_addStr(&tmpstr, ar->arr[0]))); CHKiRet((es_addBufConstcstr(&tmpstr, "\n"))); for (int jj = 1; jj < ar->nmemb; ++jj) { CHKiRet((es_addStr(&tmpstr, ar->arr[jj]))); CHKiRet((es_addBufConstcstr(&tmpstr, "\n"))); } CHKiRet((es_addBufConstcstr(&tmpstr, "\0"))); CHKmalloc(*rules = es_str2cstr(tmpstr, NULL)); finalize_it: if (tmpstr) { es_deleteStr(tmpstr); } if (iRet != RS_RET_OK) { free(*rules); *rules = NULL; } RETiRet; } #endif /* callback for liblognorm error messages */ static void errCallBack(void __attribute__((unused)) * cookie, const char *msg, size_t __attribute__((unused)) lenMsg) { LogError(0, RS_RET_ERR_LIBLOGNORM, "liblognorm error: %s", msg); } static rsRetVal set_lnctx(ln_ctx *ctxln, char *instRules, uchar *instRulebase, char *modRules, uchar *modRulebase) { DEFiRet; if (ctxln == NULL) FINALIZE; CHKmalloc(*ctxln = ln_initCtx()); ln_setErrMsgCB(*ctxln, errCallBack, NULL); if (instRules) { #if HAVE_LOADSAMPLESFROMSTRING == 1 if (ln_loadSamplesFromString(*ctxln, instRules) != 0) { LogError(0, RS_RET_NO_RULEBASE, "error: normalization rules '%s' " "could not be loaded", instRules); ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); } #else (void)instRules; #endif } else if (instRulebase) { if (ln_loadSamples(*ctxln, (char *)instRulebase) != 0) { LogError(0, RS_RET_NO_RULEBASE, "error: normalization rulebase '%s' " "could not be loaded", instRulebase); ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); } } else if (modRules) { #if HAVE_LOADSAMPLESFROMSTRING == 1 if (ln_loadSamplesFromString(*ctxln, modRules) != 0) { LogError(0, RS_RET_NO_RULEBASE, "error: normalization rules '%s' " "could not be loaded", modRules); ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); } #else (void)modRules; #endif } else if (modRulebase) { if (ln_loadSamples(*ctxln, (char *)modRulebase) != 0) { LogError(0, RS_RET_NO_RULEBASE, "error: normalization rulebase '%s' " "could not be loaded", modRulebase); ABORT_FINALIZE(RS_RET_ERR_LIBLOGNORM_SAMPDB_LOAD); } } finalize_it: if (iRet != RS_RET_OK) { ln_exitCtx(*ctxln); *ctxln = NULL; } RETiRet; } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; FILE *fp = NULL; int ret; char errStr[1024]; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "mmkubernetes: " "error processing module config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for mmkubernetes:\n"); cnfparamsPrint(&modpblk, pvals); } loadModConf->de_dot = DFLT_DE_DOT; loadModConf->busyRetryInterval = DFLT_BUSY_RETRY_INTERVAL; loadModConf->sslPartialChain = DFLT_SSL_PARTIAL_CHAIN; loadModConf->cacheEntryTTL = DFLT_CACHE_ENTRY_TTL; loadModConf->cacheExpireInterval = DFLT_CACHE_EXPIRE_INTERVAL; for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } else if (!strcmp(modpblk.descr[i].name, "kubernetesurl")) { free(loadModConf->kubernetesUrl); loadModConf->kubernetesUrl = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "srcmetadatapath")) { free(loadModConf->srcMetadataPath); loadModConf->srcMetadataPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); /* todo: sanitize the path */ } else if (!strcmp(modpblk.descr[i].name, "dstmetadatapath")) { free(loadModConf->dstMetadataPath); loadModConf->dstMetadataPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); /* todo: sanitize the path */ } else if (!strcmp(modpblk.descr[i].name, "tls.cacert")) { free(loadModConf->caCertFile); loadModConf->caCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->caCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: 'tls.cacert' file %s couldn't be accessed: %s\n", loadModConf->caCertFile, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(modpblk.descr[i].name, "tls.mycert")) { free(loadModConf->myCertFile); loadModConf->myCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->myCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: 'tls.mycert' file %s couldn't be accessed: %s\n", loadModConf->myCertFile, errStr); } else { fclose(fp); fp = NULL; } } else if (!strcmp(modpblk.descr[i].name, "tls.myprivkey")) { loadModConf->myPrivKeyFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->myPrivKeyFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", loadModConf->myPrivKeyFile, errStr); } else { fclose(fp); fp = NULL; } } else if (!strcmp(modpblk.descr[i].name, "allowunsignedcerts")) { loadModConf->allowUnsignedCerts = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "skipverifyhost")) { loadModConf->skipVerifyHost = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "token")) { free(loadModConf->token); loadModConf->token = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "tokenfile")) { free(loadModConf->tokenFile); loadModConf->tokenFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->tokenFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: token file %s couldn't be accessed: %s\n", loadModConf->tokenFile, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(modpblk.descr[i].name, "annotation_match")) { free_annotationmatch(&loadModConf->annotation_match); if ((ret = init_annotationmatch(&loadModConf->annotation_match, pvals[i].val.d.ar))) ABORT_FINALIZE(ret); } else if (!strcmp(modpblk.descr[i].name, "de_dot")) { loadModConf->de_dot = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "de_dot_separator")) { free(loadModConf->de_dot_separator); loadModConf->de_dot_separator = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); #if HAVE_LOADSAMPLESFROMSTRING == 1 } else if (!strcmp(modpblk.descr[i].name, "filenamerules")) { free(loadModConf->fnRules); CHKiRet((array_to_rules(pvals[i].val.d.ar, &loadModConf->fnRules))); #endif } else if (!strcmp(modpblk.descr[i].name, "filenamerulebase")) { free(loadModConf->fnRulebase); loadModConf->fnRulebase = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->fnRulebase, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: filenamerulebase file %s couldn't be accessed: %s\n", loadModConf->fnRulebase, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } #if HAVE_LOADSAMPLESFROMSTRING == 1 } else if (!strcmp(modpblk.descr[i].name, "containerrules")) { free(loadModConf->contRules); CHKiRet((array_to_rules(pvals[i].val.d.ar, &loadModConf->contRules))); #endif } else if (!strcmp(modpblk.descr[i].name, "containerrulebase")) { free(loadModConf->contRulebase); loadModConf->contRulebase = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)loadModConf->contRulebase, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: containerrulebase file %s couldn't be accessed: %s\n", loadModConf->contRulebase, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(modpblk.descr[i].name, "busyretryinterval")) { loadModConf->busyRetryInterval = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "sslpartialchain")) { #if defined(SUPPORT_SSL_PARTIAL_CHAIN) loadModConf->sslPartialChain = pvals[i].val.d.n; #else LogMsg(0, RS_RET_VALUE_NOT_IN_THIS_MODE, LOG_INFO, "sslpartialchain is only supported for OpenSSL\n"); #endif } else if (!strcmp(modpblk.descr[i].name, "cacheentryttl")) { loadModConf->cacheEntryTTL = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "cacheexpireinterval")) { loadModConf->cacheExpireInterval = pvals[i].val.d.n; } else { dbgprintf( "mmkubernetes: program error, non-handled " "param '%s' in module() block\n", modpblk.descr[i].name); /* todo: error message? */ } } #if HAVE_LOADSAMPLESFROMSTRING == 1 if (loadModConf->fnRules && loadModConf->fnRulebase) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: only 1 of filenamerules or filenamerulebase may be used"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (loadModConf->contRules && loadModConf->contRulebase) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: only 1 of containerrules or containerrulebase may be used"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } #endif if ((loadModConf->cacheExpireInterval > -1)) { if ((loadModConf->cacheEntryTTL < 0)) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: cacheentryttl value [%d] is invalid - " "value must be 0 or greater", loadModConf->cacheEntryTTL); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } /* set defaults */ if (loadModConf->srcMetadataPath == NULL) loadModConf->srcMetadataPath = (uchar *)strdup(DFLT_SRCMD_PATH); if (loadModConf->dstMetadataPath == NULL) loadModConf->dstMetadataPath = (uchar *)strdup(DFLT_DSTMD_PATH); if (loadModConf->de_dot_separator == NULL) loadModConf->de_dot_separator = (uchar *)strdup(DFLT_DE_DOT_SEPARATOR); if (loadModConf->de_dot_separator) loadModConf->de_dot_separator_len = strlen((const char *)loadModConf->de_dot_separator); #if HAVE_LOADSAMPLESFROMSTRING == 1 if (loadModConf->fnRules == NULL && loadModConf->fnRulebase == NULL) loadModConf->fnRules = strdup(DFLT_FILENAME_LNRULES); if (loadModConf->contRules == NULL && loadModConf->contRulebase == NULL) loadModConf->contRules = strdup(DFLT_CONTAINER_LNRULES); #else if (loadModConf->fnRulebase == NULL) loadModConf->fnRulebase = (uchar *)strdup(DFLT_FILENAME_RULEBASE); if (loadModConf->contRulebase == NULL) loadModConf->contRulebase = (uchar *)strdup(DFLT_CONTAINER_RULEBASE); #endif caches = calloc(1, sizeof(struct cache_s *)); finalize_it: if (fp) fclose(fp); if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINfreeInstance CODESTARTfreeInstance; free(pData->kubernetesUrl); msgPropDescrDestruct(pData->srcMetadataDescr); free(pData->srcMetadataDescr); free(pData->dstMetadataPath); free(pData->caCertFile); free(pData->myCertFile); free(pData->myPrivKeyFile); free(pData->token); free(pData->tokenFile); free(pData->fnRules); free(pData->fnRulebase); ln_exitCtx(pData->fnCtxln); free(pData->contRules); free(pData->contRulebase); ln_exitCtx(pData->contCtxln); free_annotationmatch(&pData->annotation_match); free(pData->de_dot_separator); msgPropDescrDestruct(pData->contNameDescr); free(pData->contNameDescr); msgPropDescrDestruct(pData->contIdFullDescr); free(pData->contIdFullDescr); ENDfreeInstance static size_t curlCB(char *data, size_t size, size_t nmemb, void *usrptr) { DEFiRet; wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t *)usrptr; char *buf; size_t newlen; newlen = pWrkrData->curlRplyLen + size * nmemb; CHKmalloc(buf = realloc(pWrkrData->curlRply, newlen)); memcpy(buf + pWrkrData->curlRplyLen, data, size * nmemb); pWrkrData->curlRply = buf; pWrkrData->curlRplyLen = newlen; finalize_it: if (iRet != RS_RET_OK) { return 0; } return size * nmemb; } #if defined(SUPPORT_SSL_PARTIAL_CHAIN) static CURLcode set_ssl_partial_chain(CURL *curl, void *ssl_ctx, void *userptr) { (void)userptr; /* currently unused */ CURLcode rv = CURLE_ABORTED_BY_CALLBACK; X509_STORE *store = NULL; store = SSL_CTX_get_cert_store((SSL_CTX *)ssl_ctx); if (!store) goto finalize_it; if (!X509_STORE_set_flags(store, X509_V_FLAG_PARTIAL_CHAIN)) goto finalize_it; rv = CURLE_OK; finalize_it: return rv; } #endif BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; CURL *ctx; struct curl_slist *hdr = NULL; char *tokenHdr = NULL; FILE *fp = NULL; char *token = NULL; char *statsName = NULL; CHKiRet(statsobj.Construct(&(pWrkrData->stats))); if ((-1 == asprintf(&statsName, "mmkubernetes(%s)", pWrkrData->pData->kubernetesUrl)) || (!statsName)) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } CHKiRet(statsobj.SetName(pWrkrData->stats, (uchar *)statsName)); free(statsName); statsName = NULL; CHKiRet(statsobj.SetOrigin(pWrkrData->stats, UCHAR_CONSTANT("mmkubernetes"))); STATSCOUNTER_INIT(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("recordseen"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->k8sRecordSeen))); STATSCOUNTER_INIT(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatasuccess"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataSuccess))); STATSCOUNTER_INIT(pWrkrData->namespaceMetadataNotFound, pWrkrData->mutNamespaceMetadataNotFound); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatanotfound"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataNotFound))); STATSCOUNTER_INIT(pWrkrData->namespaceMetadataBusy, pWrkrData->mutNamespaceMetadataBusy); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatabusy"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataBusy))); STATSCOUNTER_INIT(pWrkrData->namespaceMetadataError, pWrkrData->mutNamespaceMetadataError); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadataerror"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataError))); STATSCOUNTER_INIT(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatasuccess"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataSuccess))); STATSCOUNTER_INIT(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatanotfound"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataNotFound))); STATSCOUNTER_INIT(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatabusy"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataBusy))); STATSCOUNTER_INIT(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadataerror"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataError))); STATSCOUNTER_INIT(pWrkrData->namespaceCacheNumEntries, pWrkrData->mutNamespaceCacheNumEntries); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachenumentries"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheNumEntries))); STATSCOUNTER_INIT(pWrkrData->podCacheNumEntries, pWrkrData->mutPodCacheNumEntries); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachenumentries"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheNumEntries))); STATSCOUNTER_INIT(pWrkrData->namespaceCacheHits, pWrkrData->mutNamespaceCacheHits); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachehits"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheHits))); STATSCOUNTER_INIT(pWrkrData->podCacheHits, pWrkrData->mutPodCacheHits); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachehits"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheHits))); STATSCOUNTER_INIT(pWrkrData->namespaceCacheMisses, pWrkrData->mutNamespaceCacheMisses); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacecachemisses"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceCacheMisses))); STATSCOUNTER_INIT(pWrkrData->podCacheMisses, pWrkrData->mutPodCacheMisses); CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podcachemisses"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podCacheMisses))); CHKiRet(statsobj.ConstructFinalize(pWrkrData->stats)); hdr = curl_slist_append(hdr, "Content-Type: text/json; charset=utf-8"); if (pWrkrData->pData->token) { if ((-1 == asprintf(&tokenHdr, "Authorization: Bearer %s", pWrkrData->pData->token)) || (!tokenHdr)) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } } else if (pWrkrData->pData->tokenFile) { struct stat statbuf; fp = fopen((const char *)pWrkrData->pData->tokenFile, "r"); if (fp && !fstat(fileno(fp), &statbuf)) { size_t bytesread; CHKmalloc(token = malloc((statbuf.st_size + 1) * sizeof(char))); if (0 < (bytesread = fread(token, sizeof(char), statbuf.st_size, fp))) { token[bytesread] = '\0'; if ((-1 == asprintf(&tokenHdr, "Authorization: Bearer %s", token)) || (!tokenHdr)) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } } free(token); token = NULL; } if (fp) { fclose(fp); fp = NULL; } } if (tokenHdr) { hdr = curl_slist_append(hdr, tokenHdr); free(tokenHdr); } pWrkrData->curlHdr = hdr; ctx = curl_easy_init(); curl_easy_setopt(ctx, CURLOPT_HTTPHEADER, hdr); curl_easy_setopt(ctx, CURLOPT_WRITEFUNCTION, curlCB); curl_easy_setopt(ctx, CURLOPT_WRITEDATA, pWrkrData); if (pWrkrData->pData->caCertFile) curl_easy_setopt(ctx, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); if (pWrkrData->pData->myCertFile) curl_easy_setopt(ctx, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); if (pWrkrData->pData->myPrivKeyFile) curl_easy_setopt(ctx, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); if (pWrkrData->pData->allowUnsignedCerts) curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYPEER, 0); if (pWrkrData->pData->skipVerifyHost) curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYHOST, 0); #if defined(SUPPORT_SSL_PARTIAL_CHAIN) if (pWrkrData->pData->sslPartialChain) { curl_easy_setopt(ctx, CURLOPT_SSL_CTX_FUNCTION, set_ssl_partial_chain); curl_easy_setopt(ctx, CURLOPT_SSL_CTX_DATA, NULL); } #endif pWrkrData->curlCtx = ctx; finalize_it: free(token); free(statsName); if ((iRet != RS_RET_OK) && pWrkrData->stats) { statsobj.Destruct(&(pWrkrData->stats)); } if (fp) { fclose(fp); } ENDcreateWrkrInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; curl_easy_cleanup(pWrkrData->curlCtx); curl_slist_free_all(pWrkrData->curlHdr); statsobj.Destruct(&(pWrkrData->stats)); ENDfreeWrkrInstance /* next function is work-around to avoid type-unsafe casts. It looks * like not really needed in practice, but gcc 8 complains and doing * it 100% correct for sure does not hurt ;-) -- rgerhards, 2018-07-19 */ static void hashtable_json_object_put(void *jso) { json_object_put((struct fjson_object *)jso); } static void cache_entry_free(struct cache_entry_s *cache_entry) { if (NULL != cache_entry) { if (cache_entry->data) { hashtable_json_object_put(cache_entry->data); cache_entry->data = NULL; } free(cache_entry); } } static void cache_entry_free_raw(void *cache_entry_void) { cache_entry_free((struct cache_entry_s *)cache_entry_void); } static struct cache_s *cacheNew(instanceData *pData) { DEFiRet; struct cache_s *cache = NULL; time_t now; int need_mutex_destroy = 0; CHKmalloc(cache = (struct cache_s *)calloc(1, sizeof(struct cache_s))); CHKmalloc(cache->cacheMtx = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t))); CHKmalloc(cache->mdHt = create_hashtable(100, hash_from_string, key_equals_string, cache_entry_free_raw)); CHKmalloc(cache->nsHt = create_hashtable(100, hash_from_string, key_equals_string, cache_entry_free_raw)); CHKiConcCtrl(pthread_mutex_init(cache->cacheMtx, NULL)); need_mutex_destroy = 1; datetime.GetTime(&now); cache->kbUrl = pData->kubernetesUrl; cache->expirationTime = 0; if (pData->cacheExpireInterval > -1) cache->expirationTime = pData->cacheExpireInterval + pData->cacheEntryTTL + now; cache->lastBusyTime = 0; dbgprintf("mmkubernetes: created cache mdht [%p] nsht [%p]\n", cache->mdHt, cache->nsHt); finalize_it: if (iRet != RS_RET_OK) { LogError(errno, iRet, "mmkubernetes: cacheNew: unable to create metadata cache for %s", pData->kubernetesUrl); if (cache) { if (cache->mdHt) hashtable_destroy(cache->mdHt, 1); if (cache->nsHt) hashtable_destroy(cache->nsHt, 1); if (cache->cacheMtx) { if (need_mutex_destroy) pthread_mutex_destroy(cache->cacheMtx); free(cache->cacheMtx); } free(cache); cache = NULL; } } return cache; } static void cacheFree(struct cache_s *cache) { hashtable_destroy(cache->mdHt, 1); hashtable_destroy(cache->nsHt, 1); pthread_mutex_destroy(cache->cacheMtx); free(cache->cacheMtx); free(cache); } /* must be called with cache->cacheMtx held */ /* assumes caller has reference to jso (json_object_get or is a new object) */ static struct cache_entry_s *cache_entry_new(time_t ttl, struct fjson_object *jso) { DEFiRet; struct cache_entry_s *cache_entry = NULL; CHKmalloc(cache_entry = malloc(sizeof(struct cache_entry_s))); cache_entry->ttl = ttl; cache_entry->data = (void *)jso; finalize_it: if (iRet) { free(cache_entry); cache_entry = NULL; } return cache_entry; } static int cache_delete_expired_entries(wrkrInstanceData_t *pWrkrData, int isnsmd, time_t now) { struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; struct hashtable_itr *itr = NULL; int more; if ((pWrkrData->pData->cacheExpireInterval < 0) || (now < pWrkrData->pData->cache->expirationTime)) { return 0; /* not enabled or not time yet */ } /* set next expiration time */ pWrkrData->pData->cache->expirationTime = now + pWrkrData->pData->cacheExpireInterval; if (hashtable_count(ht) < 1) return 1; /* expire interval hit but nothing to do */ itr = hashtable_iterator(ht); if (NULL == itr) return 1; /* expire interval hit but nothing to do - err? */ do { struct cache_entry_s *cache_entry = (struct cache_entry_s *)hashtable_iterator_value(itr); if (now >= cache_entry->ttl) { cache_entry_free(cache_entry); if (isnsmd) { STATSCOUNTER_DEC(pWrkrData->namespaceCacheNumEntries, pWrkrData->mutNamespaceCacheNumEntries); } else { STATSCOUNTER_DEC(pWrkrData->podCacheNumEntries, pWrkrData->mutPodCacheNumEntries); } more = hashtable_iterator_remove(itr); } else { more = hashtable_iterator_advance(itr); } } while (more); free(itr); dbgprintf("mmkubernetes: cache_delete_expired_entries: cleaned [%s] cache - size is now [%llu]\n", isnsmd ? "namespace" : "pod", isnsmd ? pWrkrData->namespaceCacheNumEntries : pWrkrData->podCacheNumEntries); return 1; } /* must be called with cache->cacheMtx held */ static struct fjson_object *cache_entry_get(wrkrInstanceData_t *pWrkrData, int isnsmd, const char *key, time_t now) { struct fjson_object *jso = NULL; struct cache_entry_s *cache_entry = NULL; int checkttl = 1; struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; /* see if it is time for a general cache expiration */ if (cache_delete_expired_entries(pWrkrData, isnsmd, now)) checkttl = 0; /* no need to check ttl now */ cache_entry = (struct cache_entry_s *)hashtable_search(ht, (void *)key); if (cache_entry && checkttl && (now >= cache_entry->ttl)) { cache_entry = (struct cache_entry_s *)hashtable_remove(ht, (void *)key); if (isnsmd) { STATSCOUNTER_DEC(pWrkrData->namespaceCacheNumEntries, pWrkrData->mutNamespaceCacheNumEntries); } else { STATSCOUNTER_DEC(pWrkrData->podCacheNumEntries, pWrkrData->mutPodCacheNumEntries); } cache_entry_free(cache_entry); cache_entry = NULL; } if (cache_entry) { jso = (struct fjson_object *)cache_entry->data; if (isnsmd) { STATSCOUNTER_INC(pWrkrData->namespaceCacheHits, pWrkrData->mutNamespaceCacheHits); } else { STATSCOUNTER_INC(pWrkrData->podCacheHits, pWrkrData->mutPodCacheHits); } dbgprintf("mmkubernetes: cache_entry_get: cache hit for [%s] cache key [%s] - hits is now [%llu]\n", isnsmd ? "namespace" : "pod", key, isnsmd ? pWrkrData->namespaceCacheHits : pWrkrData->podCacheHits); } else { if (isnsmd) { STATSCOUNTER_INC(pWrkrData->namespaceCacheMisses, pWrkrData->mutNamespaceCacheMisses); } else { STATSCOUNTER_INC(pWrkrData->podCacheMisses, pWrkrData->mutPodCacheMisses); } dbgprintf("mmkubernetes: cache_entry_get: cache miss for [%s] cache key [%s] - misses is now [%llu]\n", isnsmd ? "namespace" : "pod", key, isnsmd ? pWrkrData->namespaceCacheMisses : pWrkrData->podCacheMisses); } return jso; } /* must be called with cache->cacheMtx held */ /* key is passed in - caller must copy or otherwise ensure it is ok to pass off * ownership */ static rsRetVal cache_entry_add(wrkrInstanceData_t *pWrkrData, int isnsmd, const char *key, struct fjson_object *jso, time_t now, const int bDupKey) { DEFiRet; struct cache_entry_s *cache_entry = NULL; struct hashtable *ht = isnsmd ? pWrkrData->pData->cache->nsHt : pWrkrData->pData->cache->mdHt; /* see if it is time for a general cache expiration */ (void)cache_delete_expired_entries(pWrkrData, isnsmd, now); CHKmalloc(cache_entry = cache_entry_new(now + pWrkrData->pData->cacheEntryTTL, jso)); if (cache_entry) { if (!hashtable_insert(ht, (void *)(bDupKey ? strdup(key) : key), cache_entry)) ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); if (isnsmd) { STATSCOUNTER_INC(pWrkrData->namespaceCacheNumEntries, pWrkrData->mutNamespaceCacheNumEntries); } else { STATSCOUNTER_INC(pWrkrData->podCacheNumEntries, pWrkrData->mutPodCacheNumEntries); } cache_entry = NULL; } finalize_it: if (cache_entry) cache_entry_free(cache_entry); return iRet; } /* must be called with cache->cacheMtx held */ static struct fjson_object *cache_entry_get_md(wrkrInstanceData_t *pWrkrData, const char *key, time_t now) { return cache_entry_get(pWrkrData, 0, key, now); } /* must be called with cache->cacheMtx held */ static struct fjson_object *cache_entry_get_nsmd(wrkrInstanceData_t *pWrkrData, const char *key, time_t now) { return cache_entry_get(pWrkrData, 1, key, now); } /* must be called with cache->cacheMtx held */ static rsRetVal cache_entry_add_md(wrkrInstanceData_t *pWrkrData, const char *key, struct fjson_object *jso, time_t now) { return cache_entry_add(pWrkrData, 0, key, jso, now, 0); } /* must be called with cache->cacheMtx held */ static rsRetVal cache_entry_add_nsmd(wrkrInstanceData_t *pWrkrData, const char *key, struct fjson_object *jso, time_t now) { return cache_entry_add(pWrkrData, 1, key, jso, now, 1); } BEGINnewActInst struct cnfparamvals *pvals = NULL; int i; FILE *fp = NULL; char *rxstr = NULL; char *srcMetadataPath = NULL; char errStr[1024]; CODESTARTnewActInst; DBGPRINTF("newActInst (mmkubernetes)\n"); pvals = nvlstGetParams(lst, &actpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "mmkubernetes: " "error processing config parameters [action(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("action param blk in mmkubernetes:\n"); cnfparamsPrint(&actpblk, pvals); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); pData->de_dot = loadModConf->de_dot; pData->allowUnsignedCerts = loadModConf->allowUnsignedCerts; pData->skipVerifyHost = loadModConf->skipVerifyHost; pData->busyRetryInterval = loadModConf->busyRetryInterval; pData->sslPartialChain = loadModConf->sslPartialChain; pData->cacheEntryTTL = loadModConf->cacheEntryTTL; pData->cacheExpireInterval = loadModConf->cacheExpireInterval; for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } else if (!strcmp(actpblk.descr[i].name, "kubernetesurl")) { free(pData->kubernetesUrl); pData->kubernetesUrl = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "srcmetadatapath")) { msgPropDescrDestruct(pData->srcMetadataDescr); free(pData->srcMetadataDescr); CHKmalloc(pData->srcMetadataDescr = malloc(sizeof(msgPropDescr_t))); srcMetadataPath = es_str2cstr(pvals[i].val.d.estr, NULL); CHKiRet(msgPropDescrFill(pData->srcMetadataDescr, (uchar *)srcMetadataPath, strlen(srcMetadataPath))); /* todo: sanitize the path */ } else if (!strcmp(actpblk.descr[i].name, "dstmetadatapath")) { free(pData->dstMetadataPath); pData->dstMetadataPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); /* todo: sanitize the path */ } else if (!strcmp(actpblk.descr[i].name, "tls.cacert")) { free(pData->caCertFile); pData->caCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->caCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: certificate file %s couldn't be accessed: %s\n", pData->caCertFile, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(actpblk.descr[i].name, "tls.mycert")) { pData->myCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->myCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: 'tls.mycert' file %s couldn't be accessed: %s\n", pData->myCertFile, errStr); } else { fclose(fp); fp = NULL; } } else if (!strcmp(actpblk.descr[i].name, "tls.myprivkey")) { pData->myPrivKeyFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->myPrivKeyFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", pData->myPrivKeyFile, errStr); } else { fclose(fp); fp = NULL; } } else if (!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) { pData->allowUnsignedCerts = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "skipverifyhost")) { pData->skipVerifyHost = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "token")) { free(pData->token); pData->token = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "tokenfile")) { free(pData->tokenFile); pData->tokenFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->tokenFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: token file %s couldn't be accessed: %s\n", pData->tokenFile, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(actpblk.descr[i].name, "annotation_match")) { free_annotationmatch(&pData->annotation_match); if (RS_RET_OK != (iRet = init_annotationmatch(&pData->annotation_match, pvals[i].val.d.ar))) ABORT_FINALIZE(iRet); } else if (!strcmp(actpblk.descr[i].name, "de_dot")) { pData->de_dot = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "de_dot_separator")) { free(pData->de_dot_separator); pData->de_dot_separator = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); #if HAVE_LOADSAMPLESFROMSTRING == 1 } else if (!strcmp(modpblk.descr[i].name, "filenamerules")) { free(pData->fnRules); CHKiRet((array_to_rules(pvals[i].val.d.ar, &pData->fnRules))); #endif } else if (!strcmp(modpblk.descr[i].name, "filenamerulebase")) { free(pData->fnRulebase); pData->fnRulebase = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->fnRulebase, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: filenamerulebase file %s couldn't be accessed: %s\n", pData->fnRulebase, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } #if HAVE_LOADSAMPLESFROMSTRING == 1 } else if (!strcmp(modpblk.descr[i].name, "containerrules")) { free(pData->contRules); CHKiRet((array_to_rules(pvals[i].val.d.ar, &pData->contRules))); #endif } else if (!strcmp(modpblk.descr[i].name, "containerrulebase")) { free(pData->contRulebase); pData->contRulebase = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->contRulebase, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); iRet = RS_RET_NO_FILE_ACCESS; LogError(0, iRet, "error: containerrulebase file %s couldn't be accessed: %s\n", pData->contRulebase, errStr); ABORT_FINALIZE(iRet); } else { fclose(fp); fp = NULL; } } else if (!strcmp(actpblk.descr[i].name, "busyretryinterval")) { pData->busyRetryInterval = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "sslpartialchain")) { #if defined(SUPPORT_SSL_PARTIAL_CHAIN) pData->sslPartialChain = pvals[i].val.d.n; #else LogMsg(0, RS_RET_VALUE_NOT_IN_THIS_MODE, LOG_INFO, "sslpartialchain is only supported for OpenSSL\n"); #endif } else if (!strcmp(actpblk.descr[i].name, "cacheentryttl")) { pData->cacheEntryTTL = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "cacheexpireinterval")) { pData->cacheExpireInterval = pvals[i].val.d.n; } else { dbgprintf( "mmkubernetes: program error, non-handled " "param '%s' in action() block\n", actpblk.descr[i].name); /* todo: error message? */ } } #if HAVE_LOADSAMPLESFROMSTRING == 1 if (pData->fnRules && pData->fnRulebase) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: only 1 of filenamerules or filenamerulebase may be used"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (pData->contRules && pData->contRulebase) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: only 1 of containerrules or containerrulebase may be used"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } #endif CHKiRet( set_lnctx(&pData->fnCtxln, pData->fnRules, pData->fnRulebase, loadModConf->fnRules, loadModConf->fnRulebase)); CHKiRet(set_lnctx(&pData->contCtxln, pData->contRules, pData->contRulebase, loadModConf->contRules, loadModConf->contRulebase)); if ((pData->cacheExpireInterval > -1)) { if ((pData->cacheEntryTTL < 0)) { LogError(0, RS_RET_CONFIG_ERROR, "mmkubernetes: cacheentryttl value [%d] is invalid - " "value must be 0 or greater", pData->cacheEntryTTL); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } } if (pData->kubernetesUrl == NULL) { if (loadModConf->kubernetesUrl == NULL) { CHKmalloc(pData->kubernetesUrl = (uchar *)strdup(DFLT_KUBERNETES_URL)); } else { CHKmalloc(pData->kubernetesUrl = (uchar *)strdup((char *)loadModConf->kubernetesUrl)); } } if (pData->srcMetadataDescr == NULL) { CHKmalloc(pData->srcMetadataDescr = malloc(sizeof(msgPropDescr_t))); CHKiRet(msgPropDescrFill(pData->srcMetadataDescr, loadModConf->srcMetadataPath, strlen((char *)loadModConf->srcMetadataPath))); } if (pData->dstMetadataPath == NULL) pData->dstMetadataPath = (uchar *)strdup((char *)loadModConf->dstMetadataPath); if (pData->caCertFile == NULL && loadModConf->caCertFile) pData->caCertFile = (uchar *)strdup((char *)loadModConf->caCertFile); if (pData->myCertFile == NULL && loadModConf->myCertFile) pData->myCertFile = (uchar *)strdup((char *)loadModConf->myCertFile); if (pData->myPrivKeyFile == NULL && loadModConf->myPrivKeyFile) pData->myPrivKeyFile = (uchar *)strdup((char *)loadModConf->myPrivKeyFile); if (pData->token == NULL && loadModConf->token) pData->token = (uchar *)strdup((char *)loadModConf->token); if (pData->tokenFile == NULL && loadModConf->tokenFile) pData->tokenFile = (uchar *)strdup((char *)loadModConf->tokenFile); if (pData->de_dot_separator == NULL && loadModConf->de_dot_separator) pData->de_dot_separator = (uchar *)strdup((char *)loadModConf->de_dot_separator); if ((pData->annotation_match.nmemb == 0) && (loadModConf->annotation_match.nmemb > 0)) copy_annotationmatch(&loadModConf->annotation_match, &pData->annotation_match); if (pData->de_dot_separator) pData->de_dot_separator_len = strlen((const char *)pData->de_dot_separator); CHKmalloc(pData->contNameDescr = malloc(sizeof(msgPropDescr_t))); CHKiRet(msgPropDescrFill(pData->contNameDescr, (uchar *)DFLT_CONTAINER_NAME, strlen(DFLT_CONTAINER_NAME))); CHKmalloc(pData->contIdFullDescr = malloc(sizeof(msgPropDescr_t))); CHKiRet(msgPropDescrFill(pData->contIdFullDescr, (uchar *)DFLT_CONTAINER_ID_FULL, strlen(DFLT_CONTAINER_NAME))); /* get the cache for this url */ for (i = 0; caches[i] != NULL; i++) { if (!strcmp((char *)pData->kubernetesUrl, (char *)caches[i]->kbUrl)) break; } if (caches[i] != NULL) { pData->cache = caches[i]; } else { CHKmalloc(pData->cache = cacheNew(pData)); struct cache_s **new_caches = realloc(caches, (i + 2) * sizeof(struct cache_s *)); CHKmalloc(new_caches); caches = new_caches; caches[i] = pData->cache; caches[i + 1] = NULL; } CODE_STD_FINALIZERnewActInst; if (pvals != NULL) cnfparamvalsDestruct(pvals, &actpblk); if (fp) fclose(fp); free(rxstr); free(srcMetadataPath); ENDnewActInst /* legacy config format is not supported */ BEGINparseSelectorAct CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) if (strncmp((char *)p, ":mmkubernetes:", sizeof(":mmkubernetes:") - 1)) { LogError(0, RS_RET_LEGA_ACT_NOT_SUPPORTED, "mmkubernetes supports only v6+ config format, use: " "action(type=\"mmkubernetes\" ...)"); } ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; int i; free(pModConf->kubernetesUrl); free(pModConf->srcMetadataPath); free(pModConf->dstMetadataPath); free(pModConf->caCertFile); free(pModConf->myCertFile); free(pModConf->myPrivKeyFile); free(pModConf->token); free(pModConf->tokenFile); free(pModConf->de_dot_separator); free(pModConf->fnRules); free(pModConf->fnRulebase); free(pModConf->contRules); free(pModConf->contRulebase); free_annotationmatch(&pModConf->annotation_match); for (i = 0; caches[i] != NULL; i++) { dbgprintf("mmkubernetes: freeing cache [%d] mdht [%p] nsht [%p]\n", i, caches[i]->mdHt, caches[i]->nsHt); cacheFree(caches[i]); } free(caches); ENDfreeCnf BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; dbgprintf("mmkubernetes\n"); dbgprintf("\tkubernetesUrl='%s'\n", pData->kubernetesUrl); dbgprintf("\tsrcMetadataPath='%s'\n", pData->srcMetadataDescr->name); dbgprintf("\tdstMetadataPath='%s'\n", pData->dstMetadataPath); dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile); dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile); dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile); dbgprintf("\tallowUnsignedCerts='%d'\n", pData->allowUnsignedCerts); dbgprintf("\tskipVerifyHost='%d'\n", pData->skipVerifyHost); dbgprintf("\ttoken='%s'\n", pData->token); dbgprintf("\ttokenFile='%s'\n", pData->tokenFile); dbgprintf("\tde_dot='%d'\n", pData->de_dot); dbgprintf("\tde_dot_separator='%s'\n", pData->de_dot_separator); dbgprintf("\tfilenamerulebase='%s'\n", pData->fnRulebase); dbgprintf("\tcontainerrulebase='%s'\n", pData->contRulebase); #if HAVE_LOADSAMPLESFROMSTRING == 1 dbgprintf("\tfilenamerules='%s'\n", pData->fnRules); dbgprintf("\tcontainerrules='%s'\n", pData->contRules); #endif dbgprintf("\tbusyretryinterval='%d'\n", pData->busyRetryInterval); dbgprintf("\tcacheentryttl='%d'\n", pData->cacheEntryTTL); dbgprintf("\tcacheexpireinterval='%d'\n", pData->cacheExpireInterval); ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume static rsRetVal extractMsgMetadata(smsg_t *pMsg, instanceData *pData, struct json_object **json) { DEFiRet; uchar *filename = NULL, *container_name = NULL, *container_id_full = NULL; rs_size_t fnLen, container_name_len, container_id_full_len; unsigned short freeFn = 0, free_container_name = 0, free_container_id_full = 0; int lnret; struct json_object *cnid = NULL; if (!json) FINALIZE; *json = NULL; /* extract metadata from the CONTAINER_NAME field and see if CONTAINER_ID_FULL is present */ container_name = MsgGetProp(pMsg, NULL, pData->contNameDescr, &container_name_len, &free_container_name, NULL); container_id_full = MsgGetProp(pMsg, NULL, pData->contIdFullDescr, &container_id_full_len, &free_container_id_full, NULL); if (container_name && container_id_full && container_name_len && container_id_full_len) { dbgprintf("mmkubernetes: CONTAINER_NAME: '%s' CONTAINER_ID_FULL: '%s'.\n", container_name, container_id_full); if ((lnret = ln_normalize(pData->contCtxln, (char *)container_name, container_name_len, json))) { if (LN_WRONGPARSER != lnret) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: error parsing container_name [%s]: [%d]", container_name, lnret); ABORT_FINALIZE(RS_RET_ERR); } /* else assume parser didn't find a match and fall through */ } else if (fjson_object_object_get_ex(*json, "pod_name", NULL) && fjson_object_object_get_ex(*json, "namespace_name", NULL) && fjson_object_object_get_ex(*json, "container_name", NULL)) { /* if we have fields for pod name, namespace name, container name, * and container id, we are good to go */ /* add field for container id */ json_object_object_add(*json, "container_id", json_object_new_string_len((const char *)container_id_full, container_id_full_len)); ABORT_FINALIZE(RS_RET_OK); } } /* extract metadata from the file name */ filename = MsgGetProp(pMsg, NULL, pData->srcMetadataDescr, &fnLen, &freeFn, NULL); if ((filename == NULL) || (fnLen == 0)) ABORT_FINALIZE(RS_RET_NOT_FOUND); dbgprintf("mmkubernetes: filename: '%s' len %d.\n", filename, fnLen); if ((lnret = ln_normalize(pData->fnCtxln, (char *)filename, fnLen, json))) { if (LN_WRONGPARSER != lnret) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: error parsing container_name [%s]: [%d]", filename, lnret); ABORT_FINALIZE(RS_RET_ERR); } else { /* no match */ ABORT_FINALIZE(RS_RET_NOT_FOUND); } } /* if we have fields for pod name, namespace name, container name, * and container id, we are good to go */ if (fjson_object_object_get_ex(*json, "pod_name", NULL) && fjson_object_object_get_ex(*json, "namespace_name", NULL) && fjson_object_object_get_ex(*json, "container_name_and_id", &cnid)) { /* parse container_name_and_id into container_name and container_id */ const char *container_name_and_id = json_object_get_string(cnid); const char *last_dash = NULL; if (container_name_and_id && (last_dash = strrchr(container_name_and_id, '-')) && *(last_dash + 1) && (last_dash != container_name_and_id)) { json_object_object_add( *json, "container_name", json_object_new_string_len(container_name_and_id, (int)(last_dash - container_name_and_id))); json_object_object_add(*json, "container_id", json_object_new_string(last_dash + 1)); ABORT_FINALIZE(RS_RET_OK); } } ABORT_FINALIZE(RS_RET_NOT_FOUND); finalize_it: if (freeFn) free(filename); if (free_container_name) free(container_name); if (free_container_id_full) free(container_id_full); if (iRet != RS_RET_OK) { json_object_put(*json); *json = NULL; } RETiRet; } static rsRetVal queryKB(wrkrInstanceData_t *pWrkrData, char *url, time_t now, struct json_object **rply) { DEFiRet; CURLcode ccode; struct json_tokener *jt = NULL; struct json_object *jo; long resp_code = 400; if (pWrkrData->pData->cache->lastBusyTime) { now -= pWrkrData->pData->cache->lastBusyTime; if (now < pWrkrData->pData->busyRetryInterval) { LogMsg(0, RS_RET_RETRY, LOG_DEBUG, "mmkubernetes: Waited [%" PRId64 "] of [%d] seconds for " "the requested url [%s]\n", (int64_t)now, pWrkrData->pData->busyRetryInterval, url); ABORT_FINALIZE(RS_RET_RETRY); } else { LogMsg(0, RS_RET_OK, LOG_DEBUG, "mmkubernetes: Cleared busy status after [%d] seconds - " "will retry the requested url [%s]\n", pWrkrData->pData->busyRetryInterval, url); pWrkrData->pData->cache->lastBusyTime = 0; } } /* query kubernetes for pod info */ ccode = curl_easy_setopt(pWrkrData->curlCtx, CURLOPT_URL, url); if (ccode != CURLE_OK) ABORT_FINALIZE(RS_RET_ERR); if (CURLE_OK != (ccode = curl_easy_perform(pWrkrData->curlCtx))) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: failed to connect to [%s] - %d:%s\n", url, ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_SUSPENDED); } if (CURLE_OK != (ccode = curl_easy_getinfo(pWrkrData->curlCtx, CURLINFO_RESPONSE_CODE, &resp_code))) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: could not get response code from query to [%s] - %d:%s\n", url, ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } if (resp_code == 401) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: Unauthorized: not allowed to view url - " "check token/auth credentials [%s]\n", url); ABORT_FINALIZE(RS_RET_ERR); } if (resp_code == 403) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: Forbidden: no access - " "check permissions to view url [%s]\n", url); ABORT_FINALIZE(RS_RET_ERR); } if (resp_code == 404) { LogMsg(0, RS_RET_NOT_FOUND, LOG_INFO, "mmkubernetes: Not Found: the resource does not exist at url [%s]\n", url); ABORT_FINALIZE(RS_RET_NOT_FOUND); } if (resp_code == 429) { if (pWrkrData->pData->busyRetryInterval) { pWrkrData->pData->cache->lastBusyTime = now; } LogMsg(0, RS_RET_RETRY, LOG_INFO, "mmkubernetes: Too Many Requests: the server is too heavily loaded " "to provide the data for the requested url [%s]\n", url); ABORT_FINALIZE(RS_RET_RETRY); } if (resp_code != 200) { LogMsg(0, RS_RET_ERR, LOG_ERR, "mmkubernetes: server returned unexpected code [%ld] for url [%s]\n", resp_code, url); ABORT_FINALIZE(RS_RET_ERR); } /* parse retrieved data */ jt = json_tokener_new(); json_tokener_reset(jt); jo = json_tokener_parse_ex(jt, pWrkrData->curlRply, pWrkrData->curlRplyLen); json_tokener_free(jt); if (!json_object_is_type(jo, json_type_object)) { json_object_put(jo); jo = NULL; LogMsg(0, RS_RET_JSON_PARSE_ERR, LOG_INFO, "mmkubernetes: unable to parse string as JSON:[%.*s]\n", (int)pWrkrData->curlRplyLen, pWrkrData->curlRply); ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); } dbgprintf("mmkubernetes: queryKB reply:\n%s\n", json_object_to_json_string_ext(jo, JSON_C_TO_STRING_PRETTY)); *rply = jo; finalize_it: if (pWrkrData->curlRply != NULL) { free(pWrkrData->curlRply); pWrkrData->curlRply = NULL; pWrkrData->curlRplyLen = 0; } RETiRet; } /* versions < 8.16.0 don't support BEGINdoAction_NoStrings */ #if defined(BEGINdoAction_NoStrings) BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; #else BEGINdoAction smsg_t *pMsg = (smsg_t *)ppString[0]; #endif const char *podName = NULL, *ns = NULL, *containerName = NULL, *containerID = NULL; char *mdKey = NULL; struct json_object *jMetadata = NULL, *jMetadataCopy = NULL, *jMsgMeta = NULL, *jo = NULL; int add_pod_metadata = 1; time_t now; CODESTARTdoAction; CHKiRet_Hdlr(extractMsgMetadata(pMsg, pWrkrData->pData, &jMsgMeta)) { ABORT_FINALIZE((iRet == RS_RET_NOT_FOUND) ? RS_RET_OK : iRet); } datetime.GetTime(&now); STATSCOUNTER_INC(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen); if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo)) podName = json_object_get_string(jo); if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo)) ns = json_object_get_string(jo); if (fjson_object_object_get_ex(jMsgMeta, "container_name", &jo)) containerName = json_object_get_string(jo); if (fjson_object_object_get_ex(jMsgMeta, "container_id", &jo)) containerID = json_object_get_string(jo); assert(podName != NULL); assert(ns != NULL); assert(containerName != NULL); assert(containerID != NULL); dbgprintf( "mmkubernetes:\n podName: '%s'\n namespace: '%s'\n containerName: '%s'\n" " containerID: '%s'\n", podName, ns, containerName, containerID); /* check cache for metadata */ if ((-1 == asprintf(&mdKey, "%s_%s_%s", ns, podName, containerName)) || (!mdKey)) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pthread_mutex_lock(pWrkrData->pData->cache->cacheMtx); jMetadata = cache_entry_get_md(pWrkrData, mdKey, now); if (jMetadata == NULL) { char *url = NULL; struct json_object *jReply = NULL, *jo2 = NULL, *jNsMeta = NULL, *jPodData = NULL; /* check cache for namespace metadata */ jNsMeta = cache_entry_get_nsmd(pWrkrData, (const char *)ns, now); if (jNsMeta == NULL) { /* query kubernetes for namespace info */ /* todo: move url definitions elsewhere */ if ((-1 == asprintf(&url, "%s/api/v1/namespaces/%s", (char *)pWrkrData->pData->kubernetesUrl, ns)) || (!url)) { pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } iRet = queryKB(pWrkrData, url, now, &jReply); free(url); if (iRet == RS_RET_NOT_FOUND) { /* negative cache namespace - make a dummy empty namespace metadata object */ jNsMeta = json_object_new_object(); STATSCOUNTER_INC(pWrkrData->namespaceMetadataNotFound, pWrkrData->mutNamespaceMetadataNotFound); } else if (iRet == RS_RET_RETRY) { /* server is busy - retry or error */ STATSCOUNTER_INC(pWrkrData->namespaceMetadataBusy, pWrkrData->mutNamespaceMetadataBusy); if (0 == pWrkrData->pData->busyRetryInterval) { pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); ABORT_FINALIZE(RS_RET_ERR); } add_pod_metadata = 0; /* don't cache pod metadata either - retry both */ } else if (iRet != RS_RET_OK) { /* one of many possible transient errors: apiserver error, network, config, auth. * Instead of causing hard error and disabling this module, we can return * basic namespace metadata that is extracted from container log file path. * When transient error resolves, other metadata will become * available. For a new a new pod whose metadata is not yet cached, this * will allow 401, 403, 500, etc. return status from apiserver treated * similar to 404 returns. * */ jNsMeta = json_object_new_object(); STATSCOUNTER_INC(pWrkrData->namespaceMetadataError, pWrkrData->mutNamespaceMetadataError); } else if (fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) { jNsMeta = json_object_get(jNsMeta); parse_labels_annotations(jNsMeta, &pWrkrData->pData->annotation_match, pWrkrData->pData->de_dot, (const char *)pWrkrData->pData->de_dot_separator, pWrkrData->pData->de_dot_separator_len); STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess); } else { /* namespace with no metadata??? */ LogMsg(0, RS_RET_ERR, LOG_INFO, "mmkubernetes: namespace [%s] has no metadata!\n", ns); /* negative cache namespace - make a dummy empty namespace metadata object */ jNsMeta = json_object_new_object(); STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess); } if (jNsMeta) { if ((iRet = cache_entry_add_nsmd(pWrkrData, ns, jNsMeta, now))) { ABORT_FINALIZE(iRet); } } json_object_put(jReply); jReply = NULL; } if ((-1 == asprintf(&url, "%s/api/v1/namespaces/%s/pods/%s", (char *)pWrkrData->pData->kubernetesUrl, ns, podName)) || (!url)) { pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } iRet = queryKB(pWrkrData, url, now, &jReply); free(url); if (iRet == RS_RET_NOT_FOUND) { /* negative cache pod - make a dummy empty pod metadata object */ iRet = RS_RET_OK; STATSCOUNTER_INC(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound); } else if (iRet == RS_RET_RETRY) { /* server is busy - retry or error */ STATSCOUNTER_INC(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy); if (0 == pWrkrData->pData->busyRetryInterval) { pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); ABORT_FINALIZE(RS_RET_ERR); } add_pod_metadata = 0; /* do not cache so that we can retry */ iRet = RS_RET_OK; } else if (iRet != RS_RET_OK) { /* This is likely caused by transient apiserver errors: 401, 403, 500, etc. * Treat it similar to 404 while returning file path based pod metadata. * When transient error condition resolves, additional metadata will be * available for events originating from a new pod whose metatadata is not * yet cached. * */ iRet = RS_RET_OK; STATSCOUNTER_INC(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError); } else { STATSCOUNTER_INC(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess); } jo = json_object_new_object(); if (jNsMeta && fjson_object_object_get_ex(jNsMeta, "uid", &jo2)) json_object_object_add(jo, "namespace_id", json_object_get(jo2)); if (jNsMeta && fjson_object_object_get_ex(jNsMeta, "labels", &jo2)) json_object_object_add(jo, "namespace_labels", json_object_get(jo2)); if (jNsMeta && fjson_object_object_get_ex(jNsMeta, "annotations", &jo2)) json_object_object_add(jo, "namespace_annotations", json_object_get(jo2)); if (jNsMeta && fjson_object_object_get_ex(jNsMeta, "creationTimestamp", &jo2)) json_object_object_add(jo, "creation_timestamp", json_object_get(jo2)); if (fjson_object_object_get_ex(jReply, "metadata", &jPodData)) { if (fjson_object_object_get_ex(jPodData, "uid", &jo2)) json_object_object_add(jo, "pod_id", json_object_get(jo2)); parse_labels_annotations(jPodData, &pWrkrData->pData->annotation_match, pWrkrData->pData->de_dot, (const char *)pWrkrData->pData->de_dot_separator, pWrkrData->pData->de_dot_separator_len); if (fjson_object_object_get_ex(jPodData, "annotations", &jo2)) json_object_object_add(jo, "annotations", json_object_get(jo2)); if (fjson_object_object_get_ex(jPodData, "labels", &jo2)) json_object_object_add(jo, "labels", json_object_get(jo2)); } if (fjson_object_object_get_ex(jReply, "spec", &jPodData)) { if (fjson_object_object_get_ex(jPodData, "nodeName", &jo2)) { json_object_object_add(jo, "host", json_object_get(jo2)); } } json_object_put(jReply); jReply = NULL; if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo2)) json_object_object_add(jo, "pod_name", json_object_get(jo2)); if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo2)) json_object_object_add(jo, "namespace_name", json_object_get(jo2)); if (fjson_object_object_get_ex(jMsgMeta, "container_name", &jo2)) json_object_object_add(jo, "container_name", json_object_get(jo2)); json_object_object_add(jo, "master_url", json_object_new_string((const char *)pWrkrData->pData->kubernetesUrl)); jMetadata = json_object_new_object(); json_object_object_add(jMetadata, "kubernetes", jo); jo = json_object_new_object(); if (fjson_object_object_get_ex(jMsgMeta, "container_id", &jo2)) json_object_object_add(jo, "container_id", json_object_get(jo2)); json_object_object_add(jMetadata, "docker", jo); if (add_pod_metadata) { if ((iRet = cache_entry_add_md(pWrkrData, mdKey, jMetadata, now))) ABORT_FINALIZE(iRet); mdKey = NULL; } } /* make a copy of the metadata for the msg to own */ /* todo: use json_object_deep_copy when implementation available in libfastjson */ /* yes, this is expensive - but there is no other way to make this thread safe - we * can't allow the msg to have a shared pointer to an element inside the cache, * outside of the cache lock */ jMetadataCopy = json_tokener_parse(json_object_get_string(jMetadata)); if (!add_pod_metadata) { /* jMetadata object was created from scratch and not cached */ json_object_put(jMetadata); jMetadata = NULL; } pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx); /* the +1 is there to skip the leading '$' */ msgAddJSON(pMsg, (uchar *)pWrkrData->pData->dstMetadataPath + 1, jMetadataCopy, 0, 0); finalize_it: json_object_put(jMsgMeta); free(mdKey); ENDdoAction BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature /* all the macros bellow have to be in a specific order */ BEGINmodExit CODESTARTmodExit; curl_global_cleanup(); objRelease(datetime, CORE_COMPONENT); objRelease(regexp, LM_REGEXP_FILENAME); objRelease(statsobj, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmkubernetes: module compiled with rsyslog version %s.\n", VERSION); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(regexp, LM_REGEXP_FILENAME)); CHKiRet(objUse(datetime, CORE_COMPONENT)); /* CURL_GLOBAL_ALL initializes more than is needed but the * libcurl documentation discourages use of other values */ curl_global_init(CURL_GLOBAL_ALL); ENDmodInit rsyslog-8.2512.0/contrib/mmkubernetes/PaxHeaders/k8s_container_name.rulebase0000644000000000000000000000013215035412264024167 xustar0030 mtime=1752569012.329251042 30 atime=1764931154.943542611 30 ctime=1764935931.109697918 rsyslog-8.2512.0/contrib/mmkubernetes/k8s_container_name.rulebase0000664000175000017500000000050715035412264023635 0ustar00rgerrgerversion=2 rule=:%k8s_prefix:char-to:_%_%container_name:char-to:.%.%container_hash:char-to:_%_%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest% rule=:%k8s_prefix:char-to:_%_%container_name:char-to:_%_%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest% rsyslog-8.2512.0/contrib/mmkubernetes/PaxHeaders/k8s_filename.rulebase0000644000000000000000000000013215035412264022765 xustar0030 mtime=1752569012.329251042 30 atime=1764931154.935542483 30 ctime=1764935931.106697872 rsyslog-8.2512.0/contrib/mmkubernetes/k8s_filename.rulebase0000664000175000017500000000017215035412264022431 0ustar00rgerrgerversion=2 rule=:/var/log/containers/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log rsyslog-8.2512.0/contrib/mmkubernetes/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316020743 xustar0030 mtime=1764935886.027007563 30 atime=1764935896.848173314 30 ctime=1764935931.100697781 rsyslog-8.2512.0/contrib/mmkubernetes/Makefile.in0000664000175000017500000006410415114544316020414 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmkubernetes ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = mmkubernetes_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_mmkubernetes_la_OBJECTS = mmkubernetes_la-mmkubernetes.lo mmkubernetes_la_OBJECTS = $(am_mmkubernetes_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmkubernetes_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(mmkubernetes_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmkubernetes_la_SOURCES) DIST_SOURCES = $(mmkubernetes_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmkubernetes.la mmkubernetes_la_SOURCES = mmkubernetes.c mmkubernetes_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBLOGNORM_CFLAGS) mmkubernetes_la_LDFLAGS = -module -avoid-version mmkubernetes_la_LIBADD = $(CURL_LIBS) $(LIBLOGNORM_LIBS) EXTRA_DIST = k8s_filename.rulebase k8s_container_name.rulebase all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmkubernetes/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmkubernetes/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmkubernetes.la: $(mmkubernetes_la_OBJECTS) $(mmkubernetes_la_DEPENDENCIES) $(EXTRA_mmkubernetes_la_DEPENDENCIES) $(AM_V_CCLD)$(mmkubernetes_la_LINK) -rpath $(pkglibdir) $(mmkubernetes_la_OBJECTS) $(mmkubernetes_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmkubernetes_la-mmkubernetes.lo: mmkubernetes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmkubernetes_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmkubernetes_la-mmkubernetes.lo -MD -MP -MF $(DEPDIR)/mmkubernetes_la-mmkubernetes.Tpo -c -o mmkubernetes_la-mmkubernetes.lo `test -f 'mmkubernetes.c' || echo '$(srcdir)/'`mmkubernetes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmkubernetes_la-mmkubernetes.Tpo $(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmkubernetes.c' object='mmkubernetes_la-mmkubernetes.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmkubernetes_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmkubernetes_la-mmkubernetes.lo `test -f 'mmkubernetes.c' || echo '$(srcdir)/'`mmkubernetes.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmkubernetes_la-mmkubernetes.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/gnutls0000644000000000000000000000013015114544360015431 xustar0029 mtime=1764935920.45653483 30 atime=1764935930.172683575 29 ctime=1764935920.45653483 rsyslog-8.2512.0/contrib/gnutls/0000775000175000017500000000000015114544360015154 5ustar00rgerrgerrsyslog-8.2512.0/contrib/gnutls/PaxHeaders/cert.pem0000644000000000000000000000013215035412264017147 xustar0030 mtime=1752569012.326271887 30 atime=1764931121.688006676 30 ctime=1764935920.454534799 rsyslog-8.2512.0/contrib/gnutls/cert.pem0000664000175000017500000000165015035412264016615 0ustar00rgerrger-----BEGIN CERTIFICATE----- MIIChjCCAfGgAwIBAgIBADALBgkqhkiG9w0BAQUwWDELMAkGA1UEBhMCREUxHTAb BgNVBAoTFHJzeXNsb2cgdGVzdCByb290IENBMQswCQYDVQQLEwJDQTEdMBsGA1UE AxMUcnN5c2xvZy10ZXN0LXJvb3QtY2EwHhcNMDgwNTIwMTMwNDE5WhcNMTgwNTE4 MTMwNDI2WjA6MQswCQYDVQQGEwJERTEQMA4GA1UEChMHcnN5c2xvZzEZMBcGA1UE CxMQdGVzdCBjZXJ0aWZpY2F0ZTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGAxmHe fztJgaGxFYEceiUg0hdMlRVWBqoZelJ8BeXTDnXcu/5F2HtM+l+QDyDaGjKlx+NI K4rkj7d6Wd3AKPgOYS0VSDZe3a1xf9rRYzOthWTv7tYi4/LTqPXqN5lKE71dgrB/ /gOmvV/1YD776FIxVGCSAT0hHwkFC3slmpJSwD8CAwEAAaOBhDCBgTAMBgNVHRMB Af8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHREECzAJ ggdyc3lzbG9nMB0GA1UdDgQWBBQYu6eC9UALvC+5K5VOnFRi5OC98TAfBgNVHSME GDAWgBQzYQQgUm0YLNdarJnc2c1LxYVClDALBgkqhkiG9w0BAQUDgYEAXaymqsG9 PNBhhWIRFvXCDMaDM71vUtgSFoNUbxIV607ua2HQosPPM4EHIda6N6hdBK1bMQoG yqBwhvw0JVaVaO70Kbs2m2Ypk3YcpJtRqyp8q8+2y/w1Mk1QazFZC29aYgX2iNVf X4/x38YEL7Gu5vqPrTn++agnV4ZXECKuvLQ= -----END CERTIFICATE----- rsyslog-8.2512.0/contrib/gnutls/PaxHeaders/ca.pem0000644000000000000000000000013215035412264016575 xustar0030 mtime=1752569012.326271887 30 atime=1764931121.680006546 30 ctime=1764935920.451534754 rsyslog-8.2512.0/contrib/gnutls/ca.pem0000664000175000017500000000156715035412264016252 0ustar00rgerrger-----BEGIN CERTIFICATE----- MIICYjCCAc2gAwIBAgIBATALBgkqhkiG9w0BAQUwWDELMAkGA1UEBhMCREUxHTAb BgNVBAoTFHJzeXNsb2cgdGVzdCByb290IENBMQswCQYDVQQLEwJDQTEdMBsGA1UE AxMUcnN5c2xvZy10ZXN0LXJvb3QtY2EwHhcNMDgwNTIwMTI1ODEyWhcNMTgwNTE4 MTI1ODI0WjBYMQswCQYDVQQGEwJERTEdMBsGA1UEChMUcnN5c2xvZyB0ZXN0IHJv b3QgQ0ExCzAJBgNVBAsTAkNBMR0wGwYDVQQDExRyc3lzbG9nLXRlc3Qtcm9vdC1j YTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGAw2s+V+WCK7jx9MLpDD4pO8SCqq6Q nK/BptvKM+YeBrV9ud3lq6YgbpNmv3/wig43rqpolqk7PdDxTW/mdXPmM72oKr/N Fc2cAyOEXK8JTWiqwc//V4qMAnKFfLOxr1dr7WRD0k4Tc8+BWJMQjL2zmGXiSGEF YWYIFHLmnX4ZgyMCAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8E BQMDBwYAMB0GA1UdDgQWBBQzYQQgUm0YLNdarJnc2c1LxYVClDALBgkqhkiG9w0B AQUDgYEAuGWtH7Jkpa0n/izqQ5ddDQP/LT6taivCwlpEYEU9aumpQPWWxtYywKaP RfM1JTMLAiYd8MS7TJ8TYRvvR32Y02Y+OhXn11xERkWvBT2M9yzqX6hDfRueN7RT fPWsfm/NBTVojzjaECcTFenZid7PC5JiFbcU6PSUMZ49/JPhxAo= -----END CERTIFICATE----- rsyslog-8.2512.0/contrib/gnutls/PaxHeaders/key.pem0000644000000000000000000000013115035412264017001 xustar0030 mtime=1752569012.326271887 30 atime=1764931121.696006805 29 ctime=1764935920.45653483 rsyslog-8.2512.0/contrib/gnutls/key.pem0000664000175000017500000000156715035412264016457 0ustar00rgerrger-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDGYd5/O0mBobEVgRx6JSDSF0yVFVYGqhl6UnwF5dMOddy7/kXY e0z6X5APINoaMqXH40griuSPt3pZ3cAo+A5hLRVINl7drXF/2tFjM62FZO/u1iLj 8tOo9eo3mUoTvV2CsH/+A6a9X/VgPvvoUjFUYJIBPSEfCQULeyWaklLAPwIDAQAB AoGARIwKqmHc+0rYenq7UUVE+vMMBjNyHyllVkvsCMmpzMRS+i5ZCf1I0vZ0O5X5 ZrX7bH8PL+R1J2eZgjXKMR3NMZBuyKHewItD9t2rIC0eD/ITlwq3VybbaMsw666e INxSmax+dS5CEcLevHHP3c+Q7S7QAFiWV43TdFUGXWJktIkCQQDPQ5WAZ+/Tvv0Q vtRjXMeTVaw/bSuKNUeDzFkmGyePnFeCReNFtJLE9PFSQWcPuYcbZgU59JTfA5ac Un+cHm31AkEA9Qek+q7PcJ+kON9E6SNodCZn6gLyHjnWrq4tf8pZO3NvoX2QiuD4 rwF7KWjr6q1JzADpLtwXnuYEhyiLFjJA4wJAcElMCEnG2y+ASH8p7z7HfKGQdLg/ O1wMB3JA5e0WLK5lllUogI4IaZ3N02NNY25+rLBDqpc/w+ZcxQnIypqNtQJATs9p ofON5wSB1oUBbhckZo9fxuWxqEUkJsUA/2Q+9R843XE8h166vdc1HOmRT8bywHne hmLl+gazmCFTMw1wzwJAHng+3zGUl4D8Ov3MPFD6hwYYK6/pEdtz/NUsCSazF7eK XuuP+DXPHNhXOuF1A3tP74pfc/fC1uCUH2G5z3Fy0Q== -----END RSA PRIVATE KEY----- rsyslog-8.2512.0/contrib/PaxHeaders/imdocker0000644000000000000000000000013115114544367015722 xustar0030 mtime=1764935927.696645671 29 atime=1764935930.17368359 30 ctime=1764935927.696645671 rsyslog-8.2512.0/contrib/imdocker/0000775000175000017500000000000015114544367015444 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imdocker/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264020023 xustar0030 mtime=1752569012.327264939 30 atime=1764930927.616795279 29 ctime=1764935927.69264561 rsyslog-8.2512.0/contrib/imdocker/Makefile.am0000664000175000017500000000036615035412264017475 0ustar00rgerrgerpkglib_LTLIBRARIES = imdocker.la imdocker_la_SOURCES = imdocker.c imdocker_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(CURL_CFLAGS) $(LIBLOGGING_STDLOG_CFLAGS) imdocker_la_LDFLAGS = -module -avoid-version imdocker_la_LIBADD = $(CURL_LIBS) rsyslog-8.2512.0/contrib/imdocker/PaxHeaders/imdocker.c0000644000000000000000000000013215114522477017737 xustar0030 mtime=1764926783.006631146 30 atime=1764926784.225661069 30 ctime=1764935927.697645686 rsyslog-8.2512.0/contrib/imdocker/imdocker.c0000664000175000017500000017073715114522477017422 0ustar00rgerrger/* imdocker.c * This is an implementation of the docker container log input module. It uses the * Docker API in order to stream all container logs available on a host. Will also * update relevant container metadata. * * Copyright (C) 2018, 2025 the rsyslog project. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef __sun #define _XPG4_2 #endif #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include "cfsysline.h" /* access to config file objects */ #include "unicode-helper.h" #include "module-template.h" #include "srUtils.h" /* some utility functions */ #include "errmsg.h" #include "net.h" #include "glbl.h" #include "msg.h" #include "parser.h" #include "prop.h" #include "debug.h" #include "statsobj.h" #include "datetime.h" #include "ratelimit.h" #include "hashtable.h" #include "hashtable_itr.h" #if !defined(_AIX) #pragma GCC diagnostic ignored "-Wswitch-enum" #endif MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imdocker") extern int Debug; #define USE_MULTI_LINE #undef ENABLE_DEBUG_BYTE_BUFFER /* defines */ #define DOCKER_TAG_NAME "docker:" #define DOCKER_CONTAINER_ID_PARSE_NAME "Id" #define DOCKER_CONTAINER_NAMES_PARSE_NAME "Names" #define DOCKER_CONTAINER_IMAGE_PARSE_NAME "Image" #define DOCKER_CONTAINER_IMAGEID_PARSE_NAME "ImageID" #define DOCKER_CONTAINER_CREATED_PARSE_NAME "Created" #define DOCKER_CONTAINER_LABELS_PARSE_NAME "Labels" /* label defines */ #define DOCKER_CONTAINER_LABEL_KEY_STARTREGEX "imdocker.startregex" /* DEFAULT VALUES */ #define DFLT_pollingInterval 60 /* polling interval in seconds */ #define DFLT_retrieveNewLogsFromStart 1 /* Process newly found containers logs from start */ #define DFLT_containersLimit 25 /* maximum number of containers */ #define DFLT_trimLineOverBytes 4194304 /* limit log lines to the value - 4MB default */ #define DFLT_bEscapeLF 1 /* whether line feeds should be escaped */ #define DFLT_SEVERITY pri2sev(LOG_INFO) #define DFLT_FACILITY pri2fac(LOG_USER) enum { dst_invalid = -1, dst_stdin, dst_stdout, dst_stderr, dst_stream_type_count } docker_stream_type_t; /* imdocker specific structs */ typedef struct imdocker_buf_s { uchar *data; size_t len; size_t data_size; } imdocker_buf_t; typedef struct docker_cont_logs_buf_s { imdocker_buf_t *buf; int8_t stream_type; size_t bytes_remaining; } docker_cont_logs_buf_t; struct docker_cont_logs_inst_s; typedef rsRetVal (*submitmsg_funcptr)(struct docker_cont_logs_inst_s *pInst, docker_cont_logs_buf_t *pBufdata, const uchar *pszTag); typedef submitmsg_funcptr SubmitMsgFuncPtr; /* curl request instance */ typedef struct docker_cont_logs_req_s { CURL *curl; docker_cont_logs_buf_t *data_bufs[dst_stream_type_count]; SubmitMsgFuncPtr submitMsg; } docker_cont_logs_req_t; typedef struct imdocker_req_s { CURL *curl; imdocker_buf_t *buf; } imdocker_req_t; typedef struct docker_container_info_s { uchar *name; uchar *image; uchar *image_id; uint64_t created; /* json string container labels */ uchar *json_str_labels; } docker_container_info_t; typedef struct docker_cont_logs_inst_s { char *id; char short_id[12]; docker_container_info_t *container_info; docker_cont_logs_req_t *logsReq; uchar *start_regex; regex_t start_preg; /* compiled version of start_regex */ uint32_t prevSegEnd; } docker_cont_logs_inst_t; typedef struct docker_cont_log_instances_s { struct hashtable *ht_container_log_insts; pthread_mutex_t mut; CURLM *curlm; /* track the latest created container */ uint64_t last_container_created; uchar *last_container_id; time_t time_started; } docker_cont_log_instances_t; /* FORWARD DEFINITIONS */ /* imdocker_buf_t */ static rsRetVal imdockerBufNew(imdocker_buf_t **ppThis); static void imdockerBufDestruct(imdocker_buf_t *pThis); /* docker_cont_logs_buf_t */ static rsRetVal dockerContLogsBufNew(docker_cont_logs_buf_t **ppThis); static void dockerContLogsBufDestruct(docker_cont_logs_buf_t *pThis); static rsRetVal dockerContLogsBufWrite(docker_cont_logs_buf_t *pThis, const uchar *pdata, size_t write_size); /* imdocker_req_t */ static rsRetVal imdockerReqNew(imdocker_req_t **ppThis); static void imdockerReqDestruct(imdocker_req_t *pThis); /* docker_cont_logs_req_t */ static rsRetVal dockerContLogsReqNew(docker_cont_logs_req_t **ppThis, SubmitMsgFuncPtr submitMsg); static void dockerContLogsReqDestruct(docker_cont_logs_req_t *pThis); /* docker_cont_logs_inst_t */ static rsRetVal dockerContLogsInstNew(docker_cont_logs_inst_t **ppThis, const char *id, docker_container_info_t *container_info, SubmitMsgFuncPtr submitMsg); static void dockerContLogsInstDestruct(docker_cont_logs_inst_t *pThis); static rsRetVal dockerContLogsInstSetUrlById(sbool isInit, docker_cont_logs_inst_t *pThis, CURLM *curlm, const char *containerId); /* docker_cont_log_instances_t */ static rsRetVal dockerContLogReqsNew(docker_cont_log_instances_t **ppThis); static rsRetVal dockerContLogReqsDestruct(docker_cont_log_instances_t *pThis); static rsRetVal dockerContLogReqsGet(docker_cont_log_instances_t *pThis, docker_cont_logs_inst_t **ppContLogsInst, const char *id); static rsRetVal dockerContLogReqsPrint(docker_cont_log_instances_t *pThis); static rsRetVal dockerContLogReqsAdd(docker_cont_log_instances_t *pThis, docker_cont_logs_inst_t *pContLogsReqInst); static rsRetVal dockerContLogReqsRemove(docker_cont_log_instances_t *pThis, const char *id); /* docker_container_info_t */ static rsRetVal dockerContainerInfoNew(docker_container_info_t **pThis); static void dockerContainerInfoDestruct(docker_container_info_t *pThis); /* utility functions */ static CURLcode docker_get(imdocker_req_t *req, const char *url); static char *dupDockerContainerName(const char *pname); static rsRetVal SubmitMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag); /* support multi-line */ static rsRetVal SubmitMsg2(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag); static size_t imdocker_container_list_curlCB(void *data, size_t size, size_t nmemb, void *buffer); static size_t imdocker_container_logs_curlCB(void *data, size_t size, size_t nmemb, void *buffer); static sbool get_stream_info(const uchar *data, size_t size, int8_t *stream_type, size_t *payload_size); static int8_t is_valid_stream_type(int8_t stream_type); /* Module static data */ DEF_IMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) DEFobjCurrIf(statsobj) statsobj_t *modStats; STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) STATSCOUNTER_DEF(ctrLostRatelimit, mutCtrLostRatelimit) STATSCOUNTER_DEF(ctrCurlError, mutCtrCurlError) const char *DFLT_dockerAPIUnixSockAddr = "/var/run/docker.sock"; const char *DFLT_dockerAPIAdd = "http://localhost:2375"; const char *DFLT_apiVersionStr = "v1.27"; const char *DFLT_listContainersOptions = ""; const char *DFLT_getContainerLogOptions = "timestamps=0&follow=1&stdout=1&stderr=1&tail=1"; const char *DFLT_getContainerLogOptionsWithoutTail = "timestamps=0&follow=1&stdout=1&stderr=1"; /* Overall module configuration structure here. */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ uchar *apiVersionStr; uchar *listContainersOptions; uchar *getContainerLogOptions; uchar *getContainerLogOptionsWithoutTail; int iPollInterval; /* in seconds */ uchar *dockerApiUnixSockAddr; uchar *dockerApiAddr; sbool retrieveNewLogsFromStart; int containersLimit; int trimLineOverBytes; int iDfltSeverity; int iDfltFacility; sbool bEscapeLf; }; static modConfData_t *loadModConf = NULL; static modConfData_t *runModConf = NULL; static prop_t *pInputName = NULL; /* our inputName currently is always "imdocker", and this will hold it */ static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */ static ratelimit_t *ratelimiter = NULL; /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"apiversionstr", eCmdHdlrString, 0}, {"dockerapiunixsockaddr", eCmdHdlrString, 0}, {"dockerapiaddr", eCmdHdlrString, 0}, {"listcontainersoptions", eCmdHdlrString, 0}, {"getcontainerlogoptions", eCmdHdlrString, 0}, {"pollinginterval", eCmdHdlrPositiveInt, 0}, {"retrievenewlogsfromstart", eCmdHdlrBinary, 0}, {"trimlineoverbytes", eCmdHdlrPositiveInt, 0}, {"defaultseverity", eCmdHdlrSeverity, 0}, {"defaultfacility", eCmdHdlrFacility, 0}, {"escapelf", eCmdHdlrBinary, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; static int bLegacyCnfModGlobalsPermitted; /* are legacy module-global config parameters permitted? */ /* imdocker specific functions */ static rsRetVal imdockerBufNew(imdocker_buf_t **ppThis) { DEFiRet; imdocker_buf_t *pThis = (imdocker_buf_t *)calloc(1, sizeof(imdocker_buf_t)); if (!pThis) { return RS_RET_OUT_OF_MEMORY; } *ppThis = pThis; RETiRet; } static void imdockerBufDestruct(imdocker_buf_t *pThis) { if (pThis) { if (pThis->data) { free(pThis->data); pThis->data = NULL; } free(pThis); } } static rsRetVal dockerContLogsBufNew(docker_cont_logs_buf_t **ppThis) { DEFiRet; docker_cont_logs_buf_t *pThis = (docker_cont_logs_buf_t *)calloc(1, sizeof(docker_cont_logs_buf_t)); if (pThis && (iRet = imdockerBufNew(&pThis->buf)) == RS_RET_OK) { pThis->stream_type = dst_invalid; pThis->bytes_remaining = 0; *ppThis = pThis; } else { dockerContLogsBufDestruct(pThis); } RETiRet; } static void dockerContLogsBufDestruct(docker_cont_logs_buf_t *pThis) { if (pThis) { if (pThis->buf) { imdockerBufDestruct(pThis->buf); } free(pThis); } } static rsRetVal dockerContLogsBufWrite(docker_cont_logs_buf_t *const pThis, const uchar *const pdata, const size_t write_size) { DEFiRet; imdocker_buf_t *const mem = pThis->buf; if (mem->len + write_size + 1 > mem->data_size) { uchar *const pbuf = realloc(mem->data, mem->len + write_size + 1); if (pbuf == NULL) { LogError(errno, RS_RET_ERR, "%s() - realloc failed!\n", __FUNCTION__); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } mem->data = pbuf; mem->data_size = mem->len + write_size + 1; } /* copy the bytes, and advance pdata */ memcpy(&(mem->data[mem->len]), pdata, write_size); mem->len += write_size; mem->data[mem->len] = '\0'; if (write_size > pThis->bytes_remaining) { pThis->bytes_remaining = 0; } else { pThis->bytes_remaining -= write_size; } finalize_it: RETiRet; } rsRetVal imdockerReqNew(imdocker_req_t **ppThis) { DEFiRet; imdocker_req_t *pThis = (imdocker_req_t *)calloc(1, sizeof(imdocker_req_t)); CHKmalloc(pThis); pThis->curl = curl_easy_init(); if (!pThis->curl) { ABORT_FINALIZE(RS_RET_ERR); } CHKiRet(imdockerBufNew(&(pThis->buf))); *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK && pThis) { imdockerReqDestruct(pThis); } RETiRet; } void imdockerReqDestruct(imdocker_req_t *pThis) { if (pThis) { if (pThis->buf) { imdockerBufDestruct(pThis->buf); } if (pThis->curl) { curl_easy_cleanup(pThis->curl); pThis->curl = NULL; } free(pThis); } } static rsRetVal dockerContLogsReqNew(docker_cont_logs_req_t **ppThis, SubmitMsgFuncPtr submitMsg) { DEFiRet; docker_cont_logs_req_t *pThis = (docker_cont_logs_req_t *)calloc(1, sizeof(docker_cont_logs_req_t)); CHKmalloc(pThis); pThis->submitMsg = submitMsg; pThis->curl = curl_easy_init(); if (!pThis->curl) { ABORT_FINALIZE(RS_RET_ERR); } for (int i = 0; i < dst_stream_type_count; i++) { CHKiRet(dockerContLogsBufNew(&pThis->data_bufs[i])); } *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK) { if (pThis) { dockerContLogsReqDestruct(pThis); } } RETiRet; } static void dockerContLogsReqDestruct(docker_cont_logs_req_t *pThis) { if (pThis) { for (int i = 0; i < dst_stream_type_count; i++) { dockerContLogsBufDestruct(pThis->data_bufs[i]); } if (pThis->curl) { curl_easy_cleanup(pThis->curl); pThis->curl = NULL; } free(pThis); } } /** * debugging aide */ static rsRetVal dockerContLogsInstPrint(docker_cont_logs_inst_t *pThis) { DEFiRet; DBGPRINTF("\t container id: %s\n", pThis->id); char *pUrl = NULL; curl_easy_getinfo(pThis->logsReq->curl, CURLINFO_EFFECTIVE_URL, &pUrl); DBGPRINTF("\t container url: %s\n", pUrl); RETiRet; } static void dockerContLogsInstDestruct(docker_cont_logs_inst_t *pThis) { if (pThis) { if (pThis->id) { free((void *)pThis->id); } if (pThis->container_info) { dockerContainerInfoDestruct(pThis->container_info); } if (pThis->logsReq) { dockerContLogsReqDestruct(pThis->logsReq); } if (pThis->start_regex) { free(pThis->start_regex); regfree(&pThis->start_preg); } free(pThis); } } static rsRetVal parseLabels(docker_cont_logs_inst_t *inst, const uchar *json) { DEFiRet; /* parse out if we need to do special handling for mult-line */ DBGPRINTF("%s() - parsing json=%s\n", __FUNCTION__, json); struct fjson_object *json_obj = fjson_tokener_parse((const char *)json); struct fjson_object_iterator it = fjson_object_iter_begin(json_obj); struct fjson_object_iterator itEnd = fjson_object_iter_end(json_obj); while (!fjson_object_iter_equal(&it, &itEnd)) { if (Debug) { DBGPRINTF("%s - \t%s: '%s'\n", __FUNCTION__, fjson_object_iter_peek_name(&it), fjson_object_get_string(fjson_object_iter_peek_value(&it))); } if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_LABEL_KEY_STARTREGEX) == 0) { inst->start_regex = (uchar *)strdup(fjson_object_get_string(fjson_object_iter_peek_value(&it))); // compile the regex for future use. int err = regcomp(&inst->start_preg, fjson_object_get_string(fjson_object_iter_peek_value(&it)), REG_EXTENDED); if (err != 0) { char errbuf[512]; regerror(err, &inst->start_preg, errbuf, sizeof(errbuf)); LogError(0, err, "%s() - error in startregex compile: %s", __FUNCTION__, errbuf); ABORT_FINALIZE(RS_RET_ERR); } } fjson_object_iter_next(&it); } finalize_it: if (json_obj) { json_object_put(json_obj); } RETiRet; } static rsRetVal dockerContLogsInstNew(docker_cont_logs_inst_t **ppThis, const char *id, docker_container_info_t *container_info, SubmitMsgFuncPtr submitMsg) { DEFiRet; docker_cont_logs_inst_t *pThis = NULL; CHKmalloc(pThis = calloc(1, sizeof(docker_cont_logs_inst_t))); pThis->id = strdup((char *)id); strncpy((char *)pThis->short_id, id, sizeof(pThis->short_id) - 1); CHKiRet(dockerContLogsReqNew(&pThis->logsReq, submitMsg)); /* make a copy */ if (container_info) { CHKiRet(dockerContainerInfoNew(&pThis->container_info)); if (container_info->image) { pThis->container_info->image = (uchar *)strdup((char *)container_info->image); } if (container_info->image_id) { pThis->container_info->image_id = (uchar *)strdup((char *)container_info->image_id); } if (container_info->name) { const char *pname = (const char *)container_info->name; /* removes un-needed characters */ pThis->container_info->name = (uchar *)dupDockerContainerName(pname); } if (container_info->json_str_labels) { pThis->container_info->json_str_labels = (uchar *)strdup((char *)container_info->json_str_labels); } pThis->container_info->created = container_info->created; } pThis->start_regex = NULL; pThis->prevSegEnd = 0; /* initialize based on labels found */ if (pThis->container_info && pThis->container_info->json_str_labels) { parseLabels(pThis, pThis->container_info->json_str_labels); } *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK) { if (pThis) { dockerContLogsInstDestruct(pThis); } } RETiRet; } static rsRetVal dockerContLogsInstSetUrl(docker_cont_logs_inst_t *pThis, CURLM *curlm, const char *pUrl) { DEFiRet; CURLcode ccode = CURLE_OK; CURLMcode mcode = CURLM_OK; if (curlm) { docker_cont_logs_req_t *req = pThis->logsReq; if (!runModConf->dockerApiAddr) { ccode = curl_easy_setopt(req->curl, CURLOPT_UNIX_SOCKET_PATH, runModConf->dockerApiUnixSockAddr); if (ccode != CURLE_OK) { LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_UNIX_SOCKET_PATH) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } } ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEFUNCTION, imdocker_container_logs_curlCB); if (ccode != CURLE_OK) { LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEFUNCTION) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEDATA, pThis); if (ccode != CURLE_OK) { LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEDATA) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } ccode = curl_easy_setopt(pThis->logsReq->curl, CURLOPT_URL, pUrl); if (ccode != CURLE_OK) { LogError(0, RS_RET_ERR, "imdocker: could not set url - %d:%s\n", ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } ccode = curl_easy_setopt(pThis->logsReq->curl, CURLOPT_PRIVATE, pThis->id); if (ccode != CURLE_OK) { LogError(0, RS_RET_ERR, "imdocker: could not set private data - %d:%s\n", ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } mcode = curl_multi_add_handle(curlm, pThis->logsReq->curl); if (mcode != CURLM_OK) { LogError(0, RS_RET_ERR, "imdocker: error curl_multi_add_handle ret- %d:%s\n", mcode, curl_multi_strerror(mcode)); ABORT_FINALIZE(RS_RET_ERR); } } finalize_it: if (ccode != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); } RETiRet; } static rsRetVal dockerContLogsInstSetUrlById(sbool isInit, docker_cont_logs_inst_t *pThis, CURLM *curlm, const char *containerId) { char url[256]; const uchar *container_log_options = runModConf->getContainerLogOptionsWithoutTail; if (isInit || !runModConf->retrieveNewLogsFromStart) { container_log_options = runModConf->getContainerLogOptions; } const uchar *pApiAddr = (uchar *)"http:"; if (runModConf->dockerApiAddr) { pApiAddr = runModConf->dockerApiAddr; } snprintf(url, sizeof(url), "%s/%s/containers/%s/logs?%s", pApiAddr, runModConf->apiVersionStr, containerId, container_log_options); DBGPRINTF("%s() - url: %s\n", __FUNCTION__, url); return dockerContLogsInstSetUrl(pThis, curlm, url); } /* special destructor for hashtable object. */ static void dockerContLogReqsDestructForHashtable(void *pData) { docker_cont_logs_inst_t *pThis = (docker_cont_logs_inst_t *)pData; dockerContLogsInstDestruct(pThis); } static rsRetVal dockerContLogReqsNew(docker_cont_log_instances_t **ppThis) { DEFiRet; docker_cont_log_instances_t *pThis = calloc(1, sizeof(docker_cont_log_instances_t)); CHKmalloc(pThis); CHKmalloc(pThis->ht_container_log_insts = create_hashtable(7, hash_from_string, key_equals_string, dockerContLogReqsDestructForHashtable)); CHKiConcCtrl(pthread_mutex_init(&pThis->mut, NULL)); pThis->curlm = curl_multi_init(); if (!pThis->curlm) { ABORT_FINALIZE(RS_RET_ERR); } *ppThis = pThis; finalize_it: if (iRet != RS_RET_OK) { if (pThis) { dockerContLogReqsDestruct(pThis); } } RETiRet; } static rsRetVal dockerContLogReqsDestruct(docker_cont_log_instances_t *pThis) { DEFiRet; if (pThis) { if (pThis->ht_container_log_insts) { pthread_mutex_lock(&pThis->mut); hashtable_destroy(pThis->ht_container_log_insts, 1); pthread_mutex_unlock(&pThis->mut); } if (pThis->last_container_id) { free(pThis->last_container_id); } curl_multi_cleanup(pThis->curlm); pthread_mutex_destroy(&pThis->mut); free(pThis); } RETiRet; } /* NOTE: not thread safe - used internally to update container log requests */ static rsRetVal dockerContLogReqsGet(docker_cont_log_instances_t *pThis, docker_cont_logs_inst_t **ppContLogsInst, const char *id) { DEFiRet; if (ppContLogsInst && id) { docker_cont_logs_inst_t *pSearchObj = hashtable_search(pThis->ht_container_log_insts, (void *)id); if (!pSearchObj) { return RS_RET_NOT_FOUND; } *ppContLogsInst = pSearchObj; } RETiRet; } /* debug print * * NOTE: not thread safe * */ static rsRetVal dockerContLogReqsPrint(docker_cont_log_instances_t *pThis) { DEFiRet; int count = 0; count = hashtable_count(pThis->ht_container_log_insts); if (count) { int ret = 0; struct hashtable_itr *itr = hashtable_iterator(pThis->ht_container_log_insts); DBGPRINTF("%s() - All container instances, count=%d...\n", __FUNCTION__, count); do { docker_cont_logs_inst_t *pObj = hashtable_iterator_value(itr); dockerContLogsInstPrint(pObj); ret = hashtable_iterator_advance(itr); } while (ret); free(itr); DBGPRINTF("End of container instances.\n"); } RETiRet; } /* NOTE: not thread safe */ static rsRetVal dockerContLogReqsAdd(docker_cont_log_instances_t *pThis, docker_cont_logs_inst_t *pContLogsReqInst) { DEFiRet; if (!pContLogsReqInst) { return RS_RET_ERR; } uchar *keyName = (uchar *)strdup((char *)pContLogsReqInst->id); if (keyName) { docker_cont_logs_inst_t *pFind; if (RS_RET_NOT_FOUND == dockerContLogReqsGet(pThis, &pFind, (void *)keyName)) { if (!hashtable_insert(pThis->ht_container_log_insts, keyName, pContLogsReqInst)) { ABORT_FINALIZE(RS_RET_ERR); } keyName = NULL; } } finalize_it: free(keyName); RETiRet; } static rsRetVal dockerContLogReqsRemove(docker_cont_log_instances_t *pThis, const char *id) { DEFiRet; if (pThis && id) { CHKiConcCtrl(pthread_mutex_lock(&pThis->mut)); docker_cont_logs_inst_t *pRemoved = hashtable_remove(pThis->ht_container_log_insts, (void *)id); pthread_mutex_unlock(&pThis->mut); if (pRemoved) { dockerContLogsInstDestruct(pRemoved); } else { iRet = RS_RET_NOT_FOUND; } } finalize_it: RETiRet; } static rsRetVal dockerContainerInfoNew(docker_container_info_t **ppThis) { DEFiRet; docker_container_info_t *pThis = calloc(1, sizeof(docker_container_info_t)); CHKmalloc(pThis); *ppThis = pThis; finalize_it: RETiRet; } static void dockerContainerInfoDestruct(docker_container_info_t *pThis) { if (pThis) { if (pThis->image_id) { free(pThis->image_id); } if (pThis->image) { free(pThis->image); } if (pThis->name) { free(pThis->name); } if (pThis->json_str_labels) { free(pThis->json_str_labels); } free(pThis); } } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; dbgprintf("imdocker: beginCnfLoad\n"); loadModConf = pModConf; pModConf->pConf = pConf; /* init our settings */ loadModConf->iPollInterval = DFLT_pollingInterval; /* in seconds */ loadModConf->retrieveNewLogsFromStart = DFLT_retrieveNewLogsFromStart; loadModConf->containersLimit = DFLT_containersLimit; loadModConf->trimLineOverBytes = DFLT_trimLineOverBytes; loadModConf->bEscapeLf = DFLT_bEscapeLF; /* Use the default url */ loadModConf->apiVersionStr = NULL; loadModConf->dockerApiUnixSockAddr = NULL; loadModConf->dockerApiAddr = NULL; loadModConf->listContainersOptions = NULL; loadModConf->getContainerLogOptions = NULL; loadModConf->getContainerLogOptionsWithoutTail = NULL; loadModConf->iDfltFacility = DFLT_FACILITY; loadModConf->iDfltSeverity = DFLT_SEVERITY; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; char *buf = NULL; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for imdocker:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { dbgprintf("%s() - iteration %d\n", __FUNCTION__, i); dbgprintf("%s() - modpblk descr: %s\n", __FUNCTION__, modpblk.descr[i].name); if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "pollinginterval")) { loadModConf->iPollInterval = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "containterlimit")) { loadModConf->containersLimit = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "trimlineoverbytes")) { loadModConf->trimLineOverBytes = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "listcontainersoptions")) { loadModConf->listContainersOptions = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "getcontainerlogoptions")) { CHKmalloc(loadModConf->getContainerLogOptions = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL)); /* also initialize the non-tail version */ size_t offset = 0; size_t option_str_len = strlen((char *)loadModConf->getContainerLogOptions); CHKmalloc(buf = strdup((char *)loadModConf->getContainerLogOptions)); uchar *option_str = calloc(1, option_str_len + 1); CHKmalloc(option_str); const char *search_str = "tail="; size_t search_str_len = strlen(search_str); char *token = strtok(buf, "&"); while (token != NULL) { if (strncmp(token, search_str, search_str_len) == 0) { token = strtok(NULL, "&"); continue; } int len = strlen(token); if (offset + len + 1 >= option_str_len + 1) { break; } int bytes = snprintf((char *)option_str + offset, (option_str_len + 1 - offset), "%s&", token); if (bytes <= 0) { break; } offset += bytes; token = strtok(NULL, "&"); } loadModConf->getContainerLogOptionsWithoutTail = option_str; free(buf); buf = NULL; } else if (!strcmp(modpblk.descr[i].name, "dockerapiunixsockaddr")) { loadModConf->dockerApiUnixSockAddr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "dockerapiaddr")) { loadModConf->dockerApiAddr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "apiversionstr")) { loadModConf->apiVersionStr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "retrievenewlogsfromstart")) { loadModConf->retrieveNewLogsFromStart = (sbool)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "defaultseverity")) { loadModConf->iDfltSeverity = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "defaultfacility")) { loadModConf->iDfltFacility = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "escapelf")) { loadModConf->bEscapeLf = (sbool)pvals[i].val.d.n; } else { LogError(0, RS_RET_INVALID_PARAMS, "imdocker: program error, non-handled " "param '%s' in setModCnf\n", modpblk.descr[i].name); } } /* disable legacy module-global config directives */ bLegacyCnfModGlobalsPermitted = 0; finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); free(buf); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; if (!loadModConf->dockerApiUnixSockAddr) { loadModConf->dockerApiUnixSockAddr = (uchar *)strdup(DFLT_dockerAPIUnixSockAddr); } if (!loadModConf->apiVersionStr) { loadModConf->apiVersionStr = (uchar *)strdup(DFLT_apiVersionStr); } if (!loadModConf->listContainersOptions) { loadModConf->listContainersOptions = (uchar *)strdup(DFLT_listContainersOptions); } if (!loadModConf->getContainerLogOptions) { loadModConf->getContainerLogOptions = (uchar *)strdup(DFLT_getContainerLogOptions); } if (!loadModConf->getContainerLogOptionsWithoutTail) { loadModConf->getContainerLogOptionsWithoutTail = (uchar *)strdup(DFLT_getContainerLogOptionsWithoutTail); } runModConf = loadModConf; /* support statistics gathering */ CHKiRet(statsobj.Construct(&modStats)); CHKiRet(statsobj.SetName(modStats, UCHAR_CONSTANT("imdocker"))); CHKiRet(statsobj.SetOrigin(modStats, UCHAR_CONSTANT("imdocker"))); STATSCOUNTER_INIT(ctrSubmit, mutCtrSubmit); CHKiRet( statsobj.AddCounter(modStats, UCHAR_CONSTANT("submitted"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrSubmit)); STATSCOUNTER_INIT(ctrLostRatelimit, mutCtrLostRatelimit); CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("ratelimit.discarded"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrLostRatelimit)); STATSCOUNTER_INIT(ctrCurlError, mutCtrCurlError); CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("curl.errors"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &ctrCurlError)); CHKiRet(statsobj.ConstructFinalize(modStats)); /* end stats */ finalize_it: ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; if (loadModConf->dockerApiUnixSockAddr) { free(loadModConf->dockerApiUnixSockAddr); } if (loadModConf->dockerApiAddr) { free(loadModConf->dockerApiAddr); } if (loadModConf->apiVersionStr) { free(loadModConf->apiVersionStr); } if (loadModConf->getContainerLogOptions) { free(loadModConf->getContainerLogOptions); } if (loadModConf->getContainerLogOptionsWithoutTail) { free(loadModConf->getContainerLogOptionsWithoutTail); } if (loadModConf->listContainersOptions) { free(loadModConf->listContainersOptions); } statsobj.Destruct(&modStats); ENDfreeCnf static rsRetVal addDockerMetaData(const uchar *container_id, docker_container_info_t *pinfo, smsg_t *pMsg) { const uchar *names[5] = { (const uchar *)DOCKER_CONTAINER_ID_PARSE_NAME, (const uchar *)DOCKER_CONTAINER_NAMES_PARSE_NAME, (const uchar *)DOCKER_CONTAINER_IMAGE_PARSE_NAME, (const uchar *)DOCKER_CONTAINER_IMAGEID_PARSE_NAME, (const uchar *)DOCKER_CONTAINER_LABELS_PARSE_NAME}; const uchar *empty_str = (const uchar *)""; const uchar *id = container_id ? container_id : empty_str; const uchar *name = pinfo->name ? pinfo->name : empty_str; const uchar *image = pinfo->image ? pinfo->image : empty_str; const uchar *image_id = pinfo->image_id ? pinfo->image_id : empty_str; const uchar *json_str_labels = pinfo->json_str_labels ? pinfo->json_str_labels : empty_str; const uchar *values[5] = {id, name, image, image_id, json_str_labels}; return msgAddMultiMetadata(pMsg, names, values, 5); } static rsRetVal enqMsg(docker_cont_logs_inst_t *pInst, uchar *msg, size_t len, const uchar *pszTag, int facility, int severity, struct timeval *tp) { struct syslogTime st; smsg_t *pMsg; DEFiRet; if (!msg) { return RS_RET_ERR; } if (tp == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { datetime.timeval2syslogTime(tp, &st, TIME_IN_LOCALTIME); CHKiRet(msgConstructWithTime(&pMsg, &st, tp->tv_sec)); } MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); MsgSetInputName(pMsg, pInputName); MsgSetRawMsg(pMsg, (char *)msg, len); if (loadModConf->bEscapeLf) { parser.SanitizeMsg(pMsg); } else { /* Perform some of the SanitizeMsg operations here - specifically: * - remove NULL character at end of message. * - drop trailing LFs. * See SanitizeMsg() for more info. */ size_t lenMsg = pMsg->iLenRawMsg; uchar *pszMsg = pMsg->pszRawMsg; if (pszMsg[lenMsg - 1] == '\0') { DBGPRINTF("dropped NULL at very end of message\n"); lenMsg--; } if (glbl.GetParserDropTrailingLFOnReception(loadModConf->pConf) && lenMsg > 0 && pszMsg[lenMsg - 1] == '\n') { DBGPRINTF("dropped LF at very end of message (DropTrailingLF is set)\n"); lenMsg--; pszMsg[lenMsg] = '\0'; } pMsg->iLenRawMsg = lenMsg; } MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); if (pLocalHostIP) { MsgSetRcvFromIP(pMsg, pLocalHostIP); } MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetTAG(pMsg, pszTag, ustrlen(pszTag)); pMsg->iFacility = facility; pMsg->iSeverity = severity; /* docker container metadata */ addDockerMetaData((const uchar *)pInst->short_id, pInst->container_info, pMsg); const char *name = (const char *)pInst->container_info->name; DBGPRINTF("imdocker: %s - %s:%s\n", __FUNCTION__, name, msg); CHKiRet(ratelimitAddMsg(ratelimiter, NULL, pMsg)); STATSCOUNTER_INC(ctrSubmit, mutCtrSubmit); finalize_it: if (iRet == RS_RET_DISCARDMSG) STATSCOUNTER_INC(ctrLostRatelimit, mutCtrLostRatelimit) RETiRet; } static int8_t is_valid_stream_type(int8_t stream_type) { return (dst_invalid < stream_type && stream_type < dst_stream_type_count); } /* For use to get docker specific stream information */ static sbool get_stream_info(const uchar *data, size_t size, int8_t *stream_type, size_t *payload_size) { if (size < 8 || !data || !stream_type || !payload_size) { return 0; } const uchar *pdata = data; *stream_type = pdata[0]; pdata += 4; uint32_t len = 0; memcpy(&len, pdata, sizeof(len)); *payload_size = ntohl(len); return 1; } #ifdef ENABLE_DEBUG_BYTE_BUFFER static void debug_byte_buffer(const uchar *data, size_t size) { if (Debug) { DBGPRINTF("%s() - ENTER, size=%lu\n", __FUNCTION__, size); for (size_t i = 0; i < size; i++) { DBGPRINTF("0x%02x,", data[i]); } DBGPRINTF("\n"); } } #endif /** * imdocker_container_list_curlCB * * Callback function for CURLOPT_WRITEFUNCTION to get * the results of a docker api call to list all containers. * */ static size_t imdocker_container_list_curlCB(void *data, size_t size, size_t nmemb, void *buffer) { DEFiRet; size_t realsize = size * nmemb; uchar *pbuf = NULL; imdocker_buf_t *mem = (imdocker_buf_t *)buffer; if ((pbuf = realloc(mem->data, mem->len + realsize + 1)) == NULL) { LogError(errno, RS_RET_ERR, "%s() - realloc failed!\n", __FUNCTION__); ABORT_FINALIZE(RS_RET_ERR); } mem->data = pbuf; mem->data_size = mem->len + realsize + 1; memcpy(&(mem->data[mem->len]), data, realsize); mem->len += realsize; mem->data[mem->len] = 0; #ifdef ENABLE_DEBUG_BYTE_BUFFER debug_byte_buffer((const uchar *)data, realsize); #endif finalize_it: if (iRet != RS_RET_OK) { return 0; } return realsize; } static rsRetVal SubmitMultiLineMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag, size_t len) { DEFiRet; imdocker_buf_t *mem = (imdocker_buf_t *)pBufData->buf; DBGPRINTF("%s() {type=%d, len=%u} %s\n", __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); uchar *message = (uchar *)mem->data; int facility = loadModConf->iDfltFacility; int severity = pBufData->stream_type == dst_stderr ? LOG_ERR : loadModConf->iDfltSeverity; enqMsg(pInst, message, len, (const uchar *)pszTag, facility, severity, NULL); size_t size = mem->len - pInst->prevSegEnd; memmove(mem->data, mem->data + pInst->prevSegEnd, size); mem->data[len] = '\0'; mem->len = size; pBufData->bytes_remaining = 0; RETiRet; } static rsRetVal SubmitMsgWithStartRegex(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag) { imdocker_buf_t *mem = (imdocker_buf_t *)pBufData->buf; /* must be null terminated string */ assert(mem->data[mem->len] == 0 || mem->data[mem->len] == '\0'); const char *thisLine = (const char *)mem->data; if (pInst->prevSegEnd) { thisLine = (const char *)mem->data + pInst->prevSegEnd; } DBGPRINTF("prevSeg: %d, thisLine: '%s'\n", pInst->prevSegEnd, thisLine); DBGPRINTF("line(s) so far: '%s'\n", mem->data); /* check if this line is a start of multi-line message */ regex_t *start_preg = (pInst->start_regex == NULL) ? NULL : &pInst->start_preg; const int isStartMatch = start_preg ? !regexec(start_preg, (char *)thisLine, 0, NULL, 0) : 0; if (isStartMatch && pInst->prevSegEnd != 0) { SubmitMultiLineMsg(pInst, pBufData, pszTag, pInst->prevSegEnd); pInst->prevSegEnd = 0; FINALIZE; } else { /* just continue parsing using same buffer */ pInst->prevSegEnd = mem->len; } finalize_it: return RS_RET_OK; } static rsRetVal SubmitMsg2(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag) { imdocker_buf_t *mem = (imdocker_buf_t *)pBufData->buf; DBGPRINTF("%s() - {type=%d, len=%u} %s\n", __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); if (pInst->start_regex) { SubmitMsgWithStartRegex(pInst, pBufData, pszTag); } else { SubmitMsg(pInst, pBufData, pszTag); } return RS_RET_OK; } static rsRetVal SubmitMsg(docker_cont_logs_inst_t *pInst, docker_cont_logs_buf_t *pBufData, const uchar *pszTag) { imdocker_buf_t *mem = (imdocker_buf_t *)pBufData->buf; DBGPRINTF("%s() - {type=%d, len=%u} %s\n", __FUNCTION__, pBufData->stream_type, (unsigned int)mem->len, mem->data); uchar *message = mem->data; int facility = loadModConf->iDfltFacility; int severity = pBufData->stream_type == dst_stderr ? LOG_ERR : loadModConf->iDfltSeverity; enqMsg(pInst, message, mem->len, (const uchar *)pszTag, facility, severity, NULL); /* clear existing buffer. */ mem->len = 0; memset(mem->data, 0, mem->data_size); pBufData->bytes_remaining = 0; return RS_RET_OK; } /** imdocker_container_logs_curlCB * * Callback function for CURLOPT_WRITEFUNCTION, gets container logs * * The main container log stream handler. This function is registerred with curl to * as callback to handle container log streaming. It follows the docker stream protocol * as described in the docker container logs api. As per docker's api documentation, * Docker Stream format: * When the TTY setting is disabled in POST /containers/create, the stream over the * hijacked connected is multiplexed to separate out stdout and stderr. The stream * consists of a series of frames, each containing a header and a payload. * * The header contains the information which the stream writes (stdout or stderr). It also * contains the size of the associated frame encoded in the last four bytes (uint32). * * It is encoded on the first eight bytes like this: * * header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4} * STREAM_TYPE can be: * 0: stdin (is written on stdout) * 1: stdout * 2: stderr * * Docker sends out data in 16KB sized frames, however with the addition of a header * of 8 bytes, a frame may be split into 2 chunks by curl. The 2nd chunk will only * contain enough data to complete the frame (8 leftever bytes). Including the header, * this amounts to 16 bytes; 8 bytes for the header, and 8 bytes for the remaining frame * data. * */ static size_t imdocker_container_logs_curlCB(void *data, size_t size, size_t nmemb, void *buffer) { DEFiRet; const uint8_t frame_size = 8; const char imdocker_eol_char = '\n'; int8_t stream_type = dst_invalid; docker_cont_logs_inst_t *pInst = (docker_cont_logs_inst_t *)buffer; docker_cont_logs_req_t *req = pInst->logsReq; size_t realsize = size * nmemb; const uchar *pdata = data; size_t write_size = 0; #ifdef ENABLE_DEBUG_BYTE_BUFFER debug_byte_buffer((const uchar *)data, realsize); #endif if (req->data_bufs[dst_stdout]->bytes_remaining || req->data_bufs[dst_stderr]->bytes_remaining) { /* on continuation, stream types should matches with previous */ if (req->data_bufs[dst_stdout]->bytes_remaining) { if (req->data_bufs[dst_stderr]->bytes_remaining != 0) { ABORT_FINALIZE(RS_RET_ERR); } } else if (req->data_bufs[dst_stderr]->bytes_remaining) { if (req->data_bufs[dst_stdout]->bytes_remaining != 0) { ABORT_FINALIZE(RS_RET_ERR); } } stream_type = req->data_bufs[dst_stdout]->bytes_remaining ? dst_stdout : dst_stderr; docker_cont_logs_buf_t *pDataBuf = req->data_bufs[stream_type]; /* read off the remaining bytes */ DBGPRINTF( "Chunk continuation, remaining bytes: type: %d, " "bytes remaining: %u, realsize: %u, data pos: %u\n", stream_type, (unsigned int)pDataBuf->bytes_remaining, (unsigned int)realsize, (unsigned int)pDataBuf->buf->len); write_size = MIN(pDataBuf->bytes_remaining, realsize); CHKiRet(dockerContLogsBufWrite(pDataBuf, pdata, write_size)); /* submit it */ if (pDataBuf->bytes_remaining == 0) { imdocker_buf_t *mem = pDataBuf->buf; if (mem->data[mem->len - 1] == imdocker_eol_char) { const char *szContainerId = NULL; CURLcode ccode; if (CURLE_OK != (ccode = curl_easy_getinfo(req->curl, CURLINFO_PRIVATE, &szContainerId))) { LogError(0, RS_RET_ERR, "imdocker: could not get private data req[%p] - %d:%s\n", req->curl, ccode, curl_easy_strerror(ccode)); ABORT_FINALIZE(RS_RET_ERR); } req->submitMsg(pInst, pDataBuf, (const uchar *)DOCKER_TAG_NAME); } } pdata += write_size; } /* not enough room left */ if ((size_t)(pdata - (const uchar *)data) >= realsize) { return (pdata - (const uchar *)data); } size_t payload_size = 0; const uchar *pread = pdata + frame_size; docker_cont_logs_buf_t *pDataBuf = NULL; if (get_stream_info(pdata, realsize, &stream_type, &payload_size) && is_valid_stream_type(stream_type)) { pDataBuf = req->data_bufs[stream_type]; pDataBuf->stream_type = stream_type; pDataBuf->bytes_remaining = payload_size; write_size = MIN(payload_size, realsize - frame_size); } else { /* copy all the data and submit to prevent data loss */ stream_type = req->data_bufs[dst_stderr]->bytes_remaining ? dst_stderr : dst_stdout; pDataBuf = req->data_bufs[stream_type]; pDataBuf->stream_type = stream_type; /* just write everything out */ pDataBuf->bytes_remaining = 0; write_size = realsize; pread = pdata; } /* allocate the expected payload size */ CHKiRet(dockerContLogsBufWrite(pDataBuf, pread, write_size)); if (pDataBuf->bytes_remaining == 0) { DBGPRINTF("%s() - write size is same as payload_size\n", __FUNCTION__); req->submitMsg(pInst, pDataBuf, (const uchar *)DOCKER_TAG_NAME); } finalize_it: if (iRet != RS_RET_OK) { return 0; } return realsize; } CURLcode docker_get(imdocker_req_t *req, const char *url) { CURLcode ccode; if (!runModConf->dockerApiAddr) { if ((ccode = curl_easy_setopt(req->curl, CURLOPT_UNIX_SOCKET_PATH, runModConf->dockerApiUnixSockAddr)) != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_UNIX_SOCKET_PATH) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); return ccode; } } if ((ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEFUNCTION, imdocker_container_list_curlCB)) != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEFUNCTION) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); return ccode; } if ((ccode = curl_easy_setopt(req->curl, CURLOPT_WRITEDATA, req->buf)) != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_WRITEDATA) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); return ccode; } if ((ccode = curl_easy_setopt(req->curl, CURLOPT_URL, url)) != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); LogError(0, RS_RET_ERR, "imdocker: curl_easy_setopt(CURLOPT_URL) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); return ccode; } CURLcode response = curl_easy_perform(req->curl); return response; } static char *dupDockerContainerName(const char *pname) { int len = strlen(pname); if (len >= 2 && *pname == '/') { /* skip '/' character */ return strdup(pname + 1); } else { return strdup(pname); } } static rsRetVal process_json(sbool isInit, const char *json, docker_cont_log_instances_t *pInstances) { DEFiRet; struct fjson_object *json_obj = NULL; int mut_locked = 0; DBGPRINTF("%s() - parsing json=%s\n", __FUNCTION__, json); if (!pInstances) { ABORT_FINALIZE(RS_RET_OK); } json_obj = fjson_tokener_parse(json); if (!json_obj || !fjson_object_is_type(json_obj, fjson_type_array)) { ABORT_FINALIZE(RS_RET_OK); } int length = fjson_object_array_length(json_obj); /* LOCK the update process. */ CHKiConcCtrl(pthread_mutex_lock(&pInstances->mut)); mut_locked = 1; for (int i = 0; i < length; i++) { fjson_object *p_json_elm = json_object_array_get_idx(json_obj, i); DBGPRINTF("element: %d...\n", i); if (p_json_elm) { const char *containerId = NULL; docker_container_info_t containerInfo = { .name = NULL, .image = NULL, .image_id = NULL, .created = 0, .json_str_labels = NULL}; struct fjson_object_iterator it = fjson_object_iter_begin(p_json_elm); struct fjson_object_iterator itEnd = fjson_object_iter_end(p_json_elm); while (!fjson_object_iter_equal(&it, &itEnd)) { if (Debug) { DBGPRINTF("\t%s: '%s'\n", fjson_object_iter_peek_name(&it), fjson_object_get_string(fjson_object_iter_peek_value(&it))); } if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_ID_PARSE_NAME) == 0) { containerId = fjson_object_get_string(fjson_object_iter_peek_value(&it)); } else if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_NAMES_PARSE_NAME) == 0) { int names_array_length = fjson_object_array_length(fjson_object_iter_peek_value(&it)); if (names_array_length) { fjson_object *names_elm = json_object_array_get_idx(fjson_object_iter_peek_value(&it), 0); containerInfo.name = (uchar *)fjson_object_get_string(names_elm); } } else if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_IMAGE_PARSE_NAME) == 0) { containerInfo.image = (uchar *)fjson_object_get_string(fjson_object_iter_peek_value(&it)); } else if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_IMAGEID_PARSE_NAME) == 0) { containerInfo.image_id = (uchar *)fjson_object_get_string(fjson_object_iter_peek_value(&it)); } else if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_CREATED_PARSE_NAME) == 0) { containerInfo.created = fjson_object_get_int64(fjson_object_iter_peek_value(&it)); } else if (strcmp(fjson_object_iter_peek_name(&it), DOCKER_CONTAINER_LABELS_PARSE_NAME) == 0) { containerInfo.json_str_labels = (uchar *)fjson_object_get_string(fjson_object_iter_peek_value(&it)); DBGPRINTF("labels: %s\n", containerInfo.json_str_labels); } fjson_object_iter_next(&it); } if (containerId) { docker_cont_logs_inst_t *pInst = NULL; iRet = dockerContLogReqsGet(pInstances, &pInst, containerId); if (iRet == RS_RET_NOT_FOUND) { #ifdef USE_MULTI_LINE if (dockerContLogsInstNew(&pInst, containerId, &containerInfo, SubmitMsg2) #else if (dockerContLogsInstNew(&pInst, containerId, &containerInfo, SubmitMsg) #endif == RS_RET_OK) { if (pInstances->last_container_created < containerInfo.created) { pInstances->last_container_created = containerInfo.created; if (pInstances->last_container_id) { free(pInstances->last_container_id); } pInstances->last_container_id = (uchar *)strdup(containerId); DBGPRINTF("last_container_id updated: ('%s', %u)\n", pInstances->last_container_id, (unsigned)pInstances->last_container_created); } CHKiRet(dockerContLogsInstSetUrlById(isInit, pInst, pInstances->curlm, containerId)); CHKiRet(dockerContLogReqsAdd(pInstances, pInst)); } } } } } finalize_it: if (mut_locked) { pthread_mutex_unlock(&pInstances->mut); } if (json_obj) { json_object_put(json_obj); } RETiRet; } static rsRetVal getContainerIds(sbool isInit, docker_cont_log_instances_t *pInstances, const char *url) { DEFiRet; imdocker_req_t *req = NULL; CHKiRet(imdockerReqNew(&req)); CURLcode response = docker_get(req, url); if (response != CURLE_OK) { DBGPRINTF("%s() - curl response: %d\n", __FUNCTION__, response); ABORT_FINALIZE(RS_RET_ERR); } CHKiRet(process_json(isInit, (const char *)req->buf->data, pInstances)); finalize_it: if (req) { imdockerReqDestruct(req); } RETiRet; } static rsRetVal getContainerIdsAndAppend(sbool isInit, docker_cont_log_instances_t *pInstances) { DEFiRet; char url[256]; const uchar *pApiAddr = (uchar *)"http:"; if (runModConf->dockerApiAddr) { pApiAddr = runModConf->dockerApiAddr; } /* * TODO: consider if we really need 'isInit' parameter. I suspect we don't need it * and i'm almost certain Travis CI will complain its not used. */ if (pInstances->last_container_id) { snprintf(url, sizeof(url), "%s/%s/containers/json?%s&filters={\"since\":[\"%s\"]}", pApiAddr, runModConf->apiVersionStr, runModConf->listContainersOptions, pInstances->last_container_id); } else { snprintf(url, sizeof(url), "%s/%s/containers/json?%s", pApiAddr, runModConf->apiVersionStr, runModConf->listContainersOptions); } DBGPRINTF("listcontainers url: %s\n", url); CHKiRet(getContainerIds(isInit, pInstances, (const char *)url)); if (Debug) { dockerContLogReqsPrint(pInstances); } finalize_it: RETiRet; } static void cleanupCompletedContainerRequests(docker_cont_log_instances_t *pInstances) { // clean up int rc = 0, msgs_left = 0; CURLMsg *msg = NULL; CURL *pCurl; while ((msg = curl_multi_info_read(pInstances->curlm, &msgs_left))) { if (msg->msg == CURLMSG_DONE) { pCurl = msg->easy_handle; rc = msg->data.result; if (rc != CURLE_OK) { STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); LogError(0, RS_RET_ERR, "imdocker: %s() - curl error code: %d:%s\n", __FUNCTION__, rc, curl_multi_strerror(rc)); continue; } CURLcode ccode; if (Debug) { long http_status = 0; curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &http_status); DBGPRINTF("http status: %lu\n", http_status); } curl_multi_remove_handle(pInstances->curlm, pCurl); const char *szContainerId = NULL; if ((ccode = curl_easy_getinfo(pCurl, CURLINFO_PRIVATE, &szContainerId)) == CURLE_OK) { DBGPRINTF("container disconnected: %s\n", szContainerId); dockerContLogReqsRemove(pInstances, szContainerId); DBGPRINTF("container removed...\n"); } else { LogError(0, RS_RET_ERR, "imdocker: private data not found " "curl_easy_setopt(CURLINFO_PRIVATE) error - %d:%s\n", ccode, curl_easy_strerror(ccode)); STATSCOUNTER_INC(ctrCurlError, mutCtrCurlError); } } } } static rsRetVal processAndPollContainerLogs(docker_cont_log_instances_t *pInstances) { DEFiRet; int count = 0; count = hashtable_count(pInstances->ht_container_log_insts); DBGPRINTF("%s() - container instances: %d\n", __FUNCTION__, count); int still_running = 0; curl_multi_perform(pInstances->curlm, &still_running); do { int numfds = 0; int res = curl_multi_wait(pInstances->curlm, NULL, 0, 1000, &numfds); if (res != CURLM_OK) { LogError(0, RS_RET_ERR, "error: curl_multi_wait() numfds=%d, res=%d:%s\n", numfds, res, curl_multi_strerror(res)); return res; } int prev_still_running = still_running; curl_multi_perform(pInstances->curlm, &still_running); if (prev_still_running > still_running) { cleanupCompletedContainerRequests(pInstances); } } while (still_running && glbl.GetGlobalInputTermState() == 0); cleanupCompletedContainerRequests(pInstances); RETiRet; } static void *getContainersTask(void *pdata) { docker_cont_log_instances_t *pInstances = (docker_cont_log_instances_t *)pdata; while (glbl.GetGlobalInputTermState() == 0) { srSleep(runModConf->iPollInterval, 10); getContainerIdsAndAppend(false, pInstances); } return pdata; } /* This function is called to gather input. */ BEGINrunInput rsRetVal localRet = RS_RET_OK; docker_cont_log_instances_t *pInstances = NULL; pthread_t thrd_id; /* the worker's thread ID */ pthread_attr_t thrd_attr; int get_containers_thread_initialized = 0; time_t now; CODESTARTrunInput; datetime.GetTime(&now); CHKiRet(ratelimitNew(&ratelimiter, "imdocker", NULL)); curl_global_init(CURL_GLOBAL_ALL); localRet = dockerContLogReqsNew(&pInstances); if (localRet != RS_RET_OK) { return localRet; } pInstances->time_started = now; /* get all current containers now */ CHKiRet(getContainerIdsAndAppend(true, pInstances)); /* using default stacksize */ CHKiConcCtrl(pthread_attr_init(&thrd_attr)); CHKiConcCtrl(pthread_create(&thrd_id, &thrd_attr, getContainersTask, pInstances)); get_containers_thread_initialized = 1; while (glbl.GetGlobalInputTermState() == 0) { CHKiRet(processAndPollContainerLogs(pInstances)); if (glbl.GetGlobalInputTermState() == 0) { /* exited from processAndPollContainerLogs, sleep before retrying */ srSleep(1, 10); } } finalize_it: if (get_containers_thread_initialized) { pthread_kill(thrd_id, SIGTTIN); pthread_join(thrd_id, NULL); pthread_attr_destroy(&thrd_attr); } if (pInstances) { dockerContLogReqsDestruct(pInstances); } if (ratelimiter) { ratelimitDestruct(ratelimiter); } ENDrunInput BEGINwillRun CODESTARTwillRun; ENDwillRun BEGINafterRun CODESTARTafterRun; ENDafterRun BEGINmodExit CODESTARTmodExit; if (pInputName != NULL) prop.Destruct(&pInputName); if (pLocalHostIP != NULL) prop.Destruct(&pLocalHostIP); objRelease(parser, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(statsobj, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); DBGPRINTF("imdocker version %s initializing\n", VERSION); /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imdocker"), sizeof("imdocker") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); ENDmodInit rsyslog-8.2512.0/contrib/imdocker/PaxHeaders/Makefile.in0000644000000000000000000000013115114544315020035 xustar0030 mtime=1764935885.734003074 30 atime=1764935897.032176133 29 ctime=1764935927.69464564 rsyslog-8.2512.0/contrib/imdocker/Makefile.in0000664000175000017500000006336515114544315017517 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imdocker ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = imdocker_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_imdocker_la_OBJECTS = imdocker_la-imdocker.lo imdocker_la_OBJECTS = $(am_imdocker_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imdocker_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(imdocker_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imdocker_la-imdocker.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imdocker_la_SOURCES) DIST_SOURCES = $(imdocker_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imdocker.la imdocker_la_SOURCES = imdocker.c imdocker_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(CURL_CFLAGS) $(LIBLOGGING_STDLOG_CFLAGS) imdocker_la_LDFLAGS = -module -avoid-version imdocker_la_LIBADD = $(CURL_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imdocker/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imdocker/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imdocker.la: $(imdocker_la_OBJECTS) $(imdocker_la_DEPENDENCIES) $(EXTRA_imdocker_la_DEPENDENCIES) $(AM_V_CCLD)$(imdocker_la_LINK) -rpath $(pkglibdir) $(imdocker_la_OBJECTS) $(imdocker_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imdocker_la-imdocker.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imdocker_la-imdocker.lo: imdocker.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imdocker_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imdocker_la-imdocker.lo -MD -MP -MF $(DEPDIR)/imdocker_la-imdocker.Tpo -c -o imdocker_la-imdocker.lo `test -f 'imdocker.c' || echo '$(srcdir)/'`imdocker.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imdocker_la-imdocker.Tpo $(DEPDIR)/imdocker_la-imdocker.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imdocker.c' object='imdocker_la-imdocker.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imdocker_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imdocker_la-imdocker.lo `test -f 'imdocker.c' || echo '$(srcdir)/'`imdocker.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imdocker_la-imdocker.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imdocker_la-imdocker.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/imkmsg0000644000000000000000000000013215114544364015412 xustar0030 mtime=1764935924.374594814 30 atime=1764935930.172683575 30 ctime=1764935924.374594814 rsyslog-8.2512.0/contrib/imkmsg/0000775000175000017500000000000015114544364015133 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imkmsg/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017516 xustar0030 mtime=1752569012.327264939 30 atime=1764930927.862799455 30 ctime=1764935924.365594676 rsyslog-8.2512.0/contrib/imkmsg/Makefile.am0000664000175000017500000000035115035412264017161 0ustar00rgerrgerpkglib_LTLIBRARIES = imkmsg.la imkmsg_la_SOURCES = imkmsg.c imkmsg.h imkmsg_la_SOURCES += kmsg.c imkmsg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imkmsg_la_LDFLAGS = -module -avoid-version imkmsg_la_LIBADD = rsyslog-8.2512.0/contrib/imkmsg/PaxHeaders/kmsg.c0000644000000000000000000000013215114522477016575 xustar0030 mtime=1764926783.006631146 30 atime=1764926784.225661069 30 ctime=1764935924.374594814 rsyslog-8.2512.0/contrib/imkmsg/kmsg.c0000664000175000017500000002305415114522477016245 0ustar00rgerrger/* imkmsg driver for Linux /dev/kmsg structured logging * * This contains Linux-specific functionality to read /dev/kmsg * For a general overview, see head comment in imkmsg.c. * This is heavily based on imklog bsd.c file. * * Copyright 2008-2025 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "srUtils.h" #include "debug.h" #include "imkmsg.h" /* globals */ static int fklog = -1; /* kernel log fd */ static int bInInitialReading = 1; /* are we in the initial kmsg reading phase? */ /* Note: There is a problem with kernel log time. * See https://github.com/troglobit/sysklogd/commit/9f6fbb3301e571d8af95f8d771469291384e9e95 * We use the same work-around if bFixKernelStamp is on, and use the kernel log time * only for past records, which we assume to be from recent boot. Later on, we do not * use them but system time. * UNFORTUNATELY, with /dev/kmsg, we always get old messages on startup. That means we * may also pull old messages. We do not address this right now, as for 10 years "old * messages" was pretty acceptable. So we wait until someone complains. Hint: we could * do a seek to the end of kmsg if desired to not pull old messages. * 2023-10-31 rgerhards */ #ifndef _PATH_KLOG #define _PATH_KLOG "/dev/kmsg" #endif /* submit a message to imkmsg Syslog() API. In this function, we parse * necessary information from kernel log line, and make json string * from the rest. */ static void submitSyslog(modConfData_t *const pModConf, const uchar *buf) { long offs = 0; struct timeval tv; struct timeval *tp = NULL; struct sysinfo info; unsigned long int timestamp = 0; char name[1024]; char value[1024]; char msg[1024]; syslog_pri_t priority = 0; long int sequnum = 0; struct json_object *json = NULL, *jval; /* create new json object */ json = json_object_new_object(); /* get priority */ for (; isdigit(*buf); buf++) { priority = (priority * 10) + (*buf - '0'); } buf++; /* get messages sequence number and add it to json */ for (; isdigit(*buf); buf++) { sequnum = (sequnum * 10) + (*buf - '0'); } buf++; /* skip , */ jval = json_object_new_int(sequnum); json_object_object_add(json, "sequnum", jval); /* get timestamp */ for (; isdigit(*buf); buf++) { timestamp = (timestamp * 10) + (*buf - '0'); } while (*buf != ';') { buf++; /* skip everything till the first ; */ } buf++; /* skip ; */ /* get message */ offs = 0; for (; *buf != '\n' && *buf != '\0'; buf++, offs++) { msg[offs] = *buf; } msg[offs] = '\0'; jval = json_object_new_string((char *)msg); json_object_object_add(json, "msg", jval); if (*buf != '\0') /* message has appended properties, skip \n */ buf++; while (*buf) { /* get name of the property */ buf++; /* skip ' ' */ offs = 0; for (; *buf != '=' && *buf != ' '; buf++, offs++) { name[offs] = *buf; } name[offs] = '\0'; buf++; /* skip = or ' ' */ ; offs = 0; for (; *buf != '\n' && *buf != '\0'; buf++, offs++) { value[offs] = *buf; } value[offs] = '\0'; if (*buf != '\0') { buf++; /* another property, skip \n */ } jval = json_object_new_string((char *)value); json_object_object_add(json, name, jval); } if ((pModConf->parseKernelStamp == KMSG_PARSE_TS_ALWAYS) || ((pModConf->parseKernelStamp == KMSG_PARSE_TS_STARTUP_ONLY) && bInInitialReading)) { /* calculate timestamp */ sysinfo(&info); gettimeofday(&tv, NULL); /* get boot time */ tv.tv_sec -= info.uptime; tv.tv_sec += timestamp / 1000000; tv.tv_usec += timestamp % 1000000; while (tv.tv_usec < 0) { tv.tv_sec--; tv.tv_usec += 1000000; } while (tv.tv_usec >= 1000000) { tv.tv_sec++; tv.tv_usec -= 1000000; } tp = &tv; } Syslog(priority, (uchar *)msg, tp, json); } /* open the kernel log - will be called inside the willRun() imkmsg entry point */ rsRetVal klogWillRunPrePrivDrop(modConfData_t __attribute__((unused)) * pModConf) { char errmsg[2048]; DEFiRet; fklog = open(_PATH_KLOG, O_RDONLY | O_NONBLOCK, 0); if (fklog < 0) { imkmsgLogIntMsg(LOG_ERR, "imkmsg: cannot open kernel log (%s): %s.", _PATH_KLOG, rs_strerror_r(errno, errmsg, sizeof(errmsg))); ABORT_FINALIZE(RS_RET_ERR_OPEN_KLOG); } finalize_it: RETiRet; } /* make sure the kernel log is readable after dropping privileges */ rsRetVal klogWillRunPostPrivDrop(modConfData_t __attribute__((unused)) * pModConf) { char errmsg[2048]; int r; DEFiRet; /* this normally returns EINVAL */ /* on an OpenVZ VM, we get EPERM */ r = read(fklog, NULL, 0); if (r < 0 && errno != EINVAL && errno != EAGAIN && errno != EWOULDBLOCK) { imkmsgLogIntMsg(LOG_ERR, "imkmsg: cannot open kernel log (%s): %s.", _PATH_KLOG, rs_strerror_r(errno, errmsg, sizeof(errmsg))); fklog = -1; ABORT_FINALIZE(RS_RET_ERR_OPEN_KLOG); } finalize_it: RETiRet; } static void change_reads_to_blocking(const int fd) { const int flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); } /* Read kernel log while data are available, each read() reads one * record of printk buffer. */ static void readkmsg(modConfData_t *const pModConf) { int i; uchar pRcv[16 * 1024 + 1]; char errmsg[2048]; off_t seek_result = 0; if (pModConf->readMode == KMSG_READMODE_FULL_BOOT) { struct sysinfo info; sysinfo(&info); DBGPRINTF("imkmsg: system uptime is %lld, expected %d\n", (long long)info.uptime, pModConf->expected_boot_complete_secs); if (info.uptime > pModConf->expected_boot_complete_secs) { seek_result = lseek(fklog, 0, SEEK_END); } } else if (pModConf->readMode == KMSG_READMODE_NEW_ONLY) { seek_result = lseek(fklog, 0, SEEK_END); } else if (pModConf->readMode != KMSG_READMODE_FULL_ALWAYS) { imkmsgLogIntMsg(LOG_ERR, "imkmsg: internal program error, " "unknown read mode %d, assuming 'full-always'", pModConf->readMode); } if (seek_result == (off_t)-1) { imkmsgLogIntMsg(LOG_WARNING, "imkmsg: could not seek to requested klog entries - will" "now potentially output all messages"); } for (;;) { dbgprintf("imkmsg waiting for kernel log line\n"); /* every read() from the opened device node receives one record of the printk buffer */ i = read(fklog, pRcv, 8192); if (i > 0) { /* successful read of message of nonzero length */ pRcv[i] = '\0'; } else if (i < 0 && errno == EPIPE) { imkmsgLogIntMsg(LOG_WARNING, "imkmsg: some messages in circular buffer got overwritten"); continue; } else { /* something went wrong - error or zero length message */ if (i < 0) { #if EAGAIN != EWOULDBLOCK if (errno == EAGAIN || errno == EWOULDBLOCK) { #else if (errno == EAGAIN) { #endif DBGPRINTF("imkmsg: initial read done, changing to blocking mode\n"); change_reads_to_blocking(fklog); bInInitialReading = 0; continue; } } if (i < 0 && errno != EINTR && errno != EAGAIN) { /* error occurred */ imkmsgLogIntMsg(LOG_ERR, "imkmsg: error reading kernel log - shutting down: %s", rs_strerror_r(errno, errmsg, sizeof(errmsg))); fklog = -1; } break; } submitSyslog(pModConf, pRcv); } } /* to be called in the module's AfterRun entry point * rgerhards, 2008-04-09 */ rsRetVal klogAfterRun(modConfData_t *pModConf) { DEFiRet; if (fklog != -1) close(fklog); /* Turn on logging of messages to console, but only if a log level was speficied */ if (pModConf->console_log_level != -1) klogctl(7, NULL, 0); RETiRet; } /* to be called in the module's WillRun entry point, this is the main * "message pull" mechanism. * rgerhards, 2008-04-09 */ rsRetVal klogLogKMsg(modConfData_t *const pModConf) { DEFiRet; readkmsg(pModConf); RETiRet; } /* provide the (system-specific) default facility for internal messages * rgerhards, 2008-04-14 */ int klogFacilIntMsg(void) { return LOG_SYSLOG; } rsyslog-8.2512.0/contrib/imkmsg/PaxHeaders/imkmsg.h0000644000000000000000000000013215071746523017132 xustar0030 mtime=1760021843.771419929 30 atime=1764931040.169676504 30 ctime=1764935924.372594783 rsyslog-8.2512.0/contrib/imkmsg/imkmsg.h0000664000175000017500000000512715071746523016603 0ustar00rgerrger/* imkmsg.h * These are the definitions for the kmsg message generation module. * * Copyright 2007-2023 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IMKLOG_H_INCLUDED #define IMKLOG_H_INCLUDED 1 #include "rsyslog.h" #include "dirty.h" typedef enum _kernel_ts_parse_mods { KMSG_PARSE_TS_OFF = 0, KMSG_PARSE_TS_ALWAYS = 1, KMSG_PARSE_TS_STARTUP_ONLY = 2 } t_kernel_ts_parse_mode; typedef enum _kernel_readmode { KMSG_READMODE_FULL_BOOT = 0, KMSG_READMODE_FULL_ALWAYS = 1, KMSG_READMODE_NEW_ONLY = 2 } t_kernel_readmode; /* we need to have the modConf type present in all submodules */ struct modConfData_s { rsconf_t *pConf; int iFacilIntMsg; uchar *pszPath; int console_log_level; int expected_boot_complete_secs; t_kernel_ts_parse_mode parseKernelStamp; t_kernel_readmode readMode; sbool configSetViaV2Method; }; /* interface to "drivers" * the platform specific drivers must implement these entry points. Only one * driver may be active at any given time, thus we simply rely on the linker * to resolve the addresses. * rgerhards, 2008-04-09 */ rsRetVal klogLogKMsg(modConfData_t *pModConf); rsRetVal klogWillRunPrePrivDrop(modConfData_t *pModConf); rsRetVal klogWillRunPostPrivDrop(modConfData_t *pModConf); rsRetVal klogAfterRun(modConfData_t *pModConf); /* the functions below may be called by the drivers */ rsRetVal imkmsgLogIntMsg(syslog_pri_t priority, const char *fmt, ...) __attribute__((format(printf, 2, 3))); rsRetVal Syslog(syslog_pri_t priority, uchar *msg, struct timeval *tp, struct json_object *json); int klogFacilIntMsg(void); /* prototypes */ extern int klog_getMaxLine(void); /* work-around for klog drivers to get configured max line size */ extern int InitKsyms(modConfData_t *); extern void DeinitKsyms(void); extern int InitMsyms(void); extern void DeinitMsyms(void); extern char *ExpandKadds(char *, char *); extern void SetParanoiaLevel(int); #endif /* #ifndef IMKLOG_H_INCLUDED */ rsyslog-8.2512.0/contrib/imkmsg/PaxHeaders/imkmsg.c0000644000000000000000000000013115055605325017120 xustar0029 mtime=1756826325.61180011 30 atime=1764931040.062674741 30 ctime=1764935924.369594737 rsyslog-8.2512.0/contrib/imkmsg/imkmsg.c0000664000175000017500000002727715055605325016604 0ustar00rgerrger/* The kernel log module. * * This is rsyslog Linux only module for reading structured kernel logs. * Module is based on imklog module so it retains its structure * and other part is currently in kmsg.c file instead of this (imkmsg.c) * For more information see that file. * * To test under Linux: * echo test1 > /dev/kmsg * * Copyright (C) 2008-2023 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include "dirty.h" #include "cfsysline.h" #include "obj.h" #include "msg.h" #include "module-template.h" #include "datetime.h" #include "imkmsg.h" #include "net.h" #include "glbl.h" #include "prop.h" #include "errmsg.h" #include "unicode-helper.h" MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imkmsg") /* Module static data */ DEF_IMOD_STATIC_DATA; DEFobjCurrIf(datetime) DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(net) /* config settings */ typedef struct configSettings_s { int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ } configSettings_t; static configSettings_t cs; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current load process */ static int bLegacyCnfModGlobalsPermitted; /* are legacy module-global config parameters permitted? */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = {{"parsekerneltimestamp", eCmdHdlrGetWord, 0}, {"readmode", eCmdHdlrGetWord, 0}, {"expectedbootcompleteseconds", eCmdHdlrPositiveInt, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this module */ static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */ static inline void initConfigSettings(void) { cs.iFacilIntMsg = klogFacilIntMsg(); } /* enqueue the the kernel message into the message queue. * The provided msg string is not freed - thus must be done * by the caller. * rgerhards, 2008-04-12 */ static rsRetVal enqMsg(uchar *msg, uchar *pszTag, syslog_pri_t pri, struct timeval *tp, struct json_object *json) { struct syslogTime st; smsg_t *pMsg; DEFiRet; assert(msg != NULL); assert(pszTag != NULL); if (tp == NULL) { CHKiRet(msgConstruct(&pMsg)); } else { datetime.timeval2syslogTime(tp, &st, TIME_IN_LOCALTIME); CHKiRet(msgConstructWithTime(&pMsg, &st, tp->tv_sec)); } MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); MsgSetInputName(pMsg, pInputName); MsgSetRawMsgWOSize(pMsg, (char *)msg); MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, pLocalHostIP); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetTAG(pMsg, pszTag, ustrlen(pszTag)); msgSetPRI(pMsg, pri); pMsg->json = json; CHKiRet(submitMsg2(pMsg)); finalize_it: RETiRet; } /* log an imkmsg-internal message * rgerhards, 2008-04-14 */ rsRetVal imkmsgLogIntMsg(syslog_pri_t priority, const char *fmt, ...) { DEFiRet; va_list ap; uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ va_start(ap, fmt); vsnprintf((char *)msgBuf, sizeof(msgBuf), fmt, ap); va_end(ap); logmsgInternal(NO_ERRCODE, priority, msgBuf, 0); RETiRet; } /* log a message from /dev/kmsg */ rsRetVal Syslog(syslog_pri_t priority, uchar *pMsg, struct timeval *tp, struct json_object *json) { DEFiRet; iRet = enqMsg((uchar *)pMsg, (uchar *)"kernel:", priority, tp, json); RETiRet; } /* helper for some klog drivers which need to know the MaxLine global setting. They can * not obtain it themselfs, because they are no modules and can not query the object hander. * It would probably be a good idea to extend the interface to support it, but so far * we create a (sufficiently valid) work-around. -- rgerhards, 2008-11-24 */ int klog_getMaxLine(void) { return glbl.GetMaxLine(runModConf->pConf); } BEGINrunInput CODESTARTrunInput; /* this is an endless loop - it is terminated when the thread is * signalled to do so. This, however, is handled by the framework, * right into the sleep below. */ while (!pThrd->bShallStop) { /* klogLogKMsg() waits for the next kernel message, obtains it * and then submits it to the rsyslog main queue. * rgerhards, 2008-04-09 */ CHKiRet(klogLogKMsg(runModConf)); } finalize_it: ENDrunInput BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; /* init our settings */ pModConf->iFacilIntMsg = klogFacilIntMsg(); pModConf->parseKernelStamp = KMSG_PARSE_TS_STARTUP_ONLY; pModConf->readMode = KMSG_READMODE_FULL_BOOT; pModConf->expected_boot_complete_secs = 90; loadModConf->configSetViaV2Method = 0; bLegacyCnfModGlobalsPermitted = 1; /* init legacy config vars */ initConfigSettings(); ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for imkmsg:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "parsekerneltimestamp")) { if (!es_strconstcmp(pvals[i].val.d.estr, "on") || !es_strconstcmp(pvals[i].val.d.estr, "always")) { loadModConf->parseKernelStamp = KMSG_PARSE_TS_ALWAYS; } else if (!es_strconstcmp(pvals[i].val.d.estr, "startup")) { loadModConf->parseKernelStamp = KMSG_PARSE_TS_STARTUP_ONLY; } else if (!es_strconstcmp(pvals[i].val.d.estr, "off")) { loadModConf->parseKernelStamp = KMSG_PARSE_TS_OFF; } else { const char *const cstr = es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_PARAM_ERROR, "imkmsg: unknown " "parse mode '%s'", cstr); free((void *)cstr); } } else if (!strcmp(modpblk.descr[i].name, "expectedbootcompleteseconds")) { loadModConf->expected_boot_complete_secs = pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "readmode")) { if (!es_strconstcmp(pvals[i].val.d.estr, "full-boot")) { loadModConf->readMode = KMSG_READMODE_FULL_BOOT; } else if (!es_strconstcmp(pvals[i].val.d.estr, "full-always")) { loadModConf->readMode = KMSG_READMODE_FULL_ALWAYS; } else if (!es_strconstcmp(pvals[i].val.d.estr, "new-only")) { loadModConf->readMode = KMSG_READMODE_NEW_ONLY; } else { const char *const cstr = es_str2cstr(pvals[i].val.d.estr, NULL); LogError(0, RS_RET_PARAM_ERROR, "imkmsg: unknown " "read mode '%s', keeping default setting", cstr); free((void *)cstr); } } else { LogMsg(0, RS_RET_INTERNAL_ERROR, LOG_WARNING, "imkmsg: RSYSLOG BUG, non-handled param '%s' in " "beginCnfLoad\n", modpblk.descr[i].name); } } /* disable legacy module-global config directives */ bLegacyCnfModGlobalsPermitted = 0; loadModConf->configSetViaV2Method = 1; finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; if (!loadModConf->configSetViaV2Method) { /* persist module-specific settings from legacy config system */ loadModConf->iFacilIntMsg = cs.iFacilIntMsg; } loadModConf = NULL; /* done loading */ ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnfPrePrivDrop CODESTARTactivateCnfPrePrivDrop; runModConf = pModConf; iRet = klogWillRunPrePrivDrop(runModConf); ENDactivateCnfPrePrivDrop BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINwillRun CODESTARTwillRun; iRet = klogWillRunPostPrivDrop(runModConf); ENDwillRun BEGINafterRun CODESTARTafterRun; iRet = klogAfterRun(runModConf); ENDafterRun BEGINmodExit CODESTARTmodExit; if (pInputName != NULL) prop.Destruct(&pInputName); if (pLocalHostIP != NULL) prop.Destruct(&pLocalHostIP); /* release objects we used */ objRelease(glbl, CORE_COMPONENT); objRelease(net, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; ENDqueryEtryPt static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { cs.iFacilIntMsg = klogFacilIntMsg(); return RS_RET_OK; } BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(net, CORE_COMPONENT)); /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.CreateStringProp(&pInputName, UCHAR_CONSTANT("imkmsg"), sizeof("imkmsg") - 1)); CHKiRet(prop.CreateStringProp(&pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); /* init legacy config settings */ initConfigSettings(); CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit rsyslog-8.2512.0/contrib/imkmsg/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017530 xustar0030 mtime=1764935885.820004392 30 atime=1764935896.418166728 30 ctime=1764935924.367594707 rsyslog-8.2512.0/contrib/imkmsg/Makefile.in0000664000175000017500000006537015114544315017207 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imkmsg ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) imkmsg_la_DEPENDENCIES = am_imkmsg_la_OBJECTS = imkmsg_la-imkmsg.lo imkmsg_la-kmsg.lo imkmsg_la_OBJECTS = $(am_imkmsg_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imkmsg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(imkmsg_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imkmsg_la-imkmsg.Plo \ ./$(DEPDIR)/imkmsg_la-kmsg.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imkmsg_la_SOURCES) DIST_SOURCES = $(imkmsg_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imkmsg.la imkmsg_la_SOURCES = imkmsg.c imkmsg.h kmsg.c imkmsg_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imkmsg_la_LDFLAGS = -module -avoid-version imkmsg_la_LIBADD = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imkmsg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imkmsg/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imkmsg.la: $(imkmsg_la_OBJECTS) $(imkmsg_la_DEPENDENCIES) $(EXTRA_imkmsg_la_DEPENDENCIES) $(AM_V_CCLD)$(imkmsg_la_LINK) -rpath $(pkglibdir) $(imkmsg_la_OBJECTS) $(imkmsg_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imkmsg_la-imkmsg.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imkmsg_la-kmsg.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imkmsg_la-imkmsg.lo: imkmsg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imkmsg_la-imkmsg.lo -MD -MP -MF $(DEPDIR)/imkmsg_la-imkmsg.Tpo -c -o imkmsg_la-imkmsg.lo `test -f 'imkmsg.c' || echo '$(srcdir)/'`imkmsg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imkmsg_la-imkmsg.Tpo $(DEPDIR)/imkmsg_la-imkmsg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imkmsg.c' object='imkmsg_la-imkmsg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imkmsg_la-imkmsg.lo `test -f 'imkmsg.c' || echo '$(srcdir)/'`imkmsg.c imkmsg_la-kmsg.lo: kmsg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imkmsg_la-kmsg.lo -MD -MP -MF $(DEPDIR)/imkmsg_la-kmsg.Tpo -c -o imkmsg_la-kmsg.lo `test -f 'kmsg.c' || echo '$(srcdir)/'`kmsg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imkmsg_la-kmsg.Tpo $(DEPDIR)/imkmsg_la-kmsg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kmsg.c' object='imkmsg_la-kmsg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imkmsg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imkmsg_la-kmsg.lo `test -f 'kmsg.c' || echo '$(srcdir)/'`kmsg.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imkmsg_la-imkmsg.Plo -rm -f ./$(DEPDIR)/imkmsg_la-kmsg.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imkmsg_la-imkmsg.Plo -rm -f ./$(DEPDIR)/imkmsg_la-kmsg.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omtcl0000644000000000000000000000013215114544373015241 xustar0030 mtime=1764935931.009696388 30 atime=1764935934.366747775 30 ctime=1764935931.009696388 rsyslog-8.2512.0/contrib/omtcl/0000775000175000017500000000000015114544373014762 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omtcl/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017345 xustar0030 mtime=1752569012.331237145 30 atime=1764930929.336824469 30 ctime=1764935931.005696326 rsyslog-8.2512.0/contrib/omtcl/Makefile.am0000664000175000017500000000027415035412264017014 0ustar00rgerrgerpkglib_LTLIBRARIES = omtcl.la omtcl_la_SOURCES = omtcl.c omtcl_la_CPPFLAGS = $(RSRT_CFLAGS) $(TCL_INCLUDE_SPEC) omtcl_la_LDFLAGS = -module omtcl_la_LIBADD = $(TCL_LIB_SPEC) EXTRA_DIST = rsyslog-8.2512.0/contrib/omtcl/PaxHeaders/omtcl.c0000644000000000000000000000013215055605325016577 xustar0030 mtime=1756826325.614800155 30 atime=1764931105.729748177 30 ctime=1764935931.009696388 rsyslog-8.2512.0/contrib/omtcl/omtcl.c0000664000175000017500000001036015055605325016243 0ustar00rgerrger/* omtcl.c * invoke a tcl procedure for every message * * NOTE: read comments in module-template.h for more specifics! * * File begun on 2016-05-16 by fcr * * Copyright 2016 Francisco Castro * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" /* work around gcc-7 build problems - acceptable for contributed module */ #pragma GCC diagnostic ignored "-Wundef" #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "tcl.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; DEF_OMOD_STATIC_DATA; typedef struct _instanceData { Tcl_Interp* interp; Tcl_Obj* cmdName; } instanceData; typedef struct wrkrInstanceData { instanceData* pData; } wrkrInstanceData_t; BEGINinitConfVars CODESTARTinitConfVars; ENDinitConfVars BEGINcreateInstance CODESTARTcreateInstance; pData->interp = Tcl_CreateInterp(); pData->cmdName = NULL; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; /* not compatible with message reduction */ ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; if (pData->cmdName != NULL) Tcl_DecrRefCount(pData->cmdName); Tcl_DeleteInterp(pData->interp); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINdoAction Tcl_Obj* objv[2]; CODESTARTdoAction; objv[0] = pWrkrData->pData->cmdName; objv[1] = Tcl_NewStringObj((char*)ppString[0], -1); if (Tcl_EvalObjv(pWrkrData->pData->interp, 2, objv, 0) != TCL_OK) { iRet = RS_RET_ERR; DBGPRINTF("omtcl: %s", Tcl_GetStringResult(pWrkrData->pData->interp)); } ENDdoAction BEGINparseSelectorAct char fileName[PATH_MAX + 1]; char buffer[4096]; CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) if (strncmp((char*)p, ":omtcl:", sizeof(":omtcl:") - 1)) { ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); } p += sizeof(":omtcl:") - 1; if (getSubString(&p, fileName, PATH_MAX + 1, ',') || getSubString(&p, buffer, 4096, ';') || !strlen(buffer)) { LogError(0, RS_RET_INVALID_PARAMS, "Invalid OmTcl parameters"); ABORT_FINALIZE(RS_RET_INVALID_PARAMS); } if (*(p - 1) == ';') --p; CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*)"RSYSLOG_FileFormat")); CHKiRet(createInstance(&pData)); pData->cmdName = Tcl_NewStringObj(buffer, -1); Tcl_IncrRefCount(pData->cmdName); // TODO parse arguments: file,procname if (Tcl_EvalFile(pData->interp, fileName) == TCL_ERROR) { LogError(0, RS_RET_CONFIG_ERROR, "Loading Tcl script: %s", Tcl_GetStringResult(pData->interp)); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; INITLegCnfVars; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("omtcl: module compiled with rsyslog version %s.\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/omtcl/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316017360 xustar0030 mtime=1764935886.344012418 30 atime=1764935896.756171904 30 ctime=1764935931.007696357 rsyslog-8.2512.0/contrib/omtcl/Makefile.in0000664000175000017500000006303715114544316017035 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omtcl ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omtcl_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_omtcl_la_OBJECTS = omtcl_la-omtcl.lo omtcl_la_OBJECTS = $(am_omtcl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omtcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omtcl_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omtcl_la-omtcl.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omtcl_la_SOURCES) DIST_SOURCES = $(omtcl_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omtcl.la omtcl_la_SOURCES = omtcl.c omtcl_la_CPPFLAGS = $(RSRT_CFLAGS) $(TCL_INCLUDE_SPEC) omtcl_la_LDFLAGS = -module omtcl_la_LIBADD = $(TCL_LIB_SPEC) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omtcl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omtcl/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omtcl.la: $(omtcl_la_OBJECTS) $(omtcl_la_DEPENDENCIES) $(EXTRA_omtcl_la_DEPENDENCIES) $(AM_V_CCLD)$(omtcl_la_LINK) -rpath $(pkglibdir) $(omtcl_la_OBJECTS) $(omtcl_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omtcl_la-omtcl.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omtcl_la-omtcl.lo: omtcl.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omtcl_la-omtcl.lo -MD -MP -MF $(DEPDIR)/omtcl_la-omtcl.Tpo -c -o omtcl_la-omtcl.lo `test -f 'omtcl.c' || echo '$(srcdir)/'`omtcl.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omtcl_la-omtcl.Tpo $(DEPDIR)/omtcl_la-omtcl.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omtcl.c' object='omtcl_la-omtcl.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omtcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omtcl_la-omtcl.lo `test -f 'omtcl.c' || echo '$(srcdir)/'`omtcl.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omtcl_la-omtcl.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omtcl_la-omtcl.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/imhiredis0000644000000000000000000000013115114544373016077 xustar0030 mtime=1764935931.776708129 29 atime=1764935934.36774779 30 ctime=1764935931.776708129 rsyslog-8.2512.0/contrib/imhiredis/0000775000175000017500000000000015114544373015621 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imhiredis/PaxHeaders/README0000644000000000000000000000013115055602573017035 xustar0029 mtime=1756824955.96045048 30 atime=1764931156.987575434 30 ctime=1764935931.773708083 rsyslog-8.2512.0/contrib/imhiredis/README0000664000175000017500000000423515055602573016506 0ustar00rgerrgerRedis Input Plugin using hiredis library REQUIREMENTS: * hiredis ( https://github.com/redis/hiredis.git ) USAGE: This plugin has two current "modes" that it supports: 1. "queue" The queue mode will LPOP or RPOP your message from a redis list. Following parameters are required: - mode: Set mode to "queue" to enable the queue mode - key: The key to xPOP on - server: The name or IP address of the redis server - port: The redis listening port Following parameters are optional: - password: If set, the plugin will issue an "AUTH" command before calling xPOP - uselpop: If set to "1", LPOP will be used instead of default RPOP Redis pipelining is used inside the worker thread. The dequeue batch size is configured with the "batchsize" parameter (default is 10). Imhiredis will query Redis every second to see if entries are in the list, if that's the case they will be dequeued continuously by batches of "batchsize elements" until none remains. Due to its balance between polling interval and pipelining and its use of lists, this mode is quite performant and reliable. However, due to the 1 second polling frequency, one may consider using the `subscribe` mode instead if very low latency is required. ``` module(load="imhiredis") input( type="imhiredis" mode="queue" key="vulture" server="127.0.0.1" port="6379" uselpop="1" password="foobar" batchsize="10" ) ``` 2. "subscribe" The subscribe mode will SUBSCRIBE to a redis channel. The "key" parameter is required and will be used for the subscribe channel. Following parameters are required: - mode: Set mode to "subscribe" to enable the subscribe mode - key: The key to subscribe to (aka the "channel") - server: The name or IP address of the redis server - port: The redis listening port Following parameters are optional: - password: If set, the plugin will issue an "AUTH" command before listening to a channel - uselpop: If set to "1", LPOP will be used instead of default RPOP ``` module(load="imhiredis") input( type="imhiredis" mode="subscribe" key="vulture" server="127.0.0.1" port="6379" password="foobar" batchsize="10" ) ``` TODO * TLS support rsyslog-8.2512.0/contrib/imhiredis/PaxHeaders/Makefile.am0000644000000000000000000000013115055602573020211 xustar0029 mtime=1756824955.96045048 30 atime=1764930927.698796671 30 ctime=1764935931.766707976 rsyslog-8.2512.0/contrib/imhiredis/Makefile.am0000664000175000017500000000036415055602573017661 0ustar00rgerrgerpkglib_LTLIBRARIES = imhiredis.la imhiredis_la_SOURCES = imhiredis.c imhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) imhiredis_la_LDFLAGS = -module -avoid-version imhiredis_la_LIBADD = $(HIREDIS_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/imhiredis/PaxHeaders/COPYING0000644000000000000000000000013115055602573017210 xustar0029 mtime=1756824955.96045048 30 atime=1764931156.979575306 30 ctime=1764935931.771708052 rsyslog-8.2512.0/contrib/imhiredis/COPYING0000664000175000017500000010437015055602573016662 0ustar00rgerrger GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . rsyslog-8.2512.0/contrib/imhiredis/PaxHeaders/imhiredis.c0000644000000000000000000000013115055605325020274 xustar0029 mtime=1756826325.61180011 30 atime=1764931156.997575595 30 ctime=1764935931.776708129 rsyslog-8.2512.0/contrib/imhiredis/imhiredis.c0000664000175000017500000023635415055605325017756 0ustar00rgerrger/* imhiredis.c * Copyright 2021 aDvens * * This file is contrib for rsyslog. * This input plugin is a log consumer from REDIS * See README for doc * * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . * * Author: Jérémie Jourdin * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "atomic.h" #include "statsobj.h" #include "unicode-helper.h" #include "prop.h" #include "ruleset.h" #include "glbl.h" #include "cfsysline.h" #include "msg.h" #include "dirty.h" MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imhiredis") /* static data */ DEF_IMOD_STATIC_DATA; #define BATCH_SIZE 10 #define WAIT_TIME_MS 500 #define STREAM_INDEX_STR_MAXLEN 44 // "18446744073709551615-18446744073709551615" #define IMHIREDIS_MODE_QUEUE 1 #define IMHIREDIS_MODE_SUBSCRIBE 2 #define IMHIREDIS_MODE_STREAM 3 DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) DEFobjCurrIf(glbl) DEFobjCurrIf(statsobj) typedef struct redisNode_s { sbool isMaster; sbool usesSocket; uchar *socketPath; uchar *server; int port; struct redisNode_s *next; } redisNode; struct instanceConf_s { uchar *password; uchar *key; uchar *modeDescription; uchar *streamConsumerGroup; uchar *streamConsumerName; uchar *streamReadFrom; int streamAutoclaimIdleTime; sbool streamConsumerACK; int mode; uint batchsize; sbool useLPop; struct { int nmemb; char **name; char **varname; } fieldList; ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ uchar *pszBindRuleset; /* default name of Ruleset to bind to */ redisContext *conn; redisAsyncContext *aconn; struct event_base *evtBase; redisNode *currentNode; /* currently used redis node, can be any of the nodes in the redisNodesList list */ /* the list of seen nodes * the preferred node (the one from configuration) will always be the first element * second one is a master (if preferred one is unavailable/replica) or a replica, others are replicas * the preferred node may appear twice, but it is accepted */ redisNode *redisNodesList; struct instanceConf_s *next; }; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ instanceConf_t *root, *tail; }; /* The following structure controls the worker threads. Global data is * needed for their access. */ static struct imhiredisWrkrInfo_s { pthread_t tid; /* the worker's thread ID */ instanceConf_t *inst; /* Pointer to imhiredis instance */ rsRetVal (*fnConnectMaster)(instanceConf_t *inst); sbool (*fnIsConnected)(instanceConf_t *inst); rsRetVal (*fnRun)(instanceConf_t *inst); } *imhiredisWrkrInfo; /* GLOBAL DATA */ pthread_attr_t wrkrThrdAttr; /* Attribute for worker threads ; read only after startup */ static int activeHiredisworkers = 0; static const char *REDIS_REPLIES[] = { "unknown", // 0 "string", // 1 "array", // 2 "integer", // 3 "nil", // 4 "status", // 5 "error", // 6 "double", // 7 "bool", // 8 "map", // 9 "set", // 10 "attr", // 11 "push", // 12 "bignum", // 13 "verb", // 14 }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current load process */ static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this input */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = {}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* input instance parameters */ static struct cnfparamdescr inppdescr[] = { {"socketPath", eCmdHdlrGetWord, 0}, {"server", eCmdHdlrGetWord, 0}, {"port", eCmdHdlrInt, 0}, {"password", eCmdHdlrGetWord, 0}, {"mode", eCmdHdlrGetWord, 0}, {"batchsize", eCmdHdlrInt, 0}, {"key", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"uselpop", eCmdHdlrBinary, 0}, {"ruleset", eCmdHdlrString, 0}, {"stream.consumerGroup", eCmdHdlrGetWord, 0}, {"stream.consumerName", eCmdHdlrGetWord, 0}, {"stream.readFrom", eCmdHdlrGetWord, 0}, {"stream.consumerACK", eCmdHdlrBinary, 0}, {"stream.autoclaimIdleTime", eCmdHdlrNonNegInt, 0}, {"fields", eCmdHdlrArray, 0}, }; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; struct timeval glblRedisConnectTimeout = {3, 0}; /* 3 seconds */ #include "im-helper.h" /* must be included AFTER the type definitions! */ /* forward references */ static void redisAsyncRecvCallback(redisAsyncContext __attribute__((unused)) * c, void *reply, void *inst_obj); static void redisAsyncConnectCallback(const redisAsyncContext *c, int status); static void redisAsyncDisconnectCallback(const redisAsyncContext *c, int status); redisReply *getRole(redisContext *c); static struct json_object *_redisParseIntegerReply(const redisReply *reply); static struct json_object *_redisParseStringReply(const redisReply *reply); static struct json_object *_redisParseArrayReply(const redisReply *reply); #ifdef REDIS_REPLY_DOUBLE static struct json_object *_redisParseDoubleReply(const redisReply *reply); #endif static rsRetVal enqMsg(instanceConf_t *const inst, const char *message, size_t msgLen); static rsRetVal enqMsgJson(instanceConf_t *const inst, struct json_object *json, struct json_object *metadata); rsRetVal redisAuthentSynchronous(redisContext *conn, uchar *password); rsRetVal redisAuthentAsynchronous(redisAsyncContext *aconn, uchar *password); rsRetVal redisActualizeCurrentNode(instanceConf_t *inst); rsRetVal redisGetServersList(redisNode *node, uchar *password, redisNode **result); rsRetVal redisAuthenticate(instanceConf_t *inst); rsRetVal redisConnectSync(redisContext **conn, redisNode *node); rsRetVal connectMasterSync(instanceConf_t *inst); static sbool isConnectedSync(instanceConf_t *inst); rsRetVal redisConnectAsync(redisAsyncContext **aconn, redisNode *node); rsRetVal connectMasterAsync(instanceConf_t *inst); static sbool isConnectedAsync(instanceConf_t *inst); rsRetVal redisDequeue(instanceConf_t *inst); rsRetVal ensureConsumerGroupCreated(instanceConf_t *inst); rsRetVal ackStreamIndex(instanceConf_t *inst, uchar *stream, uchar *group, uchar *index); static rsRetVal enqueueRedisStreamReply(instanceConf_t *const inst, redisReply *reply); static rsRetVal handleRedisXREADReply(instanceConf_t *const inst, const redisReply *reply); static rsRetVal handleRedisXAUTOCLAIMReply(instanceConf_t *const inst, const redisReply *reply, char **autoclaimIndex); rsRetVal redisStreamRead(instanceConf_t *inst); rsRetVal redisSubscribe(instanceConf_t *inst); void workerLoop(struct imhiredisWrkrInfo_s *me); static void *imhirediswrkr(void *myself); static rsRetVal createRedisNode(redisNode **root); rsRetVal copyNode(redisNode *src, redisNode **dst); redisNode *freeNode(redisNode *node); void insertNodeAfter(redisNode *root, redisNode *elem); void dbgPrintNode(redisNode *node); /* create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal createInstance(instanceConf_t **pinst) { DEFiRet; instanceConf_t *inst; CHKmalloc(inst = calloc(1, sizeof(instanceConf_t))); inst->next = NULL; inst->password = NULL; inst->key = NULL; inst->mode = 0; inst->batchsize = 0; inst->useLPop = 0; inst->streamConsumerGroup = NULL; inst->streamConsumerName = NULL; CHKmalloc(inst->streamReadFrom = calloc(1, STREAM_INDEX_STR_MAXLEN)); inst->streamAutoclaimIdleTime = 0; inst->streamConsumerACK = 1; inst->pszBindRuleset = NULL; inst->pBindRuleset = NULL; inst->fieldList.nmemb = 0; /* Redis objects */ inst->conn = NULL; inst->aconn = NULL; /* redis nodes list */ CHKiRet(createRedisNode(&(inst->redisNodesList))); inst->currentNode = inst->redisNodesList; /* libevent base for async connection */ inst->evtBase = NULL; /* node created, let's add to config */ if (loadModConf->tail == NULL) { loadModConf->tail = loadModConf->root = inst; } else { loadModConf->tail->next = inst; loadModConf->tail = inst; } *pinst = inst; finalize_it: RETiRet; } /* this function checks instance parameters and does some required pre-processing */ static rsRetVal ATTR_NONNULL() checkInstance(instanceConf_t *const inst) { DEFiRet; /* first node should be created from configuration */ assert(inst->redisNodesList != NULL); /* check and print redis connection settings */ if (inst->redisNodesList->server != NULL && inst->redisNodesList->socketPath != NULL) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: both 'server' and 'socketPath' are given, " "ignoring 'socketPath'."); free(inst->redisNodesList->socketPath); inst->redisNodesList->socketPath = NULL; } if (inst->redisNodesList->server != NULL && inst->redisNodesList->server[0] != '\0') { if (inst->redisNodesList->port == 0) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: port not set, setting default 6379"); inst->redisNodesList->port = 6379; } DBGPRINTF("imhiredis: preferred server is %s (%d)\n", inst->redisNodesList->server, inst->redisNodesList->port); inst->redisNodesList->usesSocket = 0; } else if (inst->redisNodesList->socketPath != NULL && inst->redisNodesList->socketPath[0] != '\0') { DBGPRINTF("imhiredis: preferred server is %s\n", inst->redisNodesList->socketPath); inst->redisNodesList->usesSocket = 1; } else { LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: neither 'server' nor 'socketPath' are defined!"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (inst->mode < IMHIREDIS_MODE_QUEUE || inst->mode > IMHIREDIS_MODE_STREAM) { LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: invalid mode, please choose 'subscribe', " "'queue' or 'stream' mode."); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (inst->mode != IMHIREDIS_MODE_QUEUE && inst->useLPop) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'uselpop' set with mode != queue : ignored."); } if (inst->mode == IMHIREDIS_MODE_STREAM) { if (inst->streamConsumerGroup != NULL && inst->streamConsumerName == NULL) { LogError(0, RS_RET_CONFIG_ERROR, "imhiredis: invalid configuration, " "please set a consumer name when mode is 'stream' and a consumer group is set"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } if (inst->streamAutoclaimIdleTime != 0 && inst->streamConsumerGroup == NULL) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'stream.autoclaimIdleTime' " "set with no consumer group set : ignored."); } if (inst->streamReadFrom[0] == '\0') { inst->streamReadFrom[0] = '$'; } } else { if (inst->streamConsumerGroup != NULL) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'stream.consumerGroup' " "set with mode != stream : ignored."); } if (inst->streamConsumerName != NULL) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'stream.consumerName' " "set with mode != stream : ignored."); } if (inst->streamAutoclaimIdleTime != 0) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'stream.autoclaimIdleTime' " "set with mode != stream : ignored."); } if (inst->streamConsumerACK == 0) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'stream.consumerACK' " "disabled with mode != stream : ignored."); } if (inst->fieldList.nmemb > 0) { LogMsg(0, RS_RET_CONFIG_ERROR, LOG_WARNING, "imhiredis: 'fields' " "unused for mode != stream : ignored."); } } if (inst->batchsize != 0) { DBGPRINTF("imhiredis: batchsize is '%d'\n", inst->batchsize); } else { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: batchsize not set, setting to default (%d)", BATCH_SIZE); inst->batchsize = BATCH_SIZE; } if (inst->password != NULL) { DBGPRINTF("imhiredis: password is '%s'\n", inst->password); } // set default current node as first node in list (preferred node) inst->currentNode = inst->redisNodesList; // search master node (should be either preferred node or its master) if (RS_RET_OK != redisActualizeCurrentNode(inst) || inst->currentNode == NULL) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: could not connect to a valid master!"); } finalize_it: RETiRet; } /* function to generate an error message if the ruleset cannot be found */ static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "imhiredis: ruleset '%s' not found - " "using default ruleset instead", inst->pszBindRuleset); } BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst; int i; CODESTARTnewInpInst; DBGPRINTF("newInpInst (imhiredis)\n"); if ((pvals = nvlstGetParams(lst, &inppblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("input param blk in imhiredis:\n"); cnfparamsPrint(&inppblk, pvals); } CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "server")) { inst->redisNodesList->server = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "socketPath")) { inst->redisNodesList->socketPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "port")) { inst->redisNodesList->port = (int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "password")) { inst->password = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "stream.consumerGroup")) { inst->streamConsumerGroup = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "stream.consumerName")) { inst->streamConsumerName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "stream.consumerACK")) { inst->streamConsumerACK = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "stream.readFrom")) { // inst->streamReadFrom is already allocated, only copy contents memcpy(inst->streamReadFrom, es_getBufAddr(pvals[i].val.d.estr), es_strlen(pvals[i].val.d.estr)); inst->streamReadFrom[es_strlen(pvals[i].val.d.estr)] = '\0'; } else if (!strcmp(inppblk.descr[i].name, "stream.autoclaimIdleTime")) { inst->streamAutoclaimIdleTime = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "uselpop")) { inst->useLPop = pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "mode")) { inst->modeDescription = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcmp((const char *)inst->modeDescription, "queue")) { inst->mode = IMHIREDIS_MODE_QUEUE; } else if (!strcmp((const char *)inst->modeDescription, "subscribe")) { inst->mode = IMHIREDIS_MODE_SUBSCRIBE; } else if (!strcmp((const char *)inst->modeDescription, "stream")) { inst->mode = IMHIREDIS_MODE_STREAM; } else { LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "imhiredis: unsupported mode " "'%s'", inst->modeDescription); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } } else if (!strcmp(inppblk.descr[i].name, "fields")) { inst->fieldList.nmemb = pvals[i].val.d.ar->nmemb; CHKmalloc(inst->fieldList.name = calloc(inst->fieldList.nmemb, sizeof(char *))); CHKmalloc(inst->fieldList.varname = calloc(inst->fieldList.nmemb, sizeof(char *))); for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { char *const param = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); char *varname = NULL; char *name; if (*param == ':') { char *b = strchr(param + 1, ':'); if (b == NULL) { LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "imhiredis: missing closing colon: '%s'", param); ABORT_FINALIZE(RS_RET_ERR); } *b = '\0'; /* split name & varname */ varname = param + 1; name = b + 1; } else { name = param; } CHKmalloc(inst->fieldList.name[j] = strdup(name)); char vnamebuf[1024]; snprintf(vnamebuf, sizeof(vnamebuf), "!%s", (varname == NULL) ? name : varname); CHKmalloc(inst->fieldList.varname[j] = strdup(vnamebuf)); DBGPRINTF("will map '%s' to '%s'\n", inst->fieldList.name[j], inst->fieldList.varname[j]); free(param); } } else if (!strcmp(inppblk.descr[i].name, "batchsize")) { inst->batchsize = (int)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "key")) { inst->key = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf( "imhiredis: program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } DBGPRINTF("imhiredis: checking config sanity\n"); if (inst->modeDescription == NULL) { CHKmalloc(inst->modeDescription = (uchar *)strdup("subscribe")); inst->mode = IMHIREDIS_MODE_SUBSCRIBE; LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: \"mode\" parameter not specified " "using default redis 'subscribe' mode -- this may not be what you want!"); } if (inst->key == NULL) { LogMsg(0, RS_RET_PARAM_ERROR, LOG_ERR, "imhiredis: \"key\" required parameter not specified!"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } if (inst->redisNodesList->server == NULL && inst->redisNodesList->socketPath == NULL) { CHKmalloc(inst->redisNodesList->server = (uchar *)strdup("127.0.0.1")); inst->redisNodesList->port = 6379; LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "imhiredis: no server parameter specified " "using default 127.0.0.1:6379 -- this may not be what you want!"); } if (inst->password == NULL) { LogMsg(0, RS_RET_OK, LOG_INFO, "imhiredis: no password specified"); } DBGPRINTF("imhiredis: newInpInst key=%s, mode=%s, uselpop=%d\n", inst->key, inst->modeDescription, inst->useLPop); finalize_it: CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "imhiredis: error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for imhiredis:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } else { dbgprintf( "imhiredis: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = pModConf->root; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); } ENDcheckCnf BEGINactivateCnfPrePrivDrop CODESTARTactivateCnfPrePrivDrop; runModConf = pModConf; ENDactivateCnfPrePrivDrop BEGINactivateCnf CODESTARTactivateCnf; for (instanceConf_t *inst = pModConf->root; inst != NULL; inst = inst->next) { iRet = checkInstance(inst); if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) inst->evtBase = event_base_new(); } ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; redisNode *node; CODESTARTfreeCnf; for (inst = pModConf->root; inst != NULL;) { if (inst->evtBase) event_base_free(inst->evtBase); if (inst->password != NULL) free(inst->password); free(inst->modeDescription); free(inst->key); if (inst->streamConsumerGroup != NULL) free(inst->streamConsumerGroup); if (inst->streamConsumerName != NULL) free(inst->streamConsumerName); free(inst->streamReadFrom); free(inst->pszBindRuleset); if (inst->fieldList.name != NULL) { for (int i = 0; i < inst->fieldList.nmemb; ++i) { free(inst->fieldList.name[i]); free(inst->fieldList.varname[i]); } free(inst->fieldList.name); free(inst->fieldList.varname); } if (inst->conn != NULL) { redisFree(inst->conn); inst->conn = NULL; } if (inst->aconn != NULL) { redisAsyncFree(inst->aconn); inst->aconn = NULL; } for (node = inst->redisNodesList; node != NULL; node = freeNode(node)) { ; } del = inst; inst = inst->next; free(del); } ENDfreeCnf /* Cleanup imhiredis worker threads */ static void shutdownImhiredisWorkers(void) { int i; instanceConf_t *inst; assert(imhiredisWrkrInfo != NULL); for (inst = runModConf->root; inst != NULL; inst = inst->next) { if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE && inst->aconn) { DBGPRINTF("imhiredis: disconnecting async worker\n"); redisAsyncDisconnect(inst->aconn); } } // event_base_loopbreak(runModConf->evtBase); DBGPRINTF("imhiredis: waiting on imhiredis workerthread termination\n"); for (i = 0; i < activeHiredisworkers; ++i) { pthread_join(imhiredisWrkrInfo[i].tid, NULL); DBGPRINTF("imhiredis: Stopped worker %d\n", i); } free(imhiredisWrkrInfo); imhiredisWrkrInfo = NULL; return; } /* This function is called to gather input. */ BEGINrunInput int i; instanceConf_t *inst; CODESTARTrunInput; DBGPRINTF("imhiredis: runInput loop started ...\n"); activeHiredisworkers = 0; for (inst = runModConf->root; inst != NULL; inst = inst->next) { ++activeHiredisworkers; } if (activeHiredisworkers == 0) { LogError(0, RS_RET_ERR, "imhiredis: no active inputs, input does " "not run - there should have been additional error " "messages given previously"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imhiredis: Starting %d imhiredis workerthreads\n", activeHiredisworkers); imhiredisWrkrInfo = calloc(activeHiredisworkers, sizeof(struct imhiredisWrkrInfo_s)); if (imhiredisWrkrInfo == NULL) { LogError(errno, RS_RET_OUT_OF_MEMORY, "imhiredis: worker-info array allocation failed."); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } /* Start worker threads for each imhiredis input source */ i = 0; for (inst = runModConf->root; inst != NULL; inst = inst->next) { /* init worker info structure! */ imhiredisWrkrInfo[i].inst = inst; /* Set reference pointer */ pthread_create(&imhiredisWrkrInfo[i].tid, &wrkrThrdAttr, imhirediswrkr, &(imhiredisWrkrInfo[i])); i++; } // This thread simply runs the various threads, then waits for Rsyslog to stop while (glbl.GetGlobalInputTermState() == 0) { if (glbl.GetGlobalInputTermState() == 0) /* Check termination state every 0.5s * should be sufficient to grant fast response to shutdown while not hogging CPU */ srSleep(0, 500000); } DBGPRINTF("imhiredis: terminating upon request of rsyslog core\n"); shutdownImhiredisWorkers(); finalize_it: ENDrunInput BEGINwillRun CODESTARTwillRun; /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imhiredis"), sizeof("imhiredis") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); finalize_it: ENDwillRun BEGINafterRun CODESTARTafterRun; if (pInputName != NULL) prop.Destruct(&pInputName); ENDafterRun BEGINmodExit CODESTARTmodExit; pthread_attr_destroy(&wrkrThrdAttr); /* force cleaning of all libevent-related structures * (clean shutdowns are not always guaranteed without it) */ libevent_global_shutdown(); /* release objects we used */ objRelease(statsobj, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); ENDmodExit BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr /* request objects we use */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); /* initialize "read-only" thread attributes */ pthread_attr_init(&wrkrThrdAttr); pthread_attr_setstacksize(&wrkrThrdAttr, 4096 * 1024); /* activate libevent for (p)threads support */ evthread_use_pthreads(); ENDmodInit /* ------------------------------ callbacks ------------------------------ */ /** * Asynchronous subscribe callback handler */ static void redisAsyncRecvCallback(redisAsyncContext *aconn, void *reply, void __attribute__((unused)) * unused) { /* redisReply is supposed to be an array of three elements: [''message', , ] JJO: For future reference (https://github.com/redis/hiredis/blob/master/README.md) Important: the current version of hiredis (1.0.0) frees replies when the asynchronous API is used. This means you should not call freeReplyObject when you use this API. The reply is cleaned up by hiredis after the callback returns. TODO We may have to change this function in the future to free replies. */ instanceConf_t *const inst = (instanceConf_t *)aconn->data; redisReply *r = (redisReply *)reply; if (r == NULL) return; if (r->elements < 3 || r->element[2]->str == NULL) { return; } enqMsg(inst, r->element[2]->str, r->element[2]->len); return; } /** * Asynchronous connection callback handler */ static void redisAsyncConnectCallback(const redisAsyncContext *c, int status) { if (status != REDIS_OK) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis (async): could not connect to redis: " "%s", c->errstr); // remove async context from instance config object, still contained in context's 'data' field instanceConf_t *inst = (instanceConf_t *)c->data; assert(inst != NULL); inst->aconn = NULL; return; } DBGPRINTF("imhiredis (async): successfully connected!\n"); return; } /** * Asynchronous disconnection callback handler */ static void redisAsyncDisconnectCallback(const redisAsyncContext *c, int status) { // remove context from instance config object (which is stored in the context 'data' field by us) // context will be freed by the library, so it's only set to NULL here instanceConf_t *inst = (instanceConf_t *)c->data; assert(inst != NULL); inst->aconn = NULL; inst->currentNode = NULL; if (status != REDIS_OK) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis (async): got disconnected from redis: " "%s", c->errstr); return; } DBGPRINTF("imhiredis (async): successfully disconnected!\n"); return; } /* ------------------------------ end callbacks ------------------------------ */ /* * sends a ROLE command to the redis pointed by context * context should be a valid redis context * returns a valid redisReply pointer if an array reply was received, NULL otherwise */ redisReply *getRole(redisContext *c) { redisReply *reply; assert(c != NULL); reply = redisCommand(c, "ROLE"); if (reply == NULL) { DBGPRINTF("imhiredis: could not get reply from ROLE command\n"); } else if (reply->type == REDIS_REPLY_ERROR) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis got an error while querying role -> " "%s\n", reply->str); freeReplyObject(reply); reply = NULL; } else if (reply->type != REDIS_REPLY_ARRAY) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "imhiredis: did not get an array from ROLE command"); freeReplyObject(reply); reply = NULL; } return reply; } static struct json_object *_redisParseIntegerReply(const redisReply *reply) { return json_object_new_int64(reply->integer); } #ifdef REDIS_REPLY_DOUBLE static struct json_object *_redisParseDoubleReply(const redisReply *reply) { return json_object_new_double_s(reply->dval, reply->str); } #endif static struct json_object *_redisParseStringReply(const redisReply *reply) { return json_object_new_string_len(reply->str, reply->len); } static struct json_object *_redisParseArrayReply(const redisReply *reply) { struct json_object *result = NULL; struct json_object *res = NULL; char *key = NULL; result = json_object_new_object(); // the redis type name is ARRAY, but represents a dict if (result != NULL) { for (size_t i = 0; i < reply->elements; i++) { if (reply->element[i]->type == REDIS_REPLY_STRING && i % 2 == 0) { key = reply->element[i]->str; } else { switch (reply->element[i]->type) { case REDIS_REPLY_INTEGER: res = _redisParseIntegerReply(reply->element[i]); json_object_object_add(result, key, res); break; #ifdef REDIS_REPLY_DOUBLE case REDIS_REPLY_DOUBLE: res = _redisParseDoubleReply(reply->element[i]); json_object_object_add(result, key, res); break; #endif case REDIS_REPLY_STRING: res = _redisParseStringReply(reply->element[i]); json_object_object_add(result, key, res); break; case REDIS_REPLY_ARRAY: res = _redisParseArrayReply(reply->element[i]); json_object_object_add(result, key, res); break; default: DBGPRINTF("Unhandled case!\n"); LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "Redis reply object contains an unhandled type!"); break; } } } } return result; } /* * enqueue the hiredis message. The provided string is * not freed - this must be done by the caller. */ static rsRetVal enqMsg(instanceConf_t *const inst, const char *message, size_t msgLen) { DEFiRet; smsg_t *pMsg; if (message == NULL || message[0] == '\0') { /* we do not process empty lines */ FINALIZE; } DBGPRINTF("imhiredis: enqMsg: Msg -> '%s'\n", message); CHKiRet(msgConstruct(&pMsg)); MsgSetInputName(pMsg, pInputName); MsgSetRawMsg(pMsg, message, msgLen); MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); MsgSetRuleset(pMsg, inst->pBindRuleset); MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ CHKiRet(submitMsg2(pMsg)); finalize_it: RETiRet; } static rsRetVal enqMsgJson(instanceConf_t *const inst, struct json_object *json, struct json_object *metadata) { DEFiRet; smsg_t *pMsg; struct json_object *tempJson = NULL; assert(json != NULL); CHKiRet(msgConstruct(&pMsg)); // In case of allocation error -> needs to break MsgSetInputName(pMsg, pInputName); MsgSetRuleset(pMsg, inst->pBindRuleset); MsgSetMSGoffs(pMsg, 0); /* we do not have a header... */ if (RS_RET_OK != MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY)) LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "Could not set Flow Control on message."); if (inst->fieldList.nmemb != 0) { for (int i = 0; i < inst->fieldList.nmemb; i++) { DBGPRINTF("processing field '%s'\n", inst->fieldList.name[i]); /* case 1: static field. We simply forward it */ if (inst->fieldList.name[i][0] != '!' && inst->fieldList.name[i][0] != '.') { DBGPRINTF("field is static, taking it as it is...\n"); tempJson = json_object_new_string(inst->fieldList.name[i]); } /* case 2: dynamic field. We retrieve its value from the JSON logline and add it */ else { DBGPRINTF("field is dynamic, searching in root object...\n"); if (!json_object_object_get_ex(json, inst->fieldList.name[i] + 1, &tempJson)) { DBGPRINTF("Did not find value %s in message\n", inst->fieldList.name[i]); continue; } // Getting object as it will not keep the same lifetime as its origin object tempJson = json_object_get(tempJson); // original object is put: no need for it anymore json_object_put(json); } DBGPRINTF("got value of field '%s'\n", inst->fieldList.name[i]); DBGPRINTF("will insert to '%s'\n", inst->fieldList.varname[i]); if (RS_RET_OK != msgAddJSON(pMsg, (uchar *)inst->fieldList.varname[i], tempJson, 0, 0)) { LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, "Failed to add value to '%s'", inst->fieldList.varname[i]); } tempJson = NULL; } } else { if (RS_RET_OK != msgAddJSON(pMsg, (uchar *)"!", json, 0, 0)) { LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, "Failed to add json info to message!"); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } } if (metadata != NULL && RS_RET_OK != msgAddJSON(pMsg, (uchar *)".", metadata, 0, 0)) { LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, "Failed to add metadata to message!"); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } if (RS_RET_OK != submitMsg2(pMsg)) { LogMsg(0, RS_RET_OBJ_CREATION_FAILED, LOG_ERR, "Failed to submit message to main queue!"); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } DBGPRINTF("enqMsgJson: message enqueued!\n"); finalize_it: RETiRet; } /* * execute a synchronous authentication using the context conn * conn and password should be non-NULL * conn should be a valid context */ rsRetVal redisAuthentSynchronous(redisContext *conn, uchar *password) { DEFiRet; redisReply *reply = NULL; assert(conn != NULL); assert(password != NULL); assert(password[0] != '\0'); reply = (redisReply *)redisCommand(conn, "AUTH %s", password); if (reply == NULL) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: Could not authenticate!\n"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } else if (strncmp(reply->str, "OK", 2)) { LogError(0, RS_RET_REDIS_AUTH_FAILED, "imhiredis: Authentication failure -> %s\n", reply->str); ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); } finalize_it: if (reply) freeReplyObject(reply); RETiRet; } /* * execute an asynchronous authentication using the context aconn * aconn and password should be non-NULL * aconn should be a valid (async) context */ rsRetVal redisAuthentAsynchronous(redisAsyncContext *aconn, uchar *password) { DEFiRet; assert(aconn != NULL); assert(password != NULL); assert(password[0] != '\0'); if (REDIS_OK != redisAsyncCommand(aconn, NULL, NULL, "AUTH %s", password)) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: error while authenticating asynchronously -> %s\n", aconn->errstr); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } finalize_it: RETiRet; } /* * connect to node, authenticate (if necessary), get role, then get all node information provided by ROLE * node should be a non-NULL valid redisNode pointer * password can be NULL, meaning no authentication will be done * result will hold the result of the ROLE command executed on the node: * - NULL if the node was a single master instance * - a single (master) node if the provided node was a replica * - a list of (replica) nodes if the provided node was a master */ rsRetVal redisGetServersList(redisNode *node, uchar *password, redisNode **result) { DEFiRet; redisContext *context; redisReply *reply = NULL, *replica; unsigned int i; assert(node != NULL); CHKiRet(redisConnectSync(&context, node)); if (password != NULL && password[0] != '\0') { CHKiRet(redisAuthentSynchronous(context, password)); } reply = getRole(context); if (reply == NULL) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: did not get the role of the server"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } /* * string comparisons for ROLE could be skipped * as each role returns a different number of elements, * but lets keep it as a security... */ if (reply->elements == 5 && strncmp(reply->element[0]->str, "slave", 5) == 0) { CHKiRet(createRedisNode(result)); (*result)->server = (uchar *)strdup((const char *)reply->element[1]->str); (*result)->port = reply->element[2]->integer; (*result)->isMaster = 1; } else if (reply->elements == 3 && reply->element[2]->type == REDIS_REPLY_ARRAY && strncmp(reply->element[0]->str, "master", 6) == 0) { // iterate on all replicas given in the reply (if any) for (i = 0; i < reply->element[2]->elements; i++) { replica = reply->element[2]->element[i]; if (replica->type == REDIS_REPLY_ARRAY && replica->elements == 3) { /* node will be a new node every time * with old ones shifted in the list */ CHKiRet(createRedisNode(result)); (*result)->server = (uchar *)strdup((const char *)replica->element[0]->str); // yes, the value in that case is a string and NOT an integer! (*result)->port = atoi(replica->element[1]->str); } } } else { // we have a sentinel, or a problem ABORT_FINALIZE(RS_RET_NOT_FOUND); } finalize_it: if (reply != NULL) freeReplyObject(reply); if (context != NULL) redisFree(context); RETiRet; } /* * actualize the current master node to use during connection for instance inst * inst should be a valid, non-NULL instanceConf object * inst should also possess at least a single node in inst->redisNodeList * if the function returns RS_RET_OK, inst->currentNode and inst->redisNodeList have been both updated * to reflect new master and potential replicas * the first configured node (called preferred node) is always kept as the first entry in redisNodeList */ rsRetVal redisActualizeCurrentNode(instanceConf_t *inst) { DEFiRet; redisReply *reply = NULL; redisNode *node, *tmp, *newList = NULL; assert(inst != NULL); assert(inst->redisNodesList != NULL); inst->currentNode = NULL; // keep first node in list = preferred node (comes from configuration) copyNode(inst->redisNodesList, &newList); newList->next = NULL; for (node = inst->redisNodesList; node != NULL; node = node->next) { tmp = NULL; DBGPRINTF("imhiredis: trying to connect to node to get info...\n"); dbgPrintNode(node); if (RS_RET_OK == redisGetServersList(node, inst->password, &tmp)) { // server replied if (tmp && tmp->isMaster) { DBGPRINTF("imhiredis: node replied with a master node, is a replica\n"); // master node, keep it as potential new active node inst->currentNode = tmp; tmp = NULL; // try to connect to the master and get replicas if (RS_RET_OK != redisGetServersList(inst->currentNode, inst->password, &tmp)) { /* had a master, but cannot connect * save suspected master in new list but keep searching with other nodes */ DBGPRINTF("imhiredis: had a master but cannot connect, keeping in list\n"); dbgPrintNode(inst->currentNode); insertNodeAfter(newList, inst->currentNode); inst->currentNode = NULL; continue; } } else { DBGPRINTF("imhiredis: node replied with a list of replicas, is a master\n"); // copy the node to the new currentNode, list owning node will be freed node->isMaster = 1; copyNode(node, &(inst->currentNode)); inst->currentNode->next = NULL; } /* * here, tmp is a list of replicas or NULL (single node) * inst->currentNode is the new active master */ // add the replicas to the list if (tmp) { insertNodeAfter(newList, tmp); DBGPRINTF("imhiredis: inserting replicas to list\n"); for (tmp = newList->next; tmp != NULL; tmp = tmp->next) { dbgPrintNode(tmp); } } // insert the master after the preferred node (configuration) DBGPRINTF("imhiredis: inserting new master node in list\n"); dbgPrintNode(inst->currentNode); insertNodeAfter(newList, inst->currentNode); // swap newList and redisNodesList to free old list at the end of the function tmp = newList; newList = inst->redisNodesList; inst->redisNodesList = tmp; FINALIZE; } } DBGPRINTF("imhiredis: did not find a valid master"); iRet = RS_RET_NOT_FOUND; inst->currentNode = NULL; finalize_it: if (reply != NULL) freeReplyObject(reply); // newList is always completely freed for (node = newList; node != NULL;) { node = freeNode(node); } RETiRet; } /* * authentication function, for both synchronous and asynchronous modes (queue or subscribe) * inst, inst->curentMode and inst->password should not be NULL */ rsRetVal redisAuthenticate(instanceConf_t *inst) { DEFiRet; redisContext *usedContext = NULL; redisReply *reply = NULL; assert(inst != NULL); assert(inst->currentNode != NULL); assert(inst->password != NULL); assert(inst->password[0] != '\0'); DBGPRINTF("imhiredis: authenticating...\n"); // Create a temporary context for synchronous connection, used to validate AUTH command in asynchronous contexts if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { if (RS_RET_OK != redisConnectSync(&usedContext, inst->currentNode)) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "imhiredis: could not connect to current " "active node synchronously to validate authentication"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } } else { usedContext = inst->conn; } /* * Try synchronous connection, whatever the method for the instance * This is also done for the asynchronous mode, to validate the successful authentication */ CHKiRet(redisAuthentSynchronous(usedContext, inst->password)); if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { CHKiRet(redisAuthentAsynchronous(inst->aconn, inst->password)); } DBGPRINTF("imhiredis: authentication successful\n"); finalize_it: if (inst->mode == IMHIREDIS_MODE_SUBSCRIBE && usedContext) redisFree(usedContext); if (reply) freeReplyObject(reply); RETiRet; } /* * connection function for synchronous (queue) mode * node should not be NULL */ rsRetVal redisConnectSync(redisContext **conn, redisNode *node) { DEFiRet; assert(node != NULL); if (node->usesSocket) *conn = redisConnectUnixWithTimeout((const char *)node->socketPath, glblRedisConnectTimeout); else *conn = redisConnectWithTimeout((const char *)node->server, node->port, glblRedisConnectTimeout); if (*conn == NULL) { if (node->usesSocket) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s' " "-> could not allocate context!\n", node->socketPath); } else { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s', " "port %d -> could not allocate context!\n", node->server, node->port); } ABORT_FINALIZE(RS_RET_REDIS_ERROR); } else if ((*conn)->err) { if (node->usesSocket) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s' " "-> %s\n", node->socketPath, (*conn)->errstr); } else { LogError(0, RS_RET_REDIS_ERROR, "imhiredis: can not connect to redis server '%s', " "port %d -> %s\n", node->server, node->port, (*conn)->errstr); } ABORT_FINALIZE(RS_RET_REDIS_ERROR); } finalize_it: if (iRet != RS_RET_OK) { if (*conn) redisFree(*conn); *conn = NULL; } RETiRet; } /* * connection function for asynchronous (subscribe) mode * node should not be NULL */ rsRetVal redisConnectAsync(redisAsyncContext **aconn, redisNode *node) { DEFiRet; assert(node != NULL); if (node->usesSocket) *aconn = redisAsyncConnectUnix((const char *)node->socketPath); else *aconn = redisAsyncConnect((const char *)node->server, node->port); if (*aconn == NULL) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): could not allocate context!\n"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } else if ((*aconn)->err) { if (node->usesSocket) { LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): cannot connect to server '%s' " "-> %s\n", node->socketPath, (*aconn)->errstr); } else { LogError(0, RS_RET_REDIS_ERROR, "imhiredis (async): cannot connect to server '%s', port '%d' " "-> %s\n", node->server, node->port, (*aconn)->errstr); } ABORT_FINALIZE(RS_RET_REDIS_ERROR); } finalize_it: if (iRet != RS_RET_OK) { if (*aconn) redisAsyncFree(*aconn); *aconn = NULL; } RETiRet; } /* * Helper method to connect to the current master asynchronously * 'inst' parameter should be non-NULL and have a valid currentNode object */ rsRetVal connectMasterAsync(instanceConf_t *inst) { DEFiRet; if (RS_RET_OK != redisConnectAsync(&(inst->aconn), inst->currentNode)) { inst->currentNode = NULL; ABORT_FINALIZE(RS_RET_REDIS_ERROR); } if (inst->password != NULL && inst->password[0] != '\0' && RS_RET_OK != redisAuthenticate(inst)) { redisAsyncFree(inst->aconn); inst->aconn = NULL; inst->currentNode = NULL; ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); } // finalize context creation inst->aconn->data = (void *)inst; redisAsyncSetConnectCallback(inst->aconn, redisAsyncConnectCallback); redisAsyncSetDisconnectCallback(inst->aconn, redisAsyncDisconnectCallback); redisLibeventAttach(inst->aconn, inst->evtBase); finalize_it: RETiRet; } /* * Helper method to check if (async) instance is connected */ static sbool isConnectedAsync(instanceConf_t *inst) { return inst->aconn != NULL; } /* * Helper method to connect to the current master synchronously * 'inst' parameter should be non-NULL and have a valid currentNode object */ rsRetVal connectMasterSync(instanceConf_t *inst) { DEFiRet; if (RS_RET_OK != redisConnectSync(&(inst->conn), inst->currentNode)) { inst->currentNode = NULL; ABORT_FINALIZE(RS_RET_REDIS_ERROR); } if (inst->password != NULL && inst->password[0] != '\0' && RS_RET_OK != redisAuthenticate(inst)) { redisFree(inst->conn); inst->conn = NULL; inst->currentNode = NULL; ABORT_FINALIZE(RS_RET_REDIS_AUTH_FAILED); } finalize_it: RETiRet; } /* * Helper method to check if instance is connected */ static sbool isConnectedSync(instanceConf_t *inst) { return inst->conn != NULL; } /* * dequeue all entries in the redis list, using batches of 10 commands */ rsRetVal redisDequeue(instanceConf_t *inst) { DEFiRet; redisReply *reply = NULL; uint replyType = 0, i; assert(inst != NULL); DBGPRINTF("redisDequeue: beginning to dequeue key '%s'\n", inst->key); do { // append a batch of inst->batchsize POP commands (either LPOP or RPOP depending on conf) if (inst->useLPop == 1) { DBGPRINTF("redisDequeue: Queuing #%d LPOP commands on key '%s' \n", inst->batchsize, inst->key); for (i = 0; i < inst->batchsize; ++i) { if (REDIS_OK != redisAppendCommand(inst->conn, "LPOP %s", inst->key)) break; } } else { DBGPRINTF("redisDequeue: Queuing #%d RPOP commands on key '%s' \n", inst->batchsize, inst->key); for (i = 0; i < inst->batchsize; i++) { if (REDIS_OK != redisAppendCommand(inst->conn, "RPOP %s", inst->key)) break; } } DBGPRINTF("redisDequeue: Dequeuing...\n") // parse responses from appended commands do { if (REDIS_OK != redisGetReply(inst->conn, (void **)&reply)) { // error getting reply, must stop LogError(0, RS_RET_REDIS_ERROR, "redisDequeue: Error reading reply after POP #%d " "on key '%s'", (inst->batchsize - i), inst->key); // close connection redisFree(inst->conn); inst->currentNode = NULL; inst->conn = NULL; ABORT_FINALIZE(RS_RET_REDIS_ERROR); } else { if (reply != NULL) { replyType = reply->type; switch (replyType) { case REDIS_REPLY_STRING: enqMsg(inst, reply->str, reply->len); break; case REDIS_REPLY_NIL: // replies are dequeued but are empty = end of list break; case REDIS_REPLY_ERROR: // There is a problem with the key or the Redis instance LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisDequeue: error " "while POP'ing key '%s' -> %s", inst->key, reply->str); ABORT_FINALIZE(RS_RET_REDIS_ERROR); default: LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "redisDequeue: " "unexpected reply type: %s", REDIS_REPLIES[replyType % 15]); } freeReplyObject(reply); reply = NULL; } else { /* reply == NULL */ LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisDequeue: unexpected empty reply " "for successful return"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } } // while there are replies to unpack, continue } while (--i > 0); if (replyType == REDIS_REPLY_NIL) { /* sleep 1s between 2 POP tries, when no new entries are available (list is empty) * this does NOT limit dequeing rate, but prevents the input from polling Redis too often */ for (i = 0; i < 10; i++) { // Time to stop the thread if (glbl.GetGlobalInputTermState() != 0) FINALIZE; // 100ms sleeps srSleep(0, 100000); } } // while input can run, continue with a new batch } while (glbl.GetGlobalInputTermState() == 0); DBGPRINTF("redisDequeue: finished to dequeue key '%s'\n", inst->key); finalize_it: if (reply) freeReplyObject(reply); RETiRet; } rsRetVal ensureConsumerGroupCreated(instanceConf_t *inst) { DEFiRet; redisReply *reply = NULL; DBGPRINTF("ensureConsumerGroupCreated: Creating group %s on stream %s\n", inst->streamConsumerGroup, inst->key); reply = (redisReply *)redisCommand(inst->conn, "XGROUP CREATE %s %s %s MKSTREAM", inst->key, inst->streamConsumerGroup, inst->streamReadFrom); if (reply != NULL) { switch (reply->type) { case REDIS_REPLY_STATUS: case REDIS_REPLY_STRING: if (0 == strncmp("OK", reply->str, reply->len)) DBGPRINTF( "ensureConsumerGroupCreated: Consumer group %s created successfully " "for stream %s\n", inst->streamConsumerGroup, inst->key); break; case REDIS_REPLY_ERROR: if (strcasestr(reply->str, "BUSYGROUP") != NULL) { DBGPRINTF( "ensureConsumerGroupCreated: Consumer group %s already exists for " "stream %s, ignoring\n", inst->streamConsumerGroup, inst->key); } else { LogError(0, RS_RET_ERR, "ensureConsumerGroupCreated: An unknown error " "occurred while creating a Consumer group %s on stream %s -> %s", inst->streamConsumerGroup, inst->key, reply->str); ABORT_FINALIZE(RS_RET_ERR); } break; default: LogError(0, RS_RET_ERR, "ensureConsumerGroupCreated: An unknown reply was received " "-> %s", REDIS_REPLIES[(reply->type) % 15]); ABORT_FINALIZE(RS_RET_ERR); } } else { LogError(0, RS_RET_REDIS_ERROR, "ensureConsumerGroupCreated: Could not create group %s on stream %s!", inst->streamConsumerGroup, inst->key); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } finalize_it: if (reply != NULL) freeReplyObject(reply); RETiRet; } rsRetVal ackStreamIndex(instanceConf_t *inst, uchar *stream, uchar *group, uchar *index) { DEFiRet; redisReply *reply = NULL; DBGPRINTF("ackStream: Acknowledging index '%s' in stream %s\n", index, stream); reply = (redisReply *)redisCommand(inst->conn, "XACK %s %s %s", stream, group, index); if (reply != NULL) { switch (reply->type) { case REDIS_REPLY_INTEGER: if (reply->integer == 1) { DBGPRINTF( "ackStreamIndex: index successfully acknowledged " "for stream %s\n", inst->key); } else { DBGPRINTF( "ackStreamIndex: message was not acknowledged " "-> already done?"); } break; case REDIS_REPLY_ERROR: LogError(0, RS_RET_ERR, "ackStreamIndex: An error occurred " "while trying to ACK message %s on %s[%s] -> %s", index, stream, group, reply->str); ABORT_FINALIZE(RS_RET_ERR); default: LogError(0, RS_RET_ERR, "ackStreamIndex: unexpected reply type: %s", REDIS_REPLIES[(reply->type) % 15]); ABORT_FINALIZE(RS_RET_ERR); } } else { LogError(0, RS_RET_REDIS_ERROR, "ackStreamIndex: Could not ACK message with index %s for %s[%s]!", index, stream, group); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } finalize_it: if (reply != NULL) { freeReplyObject(reply); } RETiRet; } static rsRetVal enqueueRedisStreamReply(instanceConf_t *const inst, redisReply *reply) { DEFiRet; struct json_object *json = NULL, *metadata = NULL, *redis = NULL; json = _redisParseArrayReply(reply->element[1]); CHKmalloc(metadata = json_object_new_object()); CHKmalloc(redis = json_object_new_object()); json_object_object_add(redis, "stream", json_object_new_string((char *)inst->key)); json_object_object_add(redis, "index", _redisParseStringReply(reply->element[0])); if (inst->streamConsumerGroup != NULL) { json_object_object_add(redis, "group", json_object_new_string((char *)inst->streamConsumerGroup)); } if (inst->streamConsumerName != NULL) { json_object_object_add(redis, "consumer", json_object_new_string((char *)inst->streamConsumerName)); } // ownership of redis object allocated by json_object_new_object() is taken by json // no need to free/destroy/put redis object json_object_object_add(metadata, "redis", redis); CHKiRet(enqMsgJson(inst, json, metadata)); // enqueued message successfully, json and metadata objects are now owned by enqueued message // no need to free/destroy/put json objects json = NULL; metadata = NULL; if (inst->streamConsumerGroup != NULL && inst->streamConsumerACK) { CHKiRet(ackStreamIndex(inst, (uchar *)inst->key, inst->streamConsumerGroup, (uchar *)reply->element[0]->str)); } finalize_it: // If that happens, there was an error during one of the steps and the json object is not enqueued if (json != NULL) json_object_put(json); if (metadata != NULL) json_object_put(metadata); RETiRet; } /* * handle the hiredis Stream XREAD/XREADGROUP return objects. The provided reply is * not freed - this must be done by the caller. * example of stream to parse: * 1) 1) "mystream" <- name of the stream indexes are from (list of streams requested) * 2) 1) 1) "1681749395006-0" <- list of indexes returned for stream * 2) 1) "key1" * 2) "value1" * 2) 1) "1681749409349-0" * 2) 1) "key2" * 2) "value2" * 3) "key2.2" * 4) "value2.2" * json equivalent: * [ * "mystream": [ * { * "1681749395006-0": { * "key1": "value1" * } * }, * { * "1681749409349-0": { * "key2": "value2", * "key2.2": "value2.2" * } * } * ] * ] */ static rsRetVal handleRedisXREADReply(instanceConf_t *const inst, const redisReply *reply) { DEFiRet; redisReply *streamObj = NULL, *msgList = NULL, *msgObj = NULL; if (reply == NULL || reply->type != REDIS_REPLY_ARRAY) { /* we do not process empty or non-ARRAY lines */ DBGPRINTF("handleRedisXREADReply: object is not an array, ignoring\n"); LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: object is not an array, ignoring"); ABORT_FINALIZE(RS_RET_OK_WARN); } else { // iterating on streams for (size_t i = 0; i < reply->elements; i++) { streamObj = reply->element[i]; // object should contain the name of the stream, and an array containing the messages if (streamObj->type != REDIS_REPLY_ARRAY || streamObj->elements != 2) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong object format, " "object should contain the name of the stream and an array of messages"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (streamObj->element[0]->type != REDIS_REPLY_STRING) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field format, " "first entry is not a string (supposed to be stream name)"); ABORT_FINALIZE(RS_RET_OK_WARN); } msgList = streamObj->element[1]; if (msgList->type != REDIS_REPLY_ARRAY) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field format, " "second entry is not an array (supposed to be list of messages for stream)"); ABORT_FINALIZE(RS_RET_OK_WARN); } DBGPRINTF("handleRedisXREADReply: enqueuing messages for stream '%s'\n", streamObj->element[0]->str); for (size_t j = 0; j < msgList->elements; j++) { msgObj = msgList->element[j]; // Object should contain the name of the index, and its content(s) if (msgObj->type != REDIS_REPLY_ARRAY || msgObj->elements != 2) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong object " "format, object should contain the index and its content(s)"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (msgObj->element[0]->type != REDIS_REPLY_STRING) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field " "format, first entry should be a string (index name)"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (msgObj->type != REDIS_REPLY_ARRAY) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXREADReply: wrong field " "format, second entry should be an array (index content(s))"); ABORT_FINALIZE(RS_RET_OK_WARN); } CHKiRet(enqueueRedisStreamReply(inst, msgObj)); // Update current stream index memcpy(inst->streamReadFrom, msgObj->element[0]->str, msgObj->element[0]->len); inst->streamReadFrom[msgObj->element[0]->len] = '\0'; DBGPRINTF("handleRedisXREADReply: current stream index is %s\n", inst->streamReadFrom); } } } DBGPRINTF("handleRedisXREADReply: finished enqueuing!\n"); finalize_it: RETiRet; } /* * handle the hiredis Stream XAUTOCLAIM return object. The provided reply is * not freed - this must be done by the caller. * example of stream to parse: * 1) "1681904437564-0" <- next index to use for XAUTOCLAIM * 2) 1) 1) "1681904437525-0" <- list of indexes reclaimed * 2) 1) "toto" * 2) "tata" * 2) 1) "1681904437532-0" * 2) 1) "titi" * 2) "tutu" * 3) (empty) <- indexes that no longer exist, were deleted from the PEL * json equivalent: * "1681904437564-0": [ * { * "1681904437525-0": { * "toto": "tata" * } * }, * { * "1681904437532-0": { * "titi": "tutu" * } * } * ] */ static rsRetVal handleRedisXAUTOCLAIMReply(instanceConf_t *const inst, const redisReply *reply, char **autoclaimIndex) { DEFiRet; redisReply *msgList = NULL, *msgObj = NULL; if (reply == NULL || reply->type != REDIS_REPLY_ARRAY) { /* we do not process empty or non-ARRAY lines */ DBGPRINTF("handleRedisXAUTOCLAIMReply: object is not an array, ignoring\n"); FINALIZE; } else { // Object should contain between 2 and 3 elements (depends on Redis server version) if (reply->elements < 2 || reply->elements > 3) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: wrong number of fields, " "cannot process entry"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (reply->element[0]->type != REDIS_REPLY_STRING) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: the first element " "is not a string, cannot process entry"); ABORT_FINALIZE(RS_RET_OK_WARN); } msgList = reply->element[1]; if (msgList->type != REDIS_REPLY_ARRAY) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: the second element " "is not an array, cannot process entry"); ABORT_FINALIZE(RS_RET_OK_WARN); } DBGPRINTF("handleRedisXAUTOCLAIMReply: re-claiming messages for stream '%s'\n", inst->key); for (size_t j = 0; j < msgList->elements; j++) { msgObj = msgList->element[j]; // Object should contain the name of the index, and its content(s) if (msgObj->type != REDIS_REPLY_ARRAY || msgObj->elements != 2) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: wrong message " "format, cannot process"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (msgObj->element[0]->type != REDIS_REPLY_STRING) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: first message " "element not a string, cannot process"); ABORT_FINALIZE(RS_RET_OK_WARN); } if (msgObj->type != REDIS_REPLY_ARRAY) { LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "handleRedisXAUTOCLAIMReply: second message " "element not an array, cannot process"); ABORT_FINALIZE(RS_RET_OK_WARN); } CHKiRet(enqueueRedisStreamReply(inst, msgObj)); } // Update current stream index with next index from XAUTOCLAIM // No message has to be claimed after that if value is "0-0" memcpy(*autoclaimIndex, reply->element[0]->str, reply->element[0]->len); (*autoclaimIndex)[reply->element[0]->len] = '\0'; DBGPRINTF("handleRedisXAUTOCLAIMReply: next stream index is %s\n", (*autoclaimIndex)); } DBGPRINTF("handleRedisXAUTOCLAIMReply: finished re-claiming!\n"); finalize_it: RETiRet; } /* * Read Redis stream */ rsRetVal redisStreamRead(instanceConf_t *inst) { DEFiRet; redisReply *reply = NULL; uint replyType = 0; sbool mustClaimIdle = 0; char *autoclaimIndex = NULL; assert(inst != NULL); // Ensure stream group is created before reading from it if (inst->streamConsumerGroup != NULL) { CHKiRet(ensureConsumerGroupCreated(inst)); } if (inst->streamAutoclaimIdleTime != 0) { DBGPRINTF("redisStreamRead: getting pending entries for stream '%s' from '%s', with idle time %d\n", inst->key, inst->streamReadFrom, inst->streamAutoclaimIdleTime); CHKmalloc(autoclaimIndex = calloc(1, STREAM_INDEX_STR_MAXLEN)); // Cannot claim from '$', will have to claim from the beginning of the stream if (inst->streamReadFrom[0] == '$') { LogMsg(0, RS_RET_OK, LOG_WARNING, "Cannot claim pending entries from '$', " "will have to claim from the beginning of the stream"); memcpy(autoclaimIndex, "0-0", 4); } else { memcpy(autoclaimIndex, inst->streamReadFrom, STREAM_INDEX_STR_MAXLEN); } mustClaimIdle = 1; } else { DBGPRINTF("redisStreamRead: beginning to read stream '%s' from '%s'\n", inst->key, inst->streamReadFrom); } do { if (inst->streamConsumerGroup == NULL) { reply = (redisReply *)redisCommand(inst->conn, "XREAD COUNT %d BLOCK %d STREAMS %s %s", BATCH_SIZE, WAIT_TIME_MS, inst->key, inst->streamReadFrom); } else { if (mustClaimIdle) { reply = (redisReply *)redisCommand(inst->conn, "XAUTOCLAIM %s %s %s %d %s COUNT %d", inst->key, inst->streamConsumerGroup, inst->streamConsumerName, inst->streamAutoclaimIdleTime, autoclaimIndex, BATCH_SIZE); } else { reply = (redisReply *)redisCommand(inst->conn, "XREADGROUP GROUP %s %s COUNT %d BLOCK %d STREAMS %s >", inst->streamConsumerGroup, inst->streamConsumerName, BATCH_SIZE, WAIT_TIME_MS, inst->key); } } if (reply == NULL) { LogError(0, RS_RET_REDIS_ERROR, "redisStreamRead: Error while trying to read stream '%s'", inst->key); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } replyType = reply->type; switch (replyType) { case REDIS_REPLY_ARRAY: DBGPRINTF("reply is an array, proceeding...\n"); if (mustClaimIdle) { CHKiRet(handleRedisXAUTOCLAIMReply(inst, reply, &autoclaimIndex)); if (!strncmp(autoclaimIndex, "0-0", 4)) { DBGPRINTF( "redisStreamRead: Caught up with pending messages, " "getting back to regular reads\n"); mustClaimIdle = 0; } } else { CHKiRet(handleRedisXREADReply(inst, reply)); } break; case REDIS_REPLY_NIL: // replies are dequeued but are empty = end of list if (mustClaimIdle) mustClaimIdle = 0; break; case REDIS_REPLY_ERROR: // There is a problem with the key or the Redis instance LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisStreamRead: error " "while reading stream(s) -> %s", reply->str); srSleep(1, 0); ABORT_FINALIZE(RS_RET_REDIS_ERROR); default: LogMsg(0, RS_RET_OK_WARN, LOG_WARNING, "redisStreamRead: unexpected " "reply type: %s", REDIS_REPLIES[replyType % 15]); } freeReplyObject(reply); reply = NULL; // while input can run, continue with a new batch } while (glbl.GetGlobalInputTermState() == 0); DBGPRINTF("redisStreamRead: finished to dequeue key '%s'\n", inst->key); finalize_it: if (reply != NULL) freeReplyObject(reply); if (inst->conn != NULL) { redisFree(inst->conn); inst->conn = NULL; inst->currentNode = NULL; } if (autoclaimIndex != NULL) free(autoclaimIndex); RETiRet; } /* * Subscribe to Redis channel */ rsRetVal redisSubscribe(instanceConf_t *inst) { DEFiRet; DBGPRINTF("redisSubscribe: subscribing to channel '%s'\n", inst->key); int ret = redisAsyncCommand(inst->aconn, redisAsyncRecvCallback, NULL, "SUBSCRIBE %s", inst->key); if (ret != REDIS_OK) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "redisSubscribe: Could not subscribe"); ABORT_FINALIZE(RS_RET_REDIS_ERROR); } // Will block on this function as long as connection is open and event loop is not stopped event_base_dispatch(inst->evtBase); DBGPRINTF("redisSubscribe: finished.\n"); finalize_it: RETiRet; } /* * generic worker function */ void workerLoop(struct imhiredisWrkrInfo_s *me) { uint i; DBGPRINTF("workerLoop: beginning of worker loop...\n"); // Connect first time without delay if (me->inst->currentNode != NULL) { rsRetVal ret = me->fnConnectMaster(me->inst); if (ret != RS_RET_OK) { LogMsg(0, ret, LOG_WARNING, "workerLoop: Could not connect successfully to master"); } } while (glbl.GetGlobalInputTermState() == 0) { if (!me->fnIsConnected(me->inst)) { /* * Sleep 10 seconds before attempting to resume a broken connexion * (sleep small amounts to avoid missing termination status) */ LogMsg(0, RS_RET_OK, LOG_INFO, "workerLoop: " "no valid connection, sleeping 10 seconds before retrying..."); for (i = 0; i < 100; i++) { // Rsyslog asked for shutdown, thread should be stopped if (glbl.GetGlobalInputTermState() != 0) goto end_loop; // 100ms sleeps srSleep(0, 100000); } // search the current master node if (me->inst->currentNode == NULL) { if (RS_RET_OK != redisActualizeCurrentNode(me->inst)) continue; } // connect to current master if (me->inst->currentNode != NULL) { rsRetVal ret = me->fnConnectMaster(me->inst); if (ret != RS_RET_OK) { LogMsg(0, ret, LOG_WARNING, "workerLoop: " "Could not connect successfully to master"); } } } if (me->fnIsConnected(me->inst)) { me->fnRun(me->inst); } } end_loop: return; } /* * Workerthread function for a single hiredis consumer */ static void *imhirediswrkr(void *myself) { struct imhiredisWrkrInfo_s *me = (struct imhiredisWrkrInfo_s *)myself; DBGPRINTF("imhiredis: started hiredis consumer workerthread\n"); dbgPrintNode(me->inst->currentNode); if (me->inst->mode == IMHIREDIS_MODE_QUEUE) { me->fnConnectMaster = connectMasterSync; me->fnIsConnected = isConnectedSync; me->fnRun = redisDequeue; } else if (me->inst->mode == IMHIREDIS_MODE_STREAM) { me->fnConnectMaster = connectMasterSync; me->fnIsConnected = isConnectedSync; me->fnRun = redisStreamRead; } else if (me->inst->mode == IMHIREDIS_MODE_SUBSCRIBE) { me->fnConnectMaster = connectMasterAsync; me->fnIsConnected = isConnectedAsync; me->fnRun = redisSubscribe; } workerLoop(me); DBGPRINTF("imhiredis: stopped hiredis consumer workerthread\n"); return NULL; } // -------------------------- redisNode functions ----------------------------------- /* * create a redisNode and set default values * if a valid node is given as parameter, the new node is inserted as the new head of the linked list */ static rsRetVal createRedisNode(redisNode **root) { redisNode *node; DEFiRet; CHKmalloc(node = malloc(sizeof(redisNode))); node->port = 0; node->server = NULL; node->socketPath = NULL; node->usesSocket = 0; node->isMaster = 0; node->next = NULL; if ((*root) == NULL) { *root = node; } else { node->next = (*root); *root = node; } finalize_it: RETiRet; } /* * make a complete copy of the src node into the newly-created node in dst * if dst already contains a node, the new node will be added as the new head of the provided list * src should not be NULL */ rsRetVal copyNode(redisNode *src, redisNode **dst) { DEFiRet; assert(src != NULL); CHKiRet(createRedisNode(dst)); (*dst)->isMaster = src->isMaster; (*dst)->next = src->next; (*dst)->port = src->port; (*dst)->usesSocket = src->usesSocket; if (src->server) (*dst)->server = (uchar *)strdup((const char *)src->server); if (src->socketPath) (*dst)->socketPath = (uchar *)strdup((const char *)src->socketPath); finalize_it: RETiRet; } /* * free all ressources of the node * will return next node if one is present, NULL otherwise */ redisNode *freeNode(redisNode *node) { redisNode *ret = NULL; if (node != NULL) { if (node->next != NULL) ret = node->next; if (node->server != NULL) free(node->server); if (node->socketPath != NULL) free(node->socketPath); free(node); } return ret; } /* * insert node 'elem' after node 'root' in the linked list * both root and elem should not be NULL */ void insertNodeAfter(redisNode *root, redisNode *elem) { assert(root != NULL); assert(elem != NULL); if (root->next != NULL) { elem->next = root->next; } root->next = elem; return; } void dbgPrintNode(redisNode *node) { if (node != NULL) { if (node->usesSocket) { if (node->isMaster) { DBGPRINTF("imhiredis: node is %s (master)\n", node->socketPath); } else { DBGPRINTF("imhiredis: node is %s (replica)\n", node->socketPath); } } else { if (node->isMaster) { DBGPRINTF("imhiredis: node is %s:%d (master)\n", node->server, node->port); } else { DBGPRINTF("imhiredis: node is %s:%d (replica)\n", node->server, node->port); } } } return; } rsyslog-8.2512.0/contrib/imhiredis/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315020216 xustar0030 mtime=1764935885.763003519 30 atime=1764935897.093177067 30 ctime=1764935931.768708006 rsyslog-8.2512.0/contrib/imhiredis/Makefile.in0000664000175000017500000006347115114544315017675 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imhiredis ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = imhiredis_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_imhiredis_la_OBJECTS = imhiredis_la-imhiredis.lo imhiredis_la_OBJECTS = $(am_imhiredis_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imhiredis_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(imhiredis_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imhiredis_la-imhiredis.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imhiredis_la_SOURCES) DIST_SOURCES = $(imhiredis_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imhiredis.la imhiredis_la_SOURCES = imhiredis.c imhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) imhiredis_la_LDFLAGS = -module -avoid-version imhiredis_la_LIBADD = $(HIREDIS_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imhiredis/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imhiredis/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imhiredis.la: $(imhiredis_la_OBJECTS) $(imhiredis_la_DEPENDENCIES) $(EXTRA_imhiredis_la_DEPENDENCIES) $(AM_V_CCLD)$(imhiredis_la_LINK) -rpath $(pkglibdir) $(imhiredis_la_OBJECTS) $(imhiredis_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imhiredis_la-imhiredis.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imhiredis_la-imhiredis.lo: imhiredis.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imhiredis_la-imhiredis.lo -MD -MP -MF $(DEPDIR)/imhiredis_la-imhiredis.Tpo -c -o imhiredis_la-imhiredis.lo `test -f 'imhiredis.c' || echo '$(srcdir)/'`imhiredis.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imhiredis_la-imhiredis.Tpo $(DEPDIR)/imhiredis_la-imhiredis.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imhiredis.c' object='imhiredis_la-imhiredis.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imhiredis_la-imhiredis.lo `test -f 'imhiredis.c' || echo '$(srcdir)/'`imhiredis.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imhiredis_la-imhiredis.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imhiredis_la-imhiredis.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omhttp0000644000000000000000000000013115114544367015440 xustar0030 mtime=1764935927.432641629 29 atime=1764935930.17368359 30 ctime=1764935927.432641629 rsyslog-8.2512.0/contrib/omhttp/0000775000175000017500000000000015114544367015162 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omhttp/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264017541 xustar0030 mtime=1752569012.330244093 29 atime=1764930929.09282033 30 ctime=1764935927.428641568 rsyslog-8.2512.0/contrib/omhttp/Makefile.am0000664000175000017500000000034615035412264017211 0ustar00rgerrgerpkglib_LTLIBRARIES = omhttp.la omhttp_la_SOURCES = omhttp.c omhttp_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) omhttp_la_LDFLAGS = -module -avoid-version omhttp_la_LIBADD = $(CURL_LIBS) $(LIBM) EXTRA_DIST = rsyslog-8.2512.0/contrib/omhttp/PaxHeaders/omhttp.c0000644000000000000000000000013215114522477017173 xustar0030 mtime=1764926783.006631146 30 atime=1764926784.225661069 30 ctime=1764935927.432641629 rsyslog-8.2512.0/contrib/omhttp/omhttp.c0000664000175000017500000032137615114522477016653 0ustar00rgerrger/* omhttp.c * This is an http output module based on omelasticsearch * * NOTE: read comments in module-template.h for more specifics! * * Supports profile-based configuration for common HTTP endpoints: * - profile="loki" for Grafana Loki * - profile="hec:splunk:event" for Splunk HTTP Event Collector (Endpoint EVENT) * - profile="hec:splunk:raw" for Splunk HTTP Event Collector (Endpoint RAW) * (proof-of-concept only, see * https://github.com/rsyslog/rsyslog/issues/5756 for feedback) * The profile configuration is based on this method : * profile="techno:vendor:endpoint" * * Copyright 2011 Nathan Scott. * Copyright 2009-2018 Rainer Gerhards and Adiscon GmbH. * Copyright 2018 Christian Tramnitz * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "unicode-helper.h" #include "obj-types.h" #include "ratelimit.h" #include "ruleset.h" #include "statsobj.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omhttp") /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) DEFobjCurrIf(statsobj) typedef struct _targetStats { statsobj_t *defaultstats; STATSCOUNTER_DEF(ctrMessagesSubmitted, mutCtrMessagesSubmitted); // Number of message submitted to module STATSCOUNTER_DEF(ctrMessagesSuccess, mutCtrMessagesSuccess); // Number of messages successfully sent STATSCOUNTER_DEF(ctrMessagesFail, mutCtrMessagesFail); // Number of messages that failed to send STATSCOUNTER_DEF(ctrMessagesRetry, mutCtrMessagesRetry); // Number of messages requeued for retry STATSCOUNTER_DEF(ctrHttpRequestSuccess, mutCtrHttpRequestSuccess); // Number of successful HTTP requests STATSCOUNTER_DEF(ctrHttpRequestFail, mutCtrHttpRequestFail); // Number of failed HTTP req, 4XX+ are NOT failures STATSCOUNTER_DEF(ctrHttpStatusSuccess, mutCtrHttpStatusSuccess); // Number of requests returning 1XX/2XX status STATSCOUNTER_DEF(ctrHttpStatusFail, mutCtrHttpStatusFail); // Number of requests returning 300+ status STATSCOUNTER_DEF(ctrHttpRequestsCount, mutCtrHttpRequestsCount); // Number of attempted HTTP requests STATSCOUNTER_DEF(httpRequestsBytes, mutHttpRequestsBytes); // Number of bytes in HTTP requests STATSCOUNTER_DEF(httpRequestsTimeMs, mutHttpRequestsTimeMs); // Number of Times(ms) in HTTP requests STATSCOUNTER_DEF(ctrHttpRequestsStatus0xx, mutCtrHttpRequestsStatus0xx); // HTTP requests returning 0xx STATSCOUNTER_DEF(ctrHttpRequestsStatus1xx, mutCtrHttpRequestsStatus1xx); // HTTP requests returning 1xx STATSCOUNTER_DEF(ctrHttpRequestsStatus2xx, mutCtrHttpRequestsStatus2xx); // HTTP requests returning 2xx STATSCOUNTER_DEF(ctrHttpRequestsStatus3xx, mutCtrHttpRequestsStatus3xx); // HTTP requests returning 3xx STATSCOUNTER_DEF(ctrHttpRequestsStatus4xx, mutCtrHttpRequestsStatus4xx); // HTTP requests returning 4xx STATSCOUNTER_DEF(ctrHttpRequestsStatus5xx, mutCtrHttpRequestsStatus5xx); // HTTP requests returning 5xx } targetStats_t; static prop_t *pInputName = NULL; static int omhttpInstancesCnt = 0; #define NAME_TPL_SPLK_EVENT " StdSplkEvent" #define NAME_TPL_SPLK_RAW " StdSplkRAW" static uchar template_StdSplkEvent[] = "\"{\\\"event\\\":\\\"%rawmsg:::json%\\\"}\""; static uchar template_StdSplkRaw[] = "\"%rawmsg:::drop-last-lf%\n\""; #define WRKR_DATA_TYPE_ES 0xBADF0001 #define HTTP_HEADER_CONTENT_JSON "Content-Type: application/json; charset=utf-8" #define HTTP_HEADER_CONTENT_TEXT "Content-Type: text/plain" #define HTTP_HEADER_CONTENT_KAFKA "Content-Type: application/vnd.kafka.v1+json" #define HTTP_HEADER_ENCODING_GZIP "Content-Encoding: gzip" #define HTTP_HEADER_EXPECT_EMPTY "Expect:" #define VALID_BATCH_FORMATS "newline jsonarray kafkarest lokirest" /* Splunk define value */ #define SPLUNK_HEC_RESTPATH_ENDPOINT_EVENT "services/collector/event" #define SPLUNK_HEC_RESTPATH_ENDPOINT_RAW "services/collector/raw" #define SPLUNK_HEC_RESTPATH_ENDPOINT_HEALTH "services/collector/health" #define SPLUNK_HEC_HEADER_AUTH "Splunk " /* Default batch size constants */ #define DEFAULT_MAX_BATCH_BYTES (10 * 1024 * 1024) /* 10 MB - default max message size for AWS API Gateway */ #define SPLUNK_HEC_MAX_BATCH_BYTES (1024 * 1024) /* 1 MB - Splunk HEC recommended limit */ typedef enum batchFormat_e { FMT_NEWLINE, FMT_JSONARRAY, FMT_KAFKAREST, FMT_LOKIREST } batchFormat_t; typedef enum vendor_e { LOKI, SPLUNK } vendor_t; /* REST API uses this URL: * https://:/restPath */ typedef struct curl_slist HEADER; typedef struct instanceConf_s { int defaultPort; int fdErrFile; /* error file fd or -1 if not open */ pthread_mutex_t mutErrFile; uchar **serverBaseUrls; int numServers; long healthCheckTimeout; long restPathTimeout; uchar *token; uchar *uid; uchar *pwd; uchar *authBuf; uchar *httpcontenttype; uchar *headerContentTypeBuf; uchar *httpheaderkey; uchar *httpheadervalue; uchar *headerBuf; uchar **httpHeaders; int nHttpHeaders; uchar *restPath; uchar *checkPath; uchar *proxyHost; int proxyPort; uchar *tplName; uchar *errorFile; sbool batchMode; uchar *batchFormatName; batchFormat_t batchFormat; vendor_t vendor; sbool bFreeBatchFormatName; sbool dynRestPath; size_t maxBatchBytes; size_t maxBatchSize; sbool compress; int compressionLevel; /* Compression level for zlib, default=-1, fastest=1, best=9, none=0*/ sbool useHttps; sbool allowUnsignedCerts; sbool skipVerifyHost; uchar *caCertFile; uchar *myCertFile; uchar *myPrivKeyFile; sbool reloadOnHup; sbool retryFailures; sbool retryAddMetadata; int nhttpRetryCodes; unsigned int *httpRetryCodes; int nIgnorableCodes; unsigned int *ignorableCodes; unsigned int ratelimitInterval; unsigned int ratelimitBurst; /* for retries */ ratelimit_t *ratelimiter; uchar *retryRulesetName; ruleset_t *retryRuleset; struct instanceConf_s *next; uchar *statsName; /* Stats Counter */ targetStats_t *listObjStats; sbool statsBySenders; } instanceData; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ instanceConf_t *root, *tail; }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ typedef struct wrkrInstanceData { PTR_ASSERT_DEF instanceData *pData; int serverIndex; int replyLen; char *reply; long httpStatusCode; /* http status code of response */ CURL *curlCheckConnHandle; /* libcurl session handle for checking the server connection */ CURL *curlPostHandle; /* libcurl session handle for posting data to the server */ HEADER *curlHeader; /* json POST request info */ uchar *restURL; /* last used URL for error reporting */ sbool bzInitDone; z_stream zstrm; /* zip stream to use for gzip http compression */ struct { uchar **data; /* array of strings, this will be batched up lazily */ uchar *restPath; /* Helper for restpath in batch mode */ size_t sizeBytes; /* total length of this batch in bytes */ size_t nmemb; /* number of messages in batch (for statistics counting) */ } batch; struct { uchar *buf; size_t curLen; size_t len; } compressCtx; } wrkrInstanceData_t; /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"server", eCmdHdlrArray, 0}, {"serverport", eCmdHdlrInt, 0}, {"healthchecktimeout", eCmdHdlrInt, 0}, {"restpathtimeout", eCmdHdlrInt, 0}, {"httpcontenttype", eCmdHdlrGetWord, 0}, {"httpheaderkey", eCmdHdlrGetWord, 0}, {"httpheadervalue", eCmdHdlrString, 0}, {"httpheaders", eCmdHdlrArray, 0}, {"token", eCmdHdlrGetWord, 0}, {"uid", eCmdHdlrGetWord, 0}, {"pwd", eCmdHdlrGetWord, 0}, {"restpath", eCmdHdlrGetWord, 0}, {"checkpath", eCmdHdlrGetWord, 0}, {"dynrestpath", eCmdHdlrBinary, 0}, {"proxyhost", eCmdHdlrString, 0}, {"proxyport", eCmdHdlrInt, 0}, {"batch", eCmdHdlrBinary, 0}, {"batch.format", eCmdHdlrGetWord, 0}, {"batch.maxbytes", eCmdHdlrSize, 0}, {"batch.maxsize", eCmdHdlrSize, 0}, {"compress", eCmdHdlrBinary, 0}, {"compress.level", eCmdHdlrInt, 0}, {"usehttps", eCmdHdlrBinary, 0}, {"errorfile", eCmdHdlrGetWord, 0}, {"template", eCmdHdlrGetWord, 0}, {"allowunsignedcerts", eCmdHdlrBinary, 0}, {"skipverifyhost", eCmdHdlrBinary, 0}, {"tls.cacert", eCmdHdlrString, 0}, {"tls.mycert", eCmdHdlrString, 0}, {"tls.myprivkey", eCmdHdlrString, 0}, {"reloadonhup", eCmdHdlrBinary, 0}, {"httpretrycodes", eCmdHdlrArray, 0}, {"retry", eCmdHdlrBinary, 0}, {"retry.addmetadata", eCmdHdlrBinary, 0}, {"retry.ruleset", eCmdHdlrString, 0}, {"ratelimit.interval", eCmdHdlrInt, 0}, {"ratelimit.burst", eCmdHdlrInt, 0}, {"name", eCmdHdlrGetWord, 0}, {"httpignorablecodes", eCmdHdlrArray, 0}, {"profile", eCmdHdlrGetWord, 0}, {"statsbysenders", eCmdHdlrBinary, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; static rsRetVal curlSetup(wrkrInstanceData_t *pWrkrData); static void curlCleanup(wrkrInstanceData_t *pWrkrData); static void curlCheckConnSetup(wrkrInstanceData_t *const pWrkrData); /* compressCtx functions */ static void ATTR_NONNULL() initCompressCtx(wrkrInstanceData_t *pWrkrData); static void ATTR_NONNULL() freeCompressCtx(wrkrInstanceData_t *pWrkrData); static rsRetVal ATTR_NONNULL() resetCompressCtx(wrkrInstanceData_t *pWrkrData, size_t len); static rsRetVal ATTR_NONNULL() growCompressCtx(wrkrInstanceData_t *pWrkrData, size_t newLen); static rsRetVal ATTR_NONNULL() appendCompressCtx(wrkrInstanceData_t *pWrkrData, uchar *srcBuf, size_t srcLen); BEGINcreateInstance CODESTARTcreateInstance; pData->fdErrFile = -1; pthread_mutex_init(&pData->mutErrFile, NULL); pData->caCertFile = NULL; pData->myCertFile = NULL; pData->myPrivKeyFile = NULL; pData->ratelimiter = NULL; pData->retryRulesetName = NULL; pData->retryRuleset = NULL; ENDcreateInstance BEGINcreateWrkrInstance uchar **batchData; CODESTARTcreateWrkrInstance; PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); pWrkrData->curlHeader = NULL; pWrkrData->curlPostHandle = NULL; pWrkrData->curlCheckConnHandle = NULL; pWrkrData->serverIndex = 0; pWrkrData->httpStatusCode = 0; pWrkrData->restURL = NULL; pWrkrData->bzInitDone = 0; if (pData->batchMode) { pWrkrData->batch.nmemb = 0; pWrkrData->batch.sizeBytes = 0; batchData = (uchar **)malloc(pData->maxBatchSize * sizeof(uchar *)); if (batchData == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: cannot allocate memory for batch queue turning off batch mode\n"); pData->batchMode = 0; /* at least it works */ } else { pWrkrData->batch.data = batchData; pWrkrData->batch.restPath = NULL; } } initCompressCtx(pWrkrData); iRet = curlSetup(pWrkrData); ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINfreeInstance int i; CODESTARTfreeInstance; if (pData->fdErrFile != -1) close(pData->fdErrFile); pthread_mutex_destroy(&pData->mutErrFile); for (i = 0; i < pData->numServers; ++i) free(pData->serverBaseUrls[i]); free(pData->serverBaseUrls); free(pData->token); free(pData->uid); free(pData->httpcontenttype); free(pData->headerContentTypeBuf); free(pData->httpheaderkey); free(pData->httpheadervalue); for (i = 0; i < pData->nHttpHeaders; ++i) { free((void *)pData->httpHeaders[i]); } free(pData->httpHeaders); pData->nHttpHeaders = 0; free(pData->pwd); free(pData->authBuf); free(pData->headerBuf); free(pData->restPath); free(pData->checkPath); free(pData->proxyHost); free(pData->tplName); free(pData->errorFile); free(pData->caCertFile); free(pData->myCertFile); free(pData->myPrivKeyFile); free(pData->httpRetryCodes); free(pData->retryRulesetName); free(pData->ignorableCodes); if (pData->ratelimiter != NULL) ratelimitDestruct(pData->ratelimiter); if (pData->bFreeBatchFormatName) free(pData->batchFormatName); if (pData->listObjStats != NULL) { const int numStats = pData->statsBySenders ? pData->numServers : 1; for (int j = 0; j < numStats; ++j) { if (pData->listObjStats[j].defaultstats != NULL) statsobj.Destruct(&(pData->listObjStats[j].defaultstats)); } free(pData->listObjStats); } free(pData->statsName); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; curlCleanup(pWrkrData); free(pWrkrData->restURL); pWrkrData->restURL = NULL; free(pWrkrData->batch.data); pWrkrData->batch.data = NULL; if (pWrkrData->batch.restPath != NULL) { free(pWrkrData->batch.restPath); pWrkrData->batch.restPath = NULL; } if (pWrkrData->bzInitDone) deflateEnd(&pWrkrData->zstrm); freeCompressCtx(pWrkrData); ENDfreeWrkrInstance BEGINdbgPrintInstInfo int i; CODESTARTdbgPrintInstInfo; dbgprintf("omhttp\n"); dbgprintf("\ttemplate='%s'\n", pData->tplName); dbgprintf("\tnumServers=%d\n", pData->numServers); dbgprintf("\thealthCheckTimeout=%lu\n", pData->healthCheckTimeout); dbgprintf("\trestPathTimeout=%lu\n", pData->restPathTimeout); dbgprintf("\tserverBaseUrls="); for (i = 0; i < pData->numServers; ++i) dbgprintf("%c'%s'", i == 0 ? '[' : ' ', pData->serverBaseUrls[i]); dbgprintf("]\n"); dbgprintf("\tdefaultPort=%d\n", pData->defaultPort); dbgprintf("\ttoken='%s'\n", pData->token == NULL ? (uchar *)"(not configured)" : pData->token); dbgprintf("\tuid='%s'\n", pData->uid == NULL ? (uchar *)"(not configured)" : pData->uid); dbgprintf("\thttpcontenttype='%s'\n", pData->httpcontenttype == NULL ? (uchar *)"(not configured)" : pData->httpcontenttype); dbgprintf("\thttpheaderkey='%s'\n", pData->httpheaderkey == NULL ? (uchar *)"(not configured)" : pData->httpheaderkey); dbgprintf("\thttpheadervalue='%s'\n", pData->httpheadervalue == NULL ? (uchar *)"(not configured)" : pData->httpheadervalue); dbgprintf("\thttpHeaders=["); for (i = 0; i < pData->nHttpHeaders; ++i) dbgprintf("\t%s\n", pData->httpHeaders[i]); dbgprintf("\t]\n"); dbgprintf("\tpwd=(%sconfigured)\n", pData->pwd == NULL ? "not " : ""); dbgprintf("\trest path='%s'\n", pData->restPath); dbgprintf("\tcheck path='%s'\n", pData->checkPath); dbgprintf("\tdynamic rest path=%d\n", pData->dynRestPath); dbgprintf("\tproxy host='%s'\n", (pData->proxyHost == NULL) ? "unset" : (char *)pData->proxyHost); dbgprintf("\tproxy port='%d'\n", pData->proxyPort); dbgprintf("\tuse https=%d\n", pData->useHttps); dbgprintf("\tbatch=%d\n", pData->batchMode); dbgprintf("\tbatch.format='%s'\n", pData->batchFormatName); dbgprintf("\tbatch.maxbytes=%zu\n", pData->maxBatchBytes); dbgprintf("\tbatch.maxsize=%zu\n", pData->maxBatchSize); dbgprintf("\tcompress=%d\n", pData->compress); dbgprintf("\tcompress.level=%d\n", pData->compressionLevel); dbgprintf("\tallowUnsignedCerts=%d\n", pData->allowUnsignedCerts); dbgprintf("\tskipVerifyHost=%d\n", pData->skipVerifyHost); dbgprintf("\terrorfile='%s'\n", pData->errorFile == NULL ? (uchar *)"(not configured)" : pData->errorFile); dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile); dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile); dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile); dbgprintf("\treloadonhup='%d'\n", pData->reloadOnHup); for (i = 0; i < pData->nhttpRetryCodes; ++i) dbgprintf("%c'%d'", i == 0 ? '[' : ' ', pData->httpRetryCodes[i]); dbgprintf("]\n"); dbgprintf("\tretry='%d'\n", pData->retryFailures); dbgprintf("\tretry.addmetadata='%d'\n", pData->retryAddMetadata); dbgprintf("\tretry.ruleset='%s'\n", pData->retryRulesetName); dbgprintf("\tratelimit.interval='%u'\n", pData->ratelimitInterval); dbgprintf("\tratelimit.burst='%u'\n", pData->ratelimitBurst); for (i = 0; i < pData->nIgnorableCodes; ++i) dbgprintf("%c'%d'", i == 0 ? '[' : ' ', pData->ignorableCodes[i]); dbgprintf("]\n"); dbgprintf("\tratelimit.interval='%d'\n", pData->ratelimitInterval); dbgprintf("\tratelimit.burst='%d'\n", pData->ratelimitBurst); dbgprintf("\tstatsname='%s'\n", pData->statsName); dbgprintf("\tstatsbysenders='%d'\n", pData->statsBySenders); ENDdbgPrintInstInfo /* http POST result string ... useful for debugging */ static size_t curlResult(void *ptr, size_t size, size_t nmemb, void *userdata) { char *p = (char *)ptr; wrkrInstanceData_t *pWrkrData = (wrkrInstanceData_t *)userdata; char *buf; size_t newlen; PTR_ASSERT_CHK(pWrkrData, WRKR_DATA_TYPE_ES); newlen = pWrkrData->replyLen + size * nmemb; if ((buf = realloc(pWrkrData->reply, newlen + 1)) == NULL) { LogError(errno, RS_RET_ERR, "omhttp: realloc failed in curlResult"); return 0; /* abort due to failure */ } memcpy(buf + pWrkrData->replyLen, p, size * nmemb); pWrkrData->replyLen = newlen; pWrkrData->reply = buf; return size * nmemb; } /* Build basic URL part, which includes hostname and port as follows: * http://hostname:port/ based on a server param * Newly creates a cstr for this purpose. * Note: serverParam MUST NOT end in '/' (caller must strip if it exists) */ static rsRetVal computeBaseUrl(const char *const serverParam, const int defaultPort, const sbool useHttps, uchar **baseUrl) { #define SCHEME_HTTPS "https://" #define SCHEME_HTTP "http://" char portBuf[64]; int r = 0; const char *host = serverParam; DEFiRet; assert(serverParam[strlen(serverParam) - 1] != '/'); es_str_t *urlBuf = es_newStr(256); if (urlBuf == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: failed to allocate es_str urlBuf in computeBaseUrl"); ABORT_FINALIZE(RS_RET_ERR); } /* Find where the hostname/ip of the server starts. If the scheme is not specified * in the uri, start the buffer with a scheme corresponding to the useHttps parameter. */ if (strcasestr(serverParam, SCHEME_HTTP)) host = serverParam + strlen(SCHEME_HTTP); else if (strcasestr(serverParam, SCHEME_HTTPS)) host = serverParam + strlen(SCHEME_HTTPS); else r = useHttps ? es_addBuf(&urlBuf, SCHEME_HTTPS, sizeof(SCHEME_HTTPS) - 1) : es_addBuf(&urlBuf, SCHEME_HTTP, sizeof(SCHEME_HTTP) - 1); if (r == 0) r = es_addBuf(&urlBuf, (char *)serverParam, strlen(serverParam)); if (r == 0 && !strchr(host, ':')) { snprintf(portBuf, sizeof(portBuf), ":%d", defaultPort); r = es_addBuf(&urlBuf, portBuf, strlen(portBuf)); } if (r == 0) r = es_addChar(&urlBuf, '/'); if (r == 0) *baseUrl = (uchar *)es_str2cstr(urlBuf, NULL); if (r != 0 || baseUrl == NULL) { LogError(0, RS_RET_ERR, "omhttp: error occurred computing baseUrl from server %s", serverParam); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (urlBuf) { es_deleteStr(urlBuf); } RETiRet; } static inline void incrementServerIndex(wrkrInstanceData_t *pWrkrData) { pWrkrData->serverIndex = (pWrkrData->serverIndex + 1) % pWrkrData->pData->numServers; } /* checks if connection to ES can be established; also iterates over * potential servers to support high availability (HA) feature. If it * needs to switch server, will record new one in curl handle. */ static rsRetVal ATTR_NONNULL() checkConn(wrkrInstanceData_t *const pWrkrData) { CURL *curl; CURLcode res; es_str_t *urlBuf = NULL; char *healthUrl; char *serverUrl; char *checkPath; int i; int r; DEFiRet; if (pWrkrData->pData->checkPath == NULL) { DBGPRINTF("omhttp: checkConn no health check uri configured skipping it\n"); FINALIZE; } pWrkrData->reply = NULL; pWrkrData->replyLen = 0; curl = pWrkrData->curlCheckConnHandle; urlBuf = es_newStr(256); if (urlBuf == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: unable to allocate buffer for health check uri."); ABORT_FINALIZE(RS_RET_SUSPENDED); } for (i = 0; i < pWrkrData->pData->numServers; ++i) { serverUrl = (char *)pWrkrData->pData->serverBaseUrls[pWrkrData->serverIndex]; checkPath = (char *)pWrkrData->pData->checkPath; es_emptyStr(urlBuf); r = es_addBuf(&urlBuf, serverUrl, strlen(serverUrl)); if (r == 0 && checkPath != NULL) r = es_addBuf(&urlBuf, checkPath, strlen(checkPath)); if (r == 0) healthUrl = es_str2cstr(urlBuf, NULL); if (r != 0 || healthUrl == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: unable to allocate buffer for health check uri."); ABORT_FINALIZE(RS_RET_SUSPENDED); } curlCheckConnSetup(pWrkrData); curl_easy_setopt(curl, CURLOPT_URL, healthUrl); res = curl_easy_perform(curl); free(healthUrl); if (res == CURLE_OK) { DBGPRINTF( "omhttp: checkConn %s completed with success " "on attempt %d\n", serverUrl, i); ABORT_FINALIZE(RS_RET_OK); } DBGPRINTF("omhttp: checkConn %s failed on attempt %d: %s\n", serverUrl, i, curl_easy_strerror(res)); incrementServerIndex(pWrkrData); } LogMsg(0, RS_RET_SUSPENDED, LOG_WARNING, "omhttp: checkConn failed after %d attempts.", i); ABORT_FINALIZE(RS_RET_SUSPENDED); finalize_it: if (urlBuf != NULL) es_deleteStr(urlBuf); free(pWrkrData->reply); pWrkrData->reply = NULL; /* don't leave dangling pointer */ RETiRet; } BEGINtryResume CODESTARTtryResume; DBGPRINTF("omhttp: tryResume called\n"); iRet = checkConn(pWrkrData); ENDtryResume /* get the current rest path for this message */ static void ATTR_NONNULL(1) getRestPath(const instanceData *const pData, uchar **const tpls, uchar **const restPath) { *restPath = pData->restPath; if (pData->dynRestPath && tpls != NULL) { *restPath = tpls[1]; } assert(restPath != NULL); return; } static rsRetVal ATTR_NONNULL(1) setPostURL(wrkrInstanceData_t *const pWrkrData, uchar **const tpls) { uchar *restPath; char *baseUrl; es_str_t *url; int r; DEFiRet; instanceData *const pData = pWrkrData->pData; baseUrl = (char *)pData->serverBaseUrls[pWrkrData->serverIndex]; url = es_newStrFromCStr(baseUrl, strlen(baseUrl)); if (url == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: error allocating new estr for POST url."); ABORT_FINALIZE(RS_RET_ERR); } if (pWrkrData->batch.restPath != NULL) { /* get from batch if set! */ restPath = pWrkrData->batch.restPath; } else { getRestPath(pData, tpls, &restPath); } r = 0; if (restPath != NULL) r = es_addBuf(&url, (char *)restPath, ustrlen(restPath)); if (r != 0) { LogError(0, RS_RET_ERR, "omhttp: failure in creating restURL, " "error code: %d", r); ABORT_FINALIZE(RS_RET_ERR); } if (pWrkrData->restURL != NULL) free(pWrkrData->restURL); pWrkrData->restURL = (uchar *)es_str2cstr(url, NULL); curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_URL, pWrkrData->restURL); DBGPRINTF("omhttp: using REST URL: '%s'\n", pWrkrData->restURL); finalize_it: if (url != NULL) es_deleteStr(url); RETiRet; } /* * Dumps entire bulk request and response in error log * { * "request": { * "url": "https://url.com:443/path", * "postdata": "mypayload" } * "response" : { * "status": 400, * "response": "error string" } * } */ static rsRetVal renderJsonErrorMessage(wrkrInstanceData_t *pWrkrData, uchar *reqmsg, char **rendered) { DEFiRet; fjson_object *req = NULL; fjson_object *res = NULL; fjson_object *errRoot = NULL; if ((req = fjson_object_new_object()) == NULL) ABORT_FINALIZE(RS_RET_ERR); fjson_object_object_add(req, "url", fjson_object_new_string((char *)pWrkrData->restURL)); fjson_object_object_add(req, "postdata", fjson_object_new_string((char *)reqmsg)); if ((res = fjson_object_new_object()) == NULL) { fjson_object_put(req); // cleanup request object ABORT_FINALIZE(RS_RET_ERR); } #define ERR_MSG_NULL "NULL: curl request failed or no response" fjson_object_object_add(res, "status", fjson_object_new_int(pWrkrData->httpStatusCode)); if (pWrkrData->reply == NULL) { fjson_object_object_add(res, "message", fjson_object_new_string_len(ERR_MSG_NULL, strlen(ERR_MSG_NULL))); } else { fjson_object_object_add(res, "message", fjson_object_new_string_len(pWrkrData->reply, pWrkrData->replyLen)); } if ((errRoot = fjson_object_new_object()) == NULL) { fjson_object_put(req); // cleanup request object fjson_object_put(res); // cleanup response object ABORT_FINALIZE(RS_RET_ERR); } fjson_object_object_add(errRoot, "request", req); fjson_object_object_add(errRoot, "response", res); CHKmalloc(*rendered = strdup((char *)fjson_object_to_json_string(errRoot))); finalize_it: if (errRoot != NULL) fjson_object_put(errRoot); RETiRet; } /* write data error request/replies to separate error file * Note: we open the file but never close it before exit. If it * needs to be closed, HUP must be sent. */ static rsRetVal ATTR_NONNULL() writeDataError(wrkrInstanceData_t *const pWrkrData, instanceData *const pData, uchar *const reqmsg) { char *rendered = NULL; size_t toWrite; ssize_t wrRet; sbool bMutLocked = 0; DEFiRet; if (pData->errorFile == NULL) { DBGPRINTF( "omhttp: no local error logger defined - " "ignoring REST error information\n"); FINALIZE; } pthread_mutex_lock(&pData->mutErrFile); bMutLocked = 1; CHKiRet(renderJsonErrorMessage(pWrkrData, reqmsg, &rendered)); if (pData->fdErrFile == -1) { pData->fdErrFile = open((char *)pData->errorFile, O_WRONLY | O_CREAT | O_APPEND | O_LARGEFILE | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (pData->fdErrFile == -1) { LogError(errno, RS_RET_ERR, "omhttp: error opening error file %s", pData->errorFile); ABORT_FINALIZE(RS_RET_ERR); } } /* we do not do real error-handling on the err file, as this finally complicates * things way to much. */ DBGPRINTF("omhttp: error record: '%s'\n", rendered); toWrite = strlen(rendered) + 1; /* Note: we overwrite the '\0' terminator with '\n' -- so we avoid * caling malloc() -- write() does NOT need '\0'! */ rendered[toWrite - 1] = '\n'; /* NO LONGER A STRING! */ wrRet = write(pData->fdErrFile, rendered, toWrite); if (wrRet != (ssize_t)toWrite) { LogError(errno, RS_RET_IO_ERROR, "omhttp: error writing error file %s, write returned %lld", pData->errorFile, (long long)wrRet); } finalize_it: if (bMutLocked) pthread_mutex_unlock(&pData->mutErrFile); free(rendered); RETiRet; } static rsRetVal msgAddResponseMetadata(smsg_t *const __restrict__ pMsg, wrkrInstanceData_t *const pWrkrData, size_t batch_index) { struct json_object *json = NULL; DEFiRet; CHKmalloc(json = json_object_new_object()); /* Following metadata is exposed: $!omhttp!response!code $!omhttp!response!body $!omhttp!response!batch_index */ json_object_object_add(json, "code", json_object_new_int(pWrkrData->httpStatusCode)); if (pWrkrData->reply) { json_object_object_add(json, "body", json_object_new_string(pWrkrData->reply)); } json_object_object_add(json, "batch_index", json_object_new_int(batch_index)); CHKiRet(msgAddJSON(pMsg, (uchar *)"!omhttp!response", json, 0, 0)); /* TODO: possible future, an option to automatically parse to json? would be under: $!omhttp!response!parsed */ finalize_it: if (iRet != RS_RET_OK && json) { json_object_put(json); } RETiRet; } static rsRetVal queueBatchOnRetryRuleset(wrkrInstanceData_t *const pWrkrData, instanceData *const pData) { uchar *msgData; smsg_t *pMsg; DEFiRet; int indexStats = pData->statsBySenders ? pWrkrData->serverIndex : 0; if (pData->retryRuleset == NULL) { LogError(0, RS_RET_ERR, "omhttp: queueBatchOnRetryRuleset invalid call with a NULL retryRuleset"); ABORT_FINALIZE(RS_RET_ERR); } for (size_t i = 0; i < pWrkrData->batch.nmemb; i++) { msgData = pWrkrData->batch.data[i]; DBGPRINTF("omhttp: queueBatchOnRetryRuleset putting message '%s' into retry ruleset '%s'\n", msgData, pData->retryRulesetName); // Construct the message object CHKiRet(msgConstruct(&pMsg)); CHKiRet(MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY)); MsgSetInputName(pMsg, pInputName); MsgSetRawMsg(pMsg, (const char *)msgData, ustrlen(msgData)); MsgSetMSGoffs(pMsg, 0); // No header MsgSetTAG(pMsg, (const uchar *)"omhttp-retry", 12); // And place it on the retry ruleset MsgSetRuleset(pMsg, pData->retryRuleset); // Add response specific metadata if (pData->retryAddMetadata) { CHKiRet(msgAddResponseMetadata(pMsg, pWrkrData, i)); } ratelimitAddMsg(pData->ratelimiter, NULL, pMsg); // Count here in case not entire batch succeeds STATSCOUNTER_INC(pWrkrData->pData->listObjStats[indexStats].ctrMessagesRetry, pWrkrData->pData->listObjStats[indexStats].mutCtrMessagesRetry); } finalize_it: RETiRet; } static rsRetVal checkResult(wrkrInstanceData_t *pWrkrData, uchar *reqmsg) { instanceData *pData; long statusCode; size_t numMessages; DEFiRet; CURLcode resCurl = 0; int indexStats = 0; pData = pWrkrData->pData; statusCode = pWrkrData->httpStatusCode; indexStats = pData->statsBySenders ? pWrkrData->serverIndex : 0; targetStats_t *const serverStats = &pData->listObjStats[indexStats]; if (pData->batchMode) { numMessages = pWrkrData->batch.nmemb; } else { numMessages = 1; } /* HTTP status code handling according to new semantics: * - 0xx: Transport/connection errors -> retriable * - 1xx/2xx: Success * - 3xx: Redirection -> non-retriable (for now, redirect support can be added later) * - 4xx: Client errors -> permanent failure (non-retriable) * - 5xx: Server errors -> retriable */ if (statusCode == 0) { // Transport/connection failure - retriable STATSCOUNTER_ADD(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail, numMessages); STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus0xx, serverStats->mutCtrHttpRequestsStatus0xx); iRet = RS_RET_SUSPENDED; } else if (statusCode >= 100 && statusCode < 300) { // 1xx (informational) and 2xx (success) - treat as success STATSCOUNTER_INC(serverStats->ctrHttpStatusSuccess, serverStats->mutCtrHttpStatusSuccess); STATSCOUNTER_ADD(serverStats->ctrMessagesSuccess, serverStats->mutCtrMessagesSuccess, numMessages); if (statusCode >= 100 && statusCode < 200) { STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus1xx, serverStats->mutCtrHttpRequestsStatus1xx); } else if (statusCode >= 200 && statusCode < 300) { STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus2xx, serverStats->mutCtrHttpRequestsStatus2xx); } iRet = RS_RET_OK; } else if (statusCode >= 300 && statusCode < 400) { // 3xx - redirection, treat as permanent failure (non-retriable) STATSCOUNTER_INC(serverStats->ctrHttpStatusFail, serverStats->mutCtrHttpStatusFail); STATSCOUNTER_ADD(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail, numMessages); STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus3xx, serverStats->mutCtrHttpRequestsStatus3xx); iRet = RS_RET_DATAFAIL; // permanent failure } else if (statusCode >= 400 && statusCode < 500) { // 4xx - client error, permanent failure (non-retriable) STATSCOUNTER_INC(serverStats->ctrHttpStatusFail, serverStats->mutCtrHttpStatusFail); STATSCOUNTER_ADD(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail, numMessages); STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus4xx, serverStats->mutCtrHttpRequestsStatus4xx); iRet = RS_RET_DATAFAIL; // permanent failure } else if (statusCode >= 500) { // 5xx - server error, retriable STATSCOUNTER_INC(serverStats->ctrHttpStatusFail, serverStats->mutCtrHttpStatusFail); STATSCOUNTER_ADD(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail, numMessages); STATSCOUNTER_INC(serverStats->ctrHttpRequestsStatus5xx, serverStats->mutCtrHttpRequestsStatus5xx); iRet = RS_RET_SUSPENDED; } else { // Unexpected status code STATSCOUNTER_INC(serverStats->ctrHttpStatusFail, serverStats->mutCtrHttpStatusFail); STATSCOUNTER_ADD(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail, numMessages); iRet = RS_RET_DATAFAIL; } // get curl stats for instance { long req = 0; double total = 0; /* record total bytes */ resCurl = curl_easy_getinfo(pWrkrData->curlPostHandle, CURLINFO_REQUEST_SIZE, &req); if (!resCurl) { STATSCOUNTER_ADD(serverStats->httpRequestsBytes, serverStats->mutHttpRequestsBytes, (uint64_t)req); } resCurl = curl_easy_getinfo(pWrkrData->curlPostHandle, CURLINFO_TOTAL_TIME, &total); if (CURLE_OK == resCurl) { /* this needs to be converted to milliseconds */ long total_time_ms = (long)(total * 1000); STATSCOUNTER_ADD(serverStats->httpRequestsTimeMs, serverStats->mutHttpRequestsTimeMs, (uint64_t)total_time_ms); } } /* Check custom retry codes if configured, overriding default behavior */ if (pData->nhttpRetryCodes > 0) { sbool bMatch = 0; for (int i = 0; i < pData->nhttpRetryCodes && pData->httpRetryCodes[i] != 0; ++i) { if (statusCode == (long)pData->httpRetryCodes[i]) { bMatch = 1; break; } } if (bMatch) { /* Force retry for explicitly configured codes */ iRet = RS_RET_SUSPENDED; /* HEC:SPLUNK * If receive code 503 * The HEC server can be full * Retry data to an other HEC if more than 1 HEC is set up */ if (pData->vendor == SPLUNK && pData->numServers > 1 && statusCode == 503) { incrementServerIndex(pWrkrData); } } } // also check if we can mark this as processed if (iRet != RS_RET_OK && pData->ignorableCodes) { for (int i = 0; i < pData->nIgnorableCodes && pData->ignorableCodes[i] != 0; ++i) { if (statusCode == (long)pData->ignorableCodes[i]) { iRet = RS_RET_OK; break; } } } if (iRet != RS_RET_OK) { LogMsg(0, iRet, LOG_ERR, "omhttp: checkResult error http status code: %ld reply: %s", statusCode, pWrkrData->reply != NULL ? pWrkrData->reply : "NULL"); writeDataError(pWrkrData, pWrkrData->pData, reqmsg); if (iRet == RS_RET_DATAFAIL) { /* Permanent failure - don't retry */ ABORT_FINALIZE(iRet); } /* Handle retries */ if (pData->batchMode && pData->maxBatchSize > 1) { /* Batch mode: check if retry ruleset is configured */ if (pData->retryFailures && pData->retryRuleset != NULL) { /* Use retry ruleset for batch retry (legacy/advanced mode) */ rsRetVal retryRet = queueBatchOnRetryRuleset(pWrkrData, pData); if (retryRet != RS_RET_OK) { LogMsg(0, retryRet, LOG_ERR, "omhttp: checkResult error while queueing to retry ruleset - " "some messages may be lost"); } /* Don't suspend entire action - we handled individual messages */ iRet = RS_RET_OK; } else { /* No retry ruleset - use core retry by returning RS_RET_SUSPENDED */ /* This is the new default behavior */ DBGPRINTF("omhttp: batch failed, using core retry mechanism\n"); /* iRet already set to RS_RET_SUSPENDED */ } } else { /* Non-batch mode: use core retry (RS_RET_SUSPENDED already set) */ DBGPRINTF("omhttp: single message failed, using core retry mechanism\n"); } } finalize_it: RETiRet; } /* Compress a buffer before sending using zlib. Based on code from tools/omfwd.c * Initialize the zstrm object for gzip compression, using this init function. * deflateInit2(z_stream strm, int level, int method, * int windowBits, int memLevel, int strategy); * strm: the zlib stream held in pWrkrData * level: the compression level held in pData * method: the operation constant Z_DEFLATED * windowBits: the size of the compression window 15 = log_2(32768) * to configure as gzip add 16 to windowBits (w | 16) for final value 31 * memLevel: the memory optimization level 8 is default) * strategy: using Z_DEFAULT_STRATEGY is default */ static rsRetVal compressHttpPayload(wrkrInstanceData_t *pWrkrData, uchar *message, unsigned len) { int zRet; unsigned outavail; uchar zipBuf[32 * 1024]; DEFiRet; if (!pWrkrData->bzInitDone) { pWrkrData->zstrm.zalloc = Z_NULL; pWrkrData->zstrm.zfree = Z_NULL; pWrkrData->zstrm.opaque = Z_NULL; zRet = deflateInit2(&pWrkrData->zstrm, pWrkrData->pData->compressionLevel, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY); if (zRet != Z_OK) { DBGPRINTF("omhttp: compressHttpPayload error %d returned from zlib/deflateInit2()\n", zRet); ABORT_FINALIZE(RS_RET_ZLIB_ERR); } pWrkrData->bzInitDone = 1; } CHKiRet(resetCompressCtx(pWrkrData, len)); /* now doing the compression */ pWrkrData->zstrm.next_in = (Bytef *)message; pWrkrData->zstrm.avail_in = len; /* run deflate() on buffer until everything has been compressed */ do { DBGPRINTF("omhttp: compressHttpPayload in deflate() loop, avail_in %d, total_in %ld\n", pWrkrData->zstrm.avail_in, pWrkrData->zstrm.total_in); pWrkrData->zstrm.avail_out = sizeof(zipBuf); pWrkrData->zstrm.next_out = zipBuf; zRet = deflate(&pWrkrData->zstrm, Z_NO_FLUSH); DBGPRINTF("omhttp: compressHttpPayload after deflate, ret %d, avail_out %d\n", zRet, pWrkrData->zstrm.avail_out); if (zRet != Z_OK) ABORT_FINALIZE(RS_RET_ZLIB_ERR); outavail = sizeof(zipBuf) - pWrkrData->zstrm.avail_out; if (outavail != 0) CHKiRet(appendCompressCtx(pWrkrData, zipBuf, outavail)); } while (pWrkrData->zstrm.avail_out == 0); /* run deflate again with Z_FINISH with no new input */ pWrkrData->zstrm.avail_in = 0; do { pWrkrData->zstrm.avail_out = sizeof(zipBuf); pWrkrData->zstrm.next_out = zipBuf; deflate(&pWrkrData->zstrm, Z_FINISH); /* returns Z_STREAM_END == 1 */ outavail = sizeof(zipBuf) - pWrkrData->zstrm.avail_out; if (outavail != 0) CHKiRet(appendCompressCtx(pWrkrData, zipBuf, outavail)); } while (pWrkrData->zstrm.avail_out == 0); finalize_it: if (pWrkrData->bzInitDone) deflateEnd(&pWrkrData->zstrm); pWrkrData->bzInitDone = 0; RETiRet; } static void ATTR_NONNULL() initCompressCtx(wrkrInstanceData_t *pWrkrData) { pWrkrData->compressCtx.buf = NULL; pWrkrData->compressCtx.curLen = 0; pWrkrData->compressCtx.len = 0; } static void ATTR_NONNULL() freeCompressCtx(wrkrInstanceData_t *pWrkrData) { if (pWrkrData->compressCtx.buf != NULL) { free(pWrkrData->compressCtx.buf); pWrkrData->compressCtx.buf = NULL; } } static rsRetVal ATTR_NONNULL() resetCompressCtx(wrkrInstanceData_t *pWrkrData, size_t len) { DEFiRet; pWrkrData->compressCtx.curLen = 0; pWrkrData->compressCtx.len = len; CHKiRet(growCompressCtx(pWrkrData, len)); finalize_it: if (iRet != RS_RET_OK) freeCompressCtx(pWrkrData); RETiRet; } static rsRetVal ATTR_NONNULL() growCompressCtx(wrkrInstanceData_t *pWrkrData, size_t newLen) { DEFiRet; if (pWrkrData->compressCtx.buf == NULL) { CHKmalloc(pWrkrData->compressCtx.buf = (uchar *)malloc(sizeof(uchar) * newLen)); } else { uchar *const newbuf = (uchar *)realloc(pWrkrData->compressCtx.buf, sizeof(uchar) * newLen); CHKmalloc(newbuf); pWrkrData->compressCtx.buf = newbuf; } pWrkrData->compressCtx.len = newLen; finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL() appendCompressCtx(wrkrInstanceData_t *pWrkrData, uchar *srcBuf, size_t srcLen) { size_t newLen; DEFiRet; newLen = pWrkrData->compressCtx.curLen + srcLen; if (newLen > pWrkrData->compressCtx.len) CHKiRet(growCompressCtx(pWrkrData, newLen)); memcpy(pWrkrData->compressCtx.buf + pWrkrData->compressCtx.curLen, srcBuf, srcLen); pWrkrData->compressCtx.curLen = newLen; finalize_it: if (iRet != RS_RET_OK) freeCompressCtx(pWrkrData); RETiRet; } /* Some duplicate code to curlSetup, but we need to add the gzip content-encoding * header at runtime, and if the compression fails, we do not want to send it. * Additionally, the curlCheckConnHandle should not be configured with a gzip header. */ static rsRetVal ATTR_NONNULL() buildCurlHeaders(wrkrInstanceData_t *pWrkrData, sbool contentEncodeGzip) { struct curl_slist *slist = NULL; DEFiRet; if (pWrkrData->pData->httpcontenttype != NULL) { // If content type specified use it, otherwise use a sane default slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerContentTypeBuf); } else { if (pWrkrData->pData->batchMode) { // If in batch mode, use the approprate content type header for the format, // defaulting to text/plain with newline switch (pWrkrData->pData->batchFormat) { case FMT_JSONARRAY: slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); break; case FMT_KAFKAREST: slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_KAFKA); break; case FMT_NEWLINE: slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_TEXT); break; case FMT_LOKIREST: slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); break; default: slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_TEXT); } } else { // Otherwise non batch, presume most users are sending JSON slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); } } CHKmalloc(slist); // Configured headers.. if (pWrkrData->pData->headerBuf != NULL) { slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerBuf); CHKmalloc(slist); } for (int k = 0; k < pWrkrData->pData->nHttpHeaders; k++) { slist = curl_slist_append(slist, (char *)pWrkrData->pData->httpHeaders[k]); CHKmalloc(slist); } // When sending more than 1Kb, libcurl automatically sends an Except: 100-Continue header // and will wait 1s for a response, could make this configurable but for now disable slist = curl_slist_append(slist, HTTP_HEADER_EXPECT_EMPTY); CHKmalloc(slist); if (contentEncodeGzip) { slist = curl_slist_append(slist, HTTP_HEADER_ENCODING_GZIP); CHKmalloc(slist); } if (pWrkrData->curlHeader != NULL) curl_slist_free_all(pWrkrData->curlHeader); pWrkrData->curlHeader = slist; finalize_it: if (iRet != RS_RET_OK) { curl_slist_free_all(slist); LogError(0, iRet, "omhttp: error allocating curl header slist, using previous one"); } RETiRet; } static rsRetVal ATTR_NONNULL(1, 2) curlPost( wrkrInstanceData_t *pWrkrData, uchar *message, int msglen, uchar **tpls, const int nmsgs __attribute__((unused))) { CURLcode curlCode; CURL *const curl = pWrkrData->curlPostHandle; char errbuf[CURL_ERROR_SIZE] = ""; int indexStats = pWrkrData->pData->statsBySenders ? pWrkrData->serverIndex : 0; char *postData; int postLen; sbool compressed; DEFiRet; PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); if (pWrkrData->pData->numServers > 1) { /* needs to be called to support ES HA feature */ CHKiRet(checkConn(pWrkrData)); } CHKiRet(setPostURL(pWrkrData, tpls)); pWrkrData->reply = NULL; pWrkrData->replyLen = 0; pWrkrData->httpStatusCode = 0; postData = (char *)message; postLen = msglen; compressed = 0; if (pWrkrData->pData->compress) { iRet = compressHttpPayload(pWrkrData, message, msglen); if (iRet != RS_RET_OK) { LogError(0, iRet, "omhttp: curlPost error while compressing, will default to uncompressed"); } else { postData = (char *)pWrkrData->compressCtx.buf; postLen = pWrkrData->compressCtx.curLen; compressed = 1; DBGPRINTF("omhttp: curlPost compressed %d to %d bytes\n", msglen, postLen); } } buildCurlHeaders(pWrkrData, compressed); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postLen); curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); curlCode = curl_easy_perform(curl); DBGPRINTF("omhttp: curlPost curl returned %lld\n", (long long)curlCode); STATSCOUNTER_INC(pWrkrData->pData->listObjStats[indexStats].ctrHttpRequestsCount, pWrkrData->pData->listObjStats[indexStats].mutCtrHttpRequestsCount); if (curlCode != CURLE_OK) { STATSCOUNTER_INC(pWrkrData->pData->listObjStats[indexStats].ctrHttpRequestFail, pWrkrData->pData->listObjStats[indexStats].mutCtrHttpRequestFail); LogError(0, RS_RET_SUSPENDED, "omhttp: suspending ourselves due to server failure %lld: %s", (long long)curlCode, errbuf); // Check the result here too and retry if needed, then we should suspend // Usually in batch mode we clobber any iRet values, but probably not a great // idea to keep hitting a dead server. The http status code will be 0 at this point. checkResult(pWrkrData, message); ABORT_FINALIZE(RS_RET_SUSPENDED); } else { STATSCOUNTER_INC(pWrkrData->pData->listObjStats[indexStats].ctrHttpRequestSuccess, pWrkrData->pData->listObjStats[indexStats].mutCtrHttpRequestSuccess); } // Grab the HTTP Response code curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &pWrkrData->httpStatusCode); if (pWrkrData->reply == NULL) { DBGPRINTF("omhttp: curlPost pWrkrData reply==NULL, replyLen = '%d'\n", pWrkrData->replyLen); } else { DBGPRINTF("omhttp: curlPost pWrkrData replyLen = '%d'\n", pWrkrData->replyLen); if (pWrkrData->replyLen > 0) { pWrkrData->reply[pWrkrData->replyLen] = '\0'; /* Append 0 Byte if replyLen is above 0 - byte has been reserved in malloc */ } // TODO: replyLen++? because 0 Byte is appended DBGPRINTF("omhttp: curlPost pWrkrData reply: '%s'\n", pWrkrData->reply); } CHKiRet(checkResult(pWrkrData, message)); finalize_it: incrementServerIndex(pWrkrData); if (pWrkrData->reply != NULL) { free(pWrkrData->reply); pWrkrData->reply = NULL; /* don't leave dangling pointer */ } RETiRet; } /* Build a JSON batch that conforms to the Kafka Rest Proxy format. * See https://docs.confluent.io/current/kafka-rest/docs/quickstart.html for more info. * Want {"records": [{"value": "message1"}, {"value": "message2"}]} */ static rsRetVal serializeBatchKafkaRest(wrkrInstanceData_t *pWrkrData, char **batchBuf) { fjson_object *batchArray = NULL; fjson_object *recordObj = NULL; fjson_object *valueObj = NULL; fjson_object *msgObj = NULL; size_t numMessages = pWrkrData->batch.nmemb; size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas DBGPRINTF("omhttp: serializeBatchKafkaRest numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); DEFiRet; batchArray = fjson_object_new_array(); if (batchArray == NULL) { LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create array"); ABORT_FINALIZE(RS_RET_ERR); } for (size_t i = 0; i < numMessages; i++) { valueObj = fjson_object_new_object(); if (valueObj == NULL) { fjson_object_put(batchArray); // cleanup LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create value object"); ABORT_FINALIZE(RS_RET_ERR); } msgObj = fjson_tokener_parse((char *)pWrkrData->batch.data[i]); if (msgObj == NULL) { LogError(0, NO_ERRCODE, "omhttp: serializeBatchKafkaRest failed to parse %s as json ignoring it", pWrkrData->batch.data[i]); continue; } fjson_object_object_add(valueObj, "value", msgObj); fjson_object_array_add(batchArray, valueObj); } recordObj = fjson_object_new_object(); if (recordObj == NULL) { fjson_object_put(batchArray); // cleanup LogError(0, RS_RET_ERR, "omhttp: serializeBatchKafkaRest failed to create record object"); ABORT_FINALIZE(RS_RET_ERR); } fjson_object_object_add(recordObj, "records", batchArray); const char *batchString = fjson_object_to_json_string_ext(recordObj, FJSON_TO_STRING_PLAIN); *batchBuf = strndup(batchString, strlen(batchString)); finalize_it: if (recordObj != NULL) { fjson_object_put(recordObj); recordObj = NULL; } RETiRet; } static rsRetVal serializeBatchLokiRest(wrkrInstanceData_t *pWrkrData, char **batchBuf) { fjson_object *batchArray = NULL; fjson_object *recordObj = NULL; fjson_object *msgObj = NULL; size_t numMessages = pWrkrData->batch.nmemb; size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas DBGPRINTF("omhttp: serializeBatchLokiRest numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); DEFiRet; batchArray = fjson_object_new_array(); if (batchArray == NULL) { LogError(0, RS_RET_ERR, "omhttp: serializeBatchLokiRest failed to create array"); ABORT_FINALIZE(RS_RET_ERR); } for (size_t i = 0; i < numMessages; i++) { DBGPRINTF("omhttp: serializeBatchLokiRest parsing message [%s]\n", (char *)pWrkrData->batch.data[i]); msgObj = fjson_tokener_parse((char *)pWrkrData->batch.data[i]); if (msgObj == NULL) { LogError(0, NO_ERRCODE, "omhttp: serializeBatchLokiRest failed to parse %s as json ignoring it", pWrkrData->batch.data[i]); continue; } fjson_object_array_add(batchArray, msgObj); } recordObj = fjson_object_new_object(); if (recordObj == NULL) { fjson_object_put(batchArray); // cleanup LogError(0, RS_RET_ERR, "omhttp: serializeBatchLokiRest failed to create record object"); ABORT_FINALIZE(RS_RET_ERR); } fjson_object_object_add(recordObj, "streams", batchArray); const char *batchString = fjson_object_to_json_string_ext(recordObj, FJSON_TO_STRING_PLAIN); *batchBuf = strndup(batchString, strlen(batchString)); finalize_it: if (recordObj != NULL) { fjson_object_put(recordObj); recordObj = NULL; } RETiRet; } /* Build a JSON batch by placing each element in an array. */ static rsRetVal serializeBatchJsonArray(wrkrInstanceData_t *pWrkrData, char **batchBuf) { fjson_object *batchArray = NULL; fjson_object *msgObj = NULL; size_t numMessages = pWrkrData->batch.nmemb; size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages + 1; // messages + brackets + commas DBGPRINTF("omhttp: serializeBatchJsonArray numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); DEFiRet; batchArray = fjson_object_new_array(); if (batchArray == NULL) { LogError(0, RS_RET_ERR, "omhttp: serializeBatchJsonArray failed to create array"); ABORT_FINALIZE(RS_RET_ERR); } for (size_t i = 0; i < numMessages; i++) { msgObj = fjson_tokener_parse((char *)pWrkrData->batch.data[i]); if (msgObj == NULL) { LogError(0, NO_ERRCODE, "omhttp: serializeBatchJsonArray failed to parse %s as json, ignoring it", pWrkrData->batch.data[i]); continue; } fjson_object_array_add(batchArray, msgObj); } const char *batchString = fjson_object_to_json_string_ext(batchArray, FJSON_TO_STRING_PLAIN); *batchBuf = strndup(batchString, strlen(batchString)); finalize_it: if (batchArray != NULL) { fjson_object_put(batchArray); batchArray = NULL; } RETiRet; } /* Build a batch by joining each element with a newline character. */ static rsRetVal serializeBatchNewline(wrkrInstanceData_t *pWrkrData, char **batchBuf) { DEFiRet; size_t numMessages = pWrkrData->batch.nmemb; size_t sizeTotal = pWrkrData->batch.sizeBytes + numMessages; // message + newline + null term int r = 0; DBGPRINTF("omhttp: serializeBatchNewline numMessages=%zd sizeTotal=%zd\n", numMessages, sizeTotal); es_str_t *batchString = es_newStr(1024); if (batchString == NULL) ABORT_FINALIZE(RS_RET_ERR); for (size_t i = 0; i < numMessages; i++) { size_t nToCopy = ustrlen(pWrkrData->batch.data[i]); if (r == 0) r = es_addBuf(&batchString, (char *)pWrkrData->batch.data[i], nToCopy); if (i == numMessages - 1) break; if (r == 0) r = es_addChar(&batchString, '\n'); } if (r == 0) *batchBuf = (char *)es_str2cstr(batchString, NULL); if (r != 0 || *batchBuf == NULL) { LogError(0, RS_RET_ERR, "omhttp: serializeBatchNewline failed to build batch string"); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (batchString != NULL) es_deleteStr(batchString); RETiRet; } /* Return the final batch size in bytes for each serialization method. * Used to decide if a batch should be flushed early. */ static size_t computeBatchSize(wrkrInstanceData_t *pWrkrData) { size_t extraBytes = 0; size_t sizeBytes = pWrkrData->batch.sizeBytes; size_t numMessages = pWrkrData->batch.nmemb; switch (pWrkrData->pData->batchFormat) { case FMT_JSONARRAY: // square brackets, commas between each message // 2 + numMessages - 1 = numMessages + 1 extraBytes = numMessages > 0 ? numMessages + 1 : 2; break; case FMT_KAFKAREST: // '{}', '[]', '"records":'= 2 + 2 + 10 = 14 // '{"value":}' for each message = n * 10 // plus commas between array elements (n > 0 ? n - 1 : 0) extraBytes = (numMessages * 10) + 14 + (numMessages > 0 ? numMessages - 1 : 0); break; case FMT_NEWLINE: // newlines between each message extraBytes = numMessages > 0 ? numMessages - 1 : 0; break; case FMT_LOKIREST: // {"streams":[ '{}', '[]', '"streams":' = 14 // {"stream": {key:value}..., "values":[[timestamp: msg1]]}, // {"stream": {key:value}..., "values":[[timestamp: msg2]]} // ]} // Approximate per-message wrapper overhead (2) plus commas between elements extraBytes = (numMessages * 2) + 14 + (numMessages > 0 ? numMessages - 1 : 0); break; default: // newlines between each message extraBytes = numMessages > 0 ? numMessages - 1 : 0; } return sizeBytes + extraBytes + 1; // plus a null } /* Return the delta of extra bytes added by appending one more message to * the current batch, based on the configured serialization format. */ static inline size_t computeDeltaExtraOnAppend(const wrkrInstanceData_t *pWrkrData) { const size_t numMessages = pWrkrData->batch.nmemb; switch (pWrkrData->pData->batchFormat) { case FMT_JSONARRAY: /* add a comma if there is already at least one element */ return (numMessages > 0) ? 1 : 0; case FMT_KAFKAREST: /* per-message wrapper overhead (e.g. {"value":}) + comma if needed */ return 10 + ((numMessages > 0) ? 1 : 0); case FMT_NEWLINE: /* add a newline if there is already at least one element */ return (numMessages > 0) ? 1 : 0; case FMT_LOKIREST: /* approximate per-message overhead in wrapper + comma if needed */ return 2 + ((numMessages > 0) ? 1 : 0); default: return (numMessages > 0) ? 1 : 0; } } static void ATTR_NONNULL() initializeBatch(wrkrInstanceData_t *pWrkrData) { pWrkrData->batch.sizeBytes = 0; pWrkrData->batch.nmemb = 0; if (pWrkrData->batch.restPath != NULL) { free(pWrkrData->batch.restPath); pWrkrData->batch.restPath = NULL; } } /* Adds a message to this worker's batch */ static rsRetVal buildBatch(wrkrInstanceData_t *pWrkrData, uchar *message) { DEFiRet; if (pWrkrData->batch.nmemb >= pWrkrData->pData->maxBatchSize) { LogError(0, RS_RET_ERR, "omhttp: buildBatch something has gone wrong," "number of messages in batch is bigger than the max batch size, bailing"); ABORT_FINALIZE(RS_RET_ERR); } pWrkrData->batch.data[pWrkrData->batch.nmemb] = message; pWrkrData->batch.sizeBytes += strlen((char *)message); pWrkrData->batch.nmemb++; finalize_it: RETiRet; } static rsRetVal submitBatch(wrkrInstanceData_t *pWrkrData, uchar **tpls) { DEFiRet; char *batchBuf = NULL; switch (pWrkrData->pData->batchFormat) { case FMT_JSONARRAY: iRet = serializeBatchJsonArray(pWrkrData, &batchBuf); break; case FMT_KAFKAREST: iRet = serializeBatchKafkaRest(pWrkrData, &batchBuf); break; case FMT_LOKIREST: iRet = serializeBatchLokiRest(pWrkrData, &batchBuf); break; case FMT_NEWLINE: iRet = serializeBatchNewline(pWrkrData, &batchBuf); break; default: iRet = serializeBatchNewline(pWrkrData, &batchBuf); } if (iRet != RS_RET_OK || batchBuf == NULL) ABORT_FINALIZE(iRet); DBGPRINTF("omhttp: submitBatch, batch: '%s' tpls: '%p'\n", batchBuf, tpls); CHKiRet(curlPost(pWrkrData, (uchar *)batchBuf, strlen(batchBuf), tpls, pWrkrData->batch.nmemb)); finalize_it: if (batchBuf != NULL) free(batchBuf); RETiRet; } BEGINbeginTransaction CODESTARTbeginTransaction; if (!pWrkrData->pData->batchMode) { FINALIZE; } initializeBatch(pWrkrData); finalize_it: ENDbeginTransaction BEGINcommitTransaction unsigned i; size_t nBytes; sbool submit; CODESTARTcommitTransaction; instanceData *const pData = pWrkrData->pData; const int iNumTpls = pData->dynRestPath ? 2 : 1; int indexStats = pWrkrData->pData->statsBySenders ? pWrkrData->serverIndex : 0; for (i = 0; i < nParams; ++i) { uchar *payload = actParam(pParams, iNumTpls, i, 0).param; uchar *tpls[2] = {payload, NULL}; if (iNumTpls == 2) tpls[1] = actParam(pParams, iNumTpls, i, 1).param; STATSCOUNTER_INC(pWrkrData->pData->listObjStats[indexStats].ctrMessagesSubmitted, pWrkrData->pData->listObjStats[indexStats].mutCtrMessagesSubmitted); if (pData->batchMode) { if (pData->dynRestPath) { uchar *restPath = actParam(pParams, iNumTpls, i, 1).param; if (pWrkrData->batch.restPath == NULL) { CHKmalloc(pWrkrData->batch.restPath = (uchar *)strdup((char *)restPath)); } else if (strcmp((char *)pWrkrData->batch.restPath, (char *)restPath) != 0) { /* restPath changed -> flush current batch if it contains data */ if (pWrkrData->batch.nmemb > 0) { CHKiRet(submitBatch(pWrkrData, NULL)); } initializeBatch(pWrkrData); CHKmalloc(pWrkrData->batch.restPath = (uchar *)strdup((char *)restPath)); } } /* If maxBatchSize is 1, immediately build and post a single-element batch */ if (pData->maxBatchSize == 1) { initializeBatch(pWrkrData); CHKiRet(buildBatch(pWrkrData, payload)); CHKiRet(submitBatch(pWrkrData, tpls)); continue; } /* Determine if we should submit due to size/bytes thresholds */ nBytes = ustrlen((char *)payload); submit = 0; if (pWrkrData->batch.nmemb >= pData->maxBatchSize) { submit = 1; DBGPRINTF("omhttp: maxbatchsize limit reached submitting batch of %zd elements.\n", pWrkrData->batch.nmemb); } else { const size_t predicted = computeBatchSize(pWrkrData) + nBytes + computeDeltaExtraOnAppend(pWrkrData); if (predicted > pData->maxBatchBytes) { submit = 1; DBGPRINTF("omhttp: maxbytes limit reached submitting partial batch of %zd elements.\n", pWrkrData->batch.nmemb); } } if (submit) { /* flush current batch, then start a new one. keep dyn restPath consistent */ CHKiRet(submitBatch(pWrkrData, NULL)); initializeBatch(pWrkrData); if (pData->dynRestPath) { uchar *restPath = actParam(pParams, iNumTpls, i, 1).param; CHKmalloc(pWrkrData->batch.restPath = (uchar *)strdup((char *)restPath)); } } CHKiRet(buildBatch(pWrkrData, payload)); } else { /* non-batch mode: send immediately */ CHKiRet(curlPost(pWrkrData, payload, strlen((char *)payload), tpls, 1)); } } /* finalize any remaining batch data */ if (pData->batchMode) { if (pWrkrData->batch.nmemb > 0) { CHKiRet(submitBatch(pWrkrData, NULL)); } else { dbgprintf("omhttp: commitTransaction, pWrkrData->batch.nmemb = 0, nothing to send. \n"); } } finalize_it: ENDcommitTransaction /* Creates authentication header uid:pwd */ static rsRetVal computeAuthHeader(char *uid, char *pwd, uchar **authBuf) { int r; DEFiRet; es_str_t *auth = es_newStr(1024); if (auth == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: failed to allocate es_str auth for auth header construction"); ABORT_FINALIZE(RS_RET_ERR); } r = es_addBuf(&auth, uid, strlen(uid)); if (r == 0) r = es_addChar(&auth, ':'); if (r == 0 && pwd != NULL) r = es_addBuf(&auth, pwd, strlen(pwd)); if (r == 0) *authBuf = (uchar *)es_str2cstr(auth, NULL); if (r != 0 || *authBuf == NULL) { LogError(0, RS_RET_ERR, "omhttp: failed to build auth header\n"); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (auth != NULL) es_deleteStr(auth); RETiRet; } static rsRetVal computeApiHeader(char *key, char *value, uchar **headerBuf) { int r; DEFiRet; es_str_t *header = es_newStr(10240); if (header == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: failed to allocate es_str auth for api header construction"); ABORT_FINALIZE(RS_RET_ERR); } r = es_addBuf(&header, key, strlen(key)); if (r == 0) r = es_addChar(&header, ':'); if (r == 0) r = es_addChar(&header, ' '); if (r == 0 && value != NULL) r = es_addBuf(&header, value, strlen(value)); if (r == 0) *headerBuf = (uchar *)es_str2cstr(header, NULL); if (r != 0 || *headerBuf == NULL) { LogError(0, RS_RET_ERR, "omhttp: failed to build http header\n"); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (header != NULL) es_deleteStr(header); RETiRet; } static void ATTR_NONNULL() curlSetupCommon(wrkrInstanceData_t *const pWrkrData, CURL *const handle) { PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); curl_easy_setopt(handle, CURLOPT_HTTPHEADER, pWrkrData->curlHeader); curl_easy_setopt(handle, CURLOPT_NOSIGNAL, TRUE); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curlResult); curl_easy_setopt(handle, CURLOPT_WRITEDATA, pWrkrData); if (pWrkrData->pData->proxyHost != NULL) { curl_easy_setopt(handle, CURLOPT_PROXY, pWrkrData->pData->proxyHost); } if (pWrkrData->pData->proxyPort != 0) { curl_easy_setopt(handle, CURLOPT_PROXYPORT, pWrkrData->pData->proxyPort); } if (pWrkrData->pData->restPathTimeout) { curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, pWrkrData->pData->restPathTimeout); } if (pWrkrData->pData->allowUnsignedCerts) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, FALSE); if (pWrkrData->pData->skipVerifyHost) curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, FALSE); if (pWrkrData->pData->authBuf != NULL) { curl_easy_setopt(handle, CURLOPT_USERPWD, pWrkrData->pData->authBuf); curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY); } if (pWrkrData->pData->caCertFile) curl_easy_setopt(handle, CURLOPT_CAINFO, pWrkrData->pData->caCertFile); if (pWrkrData->pData->myCertFile) curl_easy_setopt(handle, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile); if (pWrkrData->pData->myPrivKeyFile) curl_easy_setopt(handle, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile); /* uncomment for in-dept debuggung: curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE); */ } static void ATTR_NONNULL() curlCheckConnSetup(wrkrInstanceData_t *const pWrkrData) { PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); curlSetupCommon(pWrkrData, pWrkrData->curlCheckConnHandle); curl_easy_setopt(pWrkrData->curlCheckConnHandle, CURLOPT_TIMEOUT_MS, pWrkrData->pData->healthCheckTimeout); } static void ATTR_NONNULL(1) curlPostSetup(wrkrInstanceData_t *const pWrkrData) { PTR_ASSERT_SET_TYPE(pWrkrData, WRKR_DATA_TYPE_ES); curlSetupCommon(pWrkrData, pWrkrData->curlPostHandle); curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_POST, 1); CURLcode cRet; /* Enable TCP keep-alive for this transfer */ cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPALIVE, 1L); if (cRet != CURLE_OK) DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPALIVE\n"); /* keep-alive idle time to 120 seconds */ cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPIDLE, 120L); if (cRet != CURLE_OK) DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPIDLE\n"); /* interval time between keep-alive probes: 60 seconds */ cRet = curl_easy_setopt(pWrkrData->curlPostHandle, CURLOPT_TCP_KEEPINTVL, 60L); if (cRet != CURLE_OK) DBGPRINTF("omhttp: curlPostSetup unknown option CURLOPT_TCP_KEEPINTVL\n"); } static rsRetVal ATTR_NONNULL() curlSetup(wrkrInstanceData_t *const pWrkrData) { struct curl_slist *slist = NULL; DEFiRet; if (pWrkrData->pData->httpcontenttype != NULL) { slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerContentTypeBuf); } else { slist = curl_slist_append(slist, HTTP_HEADER_CONTENT_JSON); } if (pWrkrData->pData->headerBuf != NULL) { slist = curl_slist_append(slist, (char *)pWrkrData->pData->headerBuf); CHKmalloc(slist); } for (int k = 0; k < pWrkrData->pData->nHttpHeaders; k++) { slist = curl_slist_append(slist, (char *)pWrkrData->pData->httpHeaders[k]); CHKmalloc(slist); } // When sending more than 1Kb, libcurl automatically sends an Except: 100-Continue header // and will wait 1s for a response, could make this configurable but for now disable slist = curl_slist_append(slist, HTTP_HEADER_EXPECT_EMPTY); pWrkrData->curlHeader = slist; CHKmalloc(pWrkrData->curlPostHandle = curl_easy_init()); curlPostSetup(pWrkrData); CHKmalloc(pWrkrData->curlCheckConnHandle = curl_easy_init()); curlCheckConnSetup(pWrkrData); finalize_it: if (iRet != RS_RET_OK && pWrkrData->curlPostHandle != NULL) { curl_easy_cleanup(pWrkrData->curlPostHandle); pWrkrData->curlPostHandle = NULL; } RETiRet; } static void ATTR_NONNULL() curlCleanup(wrkrInstanceData_t *const pWrkrData) { if (pWrkrData->curlHeader != NULL) { curl_slist_free_all(pWrkrData->curlHeader); pWrkrData->curlHeader = NULL; } if (pWrkrData->curlCheckConnHandle != NULL) { curl_easy_cleanup(pWrkrData->curlCheckConnHandle); pWrkrData->curlCheckConnHandle = NULL; } if (pWrkrData->curlPostHandle != NULL) { curl_easy_cleanup(pWrkrData->curlPostHandle); pWrkrData->curlPostHandle = NULL; } } static void ATTR_NONNULL() setInstParamDefaults(instanceData *const pData) { pData->serverBaseUrls = NULL; pData->defaultPort = 443; pData->healthCheckTimeout = 3500; pData->token = NULL; pData->uid = NULL; pData->restPathTimeout = 0; pData->httpcontenttype = NULL; pData->headerContentTypeBuf = NULL; pData->httpheaderkey = NULL; pData->httpheadervalue = NULL; pData->httpHeaders = NULL; pData->nHttpHeaders = 0; pData->pwd = NULL; pData->authBuf = NULL; pData->headerBuf = NULL; pData->restPath = NULL; pData->checkPath = NULL; pData->dynRestPath = 0; pData->proxyHost = NULL; pData->proxyPort = 0; pData->batchMode = 0; pData->batchFormatName = (uchar *)"newline"; pData->batchFormat = FMT_NEWLINE; pData->bFreeBatchFormatName = 0; pData->useHttps = 1; pData->maxBatchBytes = DEFAULT_MAX_BATCH_BYTES; // 10 MB - default max message size for AWS API Gateway pData->maxBatchSize = 100; // 100 messages pData->compress = 0; // off pData->compressionLevel = -1; // default compression pData->allowUnsignedCerts = 0; pData->skipVerifyHost = 0; pData->tplName = NULL; pData->errorFile = NULL; pData->caCertFile = NULL; pData->myCertFile = NULL; pData->myPrivKeyFile = NULL; pData->reloadOnHup = 0; pData->retryFailures = 0; pData->retryAddMetadata = 0; pData->nhttpRetryCodes = 0; pData->httpRetryCodes = NULL; pData->ratelimitBurst = 20000; pData->ratelimitInterval = 600; pData->ratelimiter = NULL; pData->retryRulesetName = NULL; pData->retryRuleset = NULL; pData->nIgnorableCodes = 0; pData->ignorableCodes = NULL; pData->statsBySenders = 0; // Disable by default // increment number of instances ++omhttpInstancesCnt; } static rsRetVal checkHeaderParam(char *const param) { DEFiRet; char *val = strstr(param, ":"); if (val == NULL) { LogError(0, RS_RET_PARAM_ERROR, "missing ':' delimiter in " "parameter '%s'", param); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } finalize_it: RETiRet; } /* Apply profile settings to instance configuration * Profiles are meta-configurations that set multiple parameters at once * for common use cases like Loki or Splunk HEC */ static rsRetVal applyProfileSettings(instanceData *const pData, const char *const profile) { DEFiRet; if (strcasecmp(profile, "loki") == 0) { /* Loki profile settings */ LogMsg(0, RS_RET_OK, LOG_INFO, "omhttp: applying 'loki' profile"); pData->vendor = LOKI; /* Set batch format to lokirest if not already set */ if (!pData->bFreeBatchFormatName) { pData->batchFormatName = (uchar *)"lokirest"; pData->batchFormat = FMT_LOKIREST; } /* Set default rest path for Loki if not set */ if (pData->restPath == NULL) { CHKmalloc(pData->restPath = (uchar *)strdup("loki/api/v1/push")); } /* Enable batch mode by default for Loki */ if (!pData->batchMode) { pData->batchMode = 1; } /* Enable compression for Loki (typically beneficial) */ if (!pData->compress) { pData->compress = 1; pData->compressionLevel = -1; /* default compression */ } /* Set default retry codes to 5xx if not configured */ if (pData->nhttpRetryCodes == 0) { static const unsigned int loki_retry_codes[] = {500, 502, 503, 504}; const size_t num_codes = sizeof(loki_retry_codes) / sizeof(loki_retry_codes[0]); pData->nhttpRetryCodes = num_codes; CHKmalloc(pData->httpRetryCodes = malloc(sizeof(loki_retry_codes))); memcpy(pData->httpRetryCodes, loki_retry_codes, sizeof(loki_retry_codes)); } } else if (strncasecmp(profile, "hec:", 4) == 0) { /* HEC (HTTP Event Collector) profile */ const char *vendor = profile + 4; if (strncasecmp(vendor, "splunk:", 7) == 0) { /* Check endpoint */ const char *endpoint = vendor + 7; pData->vendor = SPLUNK; if (strcasecmp(endpoint, "raw") == 0) { LogMsg(0, RS_RET_OK, LOG_INFO, "omhttp: applying 'hec:splunk:raw' profile"); /* Set default rest path for Splunk HEC */ if (pData->restPath == NULL && !pData->dynRestPath) { CHKmalloc(pData->restPath = (uchar *)strdup(SPLUNK_HEC_RESTPATH_ENDPOINT_RAW)); } /* Set batch format to newline (Splunk HEC uses newline-delimited format) */ if (!pData->bFreeBatchFormatName) { pData->batchFormatName = (uchar *)"newline"; pData->batchFormat = FMT_NEWLINE; } /* Set a custom template */ if (pData->tplName == NULL) { pData->tplName = (uchar *)NAME_TPL_SPLK_RAW; } } else if (strcasecmp(endpoint, "event") == 0) { LogMsg(0, RS_RET_OK, LOG_INFO, "omhttp: applying 'hec:splunk:event' profile"); /* Set default rest path for Splunk HEC */ if (pData->restPath == NULL && !pData->dynRestPath) { CHKmalloc(pData->restPath = (uchar *)strdup(SPLUNK_HEC_RESTPATH_ENDPOINT_EVENT)); } /* Set batch format to newline (Splunk HEC uses newline-delimited format) */ if (!pData->bFreeBatchFormatName) { pData->batchFormatName = (uchar *)"newline"; pData->batchFormat = FMT_NEWLINE; } /* Enable batch mode for HEC */ if (!pData->batchMode) { pData->batchMode = 1; } /* Set a custom template */ if (pData->tplName == NULL) { pData->tplName = (uchar *)NAME_TPL_SPLK_EVENT; } } else { LogError(0, RS_RET_PARAM_ERROR, "omhttp: unknown Splunk HEC endpoint '%s' in profile", endpoint); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } /* Header */ if (pData->token != NULL) { /* Create authorization header */ es_str_t *tmpHeader = es_newStr(10240); int r = es_addBuf(&tmpHeader, "Authorization", strlen("Authorization")); if (r == 0) r = es_addChar(&tmpHeader, ':'); if (r == 0) r = es_addChar(&tmpHeader, ' '); if (r == 0) r = es_addBuf(&tmpHeader, SPLUNK_HEC_HEADER_AUTH, strlen(SPLUNK_HEC_HEADER_AUTH)); if (r == 0) r = es_addBuf(&tmpHeader, (char *)pData->token, ustrlen(pData->token)); if (r != 0 || tmpHeader == NULL) { LogError(0, RS_RET_ERR, "omhttp: error occurred computing token"); ABORT_FINALIZE(RS_RET_ERR); } if (pData->nHttpHeaders > 0) { CHKmalloc(pData->httpHeaders = malloc(sizeof(uchar *) * 1)); // Only one HEADER pData->nHttpHeaders = 1; pData->httpHeaders[0] = (uchar *)es_str2cstr(tmpHeader, NULL); } else { pData->httpHeaders = realloc(pData->httpHeaders, sizeof(uchar *) * (pData->nHttpHeaders + 1)); if (pData->httpHeaders == NULL) { LogError(0, RS_RET_OUT_OF_MEMORY, "omhttp: error reallocating httpHeaders for auth token"); es_deleteStr(tmpHeader); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pData->httpHeaders[pData->nHttpHeaders] = (uchar *)es_str2cstr(tmpHeader, NULL); pData->nHttpHeaders++; } if (tmpHeader != NULL) es_deleteStr(tmpHeader); } else { LogError(0, RS_RET_PARAM_ERROR, "omhttp: Splunk HEC endpoint : a token is need it"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } /* Set default max batch bytes (Splunk recommends < 1MB) */ if (pData->maxBatchBytes == DEFAULT_MAX_BATCH_BYTES) { /* still default */ pData->maxBatchBytes = SPLUNK_HEC_MAX_BATCH_BYTES; /* 1MB */ } /* Set default retry codes to 5xx * https://docs.splunk.com/Documentation/Splunk/9.4.2/Data/TroubleshootHTTPEventCollector#Possible_error_codes */ if (pData->nhttpRetryCodes == 0) { static const unsigned int splk_retry_codes[] = {500, 503}; const size_t num_codes = sizeof(splk_retry_codes) / sizeof(splk_retry_codes[0]); pData->nhttpRetryCodes = num_codes; CHKmalloc(pData->httpRetryCodes = malloc(sizeof(splk_retry_codes))); memcpy(pData->httpRetryCodes, splk_retry_codes, sizeof(splk_retry_codes)); } /* Define health Check URL */ if (pData->checkPath == NULL) { CHKmalloc(pData->checkPath = (uchar *)strdup(SPLUNK_HEC_RESTPATH_ENDPOINT_HEALTH)); } } else { LogError(0, RS_RET_PARAM_ERROR, "omhttp: unknown HEC vendor '%s' in profile", vendor); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } } else { LogError(0, RS_RET_PARAM_ERROR, "omhttp: unknown profile '%s'", profile); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } finalize_it: RETiRet; } static rsRetVal setStatsObject(instanceData *const pData, const char *const serverParam, size_t index) { uchar ctrName[256]; DEFiRet; targetStats_t *const serverStats = &pData->listObjStats[index]; if (serverParam == NULL) { snprintf((char *)ctrName, sizeof(ctrName), "%s(ALL)", pData->statsName); ctrName[sizeof(ctrName) - 1] = '\0'; } else { snprintf((char *)ctrName, sizeof(ctrName), "%s(%s)", pData->statsName, serverParam); ctrName[sizeof(ctrName) - 1] = '\0'; } // instantiate the stats object and add the counters CHKiRet(statsobj.Construct(&(serverStats->defaultstats))); CHKiRet(statsobj.SetName(serverStats->defaultstats, ctrName)); CHKiRet(statsobj.SetOrigin(serverStats->defaultstats, (uchar *)"omhttp")); STATSCOUNTER_INIT(serverStats->ctrMessagesSubmitted, serverStats->mutCtrMessagesSubmitted); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"messages.submitted", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrMessagesSubmitted))); STATSCOUNTER_INIT(serverStats->ctrMessagesSuccess, serverStats->mutCtrMessagesSuccess); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"messages.success", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrMessagesSuccess))); STATSCOUNTER_INIT(serverStats->ctrMessagesFail, serverStats->mutCtrMessagesFail); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"messages.fail", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrMessagesFail))); STATSCOUNTER_INIT(serverStats->ctrMessagesRetry, serverStats->mutCtrMessagesRetry); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"messages.retry", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrMessagesRetry))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestSuccess, serverStats->mutCtrHttpRequestSuccess); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"request.success", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestSuccess))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestFail, serverStats->mutCtrHttpRequestFail); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"request.fail", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestFail))); STATSCOUNTER_INIT(serverStats->ctrHttpStatusSuccess, serverStats->mutCtrHttpStatusSuccess); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"request.status.success", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpStatusSuccess))); STATSCOUNTER_INIT(serverStats->ctrHttpStatusFail, serverStats->mutCtrHttpStatusFail); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"request.status.fail", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpStatusFail))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsCount, serverStats->mutCtrHttpRequestsCount); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.count", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsCount))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus0xx, serverStats->mutCtrHttpRequestsStatus0xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.0xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus0xx))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus1xx, serverStats->mutCtrHttpRequestsStatus1xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.1xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus1xx))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus2xx, serverStats->mutCtrHttpRequestsStatus2xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.2xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus2xx))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus3xx, serverStats->mutCtrHttpRequestsStatus3xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.3xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus3xx))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus4xx, serverStats->mutCtrHttpRequestsStatus4xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.4xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus4xx))); STATSCOUNTER_INIT(serverStats->ctrHttpRequestsStatus5xx, serverStats->mutCtrHttpRequestsStatus5xx); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.status.5xx", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->ctrHttpRequestsStatus5xx))); STATSCOUNTER_INIT(serverStats->httpRequestsBytes, serverStats->mutHttpRequestsBytes); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.bytes", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->httpRequestsBytes))); STATSCOUNTER_INIT(serverStats->httpRequestsTimeMs, serverStats->mutHttpRequestsTimeMs); CHKiRet(statsobj.AddCounter(serverStats->defaultstats, (uchar *)"requests.time_ms", ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(serverStats->httpRequestsTimeMs))); CHKiRet(statsobj.ConstructFinalize(serverStats->defaultstats)); finalize_it: RETiRet; } BEGINnewActInst struct cnfparamvals *pvals; char *serverParam = NULL; struct cnfarray *servers = NULL; char *profileName = NULL; int i; int iNumTpls; FILE *fp; char errStr[1024]; char *batchFormatName; int compressionLevel = -1; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "server")) { servers = pvals[i].val.d.ar; } else if (!strcmp(actpblk.descr[i].name, "errorfile")) { pData->errorFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "serverport")) { pData->defaultPort = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "healthchecktimeout")) { pData->healthCheckTimeout = (long)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "restpathtimeout")) { pData->restPathTimeout = (long)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "token")) { pData->token = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "uid")) { pData->uid = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "httpcontenttype")) { pData->httpcontenttype = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "httpheaderkey")) { pData->httpheaderkey = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "httpheadervalue")) { pData->httpheadervalue = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "httpheaders")) { pData->nHttpHeaders = pvals[i].val.d.ar->nmemb; CHKmalloc(pData->httpHeaders = malloc(sizeof(uchar *) * pvals[i].val.d.ar->nmemb)); for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); CHKiRet(checkHeaderParam(cstr)); pData->httpHeaders[j] = (uchar *)cstr; } } else if (!strcmp(actpblk.descr[i].name, "pwd")) { pData->pwd = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "restpath")) { pData->restPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "checkpath")) { pData->checkPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "dynrestpath")) { pData->dynRestPath = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "proxyhost")) { pData->proxyHost = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "proxyport")) { pData->proxyPort = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "batch")) { pData->batchMode = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "batch.format")) { batchFormatName = es_str2cstr(pvals[i].val.d.estr, NULL); if (strstr(VALID_BATCH_FORMATS, batchFormatName) != NULL) { pData->batchFormatName = (uchar *)batchFormatName; pData->bFreeBatchFormatName = 1; if (!strcmp(batchFormatName, "newline")) { pData->batchFormat = FMT_NEWLINE; } else if (!strcmp(batchFormatName, "jsonarray")) { pData->batchFormat = FMT_JSONARRAY; } else if (!strcmp(batchFormatName, "kafkarest")) { pData->batchFormat = FMT_KAFKAREST; } else if (!strcmp(batchFormatName, "lokirest")) { pData->batchFormat = FMT_LOKIREST; } } else { LogError(0, NO_ERRCODE, "error: 'batch.format' %s unknown defaulting to 'newline'", batchFormatName); } } else if (!strcmp(actpblk.descr[i].name, "batch.maxbytes")) { pData->maxBatchBytes = (size_t)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "batch.maxsize")) { pData->maxBatchSize = (size_t)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "compress")) { pData->compress = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "compress.level")) { compressionLevel = pvals[i].val.d.n; if (compressionLevel == -1 || (compressionLevel >= 0 && compressionLevel < 10)) { pData->compressionLevel = compressionLevel; } else { LogError(0, NO_ERRCODE, "omhttp: invalid compress.level %d using default instead," "valid levels are -1 and 0-9", compressionLevel); } } else if (!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) { pData->allowUnsignedCerts = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "skipverifyhost")) { pData->skipVerifyHost = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "usehttps")) { pData->useHttps = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "tls.cacert")) { pData->caCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->caCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); LogError(0, RS_RET_NO_FILE_ACCESS, "error: 'tls.cacert' file %s couldn't be accessed: %s\n", pData->caCertFile, errStr); } else { fclose(fp); } } else if (!strcmp(actpblk.descr[i].name, "tls.mycert")) { pData->myCertFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->myCertFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); LogError(0, RS_RET_NO_FILE_ACCESS, "error: 'tls.mycert' file %s couldn't be accessed: %s\n", pData->myCertFile, errStr); } else { fclose(fp); } } else if (!strcmp(actpblk.descr[i].name, "tls.myprivkey")) { pData->myPrivKeyFile = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); fp = fopen((const char *)pData->myPrivKeyFile, "r"); if (fp == NULL) { rs_strerror_r(errno, errStr, sizeof(errStr)); LogError(0, RS_RET_NO_FILE_ACCESS, "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n", pData->myPrivKeyFile, errStr); } else { fclose(fp); } } else if (!strcmp(actpblk.descr[i].name, "reloadonhup")) { pData->reloadOnHup = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "httpretrycodes")) { pData->nhttpRetryCodes = pvals[i].val.d.ar->nmemb; // note: use zero as sentinel value CHKmalloc(pData->httpRetryCodes = calloc(pvals[i].val.d.ar->nmemb, sizeof(unsigned int))); int count = 0; for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { int bSuccess = 0; long long n = es_str2num(pvals[i].val.d.ar->arr[j], &bSuccess); if (!bSuccess) { char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); LogError(0, RS_RET_NO_FILE_ACCESS, "error: 'httpRetryCode' '%s' is not a number - ignored\n", cstr); free(cstr); } else { pData->httpRetryCodes[count++] = n; } } } else if (!strcmp(actpblk.descr[i].name, "retry")) { pData->retryFailures = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "retry.ruleset")) { pData->retryRulesetName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "retry.addmetadata")) { pData->retryAddMetadata = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ratelimit.burst")) { pData->ratelimitBurst = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ratelimit.interval")) { pData->ratelimitInterval = (unsigned int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "name")) { pData->statsName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "httpignorablecodes")) { pData->nIgnorableCodes = pvals[i].val.d.ar->nmemb; // note: use zero as sentinel value CHKmalloc(pData->ignorableCodes = calloc(pvals[i].val.d.ar->nmemb, sizeof(unsigned int))); int count = 0; for (int j = 0; j < pvals[i].val.d.ar->nmemb; ++j) { int bSuccess = 0; long long n = es_str2num(pvals[i].val.d.ar->arr[j], &bSuccess); if (!bSuccess) { char *cstr = es_str2cstr(pvals[i].val.d.ar->arr[j], NULL); LogError(0, RS_RET_NO_FILE_ACCESS, "error: 'httpIgnorableCodes' '%s' is not a number - ignored\n", cstr); free(cstr); } else { pData->ignorableCodes[count++] = n; } } } else if (!strcmp(actpblk.descr[i].name, "profile")) { profileName = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "statsbysenders")) { pData->statsBySenders = pvals[i].val.d.n; } else { LogError(0, RS_RET_INTERNAL_ERROR, "omhttp: program error, " "non-handled param '%s'", actpblk.descr[i].name); } } if (pData->pwd != NULL && pData->uid == NULL) { LogError(0, RS_RET_UID_MISSING, "omhttp: password is provided, but no uid " "- action definition invalid"); ABORT_FINALIZE(RS_RET_UID_MISSING); } if (pData->httpheaderkey != NULL && pData->httpheadervalue == NULL) { LogError(0, RS_RET_UID_MISSING, "omhttp: http header key is provided, but no http header value " "- action definition invalid"); ABORT_FINALIZE(RS_RET_UID_MISSING); } if (pData->dynRestPath && pData->restPath == NULL) { LogError(0, RS_RET_CONFIG_ERROR, "omhttp: requested dynamic rest path, but no name for rest " "path template given - action definition invalid"); ABORT_FINALIZE(RS_RET_CONFIG_ERROR); } /* Apply header before profile */ if (pData->httpcontenttype != NULL) CHKiRet(computeApiHeader((char *)"Content-Type", (char *)pData->httpcontenttype, &pData->headerContentTypeBuf)); if (pData->httpheaderkey != NULL) CHKiRet(computeApiHeader((char *)pData->httpheaderkey, (char *)pData->httpheadervalue, &pData->headerBuf)); /* Apply profile settings if specified */ if (profileName != NULL) { CHKiRet(applyProfileSettings(pData, profileName)); free(profileName); profileName = NULL; } if (pData->proxyHost == NULL) { const char *http_proxy; if ((http_proxy = getenv("http_proxy")) == NULL) { http_proxy = getenv("HTTP_PROXY"); } if (http_proxy != NULL) { pData->proxyHost = ustrdup(http_proxy); } } if (pData->uid != NULL) CHKiRet(computeAuthHeader((char *)pData->uid, (char *)pData->pwd, &pData->authBuf)); iNumTpls = 1; if (pData->dynRestPath) ++iNumTpls; DBGPRINTF("omhttp: requesting %d templates\n", iNumTpls); CODE_STD_STRING_REQUESTnewActInst(iNumTpls); CHKiRet(OMSRsetEntry(*ppOMSR, 0, (uchar *)strdup((pData->tplName == NULL) ? " StdJSONFmt" : (char *)pData->tplName), OMSR_NO_RQD_TPL_OPTS)); /* we need to request additional templates. If we have a dynamic search index, * it will always be string 1. Type may be 1 or 2, depending on whether search * index is dynamic as well. Rule needs to be followed throughout the module. */ iNumTpls = 1; if (pData->dynRestPath) { CHKiRet(OMSRsetEntry(*ppOMSR, iNumTpls, ustrdup(pData->restPath), OMSR_NO_RQD_TPL_OPTS)); ++iNumTpls; } if (!pData->statsName) { uchar pszAName[64]; snprintf((char *)pszAName, sizeof(pszAName), "omhttp-%d", omhttpInstancesCnt); pData->statsName = ustrdup(pszAName); } if (servers != NULL) { pData->numServers = servers->nmemb; pData->serverBaseUrls = malloc(servers->nmemb * sizeof(uchar *)); if (pData->serverBaseUrls == NULL) { LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " "for http server configuration."); ABORT_FINALIZE(RS_RET_ERR); } /* Set up the stats object array */ const int numStats = pData->statsBySenders ? servers->nmemb : 1; pData->listObjStats = malloc(numStats * sizeof(targetStats_t)); if (pData->listObjStats == NULL) { LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " "for http server stats object."); ABORT_FINALIZE(RS_RET_ERR); } if (!pData->statsBySenders) { CHKiRet(setStatsObject(pData, NULL, 0)); } for (i = 0; i < servers->nmemb; ++i) { serverParam = es_str2cstr(servers->arr[i], NULL); if (serverParam == NULL) { LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " "for http server configuration."); ABORT_FINALIZE(RS_RET_ERR); } /* Remove a trailing slash if it exists */ const size_t serverParamLastChar = strlen(serverParam) - 1; if (serverParam[serverParamLastChar] == '/') { serverParam[serverParamLastChar] = '\0'; } if (pData->statsBySenders) { CHKiRet(setStatsObject(pData, serverParam, i)); } CHKiRet(computeBaseUrl(serverParam, pData->defaultPort, pData->useHttps, pData->serverBaseUrls + i)); free(serverParam); serverParam = NULL; } } else { LogMsg(0, RS_RET_OK, LOG_WARNING, "omhttp: No servers specified, using localhost"); pData->numServers = 1; pData->serverBaseUrls = malloc(sizeof(uchar *)); if (pData->serverBaseUrls == NULL) { LogError(0, RS_RET_ERR, "omhttp: unable to allocate buffer " "for http server configuration."); ABORT_FINALIZE(RS_RET_ERR); } CHKiRet(computeBaseUrl("localhost", pData->defaultPort, pData->useHttps, pData->serverBaseUrls)); } if (pData->retryFailures) { CHKiRet(ratelimitNew(&pData->ratelimiter, "omhttp", NULL)); ratelimitSetLinuxLike(pData->ratelimiter, pData->ratelimitInterval, pData->ratelimitBurst); ratelimitSetNoTimeCache(pData->ratelimiter); } /* node created, let's add to list of instance configs for the module */ if (loadModConf->tail == NULL) { loadModConf->tail = loadModConf->root = pData; } else { loadModConf->tail->next = pData; loadModConf->tail = pData; } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); if (serverParam) free(serverParam); if (profileName) free(profileName); ENDnewActInst BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; pModConf->root = pModConf->tail = NULL; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ ENDendCnfLoad BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = pModConf->root; inst != NULL; inst = inst->next) { ruleset_t *pRuleset; rsRetVal localRet; if (inst->retryRulesetName) { localRet = ruleset.GetRuleset(pModConf->pConf, &pRuleset, inst->retryRulesetName); if (localRet == RS_RET_NOT_FOUND) { LogError(0, localRet, "omhttp: retry.ruleset '%s' not found - " "no retry ruleset will be used", inst->retryRulesetName); } else { inst->retryRuleset = pRuleset; } } } ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf // HUP handling for the instance... BEGINdoHUP CODESTARTdoHUP; pthread_mutex_lock(&pData->mutErrFile); if (pData->fdErrFile != -1) { close(pData->fdErrFile); pData->fdErrFile = -1; } pthread_mutex_unlock(&pData->mutErrFile); ENDdoHUP // HUP handling for the worker... BEGINdoHUPWrkr CODESTARTdoHUPWrkr; if (pWrkrData->pData->reloadOnHup) { LogMsg(0, NO_ERRCODE, LOG_INFO, "omhttp: received HUP reloading curl handles"); curlCleanup(pWrkrData); CHKiRet(curlSetup(pWrkrData)); } finalize_it: ENDdoHUPWrkr BEGINmodExit CODESTARTmodExit; if (pInputName != NULL) prop.Destruct(&pInputName); curl_global_cleanup(); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(statsobj, CORE_COMPONENT); ENDmodExit NO_LEGACY_CONF_parseSelectorAct BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMODTX_QUERIES CODEqueryEtryPt_STD_OMOD8_QUERIES CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES CODEqueryEtryPt_doHUP CODEqueryEtryPt_doHUPWrkr /* Load the worker HUP handling code */ CODEqueryEtryPt_STD_CONF2_QUERIES ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; uchar *pTmp; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); if (curl_global_init(CURL_GLOBAL_ALL) != 0) { LogError(0, RS_RET_OBJ_CREATION_FAILED, "CURL fail. -http disabled"); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } /* Add custom template for Splunk endpoit RAW */ pTmp = template_StdSplkRaw; tplAddLine(ourConf, (char *)NAME_TPL_SPLK_RAW, &pTmp); /* Add custom template for Splunk endpoit EVENT */ pTmp = template_StdSplkEvent; tplAddLine(ourConf, (char *)NAME_TPL_SPLK_EVENT, &pTmp); CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("omhttp"), sizeof("omhttp") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); ENDmodInit /* vi:set ai: */ rsyslog-8.2512.0/contrib/omhttp/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316017555 xustar0030 mtime=1764935886.257011086 30 atime=1764935896.115162087 30 ctime=1764935927.430641599 rsyslog-8.2512.0/contrib/omhttp/Makefile.in0000664000175000017500000006322115114544316017225 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omhttp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omhttp_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_omhttp_la_OBJECTS = omhttp_la-omhttp.lo omhttp_la_OBJECTS = $(am_omhttp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omhttp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omhttp_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omhttp_la-omhttp.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omhttp_la_SOURCES) DIST_SOURCES = $(omhttp_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omhttp.la omhttp_la_SOURCES = omhttp.c omhttp_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) omhttp_la_LDFLAGS = -module -avoid-version omhttp_la_LIBADD = $(CURL_LIBS) $(LIBM) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhttp/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omhttp/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omhttp.la: $(omhttp_la_OBJECTS) $(omhttp_la_DEPENDENCIES) $(EXTRA_omhttp_la_DEPENDENCIES) $(AM_V_CCLD)$(omhttp_la_LINK) -rpath $(pkglibdir) $(omhttp_la_OBJECTS) $(omhttp_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhttp_la-omhttp.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omhttp_la-omhttp.lo: omhttp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhttp_la-omhttp.lo -MD -MP -MF $(DEPDIR)/omhttp_la-omhttp.Tpo -c -o omhttp_la-omhttp.lo `test -f 'omhttp.c' || echo '$(srcdir)/'`omhttp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhttp_la-omhttp.Tpo $(DEPDIR)/omhttp_la-omhttp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhttp.c' object='omhttp_la-omhttp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhttp_la-omhttp.lo `test -f 'omhttp.c' || echo '$(srcdir)/'`omhttp.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omhttp_la-omhttp.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omhttp_la-omhttp.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/pmcisconames0000644000000000000000000000013015114544365016603 xustar0029 mtime=1764935925.59061343 30 atime=1764935930.172683575 29 ctime=1764935925.59061343 rsyslog-8.2512.0/contrib/pmcisconames/0000775000175000017500000000000015114544365016326 5ustar00rgerrgerrsyslog-8.2512.0/contrib/pmcisconames/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020710 xustar0030 mtime=1752569012.331237145 30 atime=1764930929.486827014 30 ctime=1764935925.585613353 rsyslog-8.2512.0/contrib/pmcisconames/Makefile.am0000664000175000017500000000036615035412264020361 0ustar00rgerrgerpkglib_LTLIBRARIES = pmcisconames.la pmcisconames_la_SOURCES = pmcisconames.c pmcisconames_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmcisconames_la_LDFLAGS = -module -avoid-version pmcisconames_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/pmcisconames/PaxHeaders/Makefile.in0000644000000000000000000000013015114544316020721 xustar0030 mtime=1764935886.402013307 30 atime=1764935896.666170526 28 ctime=1764935925.5886134 rsyslog-8.2512.0/contrib/pmcisconames/Makefile.in0000664000175000017500000006363315114544316020402 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/pmcisconames ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) pmcisconames_la_DEPENDENCIES = am_pmcisconames_la_OBJECTS = pmcisconames_la-pmcisconames.lo pmcisconames_la_OBJECTS = $(am_pmcisconames_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pmcisconames_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(pmcisconames_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pmcisconames_la_SOURCES) DIST_SOURCES = $(pmcisconames_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = pmcisconames.la pmcisconames_la_SOURCES = pmcisconames.c pmcisconames_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmcisconames_la_LDFLAGS = -module -avoid-version pmcisconames_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmcisconames/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pmcisconames/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pmcisconames.la: $(pmcisconames_la_OBJECTS) $(pmcisconames_la_DEPENDENCIES) $(EXTRA_pmcisconames_la_DEPENDENCIES) $(AM_V_CCLD)$(pmcisconames_la_LINK) -rpath $(pkglibdir) $(pmcisconames_la_OBJECTS) $(pmcisconames_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pmcisconames_la-pmcisconames.lo: pmcisconames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmcisconames_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmcisconames_la-pmcisconames.lo -MD -MP -MF $(DEPDIR)/pmcisconames_la-pmcisconames.Tpo -c -o pmcisconames_la-pmcisconames.lo `test -f 'pmcisconames.c' || echo '$(srcdir)/'`pmcisconames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmcisconames_la-pmcisconames.Tpo $(DEPDIR)/pmcisconames_la-pmcisconames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmcisconames.c' object='pmcisconames_la-pmcisconames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmcisconames_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmcisconames_la-pmcisconames.lo `test -f 'pmcisconames.c' || echo '$(srcdir)/'`pmcisconames.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pmcisconames_la-pmcisconames.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/pmcisconames/PaxHeaders/pmcisconames.c0000644000000000000000000000013115055605325021504 xustar0030 mtime=1756826325.614800155 30 atime=1764931051.861868826 29 ctime=1764935925.59061343 rsyslog-8.2512.0/contrib/pmcisconames/pmcisconames.c0000664000175000017500000001425415055605325021157 0ustar00rgerrger/* pmcisconames.c * * this detects logs sent by Cisco devices that mangle their syslog output when you tell them to log by name * by adding ' :' between the name and the %XXX-X-XXXXXXX: tag * * instead of actually parsing the message, this modifies the message and then falls through to allow a later * parser to handle the now modified message * * created 2010-12-13 by David Lang based on pmlastmsg * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" #include "rsconf.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.cisconames") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINparse uchar *p2parse; int lenMsg; #define OpeningText ": %" CODESTARTparse; dbgprintf("Message will now be parsed by fix Cisco Names parser.\n"); assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ /* check if this message is of the type we handle in this (very limited) parser */ /* first, we permit SP */ while (lenMsg && *p2parse == ' ') { --lenMsg; ++p2parse; } if ((unsigned)lenMsg < 34) { /* too short, can not be "our" message */ /* minimum message, 16 character timestamp, 1 character name, ' : %ASA-1-000000: '*/ ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* check if the timestamp is a 16 character or 21 character timestamp 'Mmm DD HH:MM:SS ' spaces at 3,6,15 : at 9,12 'Mmm DD YYYY HH:MM:SS ' spaces at 3,6,11,20 : at 14,17 check for the : first as that will differentiate the two conditions the fastest this allows the compiler to short circuit the rst of the tests if it is the wrong timestamp but still check the rest to see if it looks correct */ if (*(p2parse + 9) == ':' && *(p2parse + 12) == ':' && *(p2parse + 3) == ' ' && *(p2parse + 6) == ' ' && *(p2parse + 15) == ' ') { /* skip over timestamp */ dbgprintf("short timestamp found\n"); lenMsg -= 16; p2parse += 16; } else { if (*(p2parse + 14) == ':' && *(p2parse + 17) == ':' && *(p2parse + 3) == ' ' && *(p2parse + 6) == ' ' && *(p2parse + 11) == ' ' && *(p2parse + 20) == ' ') { /* skip over timestamp */ dbgprintf("long timestamp found\n"); lenMsg -= 21; p2parse += 21; } else { dbgprintf("timestamp is not one of the valid formats\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } } /* now look for the next space to walk past the hostname */ while (lenMsg && *p2parse != ' ') { --lenMsg; ++p2parse; } /* Note: we deliberately count the 0-byte below because we need to go chars+1! */ if (lenMsg < (int)sizeof(OpeningText)) { dbgprintf("pmcisconames: too short for being cisco messages\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* skip the space after the hostname */ lenMsg -= 1; p2parse += 1; /* if the syslog tag is : and the next thing starts with a % assume that this is a mangled cisco log and fix it */ if (strncasecmp((char *)p2parse, OpeningText, sizeof(OpeningText) - 1) != 0) { /* wrong opening text */ DBGPRINTF("not a cisco name mangled log!\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* bump the message portion up by two characters to overwrite the extra : */ lenMsg -= 2; memmove(p2parse, p2parse + 2, lenMsg); *(p2parse + lenMsg) = '\n'; *(p2parse + lenMsg + 1) = '\0'; pMsg->iLenRawMsg -= 2; pMsg->iLenMSG -= 2; /* now, claim to abort so that something else can parse the now modified message */ DBGPRINTF("pmcisconames: new message: [%d]'%s'\n", lenMsg, p2parse); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); finalize_it: ENDparse BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); DBGPRINTF("cisconames parser init called, compiled with version %s\n", VERSION); bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); /* cache value, is set only during rsyslogd option processing */ ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/contrib/PaxHeaders/impcap0000644000000000000000000000013015114544373015372 xustar0029 mtime=1764935931.24369997 30 atime=1764935934.366747775 29 ctime=1764935931.24369997 rsyslog-8.2512.0/contrib/impcap/0000775000175000017500000000000015114544373015115 5ustar00rgerrgerrsyslog-8.2512.0/contrib/impcap/PaxHeaders/tcp_parser.c0000644000000000000000000000013215055605325017756 xustar0030 mtime=1756826325.612800125 30 atime=1764931113.587875576 30 ctime=1764935931.233699816 rsyslog-8.2512.0/contrib/impcap/tcp_parser.c0000664000175000017500000000776615055605325017442 0ustar00rgerrger/* tcp_parser.c * * This file contains functions to parse TCP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" #define SMB_PORT 445 #define HTTP_PORT 80 #define HTTP_PORT_ALT 8080 #define FTP_PORT 21 #define FTP_PORT_DATA 20 struct tcp_header_s { uint16_t srcPort; uint16_t dstPort; uint32_t seq; uint32_t ack; uint8_t dor; uint8_t flags; uint16_t windowSize; uint16_t checksum; uint16_t urgPointer; uint8_t options[]; }; typedef struct tcp_header_s tcp_header_t; static char flagCodes[10] = "FSRPAUECN"; /* * This function parses the bytes in the received packet to extract TCP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the TCP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where TCP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *tcp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("tcp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 20) { DBGPRINTF("TCP packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } /* Union to prevent cast from uchar to tcp_header_t */ union { const uchar *pck; tcp_header_t *hdr; } tcp_header_to_char; tcp_header_to_char.pck = packet; tcp_header_t *tcp_header = tcp_header_to_char.hdr; uint8_t i, pos = 0; char flags[10] = {0}; for (i = 0; i < 8; ++i) { if (tcp_header->flags & (0x01 << i)) flags[pos++] = flagCodes[i]; } if (tcp_header->dor & 0x01) flags[pos++] = flagCodes[9]; uint16_t srcPort = ntohs(tcp_header->srcPort); uint16_t dstPort = ntohs(tcp_header->dstPort); uint8_t headerLength = (tcp_header->dor & 0xF0) >> 2; //>>4 to offset but <<2 to get offset as bytes json_object_object_add(jparent, "net_src_port", json_object_new_int(srcPort)); json_object_object_add(jparent, "net_dst_port", json_object_new_int(dstPort)); json_object_object_add(jparent, "TCP_seq_number", json_object_new_int64(ntohl(tcp_header->seq))); json_object_object_add(jparent, "TCP_ack_number", json_object_new_int64(ntohl(tcp_header->ack))); json_object_object_add(jparent, "net_flags", json_object_new_string(flags)); if (srcPort == SMB_PORT || dstPort == SMB_PORT) { return smb_parse(packet + headerLength, pktSize - headerLength, jparent); } if (srcPort == FTP_PORT || dstPort == FTP_PORT || srcPort == FTP_PORT_DATA || dstPort == FTP_PORT_DATA) { return ftp_parse(packet + headerLength, pktSize - headerLength, jparent); } if (srcPort == HTTP_PORT || dstPort == HTTP_PORT || srcPort == HTTP_PORT_ALT || dstPort == HTTP_PORT_ALT) { return http_parse(packet + headerLength, pktSize - headerLength, jparent); } DBGPRINTF("tcp return after header length (%u)\n", headerLength); RETURN_DATA_AFTER(headerLength) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/ipv6_parser.c0000644000000000000000000000013115055605325020053 xustar0030 mtime=1756826325.612800125 29 atime=1764931111.04783442 30 ctime=1764935931.221699633 rsyslog-8.2512.0/contrib/impcap/ipv6_parser.c0000664000175000017500000002322715055605325017526 0ustar00rgerrger/* ipv6_parser.c * * This file contains functions to parse IPv6 headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" typedef struct __attribute__((__packed__)) ipv6_header_s { #ifndef IPV6_VERSION_MASK #define IPV6_VERSION_MASK 0xF0000000 #endif #ifndef IPV6_TC_MASK #define IPV6_TC_MASK 0x0FF00000 #endif #ifndef IPV6_FLOW_MASK #define IPV6_FLOW_MASK 0x000FFFFF #endif uint32_t vtf; uint16_t dataLength; uint8_t nextHeader; #define IPV6_NHDR_HBH 0 #define IPV6_NHDR_TCP 6 #define IPV6_NHDR_UDP 17 #define IPV6_NHDR_ENCIP6 41 #define IPV6_NHDR_ROUT 43 #define IPV6_NHDR_FRAG 44 #define IPV6_NHDR_RRSV 46 #define IPV6_NHDR_SEC 50 #define IPV6_NHDR_AUTH 51 #define IPV6_NHDR_ICMP6 58 #define IPV6_NHDR_NONHDR 59 #define IPV6_NHDR_DOPTS 60 uint8_t hopLimit; uint8_t addrSrc[16]; uint8_t addrDst[16]; } ipv6_header_t; #pragma GCC diagnostic pop #ifndef IPV6_VERSION #define IPV6_VERSION(h) (ntohl(h->vtf) & IPV6_VERSION_MASK) >> 28 #endif #ifndef IPV6_TC #define IPV6_TC(h) (ntohl(h->vtf) & IPV6_TC_MASK) >> 20 #endif #ifndef IPV6_FLOW #define IPV6_FLOW(h) (ntohl(h->vtf) & IPV6_FLOW_MASK) #endif /* extension headers */ typedef struct hbh_header_s { uint8_t nextHeader; uint8_t hLength; uint8_t *pOptions; } hbh_header_t; typedef struct dest_header_s { uint8_t nextHeader; uint8_t hLength; uint8_t *pOptions; } dest_header_t; typedef struct route_header_s { uint8_t nextHeader; uint8_t hLength; uint8_t rType; uint8_t segsLeft; uint32_t reserved; uint8_t addrs[16]; } route_header_t; typedef struct frag_header_s { uint8_t nextHeader; uint8_t reserved; uint16_t offsetFlags; uint32_t id; } frag_header_t; static inline uint8_t hbh_header_parse(const uchar **packet, int *pktSize) { DBGPRINTF("hbh_header_parse\n"); /* Union to prevent cast from uchar to hbh_header_t */ union { const uchar *pck; hbh_header_t *hdr; } hbh_header_to_char; hbh_header_to_char.pck = *packet; hbh_header_t *hbh_header = hbh_header_to_char.hdr; /* hbh_header->hLength is the number of octets of header in 8-octet units minus 1 * the header length SHOULD be a multiple of 8 */ uint8_t hByteLength = hbh_header->hLength * 8 + 8; DBGPRINTF("hByteLength: %d\n", hByteLength); *pktSize -= hByteLength; *packet += hByteLength; return hbh_header->nextHeader; } static inline uint8_t dest_header_parse(const uchar **packet, int *pktSize) { DBGPRINTF("dest_header_parse\n"); /* Union to prevent cast from uchar to dest_header_t */ union { const uchar *pck; dest_header_t *hdr; } dest_header_to_char; dest_header_to_char.pck = *packet; dest_header_t *dest_header = dest_header_to_char.hdr; /* dest_header->hLength is the number of octets of header in 8-octet units minus 1 * the header length SHOULD be a multiple of 8 */ uint8_t hByteLength = dest_header->hLength * 8 + 8; DBGPRINTF("hByteLength: %d\n", hByteLength); *pktSize -= hByteLength; *packet += hByteLength; return dest_header->nextHeader; } static inline uint8_t route_header_parse(const uchar **packet, int *pktSize, struct json_object *jparent) { DBGPRINTF("route_header_parse\n"); /* Union to prevent cast from uchar to route_header_t */ union { const uchar *pck; route_header_t *hdr; } route_header_to_char; route_header_to_char.pck = *packet; route_header_t *route_header = route_header_to_char.hdr; /* route_header->hLength is the number of octets of header in 8-octet units minus 1 * the header length (in bytes) SHOULD be a multiple of 8 */ uint8_t hByteLength = route_header->hLength * 8 + 8; *pktSize -= hByteLength; *packet += hByteLength; if (route_header->rType == 0) { json_object_object_add(jparent, "IP6_route_seg_left", json_object_new_int(route_header->segsLeft)); hByteLength -= 8; // leave only length of routing addresses char addrStr[40], routeFieldName[20]; int addrNum = 1; uint8_t *addr = &(route_header->addrs[0]); // while there is enough space for an IPv6 address while (hByteLength >= 16) { inet_ntop(AF_INET6, (void *)addr, addrStr, 40); snprintf(routeFieldName, 20, "IP6_route_%d", addrNum++); json_object_object_add(jparent, routeFieldName, json_object_new_string((char *)addrStr)); addr += 16; hByteLength -= 16; } } return route_header->nextHeader; } #define FRAG_OFFSET_MASK 0xFFF8 #define MFLAG_MASK 0x0001 static inline uint8_t frag_header_parse(const uchar **packet, int *pktSize, struct json_object *jparent) { DBGPRINTF("frag_header_parse\n"); /* Union to prevent cast from uchar to frag_header_t */ union { const uchar *pck; frag_header_t *hdr; } frag_header_to_char; frag_header_to_char.pck = *packet; frag_header_t *frag_header = frag_header_to_char.hdr; uint16_t flags = ntohs(frag_header->offsetFlags); json_object_object_add(jparent, "IP6_frag_offset", json_object_new_int((flags & FRAG_OFFSET_MASK) >> 3)); json_object_object_add(jparent, "IP6_frag_more", json_object_new_boolean(flags & MFLAG_MASK)); json_object_object_add(jparent, "IP6_frag_id", json_object_new_int64(frag_header->id)); *pktSize -= 8; *packet += 8; return frag_header->nextHeader; } /* * This function parses the bytes in the received packet to extract IPv6 metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the IPv6 header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where IPv6 metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *ipv6_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("ipv6_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 40) { /* too small for IPv6 header + data (header might be longer)*/ DBGPRINTF("IPv6 packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } ipv6_header_t *ipv6_header = (ipv6_header_t *)packet; char addrSrc[40], addrDst[40]; inet_ntop(AF_INET6, (void *)&ipv6_header->addrSrc, addrSrc, 40); inet_ntop(AF_INET6, (void *)&ipv6_header->addrDst, addrDst, 40); json_object_object_add(jparent, "net_dst_ip", json_object_new_string((char *)addrDst)); json_object_object_add(jparent, "net_src_ip", json_object_new_string((char *)addrSrc)); json_object_object_add(jparent, "net_ttl", json_object_new_int(ipv6_header->hopLimit)); uint8_t nextHeader = ipv6_header->nextHeader; packet += sizeof(ipv6_header_t); pktSize -= sizeof(ipv6_header_t); DBGPRINTF("beginning ext headers scan\n"); uint8_t hasNext = 1; do { switch (nextHeader) { case IPV6_NHDR_HBH: nextHeader = hbh_header_parse(&packet, &pktSize); break; case IPV6_NHDR_TCP: json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); return tcp_parse(packet, pktSize, jparent); case IPV6_NHDR_UDP: json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); return udp_parse(packet, pktSize, jparent); case IPV6_NHDR_ENCIP6: hasNext = 0; break; case IPV6_NHDR_ROUT: nextHeader = route_header_parse(&packet, &pktSize, jparent); break; case IPV6_NHDR_FRAG: nextHeader = frag_header_parse(&packet, &pktSize, jparent); break; case IPV6_NHDR_RRSV: hasNext = 0; break; case IPV6_NHDR_SEC: hasNext = 0; break; case IPV6_NHDR_AUTH: hasNext = 0; break; case IPV6_NHDR_ICMP6: json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); return icmp_parse(packet, pktSize, jparent); case IPV6_NHDR_NONHDR: hasNext = 0; break; case IPV6_NHDR_DOPTS: nextHeader = dest_header_parse(&packet, &pktSize); break; default: hasNext = 0; break; } } while (hasNext); json_object_object_add(jparent, "IP_proto", json_object_new_int(nextHeader)); RETURN_DATA_AFTER(0) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/smb_parser.c0000644000000000000000000000013215055605325017751 xustar0030 mtime=1756826325.612800125 30 atime=1764931114.079883546 30 ctime=1764935931.236699863 rsyslog-8.2512.0/contrib/impcap/smb_parser.c0000664000175000017500000001105015055605325017412 0ustar00rgerrger/* smb_parser.c * * This file contains functions to parse SMB (version 2 and 3) headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" /* SMB2 opCodes */ #define SMB2_NEGOTIATE 0x00 #define SMB2_SESSIONSET 0x01 #define SMB2_SESSIONLOGOFF 0x02 #define SMB2_TREECONNECT 0x03 #define SMB2_TREEDISCONNECT 0x04 #define SMB2_CREATE 0x05 #define SMB2_CLOSE 0x06 #define SMB2_FLUSH 0x07 #define SMB2_READ 0x08 #define SMB2_WRITE 0x09 #define SMB2_LOCK 0x0a #define SMB2_IOCTL 0x0b #define SMB2_CANCEL 0x0c #define SMB2_KEEPALIVE 0x0d #define SMB2_FIND 0x0e #define SMB2_NOTIFY 0x0f #define SMB2_GETINFO 0x10 #define SMB2_SETINFO 0x11 #define SMB2_BREAK 0x12 struct smb_header_s { uint32_t version; uint16_t headerLength; uint16_t padding1; uint32_t ntStatus; uint16_t opCode; uint16_t padding2; uint32_t flags; uint32_t chainOffset; uint32_t comSeqNumber[2]; uint32_t processID; uint32_t treeID; uint32_t userID[2]; uint32_t signature[4]; }; typedef struct smb_header_s smb_header_t; static char flagCodes[5] = "RPCS"; /* * This function parses the bytes in the received packet to extract SMB2 metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the beginning of the header will be checked by the function * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where SMB2 metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *smb_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("smb_parse\n"); DBGPRINTF("packet size %d\n", pktSize); int pktSizeCpy = pktSize; const uchar *packetCpy = packet; while (pktSizeCpy > 0) { /* don't check packetCpy[0] to include SMB version byte at the beginning */ if (packetCpy[1] == 'S') { if (packetCpy[2] == 'M') { if (packetCpy[3] == 'B') { break; } } } packetCpy++, pktSizeCpy--; } if ((int)pktSizeCpy < 64) { DBGPRINTF("SMB packet too small : %d\n", pktSizeCpy); RETURN_DATA_AFTER(0) } /* Union to prevent cast from uchar to smb_header_t */ union { const uchar *pck; smb_header_t *hdr; } smb_header_to_char; smb_header_to_char.pck = packetCpy; smb_header_t *smb_header = smb_header_to_char.hdr; char flags[5] = {0}; uint64_t seqNum, userID; uint8_t version; version = (smb_header->version == 0xFF) ? 1 : 2; seqNum = smb_header->comSeqNumber[0] | smb_header->comSeqNumber[1] << 16; userID = smb_header->userID[0] | smb_header->userID[1] << 16; uint8_t i, pos = 0; for (i = 0; i < 4; ++i) { if (smb_header->flags & (0x01 << i)) flags[pos++] = flagCodes[i]; } json_object_object_add(jparent, "SMB_version", json_object_new_int(version)); json_object_object_add(jparent, "SMB_NTstatus", json_object_new_int64(smb_header->ntStatus)); json_object_object_add(jparent, "SMB_operation", json_object_new_int(smb_header->opCode)); json_object_object_add(jparent, "SMB_flags", json_object_new_string(flags)); json_object_object_add(jparent, "SMB_seqNumber", json_object_new_int64(seqNum)); json_object_object_add(jparent, "SMB_processID", json_object_new_int64(smb_header->processID)); json_object_object_add(jparent, "SMB_treeID", json_object_new_int64(smb_header->treeID)); json_object_object_add(jparent, "SMB_userID", json_object_new_int64(userID)); RETURN_DATA_AFTER(0) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/ftp_parser.c0000644000000000000000000000013115055605325017760 xustar0029 mtime=1756826325.61180011 30 atime=1764931114.583891709 30 ctime=1764935931.238699893 rsyslog-8.2512.0/contrib/impcap/ftp_parser.c0000664000175000017500000001064415055605325017432 0ustar00rgerrger/* ftp_parser.c * * This file contains functions to parse FTP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" static const int ftp_cds[] = {100, 110, 120, 125, 150, 200, 202, 211, 212, 213, 214, 215, 220, 221, 225, 226, 227, 228, 229, 230, 231, 232, 250, 257, 300, 331, 332, 350, 400, 421, 425, 426, 430, 434, 450, 451, 452, 500, 501, 502, 503, 504, 530, 532, 550, 551, 552, 553, 600, 631, 632, 633, 10000, 100054, 10060, 10061, 10066, 10068, 0}; static const char *ftp_cmds[] = {"STOR", "TYPE", "ABOR", "ACCT", "ALLO", "APPE", "CDUP", "CWD", "DELE", "HELP", "LIST", "MKD", "MODE", "NLST", "NOOP", "PASS", "PASV", "PORT", "PWD", "QUIT", "REIN", "REST", "RETR", "RMD", "RNFR", "RNTO", "SITE", "SMNT", "STAT", "STOU", "STRU", "SYST", "USER", NULL}; /* * This function searches for a valid command in the header (from the list defined in ftp_cmds[]) * and returns either the command or a NULL pointer */ static const char *check_Command_ftp(uchar *first_part_packet) { DBGPRINTF("in check_Command_ftp\n"); DBGPRINTF("first_part_packet : '%s' \n", first_part_packet); int i = 0; for (i = 0; ftp_cmds[i] != NULL; i++) { if (strncmp((const char *)first_part_packet, ftp_cmds[i], strlen((const char *)ftp_cmds[i]) + 1) == 0) { return ftp_cmds[i]; } } return "UNKNOWN"; } /* * This function searches for a valid code in the header (from the list defined in ftp_cds[]) * and returns either the command or a NULL pointer */ static int check_Code_ftp(uchar *first_part_packet) { DBGPRINTF("in check_Code_ftp\n"); DBGPRINTF("first_part_packet : %s \n", first_part_packet); int i = 0; for (i = 0; ftp_cds[i] != 0; i++) { if (strtol((const char *)first_part_packet, NULL, 10) == ftp_cds[i]) { return ftp_cds[i]; } } return 0; } /* * This function parses the bytes in the received packet to extract FTP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the FTP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where FTP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *ftp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("ftp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 5) { /* too short for ftp packet*/ RETURN_DATA_AFTER(0) } uchar *packet2 = (uchar *)malloc(pktSize * sizeof(uchar)); memcpy(packet2, packet, pktSize); // strtok changes original packet uchar *frst_part_ftp; frst_part_ftp = (uchar *)strtok((char *)packet2, " "); // Get first part of packet ftp strtok(NULL, "\r\n"); if (frst_part_ftp) { int code = check_Code_ftp(frst_part_ftp); const char *command = check_Command_ftp(frst_part_ftp); if (code != 0) { json_object_object_add(jparent, "FTP_response", json_object_new_int(code)); } else if (command != NULL) { json_object_object_add(jparent, "FTP_request", json_object_new_string(command)); } } free(packet2); RETURN_DATA_AFTER(0) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/http_parser.c0000644000000000000000000000013115055605325020146 xustar0029 mtime=1756826325.61180011 30 atime=1764931115.094899984 30 ctime=1764935931.240699924 rsyslog-8.2512.0/contrib/impcap/http_parser.c0000664000175000017500000001132115055605325017611 0ustar00rgerrger/* http_parser.c * * This file contains functions to parse HTTP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" static const char *keywords[] = {"OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", "HTTP", NULL}; static inline char *string_split(char **initString, const char *delimiterString) { char *ret = *initString; if (*initString) { char *pos = strstr(*initString, delimiterString); if (pos) { *initString = pos; **initString = '\0'; *initString += strlen(delimiterString); } else { *initString = NULL; } } return ret; } static inline int has_status_keyword(char *http) { const char *found; int i; for (i = 0; keywords[i] != NULL; i++) { found = strstr(http, keywords[i]); if (found && (found - http) < 20) { return 1; } } return 0; } /* * This function catches HTTP header fields and status line * and adds them to the provided json object */ static inline void catch_status_and_fields(char *header, struct json_object *jparent) { DBGPRINTF("catch_status_and_fields\n"); struct json_object *fields = json_object_new_object(); char *statusLine = string_split(&header, "\r\n"); char *firstPart, *secondPart, *thirdPart; firstPart = string_split(&statusLine, " "); secondPart = string_split(&statusLine, " "); thirdPart = statusLine; if (firstPart && secondPart && thirdPart) { if (strstr(firstPart, "HTTP")) { json_object_object_add(jparent, "HTTP_version", json_object_new_string(firstPart)); json_object_object_add(jparent, "HTTP_status_code", json_object_new_string(secondPart)); json_object_object_add(jparent, "HTTP_reason", json_object_new_string(thirdPart)); } else { json_object_object_add(jparent, "HTTP_method", json_object_new_string(firstPart)); json_object_object_add(jparent, "HTTP_request_URI", json_object_new_string(secondPart)); json_object_object_add(jparent, "HTTP_version", json_object_new_string(thirdPart)); } } char *fieldValue = string_split(&header, "\r\n"); char *field, *value; while (fieldValue) { field = string_split(&fieldValue, ":"); value = fieldValue; if (value) { while (*value == ' ') { value++; } DBGPRINTF("got header field -> '%s': '%s'\n", field, value); json_object_object_add(fields, field, json_object_new_string(value)); } fieldValue = string_split(&header, "\r\n"); } json_object_object_add(jparent, "HTTP_header_fields", fields); return; } /* * This function parses the bytes in the received packet to extract HTTP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the beginning of the header will be checked by the function * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where HTTP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *http_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("http_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 6) { RETURN_DATA_AFTER(0) } char *pHttp = malloc(pktSize + 1); char *http = pHttp; memcpy(http, packet, pktSize); *(http + pktSize) = '\0'; if (!has_status_keyword(http)) { free(pHttp); RETURN_DATA_AFTER(0) } char *header = string_split(&http, "\r\n\r\n"); catch_status_and_fields(header, jparent); free(pHttp); RETURN_DATA_AFTER(0) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/Makefile.am0000644000000000000000000000013115055602573017505 xustar0029 mtime=1756824955.96045048 30 atime=1764930927.942800813 30 ctime=1764935931.204699373 rsyslog-8.2512.0/contrib/impcap/Makefile.am0000664000175000017500000000123615055602573017154 0ustar00rgerrgerpkglib_LTLIBRARIES = impcap.la impcap_la_SOURCES = impcap.c impcap_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) impcap_la_LDFLAGS = -module -avoid-version impcap_la_LIBADD = -lpcap impcap_la_SOURCES += arp_parser.c impcap_la_SOURCES += eth_parser.c impcap_la_SOURCES += icmp_parser.c impcap_la_SOURCES += ipv4_parser.c impcap_la_SOURCES += ipv6_parser.c impcap_la_SOURCES += ipx_parser.c impcap_la_SOURCES += llc_parser.c impcap_la_SOURCES += udp_parser.c impcap_la_SOURCES += dns_parser.c impcap_la_SOURCES += tcp_parser.c impcap_la_SOURCES += smb_parser.c impcap_la_SOURCES += ftp_parser.c impcap_la_SOURCES += http_parser.c EXTRA_DIST=parsers.h rsyslog-8.2512.0/contrib/impcap/PaxHeaders/ipx_parser.c0000644000000000000000000000013215055605325017770 xustar0030 mtime=1756826325.612800125 30 atime=1764931111.564842798 30 ctime=1764935931.224699679 rsyslog-8.2512.0/contrib/impcap/ipx_parser.c0000664000175000017500000000731015055605325017435 0ustar00rgerrger/* ipx_parser.c * * This file contains functions to parse IPX (Novell) headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" struct __attribute__((__packed__)) ipx_header_s { uint16_t chksum; uint16_t pktLen; uint8_t transCtrl; uint8_t type; uint32_t dstNet; uint8_t dstNode[6]; uint16_t dstSocket; uint32_t srcNet; uint8_t srcNode[6]; uint16_t srcSocket; }; #pragma GCC diagnostic pop typedef struct ipx_header_s ipx_header_t; /* * This function parses the bytes in the received packet to extract IPX metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the IPX header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where IPX metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *ipx_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("entered ipx_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 30) { /* too short for IPX header */ DBGPRINTF("IPX packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } char ipxSrcNode[20], ipxDstNode[20]; ipx_header_t *ipx_header = (ipx_header_t *)packet; snprintf(ipxDstNode, sizeof(ipxDstNode), "%02x:%02x:%02x:%02x:%02x:%02x", ipx_header->dstNode[0], ipx_header->dstNode[1], ipx_header->dstNode[2], ipx_header->dstNode[3], ipx_header->dstNode[4], ipx_header->dstNode[5]); snprintf(ipxSrcNode, sizeof(ipxSrcNode), "%02x:%02x:%02x:%02x:%02x:%02x", ipx_header->srcNode[0], ipx_header->srcNode[1], ipx_header->srcNode[2], ipx_header->srcNode[3], ipx_header->srcNode[4], ipx_header->srcNode[5]); json_object_object_add(jparent, "IPX_transCtrl", json_object_new_int(ipx_header->transCtrl)); json_object_object_add(jparent, "IPX_type", json_object_new_int(ipx_header->type)); json_object_object_add(jparent, "IPX_dest_net", json_object_new_int(ntohl(ipx_header->dstNet))); json_object_object_add(jparent, "IPX_src_net", json_object_new_int(ntohl(ipx_header->srcNet))); json_object_object_add(jparent, "IPX_dest_node", json_object_new_string(ipxDstNode)); json_object_object_add(jparent, "IPX_src_node", json_object_new_string(ipxSrcNode)); json_object_object_add(jparent, "IPX_dest_socket", json_object_new_int(ntohs(ipx_header->dstSocket))); json_object_object_add(jparent, "IPX_src_socket", json_object_new_int(ntohs(ipx_header->srcSocket))); RETURN_DATA_AFTER(30) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/dns_parser.c0000644000000000000000000000013115055605325017753 xustar0029 mtime=1756826325.61180011 30 atime=1764931113.068867169 30 ctime=1764935931.231699786 rsyslog-8.2512.0/contrib/impcap/dns_parser.c0000664000175000017500000003463615055605325017434 0ustar00rgerrger/* dns_parser.c * * This file contains functions to parse DNS headers. * * File begun on 2018-11-13 * * Created by: * - Kevin Guillemot (kevin.guillemot@advens.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" /* List of RCodes defined in RFC6895 : https://tools.ietf.org/html/rfc6895 */ static const char *dns_rcodes[] = {"NoError", // 0 "FormErr", // 1 "ServFail", // 2 "NXDomain", // 3 "NotImp", // 4 "Refused", // 5 "YXDomain", // 6 "YXRRSet", // 7 "NXRRSet", // 8 "NotAuth", // 9 "NotZone", // 10 "", // 11 - Reserved "", // 12 - Reserved "", // 13 - Reserved "", // 14 - Reserved "", // 15 - Reserved "BADVERS|BADSIG", // 16 "BADKEY", // 17 "BADTIME", // 18 "BADMODE", // 19 "BADNAME", // 20 "BADALG", // 21 "BADTRUNC", // 22 /* Reserved for private use */ NULL}; /* List of record types (maybe not complete) */ static const char *dns_types[] = {0, "A", // 1 "NS", // 2 "MD", // 3 "MF", // 4 "CNAME", // 5 "SOA", // 6 "MB", // 7 "MG", // 8 "MR", // 9 "NULL", // 10 "WKS", // 11 "PTR", // 12 "HINFO", // 13 "MINFO", // 14 "MX", // 15 "TXT", // 16 "RP", // 17 "AFSDB", // 18 "X25", // 19 "ISDN", // 20 "RT", // 21 "NSAP", // 22 "NSAP-PTR", // 23 "SIG", // 24 "KEY", // 25 "PX", // 26 "GPOS", // 27 "AAAA", // 28 "LOC", // 29 "NXT", // 30 "EID", // 31 "NIMLOC", // 32 "SRV", // 33 "ATMA", // 34 "NAPTR", // 35 "KX", // 36 "CERT", // 37 "A6", // 38 "DNAME", // 39 "SINK", // 40 "OPT", // 41 "APL", // 42 "DS", // 43 "SSHFP", // 44 "IPSECKEY", // 45 "RRSIG", // 46 "NSEC", // 47 "DNSKEY", // 48 "DHCID", // 49 "NSEC3", // 50 "NSEC3PARAM", // 51 "TLSA", // 51 "SMIMEA", // 52 "Unassigned", // 53 "HIP", // 53 "NINFO", // 54 "RKEY", // 55 "TALINK", // 56 "CDS", // 57 "CDNSKEY", // 58 "OPENPGPKEY", // 59 "CSYNC", // 60 "ZONEMD", // 61 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "SPF", // 99 "UINFO", // 100 "UID", // 101 "GID", // 102 "UNSPEC", // 103 "NID", // 104 "L32", // 105 "L64", // 106 "LP", // 107 "EUI48", // 108 "EUI64", // 109 /* Reserved for private use */ NULL}; /* Part 2, since 249. To prevent useless large buffer in memory */ static const char *dns_types2[] = {"TKEY", "TSIG", "IXFR", "AXFR", "MAILB", "MAILA", "*", "URI", "CAA", "AVC", "DOA", "AMTRELAY", NULL}; /* Part 3, since 32768. To prevent useless large buffer in memory */ static const char *dns_types3[] = {"TA", "DLV", NULL}; /* This function takes an integer as parameter * and returns the corresponding string type of DNS query */ static const char *get_type(uint16_t x) { const char **types = NULL; uint16_t len_types3 = (sizeof(dns_types3) / sizeof(char *)) - 1; uint16_t len_types2 = (sizeof(dns_types2) / sizeof(char *)) - 1; uint16_t len_types = (sizeof(dns_types) / sizeof(char *)) - 1; if (x >= 32768 && x < 32768 + len_types3) { types = dns_types3; x -= 32768; } else if (x >= 249 && x < 249 + len_types2) { types = dns_types2; x -= 249; } else if (x > 0 && x < len_types) types = dns_types; else return "UNKNOWN"; if (types[x] != NULL) return types[x]; return "UNKNOWN"; } /* This function takes an integer as parameter * and returns the corresponding string class of DNS query */ static const char *get_class(uint16_t x) { switch (x) { case 1: return "IN"; case 3: return "CH"; case 4: return "HS"; case 254: return "QCLASS NONE"; case 255: return "QCLASS *"; default: // No action needed for other cases break; } return "UNKNOWN"; } /* * This function parses the bytes in the received packet to extract DNS metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where DNS metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *dns_parse(const uchar *packet, int pktSize, struct json_object *jparent) { const uchar *packet_ptr = packet; const uchar *end_packet = packet + pktSize; DBGPRINTF("dns_parse\n"); DBGPRINTF("packet size %d\n", pktSize); /* Union to prevent cast from uchar to smb_header_t */ union { unsigned short int *two_bytes; const uchar *pckt; } union_short_int; /* Get transaction id */ union_short_int.pckt = packet_ptr; unsigned short int transaction_id = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("transaction_id = %02x \n", transaction_id); union_short_int.pckt += 2; /* Get flags */ unsigned short int flags = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("flags = %02x \n", flags); /* Get response flag */ unsigned short int response_flag = (flags >> 15) & 0b1; // Get the left bit // DBGPRINTF("response_flag = %02x \n", response_flag); /* Get Opcode */ unsigned short int opcode = (flags >> 11) & 0b1111; // DBGPRINTF("opcode = %02x \n", opcode); /* Verify Z: reserved bit */ unsigned short int reserved = (flags >> 6) & 0b1; // DBGPRINTF("reserved = %02x \n", reserved); /* Reserved bit MUST be 0 */ if (reserved != 0) { DBGPRINTF("DNS packet reserved bit (Z) is not 0, aborting message. \n"); RETURN_DATA_AFTER(0) } /* Get reply code : 4 last bits */ unsigned short int reply_code = flags & 0b1111; // DBGPRINTF("reply_code = %02x \n", reply_code); union_short_int.pckt += 2; /* Get QDCOUNT */ unsigned short int query_count = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("query_count = %02x \n", query_count); union_short_int.pckt += 2; /* Get ANCOUNT */ unsigned short int answer_count = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("answer_count = %02x \n", answer_count); union_short_int.pckt += 2; /* Get NSCOUNT */ unsigned short int authority_count = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("authority_count = %02x \n", authority_count); union_short_int.pckt += 2; /* Get ARCOUNT */ unsigned short int additionnal_count = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("additionnal_count = %02x \n", additionnal_count); union_short_int.pckt += 2; packet_ptr = union_short_int.pckt; fjson_object *queries = NULL; if ((queries = json_object_new_array()) == NULL) { DBGPRINTF("impcap::dns_parser: Cannot create new json array. Stopping.\n"); RETURN_DATA_AFTER(0) } // For each query of query_count int query_cpt = 0; while (query_cpt < query_count && packet_ptr < end_packet) { size_t query_size = strnlen((const char *)packet_ptr, (size_t)(end_packet - packet_ptr)); // Check if query is valid (max 255 bytes, plus a '\0') if (query_size >= 256) { DBGPRINTF("impcap::dns_parser: Length of domain queried is > 255. Stopping.\n"); break; } // Check if remaining data is enough to hold query + '\0' + 4 bytes (QTYPE and QCLASS fields) if (query_size + 5 > (size_t)(end_packet - packet_ptr)) { DBGPRINTF("impcap::dns_parser: packet size too small to parse query. Stopping.\n"); break; } fjson_object *query = NULL; if ((query = json_object_new_object()) == NULL) { DBGPRINTF("impcap::dns_parser: Cannot create new json object. Stopping.\n"); break; } char domain_query[256] = {0}; uchar nb_char = *packet_ptr; packet_ptr++; size_t cpt = 0; while (cpt + 1 < query_size) { if (nb_char == 0) { nb_char = *packet_ptr; domain_query[cpt] = '.'; } else { domain_query[cpt] = (char)*packet_ptr; nb_char--; } cpt++; packet_ptr++; } domain_query[cpt] = '\0'; if (cpt) packet_ptr++; // pass the last \0, only if query was not empty // DBGPRINTF("Requested domain : '%s' \n", domain_query); /* Register the name in dict */ json_object_object_add(query, "qname", json_object_new_string(domain_query)); /* Get QTYPE */ union_short_int.pckt = packet_ptr; unsigned short int qtype = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("qtype = %02x \n", qtype); json_object_object_add(query, "qtype", json_object_new_int((int)qtype)); json_object_object_add(query, "type", json_object_new_string(get_type(qtype))); union_short_int.pckt += 2; /* Retrieve QCLASS */ unsigned short int qclass = ntohs(*(union_short_int.two_bytes)); // DBGPRINTF("qclass = %02x \n", qclass); json_object_object_add(query, "qclass", json_object_new_int((int)qclass)); json_object_object_add(query, "class", json_object_new_string(get_class(qclass))); packet_ptr = union_short_int.pckt + 2; /* Register the query in json array */ json_object_array_add(queries, query); query_cpt++; } json_object_object_add(jparent, "DNS_transaction_id", json_object_new_int((int)transaction_id)); json_bool is_reponse = FALSE; if (response_flag) is_reponse = TRUE; json_object_object_add(jparent, "DNS_response_flag", json_object_new_boolean(is_reponse)); json_object_object_add(jparent, "DNS_opcode", json_object_new_int(opcode)); json_object_object_add(jparent, "DNS_rcode", json_object_new_int((int)reply_code)); json_object_object_add(jparent, "DNS_error", json_object_new_string(dns_rcodes[reply_code])); json_object_object_add(jparent, "DNS_QDCOUNT", json_object_new_int((int)query_count)); json_object_object_add(jparent, "DNS_ANCOUNT", json_object_new_int((int)answer_count)); json_object_object_add(jparent, "DNS_NSCOUNT", json_object_new_int((int)authority_count)); json_object_object_add(jparent, "DNS_ARCOUNT", json_object_new_int((int)additionnal_count)); json_object_object_add(jparent, "DNS_Names", queries); /* Packet has been successfully parsed, there still can be some responses left, but do not process them */ RETURN_DATA_AFTER(0); } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/arp_parser.c0000644000000000000000000000013115055605325017751 xustar0029 mtime=1756826325.61180011 30 atime=1764931109.043801932 30 ctime=1764935931.212699495 rsyslog-8.2512.0/contrib/impcap/arp_parser.c0000664000175000017500000001430115055605325017415 0ustar00rgerrger/* arp_parser.c * * This file contains functions to parse ARP and RARP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" struct arp_header_s { uint16_t hwType; uint16_t pType; uint8_t hwAddrLen; uint8_t pAddrLen; uint16_t opCode; uint8_t pAddr[]; }; typedef struct arp_header_s arp_header_t; /* * This function parses the bytes in the received packet to extract ARP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the ARP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where ARP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *arp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("arp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 28) { /* too small for ARP header*/ DBGPRINTF("ARP packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0); } /* Union to prevent cast from uchar to arp_header_t */ union { const uchar *pck; arp_header_t *hdr; } arp_header_to_char; arp_header_to_char.pck = packet; arp_header_t *arp_header = arp_header_to_char.hdr; char pAddrSrc[20], pAddrDst[20]; json_object_object_add(jparent, "ARP_hwType", json_object_new_int(ntohs(arp_header->hwType))); json_object_object_add(jparent, "ARP_pType", json_object_new_int(ntohs(arp_header->pType))); json_object_object_add(jparent, "ARP_op", json_object_new_int(ntohs(arp_header->opCode))); if (ntohs(arp_header->hwType) == 1) { /* ethernet addresses */ char hwAddrSrc[20], hwAddrDst[20]; ether_ntoa_r((struct ether_addr *)arp_header->pAddr, hwAddrSrc); ether_ntoa_r((struct ether_addr *)(arp_header->pAddr + arp_header->hwAddrLen + arp_header->pAddrLen), hwAddrDst); json_object_object_add(jparent, "ARP_hwSrc", json_object_new_string((char *)hwAddrSrc)); json_object_object_add(jparent, "ARP_hwDst", json_object_new_string((char *)hwAddrDst)); } if (ntohs(arp_header->pType) == ETHERTYPE_IP) { inet_ntop(AF_INET, (void *)(arp_header->pAddr + arp_header->hwAddrLen), pAddrSrc, 20); inet_ntop(AF_INET, (void *)(arp_header->pAddr + 2 * arp_header->hwAddrLen + arp_header->pAddrLen), pAddrDst, 20); json_object_object_add(jparent, "ARP_pSrc", json_object_new_string((char *)pAddrSrc)); json_object_object_add(jparent, "ARP_pDst", json_object_new_string((char *)pAddrDst)); } RETURN_DATA_AFTER(28); } /* * This function parses the bytes in the received packet to extract RARP metadata. * This is a copy of ARP handler, as structure is the same but protocol code and name are different * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the RARP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where RARP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *rarp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("rarp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 28) { /* too small for RARP header*/ DBGPRINTF("RARP packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0); } /* Union to prevent cast from uchar to arp_header_t */ union { const uchar *pck; arp_header_t *hdr; } arp_header_to_char; arp_header_to_char.pck = packet; arp_header_t *rarp_header = arp_header_to_char.hdr; char pAddrSrc[20], pAddrDst[20]; json_object_object_add(jparent, "RARP_hwType", json_object_new_int(ntohs(rarp_header->hwType))); json_object_object_add(jparent, "RARP_pType", json_object_new_int(ntohs(rarp_header->pType))); json_object_object_add(jparent, "RARP_op", json_object_new_int(ntohs(rarp_header->opCode))); if (ntohs(rarp_header->hwType) == 1) { /* ethernet addresses */ char *hwAddrSrc = ether_ntoa((struct ether_addr *)rarp_header->pAddr); char *hwAddrDst = ether_ntoa((struct ether_addr *)(rarp_header->pAddr + rarp_header->hwAddrLen + rarp_header->pAddrLen)); json_object_object_add(jparent, "RARP_hwSrc", json_object_new_string((char *)hwAddrSrc)); json_object_object_add(jparent, "RARP_hwDst", json_object_new_string((char *)hwAddrDst)); } if (ntohs(rarp_header->pType) == ETHERTYPE_IP) { inet_ntop(AF_INET, (void *)(rarp_header->pAddr + rarp_header->hwAddrLen), pAddrSrc, 20); inet_ntop(AF_INET, (void *)(rarp_header->pAddr + 2 * rarp_header->hwAddrLen + rarp_header->pAddrLen), pAddrDst, 20); json_object_object_add(jparent, "RARP_pSrc", json_object_new_string((char *)pAddrSrc)); json_object_object_add(jparent, "RARP_pDst", json_object_new_string((char *)pAddrDst)); } RETURN_DATA_AFTER(28); } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/llc_parser.c0000644000000000000000000000013115055605325017741 xustar0030 mtime=1756826325.612800125 30 atime=1764931112.060850837 29 ctime=1764935931.22669971 rsyslog-8.2512.0/contrib/impcap/llc_parser.c0000664000175000017500000000740315055605325017412 0ustar00rgerrger/* llc_parser.c * * This file contains functions to parse llc headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" /* * This function parses the bytes in the received packet to extract LLC metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the LLC header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where LLC metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *llc_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("entered llc_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 3) { /* too short for llc header */ DBGPRINTF("LLC packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } uint8_t dsapField, dsap, ssapField, ssap; uint16_t ctrl; uint8_t headerLen; dsapField = (uint8_t)packet[0]; ssapField = (uint8_t)packet[1]; DBGPRINTF("dsapField : %02X\n", dsapField); DBGPRINTF("ssapField : %02X\n", ssapField); if (dsapField == 0xff && ssapField == 0xff) { /* this is an IPX packet, without LLC */ return ipx_parse(packet, pktSize, jparent); } if ((packet[2] & 0x03) == 3) { /* U frame: LLC control is 8 bits */ ctrl = (uint8_t)packet[2]; headerLen = 3; } else { /* I and S data frames: LLC control is 16 bits */ ctrl = ntohs((uint16_t)packet[2]); headerLen = 4; } /* don't take last bit into account */ dsap = dsapField & 0xfe; ssap = ssapField & 0xfe; json_object_object_add(jparent, "LLC_dsap", json_object_new_int(dsap)); json_object_object_add(jparent, "LLC_ssap", json_object_new_int(ssap)); json_object_object_add(jparent, "LLC_ctrl", json_object_new_int(ctrl)); if (dsap == 0xaa && ssap == 0xaa && ctrl == 0x03) { /* SNAP header */ uint32_t orgCode = packet[headerLen] << 16 | packet[headerLen + 1] << 8 | packet[headerLen + 2]; uint16_t ethType = packet[headerLen + 3] << 8 | packet[headerLen + 4]; json_object_object_add(jparent, "SNAP_oui", json_object_new_int(orgCode)); json_object_object_add(jparent, "SNAP_ethType", json_object_new_int(ethType)); return eth_proto_parse(ethType, packet + headerLen, pktSize - headerLen, jparent); } if (dsap == 0x06 && ssap == 0x06 && ctrl == 0x03) { /* IPv4 header */ return ipv4_parse(packet + headerLen, pktSize - headerLen, jparent); } if (dsap == 0xe0 && ssap == 0xe0 && ctrl == 0x03) { /* IPX packet with LLC */ return ipx_parse(packet + headerLen, pktSize - headerLen, jparent); } RETURN_DATA_AFTER(headerLen) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/udp_parser.c0000644000000000000000000000013215055605325017760 xustar0030 mtime=1756826325.612800125 30 atime=1764931112.555858857 30 ctime=1764935931.229699755 rsyslog-8.2512.0/contrib/impcap/udp_parser.c0000664000175000017500000000571115055605325017430 0ustar00rgerrger/* udp_parser.c * * This file contains functions to parse UDP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" #define DNS_PORT 53 struct udp_header_s { uint16_t srcPort; uint16_t dstPort; uint16_t totalLength; uint16_t checksum; }; typedef struct udp_header_s udp_header_t; /* * This function parses the bytes in the received packet to extract UDP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the UDP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where UDP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *udp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("udp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 8) { DBGPRINTF("UDP packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } /* Union to prevent cast from uchar to udp_header_t */ union { const uchar *pck; udp_header_t *hdr; } udp_header_to_char; udp_header_to_char.pck = packet; udp_header_t *udp_header = udp_header_to_char.hdr; // Prevent endianness issue unsigned short int src_port = ntohs(udp_header->srcPort); unsigned short int dst_port = ntohs(udp_header->dstPort); json_object_object_add(jparent, "net_src_port", json_object_new_int(src_port)); json_object_object_add(jparent, "net_dst_port", json_object_new_int(dst_port)); json_object_object_add(jparent, "UDP_Length", json_object_new_int(ntohs(udp_header->totalLength))); json_object_object_add(jparent, "UDP_Checksum", json_object_new_int(ntohs(udp_header->checksum))); if (src_port == DNS_PORT || dst_port == DNS_PORT) { return dns_parse(packet + sizeof(udp_header_t), pktSize - sizeof(udp_header_t), jparent); } RETURN_DATA_AFTER(8) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/ipv4_parser.c0000644000000000000000000000013215055605325020052 xustar0030 mtime=1756826325.612800125 30 atime=1764931110.547826315 30 ctime=1764935931.219699602 rsyslog-8.2512.0/contrib/impcap/ipv4_parser.c0000664000175000017500000000655715055605325017533 0ustar00rgerrger/* ipv4_parser.c * * This file contains functions to parse IP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" struct ipv4_header_s { /*#if __BYTE_ORDER == __BIG_ENDIAN unsigned char version:4; unsigned char ihl:4; #else*/ unsigned char ihl : 4; unsigned char version : 4; // #endif uint8_t service; uint16_t totLen; uint16_t id; uint16_t frag; uint8_t ttl; uint8_t proto; uint16_t hdrChksum; uint8_t addrSrc[4]; uint8_t addrDst[4]; uint8_t pOptions[]; }; typedef struct ipv4_header_s ipv4_header_t; /* * This function parses the bytes in the received packet to extract IP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the IP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where IP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *ipv4_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("ipv4_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 20) { /* too small for IPv4 header + data (header might be longer)*/ DBGPRINTF("IPv4 packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } /* Union to prevent cast from uchar to ipv4_header_t */ union { const uchar *pck; ipv4_header_t *hdr; } ipv4_header_to_char; ipv4_header_to_char.pck = packet; ipv4_header_t *ipv4_header = ipv4_header_to_char.hdr; char addrSrc[20], addrDst[20]; uint8_t hdrLen = 4 * ipv4_header->ihl; /* 4 x length in words */ inet_ntop(AF_INET, (void *)&ipv4_header->addrSrc, addrSrc, 20); inet_ntop(AF_INET, (void *)&ipv4_header->addrDst, addrDst, 20); json_object_object_add(jparent, "net_dst_ip", json_object_new_string((char *)addrDst)); json_object_object_add(jparent, "net_src_ip", json_object_new_string((char *)addrSrc)); json_object_object_add(jparent, "IP_ihl", json_object_new_int(ipv4_header->ihl)); json_object_object_add(jparent, "net_ttl", json_object_new_int(ipv4_header->ttl)); json_object_object_add(jparent, "IP_proto", json_object_new_int(ipv4_header->proto)); return ip_proto_parse(ipv4_header->proto, (packet + hdrLen), (pktSize - hdrLen), jparent); } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/parsers.h0000644000000000000000000000013115055605325017277 xustar0030 mtime=1756826325.612800125 30 atime=1764931108.574794327 29 ctime=1764935931.24369997 rsyslog-8.2512.0/contrib/impcap/parsers.h0000664000175000017500000001417415055605325016753 0ustar00rgerrger/* parser.h * * This file contains the prototypes of all the parsers available within impcap. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include "rsyslog.h" #include "msg.h" #include "dirty.h" #ifdef __FreeBSD__ #include #else #include #endif #include #include #include #include #include #include #include #include #ifndef INCLUDED_PARSER_H #define INCLUDED_PARSER_H 1 /* data return structure */ struct data_ret_s { size_t size; char *pData; }; typedef struct data_ret_s data_ret_t; #define RETURN_DATA_AFTER(x) \ data_ret_t *retData = malloc(sizeof(data_ret_t)); \ if (pktSize > x) { \ retData->size = pktSize - x; \ retData->pData = (char *)packet + x; \ } else { \ retData->size = 0; \ retData->pData = NULL; \ } \ return retData; /* --- handlers prototypes --- */ void packet_parse(uchar *arg, const struct pcap_pkthdr *pkthdr, const uchar *packet); data_ret_t *eth_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *llc_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *ipx_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *ipv4_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *icmp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *tcp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *udp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *ipv6_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *arp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *rarp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *ah_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *esp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *smb_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *ftp_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *http_parse(const uchar *packet, int pktSize, struct json_object *jparent); data_ret_t *dns_parse(const uchar *packet, int pktSize, struct json_object *jparent); // inline function definitions static inline data_ret_t *dont_parse(const uchar *packet, int pktSize, __attribute__((unused)) struct json_object *jparent); static inline data_ret_t *eth_proto_parse(uint16_t ethProto, const uchar *packet, int pktSize, struct json_object *jparent); static inline data_ret_t *ip_proto_parse(uint16_t ipProto, const uchar *packet, int pktSize, struct json_object *jparent); /* * Mock function to do no parsing when protocol is not a valid number */ static inline data_ret_t *dont_parse(const uchar *packet, int pktSize, __attribute__((unused)) struct json_object *jparent) { DBGPRINTF("protocol not handled\n"); RETURN_DATA_AFTER(0) } // proto code handlers static inline data_ret_t *eth_proto_parse(uint16_t ethProto, const uchar *packet, int pktSize, struct json_object *jparent) { switch (ethProto) { case ETHERTYPE_IP: return ipv4_parse(packet, pktSize, jparent); case ETHERTYPE_IPV6: return ipv6_parse(packet, pktSize, jparent); case ETHERTYPE_ARP: return arp_parse(packet, pktSize, jparent); case ETHERTYPE_REVARP: return rarp_parse(packet, pktSize, jparent); case ETHERTYPE_IPX: return ipx_parse(packet, pktSize, jparent); default: return dont_parse(packet, pktSize, jparent); } } static inline data_ret_t *ip_proto_parse(uint16_t ipProto, const uchar *packet, int pktSize, struct json_object *jparent) { switch (ipProto) { case IPPROTO_TCP: return tcp_parse(packet, pktSize, jparent); case IPPROTO_UDP: return udp_parse(packet, pktSize, jparent); case IPPROTO_ICMP: return icmp_parse(packet, pktSize, jparent); default: return dont_parse(packet, pktSize, jparent); } } #endif /* INCLUDED_PARSER_H */ rsyslog-8.2512.0/contrib/impcap/PaxHeaders/icmp_parser.c0000644000000000000000000000013115055605325020117 xustar0029 mtime=1756826325.61180011 30 atime=1764931110.041818113 30 ctime=1764935931.216699556 rsyslog-8.2512.0/contrib/impcap/icmp_parser.c0000664000175000017500000000505115055605325017565 0ustar00rgerrger/* icmp_parser.c * * This file contains functions to parse ICMP headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" struct icmp_header_s { uint8_t type; uint8_t code; uint16_t checksum; uint8_t data[]; }; typedef struct icmp_header_s icmp_header_t; /* * This function parses the bytes in the received packet to extract ICMP metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the ICMP header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where ICMP metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *icmp_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("icmp_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 8) { DBGPRINTF("ICMP packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0); } /* Union to prevent cast from uchar to icmp_header_t */ union { const uchar *pck; icmp_header_t *hdr; } icmp_header_to_char; icmp_header_to_char.pck = packet; icmp_header_t *icmp_header = icmp_header_to_char.hdr; json_object_object_add(jparent, "net_icmp_type", json_object_new_int(icmp_header->type)); json_object_object_add(jparent, "net_icmp_code", json_object_new_int(icmp_header->code)); json_object_object_add(jparent, "icmp_checksum", json_object_new_int(ntohs(icmp_header->checksum))); RETURN_DATA_AFTER(8) } rsyslog-8.2512.0/contrib/impcap/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017512 xustar0030 mtime=1764935885.855004928 30 atime=1764935896.878173773 30 ctime=1764935931.207699418 rsyslog-8.2512.0/contrib/impcap/Makefile.in0000664000175000017500000012521715114544315017166 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/impcap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) impcap_la_DEPENDENCIES = am_impcap_la_OBJECTS = impcap_la-impcap.lo impcap_la-arp_parser.lo \ impcap_la-eth_parser.lo impcap_la-icmp_parser.lo \ impcap_la-ipv4_parser.lo impcap_la-ipv6_parser.lo \ impcap_la-ipx_parser.lo impcap_la-llc_parser.lo \ impcap_la-udp_parser.lo impcap_la-dns_parser.lo \ impcap_la-tcp_parser.lo impcap_la-smb_parser.lo \ impcap_la-ftp_parser.lo impcap_la-http_parser.lo impcap_la_OBJECTS = $(am_impcap_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = impcap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(impcap_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/impcap_la-arp_parser.Plo \ ./$(DEPDIR)/impcap_la-dns_parser.Plo \ ./$(DEPDIR)/impcap_la-eth_parser.Plo \ ./$(DEPDIR)/impcap_la-ftp_parser.Plo \ ./$(DEPDIR)/impcap_la-http_parser.Plo \ ./$(DEPDIR)/impcap_la-icmp_parser.Plo \ ./$(DEPDIR)/impcap_la-impcap.Plo \ ./$(DEPDIR)/impcap_la-ipv4_parser.Plo \ ./$(DEPDIR)/impcap_la-ipv6_parser.Plo \ ./$(DEPDIR)/impcap_la-ipx_parser.Plo \ ./$(DEPDIR)/impcap_la-llc_parser.Plo \ ./$(DEPDIR)/impcap_la-smb_parser.Plo \ ./$(DEPDIR)/impcap_la-tcp_parser.Plo \ ./$(DEPDIR)/impcap_la-udp_parser.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(impcap_la_SOURCES) DIST_SOURCES = $(impcap_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = impcap.la impcap_la_SOURCES = impcap.c arp_parser.c eth_parser.c icmp_parser.c \ ipv4_parser.c ipv6_parser.c ipx_parser.c llc_parser.c \ udp_parser.c dns_parser.c tcp_parser.c smb_parser.c \ ftp_parser.c http_parser.c impcap_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) impcap_la_LDFLAGS = -module -avoid-version impcap_la_LIBADD = -lpcap EXTRA_DIST = parsers.h all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/impcap/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/impcap/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } impcap.la: $(impcap_la_OBJECTS) $(impcap_la_DEPENDENCIES) $(EXTRA_impcap_la_DEPENDENCIES) $(AM_V_CCLD)$(impcap_la_LINK) -rpath $(pkglibdir) $(impcap_la_OBJECTS) $(impcap_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-arp_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-dns_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-eth_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ftp_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-http_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-icmp_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-impcap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipv4_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipv6_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-ipx_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-llc_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-smb_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-tcp_parser.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/impcap_la-udp_parser.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< impcap_la-impcap.lo: impcap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-impcap.lo -MD -MP -MF $(DEPDIR)/impcap_la-impcap.Tpo -c -o impcap_la-impcap.lo `test -f 'impcap.c' || echo '$(srcdir)/'`impcap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-impcap.Tpo $(DEPDIR)/impcap_la-impcap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='impcap.c' object='impcap_la-impcap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-impcap.lo `test -f 'impcap.c' || echo '$(srcdir)/'`impcap.c impcap_la-arp_parser.lo: arp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-arp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-arp_parser.Tpo -c -o impcap_la-arp_parser.lo `test -f 'arp_parser.c' || echo '$(srcdir)/'`arp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-arp_parser.Tpo $(DEPDIR)/impcap_la-arp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='arp_parser.c' object='impcap_la-arp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-arp_parser.lo `test -f 'arp_parser.c' || echo '$(srcdir)/'`arp_parser.c impcap_la-eth_parser.lo: eth_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-eth_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-eth_parser.Tpo -c -o impcap_la-eth_parser.lo `test -f 'eth_parser.c' || echo '$(srcdir)/'`eth_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-eth_parser.Tpo $(DEPDIR)/impcap_la-eth_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='eth_parser.c' object='impcap_la-eth_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-eth_parser.lo `test -f 'eth_parser.c' || echo '$(srcdir)/'`eth_parser.c impcap_la-icmp_parser.lo: icmp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-icmp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-icmp_parser.Tpo -c -o impcap_la-icmp_parser.lo `test -f 'icmp_parser.c' || echo '$(srcdir)/'`icmp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-icmp_parser.Tpo $(DEPDIR)/impcap_la-icmp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='icmp_parser.c' object='impcap_la-icmp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-icmp_parser.lo `test -f 'icmp_parser.c' || echo '$(srcdir)/'`icmp_parser.c impcap_la-ipv4_parser.lo: ipv4_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipv4_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipv4_parser.Tpo -c -o impcap_la-ipv4_parser.lo `test -f 'ipv4_parser.c' || echo '$(srcdir)/'`ipv4_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipv4_parser.Tpo $(DEPDIR)/impcap_la-ipv4_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv4_parser.c' object='impcap_la-ipv4_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipv4_parser.lo `test -f 'ipv4_parser.c' || echo '$(srcdir)/'`ipv4_parser.c impcap_la-ipv6_parser.lo: ipv6_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipv6_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipv6_parser.Tpo -c -o impcap_la-ipv6_parser.lo `test -f 'ipv6_parser.c' || echo '$(srcdir)/'`ipv6_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipv6_parser.Tpo $(DEPDIR)/impcap_la-ipv6_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipv6_parser.c' object='impcap_la-ipv6_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipv6_parser.lo `test -f 'ipv6_parser.c' || echo '$(srcdir)/'`ipv6_parser.c impcap_la-ipx_parser.lo: ipx_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ipx_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ipx_parser.Tpo -c -o impcap_la-ipx_parser.lo `test -f 'ipx_parser.c' || echo '$(srcdir)/'`ipx_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ipx_parser.Tpo $(DEPDIR)/impcap_la-ipx_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ipx_parser.c' object='impcap_la-ipx_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ipx_parser.lo `test -f 'ipx_parser.c' || echo '$(srcdir)/'`ipx_parser.c impcap_la-llc_parser.lo: llc_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-llc_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-llc_parser.Tpo -c -o impcap_la-llc_parser.lo `test -f 'llc_parser.c' || echo '$(srcdir)/'`llc_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-llc_parser.Tpo $(DEPDIR)/impcap_la-llc_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='llc_parser.c' object='impcap_la-llc_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-llc_parser.lo `test -f 'llc_parser.c' || echo '$(srcdir)/'`llc_parser.c impcap_la-udp_parser.lo: udp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-udp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-udp_parser.Tpo -c -o impcap_la-udp_parser.lo `test -f 'udp_parser.c' || echo '$(srcdir)/'`udp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-udp_parser.Tpo $(DEPDIR)/impcap_la-udp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='udp_parser.c' object='impcap_la-udp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-udp_parser.lo `test -f 'udp_parser.c' || echo '$(srcdir)/'`udp_parser.c impcap_la-dns_parser.lo: dns_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-dns_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-dns_parser.Tpo -c -o impcap_la-dns_parser.lo `test -f 'dns_parser.c' || echo '$(srcdir)/'`dns_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-dns_parser.Tpo $(DEPDIR)/impcap_la-dns_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dns_parser.c' object='impcap_la-dns_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-dns_parser.lo `test -f 'dns_parser.c' || echo '$(srcdir)/'`dns_parser.c impcap_la-tcp_parser.lo: tcp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-tcp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-tcp_parser.Tpo -c -o impcap_la-tcp_parser.lo `test -f 'tcp_parser.c' || echo '$(srcdir)/'`tcp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-tcp_parser.Tpo $(DEPDIR)/impcap_la-tcp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tcp_parser.c' object='impcap_la-tcp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-tcp_parser.lo `test -f 'tcp_parser.c' || echo '$(srcdir)/'`tcp_parser.c impcap_la-smb_parser.lo: smb_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-smb_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-smb_parser.Tpo -c -o impcap_la-smb_parser.lo `test -f 'smb_parser.c' || echo '$(srcdir)/'`smb_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-smb_parser.Tpo $(DEPDIR)/impcap_la-smb_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='smb_parser.c' object='impcap_la-smb_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-smb_parser.lo `test -f 'smb_parser.c' || echo '$(srcdir)/'`smb_parser.c impcap_la-ftp_parser.lo: ftp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-ftp_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-ftp_parser.Tpo -c -o impcap_la-ftp_parser.lo `test -f 'ftp_parser.c' || echo '$(srcdir)/'`ftp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-ftp_parser.Tpo $(DEPDIR)/impcap_la-ftp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ftp_parser.c' object='impcap_la-ftp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-ftp_parser.lo `test -f 'ftp_parser.c' || echo '$(srcdir)/'`ftp_parser.c impcap_la-http_parser.lo: http_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT impcap_la-http_parser.lo -MD -MP -MF $(DEPDIR)/impcap_la-http_parser.Tpo -c -o impcap_la-http_parser.lo `test -f 'http_parser.c' || echo '$(srcdir)/'`http_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/impcap_la-http_parser.Tpo $(DEPDIR)/impcap_la-http_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='http_parser.c' object='impcap_la-http_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(impcap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o impcap_la-http_parser.lo `test -f 'http_parser.c' || echo '$(srcdir)/'`http_parser.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/impcap_la-arp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-dns_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-eth_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ftp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-http_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-icmp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-impcap.Plo -rm -f ./$(DEPDIR)/impcap_la-ipv4_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ipv6_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ipx_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-llc_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-smb_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-tcp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-udp_parser.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/impcap_la-arp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-dns_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-eth_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ftp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-http_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-icmp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-impcap.Plo -rm -f ./$(DEPDIR)/impcap_la-ipv4_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ipv6_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-ipx_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-llc_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-smb_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-tcp_parser.Plo -rm -f ./$(DEPDIR)/impcap_la-udp_parser.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/impcap/PaxHeaders/impcap.c0000644000000000000000000000013215055605325017065 xustar0030 mtime=1756826325.612800125 30 atime=1764931108.445792235 30 ctime=1764935931.209699449 rsyslog-8.2512.0/contrib/impcap/impcap.c0000664000175000017500000006311215055605325016534 0ustar00rgerrger/* impcap.c * * This is an input module using libpcap, a * portable C/C++ library for network traffic capture. * This module reads packets received from a network interface * using libpcap, to extract information such as IP addresses, ports, * protocols, etc... and make it available to rsyslog and other modules. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "rsyslog.h" #include "prop.h" #include "ruleset.h" #include "datetime.h" #include "errmsg.h" #include "unicode-helper.h" #include "module-template.h" #include "rainerscript.h" #include "rsconf.h" #include "glbl.h" #include "srUtils.h" #include "parsers.h" MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("impcap") #define DEFAULT_META_CONTAINER "!impcap" #define DEFAULT_DATA_CONTAINER "!data" /* static data */ DEF_IMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) DEFobjCurrIf(datetime) static prop_t *pInputName = NULL; char *stringToHex(char *string, size_t length); static ATTR_NORETURN void *startCaptureThread(void *instanceConf); /* conf structures */ struct instanceConf_s { char *interface; uchar *filePath; pcap_t *device; uchar *filter; uchar *tag; uint8_t promiscuous; uint8_t immediateMode; uint32_t bufSize; uint8_t bufTimeout; uint8_t pktBatchCnt; pthread_t tid; uchar *pszBindRuleset; /* name of ruleset to bind to */ ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */ struct instanceConf_s *next; }; struct modConfData_s { rsconf_t *pConf; instanceConf_t *root, *tail; uint16_t snap_length; uint8_t metadataOnly; char *metadataContainer; char *dataContainer; }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* input instance parameters */ static struct cnfparamdescr inppdescr[] = {{"interface", eCmdHdlrGetWord, 0}, {"file", eCmdHdlrString, 0}, {"promiscuous", eCmdHdlrBinary, 0}, {"filter", eCmdHdlrString, 0}, {"tag", eCmdHdlrString, 0}, {"ruleset", eCmdHdlrString, 0}, {"no_buffer", eCmdHdlrBinary, 0}, {"buffer_size", eCmdHdlrPositiveInt, 0}, {"buffer_timeout", eCmdHdlrPositiveInt, 0}, {"packet_count", eCmdHdlrPositiveInt, 0}}; static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; /* module-global parameters */ static struct cnfparamdescr modpdescr[] = {{"snap_length", eCmdHdlrPositiveInt, 0}, {"metadata_only", eCmdHdlrBinary, 0}, {"metadata_container", eCmdHdlrGetWord, 0}, {"data_container", eCmdHdlrGetWord, 0}}; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; #include "im-helper.h" /* * create input instance, set default parameters, and * add it to the list of instances. */ static rsRetVal createInstance(instanceConf_t **pinst) { instanceConf_t *inst; DEFiRet; CHKmalloc(inst = malloc(sizeof(instanceConf_t))); inst->next = NULL; inst->interface = NULL; inst->filePath = NULL; inst->device = NULL; inst->promiscuous = 0; inst->filter = NULL; inst->tag = NULL; inst->pszBindRuleset = NULL; inst->immediateMode = 0; inst->bufTimeout = 10; inst->bufSize = 1024 * 1024 * 15; /* should be enough for up to 10Gb interface*/ inst->pktBatchCnt = 5; /* node created, let's add to global config */ if (loadModConf->tail == NULL) { loadModConf->tail = loadModConf->root = inst; } else { loadModConf->tail->next = inst; loadModConf->tail = inst; } *pinst = inst; finalize_it: RETiRet; } /* input instances */ BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst; int i; CODESTARTnewInpInst; pvals = nvlstGetParams(lst, &inppblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "impcap: required parameters are missing\n"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(inppblk.descr[i].name, "interface")) { inst->interface = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "file")) { inst->filePath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "promiscuous")) { inst->promiscuous = (uint8_t)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "filter")) { inst->filter = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "tag")) { inst->tag = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "no_buffer")) { inst->immediateMode = (uint8_t)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "buffer_size")) { inst->bufSize = (uint32_t)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "buffer_timeout")) { inst->bufTimeout = (uint8_t)pvals[i].val.d.n; } else if (!strcmp(inppblk.descr[i].name, "packet_count")) { inst->pktBatchCnt = (uint8_t)pvals[i].val.d.n; } else { dbgprintf("impcap: non-handled param %s in beginCnfLoad\n", inppblk.descr[i].name); } } finalize_it: CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst /* global mod conf (v2 system) */ BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { LogError(0, RS_RET_MISSING_CNFPARAMS, "impcap: error processing module " "config parameters missing [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(modpblk.descr[i].name, "snap_length")) { loadModConf->snap_length = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "metadata_only")) { loadModConf->metadataOnly = (uint8_t)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "metadata_container")) { loadModConf->metadataContainer = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "data_container")) { loadModConf->dataContainer = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf("impcap: non-handled param %s in beginSetModCnf\n", modpblk.descr[i].name); } } if (!loadModConf->metadataContainer) CHKmalloc(loadModConf->metadataContainer = strdup(DEFAULT_META_CONTAINER)); if (!loadModConf->dataContainer) CHKmalloc(loadModConf->dataContainer = strdup(DEFAULT_DATA_CONTAINER)); finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf /* config v2 system */ BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; loadModConf->pConf = pConf; loadModConf->metadataOnly = 0; loadModConf->snap_length = 65535; loadModConf->metadataContainer = NULL; loadModConf->dataContainer = NULL; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad /* function to generate error message if framework does not find requested ruleset */ static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "impcap: ruleset '%s' for interface %s not found - " "using default ruleset instead", inst->pszBindRuleset, inst->interface); } BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; if (pModConf->root == NULL) { LogError(0, RS_RET_NO_LISTNERS, "impcap: module loaded, but " "no interface defined - no input will be gathered"); iRet = RS_RET_NO_LISTNERS; } if (pModConf->metadataOnly) { /* if metadata_only is "on", snap_length is overwritten */ pModConf->snap_length = 100; /* arbitrary value, but should be enough for most protocols */ } if (!pModConf->metadataContainer || !pModConf->dataContainer) { LogError(0, RS_RET_LOAD_ERROR, "impcap: no name defined for metadata_container and " "data_container, this shouldn't happen"); } else { DBGPRINTF("impcap: metadata will be stored in '%s', and data in '%s'\n", pModConf->metadataContainer, pModConf->dataContainer); } for (inst = pModConf->root; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); if (inst->interface == NULL && inst->filePath == NULL) { iRet = RS_RET_INVALID_PARAMS; LogError(0, RS_RET_LOAD_ERROR, "impcap: 'interface' or 'file' must be specified"); break; } if (inst->interface != NULL && inst->filePath != NULL) { iRet = RS_RET_INVALID_PARAMS; LogError(0, RS_RET_LOAD_ERROR, "impcap: either 'interface' or 'file' must be specified"); break; } } ENDcheckCnf BEGINactivateCnfPrePrivDrop CODESTARTactivateCnfPrePrivDrop; runModConf = pModConf; ENDactivateCnfPrePrivDrop BEGINactivateCnf instanceConf_t *inst; pcap_t *dev = NULL; struct bpf_program filter_program; bpf_u_int32 SubNet, NetMask; char errBuf[PCAP_ERRBUF_SIZE]; uint8_t retCode = 0; CODESTARTactivateCnf; for (inst = pModConf->root; inst != NULL; inst = inst->next) { if (inst->filePath != NULL) { dev = pcap_open_offline((const char *)inst->filePath, errBuf); if (dev == NULL) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while opening capture file: '%s'", errBuf); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } } else if (inst->interface != NULL) { dev = pcap_create((const char *)inst->interface, errBuf); if (dev == NULL) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while creating packet capture: '%s'", errBuf); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } DBGPRINTF("setting snap_length %d\n", pModConf->snap_length); if (pcap_set_snaplen(dev, pModConf->snap_length)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting snap length: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } DBGPRINTF("setting promiscuous %d\n", inst->promiscuous); if (pcap_set_promisc(dev, inst->promiscuous)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting promiscuous mode: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } if (inst->immediateMode) { DBGPRINTF("setting immediate mode %d\n", inst->immediateMode); retCode = pcap_set_immediate_mode(dev, inst->immediateMode); if (retCode) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting immediate mode: '%s'," " using buffer instead\n", pcap_geterr(dev)); } } if (!inst->immediateMode || retCode) { DBGPRINTF("setting buffer size %u \n", inst->bufSize); if (pcap_set_buffer_size(dev, inst->bufSize)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting buffer size: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } DBGPRINTF("setting buffer timeout %dms\n", inst->bufTimeout); if (pcap_set_timeout(dev, inst->bufTimeout)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting buffer timeout: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } } switch (pcap_activate(dev)) { case PCAP_WARNING_PROMISC_NOTSUP: LogError(0, NO_ERRCODE, "interface doesn't support promiscuous mode"); break; case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: LogError(0, NO_ERRCODE, "timestamp type is not supported"); break; case PCAP_WARNING: LogError(0, NO_ERRCODE, "pcap: %s", pcap_geterr(dev)); break; case PCAP_ERROR_ACTIVATED: LogError(0, RS_RET_LOAD_ERROR, "already activated, shouldn't happen"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR_NO_SUCH_DEVICE: LogError(0, RS_RET_LOAD_ERROR, "device doesn't exist"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR_PERM_DENIED: LogError(0, RS_RET_LOAD_ERROR, "elevated privilege needed to open capture " "interface"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR_PROMISC_PERM_DENIED: LogError(0, RS_RET_LOAD_ERROR, "elevated privilege needed to put interface " "in promiscuous mode"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR_RFMON_NOTSUP: LogError(0, RS_RET_LOAD_ERROR, "interface doesn't support monitor mode"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR_IFACE_NOT_UP: LogError(0, RS_RET_LOAD_ERROR, "interface is not up"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); case PCAP_ERROR: LogError(0, RS_RET_LOAD_ERROR, "pcap: %s", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); default: // No action needed for other cases break; } if (inst->filter != NULL) { DBGPRINTF("getting netmask on %s\n", inst->interface); // obtain the subnet if (pcap_lookupnet(inst->interface, &SubNet, &NetMask, errBuf)) { DBGPRINTF("could not get netmask\n"); NetMask = PCAP_NETMASK_UNKNOWN; } DBGPRINTF("setting filter to '%s'\n", inst->filter); /* Compile the filter */ if (pcap_compile(dev, &filter_program, (const char *)inst->filter, 1, NetMask)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while compiling filter: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } else if (pcap_setfilter(dev, &filter_program)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting filter: '%s'", pcap_geterr(dev)); pcap_freecode(&filter_program); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } pcap_freecode(&filter_program); } if (pcap_set_datalink(dev, DLT_EN10MB)) { LogError(0, RS_RET_LOAD_ERROR, "pcap: error while setting datalink type: '%s'", pcap_geterr(dev)); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } } /* inst->interface != NULL */ else { LogError(0, RS_RET_LOAD_ERROR, "impcap: no capture method specified, " "please specify either 'interface' or 'file' in config"); ABORT_FINALIZE(RS_RET_LOAD_ERROR); } inst->device = dev; } finalize_it: if (iRet != 0) { if (dev) pcap_close(dev); } ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf; DBGPRINTF("impcap: freeing confs...\n"); for (inst = pModConf->root; inst != NULL;) { del = inst; inst = inst->next; free(del->filePath); free(del->filter); free(del->pszBindRuleset); free(del->interface); free(del->tag); free(del); } free(pModConf->metadataContainer); free(pModConf->dataContainer); DBGPRINTF("impcap: finished freeing confs\n"); ENDfreeCnf /* runtime functions */ /* * Converts a list of bytes to their hexadecimal representation in ASCII * * Gets the list of bytes and the length as parameters * * Returns a pointer on the new list, being a string of ASCII characters * representing hexadecimal values, in the form "A5B34C65..." * its size is twice length parameter + 1 */ char *stringToHex(char *string, size_t length) { const char *hexChar = "0123456789ABCDEF"; char *retBuf; uint16_t i; retBuf = malloc((2 * length + 1) * sizeof(char)); for (i = 0; i < length; ++i) { retBuf[2 * i] = hexChar[(string[i] & 0xF0) >> 4]; retBuf[2 * i + 1] = hexChar[string[i] & 0x0F]; } retBuf[2 * length] = '\0'; return retBuf; } /* * This method parses every packet received by libpcap, and is called by it * It creates the message for Rsyslog, calls the parsers and add all necessary information * in the message */ void packet_parse(uchar *arg, const struct pcap_pkthdr *pkthdr, const uchar *packet) { DBGPRINTF("impcap : entered packet_parse\n"); smsg_t *pMsg; /* Prevent cast error from char to int with arg */ union { uchar *buf; int *id; } aux; aux.buf = arg; int *id = aux.id; msgConstruct(&pMsg); MsgSetInputName(pMsg, pInputName); // search inst in loadmodconf,and check if there is tag. if so set tag in msg. pthread_t ctid = pthread_self(); instanceConf_t *inst; for (inst = runModConf->root; inst != NULL; inst = inst->next) { if (pthread_equal(ctid, inst->tid)) { if (inst->pBindRuleset != NULL) { MsgSetRuleset(pMsg, inst->pBindRuleset); } if (inst->tag != NULL) { MsgSetTAG(pMsg, inst->tag, strlen((const char *)inst->tag)); } } } struct json_object *jown = json_object_new_object(); json_object_object_add(jown, "ID", json_object_new_int(++(*id))); struct syslogTime sysTimePkt; char timeStr[30]; struct timeval tv = pkthdr->ts; datetime.timeval2syslogTime(&tv, &sysTimePkt, 1 /*inUTC*/); if (datetime.formatTimestamp3339(&sysTimePkt, timeStr)) { json_object_object_add(jown, "timestamp", json_object_new_string(timeStr)); } json_object_object_add(jown, "net_bytes_total", json_object_new_int(pkthdr->len)); data_ret_t *dataLeft = eth_parse(packet, pkthdr->caplen, jown); json_object_object_add(jown, "net_bytes_data", json_object_new_int(dataLeft->size)); char *dataHex = stringToHex(dataLeft->pData, dataLeft->size); if (dataHex != NULL) { struct json_object *jadd = json_object_new_object(); json_object_object_add(jadd, "length", json_object_new_int(strlen(dataHex))); json_object_object_add(jadd, "content", json_object_new_string(dataHex)); msgAddJSON(pMsg, (uchar *)runModConf->dataContainer, jadd, 0, 0); free(dataHex); } free(dataLeft); msgAddJSON(pMsg, (uchar *)runModConf->metadataContainer, jown, 0, 0); submitMsg2(pMsg); } /* This is used to terminate the plugin. */ static void doSIGTTIN(int __attribute__((unused)) sig) { pthread_t tid = pthread_self(); const int bTerminate = ATOMIC_FETCH_32BIT(&bTerminateInputs, &mutTerminateInputs); DBGPRINTF("impcap: awoken via SIGTTIN; bTerminateInputs: %d\n", bTerminate); if (bTerminate) { for (instanceConf_t *inst = runModConf->root; inst != NULL; inst = inst->next) { if (pthread_equal(tid, inst->tid)) { pcap_breakloop(inst->device); DBGPRINTF("impcap: thread %lx, termination requested via SIGTTIN - telling libpcap\n", (long unsigned int)tid); } } } } /* * This is the main function for each thread * taking care of a specified network interface */ static ATTR_NORETURN void *startCaptureThread(void *instanceConf) { int id = 0; pthread_t tid = pthread_self(); /* we want to support non-cancel input termination. To do so, we must signal libpcap * when to stop. As we run on the same thread, we need to register as SIGTTIN handler, * which will be used to put the terminating condition into libpcap. */ DBGPRINTF("impcap: setting catch for SIGTTIN, thread %lx\n", (long unsigned int)tid); sigset_t sigSet; struct sigaction sigAct; sigfillset(&sigSet); pthread_sigmask(SIG_BLOCK, &sigSet, NULL); sigemptyset(&sigSet); sigaddset(&sigSet, SIGTTIN); pthread_sigmask(SIG_UNBLOCK, &sigSet, NULL); memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = doSIGTTIN; sigaction(SIGTTIN, &sigAct, NULL); instanceConf_t *inst = (instanceConf_t *)instanceConf; DBGPRINTF("impcap: thread %lx, begin capture!\n", (long unsigned int)tid); while (glbl.GetGlobalInputTermState() == 0) { pcap_dispatch(inst->device, inst->pktBatchCnt, packet_parse, (uchar *)&id); } DBGPRINTF("impcap: thread %lx, capture finished\n", (long unsigned int)tid); pthread_exit(0); } BEGINrunInput instanceConf_t *inst; int ret = 0; CODESTARTrunInput; for (inst = runModConf->root; inst != NULL; inst = inst->next) { /* creates a thread and starts capturing on the interface */ ret = pthread_create(&inst->tid, NULL, startCaptureThread, inst); if (ret) { LogError(0, RS_RET_NO_RUN, "impcap: error while creating threads\n"); } } DBGPRINTF("impcap: starting to wait for close condition\n"); // TODO: Use thread for capture instead of just waiting while (glbl.GetGlobalInputTermState() == 0) { if (glbl.GetGlobalInputTermState() == 0) srSleep(0, 400000); } DBGPRINTF("impcap: received close signal, signaling instance threads...\n"); for (inst = runModConf->root; inst != NULL; inst = inst->next) { pthread_kill(inst->tid, SIGTTIN); } DBGPRINTF("impcap: threads signaled, waiting for join..."); for (inst = runModConf->root; inst != NULL; inst = inst->next) { pthread_join(inst->tid, NULL); pcap_close(inst->device); } DBGPRINTF("impcap: finished threads, stopping\n"); ENDrunInput BEGINwillRun CODESTARTwillRun; /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("impcap"), sizeof("impcap") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); finalize_it: ENDwillRun BEGINafterRun CODESTARTafterRun; if (pInputName != NULL) { prop.Destruct(&pInputName); } ENDafterRun BEGINmodExit CODESTARTmodExit; DBGPRINTF("impcap:: modExit\n"); objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit /* declaration of functions */ BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES /* might need it */ CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/impcap/PaxHeaders/eth_parser.c0000644000000000000000000000013115055605325017747 xustar0029 mtime=1756826325.61180011 30 atime=1764931109.542810023 30 ctime=1764935931.214699526 rsyslog-8.2512.0/contrib/impcap/eth_parser.c0000664000175000017500000001425615055605325017424 0ustar00rgerrger/* eth_parser.c * * This file contains functions to parse Ethernet II headers. * * File begun on 2018-11-13 * * Created by: * - Théo Bertin (theo.bertin@advens.fr) * * With: * - François Bernard (francois.bernard@isen.yncrea.fr) * - Tianyu Geng (tianyu.geng@isen.yncrea.fr) * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "parsers.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpacked" #pragma GCC diagnostic ignored "-Wattributes" struct __attribute__((__packed__)) eth_header_s { uint8_t addrDst[6]; uint8_t addrSrc[6]; uint16_t type; }; struct __attribute__((__packed__)) vlan_header_s { uint8_t addrDst[6]; uint8_t addrSrc[6]; uint16_t vlanCode; uint16_t vlanTag; uint16_t type; }; #pragma GCC diagnostic pop typedef struct eth_header_s eth_header_t; typedef struct vlan_header_s vlan_header_t; /* * Get an ethernet header type as uint16_t * and return the correspondence as string * NOTE : Only most common types are present, to complete if needed */ static const char *eth_type_to_string(uint16_t eth_type) { switch (eth_type) { case 0x00bb: // Extreme Networks Discovery Protocol return "EDP"; case 0x0200: // PUP protocol return "PUP"; case 0x0800: // IP protocol return "IP"; case 0x0806: // address resolution protocol return "ARP"; case 0x88a2: // AoE protocol return "AOE"; case 0x2000: // Cisco Discovery Protocol return "CDP"; case 0x2004: // Cisco Dynamic Trunking Protocol return "DTP"; case 0x8035: // reverse addr resolution protocol return "REVARP"; case 0x8100: // IEEE 802.1Q VLAN tagging return "802.1Q"; case 0x88a8: // IEEE 802.1ad return "802.1AD"; case 0x9100: // Legacy QinQ return "QINQ1"; case 0x9200: // Legacy QinQ return "QINQ2"; case 0x8137: // Internetwork Packet Exchange return "IPX"; case 0x86DD: // IPv6 protocol return "IPv6"; case 0x880B: // PPP return "PPP"; case 0x8847: // MPLS return "MPLS"; case 0x8848: // MPLS Multicast return "MPLS_MCAST"; case 0x8863: // PPP Over Ethernet Discovery Stage return "PPPoE_DISC"; case 0x8864: // PPP Over Ethernet Session Stage return "PPPoE"; case 0x88CC: // Link Layer Discovery Protocol return "LLDP"; case 0x6558: // Transparent Ethernet Bridging return "TEB"; default: return "UNKNOWN"; } } /* * This function parses the bytes in the received packet to extract Ethernet II metadata. * * its parameters are: * - a pointer on the list of bytes representing the packet * the first byte must be the beginning of the ETH header * - the size of the list passed as first parameter * - a pointer on a json_object, containing all the metadata recovered so far * this is also where ETH metadata will be added * * This function returns a structure containing the data unprocessed by this parser * or the ones after (as a list of bytes), and the length of this data. */ data_ret_t *eth_parse(const uchar *packet, int pktSize, struct json_object *jparent) { DBGPRINTF("entered eth_parse\n"); DBGPRINTF("packet size %d\n", pktSize); if (pktSize < 14) { /* too short for eth header */ DBGPRINTF("ETH packet too small : %d\n", pktSize); RETURN_DATA_AFTER(0) } eth_header_t *eth_header = (eth_header_t *)packet; char ethMacSrc[20], ethMacDst[20]; uint8_t hdrLen = 14; ether_ntoa_r((struct ether_addr *)eth_header->addrSrc, ethMacSrc); ether_ntoa_r((struct ether_addr *)eth_header->addrDst, ethMacDst); json_object_object_add(jparent, "ETH_src", json_object_new_string((char *)ethMacSrc)); json_object_object_add(jparent, "ETH_dst", json_object_new_string((char *)ethMacDst)); uint16_t ethType = (uint16_t)ntohs(eth_header->type); if (ethType == ETHERTYPE_VLAN) { vlan_header_t *vlan_header = (vlan_header_t *)packet; json_object_object_add(jparent, "ETH_tag", json_object_new_int(ntohs(vlan_header->vlanTag))); ethType = (uint16_t)ntohs(vlan_header->type); hdrLen += 4; } data_ret_t *ret; if (ethType < 1500) { /* this is a LLC header */ json_object_object_add(jparent, "ETH_len", json_object_new_int(ethType)); ret = llc_parse(packet + hdrLen, pktSize - hdrLen, jparent); /* packet has the minimum allowed size, so the remaining data is * most likely padding, this should not appear as data, so remove it * */ // TODO this is a quick win, a more elaborate solution would be to check if all data // is indeed zero, but that would take more processing time if (pktSize <= 60 && ret->pData != NULL) { if (!ret->pData[0]) ret->size = 0; } return ret; } json_object_object_add(jparent, "ETH_type", json_object_new_int(ethType)); json_object_object_add(jparent, "ETH_typestr", json_object_new_string((char *)eth_type_to_string(ethType))); ret = eth_proto_parse(ethType, (packet + hdrLen), (pktSize - hdrLen), jparent); /* packet has the minimum allowed size, so the remaining data is * most likely padding, this should not appear as data, so remove it */ if (pktSize <= 60 && ret->pData != NULL) { if (!ret->pData[0]) ret->size = 0; } return ret; } rsyslog-8.2512.0/contrib/PaxHeaders/pmpanngfw0000644000000000000000000000013115114544366016121 xustar0030 mtime=1764935926.110621391 29 atime=1764935930.17368359 30 ctime=1764935926.110621391 rsyslog-8.2512.0/contrib/pmpanngfw/0000775000175000017500000000000015114544366015643 5ustar00rgerrgerrsyslog-8.2512.0/contrib/pmpanngfw/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020224 xustar0030 mtime=1752569012.331237145 30 atime=1764930929.646829728 30 ctime=1764935926.102621268 rsyslog-8.2512.0/contrib/pmpanngfw/Makefile.am0000664000175000017500000000034415035412264017671 0ustar00rgerrgerpkglib_LTLIBRARIES = pmpanngfw.la pmpanngfw_la_SOURCES = pmpanngfw.c pmpanngfw_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmpanngfw_la_LDFLAGS = -module -avoid-version pmpanngfw_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/pmpanngfw/PaxHeaders/pmpanngfw.c0000644000000000000000000000013215055605325020335 xustar0030 mtime=1756826325.614800155 30 atime=1764931139.576295408 30 ctime=1764935926.110621391 rsyslog-8.2512.0/contrib/pmpanngfw/pmpanngfw.c0000664000175000017500000002053015055605325020001 0ustar00rgerrger/* pmpanngfw.c * * this detects logs sent by Palo Alto Networks NGFW and transforms CSV into tab-separated fields * for handling inside the mmnormalize * * Example: foo,"bar,""baz""",qux becomes foobar,"baz"qux * * created 2010-12-13 by Luigi Mori (lmori@paloaltonetworks.com) based on pmsnare * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" #include "typedefs.h" #include "rsconf.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.panngfw") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ typedef struct { uint64 value; uint64 mask; } log_type_t; const log_type_t log_types[] = { {0x002c544145524854ULL, 0x00FFFFFFFFFFFFFFULL}, /* THREAT, */ {0x2c43494646415254ULL, 0xFFFFFFFFFFFFFFFFULL}, /* TRAFFIC, */ {0x002c4d4554535953ULL, 0x00FFFFFFFFFFFFFFULL}, /* CONFIG */ {0x002c4749464e4f43ULL, 0x00FFFFFFFFFFFFFFULL} /* SYSTEM */ }; #define NUM_LOG_TYPES (sizeof(log_types) / sizeof(log_type_t)) BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINparse uchar *p2parse; uchar *p2target; uchar *msgend; int lenMsg, lenDelta; int state; int num_fields = 4; uchar *f3_commas[3]; int cur_comma = 0; uint64 log_type; unsigned int j; CODESTARTparse; #define CSV_DELIMITER '\t' #define STATE_FIELD_START 0 #define STATE_IN_FIELD 1 #define STATE_IN_QUOTE 2 #define STATE_IN_QUOTE_QUOTE 3 state = STATE_FIELD_START; dbgprintf("Message will now be parsed by fix Palo Alto Networks NGFW parser.\n"); assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */ msgend = p2parse + lenMsg; dbgprintf("pmpanngfw: msg to look at: [%d]'%s'\n", lenMsg, p2parse); /* pass the first 3 fields */ while (p2parse < msgend) { if (*p2parse == ',') { f3_commas[cur_comma] = p2parse; if (cur_comma == 2) { break; } cur_comma++; } p2parse++; } /* check number of fields detected so far */ if (cur_comma != 2) { dbgprintf("not a PAN-OS syslog message: first 3 fields not found\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* check msg length */ p2parse++; if ((p2parse > msgend) || ((msgend - p2parse) < (int)sizeof(uint64))) { dbgprintf("not a PAN-OS syslog message: too short\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* check log type */ log_type = *((uint64 *)p2parse); for (j = 0; j < (int)NUM_LOG_TYPES; j++) { if ((log_type & log_types[j].mask) == log_types[j].value) break; } if (j == NUM_LOG_TYPES) { dbgprintf("not a PAN-OS syslog message, log type: %llx\n", log_type); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* set the delimiter */ *f3_commas[0] = CSV_DELIMITER; *f3_commas[1] = CSV_DELIMITER; *f3_commas[2] = CSV_DELIMITER; p2target = p2parse; while (p2parse < msgend) { switch (state) { case STATE_FIELD_START: switch (*p2parse) { case '"': state = STATE_IN_QUOTE; p2parse++; break; case ',': state = STATE_FIELD_START; *p2target = CSV_DELIMITER; num_fields++; p2parse++; p2target++; break; default: state = STATE_IN_FIELD; *p2target = *p2parse; p2parse++; p2target++; } break; case STATE_IN_FIELD: switch (*p2parse) { case ',': state = STATE_FIELD_START; *p2target = CSV_DELIMITER; num_fields++; p2parse++; p2target++; break; default: *p2target = *p2parse; p2parse++; p2target++; } break; case STATE_IN_QUOTE: switch (*p2parse) { case '"': state = STATE_IN_QUOTE_QUOTE; p2parse++; break; default: *p2target = *p2parse; p2parse++; p2target++; } break; case STATE_IN_QUOTE_QUOTE: switch (*p2parse) { case '"': state = STATE_IN_QUOTE; *p2target = *p2parse; p2parse++; p2target++; break; case ',': state = STATE_FIELD_START; *p2target = CSV_DELIMITER; num_fields++; p2parse++; p2target++; break; default: dbgprintf("pmpanngfw: martian char (%d) after quote in quote\n", *p2parse); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } break; default: dbgprintf("how could I have reached this state ?!?\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } } if (p2parse != p2target) { lenDelta = p2parse - p2target; assert(lenDelta >= 2); *p2target = 0; pMsg->iLenRawMsg -= lenDelta; pMsg->iLenMSG -= lenDelta; } lenMsg = p2target - (pMsg->pszRawMsg + pMsg->offAfterPRI); DBGPRINTF("pmpanngfw: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); DBGPRINTF("pmpanngfw: # fields: %d\n", num_fields); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); finalize_it: ENDparse BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); DBGPRINTF("panngfw parser init called, compiled with version %s\n", VERSION); bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); /* cache value, is set only during rsyslogd option processing */ ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/contrib/pmpanngfw/PaxHeaders/README.md0000644000000000000000000000013215035412264017447 xustar0030 mtime=1752569012.331237145 30 atime=1764865110.805064305 30 ctime=1764935926.107621345 rsyslog-8.2512.0/contrib/pmpanngfw/README.md0000664000175000017500000001072515035412264017120 0ustar00rgerrger# pmpanngfw Module to detect and transform PAN-OS NGFW logs into a format compatible with mmnormalize ## How it works Original log: Apr 10 02:48:29 1,2012/04/10 02:48:29,001606001116,THREAT,url,1,2012/04/10 02:48:28,##IP##,##IP##,##IP##,##IP##,rule1,counselor,,facebook- base,vsys1,trust,untrust,ethernet1/2,ethernet1/1,forwardAll,2012/04/10 02:48:28,27555,1,8450,80,0,0,0x208000,tcp,alert,"www.facebook. com/ajax/pagelet/generic.php/ProfileTimelineSectionPagelet?__a=1&ajaxpipe=1&ajaxpipe_token=AXgw4BUd5yCuD2rQ&data={""profile_id"":603261604,""start"":1333263600,""end"":1335855599,""query_type"":5,""page_index"":1,""section_container_id"":""ucp7d6_26"",""section_pagelet_id"":""pagelet_timeline_recent"",""unit_container_id"":""ucp7d6_25"",""current_scrubber_key"":""recent"",""time_cutoff"":null,""buffer"":1300,""require_click"":false,""num_visible_units"":5,""remove_dupes"":true}&__user=857280013&__adt=3&__att=iframe",(9999),social-networking,informational,client-to-server,0,0x0,192.168.0.0-192.168.255.255,United States,0,text/html Transformed: Apr 10 02:48:29 12012/04/10 02:48:29001606001116THREATurl12012/04/10 02:48:28##IP####IP####IP####IP##rule1counselorfacebook-basevsys1trustuntrustethernet1/2ethernet1/1forwardAll 2012/04/10 02:48:28 27555184508000x208000tcp alertwww.facebook.com/ajax/pagelet/generic.php/ProfileTimelineSectionPagelet?__a=1&ajaxpipe=1&ajaxpipe_token=AXgw4BUd5yCuD2rQ&data={"profile_id":603261604,"start":1333263600,"end":1335855599,"query_type":5,"page_index":1,"section_container_id":"ucp7d6_26","section_pagelet_id":"pagelet_timeline_recent","unit_container_id":"ucp7d6_25","current_scrubber_key":"recent","time_cutoff":null,"buffer":1300,"require_click":false,"num_visible_units":5,"remove_dupes":true}&__user=857280013&__adt=3&__att=iframe(9999)social-networkinginformationalclient-to-server00x0192.168.0.0-192.168.255.255United States0text/html ## How to compile $ autoreconf -fvi $ ./configure --enable-pmpanngfw $ cd contrib/pmpanngfw/ $ make The resulting plugin should be found in contrib/pmpanngfw/.libs/ ## Example config module(load="imtcp") module(load="pmpanngfw") module(load="mmnormalize") module(load="omrabbitmq") template(name="csv" type="list") { property(name="$!src_ip" format="csv") constant(value=",") property(name="$!dest_ip" format="csv") constant(value=",") property(name="$!url") constant(value="\n") } $template alljson,"%$!all-json%\n" template(name="mmeld_json" type="list") { constant(value="{") property(outname="@timestamp" name="timestamp" format="jsonf" dateFormat="rfc3339") constant(value=",") property(outname="@source_host" name="source" format="jsonf") constant(value=",") property(outname="@message" name="msg" format="jsonf") constant(value=",") property(outname="@timegenerated" name="timegenerated" format="jsonf" dateFormat="rfc3339") constant(value=",") property(outname="@timereported" name="timereported" format="jsonf" dateFormat="rfc3339") constant(value=",") property(outname="src_ip" name="$!src_ip" format="jsonf") constant(value=",") property(outname="dest_ip" name="$!dest_ip" format="jsonf") constant(value=",") property(outname="url" name="$!url" format="jsonf") constant(value=",") property(outname="tags" name="$!event.tags" format="jsonf") constant(value="}") constant(value="\n") } ruleset(name="pan-ngfw" parser=["rsyslog.panngfw", "rsyslog.rfc5424", "rsyslog.rfc3164"]) { action(type="mmnormalize" rulebase="palo_alto_networks.rb" userawmsg="on") if strlen($!unparsed-data) == 0 then { if $!log_subtype == "url" then set $!url = $!misc; *.* action(type="omrabbitmq" host="localhost" virtual_host="/" user="guest" password="guest" exchange="mmeld-syslog" routing_key="" exchange_type="fanout" template="alljson") } *.* stop } input(type="imtcp" port="13514" ruleset="pan-ngfw") ## mmnormalize rulebase See https://gist.github.com/jtschichold/87f59b99d98c8eac1da5 rsyslog-8.2512.0/contrib/pmpanngfw/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316020237 xustar0030 mtime=1764935886.460014195 30 atime=1764935896.297164874 30 ctime=1764935926.105621314 rsyslog-8.2512.0/contrib/pmpanngfw/Makefile.in0000664000175000017500000006336715114544316017722 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/pmpanngfw ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) pmpanngfw_la_DEPENDENCIES = am_pmpanngfw_la_OBJECTS = pmpanngfw_la-pmpanngfw.lo pmpanngfw_la_OBJECTS = $(am_pmpanngfw_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pmpanngfw_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pmpanngfw_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pmpanngfw_la_SOURCES) DIST_SOURCES = $(pmpanngfw_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = pmpanngfw.la pmpanngfw_la_SOURCES = pmpanngfw.c pmpanngfw_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmpanngfw_la_LDFLAGS = -module -avoid-version pmpanngfw_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmpanngfw/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pmpanngfw/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pmpanngfw.la: $(pmpanngfw_la_OBJECTS) $(pmpanngfw_la_DEPENDENCIES) $(EXTRA_pmpanngfw_la_DEPENDENCIES) $(AM_V_CCLD)$(pmpanngfw_la_LINK) -rpath $(pkglibdir) $(pmpanngfw_la_OBJECTS) $(pmpanngfw_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pmpanngfw_la-pmpanngfw.lo: pmpanngfw.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmpanngfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmpanngfw_la-pmpanngfw.lo -MD -MP -MF $(DEPDIR)/pmpanngfw_la-pmpanngfw.Tpo -c -o pmpanngfw_la-pmpanngfw.lo `test -f 'pmpanngfw.c' || echo '$(srcdir)/'`pmpanngfw.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmpanngfw_la-pmpanngfw.Tpo $(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmpanngfw.c' object='pmpanngfw_la-pmpanngfw.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmpanngfw_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmpanngfw_la-pmpanngfw.lo `test -f 'pmpanngfw.c' || echo '$(srcdir)/'`pmpanngfw.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pmpanngfw_la-pmpanngfw.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/imczmq0000644000000000000000000000013115114544366015424 xustar0030 mtime=1764935926.815632183 29 atime=1764935930.17368359 30 ctime=1764935926.815632183 rsyslog-8.2512.0/contrib/imczmq/0000775000175000017500000000000015114544366015146 5ustar00rgerrgerrsyslog-8.2512.0/contrib/imczmq/PaxHeaders/README0000644000000000000000000000013215035412264016353 xustar0030 mtime=1752569012.326271887 30 atime=1764931141.767330702 30 ctime=1764935926.813632153 rsyslog-8.2512.0/contrib/imczmq/README0000664000175000017500000000206515035412264016022 0ustar00rgerrgerCZMQ Input Plugin REQUIREMENTS: * libsodium ( https://github.com/jedisct1/libsodium ) * zeromq v4.x build with libsodium support ( http://zeromq.org/ ) * czmq 3.x ( http://czmq.zeromq.org/ ) ------------------------------------------------------------------------------- module( load="imczmq" servercertpath="/etc/curve.d/server" clientcertpath="/etc/curve.d/" authtype="CURVESERVER" authenticator="on" ) input( type="imczmq" endpoints="@tcp://*:24555" socktype="PULL" ) ------------------------------------------------------------------------------- Explanation of Options: Module ------ servercertpath: path to server cert if using CURVE clientcertpath: path to client cert(s) if using CURVE authtype: CURVESERVER, CURVECLIENT (omit for no auth) authenticator: whether to start an authenticator thread Action ------ type: type of action (imczmq for this plugin) endpoints: comma delimited list of zeromq endpoints (see zeromq documentation) socktype: zeromq socket type (currently supports PULL, SUB, ROUTER, DISH, SERVER) authtype: CURVECLIENT or CURVESERVER rsyslog-8.2512.0/contrib/imczmq/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017527 xustar0030 mtime=1752569012.326271887 30 atime=1764930927.534793887 30 ctime=1764935926.808632076 rsyslog-8.2512.0/contrib/imczmq/Makefile.am0000664000175000017500000000033715035412264017176 0ustar00rgerrgerpkglib_LTLIBRARIES = imczmq.la imczmq_la_SOURCES = imczmq.c imczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) imczmq_la_LDFLAGS = -module -avoid-version imczmq_la_LIBADD = $(CZMQ_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/imczmq/PaxHeaders/imczmq.c0000644000000000000000000000013215055605325017143 xustar0030 mtime=1756826325.610800095 30 atime=1764931141.775330831 30 ctime=1764935926.816632199 rsyslog-8.2512.0/contrib/imczmq/imczmq.c0000664000175000017500000004552215055605325016617 0ustar00rgerrger/** * @file imczmq.c * @brief Input module for receiving messages via ZeroMQ. * * The module creates one or more CZMQ sockets according to the * configuration and converts each incoming frame into an rsyslog * message processed by the specified ruleset. Socket type, topics and * CURVE authentication parameters are fully configurable. * * Copyright (C) 2016 Brian Knox * Copyright (C) 2014 Rainer Gerhards * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include "cfsysline.h" #include "dirty.h" #include "errmsg.h" #include "glbl.h" #include "module-template.h" #include "msg.h" #include "net.h" #include "parser.h" #include "prop.h" #include "ruleset.h" #include "srUtils.h" #include "unicode-helper.h" #include MODULE_TYPE_INPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("imczmq"); DEF_IMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) static struct cnfparamdescr modpdescr[] = { {"authenticator", eCmdHdlrBinary, 0}, {"authtype", eCmdHdlrString, 0}, {"servercertpath", eCmdHdlrString, 0}, {"clientcertpath", eCmdHdlrString, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; struct modConfData_s { rsconf_t *pConf; instanceConf_t *root; instanceConf_t *tail; int authenticator; char *authType; char *serverCertPath; char *clientCertPath; }; struct instanceConf_s { bool serverish; int sockType; char *sockEndpoints; char *topics; uchar *pszBindRuleset; ruleset_t *pBindRuleset; struct instanceConf_s *next; }; struct listener_t { zsock_t *sock; ruleset_t *ruleset; }; static zlist_t *listenerList; static modConfData_t *runModConf = NULL; static prop_t *s_namep = NULL; static struct cnfparamdescr inppdescr[] = { {"endpoints", eCmdHdlrGetWord, 1}, {"socktype", eCmdHdlrGetWord, 1}, {"ruleset", eCmdHdlrGetWord, 0}, {"topics", eCmdHdlrGetWord, 0}, }; #include "im-helper.h" static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr}; static void setDefaults(instanceConf_t *iconf) { iconf->serverish = true; iconf->sockType = -1; iconf->sockEndpoints = NULL; iconf->topics = NULL; iconf->pszBindRuleset = NULL; iconf->pBindRuleset = NULL; iconf->next = NULL; }; /** * @brief Allocate a new listener configuration block. * * The new instance is initialized with default values and appended to * the module's list of listeners which will be activated when the * input starts. * * @param[out] pinst pointer receiving the allocated instance * @retval RS_RET_OK on success * @retval RS_RET_OUT_OF_MEMORY if allocation fails */ static rsRetVal createInstance(instanceConf_t **pinst) { DEFiRet; instanceConf_t *inst; CHKmalloc(inst = malloc(sizeof(instanceConf_t))); setDefaults(inst); if (runModConf->root == NULL || runModConf->tail == NULL) { runModConf->tail = runModConf->root = inst; } else { runModConf->tail->next = inst; runModConf->tail = inst; } *pinst = inst; finalize_it: RETiRet; } /** * @brief Create a CZMQ listener socket from the given configuration. * * The function initializes the socket, applies optional CURVE * authentication, subscribes to topics and attaches the socket to the * configured endpoints. The resulting listener structure is stored in * the global list used by the receiver loop. * * @param iconf configuration describing one listener * @retval RS_RET_OK on success * @retval RS_RET_ERR if socket setup fails */ static rsRetVal addListener(instanceConf_t *iconf) { DEFiRet; DBGPRINTF("imczmq: addListener called..\n"); struct listener_t *pData = NULL; CHKmalloc(pData = (struct listener_t *)malloc(sizeof(struct listener_t))); pData->ruleset = iconf->pBindRuleset; pData->sock = zsock_new(iconf->sockType); if (!pData->sock) { LogError(0, RS_RET_NO_ERRCODE, "imczmq: new socket failed for endpoints: %s", iconf->sockEndpoints); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } DBGPRINTF("imczmq: created socket of type %d..\n", iconf->sockType); if (runModConf->authType) { if (!strcmp(runModConf->authType, "CURVESERVER")) { DBGPRINTF("imczmq: we are a CURVESERVER\n"); zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if (!serverCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } zsock_set_zap_domain(pData->sock, "global"); zsock_set_curve_server(pData->sock, 1); zcert_apply(serverCert, pData->sock); zcert_destroy(&serverCert); } else if (!strcmp(runModConf->authType, "CURVECLIENT")) { DBGPRINTF("imczmq: we are a CURVECLIENT\n"); zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if (!serverCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } const char *server_key = zcert_public_txt(serverCert); zcert_destroy(&serverCert); zsock_set_curve_serverkey(pData->sock, server_key); zcert_t *clientCert = zcert_load(runModConf->clientCertPath); if (!clientCert) { LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->clientCertPath); ABORT_FINALIZE(RS_RET_ERR); } zcert_apply(clientCert, pData->sock); zcert_destroy(&clientCert); } } switch (iconf->sockType) { case ZMQ_SUB: #if defined(ZMQ_DISH) case ZMQ_DISH: #endif iconf->serverish = false; break; case ZMQ_PULL: #if defined(ZMQ_GATHER) case ZMQ_GATHER: #endif case ZMQ_ROUTER: #if defined(ZMQ_SERVER) case ZMQ_SERVER: #endif iconf->serverish = true; break; default: break; } if (iconf->topics) { // A zero-length topic means subscribe to everything if (!*iconf->topics && iconf->sockType == ZMQ_SUB) { DBGPRINTF("imczmq: subscribing to all topics\n"); zsock_set_subscribe(pData->sock, ""); } char topic[256]; while (*iconf->topics) { char *delimiter = strchr(iconf->topics, ','); if (!delimiter) { delimiter = iconf->topics + strlen(iconf->topics); } memcpy(topic, iconf->topics, delimiter - iconf->topics); topic[delimiter - iconf->topics] = 0; DBGPRINTF("imczmq: subscribing to %s\n", topic); if (iconf->sockType == ZMQ_SUB) { zsock_set_subscribe(pData->sock, topic); } #if defined(ZMQ_DISH) else if (iconf->sockType == ZMQ_DISH) { int rc = zsock_join(pData->sock, topic); if (rc != 0) { LogError(0, NO_ERRCODE, "could not join group %s", topic); ABORT_FINALIZE(RS_RET_ERR); } } #endif if (*delimiter == 0) { break; } iconf->topics = delimiter + 1; } } int rc = zsock_attach(pData->sock, (const char *)iconf->sockEndpoints, iconf->serverish); if (rc == -1) { LogError(0, NO_ERRCODE, "zsock_attach to %s failed", iconf->sockEndpoints); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: attached socket to %s\n", iconf->sockEndpoints); rc = zlist_append(listenerList, (void *)pData); if (rc != 0) { LogError(0, NO_ERRCODE, "could not append listener"); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: if (iRet != RS_RET_OK) { free(pData); } RETiRet; } /** * @brief Receive messages from all configured CZMQ listeners. * * Builds a poller for the active sockets, waits for incoming frames and * converts them into rsyslog messages which are then processed by the * listener's ruleset. Authentication actors are started when requested * and resources are cleaned up on termination. * * @retval RS_RET_OK on graceful shutdown * @retval RS_RET_ERR on initialization or runtime failure */ static rsRetVal rcvData(void) { DEFiRet; if (!listenerList) { listenerList = zlist_new(); if (!listenerList) { LogError(0, NO_ERRCODE, "could not allocate list"); ABORT_FINALIZE(RS_RET_ERR); } } zactor_t *authActor = NULL; if (runModConf->authenticator == 1) { authActor = zactor_new(zauth, NULL); zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); zsock_wait(authActor); } instanceConf_t *inst; for (inst = runModConf->root; inst != NULL; inst = inst->next) { CHKiRet(addListener(inst)); } zpoller_t *poller = zpoller_new(NULL); if (!poller) { LogError(0, NO_ERRCODE, "could not create poller"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: created poller\n"); struct listener_t *pData; pData = zlist_first(listenerList); if (!pData) { LogError(0, NO_ERRCODE, "imczmq: no listeners were " "started, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } while (pData) { int rc = zpoller_add(poller, pData->sock); if (rc != 0) { LogError(0, NO_ERRCODE, "imczmq: could not add " "socket to poller, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } pData = zlist_next(listenerList); } zsock_t *which = (zsock_t *)zpoller_wait(poller, -1); while (which) { if (zpoller_terminated(poller)) { break; } pData = zlist_first(listenerList); while (pData->sock != which) { pData = zlist_next(listenerList); } if (which == pData->sock) { DBGPRINTF("imczmq: found matching socket\n"); } zframe_t *frame = zframe_recv(which); char *buf = NULL; if (frame != NULL) buf = zframe_strdup(frame); zframe_destroy(&frame); if (buf == NULL) { DBGPRINTF("imczmq: null buffer\n"); continue; } smsg_t *pMsg; if (msgConstruct(&pMsg) == RS_RET_OK) { MsgSetRawMsg(pMsg, buf, strlen(buf)); MsgSetInputName(pMsg, s_namep); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, pData->ruleset); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; submitMsg2(pMsg); } free(buf); which = (zsock_t *)zpoller_wait(poller, -1); } finalize_it: zpoller_destroy(&poller); pData = zlist_first(listenerList); while (pData) { zsock_destroy(&pData->sock); free(pData->ruleset); pData = zlist_next(listenerList); } zlist_destroy(&listenerList); zactor_destroy(&authActor); RETiRet; } BEGINrunInput CODESTARTrunInput; iRet = rcvData(); ENDrunInput BEGINwillRun CODESTARTwillRun; CHKiRet(prop.Construct(&s_namep)); CHKiRet(prop.SetString(s_namep, UCHAR_CONSTANT("imczmq"), sizeof("imczmq") - 1)); CHKiRet(prop.ConstructFinalize(s_namep)); finalize_it: ENDwillRun BEGINafterRun CODESTARTafterRun; if (s_namep != NULL) { prop.Destruct(&s_namep); } ENDafterRun BEGINmodExit CODESTARTmodExit; objRelease(glbl, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); ENDmodExit BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURENonCancelInputTermination) { iRet = RS_RET_OK; } ENDisCompatibleWithFeature BEGINbeginCnfLoad CODESTARTbeginCnfLoad; runModConf = pModConf; runModConf->pConf = pConf; runModConf->authenticator = 0; runModConf->authType = NULL; runModConf->serverCertPath = NULL; runModConf->clientCertPath = NULL; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (NULL == pvals) { LogError(0, RS_RET_MISSING_CNFPARAMS, "imczmq: error processing module " "config parameters ['module(...)']"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } if (!strcmp(modpblk.descr[i].name, "authenticator")) { runModConf->authenticator = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "authtype")) { runModConf->authType = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "servercertpath")) { runModConf->serverCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(modpblk.descr[i].name, "clientcertpath")) { runModConf->clientCertPath = es_str2cstr(pvals[i].val.d.estr, NULL); } else { LogError(0, RS_RET_INVALID_PARAMS, "imczmq: config error, unknown " "param %s in setModCnf\n", modpblk.descr[i].name); } } DBGPRINTF("imczmq: authenticator set to %d\n", runModConf->authenticator); DBGPRINTF("imczmq: authType set to %s\n", runModConf->authType); DBGPRINTF("imczmq: serverCertPath set to %s\n", runModConf->serverCertPath); DBGPRINTF("imczmq: clientCertPath set to %s\n", runModConf->clientCertPath); finalize_it: if (pvals != NULL) { cnfparamvalsDestruct(pvals, &modpblk); } ENDsetModCnf BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad static inline void std_checkRuleset_genErrMsg(__attribute__((unused)) modConfData_t *modConf, instanceConf_t *inst) { LogError(0, NO_ERRCODE, "imczmq: ruleset '%s' for socket %s not found - " "using default ruleset instead", inst->pszBindRuleset, inst->sockEndpoints); } BEGINcheckCnf instanceConf_t *inst; CODESTARTcheckCnf; for (inst = pModConf->root; inst != NULL; inst = inst->next) { std_checkRuleset(pModConf, inst); } ENDcheckCnf BEGINactivateCnfPrePrivDrop CODESTARTactivateCnfPrePrivDrop; runModConf = pModConf; putenv((char *)"ZSYS_SIGHANDLER=false"); ENDactivateCnfPrePrivDrop BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *inst_r; CODESTARTfreeCnf; free(pModConf->authType); free(pModConf->serverCertPath); free(pModConf->clientCertPath); for (inst = pModConf->root; inst != NULL;) { free(inst->pszBindRuleset); free(inst->sockEndpoints); inst_r = inst; inst = inst->next; free(inst_r); } ENDfreeCnf BEGINnewInpInst struct cnfparamvals *pvals; instanceConf_t *inst; int i; CODESTARTnewInpInst; DBGPRINTF("newInpInst (imczmq)\n"); pvals = nvlstGetParams(lst, &inppblk, NULL); if (NULL == pvals) { LogError(0, RS_RET_MISSING_CNFPARAMS, "imczmq: required parameters are missing\n"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { DBGPRINTF("imczmq: input param blk:\n"); cnfparamsPrint(&inppblk, pvals); } CHKiRet(createInstance(&inst)); for (i = 0; i < inppblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } if (!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "endpoints")) { inst->sockEndpoints = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "topics")) { inst->topics = es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(inppblk.descr[i].name, "socktype")) { char *stringType = es_str2cstr(pvals[i].val.d.estr, NULL); if (NULL == stringType) { LogError(0, RS_RET_CONFIG_ERROR, "imczmq: out of memory error copying sockType param"); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } if (!strcmp("PULL", stringType)) { inst->sockType = ZMQ_PULL; } #if defined(ZMQ_GATHER) else if (!strcmp("GATHER", stringType)) { inst->sockType = ZMQ_GATHER; } #endif else if (!strcmp("SUB", stringType)) { inst->sockType = ZMQ_SUB; } #if defined(ZMQ_DISH) else if (!strcmp("DISH", stringType)) { inst->sockType = ZMQ_DISH; } #endif else if (!strcmp("ROUTER", stringType)) { inst->sockType = ZMQ_ROUTER; } #if defined(ZMQ_SERVER) else if (!strcmp("SERVER", stringType)) { inst->sockType = ZMQ_SERVER; } #endif free(stringType); } else { LogError(0, NO_ERRCODE, "imczmq: program error, non-handled " "param '%s'\n", inppblk.descr[i].name); } } finalize_it: CODE_STD_FINALIZERnewInpInst cnfparamvalsDestruct(pvals, &inppblk); ENDnewInpInst BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_IMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_PREPRIVDROP_QUERIES; CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/imczmq/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017541 xustar0030 mtime=1764935885.706002645 30 atime=1764935896.543168643 30 ctime=1764935926.811632122 rsyslog-8.2512.0/contrib/imczmq/Makefile.in0000664000175000017500000006317215114544315017216 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/imczmq ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = imczmq_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_imczmq_la_OBJECTS = imczmq_la-imczmq.lo imczmq_la_OBJECTS = $(am_imczmq_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = imczmq_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(imczmq_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/imczmq_la-imczmq.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(imczmq_la_SOURCES) DIST_SOURCES = $(imczmq_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = imczmq.la imczmq_la_SOURCES = imczmq.c imczmq_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CZMQ_CFLAGS) imczmq_la_LDFLAGS = -module -avoid-version imczmq_la_LIBADD = $(CZMQ_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/imczmq/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/imczmq/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } imczmq.la: $(imczmq_la_OBJECTS) $(imczmq_la_DEPENDENCIES) $(EXTRA_imczmq_la_DEPENDENCIES) $(AM_V_CCLD)$(imczmq_la_LINK) -rpath $(pkglibdir) $(imczmq_la_OBJECTS) $(imczmq_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imczmq_la-imczmq.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< imczmq_la-imczmq.lo: imczmq.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imczmq_la-imczmq.lo -MD -MP -MF $(DEPDIR)/imczmq_la-imczmq.Tpo -c -o imczmq_la-imczmq.lo `test -f 'imczmq.c' || echo '$(srcdir)/'`imczmq.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/imczmq_la-imczmq.Tpo $(DEPDIR)/imczmq_la-imczmq.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='imczmq.c' object='imczmq_la-imczmq.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(imczmq_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imczmq_la-imczmq.lo `test -f 'imczmq.c' || echo '$(srcdir)/'`imczmq.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/imczmq_la-imczmq.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/imczmq_la-imczmq.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omhttpfs0000644000000000000000000000013115114544372015765 xustar0030 mtime=1764935930.732692147 29 atime=1764935934.36574776 30 ctime=1764935930.732692147 rsyslog-8.2512.0/contrib/omhttpfs/0000775000175000017500000000000015114544372015507 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omhttpfs/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264020072 xustar0030 mtime=1752569012.330244093 30 atime=1764930929.172821687 29 ctime=1764935930.72569204 rsyslog-8.2512.0/contrib/omhttpfs/Makefile.am0000664000175000017500000000042515035412264017540 0ustar00rgerrgerpkglib_LTLIBRARIES = omhttpfs.la omhttpfs_la_SOURCES = omhttpfs.c omhttpfs_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBFASTJSON_CFLAGS) omhttpfs_la_LDFLAGS = -module -avoid-version omhttpfs_la_LIBADD = $(CURL_LIBS) $(LIBFASTJSON_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/omhttpfs/PaxHeaders/README.md0000644000000000000000000000013215035412264017316 xustar0030 mtime=1752569012.330244093 30 atime=1764865110.805064305 30 ctime=1764935930.730692116 rsyslog-8.2512.0/contrib/omhttpfs/README.md0000664000175000017500000000302015035412264016755 0ustar00rgerrgerOmHTTPFS === Author: sskaje ([sskaje@gmail.com](mailto:sskaje@gmail.com), [http://sskaje.me/](http://sskaje.me/)) OmHTTPFS is an Rsyslog plugin writing data to HDS via *Hadoop HDFS over HTTP*. ## Hadoop HDFS over HTTP Official site: [Hadoop HDFS over HTTP](http://hadoop.apache.org/docs/current/hadoop-hdfs-httpfs/index.html) HTTPFS is not well documented. I tried to read its source and write an [intro with examples](http://sskaje.me/2014/08/doc-for-httpfs/), until I found [Administering the file system by using HttpFS REST APIs](http://www-01.ibm.com/support/knowledgecenter/SSPT3X_2.1.2/com.ibm.swg.im.infosphere.biginsights.admin.doc/doc/admin_fileupload_rest_apis.html) by IBM. ## OmHDFS for Rsyslog Rsyslog provides a plugin named omHDFS which requires lots of work compiling and configuring, and it's not that usable. Here is what I tried before writing this omhttpfs: [Build omhdfs for Rsyslog](http://sskaje.me/2014/08/build-omhdfs-rsyslog/). ## Rsyslog config Legacy config **NOT** supported. Example: ``` module(load="omhttpfs") template(name="hdfs_tmp_file" type="string" string="/tmp/%$YEAR%/test.log") template(name="hdfs_tmp_filecontent" type="string" string="%$YEAR%-%$MONTH%-%$DAY% %MSG% ==\n") local4.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on") local5.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on" template="hdfs_tmp_filecontent") ``` Tested with CDH 5.2.0 + Rsyslog 8.6.0 on CentOS 7 \# EOF rsyslog-8.2512.0/contrib/omhttpfs/PaxHeaders/omhttpfs.c0000644000000000000000000000013215055605325020053 xustar0030 mtime=1756826325.614800155 30 atime=1764931102.043688342 30 ctime=1764935930.733692162 rsyslog-8.2512.0/contrib/omhttpfs/omhttpfs.c0000664000175000017500000005701015055605325017522 0ustar00rgerrger/* omhttpfs.c * Send all output to HDFS via httpfs * * Author: sskaje (sskaje@gmail.com, http://sskaje.me/) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "datetime.h" #include "statsobj.h" #include "unicode-helper.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omhttpfs") /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) /* local definitions */ #define OMHTTPFS_VERSION "1.0" #define OMHTTPFS_DEFAULT_PORT 14000 #define OMHTTPFS_DEFAULT_USER "hdfs" #define OMHTTPFS_DEFAULT_HOST "127.0.0.1" #define HTTPFS_URL_PREFIX_V1 "/webhdfs/v1" #define HTTPFS_URL_PREFIX_V1_SSL "/swebhdfs/v1" #define HTTPFS_CONTENT_TYPE "Content-Type: application/octet-stream" #define HTTPFS_USER_AGENT "omhttpfs by sskaje/" OMHTTPFS_VERSION #define HTTPFS_CONTENT_TYPE_JSON "application/json" #define HTTPFS_JSON_BOOLEAN_TRUE "{\"boolean\":true}" #define HTTPFS_FILEALREADYEXISTSEXCEPTION "FileAlreadyExistsException" #define HTTPFS_URL_BUFFER_LENGTH 2048 /* Examples: module(load="omhttpfs") template(name="hdfs_tmp_file" type="string" string="/tmp/%$YEAR%/test.log") template(name="hdfs_tmp_filecontent" type="string" string="%$YEAR%-%$MONTH%-%$DAY% %MSG% ==\n") local4.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on") local5.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on" template="hdfs_tmp_filecontent") */ #define DPP(x) DBGPRINTF("OMHTTPFS: %s:%d %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, x) /** * Exception object * */ typedef struct _HTTPFS_JSON_REMOTE_EXCEPTION { char message[1024]; char exception[256]; char class[256]; } httpfs_json_remote_exception; typedef struct _instanceData { sbool https; uchar* host; uchar* ip; int port; uchar* user; int timeout; uchar* file; sbool isDynFile; uchar* tplName; } instanceData; typedef struct wrkrInstanceData { instanceData* pData; CURL* curl; uchar* file; int replyLen; char* reply; } wrkrInstanceData_t; /* tables for interfacing with the v6 config system */ /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"host", eCmdHdlrGetWord, 0}, {"port", eCmdHdlrInt, 0}, {"user", eCmdHdlrGetWord, 0}, {"https", eCmdHdlrBinary, 0}, {"file", eCmdHdlrGetWord, CNFPARAM_REQUIRED}, {"isdynfile", eCmdHdlrBinary, 0}, {"template", eCmdHdlrGetWord, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /** * curl init * * @param wrkrInstanceData_t *pWrkrData * @param instanceData *pData * @return rsRetVal */ static rsRetVal httpfs_init_curl(wrkrInstanceData_t* pWrkrData, instanceData* pData) { CURL* curl = NULL; curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); if (pData->https) { DBGPRINTF("%s(): Enable HTTPS\n", __FUNCTION__); /* for ssl */ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); } } else { /* LOG */ LogError(0, RS_RET_OBJ_CREATION_FAILED, "omhttpfs: failed to init cURL\n"); return RS_RET_OBJ_CREATION_FAILED; } curl_easy_setopt(curl, CURLOPT_USERAGENT, HTTPFS_USER_AGENT); pWrkrData->curl = curl; return RS_RET_OK; } /** * Build HTTPFS URL * * @param wrkrInstanceData_t *pWrkrData * @param char* op * @param es_str_t** url_buf * @return rsRetVal */ static rsRetVal httpfs_build_url(wrkrInstanceData_t* pWrkrData, const char* op, es_str_t** url_buf) { *url_buf = es_newStr(HTTPFS_URL_BUFFER_LENGTH); if (pWrkrData->pData->https) { es_addBuf(url_buf, "https://", sizeof("https://") - 1); } else { es_addBuf(url_buf, "http://", sizeof("http://") - 1); } /* host */ es_addBuf(url_buf, (char*)pWrkrData->pData->host, strlen((char*)pWrkrData->pData->host)); /* port */ es_addChar(url_buf, ':'); char portBuf[6]; snprintf(portBuf, sizeof(portBuf), "%d", pWrkrData->pData->port); es_addBuf(url_buf, portBuf, strlen(portBuf)); /* prefix */ es_addBuf(url_buf, HTTPFS_URL_PREFIX_V1, sizeof(HTTPFS_URL_PREFIX_V1) - 1); /* path */ if (pWrkrData->file[0] != '/') { es_addChar(url_buf, '/'); } es_addBuf(url_buf, (char*)pWrkrData->file, strlen((char*)pWrkrData->file)); /* queries */ /* user */ es_addBuf(url_buf, "?user.name=", sizeof("?user.name=") - 1); es_addBuf(url_buf, (char*)pWrkrData->pData->user, strlen((char*)pWrkrData->pData->user)); /* extra parameters */ es_addBuf(url_buf, op, strlen(op)); return RS_RET_OK; } /** * curl set URL * * @param wrkrInstanceData_t *pWrkrData * @param char* op * @return void */ static void httpfs_set_url(wrkrInstanceData_t* pWrkrData, const char* op) { es_str_t* url; char* url_cstr; httpfs_build_url(pWrkrData, op, &url); url_cstr = es_str2cstr(url, NULL); curl_easy_setopt(pWrkrData->curl, CURLOPT_URL, url_cstr); free(url_cstr); } /** * Set http method to PUT * * @param CURL* curl * @return void */ static void httpfs_curl_set_put(CURL* curl) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L); curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); curl_easy_setopt(curl, CURLOPT_POST, 0L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); } /** * Set http method to POST * * @param CURL* curl * @return void */ static void httpfs_curl_set_post(CURL* curl) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 0L); curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L); curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); } /** * Build curl slist * * @param struct curl_slist* headers * @param int hdr_count * @param ... * @return struct curl_slist* */ static struct curl_slist* httpfs_curl_add_header(struct curl_slist* headers, int hdr_count, ...) { const char* hdr; va_list ar; va_start(ar, hdr_count); for (; hdr_count > 0; hdr_count--) { hdr = va_arg(ar, const char*); if (hdr != NULL && hdr[0] != 0) { /* non-empty string */ headers = curl_slist_append(headers, hdr); } else { break; } } va_end(ar); headers = curl_slist_append(headers, "Expect:"); headers = curl_slist_append(headers, "Transfer-Encoding:"); return headers; } /** * Callback function for CURLOPT_WRITEFUNCTION * * @param void* contents * @param size_t size * @param size_t nmemb * @param void *userp * @return size_t */ static size_t httpfs_curl_result_callback(void* contents, size_t size, size_t nmemb, void* userp) { size_t realsize = size * nmemb; char* newreply = NULL; wrkrInstanceData_t* mem = (wrkrInstanceData_t*)userp; newreply = realloc(mem->reply, mem->replyLen + realsize + 1); if (newreply == NULL) { /* out of memory! */ dbgprintf("not enough memory (realloc returned NULL)\n"); if (mem->reply != NULL) free(mem->reply); mem->reply = NULL; mem->replyLen = 0; return 0; } mem->reply = newreply; memcpy(&(mem->reply[mem->replyLen]), contents, realsize); mem->replyLen += realsize; mem->reply[mem->replyLen] = 0; return realsize; } /** * Variables declaration * used in httpfs related operation */ #define HTTPFS_CURL_VARS_INIT \ struct curl_slist* headers = NULL; \ long response_code; \ CURLcode res; \ char* content_type; /** * Resource release * used in httpfs related operation */ #define HTTPFS_CURL_VARS_RELEASE curl_slist_free_all(headers); /** * Curl execution * used in httpfs related operation */ #define HTTPFS_CURL_EXEC \ pWrkrData->reply = NULL; \ pWrkrData->replyLen = 0; \ curl_easy_setopt(pWrkrData->curl, CURLOPT_WRITEDATA, pWrkrData); \ curl_easy_setopt(pWrkrData->curl, CURLOPT_WRITEFUNCTION, httpfs_curl_result_callback); \ res = curl_easy_perform(pWrkrData->curl); \ if (res == CURLE_OK) { \ curl_easy_getinfo(pWrkrData->curl, CURLINFO_CONTENT_TYPE, &content_type); \ if (strncmp(content_type, HTTPFS_CONTENT_TYPE_JSON, strlen(HTTPFS_CONTENT_TYPE_JSON))) { \ } \ curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); \ if (pWrkrData->reply != NULL) { \ pWrkrData->reply[pWrkrData->replyLen] = '\0'; \ } \ } else { \ LogError(0, RS_RET_ERR, "CURL request fail, code=%d, error string=%s\n", res, curl_easy_strerror(res)); \ return -1; \ } /** * Parse remote exception json string * * @param char* buf * @param int length * @param httpfs_json_remote_exception* jre * @return rsRetVal */ static rsRetVal httpfs_parse_exception(char* buf, int length, httpfs_json_remote_exception* jre) { DEFiRet; if (!length) { return RS_RET_JSON_PARSE_ERR; } struct json_tokener* jt = json_tokener_new(); json_tokener_reset(jt); struct json_object* json; json = json_tokener_parse_ex(jt, buf, length); if (!json_object_is_type(json, json_type_object)) { ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); } if (!json_object_object_get_ex(json, "RemoteException", &json)) { ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR); } struct json_object* jobj; memset(jre, 0, sizeof(*jre)); const char* str; json_object_object_get_ex(json, "javaClassName", &jobj); str = json_object_get_string(jobj); strncpy(jre->class, str, sizeof(jre->class)); jre->class[sizeof(jre->class) - 1] = '\0'; json_object_object_get_ex(json, "exception", &jobj); str = json_object_get_string(jobj); strncpy(jre->exception, str, sizeof(jre->exception)); jre->exception[sizeof(jre->exception) - 1] = '\0'; json_object_object_get_ex(json, "message", &jobj); str = json_object_get_string(jobj); strncpy(jre->message, str, sizeof(jre->message)); jre->message[sizeof(jre->message) - 1] = '\0'; finalize_it: if (jt != NULL) json_tokener_free(jt); if (json != NULL) json_object_put(json); RETiRet; } /** * Create a file * op=CREATE * overwrite is turned off * * @param wrkrInstanceData_t *pWrkrData * @param char* buf * @return rsRetVal */ static rsRetVal httpfs_create_file(wrkrInstanceData_t* pWrkrData, uchar* buf) { /* httpfs.create automatically create folders, no mkdirs needed. */ /* curl -b /tmp/c.tmp -c /tmp/c.tmp -d 'aaaaabbbbb' -i -H 'Content-Type: application/octet-stream' -X PUT \ 'http://172.16.3.20:14000/webhdfs/v1/tmp/a/b?user.name=hdfs&op=create&data=true' */ HTTPFS_CURL_VARS_INIT DBGPRINTF("%s(): file=%s\n", __FUNCTION__, pWrkrData->file); httpfs_curl_set_put(pWrkrData->curl); /* overwrite - if a file with this name already exists, then if true, the file will be overwritten, and if false an error will be thrown. bufferSize - the size of the buffer to be used. replication - required block replication for the file. */ httpfs_set_url(pWrkrData, "&op=create&overwrite=false&data=true"); curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDS, (char*)buf); curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDSIZE, strlen((char*)buf)); DBGPRINTF("%s(): msg=%s\n", __FUNCTION__, buf); headers = httpfs_curl_add_header(headers, 1, HTTPFS_CONTENT_TYPE); curl_easy_setopt(pWrkrData->curl, CURLOPT_HTTPHEADER, headers); HTTPFS_CURL_EXEC int success = 0; if (response_code == 201) { success = 1; } HTTPFS_CURL_VARS_RELEASE if (success) { return RS_RET_OK; } else { return RS_RET_FALSE; } } /** * Append to file * op=APPEND * * @param wrkrInstanceData_t *pWrkrData * @param char* buf * @return rsRetVal */ static rsRetVal httpfs_append_file(wrkrInstanceData_t* pWrkrData, uchar* buf) { /* curl -b /tmp/c.tmp -c /tmp/c.tmp -d 'aaaaabbbbb' -i -H 'Content-Type: application/octet-stream' \ 'http://172.16.3.20:14000/webhdfs/v1/tmp/a/b?user.name=hdfs&op=append&data=true' */ HTTPFS_CURL_VARS_INIT DBGPRINTF("%s(): file=%s\n", __FUNCTION__, pWrkrData->file); httpfs_curl_set_post(pWrkrData->curl); httpfs_set_url(pWrkrData, "&op=append&data=true"); curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDS, (char*)buf); curl_easy_setopt(pWrkrData->curl, CURLOPT_POSTFIELDSIZE, strlen((char*)buf)); headers = httpfs_curl_add_header(headers, 1, HTTPFS_CONTENT_TYPE); curl_easy_setopt(pWrkrData->curl, CURLOPT_HTTPHEADER, headers); DBGPRINTF("%s(): msg=%s\n", __FUNCTION__, buf); HTTPFS_CURL_EXEC int success = 0; if (response_code == 200) { success = 1; } else if (response_code == 404) { /* TODO: 404 ? */ } HTTPFS_CURL_VARS_RELEASE if (success) { return RS_RET_OK; } else { return RS_RET_FALSE; } } /** * httpfs log * * @param wrkrInstanceData_t *pWrkrData * @param uchar* buf * @return rsRetVal */ static rsRetVal httpfs_log(wrkrInstanceData_t* pWrkrData, uchar* buf) { /** append ? 200/end : (404 || ?) create & ~overwrite ? 201/200/end : append ? 200/end : error ? */ DEFiRet; long response_code; httpfs_json_remote_exception jre; iRet = httpfs_append_file(pWrkrData, buf); if (iRet == RS_RET_OK) { DBGPRINTF("omhttpfs: Append success: %s\n", pWrkrData->file); return RS_RET_OK; } curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); if (response_code != 404) { /* TODO: log error */ DBGPRINTF("omhttpfs: Append fail HTTP %ld: %s\n", response_code, pWrkrData->file); return RS_RET_FALSE; } iRet = httpfs_create_file(pWrkrData, buf); if (iRet == RS_RET_OK) { DBGPRINTF("omhttpfs: Create file success: %s\n", pWrkrData->file); return RS_RET_OK; } curl_easy_getinfo(pWrkrData->curl, CURLINFO_RESPONSE_CODE, &response_code); if (response_code == 201) { DBGPRINTF("omhttpfs: Create file success HTTP 201: %s\n", pWrkrData->file); return RS_RET_OK; } if (response_code == 500) { DBGPRINTF("omhttpfs: Create file failed HTTP %ld: %s\n", response_code, pWrkrData->file); httpfs_parse_exception(pWrkrData->reply, pWrkrData->replyLen, &jre); if (!strncmp(jre.exception, HTTPFS_FILEALREADYEXISTSEXCEPTION, strlen(HTTPFS_FILEALREADYEXISTSEXCEPTION))) { /* file exists, go to append */ DBGPRINTF("omhttpfs: File already exists, append again: %s\n", pWrkrData->file); iRet = httpfs_append_file(pWrkrData, buf); if (iRet == RS_RET_OK) { DBGPRINTF("omhttpfs: Re-Append success: %s\n", pWrkrData->file); return RS_RET_OK; } else { DBGPRINTF("omhttpfs: Re-Append failed: %s\n", pWrkrData->file); /* error exit */ } } else { DBGPRINTF("omhttpfs: Create file failed: %s %s\n", pWrkrData->file, pWrkrData->reply); } } else { DBGPRINTF("omhttpfs: Create file failed: %s %s\n", pWrkrData->file, pWrkrData->reply); } return RS_RET_FALSE; } BEGINinitConfVars CODESTARTinitConfVars; ENDinitConfVars BEGINcreateInstance CODESTARTcreateInstance; DBGPRINTF("omhttpfs: createInstance\n"); ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; DBGPRINTF("omhttpfs: createWrkrInstance\n"); pWrkrData->curl = NULL; iRet = httpfs_init_curl(pWrkrData, pWrkrData->pData); DBGPRINTF("omhttpfs: createWrkrInstance,pData %p/%p, pWrkrData %p\n", pData, pWrkrData->pData, pWrkrData); ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; free(pData->file); free(pData->tplName); free(pData->host); free(pData->user); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; free(pWrkrData->file); if (pWrkrData->curl) { curl_easy_cleanup(pWrkrData->curl); pWrkrData->curl = NULL; } ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; DBGPRINTF("OmHTTPFS\n"); DBGPRINTF("Version: %s\n", OMHTTPFS_VERSION); DBGPRINTF("\tHost: %s\n", pData->host); DBGPRINTF("\tPort: %d\n", pData->port); DBGPRINTF("\tUser: %s\n", pData->user); DBGPRINTF("\tFile: %s\n", pData->file); ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; DBGPRINTF("omhttpfs: tryResume called\n"); /* TODO: test networking */ iRet = RS_RET_OK; ENDtryResume /** * Do Action */ BEGINdoAction CODESTARTdoAction; DBGPRINTF("omhttpfs: doAction\n"); /* dynamic file name */ if (pWrkrData->pData->isDynFile) { pWrkrData->file = ustrdup(ppString[1]); } else { pWrkrData->file = ustrdup(pWrkrData->pData->file); } /* ppString[0] -> log content */ iRet = httpfs_log(pWrkrData, ppString[0]); if (iRet != RS_RET_OK) { DBGPRINTF("omhttpfs: error writing httpfs, suspending\n"); iRet = RS_RET_SUSPENDED; } ENDdoAction /** * Set default parameters * * @param instanceData *pData * @return void */ static void setInstParamDefaults(instanceData* pData) { pData->host = (uchar*)strdup(OMHTTPFS_DEFAULT_HOST); pData->port = OMHTTPFS_DEFAULT_PORT; pData->user = (uchar*)strdup(OMHTTPFS_DEFAULT_USER); pData->https = 0; pData->file = NULL; pData->isDynFile = 0; pData->tplName = NULL; } BEGINnewActInst struct cnfparamvals* pvals; int i; uchar* tplToUse; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "host")) { pData->host = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "port")) { pData->port = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "user")) { pData->user = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "https")) { pData->https = pvals[i].val.d.n ? 1 : 0; } else if (!strcmp(actpblk.descr[i].name, "file")) { pData->file = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "isdynfile")) { pData->isDynFile = pvals[i].val.d.n ? 1 : 0; } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else { DBGPRINTF("omhttpfs: program error, non-handled param '%s'\n", actpblk.descr[i].name); } } if (pData->file == NULL) { /* Note: this is primarily to make clang static analyzer happy, as we * request via pblk that file is a mandatory parameter. However, this is * also a guard against something going really wrong... */ LogError(0, RS_RET_INTERNAL_ERROR, "omhttpfs: file is not set " "[this should not be possible]\n"); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); } if (pData->user == NULL || pData->user[0] == '\0') { pData->user = ustrdup((uchar*)OMHTTPFS_DEFAULT_USER); } if (pData->host == NULL || pData->host[0] == '\0') { pData->host = ustrdup((uchar*)OMHTTPFS_DEFAULT_HOST); } if (pData->isDynFile) { CODE_STD_STRING_REQUESTparseSelectorAct(2) CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->file), OMSR_NO_RQD_TPL_OPTS)); } else { CODE_STD_STRING_REQUESTparseSelectorAct(1) } tplToUse = ustrdup((pData->tplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pData->tplName); iRet = OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst NO_LEGACY_CONF_parseSelectorAct /** * Module Exit */ BEGINmodExit CODESTARTmodExit; /* */ curl_global_cleanup(); /* release what we no longer need */ objRelease(datetime, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); ENDmodExit /** * Query Entry Point */ BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES; ENDqueryEtryPt /** * Module Init */ BEGINmodInit() CODESTARTmodInit; INITLegCnfVars; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr /* tell which objects we need */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); if (curl_global_init(CURL_GLOBAL_ALL) != 0) { LogError(0, RS_RET_OBJ_CREATION_FAILED, "CURL fail. -httpfs module init failed"); ABORT_FINALIZE(RS_RET_OBJ_CREATION_FAILED); } DBGPRINTF("omhttpfs version %s is initializing\n", OMHTTPFS_VERSION); ENDmodInit rsyslog-8.2512.0/contrib/omhttpfs/PaxHeaders/Makefile.in0000644000000000000000000000013115114544316020105 xustar0029 mtime=1764935886.28601153 30 atime=1764935896.697171001 30 ctime=1764935930.728692086 rsyslog-8.2512.0/contrib/omhttpfs/Makefile.in0000664000175000017500000006346415114544316017567 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omhttpfs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omhttpfs_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_omhttpfs_la_OBJECTS = omhttpfs_la-omhttpfs.lo omhttpfs_la_OBJECTS = $(am_omhttpfs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omhttpfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omhttpfs_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omhttpfs_la_SOURCES) DIST_SOURCES = $(omhttpfs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ README.md DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omhttpfs.la omhttpfs_la_SOURCES = omhttpfs.c omhttpfs_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(CURL_CFLAGS) $(LIBFASTJSON_CFLAGS) omhttpfs_la_LDFLAGS = -module -avoid-version omhttpfs_la_LIBADD = $(CURL_LIBS) $(LIBFASTJSON_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhttpfs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omhttpfs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omhttpfs.la: $(omhttpfs_la_OBJECTS) $(omhttpfs_la_DEPENDENCIES) $(EXTRA_omhttpfs_la_DEPENDENCIES) $(AM_V_CCLD)$(omhttpfs_la_LINK) -rpath $(pkglibdir) $(omhttpfs_la_OBJECTS) $(omhttpfs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omhttpfs_la-omhttpfs.lo: omhttpfs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttpfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhttpfs_la-omhttpfs.lo -MD -MP -MF $(DEPDIR)/omhttpfs_la-omhttpfs.Tpo -c -o omhttpfs_la-omhttpfs.lo `test -f 'omhttpfs.c' || echo '$(srcdir)/'`omhttpfs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhttpfs_la-omhttpfs.Tpo $(DEPDIR)/omhttpfs_la-omhttpfs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhttpfs.c' object='omhttpfs_la-omhttpfs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhttpfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhttpfs_la-omhttpfs.lo `test -f 'omhttpfs.c' || echo '$(srcdir)/'`omhttpfs.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omhttpfs_la-omhttpfs.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/fmhash0000644000000000000000000000013115114544370015365 xustar0030 mtime=1764935928.135652391 29 atime=1764935930.17368359 30 ctime=1764935928.135652391 rsyslog-8.2512.0/contrib/fmhash/0000775000175000017500000000000015114544370015107 5ustar00rgerrgerrsyslog-8.2512.0/contrib/fmhash/PaxHeaders/fmhash.c0000644000000000000000000000013215055605325017057 xustar0030 mtime=1756826325.610800095 30 atime=1764931078.585306406 30 ctime=1764935928.135652391 rsyslog-8.2512.0/contrib/fmhash/fmhash.c0000664000175000017500000003036115055605325016526 0ustar00rgerrger/* * Copyright (c) 2018, Harshvardhan Shrivastava * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of the original author; nor the names of any contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include #ifndef _AIX #include #endif #include #include #ifdef USE_HASH_XXHASH #include #endif #include "rsyslog.h" #include "parserif.h" #include "module-template.h" #include "rainerscript.h" MODULE_TYPE_FUNCTION MODULE_TYPE_NOKEEP; DEF_FMOD_STATIC_DATA; typedef uint64_t hash_t; typedef uint32_t seed_t; typedef struct hash_context_s hash_context_t; typedef hash_t (*hash_impl)(const void *, size_t, seed_t); typedef rsRetVal (*hash_wrapper_2)(struct svar *__restrict__ const, struct svar *__restrict__ const, hash_context_t *, hash_t *); typedef rsRetVal (*hash_wrapper_3)(struct svar *__restrict__ const, struct svar *__restrict__ const, struct svar *__restrict__ const, hash_context_t *, hash_t *); struct hash_context_s { hash_impl hashXX; hash_wrapper_2 hash_wrapper_1_2; hash_wrapper_3 hash_wrapper_2_3; }; /* * Fowler–Noll–Vo hash 32 bit * http://www.isthe.com/chongo/src/fnv/hash_32.c */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif static hash_t #if defined(__clang__) __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif fnv_32(const void *input, size_t len, seed_t seed) { unsigned char *bp = (unsigned char *)input; /* start of buffer */ /* * FNV-1 hash each octet in the buffer */ size_t i; for (i = 0; i < len; i++) { /* multiply by the 32 bit FNV magic prime mod 2^32 */ seed += (seed << 1) + (seed << 4) + (seed << 7) + (seed << 8) + (seed << 24); /* xor the bottom with the current octet */ seed ^= (seed_t)*bp++; } /* return our new hash value */ return seed; } /* * Modified Bernstein * http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif static hash_t #if defined(__clang__) __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif djb_hash(const void *input, size_t len, seed_t seed) { const char *p = input; hash_t hash = 5381; size_t i; for (i = 0; i < len; i++) { hash = 33 * hash ^ p[i]; } return hash + seed; } /*Get 32 bit hash for input*/ static hash_t hash32(const void *input, size_t len, seed_t seed) { hash_t xhash = 0; #ifdef USE_HASH_XXHASH xhash = XXH32(input, len, seed); #else xhash = fnv_32(input, len, seed); #endif return xhash; } /*Get 64 bit hash for input*/ static hash_t hash64(const void *input, size_t len, seed_t seed) { hash_t xhash = 0; #ifdef USE_HASH_XXHASH xhash = XXH64(input, len, seed); #else xhash = djb_hash(input, len, seed); #endif return xhash; } static rsRetVal hash_wrapper2(struct svar *__restrict__ const sourceVal, struct svar *__restrict__ const seedVal, hash_context_t *hcontext, hash_t *xhash) { DEFiRet; int freeHashStr = 0, success = 0; char *hashStr = NULL; seed_t seed = 0; if (seedVal) { seed = var2Number(seedVal, &success); if (!success) { parser_warnmsg( "fmhash: hashXX(string, seed) didn't get a valid 'seed' limit" ", defaulting hash value to 0"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } } hashStr = (char *)var2CString(sourceVal, &freeHashStr); size_t len = strlen(hashStr); (*xhash) = hcontext->hashXX(hashStr, len, seed); DBGPRINTF("fmhash: hashXX generated hash %" PRIu64 " for string(%.*s)", (*xhash), (int)len, hashStr); finalize_it: if (freeHashStr) { free(hashStr); } RETiRet; } static rsRetVal hash_wrapper3(struct svar *__restrict__ const sourceVal, struct svar *__restrict__ const modVal, struct svar *__restrict__ const seedVal, hash_context_t *hcontext, hash_t *xhash) { DEFiRet; int success = 0; hash_t mod = var2Number(modVal, &success); if (!success) { parser_warnmsg( "fmhash: hashXXmod(string, mod)/hash64mod(string, mod, seed) didn't" " get a valid 'mod' limit, defaulting hash value to 0"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } if (mod == 0) { parser_warnmsg( "fmhash: hashXXmod(string, mod)/hash64mod(string, mod, seed) invalid" ", 'mod' is zero, , defaulting hash value to 0"); ABORT_FINALIZE(RS_RET_PARAM_ERROR); } CHKiRet((hcontext->hash_wrapper_1_2(sourceVal, seedVal, hcontext, xhash))); if (mod != 0) { (*xhash) = (*xhash) % mod; } DBGPRINTF("fmhash: hashXXmod generated hash-mod %" PRIu64 ".", (*xhash)); finalize_it: RETiRet; } static void init_hash32_context(hash_context_t *hash32_context) { hash32_context->hashXX = hash32; hash32_context->hash_wrapper_1_2 = hash_wrapper2; hash32_context->hash_wrapper_2_3 = hash_wrapper3; }; static void init_hash64_context(hash_context_t *hash64_context) { hash64_context->hashXX = hash64; hash64_context->hash_wrapper_1_2 = hash_wrapper2; hash64_context->hash_wrapper_2_3 = hash_wrapper3; }; static void ATTR_NONNULL() fmHashXX(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { DEFiRet; struct svar hashStrVal; struct svar seedVal; hash_context_t *hcontext = NULL; hash_t xhash = 0; cnfexprEval(func->expr[0], &hashStrVal, usrptr, pWti); if (func->nParams == 2) cnfexprEval(func->expr[1], &seedVal, usrptr, pWti); ret->d.n = 0; ret->datatype = 'N'; hcontext = (hash_context_t *)func->funcdata; CHKiRet((hcontext->hash_wrapper_1_2(&hashStrVal, (func->nParams == 2 ? &seedVal : NULL), hcontext, &xhash))); ret->d.n = xhash; finalize_it: varFreeMembers(&hashStrVal); if (func->nParams == 2) varFreeMembers(&seedVal); } static void ATTR_NONNULL() fmHashXXmod(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { DEFiRet; struct svar hashStrVal; struct svar modVal; struct svar seedVal; hash_context_t *hcontext = NULL; hash_t xhash = 0; cnfexprEval(func->expr[0], &hashStrVal, usrptr, pWti); cnfexprEval(func->expr[1], &modVal, usrptr, pWti); if (func->nParams == 3) cnfexprEval(func->expr[2], &seedVal, usrptr, pWti); ret->d.n = 0; ret->datatype = 'N'; hcontext = (hash_context_t *)func->funcdata; CHKiRet((hcontext->hash_wrapper_2_3(&hashStrVal, &modVal, func->nParams > 2 ? &seedVal : NULL, hcontext, &xhash))); ret->d.n = xhash; finalize_it: varFreeMembers(&hashStrVal); varFreeMembers(&modVal); if (func->nParams == 3) varFreeMembers(&seedVal); } static inline sbool check_param_count_hash(unsigned short nParams) { return (nParams != 1 && nParams != 2); } static inline sbool check_param_count_hashmod(unsigned short nParams) { return (nParams != 2 && nParams != 3); } static rsRetVal ATTR_NONNULL(1) init_fmHash64(struct cnffunc *const func) { DEFiRet; hash_context_t *hash_context = NULL; if (check_param_count_hash(func->nParams)) { parser_errmsg( "fmhash: hash64(string) / hash64(string, seed)" " insufficient params.\n"); ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); } func->destructable_funcdata = 1; CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); init_hash64_context(hash_context); func->funcdata = (void *)hash_context; finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) init_fmHash64mod(struct cnffunc *const func) { DEFiRet; hash_context_t *hash_context = NULL; if (check_param_count_hashmod(func->nParams)) { parser_errmsg( "fmhash: hash64mod(string, mod)/hash64mod(string, mod, seed)" " insufficient params.\n"); ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); } func->destructable_funcdata = 1; CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); init_hash64_context(hash_context); func->funcdata = (void *)hash_context; finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) init_fmHash32(struct cnffunc *const func) { DEFiRet; hash_context_t *hash_context = NULL; if (check_param_count_hash(func->nParams)) { parser_errmsg( "fmhash: hash32(string) / hash32(string, seed)" " insufficient params.\n"); ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); } func->destructable_funcdata = 1; CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); init_hash32_context(hash_context); func->funcdata = (void *)hash_context; finalize_it: RETiRet; } static rsRetVal ATTR_NONNULL(1) init_fmHash32mod(struct cnffunc *const func) { DEFiRet; hash_context_t *hash_context = NULL; if (check_param_count_hashmod(func->nParams)) { parser_errmsg( "fmhash: hash32mod(string, mod)/hash32mod(string, mod, seed)" " insufficient params.\n"); ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS); } func->destructable_funcdata = 1; CHKmalloc(hash_context = calloc(1, sizeof(hash_context_t))); init_hash32_context(hash_context); func->funcdata = (void *)hash_context; finalize_it: RETiRet; } static struct scriptFunct functions[] = { {"hash64", 1, 2, fmHashXX, init_fmHash64, NULL}, {"hash64mod", 2, 3, fmHashXXmod, init_fmHash64mod, NULL}, {"hash32", 1, 2, fmHashXX, init_fmHash32, NULL}, {"hash32mod", 2, 3, fmHashXXmod, init_fmHash32mod, NULL}, {NULL, 0, 0, NULL, NULL, NULL} // last element to check end of array }; BEGINgetFunctArray CODESTARTgetFunctArray; dbgprintf("Hash: fmhhash\n"); *version = 1; *functArray = functions; ENDgetFunctArray BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_FMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf("rsyslog fmhash init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/fmhash/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017475 xustar0030 mtime=1752569012.326271887 30 atime=1764930927.289789728 30 ctime=1764935928.130652315 rsyslog-8.2512.0/contrib/fmhash/Makefile.am0000664000175000017500000000033315035412264017140 0ustar00rgerrger# # fmhash support # pkglib_LTLIBRARIES = fmhash.la fmhash_la_SOURCES = fmhash.c fmhash_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) fmhash_la_LDFLAGS = -module -avoid-version fmhash_la_LIBADD = $(HASH_XXHASH_LIBS) rsyslog-8.2512.0/contrib/fmhash/PaxHeaders/Makefile.in0000644000000000000000000000013115114544315017506 xustar0030 mtime=1764935885.622001359 30 atime=1764935896.145162546 29 ctime=1764935928.13365236 rsyslog-8.2512.0/contrib/fmhash/Makefile.in0000664000175000017500000006316415114544315017165 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/fmhash ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = fmhash_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_fmhash_la_OBJECTS = fmhash_la-fmhash.lo fmhash_la_OBJECTS = $(am_fmhash_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = fmhash_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(fmhash_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/fmhash_la-fmhash.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(fmhash_la_SOURCES) DIST_SOURCES = $(fmhash_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # # fmhash support # pkglib_LTLIBRARIES = fmhash.la fmhash_la_SOURCES = fmhash.c fmhash_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) fmhash_la_LDFLAGS = -module -avoid-version fmhash_la_LIBADD = $(HASH_XXHASH_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/fmhash/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/fmhash/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } fmhash.la: $(fmhash_la_OBJECTS) $(fmhash_la_DEPENDENCIES) $(EXTRA_fmhash_la_DEPENDENCIES) $(AM_V_CCLD)$(fmhash_la_LINK) -rpath $(pkglibdir) $(fmhash_la_OBJECTS) $(fmhash_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmhash_la-fmhash.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< fmhash_la-fmhash.lo: fmhash.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmhash_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fmhash_la-fmhash.lo -MD -MP -MF $(DEPDIR)/fmhash_la-fmhash.Tpo -c -o fmhash_la-fmhash.lo `test -f 'fmhash.c' || echo '$(srcdir)/'`fmhash.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fmhash_la-fmhash.Tpo $(DEPDIR)/fmhash_la-fmhash.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fmhash.c' object='fmhash_la-fmhash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmhash_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fmhash_la-fmhash.lo `test -f 'fmhash.c' || echo '$(srcdir)/'`fmhash.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/fmhash_la-fmhash.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/fmhash_la-fmhash.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/pmsnare0000644000000000000000000000013115114544366015571 xustar0030 mtime=1764935926.023620059 29 atime=1764935930.17368359 30 ctime=1764935926.023620059 rsyslog-8.2512.0/contrib/pmsnare/0000775000175000017500000000000015114544366015313 5ustar00rgerrgerrsyslog-8.2512.0/contrib/pmsnare/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017674 xustar0030 mtime=1752569012.331237145 30 atime=1764930929.727831103 30 ctime=1764935926.018619982 rsyslog-8.2512.0/contrib/pmsnare/Makefile.am0000664000175000017500000000033015035412264017334 0ustar00rgerrgerpkglib_LTLIBRARIES = pmsnare.la pmsnare_la_SOURCES = pmsnare.c pmsnare_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmsnare_la_LDFLAGS = -module -avoid-version pmsnare_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/pmsnare/PaxHeaders/pmsnare.c0000644000000000000000000000013115055605325017454 xustar0029 mtime=1756826325.61580017 30 atime=1764931056.362942721 30 ctime=1764935926.023620059 rsyslog-8.2512.0/contrib/pmsnare/pmsnare.c0000664000175000017500000003726215055605325017133 0ustar00rgerrger/* pmsnare.c * * this detects logs sent by Snare and cleans them up so that they can be processed by the normal parser * * there are two variations of this, if the client is set to 'syslog' mode it sends * * timestamphostnametagotherstuff * * if the client is not set to syslog it sends * * hostnametagotherstuff * * The tabs can be represented in different ways. This module will auto-detect the tab representation based on * the global config settings, but they can be overridden for each instance in the config file if needed. * * ToDo, take advantage of items in the message itself to set more friendly information * where the normal parser will find it by re-writing more of the message * * Interesting information includes: * * in the case of windows snare messages: * the system hostname is field 12 * the severity is field 3 (criticality ranging form 0 to 4) * the source of the log is field 4 and may be able to be mapped to facility * * * created 2010-12-13 by David Lang based on pmlastmsg * Modified 2017-05-29 by Shane Lawrence. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" #include "rsconf.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("rsyslog.snare") MODULE_CNFNAME("pmsnare") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(parser) DEFobjCurrIf(datetime) /* static data */ static int bParseHOSTNAMEandTAG; /* cache for the equally-named global param - performance enhancement */ /* Keep a list of parser instances so we can apply global settings after config is loaded. */ typedef struct modInstances_s { instanceConf_t *root; instanceConf_t *tail; } modInstances_t; static modInstances_t *modInstances = NULL; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *modConf = NULL; /* Per-instance config settings. */ static struct cnfparamdescr parserpdescr[] = {{"parser.controlcharacterescapeprefix", eCmdHdlrGetChar, 0}, {"parser.escapecontrolcharactersonreceive", eCmdHdlrBinary, 0}, {"parser.escapecontrolcharactertab", eCmdHdlrBinary, 0}, {"parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0}}; static struct cnfparamblk parserpblk = {CNFPARAMBLK_VERSION, sizeof(parserpdescr) / sizeof(struct cnfparamdescr), parserpdescr}; struct instanceConf_s { int bEscapeCCOnRcv; int bEscapeTab; int bParserEscapeCCCStyle; uchar cCCEscapeChar; int tabLength; char tabRepresentation[5]; struct instanceConf_s *next; }; /* Creates the instance and adds it to the list of instances. */ static rsRetVal createInstance(instanceConf_t **pinst) { instanceConf_t *inst; DEFiRet; CHKmalloc(inst = malloc(sizeof(instanceConf_t))); inst->next = NULL; *pinst = inst; /* Add to list of instances. */ if (modInstances == NULL) { CHKmalloc(modInstances = malloc(sizeof(modInstances_t))); modInstances->tail = modInstances->root = NULL; } if (modInstances->tail == NULL) { modInstances->tail = modInstances->root = inst; } else { modInstances->tail->next = inst; modInstances->tail = inst; } finalize_it: RETiRet; } BEGINnewParserInst struct cnfparamvals *pvals = NULL; int i; CODESTARTnewParserInst; DBGPRINTF("newParserInst (pmsnare)\n"); inst = NULL; CHKiRet(createInstance(&inst)); /* Mark these as unset so we know if they should be overridden later. */ inst->bEscapeCCOnRcv = -1; inst->bEscapeTab = -1; inst->bParserEscapeCCCStyle = -1; inst->cCCEscapeChar = '\0'; /* If using the old config, just use global settings for each instance. */ if (lst == NULL) FINALIZE; /* If using the new config, process module settings for this instance. */ if ((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("pmsnare: parser param blk:\n"); cnfparamsPrint(&parserpblk, pvals); } for (i = 0; i < parserpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharactersonreceive")) { inst->bEscapeCCOnRcv = pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharactertab")) { inst->bEscapeTab = pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "parser.escapecontrolcharacterscstyle")) { inst->bParserEscapeCCCStyle = pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "parser.controlcharacterescapeprefix")) { inst->cCCEscapeChar = (uchar)*es_str2cstr(pvals[i].val.d.estr, NULL); } else { dbgprintf("pmsnare: program error, non-handled param '%s'\n", parserpblk.descr[i].name); } } finalize_it: CODE_STD_FINALIZERnewParserInst if (lst != NULL) cnfparamvalsDestruct(pvals, &parserpblk); if (iRet != RS_RET_OK) free(inst); ENDnewParserInst BEGINfreeParserInst CODESTARTfreeParserInst; dbgprintf("pmsnare: free parser instance %p\n", pInst); ENDfreeParserInst BEGINcheckParserInst CODESTARTcheckParserInst; ENDcheckParserInst BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticSanitazion) iRet = RS_RET_OK; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature /* Interface with the global config. */ BEGINbeginCnfLoad CODESTARTbeginCnfLoad; modConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINsetModCnf CODESTARTsetModCnf; /* Could use module-globals here, but not global globals. */ (void)lst; ENDsetModCnf BEGINendCnfLoad instanceConf_t *inst; CODESTARTendCnfLoad; dbgprintf("pmsnare: Begin endCnfLoad\n"); /* Loop through each parser instance and apply global settings to any option that hasn't been overridden. * This can't be done any earlier because the config wasn't fully loaded until now. */ for (inst = modInstances->root; inst != NULL; inst = inst->next) { if (inst->bEscapeCCOnRcv == -1) inst->bEscapeCCOnRcv = glbl.GetParserEscapeControlCharactersOnReceive(modConf->pConf); if (inst->bEscapeTab == -1) inst->bEscapeTab = glbl.GetParserEscapeControlCharacterTab(modConf->pConf); if (inst->bParserEscapeCCCStyle == -1) inst->bParserEscapeCCCStyle = glbl.GetParserEscapeControlCharactersCStyle(modConf->pConf); if (inst->cCCEscapeChar == '\0') inst->cCCEscapeChar = glbl.GetParserControlCharacterEscapePrefix(modConf->pConf); /* Determine tab representation. Possible options: * "#011" escape on, escapetabs on, no change to prefix (default) * "?011" prefix changed in config * "\\t" C style * '\t' escape turned off */ if (inst->bEscapeCCOnRcv && inst->bEscapeTab) { if (inst->bParserEscapeCCCStyle) { strncpy(inst->tabRepresentation, "\\t", 5); } else { strncpy(inst->tabRepresentation, "#011", 5); inst->tabRepresentation[0] = inst->cCCEscapeChar; } } else { strncpy(inst->tabRepresentation, "\t", 5); } inst->tabLength = strlen(inst->tabRepresentation); /* TODO: This debug message would be more useful if it told which Snare instance! */ dbgprintf("pmsnare: Snare parser will treat '%s' as tab.\n", inst->tabRepresentation); } assert(pModConf == modConf); ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; ENDactivateCnf BEGINfreeCnf instanceConf_t *inst, *del; CODESTARTfreeCnf; for (inst = modInstances->root; inst != NULL;) { del = inst; inst = inst->next; free(del); } free(modInstances); ENDfreeCnf BEGINparse2 uchar *p2parse; int lenMsg; int snaremessage; /* 0 means not a snare message, otherwise it's the index of the tab after the tag */ CODESTARTparse2; dbgprintf("Message will now be parsed by fix Snare parser.\n"); assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); /* check if this message is of the type we handle in this (very limited) parser * * - Find out if the first separator is a tab. * - If it is, see if the second word is one of our expected tags. * - If so, flag as Snare and replace the first tab with space so that * hostname and syslog tag are going to be parsed properly * - Else not a snare message, abort. * - Else assume valid 3164 timestamp, move over to the syslog tag. * - See if syslog header is followed by tab and one of our expected tags. * - If so, flag as Snare. * - See if either type flagged as Snare. * - If so, replace the tab with a space so that it will be parsed properly. */ snaremessage = 0; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */ lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* point to start of text, after PRI */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; dbgprintf("pmsnare: msg to look at: [%d]'%s'\n", lenMsg, p2parse); if ((unsigned)lenMsg < 30) { /* too short, can not be "our" message */ dbgprintf("pmsnare: Message is too short to be Snare!\n"); ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* Find the first separator and check if it's a tab. */ while (lenMsg && *p2parse != ' ' && *p2parse != '\t' && *p2parse != pInst->tabRepresentation[0]) { --lenMsg; ++p2parse; } if ((lenMsg > pInst->tabLength) && (strncasecmp((char *)p2parse, pInst->tabRepresentation, pInst->tabLength) == 0)) { dbgprintf("pmsnare: tab separated message\n"); dbgprintf("pmsnare: tab [%d]'%s' msg at the first separator: [%d]'%s'\n", pInst->tabLength, pInst->tabRepresentation, lenMsg, p2parse); /* Look for the Snare tag. */ if (strncasecmp((char *)(p2parse + pInst->tabLength), "MSWinEventLog", 13) == 0) { dbgprintf("Found a non-syslog Windows Snare message.\n"); snaremessage = p2parse - pMsg->pszRawMsg + pInst->tabLength + 13; } else if (strncasecmp((char *)(p2parse + pInst->tabLength), "LinuxKAudit", 11) == 0) { dbgprintf("Found a non-syslog Linux Snare message.\n"); snaremessage = p2parse - pMsg->pszRawMsg + pInst->tabLength + 11; } else { /* Tab-separated but no Snare tag-> can't be Snare! */ ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); } /* This is a non-syslog Snare message. Example: * other.lab.home MSWinEventLog 1 Security 606129 Wed May 17 02:25:10 2017 */ /* Remove the tab between the hostname and Snare tag. */ *p2parse = ' '; p2parse++; lenMsg--; lenMsg -= (pInst->tabLength - 1); /* size of tab goes from tabLength to 1, so shorten the message by the difference */ memmove(p2parse, p2parse + (pInst->tabLength - 1), lenMsg); /* move the message portion up to overwrite the tab */ *(p2parse + lenMsg) = '\0'; pMsg->iLenRawMsg -= (pInst->tabLength - 1); pMsg->iLenMSG -= (pInst->tabLength - 1); snaremessage -= (pInst->tabLength - 1); } else { /* The first separator is not a tab. Look for a syslog Snare message. Example: * <14>May 17 02:25:10 syslog.lab.home MSWinEventLog 1 Security 606129 Wed May 17 02:25:10 2017 */ /* go back to the beginning of the message */ lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* offAfterPRI is already the number of PRI chars (do not add one!) */ p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* skip over timestamp and space (15 chars + space). */ lenMsg -= 16; p2parse += 16; /* skip over what should be the hostname and space */ while (lenMsg && *p2parse != ' ') { --lenMsg; ++p2parse; } if (lenMsg) { --lenMsg; ++p2parse; } dbgprintf("pmsnare: tab [%d]'%s' msg after the timestamp and hostname: [%d]'%s'\n", pInst->tabLength, pInst->tabRepresentation, lenMsg, p2parse); /* Look for the Snare tag. */ if (lenMsg > 13 && strncasecmp((char *)p2parse, "MSWinEventLog", 13) == 0) { dbgprintf("Found a syslog Windows Snare message.\n"); snaremessage = p2parse - pMsg->pszRawMsg + 13; } else if (lenMsg > 11 && strncasecmp((char *)p2parse, "LinuxKAudit", 11) == 0) { dbgprintf("pmsnare: Found a syslog Linux Snare message.\n"); snaremessage = p2parse - pMsg->pszRawMsg + 11; } } if (snaremessage) { /* Skip to the end of the tag. */ p2parse = pMsg->pszRawMsg + snaremessage; lenMsg = pMsg->iLenRawMsg - snaremessage; /* Remove the tab after the tag. */ *p2parse = ' '; p2parse++; lenMsg--; lenMsg -= (pInst->tabLength - 1); /* size of tab goes from tabLength to 1, so shorten the message by the difference */ memmove(p2parse, p2parse + (pInst->tabLength - 1), lenMsg); /* move the message portion up to overwrite the tab */ *(p2parse + lenMsg) = '\0'; pMsg->iLenRawMsg -= (pInst->tabLength - 1); pMsg->iLenMSG -= (pInst->tabLength - 1); DBGPRINTF("pmsnare: new message: [%d]'%s'\n", lenMsg, pMsg->pszRawMsg + pMsg->offAfterPRI); } ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); finalize_it: ENDparse2 BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(parser, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_MOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_PMOD2_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(parser, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); DBGPRINTF("snare parser init called, compiled with version %s\n", VERSION); bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(loadConf); /* cache value, is set only during rsyslogd option processing */ ENDmodInit /* vim:set ai: */ rsyslog-8.2512.0/contrib/pmsnare/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316017707 xustar0030 mtime=1764935886.488014624 30 atime=1764935896.267164415 30 ctime=1764935926.020620013 rsyslog-8.2512.0/contrib/pmsnare/Makefile.in0000664000175000017500000006316615114544316017367 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/pmsnare ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) pmsnare_la_DEPENDENCIES = am_pmsnare_la_OBJECTS = pmsnare_la-pmsnare.lo pmsnare_la_OBJECTS = $(am_pmsnare_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pmsnare_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pmsnare_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pmsnare_la-pmsnare.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pmsnare_la_SOURCES) DIST_SOURCES = $(pmsnare_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = pmsnare.la pmsnare_la_SOURCES = pmsnare.c pmsnare_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmsnare_la_LDFLAGS = -module -avoid-version pmsnare_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmsnare/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pmsnare/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pmsnare.la: $(pmsnare_la_OBJECTS) $(pmsnare_la_DEPENDENCIES) $(EXTRA_pmsnare_la_DEPENDENCIES) $(AM_V_CCLD)$(pmsnare_la_LINK) -rpath $(pkglibdir) $(pmsnare_la_OBJECTS) $(pmsnare_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmsnare_la-pmsnare.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pmsnare_la-pmsnare.lo: pmsnare.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmsnare_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmsnare_la-pmsnare.lo -MD -MP -MF $(DEPDIR)/pmsnare_la-pmsnare.Tpo -c -o pmsnare_la-pmsnare.lo `test -f 'pmsnare.c' || echo '$(srcdir)/'`pmsnare.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmsnare_la-pmsnare.Tpo $(DEPDIR)/pmsnare_la-pmsnare.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmsnare.c' object='pmsnare_la-pmsnare.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmsnare_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmsnare_la-pmsnare.lo `test -f 'pmsnare.c' || echo '$(srcdir)/'`pmsnare.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pmsnare_la-pmsnare.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pmsnare_la-pmsnare.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmgrok0000644000000000000000000000013115114544371015414 xustar0030 mtime=1764935929.457672629 29 atime=1764935930.17368359 30 ctime=1764935929.457672629 rsyslog-8.2512.0/contrib/mmgrok/0000775000175000017500000000000015114544371015136 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmgrok/PaxHeaders/README0000644000000000000000000000013215035412264016347 xustar0030 mtime=1752569012.329251042 30 atime=1764931149.986462955 30 ctime=1764935929.455672598 rsyslog-8.2512.0/contrib/mmgrok/README0000664000175000017500000000244215035412264016015 0ustar00rgerrgerGrok Message Modify Plugin Using hundreds of grok patterns from logstash-patterns-core. Build This plugin requires libfastjson (always present in rsyslog core), glib2, and grok packages. If you use RH/CentOS/Fedora, you'll have to build grok rpms by yourself as follow: sudo yum install -y yum-utils rpmdevtools git clone git@github.com:jordansissel/grok.git mkdir -p ~/rpmbuild/SPECS/; cp grok/grok.spec.template ~/rpmbuild/SPECS/grok.spec (mkdir -p ~/rpmbuild/SOURCES/; cd ~/rpmbuild/SOURCES/; spectool -g ../SPECS/grok.spec) sudo yum-builddep ~/rpmbuild/SPECS/grok.spec rpmbuild -bb ~/rpmbuild/SPECS/grok.spec # use yum command instead of rpm, because grok depends on libevent, pcre, tokyocabinet sudo yum install -y libjson-c-devel glib2-devel ~/rpmbuild/RPMS/x86_64/grok*.rpm Example module(load="mmgrok") template(name="tmlp" type="string" string="%$!msg!test%\n") action(type="mmgrok" patterndir="path/to/yourpatternsDir" match="%{WORD:test}" source="msg" target="!msg") action(type="omfile" file="path/to/file" template="tmlp") Description patterndir: path to grok patterns dir, default: /usr/share/grok/patterns/base match:the pattern used to match message source: the source message/variable to be matched target: the root path to write the captured json tree rsyslog-8.2512.0/contrib/mmgrok/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264017523 xustar0030 mtime=1752569012.329251042 30 atime=1764930928.360807907 30 ctime=1764935929.450672522 rsyslog-8.2512.0/contrib/mmgrok/Makefile.am0000664000175000017500000000037015035412264017167 0ustar00rgerrgerpkglib_LTLIBRARIES = mmgrok.la mmgrok_la_SOURCES = mmgrok.c mmgrok_la_CPPFLAGS = $(GLIB_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmgrok_la_LDFLAGS = -module -avoid-version mmgrok_la_LIBADD = $(GLIB_LIBS) -lgrok $(LIBFASTJSON_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/mmgrok/PaxHeaders/mmgrok.c0000644000000000000000000000013215055605325017133 xustar0030 mtime=1756826325.612800125 30 atime=1764931149.995463099 30 ctime=1764935929.457672629 rsyslog-8.2512.0/contrib/mmgrok/mmgrok.c0000664000175000017500000002502515055605325016603 0ustar00rgerrger/* mmgrok.c * Grok the message is parsed into a structured json data inside JSON. */ #include "config.h" #include "rsyslog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "dirty.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmgrok"); static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal); DEF_OMOD_STATIC_DATA; typedef struct result_s { char *key; int key_len; const char *value; int value_len; char *type; } result_t; /* config variables */ typedef struct _instanceData { char *pszPatternDir; char *pszMatch; char *pszSource; char *pszTarget; /* as a json root for store parse json data */ smsg_t *pmsg; /* store origin messages*/ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; struct modConfData_s { rsconf_t *pConf; /* our overall config object */ }; static modConfData_t *loadModConf = NULL; static modConfData_t *runModConf = NULL; /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = { {"patterndir", eCmdHdlrString, 0}, {"match", eCmdHdlrString, 0}, {"source", eCmdHdlrString, 0}, {"target", eCmdHdlrString, 0}, }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; ENDbeginCnfLoad BEGINendCnfLoad CODESTARTendCnfLoad; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINfreeInstance CODESTARTfreeInstance; free(pData->pszPatternDir); free(pData->pszMatch); free(pData->pszSource); free(pData->pszTarget); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance static inline void setInstParamDefaults(instanceData *pData) { pData->pszPatternDir = NULL; pData->pszMatch = NULL; pData->pszSource = NULL; pData->pszTarget = NULL; pData->pmsg = NULL; } BEGINnewActInst struct cnfparamvals *pvals; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (mmgrok)\n"); if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "patterndir")) { pData->pszPatternDir = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } else if (!strcmp(actpblk.descr[i].name, "match")) { pData->pszMatch = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } else if (!strcmp(actpblk.descr[i].name, "source")) { pData->pszSource = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } else if (!strcmp(actpblk.descr[i].name, "target")) { pData->pszTarget = es_str2cstr(pvals[i].val.d.estr, NULL); continue; } else { DBGPRINTF( "mmgrok: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } if (pData->pszTarget == NULL) { CHKmalloc(pData->pszTarget = strdup("!")); } CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; DBGPRINTF("mmgrok\n"); ENDdbgPrintInstInfo BEGINtryResume CODESTARTtryResume; ENDtryResume static inline grok_t *CreateGrok(void) { grok_t *grok = grok_new(); if (grok == NULL) { DBGPRINTF("mmgrok: create a grok faile!"); exit(1); } grok_init(grok); return grok; } /* the parseing is complate message into json */ static rsRetVal smsg_to_json(GList *list, instanceData *pData) { GList *it = list; struct json_object *json; struct json_object *jval; DEFiRet; json = json_object_new_object(); if (json == NULL) { ABORT_FINALIZE(RS_RET_ERR); } for (; it; it = it->next) { int key_len = ((result_t *)it->data)->key_len; char *key = (char *)malloc(key_len + 1); snprintf(key, key_len + 1, "%.*s", key_len, ((result_t *)it->data)->key); int value_len = ((result_t *)it->data)->value_len; char *value = (char *)malloc(value_len + 1); snprintf(value, value_len + 1, "%.*s", value_len, ((result_t *)it->data)->value); jval = json_object_new_string(value); json_object_object_add(json, key, jval); free(key); free(value); } msgAddJSON(pData->pmsg, (uchar *)pData->pszTarget, json, 0, 0); finalize_it: RETiRet; } /* store parse result ,use list in glib*/ static rsRetVal parse_result_store(const grok_match_t gm, instanceData *pData) { GList *re_list = NULL; char *pname; const char *pdata; int pname_len, pdata_len; char *key; char *type; DEFiRet; grok_match_walk_init(&gm); // grok API while (grok_match_walk_next(&gm, &pname, &pname_len, &pdata, &pdata_len) == 0) { /* parse key and value type from patterns */ key = strchr(pname, ':'); if (key != NULL) { int key_len; result_t *result = g_new0(result_t, 1); key_len = pname_len - ((key + 1) - pname); key = key + 1; pname_len = key_len; type = strchr(key, ':'); int type_len; if (type != NULL) { key_len = (type - key); type = type + 1; type_len = pname_len - key_len - 1; type[type_len] = '\0'; } else { type = (char *)"null"; } /* store parse result into list */ result->key = key; result->key_len = key_len; result->value = pdata; result->value_len = pdata_len; result->type = type; /* the value of merger the same key*/ re_list = g_list_append(re_list, result); } } smsg_to_json(re_list, pData); g_list_free(re_list); grok_match_walk_end(&gm); RETiRet; } /* motify message for per line */ static rsRetVal MotifyLine(char *line, grok_t *grok, instanceData *pData) { grok_match_t gm; DEFiRet; grok_patterns_import_from_file(grok, pData->pszPatternDir); int compile = grok_compile(grok, pData->pszMatch); if (compile != GROK_OK) { DBGPRINTF("mmgrok: grok_compile faile!exit code: %d\n", compile); ABORT_FINALIZE(RS_RET_ERR); } int exe = grok_exec(grok, line, &gm); if (exe != GROK_OK) { DBGPRINTF("mmgrok: grok_exec faile!exit code: %d\n", exe); ABORT_FINALIZE(RS_RET_ERR); } parse_result_store(gm, pData); finalize_it: RETiRet; } /* motify rsyslog messages */ static rsRetVal MotifyMessage(instanceData *pData) { char *saveptr = NULL; DEFiRet; grok_t *grok = CreateGrok(); char *msg = strdup(pData->pszSource); char *line = NULL; line = strtok_r(msg, "\n", &saveptr); while (line != NULL) { MotifyLine(line, grok, pData); line = strtok_r(NULL, "\n", &saveptr); } free(msg); msg = NULL; RETiRet; } BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; uchar *buf; instanceData *pData; CODESTARTdoAction; pData = pWrkrData->pData; buf = getMSG(pMsg); pData->pmsg = pMsg; while (*buf && isspace(*buf)) { ++buf; } if (*buf == '\0') { DBGPRINTF("mmgrok: not msg for mmgrok!"); ABORT_FINALIZE(RS_RET_NO_CEE_MSG); } pData->pszSource = (char *)buf; CHKiRet(MotifyMessage(pData)); finalize_it: ENDdoAction BEGINparseSelectorAct CODESTARTparseSelectorAct; CODE_STD_STRING_REQUESTparseSelectorAct(1) if (strncmp((char *)p, ":mmgrok:", sizeof(":mmgrok:") - 1)) { ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); } p += sizeof(":mmgrok:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ CHKiRet(createInstance(&pData)); if (*(p - 1) == ';') --p; CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_TPL_AS_MSG, (uchar *)"RSYSLOG_FileFormat")); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; ENDqueryEtryPt static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { DEFiRet; RETiRet; } BEGINmodInit() rsRetVal localRet; rsRetVal (*pomsrGetSupportedTplOpts)(unsigned long *pOpts); unsigned long opts; int bMsgPassingSupported; CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; CODEmodInit_QueryRegCFSLineHdlr DBGPRINTF("mmgrok: module compiled with rsyslog version %s.\n", VERSION); bMsgPassingSupported = 0; localRet = pHostQueryEtryPt((uchar *)"OMSRgetSupportedTplOpts", &pomsrGetSupportedTplOpts); if (localRet == RS_RET_OK) { CHKiRet((*pomsrGetSupportedTplOpts)(&opts)); if (opts & OMSR_TPL_AS_MSG) bMsgPassingSupported = 1; } else if (localRet != RS_RET_ENTRY_POINT_NOT_FOUND) { ABORT_FINALIZE(localRet); /* Something else went wrong, not acceptable */ } if (!bMsgPassingSupported) { DBGPRINTF( "mmgrok: msg-passing is not supported by rsyslog core, " "can not continue.\n"); ABORT_FINALIZE(RS_RET_NO_MSG_PASSING); } CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit rsyslog-8.2512.0/contrib/mmgrok/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315017535 xustar0030 mtime=1764935885.999007134 30 atime=1764935896.450167218 30 ctime=1764935929.453672568 rsyslog-8.2512.0/contrib/mmgrok/Makefile.in0000664000175000017500000006325315114544315017212 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmgrok ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = mmgrok_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_mmgrok_la_OBJECTS = mmgrok_la-mmgrok.lo mmgrok_la_OBJECTS = $(am_mmgrok_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmgrok_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(mmgrok_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmgrok_la-mmgrok.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmgrok_la_SOURCES) DIST_SOURCES = $(mmgrok_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmgrok.la mmgrok_la_SOURCES = mmgrok.c mmgrok_la_CPPFLAGS = $(GLIB_CFLAGS) $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmgrok_la_LDFLAGS = -module -avoid-version mmgrok_la_LIBADD = $(GLIB_LIBS) -lgrok $(LIBFASTJSON_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmgrok/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmgrok/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmgrok.la: $(mmgrok_la_OBJECTS) $(mmgrok_la_DEPENDENCIES) $(EXTRA_mmgrok_la_DEPENDENCIES) $(AM_V_CCLD)$(mmgrok_la_LINK) -rpath $(pkglibdir) $(mmgrok_la_OBJECTS) $(mmgrok_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmgrok_la-mmgrok.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmgrok_la-mmgrok.lo: mmgrok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmgrok_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmgrok_la-mmgrok.lo -MD -MP -MF $(DEPDIR)/mmgrok_la-mmgrok.Tpo -c -o mmgrok_la-mmgrok.lo `test -f 'mmgrok.c' || echo '$(srcdir)/'`mmgrok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmgrok_la-mmgrok.Tpo $(DEPDIR)/mmgrok_la-mmgrok.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmgrok.c' object='mmgrok_la-mmgrok.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmgrok_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmgrok_la-mmgrok.lo `test -f 'mmgrok.c' || echo '$(srcdir)/'`mmgrok.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmgrok_la-mmgrok.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmgrok_la-mmgrok.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/fmunflatten0000644000000000000000000000013115114544370016442 xustar0030 mtime=1764935928.221653708 29 atime=1764935930.17368359 30 ctime=1764935928.221653708 rsyslog-8.2512.0/contrib/fmunflatten/0000775000175000017500000000000015114544370016164 5ustar00rgerrgerrsyslog-8.2512.0/contrib/fmunflatten/PaxHeaders/Makefile.am0000644000000000000000000000013215055602573020560 xustar0030 mtime=1756824955.959450467 30 atime=1764930927.370791103 30 ctime=1764935928.216653631 rsyslog-8.2512.0/contrib/fmunflatten/Makefile.am0000664000175000017500000000035715055602573020231 0ustar00rgerrgerpkglib_LTLIBRARIES = fmunflatten.la fmunflatten_la_SOURCES = fmunflatten.c fmunflatten_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(JSON_C_CFLAGS) fmunflatten_la_LDFLAGS = -module -avoid-version fmunflatten_la_LIBADD = $(JSON_C_LIBS) rsyslog-8.2512.0/contrib/fmunflatten/PaxHeaders/fmunflatten.c0000644000000000000000000000013215055605325021211 xustar0030 mtime=1756826325.610800095 30 atime=1764931146.129400919 30 ctime=1764935928.221653708 rsyslog-8.2512.0/contrib/fmunflatten/fmunflatten.c0000664000175000017500000001740315055605325020662 0ustar00rgerrger/* * This is a function module providing ability to unflatten a JSON tree. * * Copyright 2020 Julien Thomas < jthomas @ zenetys.com > * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #ifndef _AIX #include #endif #include #include #include "rsyslog.h" #include "errmsg.h" #include "msg.h" #include "parserif.h" #include "module-template.h" #include "rainerscript.h" #include "wti.h" #define FMUNFLATTEN_KBUFLEN 256 #define _jso_type(x) json_type_to_name(json_object_get_type(x)) MODULE_TYPE_FUNCTION MODULE_TYPE_NOKEEP; DEF_FMOD_STATIC_DATA; struct unflatten_ctx { char *kbuf; size_t kbuf_len; char delim; }; /* forward declarations */ void unflatten_add(struct unflatten_ctx *ctx, struct json_object *dst, const char *key, struct json_object *value); void unflatten(struct unflatten_ctx *ctx, struct json_object *src, struct json_object *dst); void unflatten_add(struct unflatten_ctx *ctx, struct json_object *dst, const char *key, struct json_object *value) { const char *p = key; const char *q = p; int depth = 0; size_t klen; struct json_object *o; json_bool exists_already; int create; while (1) { while (*q != ctx->delim && *q != '\0') q++; klen = q - p; if (klen + 1 > ctx->kbuf_len) { DBGPRINTF( "warning: flat key \"%.20s...\" truncated at depth #%d, buffer too " "small (max %zd)\n", key, depth, ctx->kbuf_len); klen = ctx->kbuf_len - 1; } memcpy(ctx->kbuf, p, klen); ctx->kbuf[klen] = '\0'; exists_already = json_object_object_get_ex(dst, ctx->kbuf, &o); if (*q == ctx->delim) { if (!exists_already) create = 1; else if (json_object_is_type(o, json_type_object)) create = 0; else { DBGPRINTF( "warning: while processing flat key \"%s\" at depth #%d (intermediate " "node), overriding existing value of type %s by an object\n", key, depth, _jso_type(o)); json_object_object_del(dst, ctx->kbuf); create = 1; } if (create) { o = json_object_new_object(); json_object_object_add(dst, ctx->kbuf, o); } dst = o; p = q + 1; q = p; depth++; } else if (*q == '\0') { if (json_object_is_type(value, json_type_object)) { if (exists_already) { if (!json_object_is_type(o, json_type_object)) { DBGPRINTF( "warning: while processing flat key \"%s\" at depth #%d " "(final node), overriding existing value of type %s by an " "object\n", key, depth, _jso_type(o)); json_object_object_del(dst, ctx->kbuf); o = json_object_new_object(); json_object_object_add(dst, ctx->kbuf, o); } } else { o = json_object_new_object(); json_object_object_add(dst, ctx->kbuf, o); } unflatten(ctx, value, o); } else { if (exists_already) { DBGPRINTF( "warning: while processing flat key \"%s\" at depth #%d " "(final node), overriding existing value\n", key, depth); json_object_object_del(dst, ctx->kbuf); } o = jsonDeepCopy(value); json_object_object_add(dst, ctx->kbuf, o); } break; } } } void unflatten(struct unflatten_ctx *ctx, struct json_object *src, struct json_object *dst) { struct json_object_iterator it = json_object_iter_begin(src); struct json_object_iterator itEnd = json_object_iter_end(src); const char *key; struct json_object *value; while (!json_object_iter_equal(&it, &itEnd)) { key = json_object_iter_peek_name(&it); value = json_object_iter_peek_value(&it); unflatten_add(ctx, dst, key, value); json_object_iter_next(&it); } } static void ATTR_NONNULL() doFunc_unflatten(struct cnffunc *__restrict__ const func, struct svar *__restrict__ const ret, void *__restrict__ const usrptr, wti_t *__restrict__ const pWti) { struct svar src_var; struct svar delim_var; char kbuf[FMUNFLATTEN_KBUFLEN]; struct unflatten_ctx ctx = {.kbuf = kbuf, .kbuf_len = sizeof(kbuf), .delim = 0}; /* A dummy value of 0 (number) is returned by default. Callers should also * call script_error() to check if this script function succeeded before * using the value it returns. */ ret->datatype = 'N'; ret->d.n = 0; wtiSetScriptErrno(pWti, RS_SCRIPT_EINVAL); cnfexprEval(func->expr[0], &src_var, usrptr, pWti); cnfexprEval(func->expr[1], &delim_var, usrptr, pWti); /* Check argument 2 (delimiter character). */ if (delim_var.datatype == 'S' && es_strlen(delim_var.d.estr) == 1) ctx.delim = *es_getBufAddr(delim_var.d.estr); else if (delim_var.datatype == 'N') ctx.delim = delim_var.d.n; if (ctx.delim == 0) { LogError(0, RS_RET_INVALID_PARAMS, "unflatten: invalid argument 2 (delim), single character " "required (as string or decimal charcode)"); FINALIZE; } /* Check argument 1 (source). Not logging an error avoids emitting logs for * messages when $! was not touched. */ if (src_var.datatype != 'J') { DBGPRINTF("unsupported argument 1 (src) datatype %c\n", src_var.datatype); FINALIZE; } ret->datatype = 'J'; if (json_object_is_type(src_var.d.json, json_type_object)) { ret->d.json = json_object_new_object(); unflatten(&ctx, src_var.d.json, ret->d.json); } else ret->d.json = jsonDeepCopy(src_var.d.json); wtiSetScriptErrno(pWti, RS_SCRIPT_EOK); finalize_it: varFreeMembers(&src_var); varFreeMembers(&delim_var); } static rsRetVal ATTR_NONNULL(1) initFunc_unflatten(struct cnffunc *const func) { DEFiRet; func->destructable_funcdata = 0; RETiRet; } static struct scriptFunct functions[] = { {"unflatten", 2, 2, doFunc_unflatten, initFunc_unflatten, NULL}, {NULL, 0, 0, NULL, NULL, NULL} /* last element to check end of array */ }; BEGINgetFunctArray CODESTARTgetFunctArray; *version = 1; *functArray = functions; ENDgetFunctArray BEGINmodExit CODESTARTmodExit; ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_FMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr dbgprintf("rsyslog fmunflatten init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/fmunflatten/PaxHeaders/Makefile.in0000644000000000000000000000013215114544315020564 xustar0030 mtime=1764935885.649001772 30 atime=1764935896.175163006 30 ctime=1764935928.218653662 rsyslog-8.2512.0/contrib/fmunflatten/Makefile.in0000664000175000017500000006354315114544315020243 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/fmunflatten ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) fmunflatten_la_DEPENDENCIES = am_fmunflatten_la_OBJECTS = fmunflatten_la-fmunflatten.lo fmunflatten_la_OBJECTS = $(am_fmunflatten_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = fmunflatten_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(fmunflatten_la_LDFLAGS) $(LDFLAGS) -o \ $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(fmunflatten_la_SOURCES) DIST_SOURCES = $(fmunflatten_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = fmunflatten.la fmunflatten_la_SOURCES = fmunflatten.c fmunflatten_la_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(JSON_C_CFLAGS) fmunflatten_la_LDFLAGS = -module -avoid-version fmunflatten_la_LIBADD = $(JSON_C_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/fmunflatten/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/fmunflatten/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } fmunflatten.la: $(fmunflatten_la_OBJECTS) $(fmunflatten_la_DEPENDENCIES) $(EXTRA_fmunflatten_la_DEPENDENCIES) $(AM_V_CCLD)$(fmunflatten_la_LINK) -rpath $(pkglibdir) $(fmunflatten_la_OBJECTS) $(fmunflatten_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< fmunflatten_la-fmunflatten.lo: fmunflatten.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmunflatten_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fmunflatten_la-fmunflatten.lo -MD -MP -MF $(DEPDIR)/fmunflatten_la-fmunflatten.Tpo -c -o fmunflatten_la-fmunflatten.lo `test -f 'fmunflatten.c' || echo '$(srcdir)/'`fmunflatten.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fmunflatten_la-fmunflatten.Tpo $(DEPDIR)/fmunflatten_la-fmunflatten.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fmunflatten.c' object='fmunflatten_la-fmunflatten.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(fmunflatten_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fmunflatten_la-fmunflatten.lo `test -f 'fmunflatten.c' || echo '$(srcdir)/'`fmunflatten.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/fmunflatten_la-fmunflatten.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omfile-hardened0000644000000000000000000000013215114544364017146 xustar0030 mtime=1764935924.984604153 30 atime=1764935930.172683575 30 ctime=1764935924.984604153 rsyslog-8.2512.0/contrib/omfile-hardened/0000775000175000017500000000000015114544364016667 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omfile-hardened/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264021252 xustar0030 mtime=1752569012.330244093 30 atime=1764930928.929817564 30 ctime=1764935924.980604092 rsyslog-8.2512.0/contrib/omfile-hardened/Makefile.am0000664000175000017500000000041015035412264020711 0ustar00rgerrgerpkglib_LTLIBRARIES = omfile-hardened.la omfile_hardened_la_SOURCES = omfile-hardened.c omfile_hardened_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools omfile_hardened_la_LDFLAGS = -module -avoid-version omfile_hardened_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/omfile-hardened/PaxHeaders/omfile-hardened.c0000644000000000000000000000013115055605325022410 xustar0029 mtime=1756826325.61380014 30 atime=1764931136.026238193 30 ctime=1764935924.985604168 rsyslog-8.2512.0/contrib/omfile-hardened/omfile-hardened.c0000664000175000017500000017436315055605325022073 0ustar00rgerrger/* omfile.c * This is the implementation of the build-in file output module. * * NOTE: read comments in module-template.h to understand how this file * works! * * File begun on 2007-07-21 by RGerhards (extracted from syslogd.c, which * at the time of the fork from sysklogd was under BSD license) * * A large re-write of this file was done in June, 2009. The focus was * to introduce many more features (like zipped writing), clean up the code * and make it more reliable. In short, that rewrite tries to provide a new * solid basis for the next three to five years to come. During it, bugs * may have been introduced ;) -- rgerhards, 2009-06-04 * * Note that as of 2010-02-28 this module does no longer handle * pipes. These have been moved to ompipe, to reduced the entanglement * between the two different functionalities. -- rgerhards * * Copyright 2007-2017 Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include "rsyslog.h" #include "glbl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_ATOMIC_BUILTINS #include #endif #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "outchannel.h" #include "omfile.h" #include "cfsysline.h" #include "module-template.h" #include "errmsg.h" #include "stream.h" #include "unicode-helper.h" #include "atomic.h" #include "statsobj.h" #include "sigprov.h" #include "cryprov.h" #include "parserif.h" #include "janitor.h" #include "rsconf.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omfile") /* forward definitions */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal); /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(strm) DEFobjCurrIf(statsobj) /* for our current LRU mechanism, we need a monotonically increasing counters. We use * it much like a "Lamport logical clock": we do not need the actual time, we just need * to know the sequence in which files were accessed. So we use a simple counter to * create that sequence. We use an unsigned 64 bit value which is extremely unlike to * wrap within the lifetime of a process. If we process 1,000,000 file writes per * second, the process could still exist over 500,000 years before a wrap to 0 happens. * That should be sufficient (and even than, there would no really bad effect ;)). * The variable below is the global counter/clock. */ #if HAVE_ATOMIC_BUILTINS64 static uint64 clockFileAccess = 0; #else static unsigned clockFileAccess = 0; #endif /* and the "tick" function */ #ifndef HAVE_ATOMIC_BUILTINS static pthread_mutex_t mutClock; #endif static uint64 getClockFileAccess(void) { #if HAVE_ATOMIC_BUILTINS64 return ATOMIC_INC_AND_FETCH_uint64(&clockFileAccess, &mutClock); #else return ATOMIC_INC_AND_FETCH_unsigned(&clockFileAccess, &mutClock); #endif } /* The following structure is a dynafile name cache entry. */ struct s_dynaFileCacheEntry { uchar *pName; /* name currently open, if dynamic name */ strm_t *pStrm; /* our output stream */ void *sigprovFileData; /* opaque data ptr for provider use */ uint64 clkTickAccessed; /* for LRU - based on clockFileAccess */ short nInactive; /* number of minutes not writen - for close timeout */ }; typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; #define IOBUF_DFLT_SIZE 4096 /* default size for io buffers */ #define FLUSH_INTRVL_DFLT 1 /* default buffer flush interval (in seconds) */ #define USE_ASYNCWRITER_DFLT 0 /* default buffer use async writer */ #define FLUSHONTX_DFLT 1 /* default for flush on TX end */ typedef struct _instanceData { pthread_mutex_t mutWrite; /* guard against multiple instances writing to single file */ uchar *fname; /* file or template name (display only) */ uchar *tplName; /* name of assigned template */ strm_t *pStrm; /* our output stream */ short nInactive; /* number of minutes not writen (STATIC files only) */ char bDynamicName; /* 0 - static name, 1 - dynamic name (with properties) */ int fCreateMode; /* file creation mode for open() */ int fDirCreateMode; /* creation mode for mkdir() */ int bCreateDirs; /* auto-create directories? */ int bSyncFile; /* should the file by sync()'ed? 1- yes, 0- no */ uint8_t iNumTpls; /* number of tpls we use */ uid_t fileUID; /* IDs for creation */ uid_t dirUID; gid_t fileGID; gid_t dirGID; int bFailOnChown; /* fail creation if chown fails? */ uchar *sigprovName; /* signature provider */ uchar *sigprovNameFull; /* full internal signature provider name */ sigprov_if_t sigprov; /* ptr to signature provider interface */ void *sigprovData; /* opaque data ptr for provider use */ void *sigprovFileData; /* opaque data ptr for file instance */ sbool useSigprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ uchar *cryprovName; /* crypto provider */ uchar *cryprovNameFull; /* full internal crypto provider name */ void *cryprovData; /* opaque data ptr for provider use */ cryprov_if_t cryprov; /* ptr to crypto provider interface */ sbool useCryprov; /* quicker than checkig ptr (1 vs 8 bytes!) */ int iCurrElt; /* currently active cache element (-1 = none) */ uint iCurrCacheSize; /* currently cache size (1-based) */ uint iDynaFileCacheSize; /* size of file handle cache */ /* The cache is implemented as an array. An empty element is indicated * by a NULL pointer. Memory is allocated as needed. The following * pointer points to the overall structure. */ dynaFileCacheEntry **dynCache; off_t iSizeLimit; /* file size limit, 0 = no limit */ uchar *pszSizeLimitCmd; /* command to carry out when size limit is reached */ int iZipLevel; /* zip mode to use for this selector */ uint iIOBufSize; /* size of associated io buffer */ int iFlushInterval; /* how fast flush buffer on inactivity? */ short iCloseTimeout; /* after how many *minutes* shall the file be closed if inactive? */ sbool bFlushOnTXEnd; /* flush write buffers when transaction has ended? */ sbool bUseAsyncWriter; /* use async stream writer? */ sbool bVeryRobustZip; statsobj_t *stats; /* dynafile, primarily cache stats */ STATSCOUNTER_DEF(ctrRequests, mutCtrRequests); STATSCOUNTER_DEF(ctrLevel0, mutCtrLevel0); STATSCOUNTER_DEF(ctrEvict, mutCtrEvict); STATSCOUNTER_DEF(ctrMiss, mutCtrMiss); STATSCOUNTER_DEF(ctrMax, mutCtrMax); STATSCOUNTER_DEF(ctrCloseTimeouts, mutCtrCloseTimeouts); char janitorID[128]; /* holds ID for janitor calls */ } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; typedef struct configSettings_s { uint iDynaFileCacheSize; /* max cache for dynamic files */ int fCreateMode; /* mode to use when creating files */ int fDirCreateMode; /* mode to use when creating files */ int bFailOnChown; /* fail if chown fails? */ uid_t fileUID; /* UID to be used for newly created files */ uid_t fileGID; /* GID to be used for newly created files */ uid_t dirUID; /* UID to be used for newly created directories */ uid_t dirGID; /* GID to be used for newly created directories */ int bCreateDirs; /* auto-create directories for dynaFiles: 0 - no, 1 - yes */ int bEnableSync; /* enable syncing of files (no dash in front of pathname in conf): 0 - no, 1 - yes */ int iZipLevel; /* zip compression mode (0..9 as usual) */ sbool bFlushOnTXEnd; /* flush write buffers when transaction has ended? */ int64 iIOBufSize; /* size of an io buffer */ int iFlushInterval; /* how often flush the output buffer on inactivity? */ int bUseAsyncWriter; /* should we enable asynchronous writing? */ EMPTY_STRUCT } configSettings_t; static configSettings_t cs; uchar *pszFileDfltTplName; /* name of the default template to use */ struct modConfData_s { rsconf_t *pConf; /* our overall config object */ uchar *tplName; /* default template */ int fCreateMode; /* default mode to use when creating files */ int fDirCreateMode; /* default mode to use when creating files */ uid_t fileUID; /* default IDs for creation */ uid_t dirUID; gid_t fileGID; gid_t dirGID; int bDynafileDoNotSuspend; }; static modConfData_t *loadModConf = NULL; /* modConf ptr to use for the current load process */ static modConfData_t *runModConf = NULL; /* modConf ptr to use for the current exec process */ /* tables for interfacing with the v6 config system */ /* module-global parameters */ static struct cnfparamdescr modpdescr[] = { {"template", eCmdHdlrGetWord, 0}, {"dircreatemode", eCmdHdlrFileCreateMode, 0}, {"filecreatemode", eCmdHdlrFileCreateMode, 0}, {"dirowner", eCmdHdlrUID, 0}, {"dirownernum", eCmdHdlrInt, 0}, {"dirgroup", eCmdHdlrGID, 0}, {"dirgroupnum", eCmdHdlrInt, 0}, {"fileowner", eCmdHdlrUID, 0}, {"fileownernum", eCmdHdlrInt, 0}, {"filegroup", eCmdHdlrGID, 0}, {"dynafile.donotsuspend", eCmdHdlrBinary, 0}, {"filegroupnum", eCmdHdlrInt, 0}, }; static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr}; /* action (instance) parameters */ static struct cnfparamdescr actpdescr[] = {{"dynafilecachesize", eCmdHdlrInt, 0}, /* legacy: dynafilecachesize */ {"ziplevel", eCmdHdlrInt, 0}, /* legacy: omfileziplevel */ {"flushinterval", eCmdHdlrInt, 0}, /* legacy: omfileflushinterval */ {"asyncwriting", eCmdHdlrBinary, 0}, /* legacy: omfileasyncwriting */ {"veryrobustzip", eCmdHdlrBinary, 0}, {"flushontxend", eCmdHdlrBinary, 0}, /* legacy: omfileflushontxend */ {"iobuffersize", eCmdHdlrSize, 0}, /* legacy: omfileiobuffersize */ {"dirowner", eCmdHdlrUID, 0}, /* legacy: dirowner */ {"dirownernum", eCmdHdlrInt, 0}, /* legacy: dirownernum */ {"dirgroup", eCmdHdlrGID, 0}, /* legacy: dirgroup */ {"dirgroupnum", eCmdHdlrInt, 0}, /* legacy: dirgroupnum */ {"fileowner", eCmdHdlrUID, 0}, /* legacy: fileowner */ {"fileownernum", eCmdHdlrInt, 0}, /* legacy: fileownernum */ {"filegroup", eCmdHdlrGID, 0}, /* legacy: filegroup */ {"filegroupnum", eCmdHdlrInt, 0}, /* legacy: filegroupnum */ {"dircreatemode", eCmdHdlrFileCreateMode, 0}, /* legacy: dircreatemode */ {"filecreatemode", eCmdHdlrFileCreateMode, 0}, /* legacy: filecreatemode */ {"failonchownfailure", eCmdHdlrBinary, 0}, /* legacy: failonchownfailure */ {"createdirs", eCmdHdlrBinary, 0}, /* legacy: createdirs */ {"sync", eCmdHdlrBinary, 0}, /* legacy: actionfileenablesync */ {"file", eCmdHdlrString, 0}, /* either "file" or ... */ {"dynafile", eCmdHdlrString, 0}, /* "dynafile" MUST be present */ {"sig.provider", eCmdHdlrGetWord, 0}, {"cry.provider", eCmdHdlrGetWord, 0}, {"closetimeout", eCmdHdlrPositiveInt, 0}, {"template", eCmdHdlrGetWord, 0}}; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; /* this function gets the default template. It coordinates action between * old-style and new-style configuration parts. */ static uchar *getDfltTpl(void) { if (loadModConf != NULL && loadModConf->tplName != NULL) return loadModConf->tplName; else if (pszFileDfltTplName == NULL) return (uchar *)"RSYSLOG_FileFormat"; else return pszFileDfltTplName; } BEGINinitConfVars /* (re)set config variables to default values */ CODESTARTinitConfVars; pszFileDfltTplName = NULL; /* make sure this can be free'ed! */ iRet = resetConfigVariables(NULL, NULL); /* params are dummies */ ENDinitConfVars BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; if (pData->bDynamicName) { dbgprintf("[dynamic]\n"); } else { /* regular file */ dbgprintf("%s%s\n", pData->fname, (pData->pStrm == NULL) ? " (closed)" : ""); } dbgprintf("\ttemplate='%s'\n", pData->fname); dbgprintf("\tuse async writer=%d\n", pData->bUseAsyncWriter); dbgprintf("\tflush on TX end=%d\n", pData->bFlushOnTXEnd); dbgprintf("\tflush interval=%d\n", pData->iFlushInterval); dbgprintf("\tfile cache size=%d\n", pData->iDynaFileCacheSize); dbgprintf("\tcreate directories: %s\n", pData->bCreateDirs ? "on" : "off"); dbgprintf("\tvery robust zip: %s\n", pData->bCreateDirs ? "on" : "off"); dbgprintf("\tfile owner %d, group %d\n", (int)pData->fileUID, (int)pData->fileGID); dbgprintf("\tdirectory owner %d, group %d\n", (int)pData->dirUID, (int)pData->dirGID); dbgprintf("\tdir create mode 0%3.3o, file create mode 0%3.3o\n", pData->fDirCreateMode, pData->fCreateMode); dbgprintf("\tfail if owner/group can not be set: %s\n", pData->bFailOnChown ? "yes" : "no"); ENDdbgPrintInstInfo /* set the default template to be used * This is a module-global parameter, and as such needs special handling. It needs to * be coordinated with values set via the v2 config system (rsyslog v6+). What we do * is we do not permit this directive after the v2 config system has been used to set * the parameter. */ static rsRetVal setLegacyDfltTpl(void __attribute__((unused)) * pVal, uchar *newVal) { DEFiRet; if (loadModConf != NULL && loadModConf->tplName != NULL) { free(newVal); parser_errmsg( "omfile: default template already set via module " "global parameter - can no longer be changed"); ABORT_FINALIZE(RS_RET_ERR); } free(pszFileDfltTplName); pszFileDfltTplName = newVal; finalize_it: RETiRet; } /* set the dynaFile cache size. Does some limit checking. * rgerhards, 2007-07-31 */ static rsRetVal setDynaFileCacheSize(void __attribute__((unused)) * pVal, int iNewVal) { DEFiRet; if (iNewVal < 1) { errno = 0; parser_errmsg("DynaFileCacheSize must be greater 0 (%d given), changed to 1.", iNewVal); iRet = RS_RET_VAL_OUT_OF_RANGE; iNewVal = 1; } else if (iNewVal > 1000) { errno = 0; parser_errmsg("DynaFileCacheSize maximum is 1,000 (%d given), changed to 1,000.", iNewVal); iRet = RS_RET_VAL_OUT_OF_RANGE; iNewVal = 1000; } cs.iDynaFileCacheSize = iNewVal; DBGPRINTF("DynaFileCacheSize changed to %d.\n", iNewVal); RETiRet; } /* Helper to cfline(). Parses a output channel name up until the first * comma and then looks for the template specifier. Tries * to find that template. Maps the output channel to the * proper filed structure settings. Everything is stored in the * filed struct. Over time, the dependency on filed might be * removed. * rgerhards 2005-06-21 */ static rsRetVal cflineParseOutchannel( instanceData *pData, uchar *p, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts) { DEFiRet; size_t i; struct outchannel *pOch; char szBuf[128]; /* should be more than sufficient */ ++p; /* skip '$' */ i = 0; /* get outchannel name */ while (*p && *p != ';' && *p != ' ' && i < (sizeof(szBuf) - 1)) { szBuf[i++] = *p++; } szBuf[i] = '\0'; /* got the name, now look up the channel... */ pOch = ochFind(szBuf, i); if (pOch == NULL) { parser_errmsg("outchannel '%s' not found - ignoring action line", szBuf); ABORT_FINALIZE(RS_RET_NOT_FOUND); } /* check if there is a file name in the outchannel... */ if (pOch->pszFileTemplate == NULL) { parser_errmsg("outchannel '%s' has no file name template - ignoring action line", szBuf); ABORT_FINALIZE(RS_RET_ERR); } /* OK, we finally got a correct template. So let's use it... */ pData->fname = ustrdup(pOch->pszFileTemplate); pData->iSizeLimit = pOch->uSizeLimit; /* WARNING: It is dangerous "just" to pass the pointer. As we * never rebuild the output channel description, this is acceptable here. */ pData->pszSizeLimitCmd = pOch->cmdOnSizeLimit; iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, getDfltTpl()); finalize_it: RETiRet; } /* This function deletes an entry from the dynamic file name * cache. A pointer to the cache must be passed in as well * as the index of the to-be-deleted entry. This index may * point to an unallocated entry, in whcih case the * function immediately returns. Parameter bFreeEntry is 1 * if the entry should be free()ed and 0 if not. */ static rsRetVal dynaFileDelCacheEntry(instanceData *__restrict__ const pData, const int iEntry, const int bFreeEntry) { dynaFileCacheEntry **pCache = pData->dynCache; DEFiRet; assert(pCache != NULL); if (pCache[iEntry] == NULL) FINALIZE; DBGPRINTF("Removing entry %d for file '%s' from dynaCache.\n", iEntry, pCache[iEntry]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[iEntry]->pName); if (pCache[iEntry]->pName != NULL) { free(pCache[iEntry]->pName); pCache[iEntry]->pName = NULL; } if (pCache[iEntry]->pStrm != NULL) { strm.Destruct(&pCache[iEntry]->pStrm); if (pData->useSigprov) { pData->sigprov.OnFileClose(pCache[iEntry]->sigprovFileData); pCache[iEntry]->sigprovFileData = NULL; } } if (bFreeEntry) { free(pCache[iEntry]); pCache[iEntry] = NULL; } finalize_it: RETiRet; } /* This function frees all dynamic file name cache entries and closes the * relevant files. Part of Shutdown and HUP processing. * rgerhards, 2008-10-23 */ static void dynaFileFreeCacheEntries(instanceData *__restrict__ const pData) { register uint i; assert(pData != NULL); for (i = 0; i < pData->iCurrCacheSize; ++i) { dynaFileDelCacheEntry(pData, i, 1); } pData->iCurrElt = -1; /* invalidate current element */ } /* This function frees the dynamic file name cache. */ static void dynaFileFreeCache(instanceData *__restrict__ const pData) { assert(pData != NULL); dynaFileFreeCacheEntries(pData); if (pData->dynCache != NULL) free(pData->dynCache); } /* close current file */ static rsRetVal closeFile(instanceData *__restrict__ const pData) { DEFiRet; if (pData->useSigprov) { pData->sigprov.OnFileClose(pData->sigprovFileData); pData->sigprovFileData = NULL; } strm.Destruct(&pData->pStrm); RETiRet; } /* This prepares the signature provider to process a file */ static rsRetVal sigprovPrepare(instanceData *__restrict__ const pData, uchar *__restrict__ const fn) { DEFiRet; pData->sigprov.OnFileOpen(pData->sigprovData, fn, &pData->sigprovFileData); RETiRet; } /* This is now shared code for all types of files. It simply prepares * file access, which, among others, means the the file wil be opened * and any directories in between will be created (based on config, of * course). -- rgerhards, 2008-10-22 * changed to iRet interface - 2009-03-19 */ static rsRetVal prepareFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) { int fd; char errStr[1024]; /* buffer for strerr() */ DEFiRet; pData->pStrm = NULL; if (access((char *)newFileName, F_OK) != 0) { /* file does not exist, create it (and eventually parent directories */ if (pData->bCreateDirs) { /* We first need to create parent dirs if they are missing. * We do not report any errors here ourselfs but let the code * fall through to error handler below. */ if (makeFileParentDirs(newFileName, ustrlen(newFileName), pData->fDirCreateMode, pData->dirUID, pData->dirGID, pData->bFailOnChown) != 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); parser_errmsg( "omfile: creating parent " "directories for file '%s' failed: %s", newFileName, errStr); ABORT_FINALIZE(RS_RET_ERR); /* we give up */ } } /* no matter if we needed to create directories or not, we now try to create * the file. -- rgerhards, 2008-12-18 (based on patch from William Tisater) */ fd = open((char *)newFileName, O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY | O_CLOEXEC, pData->fCreateMode); if (fd != -1) { /* check and set uid/gid */ if (pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t)-1) { /* we need to set owner/group */ if (fchown(fd, pData->fileUID, pData->fileGID) != 0) { rs_strerror_r(errno, errStr, sizeof(errStr)); parser_errmsg("omfile: chown for file '%s' failed: %s", newFileName, errStr); if (pData->bFailOnChown) { close(fd); ABORT_FINALIZE(RS_RET_ERR); /* we give up */ } /* we will silently ignore the chown() failure * if configured to do so. */ } } close(fd); /* close again, as we need a stream further on */ } else { ABORT_FINALIZE(RS_RET_ERR); } } /* the copies below are clumpsy, but there is no way around given the * anomalies in dirname() and basename() [they MODIFY the provided buffer...] */ uchar szNameBuf[MAXFNAME + 1]; uchar szDirName[MAXFNAME + 1]; uchar szBaseName[MAXFNAME + 1]; ustrncpy(szNameBuf, newFileName, MAXFNAME); szNameBuf[MAXFNAME] = '\0'; ustrncpy(szDirName, (uchar *)dirname((char *)szNameBuf), MAXFNAME); szDirName[MAXFNAME] = '\0'; ustrncpy(szNameBuf, newFileName, MAXFNAME); szNameBuf[MAXFNAME] = '\0'; ustrncpy(szBaseName, (uchar *)basename((char *)szNameBuf), MAXFNAME); szBaseName[MAXFNAME] = '\0'; CHKiRet(strm.Construct(&pData->pStrm)); CHKiRet(strm.SetFName(pData->pStrm, szBaseName, ustrlen(szBaseName))); CHKiRet(strm.SetDir(pData->pStrm, szDirName, ustrlen(szDirName))); CHKiRet(strm.SetiZipLevel(pData->pStrm, pData->iZipLevel)); CHKiRet(strm.SetbVeryReliableZip(pData->pStrm, pData->bVeryRobustZip)); CHKiRet(strm.SetsIOBufSize(pData->pStrm, (size_t)pData->iIOBufSize)); CHKiRet(strm.SettOperationsMode(pData->pStrm, STREAMMODE_WRITE_APPEND)); CHKiRet(strm.SettOpenMode(pData->pStrm, cs.fCreateMode)); CHKiRet(strm.SetbSync(pData->pStrm, pData->bSyncFile)); CHKiRet(strm.SetsType(pData->pStrm, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetiSizeLimit(pData->pStrm, pData->iSizeLimit)); if (pData->useCryprov) { CHKiRet(strm.Setcryprov(pData->pStrm, &pData->cryprov)); CHKiRet(strm.SetcryprovData(pData->pStrm, pData->cryprovData)); } /* set the flush interval only if we actually use it - otherwise it will activate * async processing, which is a real performance waste if we do not do buffered * writes! -- rgerhards, 2009-07-06 */ if (pData->bUseAsyncWriter) CHKiRet(strm.SetiFlushInterval(pData->pStrm, pData->iFlushInterval)); if (pData->pszSizeLimitCmd != NULL) CHKiRet(strm.SetpszSizeLimitCmd(pData->pStrm, ustrdup(pData->pszSizeLimitCmd))); CHKiRet(strm.ConstructFinalize(pData->pStrm)); if (pData->useSigprov) sigprovPrepare(pData, szNameBuf); finalize_it: if (iRet != RS_RET_OK) { if (pData->pStrm != NULL) { closeFile(pData); } } RETiRet; } // /* verify enough we have space left for writes */ static rsRetVal fsCheck(instanceData *__restrict__ const pData, const uchar *__restrict__ const fileName) { DEFiRet; struct statvfs stat; char *pathcopy; const char *path; pathcopy = strdup((char *)fileName); path = dirname(pathcopy); if (statvfs(path, &stat) != 0) { iRet = RS_RET_FILE_NO_STAT; LogError(0, iRet, "could not stat %s", path); FINALIZE; } /* check if we have space available for all buffers to be flushed and for * a maximum length message, perhaps current msg size would be enough */ if (stat.f_bsize * stat.f_bavail < pData->iIOBufSize * pData->iDynaFileCacheSize + (uint)(glbl.GetMaxLine(runModConf->pConf))) { iRet = RS_RET_FS_ERR; LogError(0, iRet, "too few available blocks in %s", path); FINALIZE; } /* there must be enough inodes left, one is left for administrative purposes * check is not done if file system reports 0 total inodes, such as btrfs */ if (stat.f_favail < 2 && stat.f_files > 0) { iRet = RS_RET_FS_ERR; LogError(0, iRet, "too few available inodes in %s", path); FINALIZE; } /* file system must not be read only */ if (stat.f_flag == ST_RDONLY) { iRet = RS_RET_FS_ERR; LogError(0, iRet, "file-system is read-only in %s", path); FINALIZE; } iRet = RS_RET_OK; finalize_it: if (pathcopy != NULL) free(pathcopy); RETiRet; } // /* This function handles dynamic file names. It checks if the * requested file name is already open and, if not, does everything * needed to switch to the it. * Function returns 0 if all went well and non-zero otherwise. * On successful return pData->fd must point to the correct file to * be written. * This is a helper to writeFile(). rgerhards, 2007-07-03 */ static rsRetVal prepareDynFile(instanceData *__restrict__ const pData, const uchar *__restrict__ const newFileName) { uint64 ctOldest; /* "timestamp" of oldest element */ int iOldest; uint i; int iFirstFree; rsRetVal localRet; dynaFileCacheEntry **pCache; DEFiRet; assert(pData != NULL); assert(newFileName != NULL); pCache = pData->dynCache; /* first check, if we still have the current file */ if ((pData->iCurrElt != -1) && !ustrcmp(newFileName, pCache[pData->iCurrElt]->pName)) { CHKiRet(fsCheck(pData, newFileName)); /* great, we are all set */ pCache[pData->iCurrElt]->clkTickAccessed = getClockFileAccess(); STATSCOUNTER_INC(pData->ctrLevel0, pData->mutCtrLevel0); /* LRU needs only a strictly monotonically increasing counter, so such a one could do */ FINALIZE; } /* ok, no luck. Now let's search the table if we find a matching spot. * While doing so, we also prepare for creation of a new one. */ pData->iCurrElt = -1; /* invalid current element pointer */ iFirstFree = -1; /* not yet found */ iOldest = 0; /* we assume the first element to be the oldest - that will change as we loop */ ctOldest = getClockFileAccess(); /* there must always be an older one */ for (i = 0; i < pData->iCurrCacheSize; ++i) { if (pCache[i] == NULL || pCache[i]->pName == NULL) { if (iFirstFree == -1) iFirstFree = i; } else { /* got an element, let's see if it matches */ if (!ustrcmp(newFileName, pCache[i]->pName)) { CHKiRet(fsCheck(pData, newFileName)); /* we found our element! */ pData->pStrm = pCache[i]->pStrm; if (pData->useSigprov) pData->sigprovFileData = pCache[i]->sigprovFileData; pData->iCurrElt = i; pCache[i]->clkTickAccessed = getClockFileAccess(); /* update "timestamp" for LRU */ FINALIZE; } /* did not find it - so lets keep track of the counters for LRU */ if (pCache[i]->clkTickAccessed < ctOldest) { ctOldest = pCache[i]->clkTickAccessed; iOldest = i; } } } /* we have not found an entry */ STATSCOUNTER_INC(pData->ctrMiss, pData->mutCtrMiss); /* similarly, we need to set the current pStrm to NULL, because otherwise, if prepareFile() fails, * we may end up using an old stream. This bug depends on how exactly prepareFile fails, * but it could be triggered in the common case of a failed open() system call. * rgerhards, 2010-03-22 */ pData->pStrm = NULL, pData->sigprovFileData = NULL; if (iFirstFree == -1 && (pData->iCurrCacheSize < pData->iDynaFileCacheSize)) { /* there is space left, so set it to that index */ iFirstFree = pData->iCurrCacheSize++; STATSCOUNTER_SETMAX_NOMUT(pData->ctrMax, (unsigned)pData->iCurrCacheSize); } /* Note that the following code sequence does not work with the cache entry itself, * but rather with pData->pStrm, the (sole) stream pointer in the non-dynafile case. * The cache array is only updated after the open was successful. -- rgerhards, 2010-03-21 */ if (iFirstFree == -1) { dynaFileDelCacheEntry(pData, iOldest, 0); STATSCOUNTER_INC(pData->ctrEvict, pData->mutCtrEvict); iFirstFree = iOldest; /* this one *is* now free ;) */ } else { /* we need to allocate memory for the cache structure */ CHKmalloc(pCache[iFirstFree] = (dynaFileCacheEntry *)calloc(1, sizeof(dynaFileCacheEntry))); } /* Ok, we finally can open the file */ localRet = prepareFile(pData, newFileName); /* ignore exact error, we check fd below */ /* check if we had an error */ if (localRet != RS_RET_OK) { /* We do no longer care about internal messages. The errmsg rate limiter * will take care of too-frequent error messages. */ parser_errmsg("Could not open dynamic file '%s' [state %d]", newFileName, localRet); ABORT_FINALIZE(localRet); } localRet = fsCheck(pData, newFileName); if (localRet != RS_RET_OK) { parser_errmsg("Invalid file-system condition for dynamic file '%s' [state %d]", newFileName, localRet); ABORT_FINALIZE(localRet); } if ((pCache[iFirstFree]->pName = ustrdup(newFileName)) == NULL) { closeFile(pData); /* need to free failed entry! */ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pCache[iFirstFree]->pStrm = pData->pStrm; if (pData->useSigprov) pCache[iFirstFree]->sigprovFileData = pData->sigprovFileData; pCache[iFirstFree]->clkTickAccessed = getClockFileAccess(); pData->iCurrElt = iFirstFree; DBGPRINTF("Added new entry %d for file cache, file '%s'.\n", iFirstFree, newFileName); finalize_it: if (iRet == RS_RET_OK) pCache[pData->iCurrElt]->nInactive = 0; RETiRet; } /* do the actual write process. This function is to be called once we are ready for writing. * It will do buffered writes and persist data only when the buffer is full. Note that we must * be careful to detect when the file handle changed. * rgerhards, 2009-06-03 */ static rsRetVal doWrite(instanceData *__restrict__ const pData, uchar *__restrict__ const pszBuf, const int lenBuf) { DEFiRet; assert(pData != NULL); assert(pszBuf != NULL); DBGPRINTF("omfile: write to stream, pData->pStrm %p, lenBuf %d, strt data %.128s\n", pData->pStrm, lenBuf, pszBuf); if (pData->pStrm != NULL) { CHKiRet(strm.Write(pData->pStrm, pszBuf, lenBuf)); if (pData->useSigprov) { CHKiRet(pData->sigprov.OnRecordWrite(pData->sigprovFileData, pszBuf, lenBuf)); } } finalize_it: RETiRet; } /* rgerhards 2004-11-11: write to a file output. */ static rsRetVal writeFile(instanceData *__restrict__ const pData, const actWrkrIParams_t *__restrict__ const pParam, const int iMsg) { DEFiRet; STATSCOUNTER_INC(pData->ctrRequests, pData->mutCtrRequests); /* first check if we have a dynamic file name and, if so, * check if it still is ok or a new file needs to be created */ if (pData->bDynamicName) { DBGPRINTF("omfile: file to log to: %s\n", actParam(pParam, pData->iNumTpls, iMsg, 1).param); CHKiRet(prepareDynFile(pData, actParam(pParam, pData->iNumTpls, iMsg, 1).param)); } else { /* "regular", non-dynafile */ if (pData->pStrm == NULL) { CHKiRet(prepareFile(pData, pData->fname)); if (pData->pStrm == NULL) { parser_errmsg("Could not open output file '%s'", pData->fname); } CHKiRet(fsCheck(pData, pData->fname)); } pData->nInactive = 0; } iRet = doWrite(pData, actParam(pParam, pData->iNumTpls, iMsg, 0).param, actParam(pParam, pData->iNumTpls, iMsg, 0).lenStr); finalize_it: RETiRet; } BEGINbeginCnfLoad CODESTARTbeginCnfLoad; loadModConf = pModConf; pModConf->pConf = pConf; pModConf->tplName = NULL; pModConf->fCreateMode = 0644; pModConf->fDirCreateMode = 0700; pModConf->fileUID = -1; pModConf->dirUID = -1; pModConf->fileGID = -1; pModConf->dirGID = -1; pModConf->bDynafileDoNotSuspend = 1; ENDbeginCnfLoad BEGINsetModCnf struct cnfparamvals *pvals = NULL; int i; CODESTARTsetModCnf; pvals = nvlstGetParams(lst, &modpblk, NULL); if (pvals == NULL) { parser_errmsg( "error processing module " "config parameters [module(...)]"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("module (global) param blk for omfile:\n"); cnfparamsPrint(&modpblk, pvals); } for (i = 0; i < modpblk.nParams; ++i) { if (!pvals[i].bUsed) { continue; } if (!strcmp(modpblk.descr[i].name, "template")) { loadModConf->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); if (pszFileDfltTplName != NULL) { parser_errmsg( "omfile: warning: default template was already " "set via legacy directive - may lead to inconsistent " "results."); } } else if (!strcmp(modpblk.descr[i].name, "dircreatemode")) { loadModConf->fDirCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filecreatemode")) { loadModConf->fCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirowner")) { loadModConf->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirownernum")) { loadModConf->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirgroup")) { loadModConf->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dirgroupnum")) { loadModConf->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "fileowner")) { loadModConf->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "fileownernum")) { loadModConf->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filegroup")) { loadModConf->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "filegroupnum")) { loadModConf->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(modpblk.descr[i].name, "dynafile.donotsuspend")) { loadModConf->bDynafileDoNotSuspend = (int)pvals[i].val.d.n; } else { dbgprintf( "omfile: program error, non-handled " "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); } } finalize_it: if (pvals != NULL) cnfparamvalsDestruct(pvals, &modpblk); ENDsetModCnf /* This function checks dynafile cache for janitor action */ static void janitorChkDynaFiles(instanceData *__restrict__ const pData) { uint i; dynaFileCacheEntry **pCache = pData->dynCache; for (i = 0; i < pData->iCurrCacheSize; ++i) { if (pCache[i] == NULL) continue; DBGPRINTF("omfile janitor: checking dynafile %d:%s, inactive since %d\n", i, pCache[i]->pName == NULL ? UCHAR_CONSTANT("[OPEN FAILED]") : pCache[i]->pName, (int)pCache[i]->nInactive); if (pCache[i]->nInactive >= pData->iCloseTimeout) { STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); dynaFileDelCacheEntry(pData, i, 1); if (pData->iCurrElt >= 0) { if ((uint)(pData->iCurrElt) == i) pData->iCurrElt = -1; /* no longer available! */ } } else { pCache[i]->nInactive += runModConf->pConf->globals.janitorInterval; } } } /* callback for the janitor. This cleans out files (if so configured) */ static void janitorCB(void *pUsr) { instanceData *__restrict__ const pData = (instanceData *)pUsr; pthread_mutex_lock(&pData->mutWrite); if (pData->bDynamicName) { janitorChkDynaFiles(pData); } else { if (pData->pStrm != NULL) { DBGPRINTF("omfile janitor: checking file %s, inactive since %d\n", pData->fname, pData->nInactive); if (pData->nInactive >= pData->iCloseTimeout) { STATSCOUNTER_INC(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); closeFile(pData); } else { pData->nInactive += runModConf->pConf->globals.janitorInterval; } } } pthread_mutex_unlock(&pData->mutWrite); } BEGINendCnfLoad CODESTARTendCnfLoad; loadModConf = NULL; /* done loading */ /* free legacy config vars */ free(pszFileDfltTplName); pszFileDfltTplName = NULL; ENDendCnfLoad BEGINcheckCnf CODESTARTcheckCnf; ENDcheckCnf BEGINactivateCnf CODESTARTactivateCnf; runModConf = pModConf; ENDactivateCnf BEGINfreeCnf CODESTARTfreeCnf; free(pModConf->tplName); ENDfreeCnf BEGINcreateInstance CODESTARTcreateInstance; pData->pStrm = NULL; pthread_mutex_init(&pData->mutWrite, NULL); ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINfreeInstance CODESTARTfreeInstance; free(pData->tplName); free(pData->fname); if (pData->iCloseTimeout > 0) janitorDelEtry(pData->janitorID); if (pData->bDynamicName) { dynaFileFreeCache(pData); } else if (pData->pStrm != NULL) closeFile(pData); if (pData->stats != NULL) statsobj.Destruct(&(pData->stats)); if (pData->useSigprov) { pData->sigprov.Destruct(&pData->sigprovData); obj.ReleaseObj(__FILE__, pData->sigprovNameFull + 2, pData->sigprovNameFull, (void *)&pData->sigprov); free(pData->sigprovName); free(pData->sigprovNameFull); } if (pData->useCryprov) { pData->cryprov.Destruct(&pData->cryprovData); obj.ReleaseObj(__FILE__, pData->cryprovNameFull + 2, pData->cryprovNameFull, (void *)&pData->cryprov); free(pData->cryprovName); free(pData->cryprovNameFull); } pthread_mutex_destroy(&pData->mutWrite); ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINbeginTransaction CODESTARTbeginTransaction; /* we have nothing to do to begin a transaction */ ENDbeginTransaction BEGINcommitTransaction instanceData *__restrict__ const pData = pWrkrData->pData; unsigned i; CODESTARTcommitTransaction; pthread_mutex_lock(&pData->mutWrite); for (i = 0; i < nParams; ++i) { CHKiRet(writeFile(pData, pParams, i)); } /* Note: pStrm may be NULL if there was an error opening the stream */ /* if bFlushOnTXEnd is set, we need to flush on transaction end - in * any case. It is not relevant if this is using background writes * (which then become pretty slow) or not. And, similarly, no flush * happens when it is not set. Please see * https://github.com/rsyslog/rsyslog/issues/1297 * for a discussion of why we actually need this. * rgerhards, 2017-01-13 */ if (pData->bFlushOnTXEnd && pData->pStrm != NULL) { CHKiRet(strm.Flush(pData->pStrm)); } finalize_it: if (iRet != RS_RET_OK) { if (runModConf->bDynafileDoNotSuspend == 0 || !(pData->bDynamicName)) { LogError(0, iRet, "suspending action"); iRet = RS_RET_SUSPENDED; } else { LogError(0, iRet, "discarding message"); } } pthread_mutex_unlock(&pData->mutWrite); ENDcommitTransaction static void setInstParamDefaults(instanceData *__restrict__ const pData) { pData->fname = NULL; pData->tplName = NULL; pData->fileUID = loadModConf->fileUID; pData->fileGID = loadModConf->fileGID; pData->dirUID = loadModConf->dirUID; pData->dirGID = loadModConf->dirGID; pData->bFailOnChown = 1; pData->iDynaFileCacheSize = 10; pData->fCreateMode = loadModConf->fCreateMode; pData->fDirCreateMode = loadModConf->fDirCreateMode; pData->bCreateDirs = 1; pData->bSyncFile = 0; pData->iZipLevel = 0; pData->bVeryRobustZip = 0; pData->bFlushOnTXEnd = FLUSHONTX_DFLT; pData->iIOBufSize = IOBUF_DFLT_SIZE; pData->iFlushInterval = FLUSH_INTRVL_DFLT; pData->bUseAsyncWriter = USE_ASYNCWRITER_DFLT; pData->sigprovName = NULL; pData->cryprovName = NULL; pData->useSigprov = 0; pData->useCryprov = 0; pData->iCloseTimeout = -1; } static rsRetVal setupInstStatsCtrs(instanceData *__restrict__ const pData) { uchar ctrName[512]; DEFiRet; if (!pData->bDynamicName) { FINALIZE; } /* support statistics gathering */ snprintf((char *)ctrName, sizeof(ctrName), "dynafile cache %s", pData->fname); ctrName[sizeof(ctrName) - 1] = '\0'; /* be on the save side */ CHKiRet(statsobj.Construct(&(pData->stats))); CHKiRet(statsobj.SetName(pData->stats, ctrName)); CHKiRet(statsobj.SetOrigin(pData->stats, (uchar *)"omfile")); STATSCOUNTER_INIT(pData->ctrRequests, pData->mutCtrRequests); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("requests"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrRequests))); STATSCOUNTER_INIT(pData->ctrLevel0, pData->mutCtrLevel0); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("level0"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrLevel0))); STATSCOUNTER_INIT(pData->ctrMiss, pData->mutCtrMiss); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("missed"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMiss))); STATSCOUNTER_INIT(pData->ctrEvict, pData->mutCtrEvict); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("evicted"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrEvict))); STATSCOUNTER_INIT(pData->ctrMax, pData->mutCtrMax); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("maxused"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrMax))); STATSCOUNTER_INIT(pData->ctrCloseTimeouts, pData->mutCtrCloseTimeouts); CHKiRet(statsobj.AddCounter(pData->stats, UCHAR_CONSTANT("closetimeouts"), ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pData->ctrCloseTimeouts))); CHKiRet(statsobj.ConstructFinalize(pData->stats)); finalize_it: RETiRet; } static void initSigprov(instanceData *__restrict__ const pData, struct nvlst *lst) { uchar szDrvrName[1024]; if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmsig_%s", pData->sigprovName) == sizeof(szDrvrName)) { parser_errmsg( "omfile: signature provider " "name is too long: '%s' - signatures disabled", pData->sigprovName); goto done; } pData->sigprovNameFull = ustrdup(szDrvrName); pData->sigprov.ifVersion = sigprovCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean enough. */ if (obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void *)&pData->sigprov) != RS_RET_OK) { parser_errmsg( "omfile: could not load " "signature provider '%s' - signatures disabled", szDrvrName); goto done; } if (pData->sigprov.Construct(&pData->sigprovData) != RS_RET_OK) { parser_errmsg( "omfile: error constructing " "signature provider %s dataset - signatures disabled", szDrvrName); goto done; } pData->sigprov.SetCnfParam(pData->sigprovData, lst); dbgprintf("loaded signature provider %s, data instance at %p\n", szDrvrName, pData->sigprovData); pData->useSigprov = 1; done: return; } static rsRetVal initCryprov(instanceData *__restrict__ const pData, struct nvlst *lst) { uchar szDrvrName[1024]; DEFiRet; if (snprintf((char *)szDrvrName, sizeof(szDrvrName), "lmcry_%s", pData->cryprovName) == sizeof(szDrvrName)) { parser_errmsg( "omfile: crypto provider " "name is too long: '%s' - encryption disabled", pData->cryprovName); ABORT_FINALIZE(RS_RET_ERR); } pData->cryprovNameFull = ustrdup(szDrvrName); pData->cryprov.ifVersion = cryprovCURR_IF_VERSION; /* The pDrvrName+2 below is a hack to obtain the object name. It * safes us to have yet another variable with the name without "lm" in * front of it. If we change the module load interface, we may re-think * about this hack, but for the time being it is efficient and clean enough. */ if (obj.UseObj(__FILE__, szDrvrName, szDrvrName, (void *)&pData->cryprov) != RS_RET_OK) { parser_errmsg( "omfile: could not load " "crypto provider '%s' - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } if (pData->cryprov.Construct(&pData->cryprovData) != RS_RET_OK) { parser_errmsg( "omfile: error constructing " "crypto provider %s dataset - encryption disabled", szDrvrName); ABORT_FINALIZE(RS_RET_CRYPROV_ERR); } CHKiRet(pData->cryprov.SetCnfParam(pData->cryprovData, lst, CRYPROV_PARAMTYPE_REGULAR)); dbgprintf("loaded crypto provider %s, data instance at %p\n", szDrvrName, pData->cryprovData); pData->useCryprov = 1; finalize_it: RETiRet; } BEGINnewActInst struct cnfparamvals *pvals; uchar *tplToUse; int i; CODESTARTnewActInst; DBGPRINTF("newActInst (omfile)\n"); pvals = nvlstGetParams(lst, &actpblk, NULL); if (pvals == NULL) { parser_errmsg( "omfile: either the \"file\" or " "\"dynafile\" parameter must be given"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("action param blk in omfile:\n"); cnfparamsPrint(&actpblk, pvals); } CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "dynafilecachesize")) { pData->iDynaFileCacheSize = (uint)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ziplevel")) { pData->iZipLevel = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "flushinterval")) { pData->iFlushInterval = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "veryrobustzip")) { pData->bVeryRobustZip = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "asyncwriting")) { pData->bUseAsyncWriter = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "flushontxend")) { pData->bFlushOnTXEnd = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "iobuffersize")) { pData->iIOBufSize = (uint)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirowner")) { pData->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirownernum")) { pData->dirUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirgroup")) { pData->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dirgroupnum")) { pData->dirGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "fileowner")) { pData->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "fileownernum")) { pData->fileUID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filegroup")) { pData->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filegroupnum")) { pData->fileGID = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "dircreatemode")) { pData->fDirCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "filecreatemode")) { pData->fCreateMode = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "failonchownfailure")) { pData->bFailOnChown = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "sync")) { pData->bSyncFile = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "createdirs")) { pData->bCreateDirs = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "file")) { pData->fname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); CODE_STD_STRING_REQUESTnewActInst(1); pData->bDynamicName = 0; } else if (!strcmp(actpblk.descr[i].name, "dynafile")) { if (pData->fname != NULL) { parser_errmsg("omfile: both \"file\" and \"dynafile\" set, will use dynafile"); } pData->fname = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); CODE_STD_STRING_REQUESTnewActInst(2); pData->bDynamicName = 1; } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "sig.provider")) { pData->sigprovName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "cry.provider")) { pData->cryprovName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "closetimeout")) { pData->iCloseTimeout = (int)pvals[i].val.d.n; } else { dbgprintf( "omfile: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } if (pData->fname == NULL) { parser_errmsg( "omfile: either the \"file\" or " "\"dynafile\" parameter must be given"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (pData->sigprovName != NULL) { initSigprov(pData, lst); } if (pData->cryprovName != NULL) { CHKiRet(initCryprov(pData, lst)); } tplToUse = ustrdup((pData->tplName == NULL) ? getDfltTpl() : pData->tplName); CHKiRet(OMSRsetEntry(*ppOMSR, 0, tplToUse, OMSR_NO_RQD_TPL_OPTS)); pData->iNumTpls = 1; if (pData->bDynamicName) { /* "filename" is actually a template name, we need this as string 1. So let's add it * to the pOMSR. -- rgerhards, 2007-07-27 */ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); pData->iNumTpls = 2; // TODO: create unified code for this (legacy+v6 system) /* we now allocate the cache table */ CHKmalloc(pData->dynCache = (dynaFileCacheEntry **)calloc(pData->iDynaFileCacheSize, sizeof(dynaFileCacheEntry *))); pData->iCurrElt = -1; /* no current element */ } // TODO: add pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ setupInstStatsCtrs(pData); if (pData->iCloseTimeout == -1) { /* unset? */ pData->iCloseTimeout = (pData->bDynamicName) ? 10 : 0; } snprintf(pData->janitorID, sizeof(pData->janitorID), "omfile:%sfile:%s:%p", (pData->bDynamicName) ? "dyna" : "", pData->fname, pData); pData->janitorID[sizeof(pData->janitorID) - 1] = '\0'; /* just in case... */ if (pData->iCloseTimeout > 0) janitorAddEtry(janitorCB, pData->janitorID, pData); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); ENDnewActInst BEGINparseSelectorAct uchar fname[MAXFNAME]; CODESTARTparseSelectorAct; /* Note: the indicator sequence permits us to use '$' to signify * outchannel, what otherwise is not possible due to truely * unresolvable grammar conflicts (*this time no way around*). * rgerhards, 2011-07-09 */ if (!strncmp((char *)p, ":omfile:", sizeof(":omfile:") - 1)) { p += sizeof(":omfile:") - 1; } if (!(*p == '$' || *p == '?' || *p == '/' || *p == '.' || *p == '-')) ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); CHKiRet(createInstance(&pData)); if (*p == '-') { pData->bSyncFile = 0; p++; } else { pData->bSyncFile = cs.bEnableSync; } pData->iSizeLimit = 0; /* default value, use outchannels to configure! */ switch (*p) { case '$': CODE_STD_STRING_REQUESTparseSelectorAct(1) pData->iNumTpls = 1; /* rgerhards 2005-06-21: this is a special setting for output-channel * definitions. In the long term, this setting will probably replace * anything else, but for the time being we must co-exist with the * traditional mode lines. * rgerhards, 2007-07-24: output-channels will go away. We keep them * for compatibility reasons, but seems to have been a bad idea. */ CHKiRet(cflineParseOutchannel(pData, p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS)); pData->bDynamicName = 0; break; case '?': /* This is much like a regular file handle, but we need to obtain * a template name. rgerhards, 2007-07-03 */ CODE_STD_STRING_REQUESTparseSelectorAct(2) pData->iNumTpls = 2; ++p; /* eat '?' */ CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); pData->fname = ustrdup(fname); pData->bDynamicName = 1; pData->iCurrElt = -1; /* no current element */ /* "filename" is actually a template name, we need this as string 1. So let's add it * to the pOMSR. -- rgerhards, 2007-07-27 */ CHKiRet(OMSRsetEntry(*ppOMSR, 1, ustrdup(pData->fname), OMSR_NO_RQD_TPL_OPTS)); /* we now allocate the cache table */ CHKmalloc(pData->dynCache = (dynaFileCacheEntry **)calloc(cs.iDynaFileCacheSize, sizeof(dynaFileCacheEntry *))); break; case '/': case '.': CODE_STD_STRING_REQUESTparseSelectorAct(1) pData->iNumTpls = 1; CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl())); pData->fname = ustrdup(fname); pData->bDynamicName = 0; break; default: ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); } /* freeze current paremeters for this action */ pData->iDynaFileCacheSize = cs.iDynaFileCacheSize; pData->fCreateMode = cs.fCreateMode; pData->fDirCreateMode = cs.fDirCreateMode; pData->bCreateDirs = cs.bCreateDirs; pData->bFailOnChown = cs.bFailOnChown; pData->fileUID = cs.fileUID; pData->fileGID = cs.fileGID; pData->dirUID = cs.dirUID; pData->dirGID = cs.dirGID; pData->iZipLevel = cs.iZipLevel; pData->bFlushOnTXEnd = cs.bFlushOnTXEnd; pData->iIOBufSize = (uint)cs.iIOBufSize; pData->iFlushInterval = cs.iFlushInterval; pData->bUseAsyncWriter = cs.bUseAsyncWriter; pData->bVeryRobustZip = 0; /* cannot be specified via legacy conf */ pData->iCloseTimeout = 0; /* cannot be specified via legacy conf */ setupInstStatsCtrs(pData); CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct /* Reset config variables for this module to default values. * rgerhards, 2007-07-17 */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) * pp, void __attribute__((unused)) * pVal) { cs.fileUID = -1; cs.fileGID = -1; cs.dirUID = -1; cs.dirGID = -1; cs.bFailOnChown = 1; cs.iDynaFileCacheSize = 10; cs.fCreateMode = 0644; cs.fDirCreateMode = 0700; cs.bCreateDirs = 1; cs.bEnableSync = 0; cs.iZipLevel = 0; cs.bFlushOnTXEnd = FLUSHONTX_DFLT; cs.iIOBufSize = IOBUF_DFLT_SIZE; cs.iFlushInterval = FLUSH_INTRVL_DFLT; cs.bUseAsyncWriter = USE_ASYNCWRITER_DFLT; free(pszFileDfltTplName); pszFileDfltTplName = NULL; return RS_RET_OK; } BEGINdoHUP CODESTARTdoHUP; pthread_mutex_lock(&pData->mutWrite); if (pData->bDynamicName) { dynaFileFreeCacheEntries(pData); } else { if (pData->pStrm != NULL) { closeFile(pData); } } pthread_mutex_unlock(&pData->mutWrite); ENDdoHUP BEGINmodExit CODESTARTmodExit; objRelease(glbl, CORE_COMPONENT); objRelease(strm, CORE_COMPONENT); objRelease(statsobj, CORE_COMPONENT); DESTROY_ATOMIC_HELPER_MUT(mutClock); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMODTX_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_QUERIES; CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_doHUP ENDqueryEtryPt BEGINmodInit(File) CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr INITLegCnfVars; CHKiRet(objUse(strm, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); INIT_ATOMIC_HELPER_MUT(mutClock); INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); DBGPRINTF("omfile: %susing transactional output interface.\n", bCoreSupportsBatching ? "" : "not "); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dynafilecachesize", 0, eCmdHdlrInt, setDynaFileCacheSize, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileziplevel", 0, eCmdHdlrInt, NULL, &cs.iZipLevel, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushinterval", 0, eCmdHdlrInt, NULL, &cs.iFlushInterval, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileasyncwriting", 0, eCmdHdlrBinary, NULL, &cs.bUseAsyncWriter, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileflushontxend", 0, eCmdHdlrBinary, NULL, &cs.bFlushOnTXEnd, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileiobuffersize", 0, eCmdHdlrSize, NULL, &cs.iIOBufSize, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirowner", 0, eCmdHdlrUID, NULL, &cs.dirUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirownernum", 0, eCmdHdlrInt, NULL, &cs.dirUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroup", 0, eCmdHdlrGID, NULL, &cs.dirGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dirgroupnum", 0, eCmdHdlrInt, NULL, &cs.dirGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileowner", 0, eCmdHdlrUID, NULL, &cs.fileUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"fileownernum", 0, eCmdHdlrInt, NULL, &cs.fileUID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroup", 0, eCmdHdlrGID, NULL, &cs.fileGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filegroupnum", 0, eCmdHdlrInt, NULL, &cs.fileGID, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"dircreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fDirCreateMode, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &cs.fCreateMode, STD_LOADABLE_MODULE_ID)); CHKiRet( omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &cs.bCreateDirs, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileforcechown", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/omfile-hardened/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316021265 xustar0030 mtime=1764935886.200010213 30 atime=1764935896.817172839 30 ctime=1764935924.982604122 rsyslog-8.2512.0/contrib/omfile-hardened/Makefile.in0000664000175000017500000006411515114544316020740 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omfile-hardened ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) omfile_hardened_la_DEPENDENCIES = am_omfile_hardened_la_OBJECTS = omfile_hardened_la-omfile-hardened.lo omfile_hardened_la_OBJECTS = $(am_omfile_hardened_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omfile_hardened_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(omfile_hardened_la_LDFLAGS) \ $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = \ ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omfile_hardened_la_SOURCES) DIST_SOURCES = $(omfile_hardened_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omfile-hardened.la omfile_hardened_la_SOURCES = omfile-hardened.c omfile_hardened_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools omfile_hardened_la_LDFLAGS = -module -avoid-version omfile_hardened_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omfile-hardened/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omfile-hardened/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omfile-hardened.la: $(omfile_hardened_la_OBJECTS) $(omfile_hardened_la_DEPENDENCIES) $(EXTRA_omfile_hardened_la_DEPENDENCIES) $(AM_V_CCLD)$(omfile_hardened_la_LINK) -rpath $(pkglibdir) $(omfile_hardened_la_OBJECTS) $(omfile_hardened_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omfile_hardened_la-omfile-hardened.lo: omfile-hardened.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omfile_hardened_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omfile_hardened_la-omfile-hardened.lo -MD -MP -MF $(DEPDIR)/omfile_hardened_la-omfile-hardened.Tpo -c -o omfile_hardened_la-omfile-hardened.lo `test -f 'omfile-hardened.c' || echo '$(srcdir)/'`omfile-hardened.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omfile_hardened_la-omfile-hardened.Tpo $(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omfile-hardened.c' object='omfile_hardened_la-omfile-hardened.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omfile_hardened_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omfile_hardened_la-omfile-hardened.lo `test -f 'omfile-hardened.c' || echo '$(srcdir)/'`omfile-hardened.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omfile_hardened_la-omfile-hardened.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/pmdb2diag0000644000000000000000000000012715114544373015760 xustar0029 mtime=1764935931.68470672 29 atime=1764935934.36774779 29 ctime=1764935931.68470672 rsyslog-8.2512.0/contrib/pmdb2diag/0000775000175000017500000000000015114544373015475 5ustar00rgerrgerrsyslog-8.2512.0/contrib/pmdb2diag/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264020060 xustar0030 mtime=1752569012.331237145 30 atime=1764930929.565828354 30 ctime=1764935931.680706659 rsyslog-8.2512.0/contrib/pmdb2diag/Makefile.am0000664000175000017500000000034415035412264017525 0ustar00rgerrgerpkglib_LTLIBRARIES = pmdb2diag.la pmdb2diag_la_SOURCES = pmdb2diag.c pmdb2diag_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmdb2diag_la_LDFLAGS = -module -avoid-version pmdb2diag_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/pmdb2diag/PaxHeaders/pmdb2diag.c0000644000000000000000000000013115055605325020024 xustar0030 mtime=1756826325.614800155 30 atime=1764931156.705570906 29 ctime=1764935931.68470672 rsyslog-8.2512.0/contrib/pmdb2diag/pmdb2diag.c0000664000175000017500000002314515055605325017476 0ustar00rgerrger/* pmdb2diag.c * * This is a parser module specifically for DB2diag log file. * It extracted program, pid and severity from the log. * * Copyright 2015 Philippe Duveau @ Pari Mutuel Urbain. * * This file is contribution of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "msg.h" #include "module-template.h" #include "glbl.h" #include "errmsg.h" #include "parser.h" #include "datetime.h" #include "unicode-helper.h" MODULE_TYPE_PARSER MODULE_TYPE_NOKEEP; PARSER_NAME("db2.diag") MODULE_CNFNAME("pmdb2diag") /* internal structures */ DEF_PMOD_STATIC_DATA; DEFobjCurrIf(glbl) DEFobjCurrIf(datetime) /* input instance parameters */ static struct cnfparamdescr parserpdescr[] = { {"levelpos", eCmdHdlrInt, 0}, {"timepos", eCmdHdlrInt, 0}, {"timeformat", eCmdHdlrString, 0}, {"pidstarttoprogstartshift", eCmdHdlrInt, 0}, }; static struct cnfparamblk parserpblk = {CNFPARAMBLK_VERSION, sizeof(parserpdescr) / sizeof(struct cnfparamdescr), parserpdescr}; struct instanceConf_s { int levelpos; /* expected severity position in read message */ int timepos; /* expected time position in read message */ int pidstarttoprogstartshift; /* position of prog related to pid */ char *timeformat; /* format of timestamp in read message */ char sepSec; /* decimal separator between second and milliseconds */ }; BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATUREAutomaticPRIParsing) iRet = RS_RET_OK; ENDisCompatibleWithFeature BEGINparse2 struct tm tm; char *ms, *timepos, *pid, *prog, *eprog, *backslash, *end, *lvl; int lprog, lpid, lvl_len; char buffer[128]; CODESTARTparse2; assert(pMsg != NULL); assert(pMsg->pszRawMsg != NULL); DBGPRINTF("Message will now be parsed by \"db2diag\" parser.\n"); if (pMsg->iLenRawMsg - (int)pMsg->offAfterPRI < pInst->levelpos + 4) ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); /* Instead of comparing strings which a waste of cpu cycles we take interpret the 4 first chars of * level read it as int32 and compare it to same interpretation of our constant "levels" * So this test is not sensitive to ENDIANESS. This is not a clean way but very efficient. */ lvl = (char *)(pMsg->pszRawMsg + pMsg->offAfterPRI + pInst->levelpos); switch (*lvl) { case 'C': /* Critical */ pMsg->iSeverity = LOG_EMERG; lvl_len = 8; break; case 'A': /* Alert */ pMsg->iSeverity = LOG_ALERT; lvl_len = 5; break; case 'S': /* Severe */ pMsg->iSeverity = LOG_CRIT; lvl_len = 6; break; case 'E': /* Error / Event */ pMsg->iSeverity = (lvl[1] == 'r') ? LOG_ERR : LOG_NOTICE; lvl_len = 5; break; case 'W': /* Warning */ pMsg->iSeverity = LOG_WARNING; lvl_len = 7; break; case 'I': /* Info */ pMsg->iSeverity = LOG_INFO; lvl_len = 4; break; case 'D': /* Debug */ pMsg->iSeverity = LOG_DEBUG; lvl_len = 5; break; default: /* perhaps the message does not contain a proper level if so don't parse the log */ ABORT_FINALIZE(0); } /* let recheck with the real level len */ if (pMsg->iLenRawMsg - (int)pMsg->offAfterPRI < pInst->levelpos + lvl_len) ABORT_FINALIZE(RS_RET_COULD_NOT_PARSE); DBGPRINTF("db2parse Level %d\n", pMsg->iSeverity); end = (char *)pMsg->pszRawMsg + pMsg->iLenRawMsg; timepos = (char *)pMsg->pszRawMsg + pMsg->offAfterPRI + pInst->timepos; DBGPRINTF("db2parse Time %.30s\n", timepos); ms = strptime(timepos, pInst->timeformat, &tm); if (ms > timepos && *(ms - 1) == pInst->sepSec) { /* the timestamp could be properly interpreted by strptime & our format then set proper timestamp */ int secfrac = 0, tzoff = 0; char *tzpos = strchr(ms, '+'); if (!tzpos) tzpos = strchr(ms, '-'); if (!tzpos) tzpos = (char *)"+"; sscanf(ms, (*tzpos == '+') ? "%d+%d " : "%d-%d ", &secfrac, &tzoff); pMsg->tTIMESTAMP.year = tm.tm_year + 1900; pMsg->tTIMESTAMP.month = tm.tm_mon + 1; pMsg->tTIMESTAMP.day = tm.tm_mday; pMsg->tTIMESTAMP.hour = tm.tm_hour; pMsg->tTIMESTAMP.minute = tm.tm_min; pMsg->tTIMESTAMP.second = tm.tm_sec; pMsg->tTIMESTAMP.secfrac = secfrac; pMsg->tTIMESTAMP.secfracPrecision = tzpos - ms; pMsg->tTIMESTAMP.OffsetMode = *tzpos; pMsg->tTIMESTAMP.OffsetHour = tzoff / 60; pMsg->tTIMESTAMP.OffsetMinute = tzoff % 60; } pid = strchr((char *)pMsg->pszRawMsg + pInst->levelpos + lvl_len, ':'); if (!pid || pid >= end) ABORT_FINALIZE(0); pid += 2; lpid = strchr(pid, ' ') - pid; DBGPRINTF("db2parse pid %.*s\n", lpid, pid); /* set the pid */ snprintf(buffer, 128, "%.*s", lpid, pid); MsgSetPROCID(pMsg, buffer); prog = pid + pInst->pidstarttoprogstartshift; /* this offset between start of pid to start of prog */ if (prog >= end) ABORT_FINALIZE(0); eprog = strchr(prog, ' '); /* let find the end of the program */ if (eprog && eprog >= end) ABORT_FINALIZE(0); backslash = strchr(prog, '\\'); /* perhaps program contain an backslash */ if (!backslash || backslash >= end) backslash = end; /* Determine the final length of prog */ lprog = (eprog && eprog < backslash) ? eprog - prog : backslash - prog; DBGPRINTF("db2parse prog %.*s lprog %d\n", lprog, prog, lprog); /* set the appname */ snprintf(buffer, 128, "%.*s", lprog, prog); MsgSetAPPNAME(pMsg, buffer); /* the original raw msg if not altered by the parser */ finalize_it: ENDparse2 BEGINfreeParserInst CODESTARTfreeParserInst; free(pInst->timeformat); ENDfreeParserInst BEGINcheckParserInst CODESTARTcheckParserInst; ENDcheckParserInst static rsRetVal createInstance(instanceConf_t **ppInst) { instanceConf_t *pInst; DEFiRet; CHKmalloc(pInst = (instanceConf_t *)malloc(sizeof(instanceConf_t))); pInst->timeformat = NULL; pInst->levelpos = 59; pInst->timepos = 0; pInst->pidstarttoprogstartshift = 49; *ppInst = pInst; finalize_it: RETiRet; } BEGINnewParserInst struct cnfparamvals *pvals = NULL; int i; CODESTARTnewParserInst; inst = NULL; DBGPRINTF("newParserInst (pmdb2diag)\n"); CHKiRet(createInstance(&inst)); if (lst) { if ((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { DBGPRINTF("parser param blk in pmdb2diag:\n"); cnfparamsPrint(&parserpblk, pvals); } for (i = 0; i < parserpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(parserpblk.descr[i].name, "timeformat")) { inst->timeformat = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(parserpblk.descr[i].name, "timepos")) { inst->timepos = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "levelpos")) { inst->levelpos = (int)pvals[i].val.d.n; } else if (!strcmp(parserpblk.descr[i].name, "pidstarttoprogstartshift")) { inst->pidstarttoprogstartshift = (int)pvals[i].val.d.n; } else { DBGPRINTF( "pmdb2diag: program error, non-handled " "param '%s'\n", parserpblk.descr[i].name); } } } if (inst->timeformat == NULL) { inst->timeformat = strdup("%Y-%m-%d-%H.%M.%S."); inst->sepSec = '.'; } else inst->sepSec = inst->timeformat[strlen(inst->timeformat) - 1]; DBGPRINTF("pmdb2diag: parsing date/time with '%s' at position %d and level at position %d.\n", inst->timeformat, inst->timepos, inst->levelpos); finalize_it: CODE_STD_FINALIZERnewParserInst if (lst != NULL) cnfparamvalsDestruct(pvals, &parserpblk); ENDnewParserInst BEGINmodExit CODESTARTmodExit; /* release what we no longer need */ objRelease(glbl, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_PMOD2_QUERIES; CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); DBGPRINTF("pmdb2diag parser init called, compiled with version %s\n", VERSION); ENDmodInit rsyslog-8.2512.0/contrib/pmdb2diag/PaxHeaders/Makefile.in0000644000000000000000000000013115114544316020072 xustar0030 mtime=1764935886.430013736 30 atime=1764935897.062176592 29 ctime=1764935931.68270669 rsyslog-8.2512.0/contrib/pmdb2diag/Makefile.in0000664000175000017500000006335215114544316017550 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/pmdb2diag ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) pmdb2diag_la_DEPENDENCIES = am_pmdb2diag_la_OBJECTS = pmdb2diag_la-pmdb2diag.lo pmdb2diag_la_OBJECTS = $(am_pmdb2diag_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = pmdb2diag_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pmdb2diag_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(pmdb2diag_la_SOURCES) DIST_SOURCES = $(pmdb2diag_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = pmdb2diag.la pmdb2diag_la_SOURCES = pmdb2diag.c pmdb2diag_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -I ../../tools pmdb2diag_la_LDFLAGS = -module -avoid-version pmdb2diag_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/pmdb2diag/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/pmdb2diag/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } pmdb2diag.la: $(pmdb2diag_la_OBJECTS) $(pmdb2diag_la_DEPENDENCIES) $(EXTRA_pmdb2diag_la_DEPENDENCIES) $(AM_V_CCLD)$(pmdb2diag_la_LINK) -rpath $(pkglibdir) $(pmdb2diag_la_OBJECTS) $(pmdb2diag_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< pmdb2diag_la-pmdb2diag.lo: pmdb2diag.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmdb2diag_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pmdb2diag_la-pmdb2diag.lo -MD -MP -MF $(DEPDIR)/pmdb2diag_la-pmdb2diag.Tpo -c -o pmdb2diag_la-pmdb2diag.lo `test -f 'pmdb2diag.c' || echo '$(srcdir)/'`pmdb2diag.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pmdb2diag_la-pmdb2diag.Tpo $(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pmdb2diag.c' object='pmdb2diag_la-pmdb2diag.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pmdb2diag_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pmdb2diag_la-pmdb2diag.lo `test -f 'pmdb2diag.c' || echo '$(srcdir)/'`pmdb2diag.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pmdb2diag_la-pmdb2diag.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/omhiredis0000644000000000000000000000013115114544366016107 xustar0030 mtime=1764935926.550628127 29 atime=1764935930.17368359 30 ctime=1764935926.550628127 rsyslog-8.2512.0/contrib/omhiredis/0000775000175000017500000000000015114544366015631 5ustar00rgerrgerrsyslog-8.2512.0/contrib/omhiredis/PaxHeaders/README0000644000000000000000000000013215035412264017036 xustar0030 mtime=1752569012.330244093 30 atime=1764931140.942317415 30 ctime=1764935926.547628081 rsyslog-8.2512.0/contrib/omhiredis/README0000664000175000017500000000334315035412264016505 0ustar00rgerrgerRedis Outplug Plugin using hiredis library REQUIREMENTS: * hiredis ( https://github.com/redis/hiredis.git ) USAGE: This plugin has three current "modes" that it supports: 1. "template" This is the original mode that the plugin supported. You use an rsyslog template to construct a command that is sent directly to redis. This mode currently has an issue dealing with strings that contain spaces. It's useful for doing things like incrementing counters for statistics. ``` module(load="omhiredis") template( name="simple_count" type="string" string="HINCRBY testcount %programname% 1") *.* action( name="count_redis" type="omhiredis" mode="template" template="simple_count" ) ``` 2. "queue" The queue mode will LPUSH your message to a redis list. Unlike the template mode, it handles full rsyslog messages properly. If a template is not supplied, it will default to the RSYSLOG_ForwardFormat template. The "key" parameter is required. ``` module(load="omhiredis") *.* action( name="push_redis" type="omhiredis" mode="queue" key="testqueue" ) ``` 3. "publish" The publish mode will PUBLISH to a redis channel. Unlike the template mode, it handles full rsyslog messages properly. If a template is not supplied, it will default to the RSYSLOG_ForwardFormat template. The "key" parameter is required and will be used for the publish channel. ``` module(load="omhiredis") *.* action( name="publish_redis" type="omhiredis" mode="publish" key="testpublish" ) ``` NOTES * dequeuebatchsize now sets the pipeline size for hiredis, allowing pipelining commands. rsyslog-8.2512.0/contrib/omhiredis/PaxHeaders/omhiredis.c0000644000000000000000000000013215114522663020310 xustar0030 mtime=1764926899.651331683 30 atime=1764926899.660331879 30 ctime=1764935926.550628127 rsyslog-8.2512.0/contrib/omhiredis/omhiredis.c0000664000175000017500000010203015114522663017750 0ustar00rgerrger/* omhiredis.c * Copyright 2012 Talksum, Inc * Copyright 2015 DigitalOcean, Inc * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program. If not, see * . * * Author: Brian Knox * * * Author: Jérémie Jourdin (TLS support) * */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef HIREDIS_SSL #include #endif #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "srUtils.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "unicode-helper.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("omhiredis") /* internal structures */ DEF_OMOD_STATIC_DATA; #define OMHIREDIS_MODE_TEMPLATE 0 #define OMHIREDIS_MODE_QUEUE 1 #define OMHIREDIS_MODE_PUBLISH 2 #define OMHIREDIS_MODE_SET 3 #define OMHIREDIS_MODE_STREAM 4 /* our instance data. * this will be accessable * via pData */ typedef struct _instanceData { uchar *server; /* redis server address */ uchar *socketPath; /* redis server UDS address (This option only takes effect if the server is not set) */ int port; /* redis port */ uchar *serverpassword; /* redis password */ uchar *tplName; /* template name */ char *modeDescription; /* mode description */ int mode; /* mode constant */ uchar *key; /* key for QUEUE, PUBLISH and STREAM modes */ uchar *streamKeyAck; /* key name for STREAM ACKs (when enabled) */ uchar *streamGroupAck; /* group name for STREAM ACKs (when enabled) */ uchar *streamIndexAck; /* index name for STREAM ACKs (when enabled) */ int expiration; /* expiration value for SET/SETEX mode */ sbool dynaKey; /* Should we treat the key as a template? */ sbool streamDynaKeyAck; /* Should we treat the groupAck as a template? */ sbool streamDynaGroupAck; /* Should we treat the groupAck as a template? */ sbool streamDynaIndexAck; /* Should we treat the IndexAck as a template? */ sbool useRPush; /* Should we use RPUSH instead of LPUSH? */ uchar *streamOutField; /* Field to place message into (for stream insertions only) */ uint streamCapacityLimit; /* zero means stream is not capped (default) setting a non-zero value ultimately activates the approximate MAXLEN option '~' (see Redis XADD docs)*/ sbool streamAck; /* Should the module send an XACK for each inserted message? This feature requires that 3 infos are present in the '$.' object of the log: - $.redis!stream - $.redis!group - $.redis!index Those 3 infos can either be provided through usage of imhiredis or set manually with Rainerscript */ sbool streamDel; /* Should the module send an XDEL for each inserted message? This feature requires that 2 infos are present in the '$.' object of the log: - $.redis!stream - $.redis!index Those 2 infos can either be provided through usage of imhiredis or set manually with Rainerscript */ #ifdef HIREDIS_SSL sbool use_tls; /* Should we use TLS to connect to redis ? */ char *ca_cert_bundle; /* CA bundle file */ char *ca_cert_dir; /* Path of trusted certificates */ char *client_cert; /* Client certificate */ char *client_key; /* Client private key */ char *sni; /* TLS Server Name Indication */ #endif } instanceData; typedef struct wrkrInstanceData { instanceData *pData; /* instanc data */ redisContext *conn; /* redis connection */ int count; /* count of command sent for current batch */ #ifdef HIREDIS_SSL redisSSLContext *ssl_conn; /* redis ssl connection */ redisSSLContextError ssl_error; /* ssl error handler */ #endif } wrkrInstanceData_t; static struct cnfparamdescr actpdescr[] = { {"server", eCmdHdlrGetWord, 0}, {"serverport", eCmdHdlrInt, 0}, {"socketpath", eCmdHdlrGetWord, 0}, {"serverpassword", eCmdHdlrGetWord, 0}, {"template", eCmdHdlrGetWord, 0}, {"mode", eCmdHdlrGetWord, 0}, {"key", eCmdHdlrGetWord, 0}, {"expiration", eCmdHdlrInt, 0}, {"dynakey", eCmdHdlrBinary, 0}, {"userpush", eCmdHdlrBinary, 0}, {"stream.outField", eCmdHdlrGetWord, 0}, {"stream.capacityLimit", eCmdHdlrNonNegInt, 0}, {"stream.ack", eCmdHdlrBinary, 0}, {"stream.del", eCmdHdlrBinary, 0}, {"stream.keyAck", eCmdHdlrGetWord, 0}, {"stream.groupAck", eCmdHdlrGetWord, 0}, {"stream.indexAck", eCmdHdlrGetWord, 0}, {"stream.dynaKeyAck", eCmdHdlrBinary, 0}, {"stream.dynaGroupAck", eCmdHdlrBinary, 0}, {"stream.dynaIndexAck", eCmdHdlrBinary, 0}, #ifdef HIREDIS_SSL {"use_tls", eCmdHdlrBinary, 0}, {"ca_cert_bundle", eCmdHdlrGetWord, 0}, {"ca_cert_dir", eCmdHdlrGetWord, 0}, {"client_cert", eCmdHdlrGetWord, 0}, {"client_key", eCmdHdlrGetWord, 0}, {"sni", eCmdHdlrGetWord, 0}, #endif }; static struct cnfparamblk actpblk = {CNFPARAMBLK_VERSION, sizeof(actpdescr) / sizeof(struct cnfparamdescr), actpdescr}; BEGINcreateInstance CODESTARTcreateInstance; ENDcreateInstance BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; pWrkrData->conn = NULL; /* Connect later */ #ifdef HIREDIS_SSL pWrkrData->ssl_conn = NULL; /* Connect later */ pWrkrData->ssl_error = REDIS_SSL_CTX_NONE; #endif ENDcreateWrkrInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; if (eFeat == sFEATURERepeatedMsgReduction) iRet = RS_RET_OK; ENDisCompatibleWithFeature /* called when closing */ static void closeHiredis(wrkrInstanceData_t *pWrkrData) { if (pWrkrData->conn != NULL) { redisFree(pWrkrData->conn); pWrkrData->conn = NULL; } #ifdef HIREDIS_SSL if (pWrkrData->ssl_conn != NULL) { redisFreeSSLContext(pWrkrData->ssl_conn); pWrkrData->ssl_conn = NULL; } #endif } /* Free our instance data. */ BEGINfreeInstance CODESTARTfreeInstance; if (pData->server != NULL) { free(pData->server); } if (pData->socketPath != NULL) { free(pData->socketPath); } free(pData->key); free(pData->modeDescription); free(pData->serverpassword); free(pData->tplName); free(pData->streamKeyAck); free(pData->streamGroupAck); free(pData->streamIndexAck); free(pData->streamOutField); #ifdef HIREDIS_SSL free(pData->ca_cert_bundle); free(pData->ca_cert_dir); free(pData->client_cert); free(pData->client_key); free(pData->sni); #endif ENDfreeInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; closeHiredis(pWrkrData); ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; /* nothing special here */ ENDdbgPrintInstInfo /* establish our connection to redis */ static rsRetVal initHiredis(wrkrInstanceData_t *pWrkrData, int bSilent) { char *server; sbool udsAddr = 0; redisReply *reply = NULL; DEFiRet; if (pWrkrData->pData->server != NULL) { server = (char *)pWrkrData->pData->server; } else if (pWrkrData->pData->socketPath != NULL) { udsAddr = 1; server = (char *)pWrkrData->pData->socketPath; } else { server = (char *)"127.0.0.1"; } struct timeval timeout = {1, 500000}; /* 1.5 seconds */ if (udsAddr) { DBGPRINTF("omhiredis: trying connect to UDS socket '%s'\n", server); pWrkrData->conn = redisConnectUnixWithTimeout(server, timeout); } else { DBGPRINTF("omhiredis: trying connect to '%s' at port %d\n", server, pWrkrData->pData->port); pWrkrData->conn = redisConnectWithTimeout(server, pWrkrData->pData->port, timeout); } if (pWrkrData->conn == NULL || pWrkrData->conn->err) { if (!bSilent) { const char *err_str = pWrkrData->conn == NULL ? "could not allocate context!" : pWrkrData->conn->errstr; if (udsAddr) { LogError(0, RS_RET_REDIS_ERROR, "omhiredis: can not connect to redis UDS socket '%s' -> %s", server, err_str); } else { LogError(0, RS_RET_REDIS_ERROR, "omhiredis: can not connect to redis server '%s', " "port %d -> %s", server, pWrkrData->pData->port, err_str); } } ABORT_FINALIZE(RS_RET_SUSPENDED); } #ifdef HIREDIS_SSL if (pWrkrData->pData->use_tls) { pWrkrData->ssl_conn = redisCreateSSLContext(pWrkrData->pData->ca_cert_bundle, pWrkrData->pData->ca_cert_dir, pWrkrData->pData->client_cert, pWrkrData->pData->client_key, pWrkrData->pData->sni, &pWrkrData->ssl_error); if (!pWrkrData->ssl_conn || pWrkrData->ssl_error != REDIS_SSL_CTX_NONE) { LogError(0, NO_ERRCODE, "omhiredis: SSL Context error: %s", redisSSLContextGetError(pWrkrData->ssl_error)); if (!bSilent) LogError(0, RS_RET_SUSPENDED, "[TLS] can not initialize redis handle"); ABORT_FINALIZE(RS_RET_SUSPENDED); } if (redisInitiateSSLWithContext(pWrkrData->conn, pWrkrData->ssl_conn) != REDIS_OK) { LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); if (!bSilent) LogError(0, RS_RET_SUSPENDED, "[TLS] can not initialize redis handle"); ABORT_FINALIZE(RS_RET_SUSPENDED); } } #endif if (pWrkrData->pData->serverpassword != NULL) { reply = redisCommand(pWrkrData->conn, "AUTH %s", (char *)pWrkrData->pData->serverpassword); if (reply == NULL) { DBGPRINTF("omhiredis: could not get reply from AUTH command\n"); ABORT_FINALIZE(RS_RET_SUSPENDED); } else if (reply->type == REDIS_REPLY_ERROR) { LogError(0, NO_ERRCODE, "omhiredis: error while authenticating: %s", reply->str); ABORT_FINALIZE(RS_RET_ERR); } } finalize_it: if (iRet != RS_RET_OK && pWrkrData->conn != NULL) { redisFree(pWrkrData->conn); pWrkrData->conn = NULL; } #ifdef HIREDIS_SSL if (iRet != RS_RET_OK && pWrkrData->ssl_conn != NULL) { redisFreeSSLContext(pWrkrData->ssl_conn); pWrkrData->ssl_conn = NULL; } #endif if (reply != NULL) freeReplyObject(reply); RETiRet; } static rsRetVal isMaster(wrkrInstanceData_t *pWrkrData) { DEFiRet; redisReply *reply = NULL; assert(pWrkrData->conn != NULL); reply = redisCommand(pWrkrData->conn, "ROLE"); if (reply == NULL) { DBGPRINTF("omhiredis: could not get reply from ROLE command\n"); ABORT_FINALIZE(RS_RET_SUSPENDED); } else if (reply->type == REDIS_REPLY_ERROR) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_WARNING, "omhiredis: got an error while querying role -> " "%s\n", reply->str); ABORT_FINALIZE(RS_RET_SUSPENDED); } else if (reply->type != REDIS_REPLY_ARRAY || reply->element[0]->type != REDIS_REPLY_STRING) { LogMsg(0, RS_RET_REDIS_ERROR, LOG_ERR, "omhiredis: did not get a proper reply from ROLE command"); ABORT_FINALIZE(RS_RET_SUSPENDED); } else { if (strncmp(reply->element[0]->str, "master", 6)) { LogMsg(0, RS_RET_OK, LOG_WARNING, "omhiredis: current connected node is not a master"); ABORT_FINALIZE(RS_RET_SUSPENDED); } } finalize_it: free(reply); RETiRet; } static rsRetVal writeHiredis(uchar *key, uchar *message, wrkrInstanceData_t *pWrkrData) { DEFiRet; int rc, expire; size_t msgLen; char *formattedMsg = NULL; /* if we do not have a redis connection, call * initHiredis and try to establish one */ if (pWrkrData->conn == NULL) CHKiRet(initHiredis(pWrkrData, 0)); /* try to append the command to the pipeline. * REDIS_ERR reply indicates something bad * happened, in which case abort. otherwise * increase our current pipeline count * by 1 and continue. */ switch (pWrkrData->pData->mode) { case OMHIREDIS_MODE_TEMPLATE: rc = redisAppendCommand(pWrkrData->conn, (char *)message); break; case OMHIREDIS_MODE_QUEUE: rc = redisAppendCommand(pWrkrData->conn, pWrkrData->pData->useRPush ? "RPUSH %s %s" : "LPUSH %s %s", key, (char *)message); break; case OMHIREDIS_MODE_PUBLISH: rc = redisAppendCommand(pWrkrData->conn, "PUBLISH %s %s", key, (char *)message); break; case OMHIREDIS_MODE_SET: expire = pWrkrData->pData->expiration; if (expire > 0) msgLen = redisFormatCommand(&formattedMsg, "SETEX %s %d %s", key, expire, message); else msgLen = redisFormatCommand(&formattedMsg, "SET %s %s", key, message); if (msgLen) rc = redisAppendFormattedCommand(pWrkrData->conn, formattedMsg, msgLen); else { dbgprintf("omhiredis: could not append SET command\n"); rc = REDIS_ERR; } break; case OMHIREDIS_MODE_STREAM: if (pWrkrData->pData->streamCapacityLimit != 0) { rc = redisAppendCommand(pWrkrData->conn, "XADD %s MAXLEN ~ %d * %s %s", key, pWrkrData->pData->streamCapacityLimit, pWrkrData->pData->streamOutField, message); } else { rc = redisAppendCommand(pWrkrData->conn, "XADD %s * %s %s", key, pWrkrData->pData->streamOutField, message); } break; default: dbgprintf("omhiredis: mode %d is invalid something is really wrong\n", pWrkrData->pData->mode); ABORT_FINALIZE(RS_RET_ERR); } if (rc == REDIS_ERR) { LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); dbgprintf("omhiredis: %s\n", pWrkrData->conn->errstr); ABORT_FINALIZE(RS_RET_ERR); } else { pWrkrData->count++; } finalize_it: free(formattedMsg); RETiRet; } static rsRetVal ackHiredisStreamIndex(wrkrInstanceData_t *pWrkrData, uchar *key, uchar *group, uchar *index) { DEFiRet; if (REDIS_ERR == redisAppendCommand(pWrkrData->conn, "XACK %s %s %s", key, group, index)) { LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); DBGPRINTF("omhiredis: %s\n", pWrkrData->conn->errstr); ABORT_FINALIZE(RS_RET_ERR); } else { pWrkrData->count++; } finalize_it: RETiRet; } static rsRetVal delHiredisStreamIndex(wrkrInstanceData_t *pWrkrData, uchar *key, uchar *index) { DEFiRet; if (REDIS_ERR == redisAppendCommand(pWrkrData->conn, "XDEL %s %s", key, index)) { LogError(0, NO_ERRCODE, "omhiredis: %s", pWrkrData->conn->errstr); DBGPRINTF("omhiredis: %s\n", pWrkrData->conn->errstr); ABORT_FINALIZE(RS_RET_ERR); } else { pWrkrData->count++; } finalize_it: RETiRet; } /* called when resuming from suspended state. * try to restablish our connection to redis */ BEGINtryResume CODESTARTtryResume; closeHiredis(pWrkrData); CHKiRet(initHiredis(pWrkrData, 0)); // Must get a master node for all modes, except 'publish' if (pWrkrData->pData->mode != OMHIREDIS_MODE_PUBLISH) { CHKiRet(isMaster(pWrkrData)); } finalize_it: ENDtryResume /* begin a transaction. * if I decide to use MULTI ... EXEC in the * future, this block should send the * MULTI command to redis. */ BEGINbeginTransaction CODESTARTbeginTransaction; dbgprintf("omhiredis: beginTransaction called\n"); pWrkrData->count = 0; ENDbeginTransaction /* call writeHiredis for this log line, * which appends it as a command to the * current pipeline */ BEGINdoAction uchar *message, *key, *keyNameAck, *groupNameAck, *IndexNameAck; int inputIndex = 0; CODESTARTdoAction; // Don't change the order of conditions/assignations here without changing the end of the newActInst function! message = ppString[inputIndex++]; key = pWrkrData->pData->dynaKey ? ppString[inputIndex++] : pWrkrData->pData->key; keyNameAck = pWrkrData->pData->streamDynaKeyAck ? ppString[inputIndex++] : pWrkrData->pData->streamKeyAck; groupNameAck = pWrkrData->pData->streamDynaGroupAck ? ppString[inputIndex++] : pWrkrData->pData->streamGroupAck; IndexNameAck = pWrkrData->pData->streamDynaIndexAck ? ppString[inputIndex++] : pWrkrData->pData->streamIndexAck; CHKiRet(writeHiredis(key, message, pWrkrData)); if (pWrkrData->pData->streamAck) { CHKiRet(ackHiredisStreamIndex(pWrkrData, keyNameAck, groupNameAck, IndexNameAck)); } if (pWrkrData->pData->streamDel) { CHKiRet(delHiredisStreamIndex(pWrkrData, keyNameAck, IndexNameAck)); } iRet = RS_RET_DEFER_COMMIT; finalize_it: ENDdoAction /* called when we have reached the end of a * batch (queue.dequeuebatchsize). this * iterates over the replies, putting them * into the pData->replies buffer. we currently * don't really bother to check for errors * which should be fixed */ BEGINendTransaction CODESTARTendTransaction; dbgprintf("omhiredis: endTransaction called\n"); redisReply *reply; int i; for (i = 0; i < pWrkrData->count; i++) { if (REDIS_OK != redisGetReply(pWrkrData->conn, (void *)&reply) || pWrkrData->conn->err) { dbgprintf("omhiredis: %s\n", pWrkrData->conn->errstr); LogError(0, RS_RET_REDIS_ERROR, "Error while processing replies: %s", pWrkrData->conn->errstr); closeHiredis(pWrkrData); ABORT_FINALIZE(RS_RET_SUSPENDED); } else { if (reply->type == REDIS_REPLY_ERROR) { LogError(0, RS_RET_REDIS_ERROR, "Received error from redis -> %s", reply->str); closeHiredis(pWrkrData); freeReplyObject(reply); ABORT_FINALIZE(RS_RET_SUSPENDED); } freeReplyObject(reply); } } finalize_it: ENDendTransaction /* set defaults. note server is set to NULL * and is set to a default in initHiredis if * it is still null when it's called - I should * probable just set the default here instead */ static void setInstParamDefaults(instanceData *pData) { pData->server = NULL; pData->socketPath = NULL; pData->port = 6379; pData->serverpassword = NULL; pData->tplName = NULL; pData->mode = OMHIREDIS_MODE_TEMPLATE; pData->expiration = 0; pData->modeDescription = NULL; pData->key = NULL; pData->dynaKey = 0; pData->useRPush = 0; pData->streamOutField = NULL; pData->streamKeyAck = NULL; pData->streamDynaKeyAck = 0; pData->streamGroupAck = NULL; pData->streamDynaGroupAck = 0; pData->streamIndexAck = NULL; pData->streamDynaIndexAck = 0; pData->streamCapacityLimit = 0; pData->streamAck = 0; pData->streamDel = 0; #ifdef HIREDIS_SSL pData->use_tls = 0; pData->ca_cert_bundle = NULL; pData->ca_cert_dir = NULL; pData->client_cert = NULL; pData->client_key = NULL; pData->sni = NULL; #endif } /* here is where the work to set up a new instance * is done. this reads the config options from * the rsyslog conf and takes appropriate setup * actions. */ BEGINnewActInst struct cnfparamvals *pvals; int i; int iNumTpls; uchar *strDup = NULL; CODESTARTnewActInst; if ((pvals = nvlstGetParams(lst, &actpblk, NULL)) == NULL) ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); CHKiRet(createInstance(&pData)); setInstParamDefaults(pData); for (i = 0; i < actpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(actpblk.descr[i].name, "server")) { pData->server = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "serverport")) { pData->port = (int)pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "socketpath")) { pData->socketPath = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "serverpassword")) { pData->serverpassword = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "template")) { pData->tplName = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "dynakey")) { pData->dynaKey = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "userpush")) { pData->useRPush = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.outField")) { pData->streamOutField = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "stream.keyAck")) { pData->streamKeyAck = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "stream.dynaKeyAck")) { pData->streamDynaKeyAck = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.groupAck")) { pData->streamGroupAck = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "stream.dynaGroupAck")) { pData->streamDynaGroupAck = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.indexAck")) { pData->streamIndexAck = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "stream.dynaIndexAck")) { pData->streamDynaIndexAck = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.capacityLimit")) { pData->streamCapacityLimit = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.ack")) { pData->streamAck = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "stream.del")) { pData->streamDel = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "mode")) { pData->modeDescription = es_str2cstr(pvals[i].val.d.estr, NULL); if (!strcmp(pData->modeDescription, "template")) { pData->mode = OMHIREDIS_MODE_TEMPLATE; } else if (!strcmp(pData->modeDescription, "queue")) { pData->mode = OMHIREDIS_MODE_QUEUE; } else if (!strcmp(pData->modeDescription, "publish")) { pData->mode = OMHIREDIS_MODE_PUBLISH; } else if (!strcmp(pData->modeDescription, "set")) { pData->mode = OMHIREDIS_MODE_SET; } else if (!strcmp(pData->modeDescription, "stream")) { pData->mode = OMHIREDIS_MODE_STREAM; } else { dbgprintf("omhiredis: unsupported mode %s\n", actpblk.descr[i].name); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } } else if (!strcmp(actpblk.descr[i].name, "key")) { pData->key = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "expiration")) { pData->expiration = pvals[i].val.d.n; dbgprintf("omhiredis: expiration set to %d\n", pData->expiration); #ifdef HIREDIS_SSL } else if (!strcmp(actpblk.descr[i].name, "use_tls")) { pData->use_tls = pvals[i].val.d.n; } else if (!strcmp(actpblk.descr[i].name, "ca_cert_bundle")) { pData->ca_cert_bundle = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "ca_cert_dir")) { pData->ca_cert_dir = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "client_cert")) { pData->client_cert = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "client_key")) { pData->client_key = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); } else if (!strcmp(actpblk.descr[i].name, "sni")) { pData->sni = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); #endif } else { dbgprintf( "omhiredis: program error, non-handled " "param '%s'\n", actpblk.descr[i].name); } } dbgprintf("omhiredis: checking config sanity\n"); if (!pData->modeDescription) { dbgprintf("omhiredis: no mode specified, setting it to 'template'\n"); pData->mode = OMHIREDIS_MODE_TEMPLATE; } if (pData->mode == OMHIREDIS_MODE_STREAM && !pData->streamOutField) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: no stream.outField set, " "using 'msg' as default"); pData->streamOutField = ustrdup("msg"); } if (pData->server != NULL && pData->socketPath != NULL) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: both 'server' and 'socketpath' are set; 'socketpath' will be ignored"); free(pData->socketPath); pData->socketPath = NULL; } if (pData->tplName == NULL) { if (pData->mode == OMHIREDIS_MODE_TEMPLATE) { LogError(0, RS_RET_CONF_PARSE_ERROR, "omhiredis: selected mode requires a template"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } else { CHKmalloc(pData->tplName = ustrdup("RSYSLOG_ForwardFormat")); LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: no template set, " "using RSYSLOG_ForwardFormat as default"); } } if (pData->mode != OMHIREDIS_MODE_TEMPLATE && pData->key == NULL) { LogError(0, RS_RET_CONF_PARSE_ERROR, "omhiredis: mode %s requires a key", pData->modeDescription); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (pData->expiration && pData->mode != OMHIREDIS_MODE_SET) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: expiration set but mode is not " "'set', expiration will be ignored"); } if (pData->mode != OMHIREDIS_MODE_STREAM) { if (pData->streamOutField) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.outField set " "but mode is not 'stream', field will be ignored"); } if (pData->streamAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.ack set " "but mode is not 'stream', XACK will be ignored"); } if (pData->streamDel) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.del set " "but mode is not 'stream', XDEL will be ignored"); } if (pData->streamCapacityLimit) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.capacityLimit set " "but mode is not 'stream', stream trimming will be ignored"); } if (pData->streamKeyAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.keyAck set " "but mode is not 'stream', parameter will be ignored"); } if (pData->streamDynaKeyAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaKeyAck set " "but mode is not 'stream', parameter will be ignored"); } if (pData->streamGroupAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.groupAck set " "but mode is not 'stream', parameter will be ignored"); } if (pData->streamDynaGroupAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaGroupAck set " "but mode is not 'stream', parameter will be ignored"); } if (pData->streamIndexAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.indexAck set " "but mode is not 'stream', parameter will be ignored"); } if (pData->streamDynaIndexAck) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: stream.dynaIndexAck set " "but mode is not 'stream', parameter will be ignored"); } } else { if (pData->streamAck) { if (!pData->streamKeyAck || !pData->streamGroupAck || !pData->streamIndexAck) { LogError(0, RS_RET_CONF_PARSE_ERROR, "omhiredis: 'stream.ack' is set but one of " "'stream.keyAck', 'stream.groupAck' or 'stream.indexAck' is missing"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } } if (pData->streamDel) { if (!pData->streamKeyAck || !pData->streamIndexAck) { LogError(0, RS_RET_CONF_PARSE_ERROR, "omhiredis: 'stream.del' is set but one of " "'stream.keyAck' or 'stream.indexAck' is missing"); ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } } } if (pData->streamDynaKeyAck && pData->streamKeyAck == NULL) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaKeyAck' set " "but 'stream.keyAck' is empty, disabling"); pData->streamDynaKeyAck = 0; } if (pData->streamDynaGroupAck && pData->streamGroupAck == NULL) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaGroupAck' set " "but 'stream.groupAck' is empty, disabling"); pData->streamDynaGroupAck = 0; } if (pData->streamDynaIndexAck && pData->streamIndexAck == NULL) { LogError(0, RS_RET_CONF_PARSE_WARNING, "omhiredis: 'stream.dynaGroupAck' set " "but 'stream.indexAck' is empty, disabling"); pData->streamDynaIndexAck = 0; } iNumTpls = 1; if (pData->dynaKey) { assert(pData->key != NULL); iNumTpls += 1; } if (pData->streamDynaKeyAck) { assert(pData->streamKeyAck != NULL); iNumTpls += 1; } if (pData->streamDynaGroupAck) { assert(pData->streamGroupAck != NULL); iNumTpls += 1; } if (pData->streamDynaIndexAck) { assert(pData->streamIndexAck != NULL); iNumTpls += 1; } CODE_STD_STRING_REQUESTnewActInst(iNumTpls); /* Insert templates in opposite order (keep in sync with doAction), order will be * - tplName * - key * - streamKeyAck * - streamGroupAck * - streamIndexAck */ if (pData->streamDynaIndexAck) { CHKmalloc(strDup = ustrdup(pData->streamIndexAck)); CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); strDup = NULL; /* handed over */ } if (pData->streamDynaGroupAck) { CHKmalloc(strDup = ustrdup(pData->streamGroupAck)); CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); strDup = NULL; /* handed over */ } if (pData->streamDynaKeyAck) { CHKmalloc(strDup = ustrdup(pData->streamKeyAck)); CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); strDup = NULL; /* handed over */ } if (pData->dynaKey) { CHKmalloc(strDup = ustrdup(pData->key)); CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, strDup, OMSR_NO_RQD_TPL_OPTS)); strDup = NULL; /* handed over */ } CHKiRet(OMSRsetEntry(*ppOMSR, --iNumTpls, ustrdup(pData->tplName), OMSR_NO_RQD_TPL_OPTS)); CODE_STD_FINALIZERnewActInst; cnfparamvalsDestruct(pvals, &actpblk); free(strDup); ENDnewActInst NO_LEGACY_CONF_parseSelectorAct BEGINmodExit CODESTARTmodExit; ENDmodExit /* register our plugin entry points * with the rsyslog core engine */ BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; CODEqueryEtryPt_TXIF_OMOD_QUERIES /* supports transaction interface */ ENDqueryEtryPt /* note we do not support rsyslog v5 syntax */ BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* only supports rsyslog 6 configs */ CODEmodInit_QueryRegCFSLineHdlr INITChkCoreFeature(bCoreSupportsBatching, CORE_FEATURE_BATCHING); if (!bCoreSupportsBatching) { LogError(0, NO_ERRCODE, "omhiredis: rsyslog core does not support batching - abort"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("omhiredis: module compiled with rsyslog version %s.\n", VERSION); #ifdef HIREDIS_SSL // initialize OpenSSL redisInitOpenSSL(); #endif ENDmodInit rsyslog-8.2512.0/contrib/omhiredis/PaxHeaders/Makefile.am0000644000000000000000000000013215114522663020215 xustar0030 mtime=1764926899.651331683 30 atime=1764926899.660331879 30 ctime=1764935926.540627974 rsyslog-8.2512.0/contrib/omhiredis/Makefile.am0000664000175000017500000000043715114522663017665 0ustar00rgerrgerpkglib_LTLIBRARIES = omhiredis.la omhiredis_la_SOURCES = omhiredis.c omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) $(HIREDIS_SSL_CFLAGS) omhiredis_la_LDFLAGS = -module -avoid-version omhiredis_la_LIBADD = $(HIREDIS_LIBS) $(HIREDIS_SSL_LIBS) EXTRA_DIST = rsyslog-8.2512.0/contrib/omhiredis/PaxHeaders/COPYING0000644000000000000000000000013115035412264017210 xustar0030 mtime=1752569012.330244093 30 atime=1764931140.934317286 29 ctime=1764935926.54562805 rsyslog-8.2512.0/contrib/omhiredis/COPYING0000664000175000017500000010437015035412264016662 0ustar00rgerrger GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . rsyslog-8.2512.0/contrib/omhiredis/PaxHeaders/Makefile.in0000644000000000000000000000013215114544316020225 xustar0030 mtime=1764935886.229010657 30 atime=1764935896.358165809 30 ctime=1764935926.543628019 rsyslog-8.2512.0/contrib/omhiredis/Makefile.in0000664000175000017500000006357415114544316017710 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/omhiredis ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) am__DEPENDENCIES_1 = omhiredis_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_omhiredis_la_OBJECTS = omhiredis_la-omhiredis.lo omhiredis_la_OBJECTS = $(am_omhiredis_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = omhiredis_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(omhiredis_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/omhiredis_la-omhiredis.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(omhiredis_la_SOURCES) DIST_SOURCES = $(omhiredis_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = omhiredis.la omhiredis_la_SOURCES = omhiredis.c omhiredis_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(HIREDIS_CFLAGS) $(HIREDIS_SSL_CFLAGS) omhiredis_la_LDFLAGS = -module -avoid-version omhiredis_la_LIBADD = $(HIREDIS_LIBS) $(HIREDIS_SSL_LIBS) EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/omhiredis/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/omhiredis/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } omhiredis.la: $(omhiredis_la_OBJECTS) $(omhiredis_la_DEPENDENCIES) $(EXTRA_omhiredis_la_DEPENDENCIES) $(AM_V_CCLD)$(omhiredis_la_LINK) -rpath $(pkglibdir) $(omhiredis_la_OBJECTS) $(omhiredis_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omhiredis_la-omhiredis.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< omhiredis_la-omhiredis.lo: omhiredis.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT omhiredis_la-omhiredis.lo -MD -MP -MF $(DEPDIR)/omhiredis_la-omhiredis.Tpo -c -o omhiredis_la-omhiredis.lo `test -f 'omhiredis.c' || echo '$(srcdir)/'`omhiredis.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/omhiredis_la-omhiredis.Tpo $(DEPDIR)/omhiredis_la-omhiredis.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='omhiredis.c' object='omhiredis_la-omhiredis.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(omhiredis_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o omhiredis_la-omhiredis.lo `test -f 'omhiredis.c' || echo '$(srcdir)/'`omhiredis.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/omhiredis_la-omhiredis.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/omhiredis_la-omhiredis.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/contrib/PaxHeaders/mmtaghostname0000644000000000000000000000013215114544373016767 xustar0030 mtime=1764935931.596705373 30 atime=1764935934.366747775 30 ctime=1764935931.596705373 rsyslog-8.2512.0/contrib/mmtaghostname/0000775000175000017500000000000015114544373016510 5ustar00rgerrgerrsyslog-8.2512.0/contrib/mmtaghostname/PaxHeaders/mmtaghostname.c0000644000000000000000000000013115055605325022052 xustar0029 mtime=1756826325.61380014 30 atime=1764931156.433566539 30 ctime=1764935931.596705373 rsyslog-8.2512.0/contrib/mmtaghostname/mmtaghostname.c0000664000175000017500000001371415055605325021525 0ustar00rgerrger/* mmtaghostname.c * This is a message modification module. * * The name of the module is inspired by the parser module pmnull * Its objectives are closed to this parser but as a message modification * it can be used in a different step of the message processing without * interfering in the parser chain process and can be applied before or * after parsing process. * * Its purposes are : * - to add a tag on message produce by input module which does not provide * a tag like imudp or imtcp. Useful when the tag is used for routing the * message. * - to force message hostname to the rsyslog valeur. The use case is * application in auto-scaling systems (AWS) providing logs through udp/tcp * were the name of the host is based on an ephemeral IPs with a short term * meaning. In this situation rsyslog local host name is generally the * auto-scaling name then logs produced by the application is affected to * the application instead of the ephemeral VM. * * * This file is a contribution of rsyslog. * * Author : Ph. Duveau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include "rsyslog.h" #include "conf.h" #include "syslogd-types.h" #include "template.h" #include "module-template.h" #include "errmsg.h" #include "cfsysline.h" #include "dirty.h" #include "unicode-helper.h" MODULE_TYPE_OUTPUT; MODULE_TYPE_NOKEEP; MODULE_CNFNAME("mmtaghostname") /* internal structures */ DEF_OMOD_STATIC_DATA; DEFobjCurrIf(glbl) /* parser instance parameters */ static struct cnfparamdescr parserpdescr[] = { {"tag", eCmdHdlrString, 0}, {"forcelocalhostname", eCmdHdlrBinary, 0}, }; static struct cnfparamblk parserpblk = {CNFPARAMBLK_VERSION, sizeof(parserpdescr) / sizeof(struct cnfparamdescr), parserpdescr}; typedef struct _instanceData { char *pszTag; size_t lenTag; int bForceLocalHostname; } instanceData; typedef struct wrkrInstanceData { instanceData *pData; } wrkrInstanceData_t; static const uchar *pszHostname = NULL; static size_t lenHostname = 0; BEGINcreateWrkrInstance CODESTARTcreateWrkrInstance; ENDcreateWrkrInstance BEGINfreeWrkrInstance CODESTARTfreeWrkrInstance; ENDfreeWrkrInstance BEGINdbgPrintInstInfo CODESTARTdbgPrintInstInfo; dbgprintf("mmtaghostname:\n"); dbgprintf("\ttag='%s'\n", pData->pszTag); dbgprintf("\tforce local hostname='%d'\n", pData->bForceLocalHostname); ENDdbgPrintInstInfo BEGINcreateInstance CODESTARTcreateInstance; pData->pszTag = NULL; pData->lenTag = 0; pData->bForceLocalHostname = 0; ENDcreateInstance BEGINfreeInstance CODESTARTfreeInstance; free(pData->pszTag); ENDfreeInstance BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature; ENDisCompatibleWithFeature BEGINnewActInst struct cnfparamvals *pvals = NULL; int i; CODESTARTnewActInst; DBGPRINTF("newParserInst (mmtaghostname)\n"); CHKiRet(createInstance(&pData)); if (lst == NULL) FINALIZE; /* just set defaults, no param block! */ if ((pvals = nvlstGetParams(lst, &parserpblk, NULL)) == NULL) { ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS); } if (Debug) { dbgprintf("parser param blk in mmtaghostname:\n"); cnfparamsPrint(&parserpblk, pvals); } for (i = 0; i < parserpblk.nParams; ++i) { if (!pvals[i].bUsed) continue; if (!strcmp(parserpblk.descr[i].name, "tag")) { pData->pszTag = (char *)es_str2cstr(pvals[i].val.d.estr, NULL); pData->lenTag = strlen(pData->pszTag); } else if (!strcmp(parserpblk.descr[i].name, "forcelocalhostname")) { pData->bForceLocalHostname = pvals[i].val.d.n; } else { dbgprintf("program error, non-handled param '%s'\n", parserpblk.descr[i].name); } } CODE_STD_STRING_REQUESTnewActInst(1); CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG)); CODE_STD_FINALIZERnewActInst; if (lst != NULL) cnfparamvalsDestruct(pvals, &parserpblk); ENDnewActInst BEGINdoAction_NoStrings smsg_t **ppMsg = (smsg_t **)pMsgData; smsg_t *pMsg = ppMsg[0]; instanceData *pData = pWrkrData->pData; CODESTARTdoAction; DBGPRINTF("Message will now be managed by mmtaghostname\n"); if (pData->pszTag != NULL) { MsgSetTAG(pMsg, (uchar *)pData->pszTag, pData->lenTag); } if (pData->bForceLocalHostname) { if (pszHostname == NULL) { pszHostname = glbl.GetLocalHostName(); lenHostname = ustrlen(glbl.GetLocalHostName()); } MsgSetHOSTNAME(pMsg, pszHostname, lenHostname); DBGPRINTF("Message hostname forced to local\n"); } ENDdoAction BEGINtryResume CODESTARTtryResume; ENDtryResume BEGINparseSelectorAct CODESTARTparseSelectorAct; CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct BEGINmodExit CODESTARTmodExit; objRelease(glbl, CORE_COMPONENT); ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt; CODEqueryEtryPt_STD_OMOD_QUERIES; CODEqueryEtryPt_STD_OMOD8_QUERIES; CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES; ENDqueryEtryPt BEGINmodInit() CODESTARTmodInit; *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); ENDmodInit rsyslog-8.2512.0/contrib/mmtaghostname/PaxHeaders/Makefile.am0000644000000000000000000000013115035412264021072 xustar0030 mtime=1752569012.329251042 29 atime=1764930928.68681344 30 ctime=1764935931.592705312 rsyslog-8.2512.0/contrib/mmtaghostname/Makefile.am0000664000175000017500000000035515035412264020542 0ustar00rgerrgerpkglib_LTLIBRARIES = mmtaghostname.la mmtaghostname_la_SOURCES = mmtaghostname.c mmtaghostname_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmtaghostname_la_LDFLAGS = -module -avoid-version mmtaghostname_la_LIBADD = EXTRA_DIST = rsyslog-8.2512.0/contrib/mmtaghostname/PaxHeaders/Makefile.in0000644000000000000000000000013115114544316021105 xustar0029 mtime=1764935886.11300888 30 atime=1764935897.001175658 30 ctime=1764935931.594705343 rsyslog-8.2512.0/contrib/mmtaghostname/Makefile.in0000664000175000017500000006370615114544316020566 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = contrib/mmtaghostname ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) mmtaghostname_la_DEPENDENCIES = am_mmtaghostname_la_OBJECTS = mmtaghostname_la-mmtaghostname.lo mmtaghostname_la_OBJECTS = $(am_mmtaghostname_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = mmtaghostname_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(mmtaghostname_la_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(mmtaghostname_la_SOURCES) DIST_SOURCES = $(mmtaghostname_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ pkglib_LTLIBRARIES = mmtaghostname.la mmtaghostname_la_SOURCES = mmtaghostname.c mmtaghostname_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) mmtaghostname_la_LDFLAGS = -module -avoid-version mmtaghostname_la_LIBADD = EXTRA_DIST = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/mmtaghostname/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu contrib/mmtaghostname/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } mmtaghostname.la: $(mmtaghostname_la_OBJECTS) $(mmtaghostname_la_DEPENDENCIES) $(EXTRA_mmtaghostname_la_DEPENDENCIES) $(AM_V_CCLD)$(mmtaghostname_la_LINK) -rpath $(pkglibdir) $(mmtaghostname_la_OBJECTS) $(mmtaghostname_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mmtaghostname_la-mmtaghostname.lo: mmtaghostname.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmtaghostname_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mmtaghostname_la-mmtaghostname.lo -MD -MP -MF $(DEPDIR)/mmtaghostname_la-mmtaghostname.Tpo -c -o mmtaghostname_la-mmtaghostname.lo `test -f 'mmtaghostname.c' || echo '$(srcdir)/'`mmtaghostname.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mmtaghostname_la-mmtaghostname.Tpo $(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mmtaghostname.c' object='mmtaghostname_la-mmtaghostname.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mmtaghostname_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mmtaghostname_la-mmtaghostname.lo `test -f 'mmtaghostname.c' || echo '$(srcdir)/'`mmtaghostname.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(pkglibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-pkglibLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/mmtaghostname_la-mmtaghostname.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-pkglibLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-pkglibLTLIBRARIES install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-pkglibLTLIBRARIES .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/PaxHeaders/config.h.in0000644000000000000000000000013115114544315014556 xustar0030 mtime=1764935885.077993026 29 atime=1764935897.18217843 30 ctime=1764935920.399533958 rsyslog-8.2512.0/config.h.in0000664000175000017500000004740415114544315014234 0ustar00rgerrger/* config.h.in. Generated from configure.ac by autoheader. */ /* Defined if debug mode is enabled (its easier to check). */ #undef DEBUG /* Defined if debugless mode is enabled. */ #undef DEBUGLESS /* Indicator that GnuTLS is present */ #undef ENABLE_GNUTLS /* Indicator that IMDIAG is present */ #undef ENABLE_IMDIAG /* Indicator that we need to build a dummy imkafka module */ #undef ENABLE_IMKAFKA_DUMMY /* Enable epoll mode for the imtcp input module */ #undef ENABLE_IMTCP_EPOLL /* Indicator that libcap-ng is present */ #undef ENABLE_LIBCAPNG /* Indicator that libcap-ng is present */ #undef ENABLE_LIBCAPNG_PRESENT /* Indicator that LIBGCRYPT is present */ #undef ENABLE_LIBGCRYPT /* Indicator that mbedtls is present */ #undef ENABLE_MBEDTLS /* Indicator that we need to build a dummy module */ #undef ENABLE_MMBDLOOKUP_DUMMY /* Indicator that we need to build a dummy omkafka module */ #undef ENABLE_OMKAFKA_DUMMY /* Indicator that openssl is present */ #undef ENABLE_OPENSSL /* Indicator that openssl(EVP_CIPHER_get_block_size) is present */ #undef ENABLE_OPENSSL_CRYPTO_PROVIDER /* Indicator that RELP is present */ #undef ENABLE_RELP /* Regular expressions support enabled. */ #undef FEATURE_REGEXP /* Define to 1 if you have the `alarm' function. */ #undef HAVE_ALARM /* Define to 1 if you have the header file. */ #undef HAVE_APR_BASE64_H /* Define to 1 if you have the header file. */ #undef HAVE_APR_MD5_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_NAMESER_H /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define if compiler provides atomic builtins */ #undef HAVE_ATOMIC_BUILTINS /* Define if compiler provides 64 bit atomic builtins */ #undef HAVE_ATOMIC_BUILTINS64 /* Define to 1 if you have the `basename' function. */ #undef HAVE_BASENAME /* Define to 1 if compiler supports __builtin_expect */ #undef HAVE_BUILTIN_EXPECT /* Define to 1 if your system has a working `chown' function. */ #undef HAVE_CHOWN /* Define to 1 if you have the header file. */ #undef HAVE_CIVETWEB_H /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the `close_range' function. */ #undef HAVE_CLOSE_RANGE /* Define to 1 if you have the header file. */ #undef HAVE_CURL_CURL_H /* Define to 1 if you have the header file. */ #undef HAVE_DBI_DBI_H /* Define to 1 if libdbi supports the new plugin-safe interface */ #undef HAVE_DBI_R /* Define to 1 if libdbi supports transactions */ #undef HAVE_DBI_TXSUPP /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the `epoll_create' function. */ #undef HAVE_EPOLL_CREATE /* Define to 1 if you have the `epoll_create1' function. */ #undef HAVE_EPOLL_CREATE1 /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if you have the `gethostbyname' function. */ #undef HAVE_GETHOSTBYNAME /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* set define */ #undef HAVE_GETIFADDRS /* Define to 1 if you have the `getline' function. */ #undef HAVE_GETLINE /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* set define */ #undef HAVE_GLOB_NOMAGIC /* Define to 1 if you have the `gnutls_certificate_set_retrieve_function' function. */ #undef HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION /* Define to 1 if you have the `gnutls_certificate_type_set_priority' function. */ #undef HAVE_GNUTLS_CERTIFICATE_TYPE_SET_PRIORITY /* Define to 1 if you have the header file. */ #undef HAVE_GROK_H /* Define to 1 if you have the header file. */ #undef HAVE_HADOOP_HDFS_H /* Define to 1 if you have the header file. */ #undef HAVE_HDFS_H /* Define to 1 if you have the `inotify_init' function. */ #undef HAVE_INOTIFY_INIT /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* jemalloc support is integrated. */ #undef HAVE_JEMALLOC /* Define to 1 if you have the header file. */ #undef HAVE_LIBGEN_H /* Define to 1 if liblogging-stdlog is available. */ #undef HAVE_LIBLOGGING_STDLOG /* Use v1 of libmongoc */ #undef HAVE_LIBMONGOC1 /* Define to 1 if you have the `mysqlclient' library (-lmysqlclient). */ #undef HAVE_LIBMYSQLCLIENT /* Define to 1 if you have the header file. */ #undef HAVE_LIBNET_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBRDKAFKA_RDKAFKA_H /* libsystemd present */ #undef HAVE_LIBSYSTEMD /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_CLOSE_RANGE_H /* Define if ln_loadSamplesFromString exists. */ #undef HAVE_LOADSAMPLESFROMSTRING /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R /* Define to 1 if you have the `lseek64' function. */ #undef HAVE_LSEEK64 /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `malloc_trim' function. */ #undef HAVE_MALLOC_TRIM /* Define to 1 if you have the header file. */ #undef HAVE_MAXMINDDB_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have the header file. */ #undef HAVE_MINIX_CONFIG_H /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR /* mysql_library_init available */ #undef HAVE_MYSQL_LIBRARY_INIT /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the header file. */ #undef HAVE_NET_SNMP_NET_SNMP_CONFIG_H /* Define to 1 if the system has the type `off64_t'. */ #undef HAVE_OFF64_T /* Define to 1 if you have the header file. */ #undef HAVE_PATHS_H /* Define to 1 if you have the header file. */ #undef HAVE_PCAP_H /* PGsslInUse function available */ #undef HAVE_PGSSLINUSE /* Define to 1 if you have the `port_create' function. */ #undef HAVE_PORT_CREATE /* Enable FEN support for imfile */ #undef HAVE_PORT_SOURCE_FILE /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL /* Define to 1 if you have the header file. */ #undef HAVE_PROTOCOL_H /* Define to 1 if you have the header file. */ #undef HAVE_PTHREAD_H /* Set-kind available for rwlock attr. */ #undef HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP /* Can set thread-name. */ #undef HAVE_PTHREAD_SETNAME_NP /* Can set thread scheduling parameters */ #undef HAVE_PTHREAD_SETSCHEDPARAM /* Define to 1 if you have the `recvmmsg' function. */ #undef HAVE_RECVMMSG /* Define to 1 if you have the `regcomp' function. */ #undef HAVE_REGCOMP /* Define if relpSrvSetTlsConfigCmd exists. */ #undef HAVE_RELPENGINESETTLSCFGCMD /* Define if relpEngineSetTLSLibByName exists. */ #undef HAVE_RELPENGINESETTLSLIBBYNAME /* Define if relpSrvSetLstnAddr exists. */ #undef HAVE_RELPSRVSETLSTNADDR /* Define if relpSrvSetOversizeMode exists. */ #undef HAVE_RELPSRVSETOVERSIZEMODE /* Define to 1 if you have the header file. */ #undef HAVE_RESOLV_H /* Define to 1 if you have the `sched_get_priority_max' function. */ #undef HAVE_SCHED_GET_PRIORITY_MAX /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H /* set define */ #undef HAVE_SCM_CREDENTIALS /* Define to 1 if you have the `sd_journal_stream_fd_with_namespace' function. */ #undef HAVE_SD_JOURNAL_STREAM_FD_WITH_NAMESPACE /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the header file. */ #undef HAVE_SEMAPHORE_H /* Define if setns exists. */ #undef HAVE_SETNS /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET /* set define */ #undef HAVE_SO_TIMESTAMP /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define if you have `strerror_r'. */ #undef HAVE_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strndup' function. */ #undef HAVE_STRNDUP /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the `strtol' function. */ #undef HAVE_STRTOL /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN /* Define to 1 if you have the `syscall' function. */ #undef HAVE_SYSCALL /* set define */ #undef HAVE_SYSINFO_UPTIME /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_INOTIFY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSCALL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* set define */ #undef HAVE_SYS_gettid /* Define to 1 if you have the `ttyname_r' function. */ #undef HAVE_TTYNAME_R /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMPX_H /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* TLS support enabled in hiredis */ #undef HIREDIS_SSL /* the host environment, can be queried via a system variable */ #undef HOSTENV /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define with a value if your does not define MAXHOSTNAMELEN */ #undef MAXHOSTNAMELEN /* replacement for missing PATH_MAX */ #undef MAXPATHLEN /* Defined if debug mode is disabled. */ #undef NDEBUG /* new systemd present */ #undef NEW_JOURNAL /* Define if ln_loadSamplesFromString does not exist. */ #undef NO_LOADSAMPLESFROMSTRING /* Indicator for a AIX OS */ #undef OS_AIX /* Indicator for APPLE OS */ #undef OS_APPLE /* Indicator for a BSD OS */ #undef OS_BSD /* Indicator for a Linux OS */ #undef OS_LINUX /* Indicator for a Solaris OS */ #undef OS_SOLARIS /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* "Configuration file path (default : /etc/rsyslog.conf)" */ #undef PATH_CONFFILE /* replacement for missing PATH_MAX */ #undef PATH_MAX /* "Pid file path (default : /var/run/rsyslogd.pid)" */ #undef PATH_PIDFILE /* platform id for display purposes */ #undef PLATFORM_ID /* platform id for display purposes */ #undef PLATFORM_ID_LSB /* default port for omrelp */ #undef RELP_DFLT_PT /* Define version of librelp used. */ #undef RELP_VERSION /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* Define to the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Define to 1 if strerror_r returns char *. */ #undef STRERROR_R_CHAR_P /* network support is integrated. */ #undef SYSLOG_INET /* Define to 1 if you can safely include both and . This macro is obsolete. */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Define if you want to use GSSAPI */ #undef USE_GSSAPI /* Using XXHASH for hash64. */ #undef USE_HASH_XXHASH /* Define if you want to enable libuuid support */ #undef USE_LIBUUID /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable general extensions on macOS. */ #ifndef _DARWIN_C_SOURCE # undef _DARWIN_C_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable X/Open compliant socket functions that do not require linking with -lxnet on HP-UX 11.11. */ #ifndef _HPUX_ALT_XOPEN_SOCKET_API # undef _HPUX_ALT_XOPEN_SOCKET_API #endif /* Identify the host operating system as Minix. This macro does not affect the system headers' behavior. A future release of Autoconf may stop defining this macro. */ #ifndef _MINIX # undef _MINIX #endif /* Enable general extensions on NetBSD. Enable NetBSD compatibility extensions on Minix. */ #ifndef _NETBSD_SOURCE # undef _NETBSD_SOURCE #endif /* Enable OpenBSD compatibility extensions on NetBSD. Oddly enough, this does nothing on OpenBSD. */ #ifndef _OPENBSD_SOURCE # undef _OPENBSD_SOURCE #endif /* Define to 1 if needed for POSIX-compatible behavior. */ #ifndef _POSIX_SOURCE # undef _POSIX_SOURCE #endif /* Define to 2 if needed for POSIX-compatible behavior. */ #ifndef _POSIX_1_SOURCE # undef _POSIX_1_SOURCE #endif /* Enable POSIX-compatible threading on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ #ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ # undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ #ifndef __STDC_WANT_IEC_60559_BFP_EXT__ # undef __STDC_WANT_IEC_60559_BFP_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ #ifndef __STDC_WANT_IEC_60559_DFP_EXT__ # undef __STDC_WANT_IEC_60559_DFP_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ # undef __STDC_WANT_IEC_60559_FUNCS_EXT__ #endif /* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # undef __STDC_WANT_IEC_60559_TYPES_EXT__ #endif /* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ #ifndef __STDC_WANT_LIB_EXT2__ # undef __STDC_WANT_LIB_EXT2__ #endif /* Enable extensions specified by ISO/IEC 24747:2009. */ #ifndef __STDC_WANT_MATH_SPEC_FUNCS__ # undef __STDC_WANT_MATH_SPEC_FUNCS__ #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable X/Open extensions. Define to 500 only if necessary to make mbstate_t available. */ #ifndef _XOPEN_SOURCE # undef _XOPEN_SOURCE #endif /* If defined, the select() syscall won't be limited to a particular number of file descriptors. */ #undef USE_UNLIMITED_SELECT /* Defined if valgrind support settings are to be enabled (e.g. prevents dlclose()). */ #undef VALGRIND /* Version number of package */ #undef VERSION /* month part of real rsyslog version */ #undef VERSION_MONTH /* year part of real rsyslog version */ #undef VERSION_YEAR /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Use POSIX pthread semantics */ #undef _POSIX_PTHREAD_SEMANTICS /* Define for Solaris 2.5.1 so the uint8_t typedef from , , or is not used. If the typedef were allowed, the #define below would cause a syntax error. */ #undef _UINT8_T /* Use X/Open CAE Specification */ #undef _XOPEN_SOURCE /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define as a signed integer type capable of holding a process identifier. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to `int' if doesn't define. */ #undef uid_t /* Define to the type of an unsigned integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef uint8_t /* Define as `fork' if `vfork' does not work. */ #undef vfork /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ #undef volatile rsyslog-8.2512.0/PaxHeaders/README.md0000644000000000000000000000013215114522477014020 xustar0030 mtime=1764926783.005631121 30 atime=1764926784.224661044 30 ctime=1764935920.434534494 rsyslog-8.2512.0/README.md0000664000175000017500000002314715114522477013473 0ustar00rgerrger# Rsyslog – What Is It? **Rsyslog** is a **r**ocket-fast **sys**tem for **log** processing pipelines. It offers high performance, advanced security features, and a modular design. Originally a regular syslogd, rsyslog has evolved into a highly versatile logging solution capable of ingesting data from numerous sources, transforming it, and outputting it to a wide variety of destinations. Rsyslog can deliver over one million messages per second to local destinations under minimal processing (based on v7, Dec 2013). Even with complex routing and remote forwarding, performance remains excellent. --- ## Table of Contents - [Getting Rsyslog News](#getting-rsyslog-news) - [🤖 Rsyslog Assistant (Experimental AI Help)](#rsyslog-assistant-experimental-ai-help) - [Getting Help (Other Sources)](#getting-help-other-sources) - [Installation](#installation) - [Contributing](#contributing) - [AI-Based Code Review (Experimental)](#ai-based-code-review-experimental) - [Documentation](#documentation) - [Project Philosophy](#project-philosophy) - [Global Accessibility and Collaboration](#global-accessibility-and-collaboration) - [Sponsors](#sponsors) - [Legal Notice (GDPR)](#legal-notice-gdpr) --- ## Getting Rsyslog News Stay up to date with official rsyslog announcements and community insights: **Official Channels** * [Website](https://rsyslog.com/) – official news and documentation * [RSS Feed](https://rsyslog.com/feed/) * [Telegram](https://t.me/rsyslog_official) * [WhatsApp](https://whatsapp.com/channel/0029VbBJQLhCxoArVHjrL32E) **Maintainer Insights** Updates, technical commentary, and behind-the-scenes notes from [Rainer Gerhards](https://www.linkedin.com/in/rgerhards/), rsyslog founder and maintainer: * [LinkedIn](https://www.linkedin.com/in/rgerhards/) * [X (Twitter)](https://x.com/rgerhards) * [Blog – rainer-gerhards.net](https://rainer.gerhards.net/) --- ## 🤖 Rsyslog Assistant (Experimental AI Help) Need help with rsyslog configuration or troubleshooting? Try the **[rsyslog Assistant](https://rsyslog.ai)** — your AI-powered support tool built by the rsyslog team. > âš ï¸ *Experimental.* May occasionally generate incorrect config examples — always review before applying. ✅ Trained on official docs and changelogs ✅ Covers both Linux rsyslog and Windows Agent ✅ Version-aware and best-practice focused 👉 Try it now: [rsyslog.ai](https://rsyslog.ai) --- ## Getting Help (Other Sources) * **💬 GitHub Discussions:** [Ask questions or start a conversation](https://github.com/rsyslog/rsyslog/discussions) * **📧 Mailing List:** [rsyslog mailing list](https://lists.adiscon.net/mailman/listinfo/rsyslog) * **🛠GitHub Issues:** [Open an issue](https://github.com/rsyslog/rsyslog/issues) --- ## Installation ### Via Distribution Package Managers Rsyslog is available in most Linux distribution repositories and often is pre-installed. ### Project-Provided Packages (Latest Versions) Distributions may lag behind in packaging the latest rsyslog releases. Official builds for newer versions are available here: * [RPM-based systems](https://rsyslog.com/rhelcentos-rpms/) * [Ubuntu](https://rsyslog.com/ubuntu-repository/) * [Debian](https://rsyslog.com/debian-repository/) * [Official Containers](packaging/docker/README.md) For users in regions where GitHub access is limited, see the [Global Accessibility and Collaboration](#global-accessibility-and-collaboration) section for alternative mirrors.
Building from Source (click to expand) See: [Build Instructions](https://rsyslog.com/doc/v8-stable/installation/build_from_repo.html) #### Build Environment Requirements * `pkg-config` * `libestr` * `liblogging` (stdlog component, for testbench) Build support libraries from source if you're working with the latest git master. #### Branch Guidance The `master` branch tracks active development. For production use, prefer the latest tagged release. #### OS-Specific Build Instructions Refer to the respective section in the original README for required packages on CentOS, Ubuntu, Debian, SUSE, etc. #### Development Containers & Testing Ready-to-use build environments are provided in `packaging/docker/dev_env`. These images were previously built in the separate [rsyslog-docker](https://github.com/rsyslog/rsyslog-docker) repository and are now maintained here. See `packaging/docker/README.md` for details. Runtime container definitions are in `packaging/docker/rsyslog`. Run the test suite inside the container with: ```bash make check -j4 ```
--- ## Contributing Rsyslog is a community-driven open-source project. Contributions are welcome and encouraged! * See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines * Starter tasks: [Good First Issues](https://rsyslog.com/tool_good-first-issues) * To develop new output plugins in Python or Perl, see [plugins/external/README.md](plugins/external/README.md) * If you're working with AI coding agents (e.g. GitHub Copilot, OpenAI Codex), see [AGENTS.md](AGENTS.md) * Community: [Code of Conduct](CODE_OF_CONDUCT.md) If GitHub access is difficult in your region, please contact us or use one of the mirrors listed below; we will help route your patch for review. **Commit Assistant (recommended):** Draft compliant commit messages with [rsyslog Commit Assistant](https://rsyslog.com/tool_rsyslog-commit-assistant) and follow rules in [CONTRIBUTING.md](CONTRIBUTING.md). Put the substance into the **commit message** (amend before PR if needed). --- ### AI-Based Code Review (Experimental) We are currently testing AI-based code review for pull requests. At this time, we use **Google Gemini** to automatically analyze code and provide comments on new PRs. * Reviews are **informational only** * Every contribution is still **manually reviewed** by human experts * The goal is to evaluate how AI can support contributor feedback and code quality assurance Please report any issues, false positives, or suggestions about the AI review process. --- ## Documentation Documentation is located in the `doc/` directory of this repository. Contributions to the documentation should be made there. Visit the latest version online: * [rsyslog.com/doc](https://rsyslog.com/doc/) --- ## Project Philosophy Rsyslog development is driven by real-world use cases, open standards, and an active community. While sponsored primarily by Adiscon, technical decisions are made independently via consensus. All contributors are welcome — there is no formal membership beyond participation. --- ## Global Accessibility and Collaboration Rsyslog aims to remain accessible worldwide. Different regions sometimes face network or platform limits, so we provide mirrors to ensure that everyone can obtain the source code and contribute on equal terms. - **GitHub (canonical):** https://github.com/rsyslog/rsyslog - **European mirror (Germany, hosted on DigitalOcean):** https://github-mirror.rsyslog.com/rsyslog/rsyslog - **Community mirror (China, maintained by Gitee):** https://gitee.com/mirrors_rsyslog All pull requests ultimately flow through GitHub, where our CI and review infrastructure run. If you experience access issues but can provide a patch, the rsyslog team will gladly assist in forwarding it to GitHub. Our contribution workflow remains GitHub-based for now because CI and automated testing are tightly integrated there. Always verify releases and tags from the official GitHub repository before production use. > *Open source should have no borders.* > (FR) Le code ouvert ne devrait pas avoir de frontières > (ZH) å¼€æºåº”该没有边界 > (JA) オープンソースã«å›½å¢ƒã¯ãªã„ > (ES) El código abierto no debe tener fronteras > (HI) ओपन सोरà¥à¤¸ की कोई सीमाà¤à¤ नहीं होनी चाहिठ> (AR) المصدر Ø§Ù„Ù…ÙØªÙˆØ­ يجب ألا يكون له حدود --- ## Sponsors The rsyslog project is proudly supported by organizations that help sustain its continuous development, infrastructure, and innovation. (See also [Project Philosophy](#project-philosophy).) ### Prime Sponsor **[Adiscon GmbH](https://www.adiscon.com/)** Adiscon employs core rsyslog developers including Rainer Gerhards and provides ongoing engineering, infrastructure, and CI resources. Through its commercial Windows log management products — such as [WinSyslog](https://www.winsyslog.com/) and [Rsyslog Windows Agent](https://www.winsyslog.com/rsyslog-windows-agent/) — Adiscon helps fund rsyslog’s continued open-source development and ecosystem growth. ### Major Sponsor

DigitalOcean Logo

**[DigitalOcean](https://www.digitalocean.com/)** powers key parts of rsyslog’s CI pipeline, package distribution network, and AI infrastructure as part of their [#DOforOpenSource](https://www.digitalocean.com/open-source) initiative. Their support enables fast, globally available builds and the next generation of AI-assisted rsyslog documentation and tooling. ### Additional Acknowledgments rsyslog also benefits from various open-source infrastructure providers and community initiatives that make modern CI, code hosting, and collaboration possible. --- _If your organization benefits from rsyslog and would like to contribute to its sustainability, please consider [sponsoring or contributing](https://github.com/sponsors/rsyslog)._ --- ## Legal Notice (GDPR) Contributions to rsyslog are stored in git history and publicly distributed. rsyslog-8.2512.0/PaxHeaders/parse.h0000644000000000000000000000013215055605325014022 xustar0030 mtime=1756826325.635800472 30 atime=1764930981.673705866 30 ctime=1764935923.295578295 rsyslog-8.2512.0/parse.h0000664000175000017500000000723615055605325013476 0ustar00rgerrger/* parsing routines for the counted string class. These * routines provide generic parsing aid as well some fairly * complex routines targeted toward specific needs. * * General information - read this: * All routines work on a single CStr object, which must be supplied * during construction. The parse class keeps an internal pointer of * where the next parse operation is to start (you could also say * this is where the last parse operation stopped). * * Each parse operation carried out by this package starts from the * parse pointer, parses the caller-requested element (e.g. an * integer or delemited string) and the update the parse pointer. If * the caller tries to parse beyond the end of the original string, * an error is returned. In general, all functions return a parsRet * error code and all require the parseObj to be the first parameter. * The to-be-parsed string provided to the parse object MUST NOT be * freed or modified by the caller during the lifetime of the parse * object. However, the caller must free it when it is no longer needed. * Optinally, the parse object can be instructed to do that. All objects * returned by the parse routines must be freed by the caller. For * simpler data types (like integers), the caller must provide the * necessary buffer space. * * begun 2005-09-09 rgerhards * * Copyright (C) 2005-2012 Adiscon GmbH * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _PARSE_H_INCLUDED__ #define _PARSE_H_INCLUDED__ 1 #include "stringbuf.h" /** * The parse object */ struct rsParsObject { #ifndef NDEBUG rsObjID OID; /**< object ID */ #endif cstr_t *pCStr; /**< pointer to the string object we are parsing */ size_t iCurrPos; /**< current parsing position (char offset) */ }; typedef struct rsParsObject rsParsObj; /* BEGIN "inline"-like functions */ /* END "inline"-like functions */ int rsParsGetParsePointer(rsParsObj *pThis); /** * Construct a rsPars object. */ rsRetVal rsParsConstruct(rsParsObj **ppThis); rsRetVal rsParsAssignString(rsParsObj *pThis, cstr_t *pCStr); /* parse an integer. The parse pointer is advanced */ rsRetVal parsInt(rsParsObj *pThis, int *pInt); /* Skip whitespace. Often used to trim parsable entries. */ rsRetVal parsSkipWhitespace(rsParsObj *pThis); /* Parse string up to a delimiter. * * Input: * cDelim - the delimiter * The following two are for whitespace stripping, * 0 means "no", 1 "yes" * - bTrimLeading * - bTrimTrailing * * Output: * ppCStr Pointer to the parsed string */ rsRetVal parsDelimCStr( rsParsObj *pThis, cstr_t **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing, int bConvLower); rsRetVal parsSkipAfterChar(rsParsObj *pThis, char c); rsRetVal parsQuotedCStr(rsParsObj *pThis, cstr_t **ppCStr); rsRetVal rsParsConstructFromSz(rsParsObj **ppThis, unsigned char *psz); rsRetVal rsParsDestruct(rsParsObj *pThis); int parsIsAtEndOfParseString(rsParsObj *pThis); int parsGetCurrentPosition(rsParsObj *pThis); char parsPeekAtCharAtParsPtr(rsParsObj *pThis); rsRetVal parsAddrWithBits(rsParsObj *pThis, netAddr_t **pIP, int *pBits); #endif rsyslog-8.2512.0/PaxHeaders/compat0000644000000000000000000000013215114544362013744 xustar0030 mtime=1764935922.981573488 30 atime=1764935930.037681508 30 ctime=1764935922.981573488 rsyslog-8.2512.0/compat/0000775000175000017500000000000015114544362013465 5ustar00rgerrgerrsyslog-8.2512.0/compat/PaxHeaders/asprintf.c0000644000000000000000000000013215071746523016020 xustar0030 mtime=1760021843.765419834 30 atime=1764930978.350650281 30 ctime=1764935922.979573458 rsyslog-8.2512.0/compat/asprintf.c0000664000175000017500000000256015071746523015467 0ustar00rgerrger/* compatibility file for systems without asprintf. * * Copyright 2019 P Duveau * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #ifndef HAVE_ASPRINTF #include #include #include int asprintf(char **strp, const char *fmt, ...) { va_list ap; int len; va_start(ap, fmt); len = vsnprintf(NULL, 0, fmt, ap); va_end(ap); *strp = malloc(len + 1); if (!*strp) { return -1; } va_start(ap, fmt); vsnprintf(*strp, len + 1, fmt, ap); va_end(ap); (*strp)[len] = 0; return len; } #else /* XLC needs at least one method in source file even static to compile */ #ifdef __xlc__ static void dummy(void) {} #endif #endif /* #ifndef HAVE_ASPRINTF */ rsyslog-8.2512.0/compat/PaxHeaders/getifaddrs.c0000644000000000000000000000013115055605325016301 xustar0030 mtime=1756826325.609800079 30 atime=1764930977.608637863 29 ctime=1764935922.97257335 rsyslog-8.2512.0/compat/getifaddrs.c0000664000175000017500000003466615055605325015765 0ustar00rgerrger#include "config.h" #ifndef HAVE_GETIFADDRS /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ #include #if !defined(_AIX) #include #endif #include #include #if defined(_AIX) #include #include #endif #include #include #if defined(_AIX) #include #endif #if !defined(_AIX) #include #endif #include #include #include #include #if defined(_AIX) #include #endif /* Normally this is defined in but was new for Solaris 11 */ #ifndef LIFC_ENABLED #define LIFC_ENABLED 0x20 #endif #if defined(_AIX) /* Use ifaddrs_rsys instead of ifaddrs and ifreq instead of lifreq */ int getallifaddrs(sa_family_t af, struct ifaddrs_rsys **ifap, int64_t flags); int getallifs(int s, sa_family_t af, struct ifreq **ifr, int *numifs, int64_t ifc_flags); #else int getallifaddrs(sa_family_t af, struct ifaddrs **ifap, int64_t flags); int getallifs(int s, sa_family_t af, struct lifreq **lifr, int *numifs, int64_t lifc_flags); #endif /* * Create a linked list of `struct ifaddrs_rsys' structures, one for each * address that is UP. If successful, store the list in *ifap and * return 0. On errors, return -1 and set `errno'. * * The storage returned in *ifap is allocated dynamically and can * only be properly freed by passing it to `freeifaddrs'. */ int #if defined(_AIX) getifaddrs(struct ifaddrs_rsys **ifap) #else getifaddrs(struct ifaddrs **ifap) #endif { int err; char *cp; #if defined(_AIX) struct ifaddrs_rsys *curr; #else struct ifaddrs *curr; #endif if (ifap == NULL) { errno = EINVAL; return (-1); } *ifap = NULL; err = getallifaddrs(AF_UNSPEC, ifap, LIFC_ENABLED); if (err == 0) { for (curr = *ifap; curr != NULL; curr = curr->ifa_next) { if ((cp = strchr(curr->ifa_name, ':')) != NULL) *cp = '\0'; } } return (err); } void #if defined(_AIX) freeifaddrs(struct ifaddrs_rsys *ifa) #else freeifaddrs(struct ifaddrs *ifa) #endif { #if defined(_AIX) struct ifaddrs_rsys *curr; #else struct ifaddrs *curr; #endif while (ifa != NULL) { curr = ifa; ifa = ifa->ifa_next; free(curr->ifa_name); free(curr->ifa_addr); free(curr->ifa_netmask); free(curr->ifa_dstaddr); free(curr); } } /* * Returns all addresses configured on the system. If flags contain * LIFC_ENABLED, only the addresses that are UP are returned. * Address list that is returned by this function must be freed * using freeifaddrs(). */ #if defined(_AIX) int getallifaddrs(sa_family_t af, struct ifaddrs_rsys **ifap, int64_t flags) { struct ifreq *buf = NULL; struct ifreq *ifrp; struct ifreq ifrl; struct in6_ifreq ifrl6; int ret; int s, n, iflen; struct ifaddrs_rsys *curr, *prev; sa_family_t ifr_af; int sock4; int sock6; int err; int ifsize; char *s_ifrp, *e_ifrp; int flag; if ((sock4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (-1); if ((sock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { err = errno; close(sock4); errno = err; return (-1); } retry: /* Get all interfaces from SIOCGIFCONF */ ret = getallifs(sock4, af, &buf, &iflen, (flags & ~LIFC_ENABLED)); if (ret != 0) goto fail; /* * Loop through the interfaces obtained from SIOCGIFCOMF * and retrieve the addresses, netmask and flags. */ prev = NULL; s_ifrp = (char *)buf; e_ifrp = (char *)buf + iflen; *ifap = NULL; while (s_ifrp < e_ifrp) { ifrp = (struct ifreq *)s_ifrp; ifsize = sizeof(struct ifreq); if (ifrp->ifr_addr.sa_len > sizeof(ifrp->ifr_ifru)) { ifsize += ifrp->ifr_addr.sa_len - sizeof(ifrp->ifr_ifru); } /* Prepare for the ioctl call */ (void)strncpy(ifrl.ifr_name, ifrp->ifr_name, sizeof(ifrl.ifr_name)); (void)strncpy(ifrl6.ifr_name, ifrp->ifr_name, sizeof(ifrl.ifr_name)); ifr_af = ifrp->ifr_addr.sa_family; if (ifr_af != AF_INET && ifr_af != AF_INET6) goto next; s = (ifr_af == AF_INET ? sock4 : sock6); if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifrl) < 0) goto fail; if ((flags & LIFC_ENABLED) && !(ifrl.ifr_flags & IFF_UP)) { goto next; } /* * Allocate the current list node. Each node contains data * for one ifaddrs structure. */ curr = calloc(1, sizeof(struct ifaddrs_rsys)); if (curr == NULL) goto fail; if (prev != NULL) { prev->ifa_next = curr; } else { /* First node in the linked list */ *ifap = curr; } prev = curr; /* AIXPORT : ifreq field names used instead of linux lifreq field names */ curr->ifa_flags = ifrl.ifr_flags; if ((curr->ifa_name = strdup(ifrp->ifr_name)) == NULL) goto fail; curr->ifa_addr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_addr == NULL) goto fail; (void)memcpy(curr->ifa_addr, &ifrp->ifr_addr, sizeof(struct sockaddr_storage)); /* Get the netmask */ if (ifr_af == AF_INET) { if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifrl) < 0) { goto fail; } curr->ifa_netmask = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_netmask == NULL) goto fail; (void)memcpy(curr->ifa_netmask, &ifrl.ifr_addr, sizeof(struct sockaddr_storage)); } else { if (ioctl(s, SIOCGIFNETMASK6, (caddr_t)&ifrl6) < 0) { goto fail; } curr->ifa_netmask = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_netmask == NULL) goto fail; (void)memcpy(curr->ifa_netmask, &ifrl6.ifr_Addr, sizeof(struct sockaddr_storage)); } /* Get the destination for a pt-pt interface */ if (curr->ifa_flags & IFF_POINTOPOINT) { if (ifr_af == AF_INET) { if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifrl) < 0) goto fail; curr->ifa_dstaddr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_dstaddr == NULL) goto fail; (void)memcpy(curr->ifa_dstaddr, &ifrl.ifr_addr, sizeof(struct sockaddr_storage)); } else { if (ioctl(s, SIOCGIFDSTADDR6, (caddr_t)&ifrl6) < 0) goto fail; curr->ifa_dstaddr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_dstaddr == NULL) goto fail; (void)memcpy(curr->ifa_dstaddr, &ifrl6.ifr_Addr, sizeof(struct sockaddr_storage)); } /* Do not get broadcast address for IPv6 */ } else if ((curr->ifa_flags & IFF_BROADCAST) && (ifr_af == AF_INET)) { if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifrl) < 0) goto fail; curr->ifa_broadaddr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_broadaddr == NULL) goto fail; (void)memcpy(curr->ifa_broadaddr, &ifrl.ifr_addr, sizeof(struct sockaddr_storage)); } next: s_ifrp += ifsize; } free(buf); close(sock4); close(sock6); return (0); fail: err = errno; free(buf); freeifaddrs(*ifap); *ifap = NULL; if (err == ENXIO) goto retry; close(sock4); close(sock6); errno = err; return (-1); } /* * Do a SIOCGIFCONF and store all the interfaces in `buf'. */ int getallifs(int s, sa_family_t af, struct ifreq **ifr, int *iflen, int64_t ifc_flags) { int ifsize; struct ifconf ifc; size_t bufsize; char *tmp; caddr_t *buf = (caddr_t *)ifr; *buf = NULL; retry: if (ioctl(s, SIOCGSIZIFCONF, &ifsize) < 0) goto fail; /* * When calculating the buffer size needed, add a small number * of interfaces to those we counted. We do this to capture * the interface status of potential interfaces which may have * been plumbed between the SIOCGSIZIFCONF and the SIOCGIFCONF. */ bufsize = ifsize + (4 * sizeof(struct in6_ifreq)); if ((tmp = realloc(*buf, bufsize)) == NULL) goto fail; *buf = tmp; ifc.ifc_buf = *buf; ifc.ifc_len = bufsize; if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) goto fail; *iflen = ifc.ifc_len; if (*iflen >= bufsize) { /* * If every entry was filled, there are probably * more interfaces than (ifn + 4) * Redo the ioctls SIOCGSIZIFCONF and SIOCGIFCONF to * get all the interfaces. */ goto retry; } return (0); fail: free(*buf); *buf = NULL; return (-1); } #else /* _AIX */ int getallifaddrs(sa_family_t af, struct ifaddrs **ifap, int64_t flags) { struct lifreq *buf = NULL; struct lifreq *lifrp; struct lifreq lifrl; int ret; int s, n, numifs; struct ifaddrs *curr, *prev; sa_family_t lifr_af; int sock4; int sock6; int err; if ((sock4 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (-1); if ((sock6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { err = errno; close(sock4); errno = err; return (-1); } retry: /* Get all interfaces from SIOCGLIFCONF */ ret = getallifs(sock4, af, &buf, &numifs, (flags & ~LIFC_ENABLED)); if (ret != 0) goto fail; /* * Loop through the interfaces obtained from SIOCGLIFCOMF * and retrieve the addresses, netmask and flags. */ prev = NULL; lifrp = buf; *ifap = NULL; for (n = 0; n < numifs; n++, lifrp++) { /* Prepare for the ioctl call */ (void)strncpy(lifrl.lifr_name, lifrp->lifr_name, sizeof(lifrl.lifr_name)); lifr_af = lifrp->lifr_addr.ss_family; if (af != AF_UNSPEC && lifr_af != af) continue; s = (lifr_af == AF_INET ? sock4 : sock6); if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifrl) < 0) goto fail; if ((flags & LIFC_ENABLED) && !(lifrl.lifr_flags & IFF_UP)) continue; /* * Allocate the current list node. Each node contains data * for one ifaddrs structure. */ curr = calloc(1, sizeof(struct ifaddrs)); if (curr == NULL) goto fail; if (prev != NULL) { prev->ifa_next = curr; } else { /* First node in the linked list */ *ifap = curr; } prev = curr; curr->ifa_flags = lifrl.lifr_flags; if ((curr->ifa_name = strdup(lifrp->lifr_name)) == NULL) goto fail; curr->ifa_addr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_addr == NULL) goto fail; (void)memcpy(curr->ifa_addr, &lifrp->lifr_addr, sizeof(struct sockaddr_storage)); /* Get the netmask */ if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifrl) < 0) goto fail; curr->ifa_netmask = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_netmask == NULL) goto fail; (void)memcpy(curr->ifa_netmask, &lifrl.lifr_addr, sizeof(struct sockaddr_storage)); /* Get the destination for a pt-pt interface */ if (curr->ifa_flags & IFF_POINTOPOINT) { if (ioctl(s, SIOCGLIFDSTADDR, (caddr_t)&lifrl) < 0) goto fail; curr->ifa_dstaddr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_dstaddr == NULL) goto fail; (void)memcpy(curr->ifa_dstaddr, &lifrl.lifr_addr, sizeof(struct sockaddr_storage)); } else if (curr->ifa_flags & IFF_BROADCAST) { if (ioctl(s, SIOCGLIFBRDADDR, (caddr_t)&lifrl) < 0) goto fail; curr->ifa_broadaddr = malloc(sizeof(struct sockaddr_storage)); if (curr->ifa_broadaddr == NULL) goto fail; (void)memcpy(curr->ifa_broadaddr, &lifrl.lifr_addr, sizeof(struct sockaddr_storage)); } } free(buf); close(sock4); close(sock6); return (0); fail: err = errno; free(buf); freeifaddrs(*ifap); *ifap = NULL; if (err == ENXIO) goto retry; close(sock4); close(sock6); errno = err; return (-1); } /* * Do a SIOCGLIFCONF and store all the interfaces in `buf'. */ int getallifs(int s, sa_family_t af, struct lifreq **lifr, int *numifs, int64_t lifc_flags) { struct lifnum lifn; struct lifconf lifc; size_t bufsize; char *tmp; caddr_t *buf = (caddr_t *)lifr; lifn.lifn_family = af; lifn.lifn_flags = lifc_flags; *buf = NULL; retry: if (ioctl(s, SIOCGLIFNUM, &lifn) < 0) goto fail; /* * When calculating the buffer size needed, add a small number * of interfaces to those we counted. We do this to capture * the interface status of potential interfaces which may have * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF. */ bufsize = (lifn.lifn_count + 4) * sizeof(struct lifreq); if ((tmp = realloc(*buf, bufsize)) == NULL) goto fail; *buf = tmp; lifc.lifc_family = af; lifc.lifc_flags = lifc_flags; lifc.lifc_len = bufsize; lifc.lifc_buf = *buf; if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) goto fail; *numifs = lifc.lifc_len / sizeof(struct lifreq); if (*numifs >= (lifn.lifn_count + 4)) { /* * If every entry was filled, there are probably * more interfaces than (lifn.lifn_count + 4). * Redo the ioctls SIOCGLIFNUM and SIOCGLIFCONF to * get all the interfaces. */ goto retry; } return (0); fail: free(*buf); *buf = NULL; return (-1); } #endif /* _AIX */ #endif /* HAVE_GETIFADDRS */ rsyslog-8.2512.0/compat/PaxHeaders/Makefile.am0000644000000000000000000000013215035412264016052 xustar0030 mtime=1752569012.325278836 30 atime=1764930927.124786927 30 ctime=1764935922.965573243 rsyslog-8.2512.0/compat/Makefile.am0000664000175000017500000000040515035412264015515 0ustar00rgerrgernoinst_LTLIBRARIES = compat.la compat_la_SOURCES = getifaddrs.c ifaddrs.h strndup.c asprintf.c solaris_elf_fix.c compat_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) compat_la_LDFLAGS = -module -avoid-version compat_la_LIBADD = $(IMUDP_LIBS) rsyslog-8.2512.0/compat/PaxHeaders/solaris_elf_fix.c0000644000000000000000000000013215035412264017332 xustar0030 mtime=1752569012.325278836 30 atime=1764930978.715656389 30 ctime=1764935922.981573488 rsyslog-8.2512.0/compat/solaris_elf_fix.c0000664000175000017500000000206315035412264016777 0ustar00rgerrger/* This file ensure that is at least one symbol in our compat * convenience library. Otherwise, at least the Solaris linker * bails out with an error message like this: * * ld: elf error: file ../compat/.libs/compat.a: elf_getarsym * * Copyright 2016 Rainer Gerhards and Adiscon * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #if defined(OS_SOLARIS) || defined(__xlc__) int SOLARIS_and_XLC_wants_a_symbol_inside_the_lib; #endif rsyslog-8.2512.0/compat/PaxHeaders/Makefile.in0000644000000000000000000000013115114544315016063 xustar0029 mtime=1764935885.56400047 30 atime=1764935894.240133366 30 ctime=1764935922.968573289 rsyslog-8.2512.0/compat/Makefile.in0000664000175000017500000006621715114544315015544 0ustar00rgerrger# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = compat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_define.m4 \ $(top_srcdir)/m4/atomic_operations.m4 \ $(top_srcdir)/m4/atomic_operations_64bit.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = compat_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_compat_la_OBJECTS = compat_la-getifaddrs.lo compat_la-strndup.lo \ compat_la-asprintf.lo compat_la-solaris_elf_fix.lo compat_la_OBJECTS = $(am_compat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = compat_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(compat_la_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/compat_la-asprintf.Plo \ ./$(DEPDIR)/compat_la-getifaddrs.Plo \ ./$(DEPDIR)/compat_la-solaris_elf_fix.Plo \ ./$(DEPDIR)/compat_la-strndup.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(compat_la_SOURCES) DIST_SOURCES = $(compat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APU_CFLAGS = @APU_CFLAGS@ APU_LIBS = @APU_LIBS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CIVETWEB_LIBS = @CIVETWEB_LIBS@ CONF_FILE_PATH = @CONF_FILE_PATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CURL_CFLAGS = @CURL_CFLAGS@ CURL_LIBS = @CURL_LIBS@ CYGPATH_W = @CYGPATH_W@ CZMQ_CFLAGS = @CZMQ_CFLAGS@ CZMQ_LIBS = @CZMQ_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FAUP_LIBS = @FAUP_LIBS@ FGREP = @FGREP@ FILECMD = @FILECMD@ GLIB_CFLAGS = @GLIB_CFLAGS@ GLIB_LIBS = @GLIB_LIBS@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GSS_LIBS = @GSS_LIBS@ GT_KSI_LS12_CFLAGS = @GT_KSI_LS12_CFLAGS@ GT_KSI_LS12_LIBS = @GT_KSI_LS12_LIBS@ HASH_XXHASH_LIBS = @HASH_XXHASH_LIBS@ HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@ HIREDIS_CFLAGS = @HIREDIS_CFLAGS@ HIREDIS_LIBS = @HIREDIS_LIBS@ HIREDIS_SSL_CFLAGS = @HIREDIS_SSL_CFLAGS@ HIREDIS_SSL_LIBS = @HIREDIS_SSL_LIBS@ IMUDP_LIBS = @IMUDP_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ IP = @IP@ JAVA = @JAVA@ JAVAC = @JAVAC@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBCAPNG_CFLAGS = @LIBCAPNG_CFLAGS@ LIBCAPNG_LIBS = @LIBCAPNG_LIBS@ LIBCAPNG_PRESENT_CFLAGS = @LIBCAPNG_PRESENT_CFLAGS@ LIBCAPNG_PRESENT_LIBS = @LIBCAPNG_PRESENT_LIBS@ LIBDBI_CFLAGS = @LIBDBI_CFLAGS@ LIBDBI_LIBS = @LIBDBI_LIBS@ LIBESTR_CFLAGS = @LIBESTR_CFLAGS@ LIBESTR_LIBS = @LIBESTR_LIBS@ LIBEVENT_CFLAGS = @LIBEVENT_CFLAGS@ LIBEVENT_LIBS = @LIBEVENT_LIBS@ LIBFASTJSON_CFLAGS = @LIBFASTJSON_CFLAGS@ LIBFASTJSON_LIBS = @LIBFASTJSON_LIBS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBLOGGING_CFLAGS = @LIBLOGGING_CFLAGS@ LIBLOGGING_LIBS = @LIBLOGGING_LIBS@ LIBLOGGING_STDLOG_CFLAGS = @LIBLOGGING_STDLOG_CFLAGS@ LIBLOGGING_STDLOG_LIBS = @LIBLOGGING_STDLOG_LIBS@ LIBLOGNORM_CFLAGS = @LIBLOGNORM_CFLAGS@ LIBLOGNORM_LIBS = @LIBLOGNORM_LIBS@ LIBLZ4_CFLAGS = @LIBLZ4_CFLAGS@ LIBLZ4_LIBS = @LIBLZ4_LIBS@ LIBM = @LIBM@ LIBMONGOC_CFLAGS = @LIBMONGOC_CFLAGS@ LIBMONGOC_LIBS = @LIBMONGOC_LIBS@ LIBOBJS = @LIBOBJS@ LIBRDKAFKA_CFLAGS = @LIBRDKAFKA_CFLAGS@ LIBRDKAFKA_LIBS = @LIBRDKAFKA_LIBS@ LIBS = @LIBS@ LIBSYSTEMD_CFLAGS = @LIBSYSTEMD_CFLAGS@ LIBSYSTEMD_JOURNAL_CFLAGS = @LIBSYSTEMD_JOURNAL_CFLAGS@ LIBSYSTEMD_JOURNAL_LIBS = @LIBSYSTEMD_JOURNAL_LIBS@ LIBSYSTEMD_LIBS = @LIBSYSTEMD_LIBS@ LIBTOOL = @LIBTOOL@ LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ LIBUUID_LIBS = @LIBUUID_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@ MBEDTLS_LIBS = @MBEDTLS_LIBS@ MKDIR_P = @MKDIR_P@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LIBS = @MYSQL_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PGSQL_CFLAGS = @PGSQL_CFLAGS@ PGSQL_LIBS = @PGSQL_LIBS@ PG_CONFIG = @PG_CONFIG@ PID_FILE_PATH = @PID_FILE_PATH@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PROTON_CFLAGS = @PROTON_CFLAGS@ PROTON_LIBS = @PROTON_LIBS@ PROTON_PROACTOR_CFLAGS = @PROTON_PROACTOR_CFLAGS@ PROTON_PROACTOR_LIBS = @PROTON_PROACTOR_LIBS@ PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ PTHREADS_LIBS = @PTHREADS_LIBS@ PYTHON = @PYTHON@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RABBITMQ_CFLAGS = @RABBITMQ_CFLAGS@ RABBITMQ_LIBS = @RABBITMQ_LIBS@ RANLIB = @RANLIB@ READLINK = @READLINK@ REDIS = @REDIS@ RELP_CFLAGS = @RELP_CFLAGS@ RELP_LIBS = @RELP_LIBS@ RSRT_CFLAGS = @RSRT_CFLAGS@ RSRT_CFLAGS1 = @RSRT_CFLAGS1@ RSRT_LIBS = @RSRT_LIBS@ RSRT_LIBS1 = @RSRT_LIBS1@ RST2MAN = @RST2MAN@ RT_LIBS = @RT_LIBS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNMP_CFLAGS = @SNMP_CFLAGS@ SNMP_LIBS = @SNMP_LIBS@ SOL_LIBS = @SOL_LIBS@ STRIP = @STRIP@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_FLAG = @TCL_LIB_FLAG@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ TCL_VERSION = @TCL_VERSION@ UDPSPOOF_CFLAGS = @UDPSPOOF_CFLAGS@ UDPSPOOF_LIBS = @UDPSPOOF_LIBS@ VALGRIND = @VALGRIND@ VERSION = @VERSION@ WARN_CFLAGS = @WARN_CFLAGS@ WARN_LDFLAGS = @WARN_LDFLAGS@ WARN_SCANNERFLAGS = @WARN_SCANNERFLAGS@ WGET = @WGET@ YACC = @YACC@ YACC_FOUND = @YACC_FOUND@ YFLAGS = @YFLAGS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ZSTD_CFLAGS = @ZSTD_CFLAGS@ ZSTD_LIBS = @ZSTD_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ moddirs = @moddirs@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = compat.la compat_la_SOURCES = getifaddrs.c ifaddrs.h strndup.c asprintf.c solaris_elf_fix.c compat_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) compat_la_LDFLAGS = -module -avoid-version compat_la_LIBADD = $(IMUDP_LIBS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu compat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu compat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } compat.la: $(compat_la_OBJECTS) $(compat_la_DEPENDENCIES) $(EXTRA_compat_la_DEPENDENCIES) $(AM_V_CCLD)$(compat_la_LINK) $(compat_la_OBJECTS) $(compat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat_la-asprintf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat_la-getifaddrs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat_la-solaris_elf_fix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat_la-strndup.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< compat_la-getifaddrs.lo: getifaddrs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat_la-getifaddrs.lo -MD -MP -MF $(DEPDIR)/compat_la-getifaddrs.Tpo -c -o compat_la-getifaddrs.lo `test -f 'getifaddrs.c' || echo '$(srcdir)/'`getifaddrs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/compat_la-getifaddrs.Tpo $(DEPDIR)/compat_la-getifaddrs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getifaddrs.c' object='compat_la-getifaddrs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat_la-getifaddrs.lo `test -f 'getifaddrs.c' || echo '$(srcdir)/'`getifaddrs.c compat_la-strndup.lo: strndup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat_la-strndup.lo -MD -MP -MF $(DEPDIR)/compat_la-strndup.Tpo -c -o compat_la-strndup.lo `test -f 'strndup.c' || echo '$(srcdir)/'`strndup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/compat_la-strndup.Tpo $(DEPDIR)/compat_la-strndup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strndup.c' object='compat_la-strndup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat_la-strndup.lo `test -f 'strndup.c' || echo '$(srcdir)/'`strndup.c compat_la-asprintf.lo: asprintf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat_la-asprintf.lo -MD -MP -MF $(DEPDIR)/compat_la-asprintf.Tpo -c -o compat_la-asprintf.lo `test -f 'asprintf.c' || echo '$(srcdir)/'`asprintf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/compat_la-asprintf.Tpo $(DEPDIR)/compat_la-asprintf.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='asprintf.c' object='compat_la-asprintf.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat_la-asprintf.lo `test -f 'asprintf.c' || echo '$(srcdir)/'`asprintf.c compat_la-solaris_elf_fix.lo: solaris_elf_fix.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT compat_la-solaris_elf_fix.lo -MD -MP -MF $(DEPDIR)/compat_la-solaris_elf_fix.Tpo -c -o compat_la-solaris_elf_fix.lo `test -f 'solaris_elf_fix.c' || echo '$(srcdir)/'`solaris_elf_fix.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/compat_la-solaris_elf_fix.Tpo $(DEPDIR)/compat_la-solaris_elf_fix.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='solaris_elf_fix.c' object='compat_la-solaris_elf_fix.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(compat_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o compat_la-solaris_elf_fix.lo `test -f 'solaris_elf_fix.c' || echo '$(srcdir)/'`solaris_elf_fix.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/compat_la-asprintf.Plo -rm -f ./$(DEPDIR)/compat_la-getifaddrs.Plo -rm -f ./$(DEPDIR)/compat_la-solaris_elf_fix.Plo -rm -f ./$(DEPDIR)/compat_la-strndup.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/compat_la-asprintf.Plo -rm -f ./$(DEPDIR)/compat_la-getifaddrs.Plo -rm -f ./$(DEPDIR)/compat_la-solaris_elf_fix.Plo -rm -f ./$(DEPDIR)/compat_la-strndup.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: rsyslog-8.2512.0/compat/PaxHeaders/ifaddrs.h0000644000000000000000000000013215055605325015607 xustar0030 mtime=1756826325.609800079 30 atime=1764931129.795137662 30 ctime=1764935922.974573381 rsyslog-8.2512.0/compat/ifaddrs.h0000664000175000017500000000673415055605325015265 0ustar00rgerrger#include "config.h" #ifndef HAVE_GETIFADDRS /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _IFADDRS_H #define _IFADDRS_H #ifdef __cplusplus extern "C" { #endif #include /* * The `getifaddrs' function generates a linked list of these structures. * Each element of the list describes one network interface. */ #if defined(_AIX) struct ifaddrs_rsys { struct ifaddrs_rsys *ifa_next; /* Pointer to the next structure. */ #else struct ifaddrs { struct ifaddrs *ifa_next; /* Pointer to the next structure. */ #endif char *ifa_name; /* Name of this network interface. */ uint64_t ifa_flags; /* Flags as from SIOCGLIFFLAGS ioctl. */ struct sockaddr *ifa_addr; /* Network address of this interface. */ struct sockaddr *ifa_netmask; /* Netmask of this interface. */ union { /* * At most one of the following two is valid. If the * IFF_BROADCAST bit is set in `ifa_flags', then * `ifa_broadaddr' is valid. If the IFF_POINTOPOINT bit is * set, then `ifa_dstaddr' is valid. It is never the case that * both these bits are set at once. */ struct sockaddr *ifu_broadaddr; struct sockaddr *ifu_dstaddr; } ifa_ifu; void *ifa_data; /* Address-specific data (may be unused). */ /* * This may have been defined in . */ #ifndef ifa_broadaddr #define ifa_broadaddr ifa_ifu.ifu_broadaddr /* broadcast address */ #endif #ifndef ifa_dstaddr #define ifa_dstaddr ifa_ifu.ifu_dstaddr /* other end of p-to-p link */ #endif }; /* * Create a linked list of `struct ifaddrs' structures, one for each * network interface on the host machine. If successful, store the * list in *ifap and return 0. On errors, return -1 and set `errno'. * * The storage returned in *ifap is allocated dynamically and can * only be properly freed by passing it to `freeifaddrs'. */ #if defined(_AIX) extern int getifaddrs(struct ifaddrs_rsys **); #else extern int getifaddrs(struct ifaddrs **); #endif /* Reclaim the storage allocated by a previous `getifaddrs' call. */ #if defined(_AIX) extern void freeifaddrs(struct ifaddrs_rsys *); #else extern void freeifaddrs(struct ifaddrs *); #endif #ifdef __cplusplus } #endif #endif /* _IFADDRS_H */ #endif /* HAVE_GETIFADDRS */ rsyslog-8.2512.0/compat/PaxHeaders/strndup.c0000644000000000000000000000013215071746523015671 xustar0030 mtime=1760021843.765419834 30 atime=1764930977.980644089 30 ctime=1764935922.977573427 rsyslog-8.2512.0/compat/strndup.c0000664000175000017500000000247415071746523015344 0ustar00rgerrger/* compatibility file for systems without strndup. * * Copyright 2015 Rainer Gerhards and Adiscon * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #ifndef HAVE_STRNDUP #include #include extern char *strndup(const char *s, size_t n); char *strndup(const char *s, size_t n) { const size_t len = strlen(s); char *new_s; if (len <= n) return strdup(s); new_s = malloc(n + 1); if (new_s == NULL) return NULL; memcpy(new_s, s, n); new_s[n] = '\0'; return new_s; } #else /* XLC needs at least one method in source file even static to compile */ #ifdef __xlc__ static void dummy(void) {} #endif #endif /* #ifndef HAVE_STRNDUP */ rsyslog-8.2512.0/PaxHeaders/aclocal.m40000644000000000000000000000013215114544314014373 xustar0030 mtime=1764935884.144978734 30 atime=1764935884.248980327 30 ctime=1764935920.395533896 rsyslog-8.2512.0/aclocal.m40000664000175000017500000064660315114544314014056 0ustar00rgerrger# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, [m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # ============================================================================ # https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html # ============================================================================ # # SYNOPSIS # # AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # For every FLAG1, FLAG2 it is checked whether the compiler works with the # flag. If it does, the flag is added FLAGS-VARIABLE # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. During the check the flag is always added to the # current language's flags. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: This macro depends on the AX_APPEND_FLAG and # AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with # AX_APPEND_LINK_FLAGS. # # LICENSE # # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 7 AC_DEFUN([AX_APPEND_COMPILE_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) for flag in $1; do AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4]) done ])dnl AX_APPEND_COMPILE_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_append_flag.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) # # DESCRIPTION # # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space # added in between. # # If FLAGS-VARIABLE is not specified, the current language's flags (e.g. # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly # FLAG. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 8 AC_DEFUN([AX_APPEND_FLAG], [dnl AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) AS_VAR_SET_IF(FLAGS,[ AS_CASE([" AS_VAR_GET(FLAGS) "], [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], [ AS_VAR_APPEND(FLAGS,[" $1"]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) ], [ AS_VAR_SET(FLAGS,[$1]) AC_RUN_LOG([: FLAGS="$FLAGS"]) ]) AS_VAR_POPDEF([FLAGS])dnl ])dnl AX_APPEND_FLAG # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html # =========================================================================== # # SYNOPSIS # # AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # For every FLAG1, FLAG2 it is checked whether the linker works with the # flag. If it does, the flag is added FLAGS-VARIABLE # # If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is # used. During the check the flag is always added to the linker's flags. # # If EXTRA-FLAGS is defined, it is added to the linker's default flags # when the check is done. The check is thus made with the flags: "LDFLAGS # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. # Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. # # LICENSE # # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 7 AC_DEFUN([AX_APPEND_LINK_FLAGS], [AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) for flag in $1; do AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4]) done ])dnl AX_APPEND_LINK_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the linker or gives an error. # (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the linker's default flags # when the check is done. The check is thus made with the flags: "LDFLAGS # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_LINK_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6 AC_DEFUN([AX_CHECK_LINK_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS $4 $1" AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) LDFLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_LINK_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html # =========================================================================== # # SYNOPSIS # # AX_COMPILER_FLAGS([CFLAGS-VARIABLE], [LDFLAGS-VARIABLE], [IS-RELEASE], [EXTRA-BASE-CFLAGS], [EXTRA-YES-CFLAGS], [UNUSED], [UNUSED], [UNUSED], [EXTRA-BASE-LDFLAGS], [EXTRA-YES-LDFLAGS], [UNUSED], [UNUSED], [UNUSED]) # # DESCRIPTION # # Check for the presence of an --enable-compile-warnings option to # configure, defaulting to "error" in normal operation, or "yes" if # IS-RELEASE is equal to "yes". Return the value in the variable # $ax_enable_compile_warnings. # # Depending on the value of --enable-compile-warnings, different compiler # warnings are checked to see if they work with the current compiler and, # if so, are appended to CFLAGS-VARIABLE and LDFLAGS-VARIABLE. This # allows a consistent set of baseline compiler warnings to be used across # a code base, irrespective of any warnings enabled locally by individual # developers. By standardising the warnings used by all developers of a # project, the project can commit to a zero-warnings policy, using -Werror # to prevent compilation if new warnings are introduced. This makes # catching bugs which are flagged by warnings a lot easier. # # By providing a consistent --enable-compile-warnings argument across all # projects using this macro, continuous integration systems can easily be # configured the same for all projects. Automated systems or build # systems aimed at beginners may want to pass the --disable-Werror # argument to unconditionally prevent warnings being fatal. # # --enable-compile-warnings can take the values: # # * no: Base compiler warnings only; not even -Wall. # * yes: The above, plus a broad range of useful warnings. # * error: The above, plus -Werror so that all warnings are fatal. # Use --disable-Werror to override this and disable fatal # warnings. # # The set of base and enabled flags can be augmented using the # EXTRA-*-CFLAGS and EXTRA-*-LDFLAGS variables, which are tested and # appended to the output variable if --enable-compile-warnings is not # "no". Flags should not be disabled using these arguments, as the entire # point of AX_COMPILER_FLAGS is to enforce a consistent set of useful # compiler warnings on code, using warnings which have been chosen for low # false positive rates. If a compiler emits false positives for a # warning, a #pragma should be used in the code to disable the warning # locally. See: # # https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas # # The EXTRA-* variables should only be used to supply extra warning flags, # and not general purpose compiler flags, as they are controlled by # configure options such as --disable-Werror. # # IS-RELEASE can be used to disable -Werror when making a release, which # is useful for those hairy moments when you just want to get the release # done as quickly as possible. Set it to "yes" to disable -Werror. By # default, it uses the value of $ax_is_release, so if you are using the # AX_IS_RELEASE macro, there is no need to pass this parameter. For # example: # # AX_IS_RELEASE([git-directory]) # AX_COMPILER_FLAGS() # # CFLAGS-VARIABLE defaults to WARN_CFLAGS, and LDFLAGS-VARIABLE defaults # to WARN_LDFLAGS. Both variables are AC_SUBST-ed by this macro, but must # be manually added to the CFLAGS and LDFLAGS variables for each target in # the code base. # # If C++ language support is enabled with AC_PROG_CXX, which must occur # before this macro in configure.ac, warning flags for the C++ compiler # are AC_SUBST-ed as WARN_CXXFLAGS, and must be manually added to the # CXXFLAGS variables for each target in the code base. EXTRA-*-CFLAGS can # be used to augment the base and enabled flags. # # Warning flags for g-ir-scanner (from GObject Introspection) are # AC_SUBST-ed as WARN_SCANNERFLAGS. This variable must be manually added # to the SCANNERFLAGS variable for each GIR target in the code base. If # extra g-ir-scanner flags need to be enabled, the AX_COMPILER_FLAGS_GIR # macro must be invoked manually. # # AX_COMPILER_FLAGS may add support for other tools in future, in addition # to the compiler and linker. No extra EXTRA-* variables will be added # for those tools, and all extra support will still use the single # --enable-compile-warnings configure option. For finer grained control # over the flags for individual tools, use AX_COMPILER_FLAGS_CFLAGS, # AX_COMPILER_FLAGS_LDFLAGS and AX_COMPILER_FLAGS_* for new tools. # # The UNUSED variables date from a previous version of this macro, and are # automatically appended to the preceding non-UNUSED variable. They should # be left empty in new uses of the macro. # # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall # Copyright (c) 2015 David King # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 14 # _AX_COMPILER_FLAGS_LANG([LANGNAME]) m4_defun([_AX_COMPILER_FLAGS_LANG], [m4_ifdef([_AX_COMPILER_FLAGS_LANG_]$1[_enabled], [], [m4_define([_AX_COMPILER_FLAGS_LANG_]$1[_enabled], [])dnl AX_REQUIRE_DEFINED([AX_COMPILER_FLAGS_]$1[FLAGS])])dnl ]) AC_DEFUN([AX_COMPILER_FLAGS],[ # C support is enabled by default. _AX_COMPILER_FLAGS_LANG([C]) # Only enable C++ support if AC_PROG_CXX is called. The redefinition of # AC_PROG_CXX is so that a fatal error is emitted if this macro is called # before AC_PROG_CXX, which would otherwise cause no C++ warnings to be # checked. AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AX_COMPILER_FLAGS_LANG([CXX])], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AX_COMPILER_FLAGS_LANG([CXX])])]) AX_REQUIRE_DEFINED([AX_COMPILER_FLAGS_LDFLAGS]) # Default value for IS-RELEASE is $ax_is_release ax_compiler_flags_is_release=m4_tolower(m4_normalize(ifelse([$3],, [$ax_is_release], [$3]))) AC_ARG_ENABLE([compile-warnings], AS_HELP_STRING([--enable-compile-warnings=@<:@no/yes/error@:>@], [Enable compiler warnings and errors]),, [AS_IF([test "$ax_compiler_flags_is_release" = "yes"], [enable_compile_warnings="yes"], [enable_compile_warnings="error"])]) AC_ARG_ENABLE([Werror], AS_HELP_STRING([--disable-Werror], [Unconditionally make all compiler warnings non-fatal]),, [enable_Werror=maybe]) # Return the user's chosen warning level AS_IF([test "$enable_Werror" = "no" -a \ "$enable_compile_warnings" = "error"],[ enable_compile_warnings="yes" ]) ax_enable_compile_warnings=$enable_compile_warnings AX_COMPILER_FLAGS_CFLAGS([$1],[$ax_compiler_flags_is_release], [$4],[$5 $6 $7 $8]) m4_ifdef([_AX_COMPILER_FLAGS_LANG_CXX_enabled], [AX_COMPILER_FLAGS_CXXFLAGS([WARN_CXXFLAGS], [$ax_compiler_flags_is_release], [$4],[$5 $6 $7 $8])]) AX_COMPILER_FLAGS_LDFLAGS([$2],[$ax_compiler_flags_is_release], [$9],[$10 $11 $12 $13]) AX_COMPILER_FLAGS_GIR([WARN_SCANNERFLAGS],[$ax_compiler_flags_is_release]) ])dnl AX_COMPILER_FLAGS # ============================================================================= # https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cflags.html # ============================================================================= # # SYNOPSIS # # AX_COMPILER_FLAGS_CFLAGS([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) # # DESCRIPTION # # Add warning flags for the C compiler to VARIABLE, which defaults to # WARN_CFLAGS. VARIABLE is AC_SUBST-ed by this macro, but must be # manually added to the CFLAGS variable for each target in the code base. # # This macro depends on the environment set up by AX_COMPILER_FLAGS. # Specifically, it uses the value of $ax_enable_compile_warnings to decide # which flags to enable. # # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall # Copyright (c) 2017, 2018 Reini Urban # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 17 AC_DEFUN([AX_COMPILER_FLAGS_CFLAGS],[ AC_REQUIRE([AC_PROG_SED]) AX_REQUIRE_DEFINED([AX_APPEND_COMPILE_FLAGS]) AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) # Variable names m4_define([ax_warn_cflags_variable], [m4_normalize(ifelse([$1],,[WARN_CFLAGS],[$1]))]) AC_LANG_PUSH([C]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ [#ifndef __cplusplus #error "no C++" #endif]])], [ax_compiler_cxx=yes;], [ax_compiler_cxx=no;]) # Always pass -Werror=unknown-warning-option to get Clang to fail on bad # flags, otherwise they are always appended to the warn_cflags variable, and # Clang warns on them for every compilation unit. # If this is passed to GCC, it will explode, so the flag must be enabled # conditionally. AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ ax_compiler_flags_test="-Werror=unknown-warning-option" ],[ ax_compiler_flags_test="" ]) # Check that -Wno-suggest-attribute=format is supported AX_CHECK_COMPILE_FLAG([-Wno-suggest-attribute=format],[ ax_compiler_no_suggest_attribute_flags="-Wno-suggest-attribute=format" ],[ ax_compiler_no_suggest_attribute_flags="" ]) # Base flags AX_APPEND_COMPILE_FLAGS([ dnl -fno-strict-aliasing dnl $3 dnl ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) AS_IF([test "$ax_enable_compile_warnings" != "no"],[ if test "$ax_compiler_cxx" = "no" ; then # C-only flags. Warn in C++ AX_APPEND_COMPILE_FLAGS([ dnl -Wnested-externs dnl -Wmissing-prototypes dnl -Wstrict-prototypes dnl -Wdeclaration-after-statement dnl -Wimplicit-function-declaration dnl -Wold-style-definition dnl -Wjump-misses-init dnl ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) fi # "yes" flags AX_APPEND_COMPILE_FLAGS([ dnl -Wall dnl -Wextra dnl -Wundef dnl -Wwrite-strings dnl -Wpointer-arith dnl -Wmissing-declarations dnl -Wredundant-decls dnl -Wno-unused-parameter dnl -Wno-missing-field-initializers dnl -Wformat=2 dnl -Wcast-align dnl -Wformat-nonliteral dnl -Wformat-security dnl -Wsign-compare dnl -Wstrict-aliasing dnl -Wshadow dnl -Winline dnl -Wpacked dnl -Wmissing-format-attribute dnl -Wmissing-noreturn dnl -Winit-self dnl -Wredundant-decls dnl -Wmissing-include-dirs dnl -Wunused-but-set-variable dnl -Warray-bounds dnl -Wreturn-type dnl -Wswitch-enum dnl -Wswitch-default dnl -Wduplicated-cond dnl -Wduplicated-branches dnl -Wlogical-op dnl -Wrestrict dnl -Wnull-dereference dnl -Wdouble-promotion dnl $4 dnl $5 dnl $6 dnl $7 dnl ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) ]) AS_IF([test "$ax_enable_compile_warnings" = "error"],[ # "error" flags; -Werror has to be appended unconditionally because # it's not possible to test for # # suggest-attribute=format is disabled because it gives too many false # positives AX_APPEND_FLAG([-Werror],ax_warn_cflags_variable) AX_APPEND_COMPILE_FLAGS([ dnl [$ax_compiler_no_suggest_attribute_flags] dnl ],ax_warn_cflags_variable,[$ax_compiler_flags_test]) ]) # In the flags below, when disabling specific flags, always add *both* # -Wno-foo and -Wno-error=foo. This fixes the situation where (for example) # we enable -Werror, disable a flag, and a build bot passes CFLAGS=-Wall, # which effectively turns that flag back on again as an error. for flag in $ax_warn_cflags_variable; do AS_CASE([$flag], [-Wno-*=*],[], [-Wno-*],[ AX_APPEND_COMPILE_FLAGS([-Wno-error=$(AS_ECHO([$flag]) | $SED 's/^-Wno-//')], ax_warn_cflags_variable, [$ax_compiler_flags_test]) ]) done AC_LANG_POP([C]) # Substitute the variables AC_SUBST(ax_warn_cflags_variable) ])dnl AX_COMPILER_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_gir.html # =========================================================================== # # SYNOPSIS # # AX_COMPILER_FLAGS_GIR([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) # # DESCRIPTION # # Add warning flags for the g-ir-scanner (from GObject Introspection) to # VARIABLE, which defaults to WARN_SCANNERFLAGS. VARIABLE is AC_SUBST-ed # by this macro, but must be manually added to the SCANNERFLAGS variable # for each GIR target in the code base. # # This macro depends on the environment set up by AX_COMPILER_FLAGS. # Specifically, it uses the value of $ax_enable_compile_warnings to decide # which flags to enable. # # LICENSE # # Copyright (c) 2015 Philip Withnall # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6 AC_DEFUN([AX_COMPILER_FLAGS_GIR],[ AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) # Variable names m4_define([ax_warn_scannerflags_variable], [m4_normalize(ifelse([$1],,[WARN_SCANNERFLAGS],[$1]))]) # Base flags AX_APPEND_FLAG([$3],ax_warn_scannerflags_variable) AS_IF([test "$ax_enable_compile_warnings" != "no"],[ # "yes" flags AX_APPEND_FLAG([ dnl --warn-all dnl $4 dnl $5 dnl $6 dnl $7 dnl ],ax_warn_scannerflags_variable) ]) AS_IF([test "$ax_enable_compile_warnings" = "error"],[ # "error" flags AX_APPEND_FLAG([ dnl --warn-error dnl ],ax_warn_scannerflags_variable) ]) # Substitute the variables AC_SUBST(ax_warn_scannerflags_variable) ])dnl AX_COMPILER_FLAGS # ============================================================================== # https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_ldflags.html # ============================================================================== # # SYNOPSIS # # AX_COMPILER_FLAGS_LDFLAGS([VARIABLE], [IS-RELEASE], [EXTRA-BASE-FLAGS], [EXTRA-YES-FLAGS]) # # DESCRIPTION # # Add warning flags for the linker to VARIABLE, which defaults to # WARN_LDFLAGS. VARIABLE is AC_SUBST-ed by this macro, but must be # manually added to the LDFLAGS variable for each target in the code base. # # This macro depends on the environment set up by AX_COMPILER_FLAGS. # Specifically, it uses the value of $ax_enable_compile_warnings to decide # which flags to enable. # # LICENSE # # Copyright (c) 2014, 2015 Philip Withnall # Copyright (c) 2017, 2018 Reini Urban # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 9 AC_DEFUN([AX_COMPILER_FLAGS_LDFLAGS],[ AX_REQUIRE_DEFINED([AX_APPEND_LINK_FLAGS]) AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) # Variable names m4_define([ax_warn_ldflags_variable], [m4_normalize(ifelse([$1],,[WARN_LDFLAGS],[$1]))]) # Always pass -Werror=unknown-warning-option to get Clang to fail on bad # flags, otherwise they are always appended to the warn_ldflags variable, # and Clang warns on them for every compilation unit. # If this is passed to GCC, it will explode, so the flag must be enabled # conditionally. AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ ax_compiler_flags_test="-Werror=unknown-warning-option" ],[ ax_compiler_flags_test="" ]) AX_CHECK_LINK_FLAG([-Wl,--as-needed], [ AX_APPEND_LINK_FLAGS([-Wl,--as-needed], [AM_LDFLAGS],[$ax_compiler_flags_test]) ]) AX_CHECK_LINK_FLAG([-Wl,-z,relro], [ AX_APPEND_LINK_FLAGS([-Wl,-z,relro], [AM_LDFLAGS],[$ax_compiler_flags_test]) ]) AX_CHECK_LINK_FLAG([-Wl,-z,now], [ AX_APPEND_LINK_FLAGS([-Wl,-z,now], [AM_LDFLAGS],[$ax_compiler_flags_test]) ]) AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [ AX_APPEND_LINK_FLAGS([-Wl,-z,noexecstack], [AM_LDFLAGS],[$ax_compiler_flags_test]) ]) # textonly, retpolineplt not yet # macOS and cygwin linker do not have --as-needed AX_CHECK_LINK_FLAG([-Wl,--no-as-needed], [ ax_compiler_flags_as_needed_option="-Wl,--no-as-needed" ], [ ax_compiler_flags_as_needed_option="" ]) # macOS linker speaks with a different accent ax_compiler_flags_fatal_warnings_option="" AX_CHECK_LINK_FLAG([-Wl,--fatal-warnings], [ ax_compiler_flags_fatal_warnings_option="-Wl,--fatal-warnings" ]) AX_CHECK_LINK_FLAG([-Wl,-fatal_warnings], [ ax_compiler_flags_fatal_warnings_option="-Wl,-fatal_warnings" ]) # Base flags AX_APPEND_LINK_FLAGS([ dnl $ax_compiler_flags_as_needed_option dnl $3 dnl ],ax_warn_ldflags_variable,[$ax_compiler_flags_test]) AS_IF([test "$ax_enable_compile_warnings" != "no"],[ # "yes" flags AX_APPEND_LINK_FLAGS([$4 $5 $6 $7], ax_warn_ldflags_variable, [$ax_compiler_flags_test]) ]) AS_IF([test "$ax_enable_compile_warnings" = "error"],[ # "error" flags; -Werror has to be appended unconditionally because # it's not possible to test for # # suggest-attribute=format is disabled because it gives too many false # positives AX_APPEND_LINK_FLAGS([ dnl $ax_compiler_flags_fatal_warnings_option dnl ],ax_warn_ldflags_variable,[$ax_compiler_flags_test]) ]) # Substitute the variables AC_SUBST(ax_warn_ldflags_variable) ])dnl AX_COMPILER_FLAGS # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_is_release.html # =========================================================================== # # SYNOPSIS # # AX_IS_RELEASE(POLICY) # # DESCRIPTION # # Determine whether the code is being configured as a release, or from # git. Set the ax_is_release variable to 'yes' or 'no'. # # If building a release version, it is recommended that the configure # script disable compiler errors and debug features, by conditionalising # them on the ax_is_release variable. If building from git, these # features should be enabled. # # The POLICY parameter specifies how ax_is_release is determined. It can # take the following values: # # * git-directory: ax_is_release will be 'no' if a '.git' # directory or git worktree exists # * minor-version: ax_is_release will be 'no' if the minor version number # in $PACKAGE_VERSION is odd; this assumes # $PACKAGE_VERSION follows the 'major.minor.micro' scheme # * micro-version: ax_is_release will be 'no' if the micro version number # in $PACKAGE_VERSION is odd; this assumes # $PACKAGE_VERSION follows the 'major.minor.micro' scheme # * dash-version: ax_is_release will be 'no' if there is a dash '-' # in $PACKAGE_VERSION, for example 1.2-pre3, 1.2.42-a8b9 # or 2.0-dirty (in particular this is suitable for use # with git-version-gen) # * always: ax_is_release will always be 'yes' # * never: ax_is_release will always be 'no' # # Other policies may be added in future. # # LICENSE # # Copyright (c) 2015 Philip Withnall # Copyright (c) 2016 Collabora Ltd. # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. #serial 8 AC_DEFUN([AX_IS_RELEASE],[ AC_BEFORE([AC_INIT],[$0]) m4_case([$1], [git-directory],[ # $is_release = (.git directory does not exist) AS_IF([test -d ${srcdir}/.git || (test -f ${srcdir}/.git && grep \.git/worktrees ${srcdir}/.git)],[ax_is_release=no],[ax_is_release=yes]) ], [minor-version],[ # $is_release = ($minor_version is even) minor_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]][[^.]]*.\([[^.]][[^.]]*\).*/\1/'` AS_IF([test "$(( $minor_version % 2 ))" -ne 0], [ax_is_release=no],[ax_is_release=yes]) ], [micro-version],[ # $is_release = ($micro_version is even) micro_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]]*\.[[^.]]*\.\([[^.]]*\).*/\1/'` AS_IF([test "$(( $micro_version % 2 ))" -ne 0], [ax_is_release=no],[ax_is_release=yes]) ], [dash-version],[ # $is_release = ($PACKAGE_VERSION has a dash) AS_CASE([$PACKAGE_VERSION], [*-*], [ax_is_release=no], [*], [ax_is_release=yes]) ], [always],[ax_is_release=yes], [never],[ax_is_release=no], [ AC_MSG_ERROR([Invalid policy. Valid policies: git-directory, minor-version, micro-version, dash-version, always, never.]) ]) ]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_java.html # =========================================================================== # # SYNOPSIS # # AX_PROG_JAVA # # DESCRIPTION # # Here is a summary of the main macros: # # AX_PROG_JAVAC: finds a Java compiler. # # AX_PROG_JAVA: finds a Java virtual machine. # # AX_CHECK_CLASS: finds if we have the given class (beware of CLASSPATH!). # # AX_CHECK_RQRD_CLASS: finds if we have the given class and stops # otherwise. # # AX_TRY_COMPILE_JAVA: attempt to compile user given source. # # AX_TRY_RUN_JAVA: attempt to compile and run user given source. # # AX_JAVA_OPTIONS: adds Java configure options. # # AX_PROG_JAVA tests an existing Java virtual machine. It uses the # environment variable JAVA then tests in sequence various common Java # virtual machines. For political reasons, it starts with the free ones. # You *must* call [AX_PROG_JAVAC] before. # # If you want to force a specific VM: # # - at the configure.in level, set JAVA=yourvm before calling AX_PROG_JAVA # # (but after AC_INIT) # # - at the configure level, setenv JAVA # # You can use the JAVA variable in your Makefile.in, with @JAVA@. # # *Warning*: its success or failure can depend on a proper setting of the # CLASSPATH env. variable. # # TODO: allow to exclude virtual machines (rationale: most Java programs # cannot run with some VM like kaffe). # # Note: This is part of the set of autoconf M4 macros for Java programs. # It is VERY IMPORTANT that you download the whole set, some macros depend # on other. Unfortunately, the autoconf archive does not support the # concept of set of macros, so I had to break it for submission. # # A Web page, with a link to the latest CVS snapshot is at # . # # This is a sample configure.in Process this file with autoconf to produce # a configure script. # # AC_INIT(UnTag.java) # # dnl Checks for programs. # AC_CHECK_CLASSPATH # AX_PROG_JAVAC # AX_PROG_JAVA # # dnl Checks for classes # AX_CHECK_RQRD_CLASS(org.xml.sax.Parser) # AX_CHECK_RQRD_CLASS(com.jclark.xml.sax.Driver) # # AC_OUTPUT(Makefile) # # LICENSE # # Copyright (c) 2008 Stephane Bortzmeyer # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 10 AU_ALIAS([AC_PROG_JAVA], [AX_PROG_JAVA]) AC_DEFUN([AX_PROG_JAVA],[ m4_define([m4_ax_prog_java_list], [kaffe java])dnl AS_IF([test "x$JAVAPREFIX" = x], [test x$JAVA = x && AC_CHECK_PROGS([JAVA], [m4_ax_prog_java_list])], [test x$JAVA = x && AC_CHECK_PROGS([JAVA], [m4_ax_prog_java_list], [], [$JAVAPREFIX/bin])]) test x$JAVA = x && AC_MSG_ERROR([no acceptable Java virtual machine found in \$PATH]) m4_undefine([m4_ax_prog_java_list])dnl AX_PROG_JAVA_WORKS AC_PROVIDE([$0])dnl ]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_java_works.html # =========================================================================== # # SYNOPSIS # # AX_PROG_JAVA_WORKS # # DESCRIPTION # # Internal use ONLY. # # Note: This is part of the set of autoconf M4 macros for Java programs. # It is VERY IMPORTANT that you download the whole set, some macros depend # on other. Unfortunately, the autoconf archive does not support the # concept of set of macros, so I had to break it for submission. The # general documentation, as well as the sample configure.in, is included # in the AX_PROG_JAVA macro. # # LICENSE # # Copyright (c) 2008 Stephane Bortzmeyer # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 11 AU_ALIAS([AC_PROG_JAVA_WORKS], [AX_PROG_JAVA_WORKS]) AC_DEFUN([AX_PROG_JAVA_WORKS], [ if test x$ac_cv_prog_javac_works = xno; then AC_MSG_ERROR([Cannot compile java source. $JAVAC does not work properly]) fi if test x$ac_cv_prog_javac_works = x; then AX_PROG_JAVAC fi AC_CACHE_CHECK(if $JAVA works, ac_cv_prog_java_works, [ JAVA_TEST=Test.java CLASS_TEST=Test.class TEST=Test changequote(, )dnl cat << \EOF > $JAVA_TEST /* [#]line __oline__ "configure" */ public class Test { public static void main (String args[]) { System.exit (0); } } EOF changequote([, ])dnl if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) && test -s $CLASS_TEST; then : else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat $JAVA_TEST >&AS_MESSAGE_LOG_FD AC_MSG_ERROR(The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)) fi if AC_TRY_COMMAND($JAVA -classpath . $JAVAFLAGS $TEST) >/dev/null 2>&1; then ac_cv_prog_java_works=yes else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat $JAVA_TEST >&AS_MESSAGE_LOG_FD AC_MSG_ERROR(The Java VM $JAVA failed (see config.log, check the CLASSPATH?)) fi rm -f $JAVA_TEST $CLASS_TEST ]) AC_PROVIDE([$0])dnl ] ) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_javac.html # =========================================================================== # # SYNOPSIS # # AX_PROG_JAVAC # # DESCRIPTION # # AX_PROG_JAVAC tests an existing Java compiler. It uses the environment # variable JAVAC then tests in sequence various common Java compilers. For # political reasons, it starts with the free ones. # # If you want to force a specific compiler: # # - at the configure.in level, set JAVAC=yourcompiler before calling # AX_PROG_JAVAC # # - at the configure level, setenv JAVAC # # You can use the JAVAC variable in your Makefile.in, with @JAVAC@. # # *Warning*: its success or failure can depend on a proper setting of the # CLASSPATH env. variable. # # TODO: allow to exclude compilers (rationale: most Java programs cannot # compile with some compilers like guavac). # # Note: This is part of the set of autoconf M4 macros for Java programs. # It is VERY IMPORTANT that you download the whole set, some macros depend # on other. Unfortunately, the autoconf archive does not support the # concept of set of macros, so I had to break it for submission. The # general documentation, as well as the sample configure.in, is included # in the AX_PROG_JAVA macro. # # LICENSE # # Copyright (c) 2008 Stephane Bortzmeyer # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 8 AU_ALIAS([AC_PROG_JAVAC], [AX_PROG_JAVAC]) AC_DEFUN([AX_PROG_JAVAC],[ m4_define([m4_ax_prog_javac_list],["gcj -C" guavac jikes javac])dnl AS_IF([test "x$JAVAPREFIX" = x], [test "x$JAVAC" = x && AC_CHECK_PROGS([JAVAC], [m4_ax_prog_javac_list])], [test "x$JAVAC" = x && AC_CHECK_PROGS([JAVAC], [m4_ax_prog_javac_list], [], [$JAVAPREFIX/bin])]) m4_undefine([m4_ax_prog_javac_list])dnl test "x$JAVAC" = x && AC_MSG_ERROR([no acceptable Java compiler found in \$PATH]) AX_PROG_JAVAC_WORKS AC_PROVIDE([$0])dnl ]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_prog_javac_works.html # =========================================================================== # # SYNOPSIS # # AX_PROG_JAVAC_WORKS # # DESCRIPTION # # Internal use ONLY. # # Note: This is part of the set of autoconf M4 macros for Java programs. # It is VERY IMPORTANT that you download the whole set, some macros depend # on other. Unfortunately, the autoconf archive does not support the # concept of set of macros, so I had to break it for submission. The # general documentation, as well as the sample configure.in, is included # in the AX_PROG_JAVA macro. # # LICENSE # # Copyright (c) 2008 Stephane Bortzmeyer # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 7 AU_ALIAS([AC_PROG_JAVAC_WORKS], [AX_PROG_JAVAC_WORKS]) AC_DEFUN([AX_PROG_JAVAC_WORKS],[ AC_CACHE_CHECK([if $JAVAC works], ac_cv_prog_javac_works, [ JAVA_TEST=Test.java CLASS_TEST=Test.class cat << \EOF > $JAVA_TEST /* [#]line __oline__ "configure" */ public class Test { } EOF if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) >/dev/null 2>&1; then ac_cv_prog_javac_works=yes else AC_MSG_ERROR([The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)]) echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat $JAVA_TEST >&AS_MESSAGE_LOG_FD fi rm -f $JAVA_TEST $CLASS_TEST ]) AC_PROVIDE([$0])dnl ]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_require_defined.html # =========================================================================== # # SYNOPSIS # # AX_REQUIRE_DEFINED(MACRO) # # DESCRIPTION # # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have # been defined and thus are available for use. This avoids random issues # where a macro isn't expanded. Instead the configure script emits a # non-fatal: # # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found # # It's like AC_REQUIRE except it doesn't expand the required macro. # # Here's an example: # # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) # # LICENSE # # Copyright (c) 2014 Mike Frysinger # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 2 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) ])dnl AX_REQUIRE_DEFINED # pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- # serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------ dnl dnl Prepare a "--with-" configure option using the lowercase dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and dnl PKG_CHECK_MODULES in a single macro. AC_DEFUN([PKG_WITH_MODULES], [ m4_pushdef([with_arg], m4_tolower([$1])) m4_pushdef([description], [m4_default([$5], [build with ]with_arg[ support])]) m4_pushdef([def_arg], [m4_default([$6], [auto])]) m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) m4_case(def_arg, [yes],[m4_pushdef([with_without], [--without-]with_arg)], [m4_pushdef([with_without],[--with-]with_arg)]) AC_ARG_WITH(with_arg, AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, [AS_TR_SH([with_]with_arg)=def_arg]) AS_CASE([$AS_TR_SH([with_]with_arg)], [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], [auto],[PKG_CHECK_MODULES([$1],[$2], [m4_n([def_action_if_found]) $3], [m4_n([def_action_if_not_found]) $4])]) m4_popdef([with_arg]) m4_popdef([description]) m4_popdef([def_arg]) ])dnl PKG_WITH_MODULES dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ----------------------------------------------- dnl dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES dnl check._[VARIABLE-PREFIX] is exported as make variable. AC_DEFUN([PKG_HAVE_WITH_MODULES], [ PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) AM_CONDITIONAL([HAVE_][$1], [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ])dnl PKG_HAVE_WITH_MODULES dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, dnl [DESCRIPTION], [DEFAULT]) dnl ------------------------------------------------------ dnl dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make dnl and preprocessor variable. AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], [ PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES #------------------------------------------------------------------------ # SC_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_TCLCONFIG], [ # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl], [directory containing tcl configuration (tclConfig.sh)]), [with_tclconfig="${withval}"]) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case "${with_tclconfig}" in */tclConfig.sh ) if test -f "${with_tclconfig}"; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # SC_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([SC_PATH_TKCONFIG], [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, AS_HELP_STRING([--with-tk], [directory containing tk configuration (tkConfig.sh)]), [with_tkconfig="${withval}"]) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case "${with_tkconfig}" in */tkConfig.sh ) if test -f "${with_tkconfig}"; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib/tk8.6 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # SC_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Substitutes the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TCL_BIN_DIR}/tclConfig.sh" else AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitrary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi AC_SUBST(TCL_VERSION) AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) ]) #------------------------------------------------------------------------ # SC_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TKCONFIG], [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TK_BIN_DIR}/tkConfig.sh" else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitrary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd "${TK_BIN_DIR}"; pwd`" \ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) ]) #------------------------------------------------------------------------ # SC_PROG_TCLSH # Locate a tclsh shell installed on the system path. This macro # will only find a Tcl shell that already exists on the system. # It will not find a Tcl shell in the Tcl build directory or # a Tcl shell that has been installed from the Tcl build directory. # If a Tcl shell can't be located on the PATH, then TCLSH_PROG will # be set to "". Extensions should take care not to create Makefile # rules that are run by default and depend on TCLSH_PROG. An # extension can't assume that an executable Tcl shell exists at # build time. # # Arguments: # none # # Results: # Substitutes the following vars: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN([SC_PROG_TCLSH], [ AC_MSG_CHECKING([for tclsh]) AC_CACHE_VAL(ac_cv_path_tclsh, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/tclsh[[8-9]]* 2> /dev/null` \ `ls -r $dir/tclsh* 2> /dev/null` ; do if test x"$ac_cv_path_tclsh" = x ; then if test -f "$j" ; then ac_cv_path_tclsh=$j break fi fi done done ]) if test -f "$ac_cv_path_tclsh" ; then TCLSH_PROG="$ac_cv_path_tclsh" AC_MSG_RESULT([$TCLSH_PROG]) else # It is not an error if an installed version of Tcl can't be located. TCLSH_PROG="" AC_MSG_RESULT([No tclsh found on PATH]) fi AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # SC_BUILD_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory. This macro will correctly determine # the name of the tclsh executable even if tclsh has not yet # been built in the build directory. The build tclsh must be used # when running tests from an extension build directory. It is not # correct to use the TCLSH_PROG in cases like this. # # Arguments: # none # # Results: # Substitutes the following values: # BUILD_TCLSH #------------------------------------------------------------------------ AC_DEFUN([SC_BUILD_TCLSH], [ AC_MSG_CHECKING([for tclsh in Tcl build directory]) BUILD_TCLSH="${TCL_BIN_DIR}"/tclsh AC_MSG_RESULT([$BUILD_TCLSH]) AC_SUBST(BUILD_TCLSH) ]) #------------------------------------------------------------------------ # SC_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared], [build and link with shared libraries (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "$tcl_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ # SC_ENABLE_FRAMEWORK -- # # Allows the building of shared libraries into frameworks # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-framework=yes|no # # Sets the following vars: # FRAMEWORK_BUILD Value of 1 or 0 #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_FRAMEWORK], [ if test "`uname -s`" = "Darwin" ; then AC_MSG_CHECKING([how to package libraries]) AC_ARG_ENABLE(framework, AS_HELP_STRING([--enable-framework], [package shared libraries in MacOSX frameworks (default: off)]), [enable_framework=$enableval], [enable_framework=no]) if test $enable_framework = yes; then if test $SHARED_BUILD = 0; then AC_MSG_WARN([Frameworks can only be built if --enable-shared is yes]) enable_framework=no fi if test $tcl_corefoundation = no; then AC_MSG_WARN([Frameworks can only be used when CoreFoundation is available]) enable_framework=no fi fi if test $enable_framework = yes; then AC_MSG_RESULT([framework]) FRAMEWORK_BUILD=1 else if test $SHARED_BUILD = 1; then AC_MSG_RESULT([shared library]) else AC_MSG_RESULT([static library]) fi FRAMEWORK_BUILD=0 fi fi ]) #------------------------------------------------------------------------ # SC_ENABLE_THREADS -- # # Specify if thread support should be enabled # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # _THREAD_SAFE #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_THREADS], [ AC_ARG_ENABLE(threads, AS_HELP_STRING([--enable-threads], [build with threads (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${TCL_THREADS}" = 1; then tcl_threaded_core=1; fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) if test "`uname -s`" = "SunOS" ; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) fi AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN([Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile...]) fi fi fi fi # Does the pthread-implementation provide # 'pthread_attr_setstacksize' ? ac_saved_libs=$LIBS LIBS="$LIBS $THREADS_LIBS" AC_CHECK_FUNCS(pthread_attr_setstacksize pthread_atfork) LIBS=$ac_saved_libs else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = 1; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) if test "${tcl_threaded_core}" = 1; then AC_MSG_RESULT([yes (threaded core)]) else AC_MSG_RESULT([yes]) fi else AC_MSG_RESULT([no]) fi AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # SC_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) and compile (TCL_COMPILE_DEBUG) debugging # can also be enabled. # # Arguments: # none # # Requires the following vars to be set in the Makefile: # CFLAGS_DEBUG # CFLAGS_OPTIMIZE # LDFLAGS_DEBUG # LDFLAGS_OPTIMIZE # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true # Sets to $(CFLAGS_OPTIMIZE) if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_SYMBOLS], [ AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, AS_HELP_STRING([--enable-symbols], [build with debugging symbols (default: off)]), [tcl_ok=$enableval], [tcl_ok=no]) # FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?]) AC_MSG_RESULT([no]) AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?]) else CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi ifelse($1,bccdebug,dnl Only enable 'compile' for the Tcl core itself if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_COMPILE_DEBUG, 1, [Is bytecode debugging enabled?]) AC_DEFINE(TCL_COMPILE_STATS, 1, [Are bytecode statistics enabled?]) fi) if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem ]ifelse($1,bccdebug,[compile ])[debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # SC_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. #------------------------------------------------------------------------ AC_DEFUN([SC_ENABLE_LANGINFO], [ AC_ARG_ENABLE(langinfo, AS_HELP_STRING([--enable-langinfo], [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[nl_langinfo(CODESET);]])], [tcl_cv_langinfo_h=yes], [tcl_cv_langinfo_h=no])]) AC_MSG_RESULT([$tcl_cv_langinfo_h]) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # SC_CONFIG_MANPAGES # # Decide whether to use symlinks for linking the manpages, # whether to compress the manpages after installation, and # whether to add a package name suffix to the installed # manpages to avoidfile name clashes. # If compression is enabled also find out what file name suffix # the given compression program is using. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-man-symlinks # --enable-man-compression=PROG # --enable-man-suffix[=STRING] # # Defines the following variable: # # MAN_FLAGS - The apropriate flags for installManPage # according to the user's selection. # #-------------------------------------------------------------------- AC_DEFUN([SC_CONFIG_MANPAGES], [ AC_MSG_CHECKING([whether to use symlinks for manpages]) AC_ARG_ENABLE(man-symlinks, AS_HELP_STRING([--enable-man-symlinks], [use symlinks for the manpages (default: off)]), [test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"], [enableval="no"]) AC_MSG_RESULT([$enableval]) AC_MSG_CHECKING([whether to compress the manpages]) AC_ARG_ENABLE(man-compression, AS_HELP_STRING([--enable-man-compression=PROG], [compress the manpages with PROG (default: off)]), [case $enableval in yes) AC_MSG_ERROR([missing argument to --enable-man-compression]);; no) ;; *) MAN_FLAGS="$MAN_FLAGS --compress $enableval";; esac], [enableval="no"]) AC_MSG_RESULT([$enableval]) if test "$enableval" != "no"; then AC_MSG_CHECKING([for compressed file suffix]) touch TeST $enableval TeST Z=`ls TeST* | sed 's/^....//'` rm -f TeST* MAN_FLAGS="$MAN_FLAGS --extension $Z" AC_MSG_RESULT([$Z]) fi AC_MSG_CHECKING([whether to add a package name suffix for the manpages]) AC_ARG_ENABLE(man-suffix, AS_HELP_STRING([--enable-man-suffix=STRING], [use STRING as a suffix to manpage file names (default: no, AC_PACKAGE_NAME if enabled without specifying STRING)]), [case $enableval in yes) enableval="AC_PACKAGE_NAME" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; no) ;; *) MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; esac], [enableval="no"]) AC_MSG_RESULT([$enableval]) AC_SUBST(MAN_FLAGS) ]) #-------------------------------------------------------------------- # SC_CONFIG_SYSTEM # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the # "uname" command, but there are a few systems, like Next, where # this doesn't work. # # Arguments: # none # # Results: # Defines the following var: # # system - System/platform/version identification code. # #-------------------------------------------------------------------- AC_DEFUN([SC_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ if test -f /usr/lib/NextStep/software_version; then tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird # results, and the version is kept in special file). if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid` fi if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then tcl_cv_sys_version=NetBSD-Debian fi fi fi ]) system=$tcl_cv_sys_version ]) #-------------------------------------------------------------------- # SC_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines and substitutes the following vars: # # DL_OBJS - Name of the object file that implements dynamic # loading for Tcl on this system. # DL_LIBS - Library file(s) to include in tclsh and other base # applications in order for the "load" command to work. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. Could # be the same as CC_SEARCH_FLAGS if ${CC} is used to link. # CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # MAKE_LIB - Command to execute to build the a library; # differs when building shared or static. # MAKE_STUB_LIB - # Command to execute to build a stub library. # INSTALL_LIB - Command to execute to install a library; # differs when building shared or static. # INSTALL_STUB_LIB - # Command to execute to install a stub library. # STLIB_LD - Base command to use for combining object files # into a static library. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # TCL_SHLIB_LD_EXTRAS - Additional element which are added to SHLIB_LD_LIBS # TK_SHLIB_LD_EXTRAS for the build of Tcl and Tk, but not recorded in the # tclConfig.sh, since they are only used for the build # of Tcl and Tk. # Examples: MacOS X records the library version and # compatibility version in the shared library. But # of course the Tcl version of this is only used for Tcl. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" # in a static or shared library name, using the $VERSION variable # to put the version in the right place. This is used # by platforms that need non-standard library names. # Examples: ${VERSION}.so.1.1 on NetBSD, since it needs # to have a version after the .so, and ${VERSION}.a # on AIX, since a shared library needs to have # a .a extension whereas shared objects for loadable # extensions have a .so extension. Defaults to # ${VERSION}${SHLIB_SUFFIX}. # TCL_LIBS - # Libs to use when linking Tcl shell or some other # shell that includes Tcl libs. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) # #-------------------------------------------------------------------- AC_DEFUN([SC_CONFIG_CFLAGS], [ # Step 0.a: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is requested]) AC_ARG_ENABLE(64bit, AS_HELP_STRING([--enable-64bit], [enable 64bit support (default: off)]), [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis, AS_HELP_STRING([--enable-64bit-vis], [enable 64bit Sparc VIS support (default: off)]), [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) # Force 64bit on with VIS AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. AC_CACHE_CHECK([if compiler supports visibility "hidden"], tcl_cv_cc_visibility_hidden, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {}]], [[f();]])], [tcl_cv_cc_visibility_hidden=yes], [tcl_cv_cc_visibility_hidden=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? AC_MSG_CHECKING([if rpath support is requested]) AC_ARG_ENABLE(rpath, AS_HELP_STRING([--disable-rpath], [disable rpath support (default: on)]), [doRpath=$enableval], [doRpath=yes]) AC_MSG_RESULT([$doRpath]) # Step 1: set the variable "system" to hold the name and version number # for the system. SC_CONFIG_SYSTEM # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) # Require ranlib early so we can override it in special cases below. AC_REQUIRE([AC_PROG_RANLIB]) # Step 3: set configuration options based on system name and version. do64bit_ok=no # default to '{$LIBS}' and set to "" on per-platform necessary basis SHLIB_LD_LIBS='${LIBS}' LDFLAGS_ORIG="$LDFLAGS" # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" UNSHARED_LIB_SUFFIX="" TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`' ECHO_VERSION='`echo ${VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall -Wpointer-arith" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" ]) AC_CHECK_TOOL(AR, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" AS_IF([test "x${SHLIB_VERSION}" = x],[SHLIB_VERSION=".1.0"],[SHLIB_VERSION=".${SHLIB_VERSION}"]) case $system in AIX-*) AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r|*_r\ *) # ok ... ;; *) # Make sure only first arg gets _r CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'` ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) ]) LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" LD_LIBRARY_PATH_VAR="LIBPATH" # ldAix No longer needed with use of -bexpall/-brtl # but some extensions may still reference it LDAIX_SRC='$(UNIX_DIR)/ldAix' # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported with GCC on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" ]) ]) AS_IF([test "`uname -m`" = ia64], [ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" AS_IF([test "$GCC" = yes], [ CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' ], [ CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' ]) LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ], [ AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared -Wl,-bexpall' ], [ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry" LDFLAGS="$LDFLAGS -brtl" ]) SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -nostart' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; CYGWIN_*|MINGW32_*|MSYS_*) SHLIB_CFLAGS="-fno-common" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" DL_OBJS="tclLoadDl.o" PLAT_OBJS='${CYGWIN_OBJS}' PLAT_SRCS='${CYGWIN_SRCS}' DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" AC_CACHE_CHECK(for Cygwin version of gcc, ac_cv_cygwin, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef __CYGWIN__ #error cygwin #endif ]], [[]])], [ac_cv_cygwin=no], [ac_cv_cygwin=yes]) ) if test "$ac_cv_cygwin" = "no"; then AC_MSG_ERROR([${CC} is not a cygwin compiler.]) fi if test "x${TCL_THREADS}" = "x0"; then AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads]) fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32" # The eval makes quoting arguments work. if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args --enable-64bit --host=x86_64-w64-mingw32; cd ../unix then : else { echo "configure: error: configure failed for ../win" 1>&2; exit 1; } fi fi ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; Haiku*) LDFLAGS="$LDFLAGS -Wl,--export-dynamic" SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-lroot" AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) LIBS="$LIBS -lxnet" # Use the XOPEN network library AS_IF([test "`uname -m`" = ia64], [ SHLIB_SUFFIX=".so" ], [ SHLIB_SUFFIX=".sl" ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ CFLAGS="$CFLAGS -z" ]) # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = "yes"], [ AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" ]) ]) ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" DL_OBJS="tclLoadShl.o" DL_LIBS="-ldld" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" ]) ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) ], [ do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" ]) ]) ;; Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*) SHLIB_CFLAGS="-fPIC -fno-common" SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE="-O2" # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings # when you inline the string and math operations. Turn this off to # get rid of the warnings. #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" case $system in DragonFly-*|FreeBSD-*) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) ;; esac AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_m64=yes],[tcl_cv_cc_m64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_m64 = yes], [ CFLAGS="$CFLAGS -m64" do64bit_ok=yes ]) ]) # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; MP-RAS-*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,-Bexport" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OpenBSD-*) arch=`arch -s` case "$arch" in alpha|sparc64) SHLIB_CFLAGS="-fPIC" ;; *) SHLIB_CFLAGS="-fpic" ;; esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" AS_IF([test "${TCL_THREADS}" = "1"], [ # On OpenBSD: Compile with -pthread # Don't link with -lpthread LIBS=`echo $LIBS | sed s/-lpthread//` CFLAGS="$CFLAGS -pthread" ]) # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*) # NetBSD has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ;; Darwin-*) CFLAGS_OPTIMIZE="-O2" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" AS_IF([test $do64bit = yes], [ case `arch` in ppc) AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], tcl_cv_cc_arch_ppc64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_ppc64=yes],[tcl_cv_cc_arch_ppc64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes ]);; i386|x86_64) AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], tcl_cv_cc_arch_x86_64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_x86_64=yes],[tcl_cv_cc_arch_x86_64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes ]);; arm64) AC_CACHE_CHECK([if compiler accepts -arch arm64 flag], tcl_cv_cc_arch_arm64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch arm64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_arm64=yes],[tcl_cv_cc_arch_arm64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_arm64 = yes], [ CFLAGS="$CFLAGS -arch arm64" do64bit_ok=yes ]);; *) AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; esac ], [ # Check for combined 32-bit and 64-bit fat build AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ fat_32_64=yes]) ]) SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}' AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_single_module=yes], [tcl_cv_ld_single_module=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_single_module = yes], [ SHLIB_LD="${SHLIB_LD} -Wl,-single_module" ]) SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])], [tcl_cv_ld_search_paths_first=yes], [tcl_cv_ld_search_paths_first=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [__private_extern__], [Compiler support for module scope symbols]) tcl_cv_cc_visibility_hidden=yes ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_FALLBACK_LIBRARY_PATH" AC_DEFINE(MAC_OSX_TCL, 1, [Is this a Mac I see before me?]) PLAT_OBJS='${MAC_OSX_OBJS}' PLAT_SRCS='${MAC_OSX_SRCS}' AC_MSG_CHECKING([whether to use CoreFoundation]) AC_ARG_ENABLE(corefoundation, AS_HELP_STRING([--enable-corefoundation], [use CoreFoundation API on MacOSX (default: on)]), [tcl_corefoundation=$enableval], [tcl_corefoundation=yes]) AC_MSG_RESULT([$tcl_corefoundation]) AS_IF([test $tcl_corefoundation = yes], [ AC_CACHE_CHECK([for CoreFoundation.framework], tcl_cv_lib_corefoundation, [ hold_libs=$LIBS AS_IF([test "$fat_32_64" = yes], [ for v in CFLAGS CPPFLAGS LDFLAGS; do # On Tiger there is no 64-bit CF, so remove 64-bit # archs from CFLAGS et al. while testing for # presence of CF. 64-bit CF is disabled in # tclUnixPort.h if necessary. eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done]) LIBS="$LIBS -framework CoreFoundation" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[CFBundleRef b = CFBundleGetMainBundle();]])], [tcl_cv_lib_corefoundation=yes], [tcl_cv_lib_corefoundation=no]) AS_IF([test "$fat_32_64" = yes], [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) LIBS=$hold_libs]) AS_IF([test $tcl_cv_lib_corefoundation = yes], [ LIBS="$LIBS -framework CoreFoundation" AC_DEFINE(HAVE_COREFOUNDATION, 1, [Do we have access to Darwin CoreFoundation.framework?]) ], [tcl_corefoundation=no]) AS_IF([test "$fat_32_64" = yes -a $tcl_corefoundation = yes],[ AC_CACHE_CHECK([for 64-bit CoreFoundation], tcl_cv_lib_corefoundation_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[CFBundleRef b = CFBundleGetMainBundle();]])], [tcl_cv_lib_corefoundation_64=yes], [tcl_cv_lib_corefoundation_64=no]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) AS_IF([test $tcl_cv_lib_corefoundation_64 = no], [ AC_DEFINE(NO_COREFOUNDATION_64, 1, [Is Darwin CoreFoundation unavailable for 64-bit?]) LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings" ]) ]) ]) ;; NEXTSTEP-*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -nostdlib -r' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadNext.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OS/390-*) SHLIB_LD_LIBS="" CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1 SHLIB_CFLAGS="" # Hack: make package name same as library name SHLIB_LD='ld -R -export $@:' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadOSF.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" AS_IF([test "$SHARED_BUILD" = 1], [SHLIB_LD="ld -shared"], [ SHLIB_LD="ld -non_shared" ]) SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" AS_IF([test "$SHARED_BUILD" = 1], [ SHLIB_LD='${CC} -shared' ], [ SHLIB_LD='${CC} -non_shared' ]) SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa AS_IF([test "${TCL_THREADS}" = 1], [ CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` AS_IF([test "$GCC" = yes], [ LIBS="$LIBS -lpthread -lmach -lexc" ], [ CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ]) ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" # dlopen is in -lc on QNX DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. AS_IF([test "$GCC" = yes], [ SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" ], [ SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" ]) SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SINIX*5.4*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-4*) SHLIB_CFLAGS="-PIC" SHLIB_LD="ld" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} # SunOS can't handle version numbers with dots in them in library # specs, like -ltcl7.5, so use -ltcl75 instead. Also, it # requires an extra version number at the end of .so file names. # So, the library has to have a name like libtcl75.so.1.0 SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ arch=`isainfo` AS_IF([test "$arch" = "sparcv9 sparc"], [ AS_IF([test "$GCC" = yes], [ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" ]) ], [ do64bit_ok=yes AS_IF([test "$do64bitVIS" = yes], [ CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" ], [ CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" ]) # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" ]) ], [AS_IF([test "$arch" = "amd64 i386"], [ AS_IF([test "$GCC" = yes], [ case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]);; esac ], [ do64bit_ok=yes case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac ]) ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) ]) #-------------------------------------------------------------------- # On Solaris 5.x i386 with the sunpro compiler we need to link # with sunmath to get floating point rounding control #-------------------------------------------------------------------- AS_IF([test "$GCC" = yes],[use_sunmath=no],[ arch=`isainfo` AC_MSG_CHECKING([whether to use -lsunmath for fp rounding control]) AS_IF([test "$arch" = "amd64 i386" -o "$arch" = "i386"], [ AC_MSG_RESULT([yes]) MATH_LIBS="-lsunmath $MATH_LIBS" AC_CHECK_HEADER(sunmath.h) use_sunmath=yes ], [ AC_MSG_RESULT([no]) use_sunmath=no ]) ]) SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "$do64bit_ok" = yes], [ AS_IF([test "$arch" = "sparcv9 sparc"], [ # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" ], [AS_IF([test "$arch" = "amd64 i386"], [ SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" ])]) ]) ], [ AS_IF([test "$use_sunmath" = yes], [textmode=textoff],[textmode=text]) case $system in SunOS-5.[[1-9]][[0-9]]*|SunOS-5.[[7-9]]) SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";; *) SHLIB_LD="/usr/ccs/bin/ld -G -z $textmode";; esac CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' ]) ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],[tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_Bexport = yes], [ LDFLAGS="$LDFLAGS -Wl,-Bexport" ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) ]) AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = yes], [ AC_DEFINE(TCL_CFG_DO64BIT, 1, [Is this a 64-bit build?]) ]) dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so dnl # until the end of configure, as configure's compile and link tests use dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's dnl # preprocessing tests use only CPPFLAGS. AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) # Step 4: disable dynamic loading if requested via a command-line switch. AC_ARG_ENABLE(load, AS_HELP_STRING([--enable-load], [allow dynamic loading and "load" command (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) AS_IF([test "$tcl_ok" = no], [DL_OBJS=""]) AS_IF([test "x$DL_OBJS" != x], [BUILD_DLTEST="\$(DLTEST_TARGETS)"], [ AC_MSG_WARN([Can't figure out how to do dynamic loading or shared libraries on this system.]) SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" DL_OBJS="tclLoadNone.o" DL_LIBS="" LDFLAGS="$LDFLAGS_ORIG" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" BUILD_DLTEST="" ]) LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [ case $system in AIX-*) ;; BSD/OS*) ;; CYGWIN_*|MINGW32_*|MSYS_*) ;; HP-UX*) ;; Darwin-*) ;; IRIX*) ;; NetBSD-*|OpenBSD-*) ;; OSF1-*) ;; SCO_SV-3.2*) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [extern], [No Compiler support for module scope symbols]) ]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ UNSHARED_LIB_SUFFIX='${VERSION}.a']) DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)" AS_IF([test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""], [ LIB_SUFFIX=${SHARED_LIB_SUFFIX} MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${LDFLAGS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}' AS_IF([test "${SHLIB_SUFFIX}" = ".dll"], [ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"' DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)" ], [ INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' ]) ], [ LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} AS_IF([test "$RANLIB" = ""], [ MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}' ], [ MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@' ]) INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' ]) # Stub lib does not depend on shared/static configuration AS_IF([test "$RANLIB" = ""], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}' ], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@' ]) INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' # Define TCL_LIBS now that we know what DL_LIBS is. # The trick here is that we don't want to change the value of TCL_LIBS if # it is already set when tclConfig.sh had been loaded by Tk. AS_IF([test "x${TCL_LIBS}" = x], [ TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"]) AC_SUBST(TCL_LIBS) # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. AC_CACHE_CHECK(for cast to union support, tcl_cv_cast_to_union, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ union foo { int i; double d; }; union foo f = (union foo) (int) 0; ]])], [tcl_cv_cast_to_union=yes], [tcl_cv_cast_to_union=no]) ) if test "$tcl_cv_cast_to_union" = "yes"; then AC_DEFINE(HAVE_CAST_TO_UNION, 1, [Defined when compiler supports casting to union type.]) fi hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -fno-lto" AC_CACHE_CHECK(for working -fno-lto, ac_cv_nolto, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], [ac_cv_nolto=yes], [ac_cv_nolto=no]) ) CFLAGS=$hold_cflags if test "$ac_cv_nolto" = "yes" ; then CFLAGS_NOLTO="-fno-lto" else CFLAGS_NOLTO="" fi # Check for vfork, posix_spawnp() and friends unconditionally AC_CHECK_FUNCS(vfork posix_spawnp posix_spawn_file_actions_adddup2 posix_spawnattr_setflags) # FIXME: This subst was left in only because the TCL_DL_LIBS # entry in tclConfig.sh uses it. It is not clear why someone # would use TCL_DL_LIBS instead of TCL_LIBS. AC_SUBST(DL_LIBS) AC_SUBST(DL_OBJS) AC_SUBST(PLAT_OBJS) AC_SUBST(PLAT_SRCS) AC_SUBST(LDAIX_SRC) AC_SUBST(CFLAGS) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(CFLAGS_NOLTO) AC_SUBST(LDFLAGS) AC_SUBST(LDFLAGS_DEBUG) AC_SUBST(LDFLAGS_OPTIMIZE) AC_SUBST(CC_SEARCH_FLAGS) AC_SUBST(LD_SEARCH_FLAGS) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(TCL_SHLIB_LD_EXTRAS) AC_SUBST(TK_SHLIB_LD_EXTRAS) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(SHLIB_SUFFIX) AC_DEFINE_UNQUOTED(TCL_SHLIB_EXT,"${SHLIB_SUFFIX}", [What is the default extension for shared libraries?]) AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(INSTALL_LIB) AC_SUBST(DLL_INSTALL_DIR) AC_SUBST(INSTALL_STUB_LIB) AC_SUBST(RANLIB) ]) #-------------------------------------------------------------------- # SC_MISSING_POSIX_HEADERS # # Supply substitutes for missing POSIX header files. Special # notes: # - stdlib.h doesn't define strtol, strtoul, or # strtod insome versions of SunOS # - some versions of string.h don't declare procedures such # as strstr # # Arguments: # none # # Results: # # Defines some of the following vars: # NO_DIRENT_H # NO_FLOAT_H # NO_VALUES_H # NO_STDLIB_H # NO_STRING_H # NO_SYS_WAIT_H # NO_DLFCN_H # HAVE_SYS_PARAM_H # HAVE_STRING_H ? # #-------------------------------------------------------------------- AC_DEFUN([SC_MISSING_POSIX_HEADERS], [ AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[ #ifndef _POSIX_SOURCE # ifdef __Lynx__ /* * Generate compilation error to make the test fail: Lynx headers * are only valid if really in the POSIX environment. */ missing_procedure(); # endif #endif DIR *d; struct dirent *entryPtr; char *p; d = opendir("foobar"); entryPtr = readdir(d); p = entryPtr->d_name; closedir(d); ]])],[tcl_cv_dirent_h=yes],[tcl_cv_dirent_h=no])]) if test $tcl_cv_dirent_h = no; then AC_DEFINE(NO_DIRENT_H, 1, [Do we have ?]) fi AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])]) AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0) if test $tcl_ok = 0; then AC_DEFINE(NO_STDLIB_H, 1, [Do we have ?]) fi AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0) AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0) # See also memmove check below for a place where NO_STRING_H can be # set and why. if test $tcl_ok = 0; then AC_DEFINE(NO_STRING_H, 1, [Do we have ?]) fi AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have ?])]) # OS/390 lacks sys/param.h (and doesn't need it, by chance). AC_CHECK_HEADERS([sys/param.h]) ]) #-------------------------------------------------------------------- # SC_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # #-------------------------------------------------------------------- AC_DEFUN([SC_PATH_X], [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[],[not_really_there="yes"]) else if test ! -r $x_includes/X11/Xlib.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[found_xincludes="yes"],[found_xincludes="no"]) if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Xlib.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" break fi done fi else if test "$x_includes" != ""; then XINCLUDES="-I$x_includes" found_xincludes="yes" fi fi if test "$found_xincludes" = "no"; then AC_MSG_RESULT([couldn't find any!]) fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi ]) #-------------------------------------------------------------------- # SC_BLOCKING_STYLE # # The statements below check for systems where POSIX-style # non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. # On these systems (mostly older ones), use the old BSD-style # FIONBIO approach instead. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK # #-------------------------------------------------------------------- AC_DEFUN([SC_BLOCKING_STYLE], [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) SC_CONFIG_SYSTEM AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) case $system in OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; SunOS-4*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # SC_TIME_HANLDER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR # #-------------------------------------------------------------------- AC_DEFUN([SC_TIME_HANDLER], [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_CHECK_FUNCS(gmtime_r localtime_r mktime) AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_tzadj;]])], [tcl_cv_member_tm_tzadj=yes], [tcl_cv_member_tm_tzadj=no])]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_gmtoff;]])], [tcl_cv_member_tm_gmtoff=yes], [tcl_cv_member_tm_gmtoff=no])]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern long timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_long=yes], [tcl_cv_timezone_long=no])]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern time_t timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_time=yes], [tcl_cv_timezone_time=no])]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # SC_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm), socket stuff (-lsocket vs. # -lnsl), zlib (-lz) and libtommath (-ltommath) are dealt with here. # # Arguments: # None. # # Results: # # Might append to the following vars: # LIBS # MATH_LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_LINK_LIBS], [ #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])]) ]) #-------------------------------------------------------------------- # SC_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _LARGEFILE64_SOURCE # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[ ]$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)])) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN([SC_TCL_EARLY_FLAGS],[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" SC_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include ], [struct stat64 buf; int i = stat64("/", &buf);]) if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # SC_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64, HAVE_DIR64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_64BIT_FLAGS], [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[__int64 value = (__int64) 0;]])], [tcl_type_64bit=__int64], [tcl_type_64bit="long long"]) # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?]) AC_MSG_RESULT([using long]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 p;]])], [tcl_cv_struct_dirent64=yes],[tcl_cv_struct_dirent64=no])]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 *p; DIR64 d = opendir64("."); p = readdir64(d); rewinddir64(d); closedir64(d);]])], [tcl_cv_DIR64=yes], [tcl_cv_DIR64=no])]) if test "x${tcl_cv_DIR64}" = "xyes" ; then AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in ?]) fi AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct stat64 p; ]])], [tcl_cv_struct_stat64=yes], [tcl_cv_struct_stat64=no])]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) fi AC_CHECK_FUNCS(open64 lseek64) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[off64_t offset; ]])], [tcl_cv_type_off64_t=yes], [tcl_cv_type_off64_t=no])]) dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the dnl functions lseek64 and open64 are defined. if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi ]) #-------------------------------------------------------------------- # SC_TCL_CFG_ENCODING TIP #59 # # Declare the encoding to use for embedded configuration information. # # Arguments: # None. # # Results: # Might append to the following vars: # DEFS (implicit) # # Will define the following vars: # TCL_CFGVAL_ENCODING # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_CFG_ENCODING], [ AC_ARG_WITH(encoding, AS_HELP_STRING([--with-encoding], [encoding for configuration values (default: iso8859-1)]), [with_tcencoding=${withval}]) if test x"${with_tcencoding}" != x ; then AC_DEFINE_UNQUOTED(TCL_CFGVAL_ENCODING,"${with_tcencoding}", [What encoding should be used for embedded configuration info?]) else AC_DEFINE(TCL_CFGVAL_ENCODING,"iso8859-1", [What encoding should be used for embedded configuration info?]) fi ]) #-------------------------------------------------------------------- # SC_TCL_CHECK_BROKEN_FUNC # # Check for broken function. # # Arguments: # funcName - function to test for # advancedTest - the advanced test to run if the function is present # # Results: # Might cause compatibility versions of the function to be used. # Might affect the following vars: # USE_COMPAT (implicit) # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_CHECK_BROKEN_FUNC],[ AC_CHECK_FUNC($1, tcl_ok=1, tcl_ok=0) if test ["$tcl_ok"] = 1; then AC_CACHE_CHECK([proper ]$1[ implementation], [tcl_cv_]$1[_unbroken], AC_RUN_IFELSE([AC_LANG_SOURCE([[[ #include #include int main() {]$2[}]]])],[tcl_cv_$1_unbroken=ok], [tcl_cv_$1_unbroken=broken],[tcl_cv_$1_unbroken=unknown])) if test ["$tcl_cv_]$1[_unbroken"] = "ok"; then tcl_ok=1 else tcl_ok=0 fi fi if test ["$tcl_ok"] = 0; then AC_LIBOBJ($1) USE_COMPAT=1 fi ]) #-------------------------------------------------------------------- # SC_TCL_GETHOSTBYADDR_R # # Check if we have MT-safe variant of gethostbyaddr(). # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETHOSTBYADDR_R # HAVE_GETHOSTBYADDR_R_7 # HAVE_GETHOSTBYADDR_R_8 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETHOSTBYADDR_R], [ # Avoids picking hidden internal symbol from libc SC_TCL_GETHOSTBYADDR_R_DECL if test "$tcl_cv_api_gethostbyaddr_r" = yes; then SC_TCL_GETHOSTBYADDR_R_TYPE fi ]) AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_DECL], [AC_CHECK_DECLS(gethostbyaddr_r, [ tcl_cv_api_gethostbyaddr_r=yes],[tcl_cv_api_gethostbyaddr_r=no],[#include ]) ]) AC_DEFUN([SC_TCL_GETHOSTBYADDR_R_TYPE], [AC_CHECK_FUNC(gethostbyaddr_r, [ AC_CACHE_CHECK([for gethostbyaddr_r with 7 args], tcl_cv_api_gethostbyaddr_r_7, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *addr; int length; int type; struct hostent *result; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, &h_errnop); ]])],[tcl_cv_api_gethostbyaddr_r_7=yes],[tcl_cv_api_gethostbyaddr_r_7=no])]) tcl_ok=$tcl_cv_api_gethostbyaddr_r_7 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYADDR_R_7, 1, [Define to 1 if gethostbyaddr_r takes 7 args.]) else AC_CACHE_CHECK([for gethostbyaddr_r with 8 args], tcl_cv_api_gethostbyaddr_r_8, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *addr; int length; int type; struct hostent *result, *resultp; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, &resultp, &h_errnop); ]])],[tcl_cv_api_gethostbyaddr_r_8=yes],[tcl_cv_api_gethostbyaddr_r_8=no])]) tcl_ok=$tcl_cv_api_gethostbyaddr_r_8 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYADDR_R_8, 1, [Define to 1 if gethostbyaddr_r takes 8 args.]) fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYADDR_R, 1, [Define to 1 if gethostbyaddr_r is available.]) fi ])]) #-------------------------------------------------------------------- # SC_TCL_GETHOSTBYNAME_R # # Check to see what variant of gethostbyname_r() we have. # Based on David Arnold's example from the comp.programming.threads # FAQ Q213 # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETHOSTBYNAME_R # HAVE_GETHOSTBYNAME_R_3 # HAVE_GETHOSTBYNAME_R_5 # HAVE_GETHOSTBYNAME_R_6 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETHOSTBYNAME_R], [ # Avoids picking hidden internal symbol from libc SC_TCL_GETHOSTBYNAME_R_DECL if test "$tcl_cv_api_gethostbyname_r" = yes; then SC_TCL_GETHOSTBYNAME_R_TYPE fi ]) AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_DECL], [AC_CHECK_DECLS(gethostbyname_r, [ tcl_cv_api_gethostbyname_r=yes],[tcl_cv_api_gethostbyname_r=no],[#include ]) ]) AC_DEFUN([SC_TCL_GETHOSTBYNAME_R_TYPE], [AC_CHECK_FUNC(gethostbyname_r, [ AC_CACHE_CHECK([for gethostbyname_r with 6 args], tcl_cv_api_gethostbyname_r_6, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *name; struct hostent *he, *res; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop); ]])],[tcl_cv_api_gethostbyname_r_6=yes],[tcl_cv_api_gethostbyname_r_6=no])]) tcl_ok=$tcl_cv_api_gethostbyname_r_6 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R_6, 1, [Define to 1 if gethostbyname_r takes 6 args.]) else AC_CACHE_CHECK([for gethostbyname_r with 5 args], tcl_cv_api_gethostbyname_r_5, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *name; struct hostent *he; char buffer[2048]; int buflen = 2048; int h_errnop; (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop); ]])],[tcl_cv_api_gethostbyname_r_5=yes],[tcl_cv_api_gethostbyname_r_5=no])]) tcl_ok=$tcl_cv_api_gethostbyname_r_5 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R_5, 1, [Define to 1 if gethostbyname_r takes 5 args.]) else AC_CACHE_CHECK([for gethostbyname_r with 3 args], tcl_cv_api_gethostbyname_r_3, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *name; struct hostent *he; struct hostent_data data; (void) gethostbyname_r(name, he, &data); ]])],[tcl_cv_api_gethostbyname_r_3=yes],[tcl_cv_api_gethostbyname_r_3=no])]) tcl_ok=$tcl_cv_api_gethostbyname_r_3 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R_3, 1, [Define to 1 if gethostbyname_r takes 3 args.]) fi fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETHOSTBYNAME_R, 1, [Define to 1 if gethostbyname_r is available.]) fi ])]) #-------------------------------------------------------------------- # SC_TCL_GETPWUID_R # # Check if we have MT-safe variant of getpwuid() and if yes, # which one exactly. # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETPWUID_R # HAVE_GETPWUID_R_4 # HAVE_GETPWUID_R_5 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETPWUID_R], [AC_CHECK_FUNC(getpwuid_r, [ AC_CACHE_CHECK([for getpwuid_r with 5 args], tcl_cv_api_getpwuid_r_5, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ uid_t uid; struct passwd pw, *pwp; char buf[512]; int buflen = 512; (void) getpwuid_r(uid, &pw, buf, buflen, &pwp); ]])],[tcl_cv_api_getpwuid_r_5=yes],[tcl_cv_api_getpwuid_r_5=no])]) tcl_ok=$tcl_cv_api_getpwuid_r_5 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWUID_R_5, 1, [Define to 1 if getpwuid_r takes 5 args.]) else AC_CACHE_CHECK([for getpwuid_r with 4 args], tcl_cv_api_getpwuid_r_4, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ uid_t uid; struct passwd pw; char buf[512]; int buflen = 512; (void)getpwnam_r(uid, &pw, buf, buflen); ]])],[tcl_cv_api_getpwuid_r_4=yes],[tcl_cv_api_getpwuid_r_4=no])]) tcl_ok=$tcl_cv_api_getpwuid_r_4 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWUID_R_4, 1, [Define to 1 if getpwuid_r takes 4 args.]) fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWUID_R, 1, [Define to 1 if getpwuid_r is available.]) fi ])]) #-------------------------------------------------------------------- # SC_TCL_GETPWNAM_R # # Check if we have MT-safe variant of getpwnam() and if yes, # which one exactly. # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETPWNAM_R # HAVE_GETPWNAM_R_4 # HAVE_GETPWNAM_R_5 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETPWNAM_R], [AC_CHECK_FUNC(getpwnam_r, [ AC_CACHE_CHECK([for getpwnam_r with 5 args], tcl_cv_api_getpwnam_r_5, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ char *name; struct passwd pw, *pwp; char buf[512]; int buflen = 512; (void) getpwnam_r(name, &pw, buf, buflen, &pwp); ]])],[tcl_cv_api_getpwnam_r_5=yes],[tcl_cv_api_getpwnam_r_5=no])]) tcl_ok=$tcl_cv_api_getpwnam_r_5 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWNAM_R_5, 1, [Define to 1 if getpwnam_r takes 5 args.]) else AC_CACHE_CHECK([for getpwnam_r with 4 args], tcl_cv_api_getpwnam_r_4, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ char *name; struct passwd pw; char buf[512]; int buflen = 512; (void)getpwnam_r(name, &pw, buf, buflen); ]])],[tcl_cv_api_getpwnam_r_4=yes],[tcl_cv_api_getpwnam_r_4=no])]) tcl_ok=$tcl_cv_api_getpwnam_r_4 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWNAM_R_4, 1, [Define to 1 if getpwnam_r takes 4 args.]) fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETPWNAM_R, 1, [Define to 1 if getpwnam_r is available.]) fi ])]) #-------------------------------------------------------------------- # SC_TCL_GETGRGID_R # # Check if we have MT-safe variant of getgrgid() and if yes, # which one exactly. # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETGRGID_R # HAVE_GETGRGID_R_4 # HAVE_GETGRGID_R_5 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETGRGID_R], [AC_CHECK_FUNC(getgrgid_r, [ AC_CACHE_CHECK([for getgrgid_r with 5 args], tcl_cv_api_getgrgid_r_5, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ gid_t gid; struct group gr, *grp; char buf[512]; int buflen = 512; (void) getgrgid_r(gid, &gr, buf, buflen, &grp); ]])],[tcl_cv_api_getgrgid_r_5=yes],[tcl_cv_api_getgrgid_r_5=no])]) tcl_ok=$tcl_cv_api_getgrgid_r_5 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRGID_R_5, 1, [Define to 1 if getgrgid_r takes 5 args.]) else AC_CACHE_CHECK([for getgrgid_r with 4 args], tcl_cv_api_getgrgid_r_4, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ gid_t gid; struct group gr; char buf[512]; int buflen = 512; (void)getgrgid_r(gid, &gr, buf, buflen); ]])],[tcl_cv_api_getgrgid_r_4=yes],[tcl_cv_api_getgrgid_r_4=no])]) tcl_ok=$tcl_cv_api_getgrgid_r_4 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRGID_R_4, 1, [Define to 1 if getgrgid_r takes 4 args.]) fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRGID_R, 1, [Define to 1 if getgrgid_r is available.]) fi ])]) #-------------------------------------------------------------------- # SC_TCL_GETGRNAM_R # # Check if we have MT-safe variant of getgrnam() and if yes, # which one exactly. # # Arguments: # None # # Results: # # Might define the following vars: # HAVE_GETGRNAM_R # HAVE_GETGRNAM_R_4 # HAVE_GETGRNAM_R_5 # #-------------------------------------------------------------------- AC_DEFUN([SC_TCL_GETGRNAM_R], [AC_CHECK_FUNC(getgrnam_r, [ AC_CACHE_CHECK([for getgrnam_r with 5 args], tcl_cv_api_getgrnam_r_5, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ char *name; struct group gr, *grp; char buf[512]; int buflen = 512; (void) getgrnam_r(name, &gr, buf, buflen, &grp); ]])],[tcl_cv_api_getgrnam_r_5=yes],[tcl_cv_api_getgrnam_r_5=no])]) tcl_ok=$tcl_cv_api_getgrnam_r_5 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRNAM_R_5, 1, [Define to 1 if getgrnam_r takes 5 args.]) else AC_CACHE_CHECK([for getgrnam_r with 4 args], tcl_cv_api_getgrnam_r_4, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ char *name; struct group gr; char buf[512]; int buflen = 512; (void)getgrnam_r(name, &gr, buf, buflen); ]])],[tcl_cv_api_getgrnam_r_4=yes],[tcl_cv_api_getgrnam_r_4=no])]) tcl_ok=$tcl_cv_api_getgrnam_r_4 if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRNAM_R_4, 1, [Define to 1 if getgrnam_r takes 4 args.]) fi fi if test "$tcl_ok" = yes; then AC_DEFINE(HAVE_GETGRNAM_R, 1, [Define to 1 if getgrnam_r is available.]) fi ])]) AC_DEFUN([SC_TCL_IPV6],[ NEED_FAKE_RFC2553=0 AC_CHECK_FUNCS(getnameinfo getaddrinfo freeaddrinfo gai_strerror,,[NEED_FAKE_RFC2553=1]) AC_CHECK_TYPES([ struct addrinfo, struct in6_addr, struct sockaddr_in6, struct sockaddr_storage],,[NEED_FAKE_RFC2553=1],[[ #include #include #include #include ]]) if test "x$NEED_FAKE_RFC2553" = "x1"; then AC_DEFINE([NEED_FAKE_RFC2553], 1, [Use compat implementation of getaddrinfo() and friends]) AC_LIBOBJ([fake-rfc2553]) AC_CHECK_FUNC(strlcpy) fi ]) # Local Variables: # mode: autoconf # End: # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 dnl python3.11 python3.10 dnl python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl python3.2 python3.1 python3.0 dnl python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Although site.py simply uses dnl sys.version[:3], printing that failed with Python 3.10, since the dnl trailing zero was eliminated. So now we output just the major dnl and minor version numbers, as numbers. Apparently the tertiary dnl version is not of interest. dnl AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl At times, e.g., when building shared libraries, you may want dnl to know which OS platform Python thinks this is. dnl AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) dnl emacs-page dnl If --with-python-sys-prefix is given, use the values of sys.prefix dnl and sys.exec_prefix for the corresponding values of PYTHON_PREFIX dnl and PYTHON_EXEC_PREFIX. Otherwise, use the GNU ${prefix} and dnl ${exec_prefix} variables. dnl dnl The two are made distinct variables so they can be overridden if dnl need be, although general consensus is that you shouldn't need dnl this separation. dnl dnl Also allow directly setting the prefixes via configure options, dnl overriding any default. dnl if test "x$prefix" = xNONE; then am__usable_prefix=$ac_default_prefix else am__usable_prefix=$prefix fi # Allow user to request using sys.* values from Python, # instead of the GNU $prefix values. AC_ARG_WITH([python-sys-prefix], [AS_HELP_STRING([--with-python-sys-prefix], [use Python's sys.prefix and sys.exec_prefix values])], [am_use_python_sys=:], [am_use_python_sys=false]) # Allow user to override whatever the default Python prefix is. AC_ARG_WITH([python_prefix], [AS_HELP_STRING([--with-python_prefix], [override the default PYTHON_PREFIX])], [am_python_prefix_subst=$withval am_cv_python_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_cv_python_prefix])], [ if $am_use_python_sys; then # using python sys.prefix value, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON prefix], [am_cv_python_prefix], [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`]) dnl If sys.prefix is a subdir of $prefix, replace the literal value of dnl $prefix with a variable reference so it can be overridden. case $am_cv_python_prefix in $am__usable_prefix*) am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` ;; *) am_python_prefix_subst=$am_cv_python_prefix ;; esac else # using GNU prefix value, not python sys.prefix am_python_prefix_subst='${prefix}' am_python_prefix=$am_python_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON prefix]) AC_MSG_RESULT([$am_python_prefix]) fi]) # Substituting python_prefix_subst value. AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst]) # emacs-page Now do it all over again for Python exec_prefix, but with yet # another conditional: fall back to regular prefix if that was specified. AC_ARG_WITH([python_exec_prefix], [AS_HELP_STRING([--with-python_exec_prefix], [override the default PYTHON_EXEC_PREFIX])], [am_python_exec_prefix_subst=$withval am_cv_python_exec_prefix=$withval AC_MSG_CHECKING([for explicit $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # no explicit --with-python_exec_prefix, but if # --with-python_prefix was given, use its value for python_exec_prefix too. AS_IF([test -n "$with_python_prefix"], [am_python_exec_prefix_subst=$with_python_prefix am_cv_python_exec_prefix=$with_python_prefix AC_MSG_CHECKING([for python_prefix-given $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_cv_python_exec_prefix])], [ # Set am__usable_exec_prefix whether using GNU or Python values, # since we use that variable for pyexecdir. if test "x$exec_prefix" = xNONE; then am__usable_exec_prefix=$am__usable_prefix else am__usable_exec_prefix=$exec_prefix fi # if $am_use_python_sys; then # using python sys.exec_prefix, not GNU AC_CACHE_CHECK([for python default $am_display_PYTHON exec_prefix], [am_cv_python_exec_prefix], [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`]) dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the dnl literal value of $exec_prefix with a variable reference so it can dnl be overridden. case $am_cv_python_exec_prefix in $am__usable_exec_prefix*) am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` ;; *) am_python_exec_prefix_subst=$am_cv_python_exec_prefix ;; esac else # using GNU $exec_prefix, not python sys.exec_prefix am_python_exec_prefix_subst='${exec_prefix}' am_python_exec_prefix=$am_python_exec_prefix_subst AC_MSG_CHECKING([for GNU default $am_display_PYTHON exec_prefix]) AC_MSG_RESULT([$am_python_exec_prefix]) fi])]) # Substituting python_exec_prefix_subst. AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst]) # Factor out some code duplication into this shell variable. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" dnl emacs-page Set up 4 directories: dnl 1. pythondir: where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)], [am_cv_python_pythondir], [if test "x$am_cv_python_prefix" = x; then am_py_prefix=$am__usable_prefix else am_py_prefix=$am_cv_python_prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl 2. pkgpythondir: $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. dnl AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl 3. pyexecdir: directory for installing python extension modules dnl (shared libraries). dnl Query distutils for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)], [am_cv_python_pyexecdir], [if test "x$am_cv_python_exec_prefix" = x; then am_py_exec_prefix=$am__usable_exec_prefix else am_py_exec_prefix=$am_cv_python_exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: if hasattr(sysconfig, 'get_default_scheme'): scheme = sysconfig.get_default_scheme() else: scheme = sysconfig._get_default_scheme() if scheme == 'posix_local': # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ scheme = 'posix_prefix' sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') sys.stdout.write(sitedir)"` # case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl 4. pkgpyexecdir: $(pyexecdir)/$(PACKAGE) dnl AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/ac_check_define.m4]) m4_include([m4/atomic_operations.m4]) m4_include([m4/atomic_operations_64bit.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) rsyslog-8.2512.0/PaxHeaders/CONTRIBUTING.md0000644000000000000000000000013115071746523014773 xustar0029 mtime=1760021843.75941974 30 atime=1764850697.815906238 30 ctime=1764935920.447534693 rsyslog-8.2512.0/CONTRIBUTING.md0000664000175000017500000001264615071746523014451 0ustar00rgerrger# Rsyslog Contribution Guide Rsyslog is a real open source project, welcoming contributions of all kinds—from code to documentation to community engagement. Whether you're an experienced developer or a first-time contributor, there are many ways to get involved. Quick start for newcomers: pick a small task from our curated board: https://www.rsyslog.com/tool_good-first-issues > Community expectations: please read our [Code of Conduct](CODE_OF_CONDUCT.md). --- ## Ways to Contribute - **Be an ambassador**: Spread the word about rsyslog and how to best use it. - **Offer support**: - On GitHub: [rsyslog repository](https://github.com/rsyslog/rsyslog) - On the mailing list: [mailing list signup](http://lists.adiscon.net/mailman/listinfo/rsyslog) - **Improve documentation**: - Contributions to documentation should be made to the `doc/` directory of this repository. - Help maintain [rsyslog.com/doc](http://rsyslog.com/doc) - **Maintain infrastructure**: Help with project websites, CI, or packaging. - **Develop code**: Implement new features, improve existing ones, or fix bugs. - the rsyslog project welcomes AI generated patches, we have no friction with them. Qualitiy is ensured by CI and maitainer guidance and review. - AI-assisted contributions should follow [AGENTS.md](AGENTS.md) for setup and workflow guidance. --- ## Pull Requests ### Drafts and Experiments - You may submit early PRs for CI testing. Mark them clearly as `WiP:`. - For experiments, use **draft pull requests**. Close them after testing. ### Target Branch - All PRs must target the `main` branch. --- ## AI-Based Code Review (Experimental) We are currently testing AI-based code review for pull requests. At this time, we use **Google Gemini** to automatically analyze code and provide comments on new PRs. - These reviews are **informational only**. - Every contribution is still **manually reviewed** by human experts. - The goal is to evaluate how AI can support contributor feedback and code quality assurance. Please report any issues, false positives, or suggestions about the AI review process. --- ## Commit Guidelines for AI Agents If you use an AI agent (e.g. GitHub Copilot, ChatGPT, Codex), include a commit footer tag: ``` AI-Agent: Codex 2025-06 ``` This helps us track and evaluate contributions and agent capabilities. --- ## Commit Messages & Commit Assistant To speed up reviews and keep history consistent, please follow these rules for commit messages. You can use our assistant to generate compliant messages. - **Commit Assistant (web, for humans):** https://www.rsyslog.com/tool_rsyslog-commit-assistant - **Base prompt (canonical, in-repo; for agents/offline):** `ai/rsyslog_commit_assistant/base_prompt.txt` **Rules (must):** - ASCII only. - Title ≤ **62** characters; body lines ≤ **72** characters. - Title format: `: ` Examples: `omhttp: migrate to OMODTX`, `docs: clarify imfile wildcards`. - Lead with a brief **non-technical “whyâ€** (modernization, maintainability, performance, security, Docker/CI readiness, user value). - Include **Impact:** one line when tests or user-visible behavior change. - Add a one-line **Before/After** behavior summary. - Provide a **technical overview** (conceptual, not line-by-line) in 4–12 lines. - Footer with full-URL reference(s): - `Fixes: https://github.com/rsyslog/rsyslog/issues/` (only if conclusively fixed) - otherwise `Refs: https://github.com/rsyslog/rsyslog/issues/` Do **not** include secrets/tokens or paste sensitive data from diffs. --- ## Patch Requirements All submissions must: - Use RainerScript (no legacy `$...` config statements). - Compile cleanly with **no warnings** on both `gcc` and `clang`. - Pass `clang` static analysis with no findings. - Pass **all CI test jobs** (see below). - Include: - Tests (for new features or bugfixes) - Documentation updates (for new features) - Squashed commits ([why it matters](https://rainer.gerhards.net/2019/03/squash-your-pull-requests.html)) ### Testbench Tips - Write small, focused tests. - Use similar existing tests as templates. - Test driver is `make check`, backed by `tests/diag.sh`. - Test concurrency is limited due to resource load. ### Compiler Warnings False positives must be resolved, not ignored. Only in extreme cases use: ```c #pragma diagnostic push #pragma GCC diagnostic ignored "..." /* ... function ... */ #pragma diagnostic pop ``` Apply to **single functions only**. See: [Why static analysis matters](https://rainer.gerhards.net/2018/06/why-static-code-analysis.html) --- ## Continuous Integration (CI) All PRs are tested via: - GitHub Actions workflows (including multi-platform docker-based tests) - Additional off-GitHub runners (Solaris, exotic distros) Build durations: 10–40 min per matrix job. Some known flaky tests exist; we re-run these manually if needed. --- ## GDPR and Privacy By contributing, your name, email, commit hash, and timestamp become part of the git history. This is fundamental to git and public open source contribution. If you have privacy concerns, you may commit anonymously: ```bash git commit --author "anonymous " ``` Avoid `--gpg-sign` in that case. If you use your real identity, note: - We cannot delete commits retroactively without damaging project history. - Identity data is used only to maintain copyright tracking and audit trails. - Public commits may be copied by third parties and redistributed without control. rsyslog-8.2512.0/PaxHeaders/tests0000644000000000000000000000013115114544377013630 xustar0030 mtime=1764935935.192760419 29 atime=1764935935.21376074 30 ctime=1764935935.192760419 rsyslog-8.2512.0/tests/0000775000175000017500000000000015114544377013352 5ustar00rgerrgerrsyslog-8.2512.0/tests/PaxHeaders/mmanon_recognize_ipv6.sh0000644000000000000000000000013215055602574020536 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.354629473 30 ctime=1764935932.717722533 rsyslog-8.2512.0/tests/mmanon_recognize_ipv6.sh0000775000175000017500000000375015055602574020212 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.enable="off" ipv6.enable="on" ipv6.bits="128" ipv6.anonmode="zero") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0 <129>Mar 10 01:00:00 172.20.245.8 tag: :: <129>Mar 10 01:00:00 172.20.245.8 tag: 0:: <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45: <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::. test <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45::* test <129>Mar 10 01:00:00 172.20.245.8 tag: *13:abd:45::* test <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45:* test <129>Mar 10 01:00:00 172.20.245.8 tag: ewirnwemaa:ff43::756:99:0 <129>Mar 10 01:00:00 172.20.245.8 tag: a::, cc:: LLL <129>Mar 10 01:00:00 172.20.245.8 tag: 12:12345::a <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFE <129>Mar 10 01:00:00 172.20.245.8 tag: 72:8374:adc7:47FF::43:0:1AFEstillnoblank <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\"" shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 13:abd:45: 0:0:0:0:0:0:0:0. test 0:0:0:0:0:0:0:0* test *0:0:0:0:0:0:0:0* test 13:abd:45:* test ewirnwem0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0, 0:0:0:0:0:0:0:0 LLL 12:10:0:0:0:0:0:0:0 textnoblank0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0stillnoblank textnoblank0:0:0:0:0:0:0:0stillnoblank' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_processing_test4.sh0000644000000000000000000000013215035412264022142 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.852653505 30 ctime=1764935933.147729116 rsyslog-8.2512.0/tests/mmnormalize_processing_test4.sh0000775000175000017500000000326115035412264021613 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=TEST-02:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n") template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n") ruleset(name="ruleset1") { action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on") if ($!v_file == "") then { set $!v_file=$!v_tag; } action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record") action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path") } ' FAKETIME='2017-03-08 14:56:37' startup tcpflood -m1 -M "\"<187>Mar 8 14:56:37 host4 Process2: {SER4.local7 Y01 LNX [SRCH ALRT DASH REPT ANOM]} (/sb/env/logs/dir1/dir2/log_20170308.log) in 1: X/c79RgpDtrva5we84XHTg== (String)\"" shutdown_when_empty wait_shutdown echo '2017-03-08T14:56:37+02:00 2017-03-08T14:56:37+02:00 host4 Process2 in 1: X/c79RgpDtrva5we84XHTg== (String) /sb/logs/incoming/2017/03/08/svc_SER4/ret_Y01/os_LNX/127.0.0.1/r_relay1/sb/env/logs/dir1/dir2/log_20170308.log.gz' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_hostname.sh0000644000000000000000000000013215055602574020000 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.615729866 30 ctime=1764935934.527750239 rsyslog-8.2512.0/tests/imuxsock_hostname.sh0000775000175000017500000000164015055602574017450 0ustar00rgerrger#!/bin/bash # test set hostname . ${srcdir:=.}/diag.sh init ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' global(localHostName="rsyslog-testbench-hostname") module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%hostname:%\n") local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # the message itself is irrelevant. The only important thing is # there is one ./syslog_caller -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" shutdown_when_empty wait_shutdown export EXPECTED="rsyslog-testbench-hostname" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_dtls_certvalid_missing.sh0000644000000000000000000000013215055603742022351 xustar0030 mtime=1756825570.303069141 30 atime=1764931164.464695389 30 ctime=1764935933.892740519 rsyslog-8.2512.0/tests/sndrcv_dtls_certvalid_missing.sh0000775000175000017500000000370215055603742022022 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls} export NUMMESSAGES=1 # export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( # debug.whitelist="on" # debug.files=["imdtls.c", "modules.c", "errmsg.c", "action.c"] ) module( load="../plugins/imdtls/.libs/imdtls" ) input( type="imdtls" port="'$PORT_RCVR'" tls.cacert="'$srcdir'/tls-certs/ca.pem" tls.mycert="'$srcdir'/tls-certs/cert.pem" tls.myprivkey="'$srcdir'/tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog" ) action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" #valgrind="valgrind" generate_conf 2 add_conf ' global( # debug.whitelist="on" # debug.files=["omdtls.c", "modules.c", "errmsg.c", "action.c"] ) # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") $imdiagInjectDelayMode full # Load modules module( load="../plugins/omdtls/.libs/omdtls" ) local4.* { action( name="omdtls" type="omdtls" target="127.0.0.1" port="'$PORT_RCVR'" action.resumeInterval="1" action.resumeRetryCount="2" ) stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # Kindly check for a failed session content_check "OpenSSL Error Stack" content_check "peer did not return a certificate" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-str.sh0000644000000000000000000000013215055602574021652 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.497615722 30 ctime=1764935932.492719089 rsyslog-8.2512.0/tests/rscript_compare_numstr-str.sh0000775000175000017500000000015315055602574021320 0ustar00rgerrger#!/bin/bash export LOWER_VAL='"1"' export HIGHER_VAL='"abc"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_omsnmpv1_udp_invalidoid.sh0000644000000000000000000000013215035412264022442 xustar0030 mtime=1752569012.413660417 30 atime=1764931160.128625847 30 ctime=1764935932.650721508 rsyslog-8.2512.0/tests/sndrcv_omsnmpv1_udp_invalidoid.sh0000775000175000017500000000236615035412264022120 0ustar00rgerrger#!/bin/bash # alorbach, 2019-11-27 # Required Packages # pip install pysnmp # # Ubuntu 18 Packages needed # apt install snmp libsnmp-dev # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export TESTMESSAGES=1 export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.omsnmp.debuglog" generate_conf export PORT_SNMP="$(get_free_port)" # Start SNMP Trap Receiver snmp_start_trapreceiver ${PORT_SNMP} ${RSYSLOG_OUT_LOG} add_conf ' module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) module( load="../plugins/omsnmp/.libs/omsnmp" ) # set up the action template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omsnmp" name="name" server="127.0.0.1" port="'${PORT_SNMP}'" version="0" community="public" enterpriseOID="1337.1.3.3.7.1.3.3.7" messageOID="invalidOIDstring" TrapType="5" specificType="0" ) ' startup tcpflood -p'$TCPFLOOD_PORT' -m${TESTMESSAGES} shutdown_when_empty wait_shutdown snmp_stop_trapreceiver content_check "Parsing SyslogMessageOID failed" ${RSYSLOG_DYNNAME}.started content_check "Unknown Object Identifier" ${RSYSLOG_DYNNAME}.started exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_root.sh0000644000000000000000000000013215055602574020504 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.542728696 30 ctime=1764935934.506749918 rsyslog-8.2512.0/tests/imuxsock_logger_root.sh0000775000175000017500000000163615055602574020161 0ustar00rgerrger#!/bin/bash # note: we must be root and no other syslogd running in order to # carry out this test. echo \[imuxsock_logger_root.sh\]: test trailing LF handling in imuxsock echo This test must be run as root with no other active syslogd if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imuxsock/.libs/imuxsock $template outfmt,"%msg:%\n" *.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # send a message with trailing LF logger test # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log if [ ! $? -eq 0 ]; then echo "imuxsock_logger.sh failed" exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-gtls-manycon.sh0000644000000000000000000000013215055603742020563 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.375677929 30 ctime=1764935933.580735744 rsyslog-8.2512.0/tests/imtcp-tls-gtls-manycon.sh0000775000175000017500000000234115055603742020232 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100000 ulimit -n 2048 # may or may not work ;-) generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/name" #PermittedPeer=["/CN=rsyslog-client/OU=Adiscon GmbH/O=Adiscon GmbH/L=Grossrinderfeld/ST=BW/C=DE/DC=rsyslog.com","rsyslog.com"] PermittedPeer=["rsyslog-client"] ) input(type="imtcp" socketBacklog="1000" maxsessions="1000" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase startup tcpflood -c-1000 -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-load.sh0000644000000000000000000000013215035412264017277 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.389662117 30 ctime=1764935933.296731396 rsyslog-8.2512.0/tests/clickhouse-load.sh0000775000175000017500000000172315035412264016751 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.load (id, ipaddress, message) VALUES (%msg:F,58:2%, ' add_conf "'%fromhost-ip%', '%msg:F,58:2%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" usehttps="off" user="default" pwd="" template="outfmt" bulkmode="off") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.load ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="SELECT message FROM rsyslog.load ORDER BY id" > $RSYSLOG_OUT_LOG clickhouse-client --query="DROP TABLE rsyslog.load" seq_check 0 $(( NUMMESSAGES - 1 )) exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_num-str.sh0000644000000000000000000000013215055602574021121 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.505615851 30 ctime=1764935932.495719135 rsyslog-8.2512.0/tests/rscript_compare_num-str.sh0000775000175000017500000000014715055602574020572 0ustar00rgerrger#!/bin/bash export LOWER_VAL='1' export HIGHER_VAL='"b"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_toupper.sh0000644000000000000000000000013215071746523017505 xustar0030 mtime=1760021843.906422059 30 atime=1764931159.698618948 30 ctime=1764935932.541719839 rsyslog-8.2512.0/tests/rscript_toupper.sh0000775000175000017500000000107415071746523017156 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!str!var1 = toupper("test"); set $!str!var2 = toupper("TeSt"); set $!str!var3 = toupper(""); template(name="outfmt" type="string" string="%!str%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown export EXPECTED='{ "var1": "TEST", "var2": "TEST", "var3": "" }' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-bulk-errfile-popul-erronly-interleaved.sh0000644000000000000000000000013215071746523024356 xustar0030 mtime=1760021843.885421727 30 atime=1764931162.645666223 30 ctime=1764935933.366732468 rsyslog-8.2512.0/tests/es-bulk-errfile-popul-erronly-interleaved.sh0000775000175000017500000000261215071746523024026 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ensure_elasticsearch_ready init_elasticsearch echo '{ "name" : "foo" } {"name": bar"} {"name": "baz"} {"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") # Note: we must mess up with the template, because we can not # instruct ES to put further constraints on the data type and # values. So we require integer and make sure it is none. template(name="tpl" type="list") { constant(value="{\"") property(name="$!key") constant(value="\":") property(name="$!obj") constant(value="}") } module(load="../plugins/omelasticsearch/.libs/omelasticsearch") module(load="../plugins/imfile/.libs/imfile") ruleset(name="foo") { set $!key = "my_obj"; set $!obj = $msg; action(type="omelasticsearch" template="tpl" searchIndex="rsyslog_testbench" bulkmode="on" serverport="19200" errorFile="./'${RSYSLOG_DYNNAME}'.errorfile" erroronly="on" interleaved="on") } input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile" Tag="foo" Severity="info" ruleset="foo") ' startup shutdown_when_empty wait_shutdown $PYTHON $srcdir/elasticsearch-error-format-check.py errorinterleaved if [ $? -ne 0 ] then echo "error: Format for error file different! " $? exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/compresssp-stringtpl.sh0000644000000000000000000000013215035412264020453 xustar0030 mtime=1752569012.385854976 30 atime=1764931161.526648275 30 ctime=1764935933.054727692 rsyslog-8.2512.0/tests/compresssp-stringtpl.sh0000775000175000017500000000172315035412264020125 0ustar00rgerrger#!/bin/bash # addd 2016-03-22 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:::compressSPACE%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup # we need to generate a file, because otherwise our multiple spaces # do not survive the execution paths through the shell echo "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test" >$RSYSLOG_DYNNAME.tmp tcpflood -I $RSYSLOG_DYNNAME.tmp rm $RSYSLOG_DYNNAME.tmp #tcpflood -m1 -M"\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000 test test test\"" shutdown_when_empty wait_shutdown export EXPECTED="msgnum:0000000 test test test" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-feedback-mt.sh0000644000000000000000000000013115062756615017706 xustar0029 mtime=1758190989.23764163 30 atime=1764931165.152706418 30 ctime=1764935934.084743458 rsyslog-8.2512.0/tests/omprog-feedback-mt.sh0000775000175000017500000000350415062756615017360 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Similar to the 'omprog-feedback.sh' test, with multiple worker threads # on high load, and a given error rate (percentage of failed messages, i.e. # confirmed as failed by the program). Note: the action retry interval # (1 second) causes a very low throughput; we need to set a very low error # rate to avoid the test lasting too much. . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "On Solaris, this test causes rsyslog to hang for unknown reasons" if [ "$CC" == "gcc" ] && [[ "$CFLAGS" == *"-coverage"* ]]; then printf 'This test does not work with gcc coverage instrumentation\n' printf 'It will hang, but we do not know why. See\n' printf 'https://github.com/rsyslog/rsyslog/issues/3361\n' exit 77 fi export NUMMESSAGES=10000 # number of logs to send export ERROR_RATE_PERCENT=1 # percentage of logs to be retried export command_line="$srcdir/testsuites/omprog-feedback-mt-bin.sh $ERROR_RATE_PERCENT" generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") main_queue( queue.timeoutShutdown="30000" # long shutdown timeout for the main queue ) :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $command_line` template="outfmt" name="omprog_action" confirmMessages="on" queue.type="LinkedList" # use a dedicated queue queue.workerThreads="10" # ...with multiple workers queue.size="10000" # ...high capacity (default is 1000) queue.timeoutShutdown="60000" # ...and a long shutdown timeout action.resumeInterval="1" # retry interval: 1 second ) } ' startup injectmsg 0 $NUMMESSAGES wait_file_lines "$RSYSLOG_OUT_LOG" $NUMMESSAGES shutdown_when_empty wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_num-num-vg.sh0000644000000000000000000000013215055602574021522 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.623617744 30 ctime=1764935932.525719594 rsyslog-8.2512.0/tests/rscript_compare_num-num-vg.sh0000775000175000017500000000017715055602574021176 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='1' export HIGHER_VAL='2' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_syssock.sh0000644000000000000000000000013215055602574021217 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.550728824 30 ctime=1764935934.508749948 rsyslog-8.2512.0/tests/imuxsock_logger_syssock.sh0000775000175000017500000000133715055602574020672 0ustar00rgerrger#!/bin/bash # test trailing LF handling in imuxsock # note: we use the system socket, but assign a different name to # it. This is not 100% the same thing as running as root, but it # is pretty close to it. -- rgerhards, 201602-19 . ${srcdir:=.}/diag.sh init check_logger_has_option_d export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket") $template outfmt,"%msg:%\n" *.=notice action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup logger -d -u $RSYSLOG_DYNNAME-testbench_socket test shutdown_when_empty wait_shutdown export EXPECTED=" test" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-kafkarest-retry.sh0000644000000000000000000000013215055602574021746 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.869701882 30 ctime=1764935934.004742234 rsyslog-8.2512.0/tests/omhttp-batch-kafkarest-retry.sh0000775000175000017500000000320315055602574021413 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 omhttp_start_server 0 --fail-every 100 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="2048") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") # Echo message as-is for retry template(name="tpl_echo" type="string" string="%msg%") ruleset(name="ruleset_omhttp_retry") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl_echo" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="kafkarest" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } ruleset(name="ruleset_omhttp") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="kafkarest" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint kafkarest omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_err.sh0000644000000000000000000000013215055602574020311 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.534728568 30 ctime=1764935934.504749887 rsyslog-8.2512.0/tests/imuxsock_logger_err.sh0000775000175000017500000000213315055602574017757 0ustar00rgerrger#!/bin/bash # this is primarily a safeguard to ensure the imuxsock tests basically work # added 2014-12-04 by Rainer Gerhards, licensed under ASL 2.0 echo \[imuxsock_logger.sh\]: test imuxsock . ${srcdir:=.}/diag.sh init check_logger_has_option_d generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") *.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # send a message with trailing LF logger -d -u $RSYSLOG_DYNNAME-testbench_socket "wrong message" # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log if [ $? -eq 0 ]; then echo "imuxsock_logger_err.sh did not report an error where it should!" exit 1 else echo "all well, we saw the error that we wanted to have" fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omamqp1-basic-vg.sh0000644000000000000000000000013215035412264017275 xustar0030 mtime=1752569012.402736851 30 atime=1764931168.977767708 30 ctime=1764935935.192760419 rsyslog-8.2512.0/tests/omamqp1-basic-vg.sh0000775000175000017500000000011315035412264016737 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omamqp1-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_kafka.sh0000644000000000000000000000012715071746523016701 xustar0030 mtime=1760021843.907422074 27 atime=1764931166.873734 30 ctime=1764935934.602751388 rsyslog-8.2512.0/tests/sndrcv_kafka.sh0000775000175000017500000000621615071746523016351 0ustar00rgerrger#!/bin/bash # added 2017-05-03 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export KEEP_KAFKA_RUNNING="YES" export TESTMESSAGES=100000 export TESTMESSAGESFULL=100000 # Generate random topic name export RANDTOPIC="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. export EXTRA_EXITCHECK=dumpkafkalogs export EXTRA_EXIT=kafka download_kafka stop_zookeeper stop_kafka start_zookeeper start_kafka create_kafka_topic $RANDTOPIC '.dep_wrk' '22181' export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") $imdiagInjectDelayMode full module(load="../plugins/omkafka/.libs/omkafka") template(name="outfmt" type="string" string="%msg%\n") local4.* { action( name="kafka-fwd" type="omkafka" topic="'$RANDTOPIC'" broker="localhost:29092" template="outfmt" confParam=[ "compression.codec=none", "socket.timeout.ms=10000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "queue.buffering.max.messages=10000", "enable.auto.commit=true", "message.send.max.retries=1"] topicConfParam=["message.timeout.ms=10000"] partitions.auto="on" closeTimeout="60000" resubmitOnFailure="on" keepFailedMessages="on" failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC'.data" action.resumeInterval="1" action.resumeRetryCount="10" queue.saveonshutdown="on" ) stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.snd.othermsg'") ' echo Starting sender instance [omkafka] startup # --- # Injection messages now before starting receiver, simply because omkafka will take some time and # there is no reason to wait for the receiver to startup first. echo Inject messages into rsyslog sender instance injectmsg 1 $TESTMESSAGES # --- Create/Start imkafka receiver config export RSYSLOG_DEBUGLOG="log2" generate_conf 2 add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") module(load="../plugins/imkafka/.libs/imkafka") /* Polls messages from kafka server!*/ input( type="imkafka" topic="'$RANDTOPIC'" broker="localhost:29092" consumergroup="default" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=5000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "enable.partition.eof=false" ] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if ($msg contains "msgnum:") then { action( type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt" ) } else { action( type="omfile" file="'$RSYSLOG_DYNNAME.rcv.othermsg'") } ' 2 echo Starting receiver instance [imkafka] startup 2 # --- echo Stopping sender instance [omkafka] shutdown_when_empty wait_shutdown echo Stopping receiver instance [imkafka] kafka_wait_group_coordinator shutdown_when_empty 2 wait_shutdown 2 delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181' # Dump Kafka log | uncomment if needed # dump_kafka_serverlog kafka_check_broken_broker $RSYSLOG_DYNNAME.snd.othermsg kafka_check_broken_broker $RSYSLOG_DYNNAME.rcv.othermsg seq_check 1 $TESTMESSAGESFULL -d echo success exit_test rsyslog-8.2512.0/tests/PaxHeaders/execonlywhenprevsuspended-queue.sh0000644000000000000000000000013015035412264022671 xustar0029 mtime=1752569012.38883413 30 atime=1764931166.399726404 29 ctime=1764935934.46574929 rsyslog-8.2512.0/tests/execonlywhenprevsuspended-queue.sh0000775000175000017500000000176515035412264022353 0ustar00rgerrger#!/bin/bash # rgerhards, 2015-05-27 echo ===================================================================================== echo \[execonlywhenprevsuspended-queue.sh\]: test execonly...suspended functionality with action on its own queue uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' main_queue(queue.workerthreads="1") # omtesting provides the ability to cause "SUSPENDED" action state module(load="../plugins/omtesting/.libs/omtesting") $MainMsgQueueTimeoutShutdown 100000 template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" { :omtesting:fail 2 0 # omtesting has only legacy params! action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" queue.type="linkedList" action.ExecOnlyWhenPreviousIsSuspended="on" ) } ' startup injectmsg 0 1000 shutdown_when_empty wait_shutdown seq_check 1 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_previous_action_suspended.sh0000644000000000000000000000013115035412264023261 xustar0030 mtime=1752569012.412667365 29 atime=1764931159.82462097 30 ctime=1764935932.569720268 rsyslog-8.2512.0/tests/rscript_previous_action_suspended.sh0000775000175000017500000000123315035412264022730 0ustar00rgerrger#!/bin/bash # Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omtesting/.libs/omtesting") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="output_writer") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } :msg, contains, "msgnum:" { :omtesting:fail 2 0 if previous_action_suspended() then call output_writer } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown seq_check 1 9 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-feedback-timeout.sh0000644000000000000000000000013215035412264020742 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.168706675 30 ctime=1764935934.089743535 rsyslog-8.2512.0/tests/omprog-feedback-timeout.sh0000775000175000017500000000242015035412264020407 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests the feedback feature of omprog (confirmMessages=on), # by checking that omprog restarts the program if it does not send the # feedback before the configured 'confirmTimeout'. Also tests the # keep-alive feature. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-feedback-timeout-bin.sh` template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process confirmMessages="on" confirmTimeout="2000" # 2 seconds reportFailures="on" ) } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown export EXPECTED="Starting <= OK => msgnum:00000000: <= OK => msgnum:00000001: <= OK => msgnum:00000002: <= OK => msgnum:00000003: <= OK => msgnum:00000004: <= (timeout) Starting <= OK => msgnum:00000004: <= OK => msgnum:00000005: <= OK => msgnum:00000006: <= OK => msgnum:00000007: <= ........OK => msgnum:00000008: <= OK => msgnum:00000009: <= OK" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/fieldtest-udp.sh0000644000000000000000000000013115035412264017001 xustar0030 mtime=1752569012.389827181 29 atime=1764931159.03760834 30 ctime=1764935932.359717053 rsyslog-8.2512.0/tests/fieldtest-udp.sh0000775000175000017500000000162415035412264016454 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%msg:F,32:2%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: DROP_url_www.sina.com.cn:IN=eth1 OUT=eth0 SRC=192.168.10.78 DST=61.172.201.194 LEN=1182 TOS=0x00 PREC=0x00 TTL=63 ID=14368 DF PROTO=TCP SPT=33343 DPT=80 WINDOW=92 RES=0x00 ACK PSH URGP=0\"" shutdown_when_empty wait_shutdown echo 'DROP_url_www.sina.com.cn:IN=eth1' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/README0000644000000000000000000000013115071746523014564 xustar0030 mtime=1760021843.879421633 29 atime=1764931157.35358131 30 ctime=1764935931.898709996 rsyslog-8.2512.0/tests/README0000664000175000017500000000644615071746523014243 0ustar00rgerrger# rsyslog testbench quick reference This directory houses the rsyslog Automake test suite. The [`tests/AGENTS.md`](./AGENTS.md) file gives AI agents authoring guidance and conventions; this README focuses on operators and contributors who need to run the suite. Most scripts validate a single module, but complex end-to-end scenarios are welcome. For a minimal example, examine `rtinit.c`, which performs a simple runtime init/deinit cycle. ## Quickstart Bootstrap the build tree before attempting to run tests: ```sh ./autogen.sh ./configure --enable-testbench make -j$(nproc) make check ``` `make check` compiles the helper binaries, prepares fixtures, and then executes the entire suite. Use Ctrl+C to stop an ongoing run. ## Running individual scenarios ``` make .log ``` For example, `make imfile-basic.log` produces `imfile-basic.log` and `imfile-basic.trs`. Remove those files before re-running to clear cached results. When you need Automake’s logging but do not want to type the `.log` suffix, use: ``` make check TESTS='imfile-basic.sh' ``` You can also execute scripts directly (`./tests/imfile-basic.sh`) for quicker iteration, though Automake will not capture transcripts. ## Harness conventions - Source `diag.sh` at the top of every shell test: `. "$srcdir/diag.sh"`. - Prefer helpers such as `cmp_exact` and `require_plugin` over ad-hoc shell so diagnostics stay consistent. See `tests/AGENTS.md` for a longer checklist. - Name Valgrind-enabled wrappers with the `-vg.sh` suffix and Helgrind-enabled scripts with `-vgthread.sh`. `tests/timereported-utc-vg.sh` illustrates how to source the base scenario rather than duplicating it and how to trim emitted messages when a slow test would otherwise become prohibitively long under Valgrind. Some legacy wrappers predate this pattern; follow the newer style when adding or refactoring coverage. ## Environment setup snippets ### MariaDB/MySQL ``` echo "create user 'rsyslog'@'localhost' identified by 'testbench';" | mysql -u root mysql -u root < ../plugins/ommysql/createDB.sql echo "grant all on Syslog.* to 'rsyslog'@'localhost';" | mysql -u root ``` ### openSUSE tips Use the graphical `yast2` tool to adjust hostname and firewall rules. SSH access is disabled in the firewall by default. ## Debugging aids To pause a test and attach a debugger, add the following guard: ```sh . "$srcdir/diag.sh" startup if [ -n "${USE_GDB:-}" ]; then echo "attach gdb here" sleep 54321 || : fi ``` Run the scenario in the background, wait for the prompt, and attach GDB: ``` USE_GDB=1 make mytest.sh.log & tail -f mytest.sh.log # wait for "attach gdb here" gdb ../tools/rsyslogd ``` After continuing in GDB, terminate the `sleep` with `pkill -f 54321` (or locate the PID via `ps -ef | grep 54321`). ## Core dump analysis The harness can inspect core dumps automatically. Ensure the operating system allows them to be written: 1. Set `ulimit -c unlimited` (you might need to adjust `/etc/security/limits.conf` to raise `soft core unlimited`). 2. Confirm `/proc/sys/kernel/core_pattern` is set to `core`. Systemd-based distributions often redirect cores elsewhere; revert to the classic format with `sudo bash -c 'echo core > /proc/sys/kernel/core_pattern'`. Avoid applying these tweaks on production hosts. rsyslog-8.2512.0/tests/PaxHeaders/override_gethostname_nonfqdn.c0000644000000000000000000000013215055605325022005 xustar0030 mtime=1756826325.657800804 30 atime=1764931119.715974779 30 ctime=1764935931.905710103 rsyslog-8.2512.0/tests/override_gethostname_nonfqdn.c0000664000175000017500000000037715055605325021460 0ustar00rgerrger#include int gethostname(char *name, size_t __attribute__((unused)) len) { *name++ = 'n'; *name++ = 'o'; *name++ = 'n'; *name++ = 'f'; *name++ = 'q'; *name++ = 'd'; *name++ = 'n'; *name++ = '\0'; return 0; } rsyslog-8.2512.0/tests/PaxHeaders/imfile-error-not-repeated.sh0000644000000000000000000000013015035412264021210 xustar0030 mtime=1752569012.391813284 29 atime=1764931165.82971727 29 ctime=1764935934.28674655 rsyslog-8.2512.0/tests/imfile-error-not-repeated.sh0000775000175000017500000000255015035412264020663 0ustar00rgerrger#!/bin/bash # add 2017-04-28 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1") template(name="tmpl1" type="string" string="%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) ' startup ./msleep 3000 echo 'testmessage1 testmessage2 testmessage3' > $RSYSLOG_DYNNAME.input ./msleep 2000 rm ./'$RSYSLOG_DYNNAME'.input ./msleep 3000 shutdown_when_empty wait_shutdown grep "file.*$RSYSLOG_DYNNAME.input.*No such file or directory" ${RSYSLOG2_OUT_LOG} > /dev/null if [ $? -ne 0 ]; then echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi if [ $(grep "No such file or directory" ${RSYSLOG2_OUT_LOG} | wc -l) -ne 1 ]; then echo "FAIL: expected error message is put out multiple times. ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi echo 'testmessage1 testmessage2 testmessage3' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_num2ipv4.sh0000644000000000000000000000013215035412264017463 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.650618178 30 ctime=1764935932.532719701 rsyslog-8.2512.0/tests/rscript_num2ipv4.sh0000775000175000017500000000270015035412264017131 0ustar00rgerrger#!/bin/bash # add 2017-02-09 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/fmhttp/.libs/fmhttp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!ip!v0 = num2ipv4(""); set $!ip!v1 = num2ipv4("0"); set $!ip!v2 = num2ipv4("1"); set $!ip!v3 = num2ipv4("256"); set $!ip!v4 = num2ipv4("65536"); set $!ip!v5 = num2ipv4("16777216"); set $!ip!v6 = num2ipv4("135"); set $!ip!v7 = num2ipv4("16843009"); set $!ip!v8 = num2ipv4("3777036554"); set $!ip!v9 = num2ipv4("2885681153"); set $!ip!v10 = num2ipv4("4294967295"); set $!ip!e1 = num2ipv4("a"); set $!ip!e2 = num2ipv4("-123"); set $!ip!e3 = num2ipv4("1725464567890"); set $!ip!e4 = num2ipv4("4294967296"); set $!ip!e5 = num2ipv4("2839."); template(name="outfmt" type="string" string="%!ip%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown echo '{ "v0": "0.0.0.0", "v1": "0.0.0.0", "v2": "0.0.0.1", "v3": "0.0.1.0", "v4": "0.1.0.0", "v5": "1.0.0.0", "v6": "0.0.0.135", "v7": "1.1.1.1", "v8": "225.33.1.10", "v9": "172.0.0.1", "v10": "255.255.255.255", "e1": "-1", "e2": "-1", "e3": "-1", "e4": "-1", "e5": "-1" }' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid function output detected, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/diskqueue-full.sh0000644000000000000000000000013215035412264017170 xustar0030 mtime=1752569012.386848027 30 atime=1764931159.153610202 30 ctime=1764935932.393717573 rsyslog-8.2512.0/tests/diskqueue-full.sh0000775000175000017500000000150115035412264016634 0ustar00rgerrger#!/bin/bash # checks that nothing bad happens if a DA (disk) queue runs out # of configured disk space # addd 2017-02-07 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.filename="mainq" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutenqueue="300000" queue.lowwatermark="5000" ) template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :omtesting:sleep 0 5000 :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 20000 ls -l ${RSYSLOG_DYNNAME}.spool shutdown_when_empty wait_shutdown ls -l ${RSYSLOG_DYNNAME}.spool seq_check 0 19999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/randomgen.c0000644000000000000000000000013215071746523016023 xustar0030 mtime=1760021843.904422027 30 atime=1764931157.537584264 30 ctime=1764935931.940710639 rsyslog-8.2512.0/tests/randomgen.c0000664000175000017500000000733115071746523015473 0ustar00rgerrger/* generates random data for later use in test cases. Of course, * we could generate random data during the testcase itself, but * the core idea is that we record the random data so that we have * a chance to reproduce a problem should it occur. IMHO this * provides the best compromise, by a) having randomness but * b) knowing what was used during the test. * * Params * -f output file name (stdout if not given) * -s size of test data, plain number is size in k, 1MB default * -u uses /dev/urandom instead of libc random number generator * (when available). Note that this is usually much slower. * * Part of the testbench for rsyslog. * * Copyright 2010-2016 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #define EXIT_FAILURE 1 static char *fileName = NULL; /* name of output file */ static int tryUseURandom = 0; /* try to use /dev/urandom? */ static long long fileSize = 1024 * 1024; /* file size in K, 1MB default */ /* generate the random file. This code really can be improved (e.g. read /dev/urandom * when available) */ static void genFile(void) { long i; FILE *fp; FILE *rfp = NULL; if (fileName == NULL) { fp = stdout; } else { if ((fp = fopen(fileName, "w")) == NULL) { perror(fileName); } } /* try to use /dev/urandom, if available */ if (tryUseURandom) rfp = fopen("/dev/urandom", "r"); if (rfp == NULL) { /* fallback, use libc random number generator */ for (i = 0; i < fileSize; ++i) { if (fputc((char)rand(), fp) == EOF) { perror(fileName); exit(1); } } } else { /* use /dev/urandom */ printf("using /dev/urandom"); for (i = 0; i < fileSize; ++i) { if (fputc(fgetc(rfp), fp) == EOF) { perror(fileName); exit(1); } } } if (fileName != NULL) fclose(fp); } /* Run the test. * rgerhards, 2009-04-03 */ int main(int argc, char *argv[]) { int ret = 0; int opt; srand(time(NULL)); /* seed is good enough for our needs */ while ((opt = getopt(argc, argv, "f:s:u")) != -1) { switch (opt) { case 'f': fileName = optarg; break; case 's': fileSize = atol(optarg) * 1024; break; case 'u': tryUseURandom = 1; break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit(1); break; } } printf("generating random data file '%s' of %ldkb - may take a short while...\n", fileName, (long)(fileSize / 1024)); genFile(); exit(ret); } rsyslog-8.2512.0/tests/PaxHeaders/dynfile_invld_async.sh0000644000000000000000000000013215055602574020263 xustar0030 mtime=1756824956.027451414 30 atime=1764931166.288724626 30 ctime=1764935934.430748755 rsyslog-8.2512.0/tests/dynfile_invld_async.sh0000775000175000017500000000367315055602574017743 0ustar00rgerrger#!/bin/bash # This test checks if omfile segfaults when a file open() in dynacache mode fails. # The test is mimiced after a real-life scenario (which, of course, was much more # complex). # # added 2010-03-09 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:3%\n" $template dynfile,"%msg:F,58:2%.log" # complete name is in message $OMFileFlushOnTXEnd on $OMFileAsyncWriting on $DynaFileCacheSize 4 local0.* ?dynfile;outfmt ' startup # we send handcrafted message. We have a dynafile cache of 4, and now send one message # each to fill up the cache. tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3\"" # the next one has caused a segfault in practice # note that /proc/rsyslog.error.file must not be creatable tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom\"" # some more writes tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7\"" # done message generation shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG seq_check 0 7 exit_test rsyslog-8.2512.0/tests/PaxHeaders/operatingstate-empty.sh0000644000000000000000000000013215035412264020416 xustar0030 mtime=1752569012.406709056 30 atime=1764931157.672586431 30 ctime=1764935931.977711206 rsyslog-8.2512.0/tests/operatingstate-empty.sh0000775000175000017500000000135715035412264020073 0ustar00rgerrger#!/bin/bash # added 2018-10-24 by Rainer Gerhards # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(operatingStateFile="'$RSYSLOG_DYNNAME.osf'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' # create an unclean file err_osf_content="" printf '%s' "$err_osf_content" > $RSYSLOG_DYNNAME.osf startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! check_file_exists "$RSYSLOG_DYNNAME.osf.previous" check_file_exists "$RSYSLOG_DYNNAME.osf" content_check "this may be an indication of a problem, e.g. empty file" "$RSYSLOG_OUT_LOG" content_check "CLEAN CLOSE" "$RSYSLOG_DYNNAME.osf" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-freshStartTail1.sh0000644000000000000000000000013215035412264020514 xustar0030 mtime=1752569012.391813284 30 atime=1764931166.009720155 30 ctime=1764935934.342747407 rsyslog-8.2512.0/tests/imfile-freshStartTail1.sh0000775000175000017500000000146015035412264020164 0ustar00rgerrger#!/bin/bash # add 2018-05-17 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" freshStartTail="on" Tag="pro" File="'$RSYSLOG_DYNNAME'.input") template(name="outfmt" type="string" string="%msg%\n") :syslogtag, contains, "pro" action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup echo '{ "id": "jinqiao1"}' > $RSYSLOG_DYNNAME.input ./msleep 2000 echo '{ "id": "jinqiao2"}' >> $RSYSLOG_DYNNAME.input shutdown_when_empty wait_shutdown echo '{ "id": "jinqiao1"} { "id": "jinqiao2"}' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_50_ipv6.sh0000644000000000000000000000013215055602574020034 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.339629233 30 ctime=1764935932.715722503 rsyslog-8.2512.0/tests/mmanon_zero_50_ipv6.sh0000775000175000017500000000240715055602574017506 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv6.bits="50" ipv6.anonmode="zero") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0 <129>Mar 10 01:00:00 172.20.245.8 tag: :: <129>Mar 10 01:00:00 172.20.245.8 tag: 0:: <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45: <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\"" shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk ffff:ffff:ffff:ffff:fffc:0:0:0 61:34:ad:0:0:0:0:0 aa:ff43:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 13:abd:45: textnoblank72:8374:adc7:47ff:0:0:0:0stillnoblank' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd-lb-2target-retry.sh0000644000000000000000000000013215055603742020456 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.537632409 30 ctime=1764935932.766723283 rsyslog-8.2512.0/tests/omfwd-lb-2target-retry.sh0000775000175000017500000000443015055603742020126 0ustar00rgerrger#!/bin/bash # added 2024-02-24 by rgerhards. Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf export NUMMESSAGES=10000 # MUST be an EVEN number! # starting minitcpsrvr receivers so that we can obtain their port # numbers start_minitcpsrvr $RSYSLOG_OUT_LOG 1 # regular startup add_conf ' $MainMsgQueueTimeoutShutdown 10000 $MainMsgQueueWorkerThreads 2 template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="builtin:omfwd" template="outfmt") if $msg contains "msgnum:" then { action(type="omfwd" target=["127.0.0.1", "127.0.0.1"] port=["'$MINITCPSRVR_PORT1'", "'$TCPFLOOD_PORT'"] protocol="tcp" pool.resumeInterval="1" action.resumeRetryCount="-1" action.resumeInterval="5") } ' startup # we need special logic. In a first iteration, the second target is offline # so everything is expected to go the the first target, only. injectmsg # combine both files to check for correct message content #cat "$RSYSLOG_OUT_LOG" "$RSYSLOG2_OUT_LOG" > "$SEQ_CHECK_FILE" wait_queueempty wait_file_lines cp "$RSYSLOG_OUT_LOG" tmp.log seq_check printf "\nSUCCESS for part 1 of the test\n\n" echo WARNING: The next part of this test is flacky, because there is an echo inevitable race on the port number for minitcpsrvr. If another echo parallel test has aquired it in the interim, this test here will echo invalidly fail. ./minitcpsrv -t127.0.0.1 -p $TCPFLOOD_PORT -f "$RSYSLOG2_OUT_LOG" \ -P "$RSYSLOG_DYNNAME.minitcpsrvr_port2" & # Note: we use the port file just to make sure minitcpsrvr has initialized! wait_file_exists "$RSYSLOG_DYNNAME.minitcpsrvr_port2" BGPROCESS=$! echo "### background minitcpsrv process id is $BGPROCESS port $TCPFLOOD_PORT ###" echo "waiting a bit to ensure rsyslog retries the currently suspended pool member" sleep 3 injectmsg $NUMMESSAGES $NUMMESSAGES shutdown_when_empty wait_shutdown if [ "$(wc -l < $RSYSLOG2_OUT_LOG)" != "$(( NUMMESSAGES / 2 ))" ]; then echo "ERROR: RSYSLOG2_OUT_LOG has invalid number of messages $(( NUMMESSAGES / 2 ))" cat -n $RSYSLOG2_OUT_LOG | head -10 error_exit 100 fi # combine both files to check for correct message content export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.log-combined" export NUMMESSAGES=$((NUMMESSAGES*2)) cat "$RSYSLOG_OUT_LOG" "$RSYSLOG2_OUT_LOG" > "$SEQ_CHECK_FILE" seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_str-num-vg.sh0000644000000000000000000000013115055602574021532 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.567616846 29 ctime=1764935932.51171938 rsyslog-8.2512.0/tests/rscript_compare_str-num-vg.sh0000775000175000017500000000020115055602574021173 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='"-"' export HIGHER_VAL='1' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-enhanced-validation.sh0000644000000000000000000000013115103346332022616 xustar0030 mtime=1762512090.634176013 30 atime=1764931158.254595773 29 ctime=1764935932.13871367 rsyslog-8.2512.0/tests/mmsnareparse-enhanced-validation.sh0000775000175000017500000001055015103346332022267 0ustar00rgerrger#!/bin/bash ## @file tests/mmsnareparse-enhanced-validation.sh ## @brief Validate enhanced parsing, validation, and stats for mmsnareparse. unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmsnareparse/.libs/mmsnareparse") template(name="validation_test_json" type="list" option.jsonf="on") { property(outname="eventid" name="$!win!Event!EventID" format="jsonf") property(outname="validation_errors" name="$!win!Validation!Errors" format="jsonf") property(outname="parsing_stats" name="$!win!Stats!ParsingStats" format="jsonf") property(outname="event_json" name="$!win" format="jsonf") } input(type="imtcp" port="'$TCPFLOOD_PORT'") action(type="mmsnareparse" rootpath="!win" validation_mode="strict" debugjson="on" template="validation_test_json") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="validation_test_json") ' startup tcpflood -m1 -M "\"<14>Jun 10 11:30:45 LAB-LOGON105 MSWinEventLog\t1\tSecurity\t10105\tMon Jun 10 11:30:45 2024\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\tLAB-LOGON105\tLogon\t\tAn account was successfully logged on. Subject: Security ID: SYSTEM Account Name: HOST-007\\$ Account Domain: WORKGROUP Logon ID: 0x3E7 Logon Information: Logon Type: 7 Restricted Admin Mode: - Remote Credential Guard: - Virtual Account: No Elevated Token: No Impersonation Level: Impersonation New Logon: Security ID: CLOUDDOMAIN\\User009 Account Name: user010@example.com Account Domain: CLOUDDOMAIN Logon ID: 0xFD5113F Linked Logon ID: 0xFD5112A Network Account Name: - Network Account Domain: - Logon GUID: {00000000-0000-0000-0000-000000000000} Process Information: Process ID: 0x30c Process Name: C:\\Windows\\System32\\lsass.exe Network Information: Workstation Name: HOST-007 Source Network Address: - Source Port: - Detailed Authentication Information: Logon Process: Negotiat Authentication Package: Negotiate Transited Services: - Package Name (NTLM only): - Key Length: 0\t1\"" shutdown_when_empty wait_shutdown python3 - "$RSYSLOG_OUT_LOG" <<'PY' import json import sys from pathlib import Path path = Path(sys.argv[1]) data = [] try: for line in path.read_text().splitlines(): line = line.strip() if not line: continue try: data.append(json.loads(line)) except json.JSONDecodeError as exc: raise SystemExit(f"failed to decode JSON line: {line}\n{exc}") except FileNotFoundError as exc: raise SystemExit(f"output log not found: {exc}") event = next((entry for entry in data if entry.get("eventid")), None) if event is None: raise SystemExit("no event record with an eventid was captured") try: stats = json.loads(event["parsing_stats"]) except (KeyError, json.JSONDecodeError) as exc: raise SystemExit(f"unable to parse parsing_stats payload: {exc}") try: errors = json.loads(event["validation_errors"]) except (KeyError, json.JSONDecodeError) as exc: raise SystemExit(f"unable to parse validation_errors payload: {exc}") if event["eventid"] != "4624": raise SystemExit(f"unexpected eventid: {event['eventid']}") if errors != []: raise SystemExit(f"expected no validation errors, got: {errors}") expected_stats = {"total_fields": 25, "successful_parses": 25, "failed_parses": 0} if stats != expected_stats: raise SystemExit(f"unexpected parsing stats: {stats}") try: event_root = json.loads(event["event_json"]) except (KeyError, json.JSONDecodeError) as exc: raise SystemExit(f"unable to parse event_json payload: {exc}") logon = event_root.get("Logon", {}) new_logon = event_root.get("NewLogon", {}) network = event_root.get("Network", {}) auth = event_root.get("Authentication", {}) placeholder_checks = [ (logon, "RemoteCredentialGuard", "Logon"), (new_logon, "NetworkAccountName", "NewLogon"), (new_logon, "NetworkAccountDomain", "NewLogon"), (network, "SourceNetworkAddress", "Network"), (network, "SourcePort", "Network"), (auth, "TransitedServices", "Authentication"), (auth, "PackageName", "Authentication"), ] for container_obj, field_name, container_name in placeholder_checks: if field_name in container_obj: raise SystemExit( f"placeholder field {container_name}.{field_name} should be absent but was present: {container_obj[field_name]}" ) PY exit_test rsyslog-8.2512.0/tests/PaxHeaders/action-tx-errfile.sh0000644000000000000000000000013215055602574017574 xustar0030 mtime=1756824956.025451386 30 atime=1764931164.517696239 30 ctime=1764935933.906740734 rsyslog-8.2512.0/tests/action-tx-errfile.sh0000775000175000017500000000230315055602574017241 0ustar00rgerrger#!/bin/bash # added by Rainer Gerhards 2018-01-05 # part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50 # sufficient for our needs! export SEQ_CHECK_OPTIONS=-i2 check_sql_data_ready() { mysql_get_data seq_check --check-only 0 $((NUMMESSAGES - 2)) } export QUEUE_EMPTY_CHECK_FUNC=check_sql_data_ready generate_conf add_conf ' $ModLoad ../plugins/ommysql/.libs/ommysql global(errormessagestostderr.maxnumber="5") template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on") if((not($msg contains "error")) and ($msg contains "msgnum:")) then { set $.num = field($msg, 58, 2); if $.num % 2 == 0 then { set $!facility = $syslogfacility; } else { set $/cntr = 0; } action(type="ommysql" name="mysql_action" server="127.0.0.1" template="tpl" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" action.errorfile="'$RSYSLOG2_OUT_LOG'") } ' mysql_prep_for_test startup injectmsg shutdown_when_empty wait_shutdown export EXPECTED="$(cat ${srcdir}/testsuites/action-tx-errfile.result)" cmp_exact ${RSYSLOG2_OUT_LOG} mysql_get_data seq_check 0 $((NUMMESSAGES - 2)) -i2 exit_test rsyslog-8.2512.0/tests/PaxHeaders/hostname-with-slash-pmrfc3164.sh0000644000000000000000000000013215035412264021553 xustar0030 mtime=1752569012.390820233 30 atime=1764931157.839589112 30 ctime=1764935932.022711894 rsyslog-8.2512.0/tests/hostname-with-slash-pmrfc3164.sh0000775000175000017500000000156715035412264021233 0ustar00rgerrger#!/bin/bash # addd 2016-07-11 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%hostname%\n") parser(name="pmrfc3164.hostname_with_slashes" type="pmrfc3164" permit.slashesinhostname="on") $rulesetparser pmrfc3164.hostname_with_slashes local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup echo '<167>Mar 6 16:57:54 hostname1/hostname2 test: msgnum:0' > $RSYSLOG_DYNNAME.input tcpflood -B -I $RSYSLOG_DYNNAME.input shutdown_when_empty wait_shutdown echo "hostname1/hostname2" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-wrong-template-option.sh0000644000000000000000000000013215035412264022633 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.440662935 30 ctime=1764935933.310731611 rsyslog-8.2512.0/tests/clickhouse-wrong-template-option.sh0000775000175000017500000000217415035412264022306 0ustar00rgerrger#!/bin/bash # add 2018-12-19 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" type="string" string="INSERT INTO rsyslog.template (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, ' add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" usehttps="off" bulkmode="off" user="default" pwd="" template="outfmt") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.template ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="DROP TABLE rsyslog.template" content_check "you have to specify the SQL or stdSQL option in your template!" exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-limited-batch.sh0000644000000000000000000000013115035412264021065 xustar0030 mtime=1752569012.385854976 29 atime=1764931162.41666255 30 ctime=1764935933.303731503 rsyslog-8.2512.0/tests/clickhouse-limited-batch.sh0000775000175000017500000000173515035412264020543 0ustar00rgerrger#!/bin/bash # add 2018-12-20 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100000 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.limited (id, ipaddress, message) VALUES (%msg:F,58:2%, ' add_conf "'%fromhost-ip%', '%msg:F,58:2%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" user="default" pwd="" template="outfmt" maxbytes="1k") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.limited ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="SELECT message FROM rsyslog.limited ORDER BY id" > $RSYSLOG_OUT_LOG clickhouse-client --query="DROP TABLE rsyslog.limited" seq_check 0 $(( NUMMESSAGES - 1 )) exit_test rsyslog-8.2512.0/tests/PaxHeaders/discard-allmark.sh0000644000000000000000000000013215035412264017263 xustar0030 mtime=1752569012.386848027 30 atime=1764931163.819685048 30 ctime=1764935933.706737672 rsyslog-8.2512.0/tests/discard-allmark.sh0000775000175000017500000000146615035412264016741 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 echo =============================================================================== echo \[discard-allmark.sh\]: testing discard-allmark functionality . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 10000 input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $ActionWriteAllMarkMessages on :msg, contains, "00000001" ~ $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup tcpflood -m10 -i1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 2 10 exit_test rsyslog-8.2512.0/tests/PaxHeaders/cfg1.cfgtest0000644000000000000000000000013215055602574016105 xustar0030 mtime=1756824956.026451401 30 atime=1764931158.711603108 30 ctime=1764935932.267715645 rsyslog-8.2512.0/tests/cfg1.cfgtest0000664000175000017500000000035215055602574015551 0ustar00rgerrgerrsyslogd: invalid or yet-unknown config file command - have you forgotten to load a module? [try https://www.rsyslog.com/e/3003 ] rsyslogd: the last error occurred in ./cfg1.testin, line 2 rsyslogd: End of config validation run. Bye. rsyslog-8.2512.0/tests/PaxHeaders/killrsyslog.sh0000644000000000000000000000013215035412264016607 xustar0030 mtime=1752569012.398764645 30 atime=1764931158.883605869 30 ctime=1764935932.316716395 rsyslog-8.2512.0/tests/killrsyslog.sh0000775000175000017500000000063315035412264016260 0ustar00rgerrger#!/bin/bash #check if rsyslog instance exists and, if so, kill it if [ -e "rsyslog.pid" ] then echo rsyslog.pid exists, trying to shut down rsyslogd process `cat rsyslog.pid`. kill -9 `cat rsyslog.pid` sleep 1 rm rsyslog.pid fi if [ -e "rsyslog2.pid" ] then echo rsyslog2.pid exists, trying to shut down rsyslogd process `cat rsyslog2.pid`. kill -9 `cat rsyslog2.pid` sleep 1 rm rsyslog2.pid fi rsyslog-8.2512.0/tests/PaxHeaders/manytcp.sh0000644000000000000000000000013215071746523015714 xustar0030 mtime=1760021843.894421869 30 atime=1764931163.367677801 30 ctime=1764935933.577735698 rsyslog-8.2512.0/tests/manytcp.sh0000775000175000017500000000216415071746523015366 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" skip_platform "SunOS" "timing on connection establishment is different on solaris and makes this test fail" skip_platform "Darwin" "Test fails on MacOS" export NUMMESSAGES=40000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' $MaxOpenFiles 2100 module(load="../plugins/imtcp/.libs/imtcp" maxSessions="2100") input(type="imtcp" name="test-input" socketBacklog="2000" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" workerthreads="8") $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup # we first send a single message so that the output file is opened. Otherwise, we may # use up all file handles for tcp connections and so the output file could eventually # not be opened. 2019-03-18 rgerhards tcpflood -m1 tcpflood -c-2000 -i1 -m $((NUMMESSAGES - 1 )) shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp-msg-truncation-on-number.sh0000644000000000000000000000013215071746523022405 xustar0030 mtime=1760021843.891421822 30 atime=1764931162.174658669 30 ctime=1764935933.236730478 rsyslog-8.2512.0/tests/imptcp-msg-truncation-on-number.sh0000775000175000017500000000276115071746523022062 0ustar00rgerrger#!/bin/bash # addd 2017-03-01 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "Darwin" "Test fails on MacOS 13, TCP chunking causes false octet-counting detection with sequence 9876543210" generate_conf add_conf ' $MaxMessageSize 128 global(processInternalMessages="on" oversizemsg.input.mode="accept") module(load="../plugins/imptcp/.libs/imptcp") input( type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" maxframesize="128") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab 9876543210 cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestetstetstetstetstetsstetstetsytetestetste\"" shutdown_when_empty wait_shutdown grep "Framing Error" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi grep " 9876543210cdefghijklmn test8 test9 test10 test11 test12 test13 test14 test15 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk tag: testtestets" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message from imptcp truncation not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/cfg4.cfgtest0000644000000000000000000000013215035412264016101 xustar0030 mtime=1752569012.384861924 30 atime=1764931158.768604023 30 ctime=1764935932.282715874 rsyslog-8.2512.0/tests/cfg4.cfgtest0000664000175000017500000000005515035412264015545 0ustar00rgerrgerrsyslogd: End of config validation run. Bye. rsyslog-8.2512.0/tests/PaxHeaders/imdtls-basic-timeout.sh0000644000000000000000000000013215055603742020275 xustar0030 mtime=1756825570.301069108 30 atime=1764931164.393694251 30 ctime=1764935933.871740198 rsyslog-8.2512.0/tests/imdtls-basic-timeout.sh0000775000175000017500000000331215055603742017743 0ustar00rgerrger#!/bin/bash # added 2023-10-05 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=2000 export SENDESSAGES=500 generate_conf export PORT_RCVR="$(get_free_port)" export TIMEOUT="5" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imdtls/.libs/imdtls" ) # tls.authmode="anon" ) input( type="imdtls" port="'$PORT_RCVR'" timeout="'$TIMEOUT'" ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase startup # valgrind --tool=helgrind $RS_TEST_VALGRIND_EXTRA_OPTS $RS_TESTBENCH_VALGRIND_EXTRA_OPTS --log-fd=1 --error-exitcode=10 ./tcpflood -b1 -W1000 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0 # ./msleep 500 ./tcpflood -b1 -W1000 -i500 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0 ./tcpflood -b1 -W1000 -i1000 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0 ./tcpflood -b1 -W1000 -i1500 -p$PORT_RCVR -m$SENDESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -L0 wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl-internalmsg_severity-info-shown.sh0000644000000000000000000000013215035412264023511 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.706586977 30 ctime=1764935931.987711359 rsyslog-8.2512.0/tests/glbl-internalmsg_severity-info-shown.sh0000775000175000017500000000111415035412264023155 0ustar00rgerrger#!/bin/bash # check that info-severity messages are actually emitted; we use # lookup table as a simple sample to get such a message. # addd 2019-05-07 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(internalmsg.severity="info") lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup shutdown_when_empty wait_shutdown content_check "lookup table 'xlate' loaded from file" exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse-find-json-invalid.sh0000644000000000000000000000013215103346332022076 xustar0030 mtime=1762512090.634176013 30 atime=1764931162.104657547 30 ctime=1764935933.217730187 rsyslog-8.2512.0/tests/mmjsonparse-find-json-invalid.sh0000775000175000017500000000226315103346332021550 0ustar00rgerrger#!/bin/bash # Test mmjsonparse find-json mode with invalid JSON # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmjsonparse/.libs/mmjsonparse") template(name="outfmt" type="string" string="%msg% parsesuccess=%parsesuccess% json=%$!%\n") # Test invalid JSON if $msg contains "INVALID" then { action(type="mmjsonparse" mode="find-json") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } # Test no JSON present if $msg contains "NOJSON" then { action(type="mmjsonparse" mode="find-json") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } ' startup injectmsg_literal '<167>Jan 16 16:57:54 host.example.net TAG: INVALID prefix {invalid json' injectmsg_literal '<167>Jan 16 16:57:54 host.example.net TAG: NOJSON just plain text without any json' shutdown_when_empty wait_shutdown export EXPECTED=' INVALID prefix {invalid json parsesuccess=FAIL json={ "msg": " INVALID prefix {invalid json" } NOJSON just plain text without any json parsesuccess=FAIL json={ "msg": " NOJSON just plain text without any json" }' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_8_ipv4.sh0000644000000000000000000000013215055602574017755 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.277628238 30 ctime=1764935932.694722181 rsyslog-8.2512.0/tests/mmanon_zero_8_ipv4.sh0000775000175000017500000000152315055602574017425 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.bits="8") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255 <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\"" shutdown_when_empty wait_shutdown export EXPECTED=' 1.1.1.0 0.0.0.0 172.0.234.0 111.1.1.0.' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-lokirest-retry-vg.sh0000644000000000000000000000013215035412264022232 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.069705088 30 ctime=1764935934.059743076 rsyslog-8.2512.0/tests/omhttp-batch-lokirest-retry-vg.sh0000775000175000017500000000013215035412264021675 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-batch-kafkarest-retry.sh rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-redis-start-after.sh0000644000000000000000000000013215055602574021553 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.975639437 30 ctime=1764935932.893725227 rsyslog-8.2512.0/tests/imhiredis-redis-start-after.sh0000775000175000017500000000217715055602574021231 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init # Start redis once to be able to generate configuration start_redis stop_redis generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mykey" mode="queue" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup start_redis redis_command "RPUSH mykey message1" redis_command "RPUSH mykey message2" redis_command "RPUSH mykey message3" wait_content '1 message3' shutdown_when_empty wait_shutdown stop_redis content_check '1 message3' content_check '2 message2' content_check '3 message1' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-basic-errfile-empty.sh0000644000000000000000000000013115071746523020510 xustar0029 mtime=1760021843.88242168 30 atime=1764931162.594665405 30 ctime=1764935933.352732253 rsyslog-8.2512.0/tests/es-basic-errfile-empty.sh0000775000175000017500000000171715071746523020166 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export ES_PORT=19200 export NUMMESSAGES=1500 # slow test, thus low number - large number is NOT necessary export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check ensure_elasticsearch_ready init_elasticsearch generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") :msg, contains, "msgnum:" action(type="omelasticsearch" template="tpl" serverport=`echo $ES_PORT` searchIndex="rsyslog_testbench" errorFile="./'${RSYSLOG_DYNNAME}.errorfile'") ' startup injectmsg shutdown_when_empty wait_shutdown es_getdata if [ -f ${RSYSLOG_DYNNAME}.errorfile ] then echo "error: error file exists!" error_exit 1 fi seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-endmsg.regex-with-example.sh0000644000000000000000000000013115055602574022472 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.926718824 29 ctime=1764935934.31874704 rsyslog-8.2512.0/tests/imfile-endmsg.regex-with-example.sh0000775000175000017500000001102715055602574022143 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # This test tests imfile endmsg.regex. . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify export IMFILECHECKTIMEOUT="60" export IMFILELASTINPUTLINES="6" mkdir $RSYSLOG_DYNNAME.statefiles generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imfile" statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles" File="./'$RSYSLOG_DYNNAME'.*.input" Tag="file:" addMetadata="on" escapelf="off" endmsg.regex="(^[^ ]+ (stdout|stderr) F )|(\\n\"}$)") if $msg startswith "{" then { action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.json.rulebase'") foreach ($.ii in $!multilinejson) do { if strlen($!@timestamp) == 0 then { set $!@timestamp = $.ii!time; } if strlen($!stream) == 0 then { set $!stream = $.ii!stream; } if strlen($!log) == 0 then { set $!log = $.ii!log; } else { reset $!log = $!log & $.ii!log; } } unset $!multilinejson; } else { action(type="mmnormalize" rulebase="'$srcdir/imfile-endmsg.regex.crio.rulebase'") foreach ($.ii in $!multilinecrio) do { if strlen($!@timestamp) == 0 then { set $!@timestamp = $.ii!time; } if strlen($!stream) == 0 then { set $!stream = $.ii!stream; } if strlen($!log) == 0 then { set $!log = $.ii!log; } else { reset $!log = $!log & $.ii!log; } } unset $!multilinecrio; } template(name="outfmt" type="list") { property(name="$!all-json-plain") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' if [ "${USE_VALGRIND:-false}" == "true" ] ; then startup_vg else startup fi if [ -n "${USE_GDB:-}" ] ; then echo attach gdb here sleep 54321 || : fi # write the beginning of the file echo 'date stdout P msgnum:0' > $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:0"}' > $RSYSLOG_DYNNAME.json.input echo 'date stdout F msgnum:1' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:1\n"}' >> $RSYSLOG_DYNNAME.json.input echo 'date stdout F msgnum:2' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:2\n"}' >> $RSYSLOG_DYNNAME.json.input # sleep a little to give rsyslog a chance to begin processing if [ -n "${USE_GDB:-}" ] ; then sleep 54321 || : else sleep 1 fi echo 'date stdout P msgnum:3' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:3"}' >> $RSYSLOG_DYNNAME.json.input echo 'date stdout P msgnum:4' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:4"}' >> $RSYSLOG_DYNNAME.json.input echo 'date stdout P msgnum:5' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:5"}' >> $RSYSLOG_DYNNAME.json.input # give it time to finish if [ -n "${USE_GDB:-}" ] ; then sleep 54321 || : else sleep 1 fi echo 'date stdout F msgnum:6' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:6\n"}' >> $RSYSLOG_DYNNAME.json.input echo 'date stdout P msgnum:7' >> $RSYSLOG_DYNNAME.crio.input echo '{"time":"date", "stream":"stdout", "log":"msgnum:7"}' >> $RSYSLOG_DYNNAME.json.input content_check_with_count "$RSYSLOG_DYNNAME" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT shutdown_when_empty # shut down rsyslogd when done processing messages if [ "${USE_VALGRIND:-false}" == "true" ] ; then wait_shutdown_vg check_exit_vg else wait_shutdown # we need to wait until rsyslogd is finished! fi # give it time to write the output file sleep 1 ## check if we have the correct number of messages NUMLINES=$(wc -l $RSYSLOG_OUT_LOG | awk '{print $1}' 2>/dev/null) rc=0 if [ ! $NUMLINES -eq $IMFILELASTINPUTLINES ]; then echo "ERROR: expecting $IMFILELASTINPUTLINES lines, got $NUMLINES" rc=1 fi ## check if all the data we expect to get in the file is there for string in "metadata.*filename.*json[.]input.*msgnum:0msgnum:1" \ "metadata.*filename.*crio[.]input.*msgnum:0msgnum:1" \ "metadata.*filename.*json[.]input.*msgnum:2" \ "metadata.*filename.*crio[.]input.*msgnum:2" \ "metadata.*filename.*json[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" \ "metadata.*filename.*crio[.]input.*msgnum:3msgnum:4msgnum:5msgnum:6" ; do if grep "$string" $RSYSLOG_OUT_LOG > /dev/null 2>&1 ; then : # ok else echo "Error: the expected string '$string' not found" rc=1 fi done if [ $rc -ne 0 ]; then cat $RSYSLOG_OUT_LOG exit 1 fi ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-endregex-timeout-polling.sh0000644000000000000000000000013215055602574022432 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.852717638 30 ctime=1764935934.295746688 rsyslog-8.2512.0/tests/imfile-endregex-timeout-polling.sh0000775000175000017500000000312015055602574022075 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init if [ $(uname) = "SunOS" ] ; then echo "Solaris: FIX ME" exit 77 fi mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="2" ) input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" PersistStateInterval="1" readTimeout="2" startmsg.regex="^[^ ]") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # we need to sleep a bit between writes to give imfile a chance # to pick up the data (IN MULTIPLE ITERATIONS!) echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input ./msleep 10000 echo ' msgnum:2 msgnum:3' >> $RSYSLOG_DYNNAME.input # the next line terminates our test. It is NOT written to the output file, # as imfile waits whether or not there is a follow-up line that it needs # to combine. echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input ./msleep 2000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo 'HEADER msgnum:0\\n msgnum:1 HEADER msgnum:2\\n msgnum:3' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-persist-state-1.sh0000644000000000000000000000013115035412264020440 xustar0030 mtime=1752569012.392806336 29 atime=1764931166.00072001 30 ctime=1764935934.340747377 rsyslog-8.2512.0/tests/imfile-persist-state-1.sh0000775000175000017500000000147215035412264020114 0ustar00rgerrger#!/bin/bash # added 2016-11-02 by rgerhards # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile") input( type="imfile" file="./'$RSYSLOG_DYNNAME'.input" tag="file:" startmsg.regex="^msgnum" PersistStateInterval="1" ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' # generate input file first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). ./inputfilegen -m5 -d4000 > $RSYSLOG_DYNNAME.input startup shutdown_when_empty wait_shutdown seq_check 0 3 exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_prog_confirm.sh0000644000000000000000000000013215035412264020272 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.581697265 30 ctime=1764935933.925741025 rsyslog-8.2512.0/tests/improg_prog_confirm.sh0000775000175000017500000000132215035412264017737 0ustar00rgerrger#!/bin/bash # add 2019-04-04 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/improg/.libs/improg") input(type="improg" tag="tag" ruleset="ruleset" binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -c -n 1" confirmmessages="on" signalonclose="off" killunresponsive="on" ) ruleset(name="ruleset") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'") } ' startup shutdown_when_empty wait_shutdown content_check "program data" if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then echo $RSYSLOG_DYNNAME'.stderr missing' error_exit 1 fi export EXPECTED='START Received ACK Received STOP Received' cmp_exact $RSYSLOG_DYNNAME.stderr exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd-errfile-maxsize-filled.sh0000644000000000000000000000013215055602574021715 xustar0030 mtime=1756824956.034451512 30 atime=1764931164.501695982 30 ctime=1764935933.901740657 rsyslog-8.2512.0/tests/omfwd-errfile-maxsize-filled.sh0000775000175000017500000000113115055602574021360 0ustar00rgerrger#!/bin/bash # part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ERRFILE="$RSYSLOG_DYNNAME.err" export MAX_ERROR_SIZE=1999 export INITIAL_FILE_SIZE=$((MAX_ERROR_SIZE - 100)) dd if=/dev/urandom of=${ERRFILE} bs=1 count=${INITIAL_FILE_SIZE} generate_conf add_conf ' action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist" action.errorfile="'$ERRFILE'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") ' startup shutdown_when_empty wait_shutdown check_file_exists ${ERRFILE} file_size_check ${ERRFILE} ${MAX_ERROR_SIZE} exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_gzip.sh0000644000000000000000000000013215055602574016570 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.367693834 30 ctime=1764935933.864740091 rsyslog-8.2512.0/tests/sndrcv_gzip.sh0000775000175000017500000000240215055602574016235 0ustar00rgerrger#!/bin/bash # This test is similar to tcpsndrcv, but it forwards messages in # zlib-compressed format (our own syslog extension). # rgerhards, 2009-11-11 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' # then SENDER sends to this port (not tcpflood!) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" export RCVR_PORT=$TCPFLOOD_PORT generate_conf 2 add_conf ' *.* @@(z5)127.0.0.1:'$RCVR_PORT' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-wildcards-dirs.sh0000644000000000000000000000013215055602574020416 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.061720988 30 ctime=1764935934.358747652 rsyslog-8.2512.0/tests/imfile-wildcards-dirs.sh0000775000175000017500000000335715055602574020075 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init export IMFILEINPUTFILES="10" export IMFILECHECKTIMEOUT="60" mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' /* Filter out busy debug output, comment out if needed */ global( debug.whitelist="off" debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"] ) global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module( load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*/*.logfile" Tag="file:" Severity="error" Facility="local7" addMetadata="on" ) template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value=", ") property(name="$!metadata!filename") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' # generate input files first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). # Start rsyslog now before adding more files startup for i in $(seq 1 $IMFILEINPUTFILES); do mkdir $RSYSLOG_DYNNAME.input.dir$i touch $RSYSLOG_DYNNAME.input.dir$i/file.logfile ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/file.logfile done ls -d $RSYSLOG_DYNNAME.input.* # Content check with timeout content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILES $IMFILECHECKTIMEOUT for i in $(seq 1 $IMFILEINPUTFILES); do rm -rf $RSYSLOG_DYNNAME.input.dir$i/ done shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! exit_test rsyslog-8.2512.0/tests/PaxHeaders/now-utc-casecmp.sh0000644000000000000000000000013115055602574017244 xustar0030 mtime=1756824956.034451512 29 atime=1764931161.55064866 30 ctime=1764935933.062727814 rsyslog-8.2512.0/tests/now-utc-casecmp.sh0000775000175000017500000000211015055602574016706 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # addd 2016-02-23 by RGerhards, released under ASL 2.0 # requires faketime echo \[now-utc-casecmp\]: test \$year-utc, \$month-utc, \$day-utc . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=TEST-02:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$Now%:%$Year%-%$Month%-%$Day%,%$Now-utc%:%$Year-utc%-%$Month-utc%-%$Day-utc%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' FAKETIME='2016-01-01 01:00:00' startup # what we send actually is irrelevant, as we just use system properties. # but we need to send one message in order to gain output! tcpflood -m1 shutdown_when_empty wait_shutdown echo "2016-01-01:2016-01-01,2015-12-31:2015-12-31" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid timestamps generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error-exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/complex1.sh0000644000000000000000000000013215055602574015770 xustar0030 mtime=1756824956.026451401 30 atime=1764931165.654714465 30 ctime=1764935934.234745754 rsyslog-8.2512.0/tests/complex1.sh0000775000175000017500000000771115055602574015445 0ustar00rgerrger#!/bin/bash # This is a rather complex test that runs a number of features together. # # added 2010-03-16 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on all flavors of Solaris." export NUMMESSAGES=40000 export RSYSLOG_PORT2="$(get_free_port)" export RSYSLOG_PORT3="$(get_free_port)" generate_conf echo ports: $TCPFLOOD_PORT $RSYSLOG_PORT2 $RSYSLOG_PORT3 add_conf ' $MaxMessageSize 10k $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 10000 $template outfmt,"%msg:F,58:3%,%msg:F,58:4%,%msg:F,58:5%\n" $template dynfile,"'$RSYSLOG_DYNNAME'.out.%inputname%.%msg:F,58:2%.log.Z" ## RULESET with listener $Ruleset R13514 # queue params: $ActionQueueTimeoutShutdown 60000 $ActionQueueTimeoutEnqueue 20000 $ActionQueueSize 5000 $ActionQueueSaveOnShutdown on $ActionQueueHighWaterMark 4900 $ActionQueueLowWaterMark 3500 $ActionQueueType FixedArray $ActionQueueWorkerThreads 1 # action params: $OMFileFlushOnTXEnd off $OMFileZipLevel 6 $DynaFileCacheSize 4 $omfileFlushInterval 1 *.* ?dynfile;outfmt action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile") # listener $InputTCPServerInputName '$TCPFLOOD_PORT' $InputTCPServerBindRuleset R13514 $InputTCPServerRun '$TCPFLOOD_PORT' ## RULESET with listener $Ruleset R_PORT2 # queue params: $ActionQueueTimeoutShutdown 60000 $ActionQueueTimeoutEnqueue 20000 $ActionQueueSize 5000 $ActionQueueSaveOnShutdown on $ActionQueueHighWaterMark 4900 $ActionQueueLowWaterMark 3500 $ActionQueueType FixedArray $ActionQueueWorkerThreads 1 # action params: $OMFileFlushOnTXEnd off $OMFileZipLevel 6 $OMFileIOBufferSize 256k $DynaFileCacheSize 4 $omfileFlushInterval 1 *.* ?dynfile;outfmt action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile") # listener $InputTCPServerInputName '$RSYSLOG_PORT2' $InputTCPServerBindRuleset R_PORT2 $InputTCPServerRun '$RSYSLOG_PORT2' ## RULESET with listener $Ruleset R_PORT3 # queue params: $ActionQueueTimeoutShutdown 60000 $ActionQueueTimeoutEnqueue 20000 $ActionQueueSize 5000 $ActionQueueSaveOnShutdown on $ActionQueueHighWaterMark 4900 $ActionQueueLowWaterMark 3500 $ActionQueueType FixedArray $ActionQueueWorkerThreads 1 # action params: $OMFileFlushOnTXEnd off $OMFileZipLevel 6 $OMFileIOBufferSize 256k $DynaFileCacheSize 4 $omfileFlushInterval 1 *.* ?dynfile;outfmt action(type="omfile" file ="'$RSYSLOG_DYNNAME'.countfile") # listener $InputTCPServerInputName '$RSYSLOG_PORT3' $InputTCPServerBindRuleset R_PORT3 $InputTCPServerRun '$RSYSLOG_PORT3' ' count_function() { # TODO: try to make this work on the compressed files, only # idea does not work as we miss end-of-zip record # leaving it commented out if we see we should really switch to that # method; if we do not need for an extended period of time, this shall # be removed -- rgerhards, 2018-12-19 #mkdir "$RSYSLOG_DYNNAME.countwrk" #cp $RSYSLOG_DYNNAME.out.*.log.Z "$RSYSLOG_DYNNAME.countwrk" #cd "$RSYSLOG_DYNNAME.countwrk" #gunzip $RSYSLOG_DYNNAME.out.*.log.Z #printf '%d' $(cat $RSYSLOG_DYNNAME.out.*.log | wc -l) #cd .. #rm -rf "$RSYSLOG_DYNNAME.countwrk" # now the real - simple - code: printf '%d' $(wc -l < $RSYSLOG_DYNNAME.countfile) } startup # send 40,000 messages of 400 bytes plus header max, via three dest ports export TCPFLOOD_PORT="$TCPFLOOD_PORT:$RSYSLOG_PORT2:$RSYSLOG_PORT3" tcpflood -m$NUMMESSAGES -rd400 -P129 -f5 -n3 -c15 -i1 # note: we have FlushOnTX=off, so we will not see the last block inside the file; # as such we wait until a "sufficiently large" number of messages has arrived and # hope that shutdown_when_empty gets us toward the rest. It's still a bit racy, # but should be better than without the wait_file_lines. wait_file_lines --delay 1000 --count-function count_function DUMMY-filename $((NUMMESSAGES - 1500)) shutdown_when_empty wait_shutdown ls $RSYSLOG_DYNNAME.out.*.log.Z gunzip $RSYSLOG_DYNNAME.out.*.log.Z cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG seq_check 1 $NUMMESSAGES -E exit_test rsyslog-8.2512.0/tests/PaxHeaders/uxsockrcvr.c0000644000000000000000000000013215114522477016260 xustar0030 mtime=1764926783.046632128 30 atime=1764926784.241661461 30 ctime=1764935931.949710777 rsyslog-8.2512.0/tests/uxsockrcvr.c0000664000175000017500000001673715114522477015742 0ustar00rgerrger/* receives messages from a specified unix sockets and writes * output to specfied file. * * Command line options: * -s name of socket (required) * -o name of output file (stdout if not given) * -l add newline after each message received (default: do not add anything) * -t timeout in seconds (default 60) * * Part of the testbench for rsyslog. * * Copyright 2010 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #include #include #include #if defined(_AIX) #include #include #include #include #else #include #endif #include #include #include #include #if defined(__FreeBSD__) #include #endif #define DFLT_TIMEOUT 60 char *sockName = NULL; int sockType = SOCK_DGRAM; int sockConnected = 0; int addNL = 0; int abstract; #define MAX_FDS 4 int sockBacklog = MAX_FDS - 1; struct pollfd fds[MAX_FDS]; int nfds; /* called to clean up on exit */ void cleanup(void) { int index; if (!abstract) unlink(sockName); for (index = 0; index < nfds; ++index) { close(fds[index].fd); } } void doTerm(int __attribute__((unused)) signum) { exit(1); } void usage(void) { fprintf(stderr, "usage: uxsockrcvr -s /socket/name -o /output/file -l\n" "-l adds newline after each message received\n" "-s MUST be specified\n" "-a Use abstract socket name\n" "-T {DGRAM|STREAM" #ifdef SOCK_SEQPACKET "|SEQPACKET" #endif /* def SOCK_SEQPACKET */ "} Set socket type (default DGRAM)\n" "if -o ist not specified, stdout is used\n"); exit(1); } static struct { const char *id; int val; int connected; } _sockType_map[] = { {"DGRAM", SOCK_DGRAM, 0}, {"STREAM", SOCK_STREAM, 1}, #ifdef SOCK_SEQPACKET {"SEQPACKET", SOCK_SEQPACKET, 1}, #endif /* def SOCK_SEQPACKET */ {NULL, 0, 0}, }; static void _decode_sockType(const char *s) { int index; for (index = 0; _sockType_map[index].id; ++index) { if (!strcasecmp(s, _sockType_map[index].id)) { sockType = _sockType_map[index].val; sockConnected = _sockType_map[index].connected; return; } } fprintf(stderr, "?Illegal socket type '%s'. Valid socket types:\n", s); for (index = 0; _sockType_map[index].id; ++index) { fprintf(stderr, " %s\n", _sockType_map[index].id); } exit(1); } int main(int argc, char *argv[]) { int opt; int rlen; int timeout = DFLT_TIMEOUT; FILE *fp = stdout; unsigned char data[128 * 1024]; struct sockaddr_un addr; /* address of server */ struct sockaddr from; socklen_t fromlen; int index; if (argc < 2) { fprintf(stderr, "error: too few arguments!\n"); usage(); } while ((opt = getopt(argc, argv, "as:o:lt:T:")) != EOF) { switch ((char)opt) { case 'a': abstract = 1; break; case 'l': addNL = 1; break; case 's': sockName = optarg; break; case 'o': if ((fp = fopen(optarg, "w")) == NULL) { perror(optarg); exit(1); } break; case 't': timeout = atoi(optarg); break; case 'T': _decode_sockType(optarg); break; default: usage(); } } timeout = timeout * 1000; if (sockName == NULL) { fprintf(stderr, "error: -s /socket/name must be specified!\n"); exit(1); } if (signal(SIGTERM, doTerm) == SIG_ERR) { perror("signal(SIGTERM, ...)"); exit(1); } if (signal(SIGINT, doTerm) == SIG_ERR) { perror("signal(SIGINT, ...)"); exit(1); } /* Create a UNIX datagram socket for server */ if ((fds[0].fd = socket(AF_UNIX, sockType, 0)) < 0) { perror("server: socket"); exit(1); } atexit(cleanup); /* Set up address structure for server socket */ memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path + abstract, sockName, sizeof(addr.sun_path) - abstract); /* * Abstract socket addresses do not require termination. */ if (!abstract && addr.sun_path[sizeof(addr.sun_path) - 1]) { addr.sun_path[sizeof(addr.sun_path) - 1] = 0; fprintf(stderr, "warning: socket path truncated: %s\n", addr.sun_path); } /* * For pathname addresses, the +1 is the terminating \0 character. * For abstract addresses, the +1 is the leading \0 character. */ if (bind(fds[0].fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + strlen(sockName) + 1) < 0) { perror("server: bind"); close(fds[0].fd); exit(1); } if (sockConnected && listen(fds[0].fd, sockBacklog) == -1) { perror("server: listen"); close(fds[0].fd); exit(1); } fds[0].events = POLLIN; nfds = 1; /* we now run in an endless loop. We do not check who sends us * data. This should be no problem for our testbench use. */ while (1) { rlen = poll(fds, nfds, timeout); if (rlen == -1) { perror("uxsockrcvr : poll\n"); exit(1); } else if (rlen == 0) { fprintf(stderr, "Socket timed out - nothing to receive\n"); exit(1); } if (sockConnected && fds[0].revents & POLLIN) { fds[nfds].fd = accept(fds[0].fd, NULL, NULL); fds[nfds].events = POLLIN; fds[nfds].revents = 0; if (fds[nfds].fd < 0) { perror("accept"); } else if (++nfds == MAX_FDS) { fds[0].events = 0; } } for (index = sockConnected; index < nfds; ++index) { if (fds[index].revents & POLLIN) { fromlen = sizeof(from); rlen = recvfrom(fds[index].fd, data, 2000, 0, &from, &fromlen); if (rlen == -1) { perror("uxsockrcvr : recv\n"); exit(1); } else { fwrite(data, 1, rlen, fp); if (addNL) fputc('\n', fp); } } if (fds[index].revents & POLLHUP) { close(fds[index].fd); fds[index].fd = -1; fds[index].events = 0; } } while (nfds && fds[nfds - 1].fd < 0) { --nfds; } } return 0; } rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_str-num.sh0000644000000000000000000000013215055602574021121 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.488615578 30 ctime=1764935932.490719058 rsyslog-8.2512.0/tests/rscript_compare_str-num.sh0000775000175000017500000000014715055602574020572 0ustar00rgerrger#!/bin/bash export LOWER_VAL='"-"' export HIGHER_VAL='1' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_is_time.sh0000644000000000000000000000013215035412264017430 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.754619846 30 ctime=1764935932.550719977 rsyslog-8.2512.0/tests/rscript_is_time.sh0000775000175000017500000000735415035412264017110 0ustar00rgerrger#!/bin/bash # Added 2017-12-16 by Stephen Workman, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omstdout/.libs/omstdout") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # $DebugLevel 2 set $!result!date_auto_1 = is_time("Oct 5 01:10:11"); set $!result!errno_date_auto_1 = script_error(); set $!result!date_auto_2 = is_time("2017-10-05T01:10:11Z"); set $!result!errno_date_auto_2 = script_error(); set $!result!date_auto_3 = is_time("2017-10-05T01:10:11-03:00"); set $!result!errno_date_auto_3 = script_error(); set $!result!date_auto_4 = is_time("90210"); set $!result!errno_date_auto_4 = script_error(); set $!result!date_explicit_1 = is_time("Oct 5 01:10:11", "date-rfc3164"); set $!result!errno_date_explicit_1 = script_error(); set $!result!date_explicit_2 = is_time("2017-10-05T01:10:11Z", "date-rfc3339"); set $!result!errno_date_explicit_2 = script_error(); set $!result!date_explicit_3 = is_time("2017-10-05T01:10:11+04:00", "date-rfc3339"); set $!result!errno_date_explicit_3 = script_error(); set $!result!date_explicit_4 = is_time(90210, "date-unix"); set $!result!errno_date_explicit_4 = script_error(); set $!result!date_explicit_5 = is_time(-88, "date-unix"); set $!result!errno_date_explicit_5 = script_error(); set $!result!date_explicit_6 = is_time(0, "date-unix"); set $!result!errno_date_explicit_6 = script_error(); set $!result!date_explicit_7 = is_time("90210", "date-unix"); set $!result!errno_date_explicit_7 = script_error(); set $!result!date_explicit_8 = is_time("-88", "date-unix"); set $!result!errno_date_explicit_8 = script_error(); # Bad dates set $!result!date_fail_1 = is_time("Oct 88 01:10:11"); set $!result!errno_date_fail_1 = script_error(); set $!result!date_fail_2 = is_time("not at all a date"); set $!result!errno_date_fail_2 = script_error(); # Wrong format set $!result!date_fail_3 = is_time("Oct 5 01:10:11", "date-rfc3339"); set $!result!errno_date_fail_3 = script_error(); set $!result!date_fail_4 = is_time("2017-10-05T01:10:11Z", "date-rfc3164"); set $!result!errno_date_fail_4 = script_error(); set $!result!date_fail_5 = is_time("Oct 5 01:10:11", "date-unix"); set $!result!errno_date_fail_5 = script_error(); # Invalid format set $!result!date_fail_6 = is_time("90210", "date-spoonix"); set $!result!errno_date_fail_6 = script_error(); template(name="outfmt" type="string" string="%!result%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") local4.* :omstdout:;outfmt ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown # Our fixed and calculated expected results export EXPECTED='{ "date_auto_1": 1, "errno_date_auto_1": 0, "date_auto_2": 1, "errno_date_auto_2": 0, "date_auto_3": 1, "errno_date_auto_3": 0, "date_auto_4": 1, "errno_date_auto_4": 0, "date_explicit_1": 1, "errno_date_explicit_1": 0, "date_explicit_2": 1, "errno_date_explicit_2": 0, "date_explicit_3": 1, "errno_date_explicit_3": 0, "date_explicit_4": 1, "errno_date_explicit_4": 0, "date_explicit_5": 1, "errno_date_explicit_5": 0, "date_explicit_6": 1, "errno_date_explicit_6": 0, "date_explicit_7": 1, "errno_date_explicit_7": 0, "date_explicit_8": 1, "errno_date_explicit_8": 0, "date_fail_1": 0, "errno_date_fail_1": 1, "date_fail_2": 0, "errno_date_fail_2": 1, "date_fail_3": 0, "errno_date_fail_3": 1, "date_fail_4": 0, "errno_date_fail_4": 1, "date_fail_5": 0, "errno_date_fail_5": 1, "date_fail_6": 0, "errno_date_fail_6": 1 }' # FreeBSD's cmp does not support reading from STDIN cmp <(echo "$EXPECTED") $RSYSLOG_OUT_LOG if [[ $? -ne 0 ]]; then printf "Invalid function output detected!\n" printf "Expected: $EXPECTED\n" printf "Got: " cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_non_object.sh0000644000000000000000000000013215055602574022206 xustar0030 mtime=1756824956.039451582 30 atime=1764931159.951623008 30 ctime=1764935932.602720773 rsyslog-8.2512.0/tests/rscript_unflatten_non_object.sh0000775000175000017500000000167715055602574021670 0ustar00rgerrger#!/bin/bash # added 2021-03-09 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init #export RSYSLOG_DEBUG="debug nostdout" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $/cpt = $/cpt + 1; if ($/cpt == 1) then set $! = "string"; else set $! = 42; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 2 wait_file_lines "$RSYSLOG_OUT_LOG" 2 60 shutdown_when_empty wait_shutdown EXPECTED=' msgnum:00000000: 0 string msgnum:00000001: 0 42' cmp_exact "$RSYSLOG_OUT_LOG" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-endregex-timeout-with-shutdown-polling.sh0000644000000000000000000000013215055602574025254 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.884718151 30 ctime=1764935934.305746841 rsyslog-8.2512.0/tests/imfile-endregex-timeout-with-shutdown-polling.sh0000775000175000017500000000324415055602574024726 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init export IMFILECHECKTIMEOUT="60" mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile" mode="polling" pollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" PersistStateInterval="1" readTimeout="3" startmsg.regex="^[^ ]") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # we need to sleep a bit between writes to give imfile a chance # to pick up the data (IN MULTIPLE ITERATIONS!) echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input content_check_with_count 'msgnum:0 msgnum:1' 1 $IMFILECHECKTIMEOUT echo ' msgnum:2 msgnum:3' >> $RSYSLOG_DYNNAME.input # we now do a stop and restart of rsyslog. This checks that everything # works across restarts. shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! #echo DROPPING YOU TO BASH! #bash startup # new data echo ' msgnum:4' >> $RSYSLOG_DYNNAME.input content_check_with_count 'msgnum:2 msgnum:3 msgnum:4' 1 $IMFILECHECKTIMEOUT echo ' msgnum:5 msgnum:6' >> $RSYSLOG_DYNNAME.input content_check_with_count 'msgnum:5 msgnum:6' 1 $IMFILECHECKTIMEOUT shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-pos-from-to-oversize.sh0000644000000000000000000000013215035412264022070 xustar0030 mtime=1752569012.416639571 30 atime=1764931161.365645693 30 ctime=1764935933.009727003 rsyslog-8.2512.0/tests/template-pos-from-to-oversize.sh0000775000175000017500000000265115035412264021543 0ustar00rgerrger#!/bin/bash # addd 2016-03-28 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo "*** string template ****" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="-%msg:109:116:%-\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 shutdown_when_empty wait_shutdown echo "--" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid output generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG echo "expected was:" echo "--" exit 1 fi; echo "*** list template ****" rm $RSYSLOG_OUT_LOG # cleanup previous run generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="list") { constant(value="-") property(name="msg" position.from="109" position.to="116") constant(value="-") constant(value="\n") } :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 shutdown_when_empty wait_shutdown echo "--" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid output generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG echo "expected was:" echo "--" exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-fileNotFoundError-parameter.sh0000644000000000000000000000013215035412264023060 xustar0030 mtime=1752569012.391813284 30 atime=1764931165.820717125 30 ctime=1764935934.283746504 rsyslog-8.2512.0/tests/imfile-fileNotFoundError-parameter.sh0000775000175000017500000000131315035412264022525 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 echo [imfile-file-not-found-error.sh] . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="testsuites/NotExistingInputFile" Tag="tag1" fileNotFoundError="off") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup shutdown_when_empty wait_shutdown grep "error*file*NotExistingInputFile*No such file or directory" $RSYSLOG_OUT_LOG > /dev/null if [ $? -eq 0 ]; then echo echo "FAIL: error message from missing input file found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh0000644000000000000000000000013115055602574023572 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.025672317 30 ctime=1764935933.478734182 rsyslog-8.2512.0/tests/imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh0000775000175000017500000000346215055602574023247 0ustar00rgerrger#!/bin/bash # This test checks imtcp functionality with multiple drivers running together. It is # a minimal test. # added 2021-04-27 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=60000 # must be evenly dividable by 3 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" name="i1" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" name="i2" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" name="i3" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" name="i3") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2" assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3" tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 3)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem tcpflood -p$TCPFLOOD_PORT2 -m$((NUMMESSAGES / 3)) -i$((NUMMESSAGES / 3)) tcpflood -p$RS_PORT -m$((NUMMESSAGES / 3)) -i$((NUMMESSAGES / 3 * 2)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_anon_rebind.sh0000644000000000000000000000013115055603742020754 xustar0030 mtime=1756825570.303069141 30 atime=1764931168.286756639 29 ctime=1764935935.00075748 rsyslog-8.2512.0/tests/sndrcv_tls_anon_rebind.sh0000775000175000017500000000424115055603742020425 0ustar00rgerrger#!/bin/bash # testing sending and receiving via TLS with anon auth and rebind # rgerhards, 2011-04-04 # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "Test fails with environment-induced errors, which we cannot solve" export NUMMESSAGES=25000 #25000 # uncomment for debugging support: # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="gtls" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config #export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="gtls" ) # set up the action $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon $ActionSendTCPRebindInterval 50 *.* @@127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 $NUMMESSAGES # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/omruleset-queue.sh0000644000000000000000000000013115055602574017400 xustar0029 mtime=1756824956.03645154 30 atime=1764931166.336725395 30 ctime=1764935934.444748969 rsyslog-8.2512.0/tests/omruleset-queue.sh0000775000175000017500000000272615055602574017057 0ustar00rgerrger#!/bin/bash # test for omruleset. What we do is have the main queue forward # all messages to a secondary ruleset via omruleset, which then does # the actual file write. We check if all messages arrive at the file, # what implies that omruleset works. No filters or special queue modes # are used, but the ruleset uses its own queue. So we can also inject # more messages without running into troubles. # added 2009-11-02 by rgerhards # This file is part of the rsyslog project, released under GPLv3 echo =============================================================================== echo \[omruleset-queue.sh\]: test for omruleset functionality with a ruleset queue uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init export NUMMESSAGES=20000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' $ModLoad ../plugins/omruleset/.libs/omruleset $ruleset rsinclude # create ruleset main queue with default parameters $RulesetCreateMainQueue on # make sure we do not terminate too early! $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt $ruleset RSYSLOG_DefaultRuleset $ActionOmrulesetRulesetName rsinclude *.* :omruleset: ' startup injectmsg echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_privdropgroup.sh0000644000000000000000000000013215055602574020730 xustar0030 mtime=1756824956.038451568 30 atime=1764931161.233643575 30 ctime=1764935932.968726375 rsyslog-8.2512.0/tests/rscript_privdropgroup.sh0000775000175000017500000000120015055602574020370 0ustar00rgerrger#!/bin/bash # added 2021-09-23 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.group.keepsupplemental="on" privdrop.group.name="'${TESTBENCH_TESTUSER[groupname]}'") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_exists-yes.sh0000644000000000000000000000013215055602574020123 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.842621259 30 ctime=1764935932.574720344 rsyslog-8.2512.0/tests/rscript_exists-yes.sh0000775000175000017500000000075415055602574017600 0ustar00rgerrger#!/bin/bash # add 2020-10-02 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%!result%\n") set $!p1!p2!val="yes!"; if $msg contains "msgnum" then { if exists($!p1!p2!val) then set $!result = "on"; else set $!result = "off"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='on' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript-config_enable-off-vg.sh0000644000000000000000000000013215035412264021652 xustar0030 mtime=1752569012.409688211 30 atime=1764931159.246611694 30 ctime=1764935932.419717972 rsyslog-8.2512.0/tests/rscript-config_enable-off-vg.sh0000775000175000017500000000100615035412264021316 0ustar00rgerrger#!/bin/bash # added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init export DO_STOP=off generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then { if $msg contains "msgnum:00000000" then { include(text="stop" config.enabled=`echo $DO_STOP`) } action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ' startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg seq_check 0 9 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmdb-container-empty.sh0000644000000000000000000000013215035412264020264 xustar0030 mtime=1752569012.400750748 30 atime=1764931162.290660529 30 ctime=1764935933.269730983 rsyslog-8.2512.0/tests/mmdb-container-empty.sh0000775000175000017500000000154215035412264017735 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$!src_geoip%\n") module(load="../plugins/mmdblookup/.libs/mmdblookup" container="!") module(load="../plugins/mmnormalize/.libs/mmnormalize") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmnormalize" rulebase=`echo $srcdir/mmdb.rb`) action(type="mmdblookup" mmdbfile=`echo $srcdir/test.mmdb` key="$!ip" fields=":src_geoip!city_name:city" ) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m 1 -j "202.106.0.20\ " shutdown_when_empty wait_shutdown content_check '{ "city_name": "Beijing" }' exit_test rsyslog-8.2512.0/tests/PaxHeaders/rs-cnum.sh0000644000000000000000000000013215035412264015615 xustar0030 mtime=1752569012.409688211 30 atime=1764931160.077625029 30 ctime=1764935932.635721278 rsyslog-8.2512.0/tests/rs-cnum.sh0000775000175000017500000000133415035412264015265 0ustar00rgerrger#!/bin/bash # add 2018-04-04 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!var = cnum(15*3); template(name="outfmt" type="string" string="-%$!var%-\n") :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" shutdown_when_empty wait_shutdown echo '-45-' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/execonlywhenprevsuspended.sh0000644000000000000000000000013115035412264021550 xustar0029 mtime=1752569012.38883413 30 atime=1764931166.359725763 30 ctime=1764935934.454749122 rsyslog-8.2512.0/tests/execonlywhenprevsuspended.sh0000775000175000017500000000163315035412264021223 0ustar00rgerrger#!/bin/bash # we test the execonly if previous is suspended directive. This is the # most basic test which solely tests a single case but no dependencies within # the ruleset. # rgerhards, 2010-06-23 echo ===================================================================================== echo \[execonlywhenprevsuspended.sh\]: test execonly...suspended functionality simple case . ${srcdir:=.}/diag.sh init generate_conf add_conf ' main_queue(queue.workerthreads="1") # omtesting provides the ability to cause "SUSPENDED" action state $ModLoad ../plugins/omtesting/.libs/omtesting $MainMsgQueueTimeoutShutdown 100000 $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" :omtesting:fail 2 0 $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"';outfmt ' startup injectmsg 0 1000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 1 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/gzipwr_flushInterval.sh0000644000000000000000000000013215035412264020461 xustar0030 mtime=1752569012.389827181 30 atime=1764931165.612713792 30 ctime=1764935934.222745571 rsyslog-8.2512.0/tests/gzipwr_flushInterval.sh0000775000175000017500000000165415035412264020136 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" export NUMMESSAGES=5000 #even number! export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.gz generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" zipLevel="6" ioBufferSize="256k" flushOnTXEnd="off" flushInterval="1" asyncWriting="on" file="'$RSYSLOG_OUT_LOG'.gz") ' startup tcpflood -m$((NUMMESSAGES / 2)) -P129 ./msleep 5000 #wait for flush seq_check 0 2499 tcpflood -i$((NUMMESSAGES / 2)) -m$((NUMMESSAGES / 2)) -P129 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/json_object_looping.sh0000644000000000000000000000013215035412264020257 xustar0030 mtime=1752569012.398764645 30 atime=1764931167.580745328 30 ctime=1764935934.797754372 rsyslog-8.2512.0/tests/json_object_looping.sh0000775000175000017500000000561115035412264017731 0ustar00rgerrger#!/bin/bash # added 2016-03-31 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[json_object_looping.sh\]: basic test for looping over json object / associative-array . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="garply" type="string" string="garply: %$.garply%\n") template(name="corge" type="string" string="corge: key: %$.corge!key% val: %$.corge!value%\n") template(name="prefixed_corge" type="string" string="prefixed_corge: %$.corge%\n") template(name="quux" type="string" string="quux: %$.quux%\n") template(name="modified" type="string" string="new: %$!foo!str4% deleted: %$!foo!str3%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse") set $.garply = ""; ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") { action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_corge" queue.type="linkedlist") } foreach ($.quux in $!foo) do { if ($.quux!key == "str2") then { set $.quux!random_key = $.quux!key; unset $!foo!str3; #because it is deep copied, the foreach loop will still see str3, but the "modified" action in the bottom will not set $!foo!str4 = "jkl3"; } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux") foreach ($.corge in $.quux!value) do { action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="corge" queue.type="linkedlist" action.copyMsg="on") call prefixed_writer foreach ($.grault in $.corge!value) do { if ($.garply != "") then set $.garply = $.garply & ", "; set $.garply = $.garply & $.grault!key & "=" & $.grault!value; } } } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="modified") ' startup tcpflood -m 1 -I $srcdir/testsuites/json_object_input echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check 'quux: { "key": "str1", "value": "abc0" }' content_check 'quux: { "key": "str2", "value": "def1", "random_key": "str2" }' content_check 'quux: { "key": "str3", "value": "ghi2" }' assert_content_missing 'quux: { "key": "str4", "value": "jkl3" }' content_check 'new: jkl3' assert_content_missing 'deleted: ghi2' content_check 'quux: { "key": "obj", "value": { "bar": { "k1": "important_msg", "k2": "other_msg" } } }' custom_content_check 'corge: key: bar val: { "k1": "important_msg", "k2": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log custom_content_check 'prefixed_corge: { "key": "bar", "value": { "k1": "important_msg", "k2": "other_msg" } }' $RSYSLOG_DYNNAME.out.prefixed.log content_check 'garply: k1=important_msg, k2=other_msg' exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_http_request.sh0000644000000000000000000000013215035412264020526 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.262611951 30 ctime=1764935932.424718048 rsyslog-8.2512.0/tests/rscript_http_request.sh0000775000175000017500000000272015035412264020176 0ustar00rgerrger#!/bin/bash # add 2017-12-01 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init rsyslog_testbench_test_url_access http://testbench.rsyslog.com/testbench/echo-get.php generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/fmhttp/.libs/fmhttp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # for debugging the test itself: #template(name="outfmt" type="string" string="%$!%: :%$.%: %rawmsg%\n") template(name="outfmt" type="string" string="%$!%\n") if $msg contains "msgnum:" then { set $.url = "http://testbench.rsyslog.com/testbench/echo-get.php?content=" & ltrim($msg); set $!reply = http_request($.url); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m10 wait_file_lines $RSYSLOG_OUT_LOG 10 200 shutdown_when_empty wait_shutdown # check for things that look like http failures if grep -q "DOCTYPE" "$RSYSLOG_OUT_LOG" ; then printf 'SKIP: looks like we have problems with the upstream http server:\n' cat -n "$RSYSLOG_OUT_LOG" printf '\n' error_exit 177 fi export EXPECTED='{ "reply": "msgnum:00000000:" } { "reply": "msgnum:00000001:" } { "reply": "msgnum:00000002:" } { "reply": "msgnum:00000003:" } { "reply": "msgnum:00000004:" } { "reply": "msgnum:00000005:" } { "reply": "msgnum:00000006:" } { "reply": "msgnum:00000007:" } { "reply": "msgnum:00000008:" } { "reply": "msgnum:00000009:" }' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile-module-params.sh0000644000000000000000000000013215035412264020250 xustar0030 mtime=1752569012.402736851 30 atime=1764931160.699635009 30 ctime=1764935932.813724003 rsyslog-8.2512.0/tests/omfile-module-params.sh0000775000175000017500000000101715035412264017716 0ustar00rgerrger#!/bin/bash # addd 2018-08-02 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 # we only check output fmt, so few messages are OK generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="../plugins/imtcp/.libs/imtcp") module(load="builtin:omfile" template="outfmt") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-fail-with-400.sh0000644000000000000000000000013215062756615021021 xustar0030 mtime=1758190989.236641616 30 atime=1764931164.835701337 30 ctime=1764935933.994742081 rsyslog-8.2512.0/tests/omhttp-batch-fail-with-400.sh0000775000175000017500000000272215062756615020473 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 omhttp_start_server 0 --fail-with-400-after 1000 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="500") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") # Wrap message as a single batch for retry template(name="tpl_retry" type="string" string="[%msg%]") ruleset(name="ruleset_omhttp") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="off" retry="on" # Configure retry codes - only retry 5xx server errors, not 4xx client errors # This fixes the bug where HTTP 400 errors were incorrectly retried httpretrycodes=["500", "502", "503", "504"] # Auth usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp ' startup injectmsg 0 $NUMMESSAGES shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint omhttp_stop_server # Test expects only the first 1000 messages to be processed successfully # Messages after 1000 get HTTP 400 errors and should NOT be retried seq_check $SEQ_CHECK_OPTIONS 0 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_rename_params.sh0000644000000000000000000000013215035412264023345 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.127593735 30 ctime=1764935932.103713134 rsyslog-8.2512.0/tests/imbatchreport_errmsg_rename_params.sh0000775000175000017500000000067415035412264023023 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" reports="*.done" rename=".done$ - ") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "'rename' must specify THREE parameters separated by spaces or tabs" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_conflict1-vg.sh0000644000000000000000000000013215055602574022362 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.998623762 30 ctime=1764935932.614720956 rsyslog-8.2512.0/tests/rscript_unflatten_conflict1-vg.sh0000775000175000017500000000013115055602574022024 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_conflict1.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_ruleset_call_indirect-invld.sh0000644000000000000000000000013215035412264023450 xustar0030 mtime=1752569012.412667365 30 atime=1764931162.028656328 30 ctime=1764935933.196729865 rsyslog-8.2512.0/tests/rscript_ruleset_call_indirect-invld.sh0000775000175000017500000000140415035412264023116 0ustar00rgerrger#!/bin/bash # added 2016-12-11 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" field.delimiter="58" field.number="2") constant(value="\n") } ruleset(name="rs") { action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt") } if $msg contains "msgnum" then call_indirect "does-not-exist"; else action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 5 shutdown_when_empty wait_shutdown grep "error.*does-not-exist" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/stats-prometheus.sh0000644000000000000000000000013215055605325017564 xustar0030 mtime=1756826325.658800819 30 atime=1764931167.337741435 30 ctime=1764935934.727753301 rsyslog-8.2512.0/tests/stats-prometheus.sh0000775000175000017500000000164615055605325017242 0ustar00rgerrger#!/bin/bash # added 2025-07-12 by Codex # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="prometheus") if ($msg == "this condition will never match") then { action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`) } ' startup injectmsg_file $srcdir/testsuites/dynstats_input_1 wait_queueempty wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown custom_content_check '# TYPE main Q_enqueued_total counter' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing '@cee' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/cee_diskqueue.sh0000644000000000000000000000013215035412264017044 xustar0030 mtime=1752569012.384861924 30 atime=1764931162.044656584 30 ctime=1764935933.201729942 rsyslog-8.2512.0/tests/cee_diskqueue.sh0000775000175000017500000000131415035412264016512 0ustar00rgerrger#!/bin/bash # check if CEE properties are properly saved & restored to/from disk queue # added 2012-09-19 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test probably does not work on all flavors of Solaris" export NUMMESSAGES=5000 generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") template(name="outfmt" type="string" string="%$!usr!msg:F,58:2%\n") set $!usr!msg = $msg; if $msg contains "msgnum" then action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt" queue.type="disk" queue.filename="rsyslog-act1") ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/uxsock_simple_abstract.sh0000644000000000000000000000013215114522477021007 xustar0030 mtime=1764926783.046632128 30 atime=1764926783.497643201 30 ctime=1764935934.155744545 rsyslog-8.2512.0/tests/uxsock_simple_abstract.sh0000775000175000017500000000310615114522477020456 0ustar00rgerrger#!/bin/bash # This tests basic omuxsock functionality. A socket receiver is started which sends # all data to an output file, then a rsyslog instance is started which generates # messages and sends them to the unix socket. Datagram sockets are being used. # added 2010-08-06 by Rgerhards # Updated 2025-04-16 for abstract sockets . ${srcdir:=.}/diag.sh init check_command_available timeout uname if [ $(uname) != "Linux" ] ; then echo "This test requires Linux (AF_UNIX abstract addresses)" exit 77 fi SOCKET_NAME="$RSYSLOG_DYNNAME-testbench-dgram-uxsock-abstract" # create the pipe and start a background process that copies data from # it to the "regular" work file generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 $template outfmt,"%msg:F,58:2%\n" module( load = "../plugins/omuxsock/.libs/omuxsock" template = "outfmt" ) :msg, contains, "msgnum:" action( type = "omuxsock" SocketName = "'$SOCKET_NAME'" abstract = "1" ) ' timeout 30s ./uxsockrcvr -a -s$SOCKET_NAME -o $RSYSLOG_OUT_LOG -t 60 & BGPROCESS=$! echo background uxsockrcvr process id is $BGPROCESS # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # wait for the cp process to finish, do pipe-specific cleanup echo shutting down uxsockrcvr... # TODO: we should do this more reliable in the long run! (message counter? timeout?) kill $BGPROCESS wait $BGPROCESS echo background process has terminated, continue test... # and continue the usual checks seq_check 0 9999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/chkseq.c0000644000000000000000000000013115055605325015322 xustar0030 mtime=1756826325.656800789 30 atime=1764931157.399582048 29 ctime=1764935931.91071018 rsyslog-8.2512.0/tests/chkseq.c0000664000175000017500000002044515055605325014774 0ustar00rgerrger/* Checks if a file consists of line of strictly monotonically * increasing numbers. An expected start and end number may * be set. * * Params * -f file to process, if not given stdin is processed. * -s -e * default for s is 0. -e should be given (else it is also 0) * -d may be specified, in which case duplicate messages are permitted. * -m number of messages permitted to be missing without triggering a * failure. This is necessary for some failover tests, where it is * impossible to totally guard against messagt loss. By default, NO * message is permitted to be lost. * -T anticipate truncation (which means specified payload length may be * more than actual payload (which may have been truncated) * -i increment between messages (default: 1). Can be used for tests which * intentionally leave consistent gaps in the message numbering. * * Part of the testbench for rsyslog. * * Copyright 2009-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #if defined(_AIX) #include #else #include #endif int main(int argc, char *argv[]) { FILE *fp; int val; int i; int ret = 0; int scanfOK; int verbose = 0; int bHaveExtraData = 0; int bAnticipateTruncation = 0; int dupsPermitted = 0; int start = 0, end = 0; int opt; int lostok = 0; /* how many messages are OK to be lost? */ int nDups = 0; int increment = 1; int reachedEOF; int edLen; /* length of extra data */ static char edBuf[500 * 1024]; /* buffer for extra data (pretty large to be on the save side...) */ static char ioBuf[sizeof(edBuf) + 1024]; char *file = NULL; while ((opt = getopt(argc, argv, "i:e:f:ds:vm:ET")) != EOF) { switch ((char)opt) { case 'f': file = optarg; break; case 'd': dupsPermitted = 1; break; case 'i': increment = atoi(optarg); break; case 'e': end = atoi(optarg); break; case 's': start = atoi(optarg); break; case 'v': ++verbose; break; case 'm': lostok = atoi(optarg); break; case 'E': bHaveExtraData = 1; break; case 'T': bAnticipateTruncation = 1; break; default: printf("Invalid call of chkseq, optchar='%c'\n", opt); printf("Usage: chkseq file -sstart -eend -d -E\n"); exit(1); } } if (start > end) { printf("start must be less than or equal end!\n"); exit(1); } if (verbose) { printf("chkseq: start %d, end %d\n", start, end); } /* read file */ if (file == NULL) { fp = stdin; } else { fp = fopen(file, "r"); } if (fp == NULL) { printf("error opening file '%s'\n", file); perror(file); exit(1); } for (i = start; i <= end; i += increment) { if (bHaveExtraData) { if (fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { scanfOK = 0; } else { scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val, &edLen, edBuf) == 3 ? 1 : 0; } if (edLen != (int)strlen(edBuf)) { if (bAnticipateTruncation == 1) { if (edLen < (int)strlen(edBuf)) { printf( "extra data length specified %d, but actually is %ld in" " record %d (truncation was anticipated, but payload should" " have been smaller than data-length, not larger)\n", edLen, (long)strlen(edBuf), i); exit(1); } } else { printf("extra data length specified %d, but actually is %ld in record %d\n", edLen, (long)strlen(edBuf), i); exit(1); } } } else { if (fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { scanfOK = 0; } else { scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0; } } if (!scanfOK) { printf("scanf error in index i=%d\n", i); exit(1); } while (val > i && lostok > 0) { --lostok; printf("message %d missing (ok due to -m [now %d])\n", i, lostok); ++i; } if (val != i) { if (val == i - increment && dupsPermitted) { --i; ++nDups; } else { printf("read value %d, but expected value %d\n", val, i); exit(1); } } } if (i - increment != end) { printf("lastrecord does not match. file: %d, expected %d\n", i - increment, end); exit(1); } int c = getc(fp); if (c == EOF) { reachedEOF = 1; } else { ungetc(c, fp); /* if duplicates are permitted, we need to do a final check if we have duplicates at the * end of file. */ if (dupsPermitted) { i = end; while (!feof(fp)) { if (bHaveExtraData) { if (fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { scanfOK = 0; } else { scanfOK = sscanf(ioBuf, "%d,%d,%s\n", &val, &edLen, edBuf) == 3 ? 1 : 0; } if (edLen != (int)strlen(edBuf)) { if (bAnticipateTruncation == 1) { if (edLen < (int)strlen(edBuf)) { printf( "extra data length specified %d, but " "actually is %ld in record %d (truncation was" " anticipated, but payload should have been " "smaller than data-length, not larger)\n", edLen, (long)strlen(edBuf), i); exit(1); } } else { printf( "extra data length specified %d, but actually " "is %ld in record %d\n", edLen, (long)strlen(edBuf), i); exit(1); } } } else { if (fgets(ioBuf, sizeof(ioBuf), fp) == NULL) { scanfOK = 0; } else { scanfOK = sscanf(ioBuf, "%d\n", &val) == 1 ? 1 : 0; } } if (val != i) { reachedEOF = 0; goto breakIF; } } reachedEOF = feof(fp) ? 1 : 0; } else { reachedEOF = 0; } } breakIF: if (nDups != 0) printf("info: had %d duplicates (this is no error)\n", nDups); if (!reachedEOF) { printf("end of processing, but NOT end of file! First line of extra data is:\n"); for (c = fgetc(fp); c != '\n' && c != EOF; c = fgetc(fp)) putchar(c); putchar('\n'); exit(1); } exit(ret); } rsyslog-8.2512.0/tests/PaxHeaders/imdocker-basic.sh0000644000000000000000000000013215055602574017114 xustar0030 mtime=1756824956.028451428 30 atime=1764931168.843765561 30 ctime=1764935935.155759852 rsyslog-8.2512.0/tests/imdocker-basic.sh0000775000175000017500000000202515055602574016562 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # imdocker unit tests are enabled with --enable-imdocker-tests . ${srcdir:=.}/diag.sh init NUMMESSAGES=1000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1) generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../contrib/imdocker/.libs/imdocker" ListContainersOptions="all=true" GetContainerLogOptions="timestamps=0&follow=1&stdout=1&stderr=0") if $!metadata!Names == "'$COOKIE'" then { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' # launch a docker runtime to generate some logs. docker run \ --name $COOKIE \ -e NUMMESSAGES=$NUMMESSAGES \ alpine \ /bin/sh -c 'for i in $(seq 0 $((NUMMESSAGES-1))); do echo "$i"; done' > /dev/null #export RS_REDIR=-d startup shutdown_when_empty wait_shutdown echo "cookie: $COOKIE, file name: $RSYSLOG_OUT_LOG" seq_check docker container rm $COOKIE exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse_simple.sh0000644000000000000000000000013115055602574020146 xustar0030 mtime=1756824956.033451498 29 atime=1764931162.13165798 30 ctime=1764935933.224730294 rsyslog-8.2512.0/tests/mmjsonparse_simple.sh0000775000175000017500000000137515055602574017624 0ustar00rgerrger#!/bin/bash # added 2014-07-15 by rgerhards # basic test for mmjsonparse module with defaults # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' template(name="outfmt" type="string" string="%$!msgnum%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse") if $parsesuccess == "OK" then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m $NUMMESSAGES -j "@cee: " shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-custom.sh0000644000000000000000000000013115103346332020233 xustar0030 mtime=1762512090.634176013 30 atime=1764931158.246595645 29 ctime=1764935932.13671364 rsyslog-8.2512.0/tests/mmsnareparse-custom.sh0000775000175000017500000000364515103346332017713 0ustar00rgerrger#!/bin/bash ## Validate custom pattern loading and section detection for mmsnareparse. unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init DEF_FILE="${RSYSLOG_DYNNAME}.defs.json" cat >"$DEF_FILE" <<'JSON' { "sections": [ { "pattern": "Custom Block*", "canonical": "CustomBlock", "behavior": "standard", "priority": 250, "sensitivity": "case_insensitive" } ], "fields": [ { "pattern": "CustomEventTag", "canonical": "CustomEventTag", "section": "EventData", "priority": 80, "value_type": "string" } ], "eventFields": [ { "event_id": 4001, "patterns": [ { "pattern": "WidgetID", "canonical": "WidgetID", "section": "CustomBlock", "value_type": "string" } ] } ], "events": [ { "event_id": 4001, "category": "Custom", "subtype": "Injected", "outcome": "success" } ] } JSON generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmsnareparse/.libs/mmsnareparse" \ definition.file="'${PWD}/${DEF_FILE}'" \ validation.mode="strict") template(name="customfmt" type="list") { property(name="$!win!Event!Category") constant(value=",") property(name="$!win!CustomBlock!WidgetID") constant(value=",") property(name="$!win!EventData!CustomEventTag") constant(value=",") property(name="$!win!Event!Outcome") constant(value="\n") } action(type="mmsnareparse") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="customfmt") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") ' startup assign_tcpflood_port "$RSYSLOG_DYNNAME.tcpflood_port" tcpflood -m 1 -I "${srcdir}/testsuites/mmsnareparse/sample-custom-pattern.data" shutdown_when_empty wait_shutdown content_check ',ZX-42,Demo,success' "$RSYSLOG_OUT_LOG" rm -f "$DEF_FILE" exit_test rsyslog-8.2512.0/tests/PaxHeaders/kafka-selftest.sh0000644000000000000000000000013215071746523017145 xustar0030 mtime=1760021843.892421838 30 atime=1764931166.743731917 30 ctime=1764935934.564750806 rsyslog-8.2512.0/tests/kafka-selftest.sh0000775000175000017500000000270315071746523016616 0ustar00rgerrger#!/bin/bash # added 2018-10-26 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init check_command_available kcat export KEEP_KAFKA_RUNNING="YES" export TESTMESSAGES=100000 export RANDTOPIC="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. #export EXTRA_EXITCHECK=dumpkafkalogs export EXTRA_EXIT=kafka download_kafka stop_zookeeper stop_kafka start_zookeeper start_kafka create_kafka_topic $RANDTOPIC '.dep_wrk' '22181' printf 'injecting messages via kcat\n' injectmsg_kcat # experimental: wait until kcat receives everything timeoutend=10 timecounter=0 printf 'receiving messages via kcat\n' while [ $timecounter -lt $timeoutend ]; do (( timecounter++ )) kcat -b 127.0.0.1:29092 -e -C -o beginning -t $RANDTOPIC -f '%s\n' > $RSYSLOG_OUT_LOG count=$(wc -l < ${RSYSLOG_OUT_LOG}) if [ $count -eq $TESTMESSAGES ]; then printf '**** wait-kafka-lines success, have %d lines ****\n\n' "$TESTMESSAGES" break else if [ "x$timecounter" == "x$timeoutend" ]; then echo wait-kafka-lines failed, expected $TESTMESSAGES got $count error_exit 1 else echo wait-file-lines not yet there, currently $count lines printf '\n' $TESTTOOL_DIR/msleep 1000 fi fi done unset count #end experimental delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181' sed -i 's/ msgnum://' "$RSYSLOG_OUT_LOG" seq_check 1 $TESTMESSAGES -d exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-invld-rulebase-vg.sh0000644000000000000000000000013215035412264022112 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.952655108 30 ctime=1764935933.175729544 rsyslog-8.2512.0/tests/pmnormalize-invld-rulebase-vg.sh0000775000175000017500000000022615035412264021561 0ustar00rgerrger#!/bin/bash # added 2019-04-10 by Rainer Gerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/pmnormalize-invld-rulebase.sh rsyslog-8.2512.0/tests/PaxHeaders/omfwd-errfile-maxsize.sh0000644000000000000000000000013215055602574020460 xustar0030 mtime=1756824956.034451512 30 atime=1764931164.492695838 30 ctime=1764935933.899740627 rsyslog-8.2512.0/tests/omfwd-errfile-maxsize.sh0000775000175000017500000000074215055602574020132 0ustar00rgerrger#!/bin/bash # part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export MAX_ERROR_SIZE=1999 generate_conf add_conf ' action(type="omfwd" target="1.2.3.4" port="1234" Protocol="tcp" NetworkNamespace="doesNotExist" action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") ' startup shutdown_when_empty wait_shutdown check_file_exists ${RSYSLOG2_OUT_LOG} file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE} exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_33_ipv4.sh0000644000000000000000000000013215055602574020033 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.270628126 30 ctime=1764935932.691722135 rsyslog-8.2512.0/tests/mmanon_zero_33_ipv4.sh0000775000175000017500000000214015055602574017477 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.bits="33") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255 <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\"" shutdown_when_empty wait_shutdown export EXPECTED=' 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0.' cmp_exact grep 'invalid number of ipv4.bits (33), corrected to 32' ${RSYSLOG2_OUT_LOG} > /dev/null if [ $? -ne 0 ]; then echo "invalid response generated, ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse-find-json-basic.sh0000644000000000000000000000013115103346332021530 xustar0030 mtime=1762512090.634176013 30 atime=1764931162.080657162 29 ctime=1764935933.21073008 rsyslog-8.2512.0/tests/mmjsonparse-find-json-basic.sh0000775000175000017500000000232015103346332021175 0ustar00rgerrger#!/bin/bash # Test mmjsonparse find-json mode basic functionality # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmjsonparse/.libs/mmjsonparse") template(name="outfmt" type="string" string="%msg% parsesuccess=%parsesuccess% json=%$!%\n") # Legacy cookie mode (default) - should NOT parse text with JSON if $msg contains "LEGACY" then { action(type="mmjsonparse") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } # Find-JSON mode - should parse text with embedded JSON if $msg contains "FINDJSON" then { action(type="mmjsonparse" mode="find-json") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } ' startup injectmsg_literal '<167>Jan 16 16:57:54 host.example.net TAG: LEGACY prefix {"field":"value"}' injectmsg_literal '<167>Jan 16 16:57:54 host.example.net TAG: FINDJSON prefix {"field":"value"}' shutdown_when_empty wait_shutdown export EXPECTED=' LEGACY prefix {"field":"value"} parsesuccess=FAIL json={ "msg": "LEGACY prefix {\"field\":\"value\"}" } FINDJSON prefix {"field":"value"} parsesuccess=OK json={ "field": "value" }' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_conflict3.sh0000644000000000000000000000013215055602574021752 xustar0030 mtime=1756824956.039451582 30 atime=1764931159.934622735 30 ctime=1764935932.597720696 rsyslog-8.2512.0/tests/rscript_unflatten_conflict3.sh0000775000175000017500000000237415055602574021427 0ustar00rgerrger#!/bin/bash # added 2021-03-09 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $!a!b = "foo"; set $!a.b = "bar"; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 1 wait_file_lines "$RSYSLOG_OUT_LOG" 1 60 shutdown_when_empty wait_shutdown # this test may need changes to produce a more deterministic # output by sorting keys EXPECTED=' msgnum:00000000: 0 { "a": { "b": "bar" } }' cmp_exact "$RSYSLOG_OUT_LOG" EXPECTED='fmunflatten.c: warning: while processing flat key "a.b" at depth #1 (final node), overriding existing value' if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then echo "GREP FAILED" echo " => FILE: $RSYSLOG_DEBUGLOG" echo " => EXPECTED: $EXPECTED" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse-find-json-invalid-mode.sh0000644000000000000000000000013215103346332023020 xustar0030 mtime=1762512090.634176013 30 atime=1764931162.114657707 30 ctime=1764935933.219730218 rsyslog-8.2512.0/tests/mmjsonparse-find-json-invalid-mode.sh0000775000175000017500000000102115103346332022461 0ustar00rgerrger#!/bin/bash # Test mmjsonparse invalid mode parameter error handling # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmjsonparse/.libs/mmjsonparse") template(name="outfmt" type="string" string="%msg%\n") action(type="mmjsonparse" mode="INVALID") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup shutdown_when_empty wait_shutdown content_check --regex "mmjsonparse: invalid mode 'INVALID'" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-getrequest-file.sh0000644000000000000000000000013215055602574020650 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.723699541 30 ctime=1764935933.963741606 rsyslog-8.2512.0/tests/imhttp-getrequest-file.sh0000775000175000017500000000101615055602574020315 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf IMHTTP_PORT="$(get_free_port)" add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../contrib/imhttp/.libs/imhttp" ports="'$IMHTTP_PORT'" documentroot="'$srcdir'/testsuites/docroot") ' startup curl -s http://localhost:$IMHTTP_PORT/file.txt > "$RSYSLOG_OUT_LOG" shutdown_when_empty echo "file name: $RSYSLOG_OUT_LOG" content_check "This is a test of get page" exit_test rsyslog-8.2512.0/tests/PaxHeaders/abort-uncleancfg-badcfg-check.sh0000644000000000000000000000013115035412264021721 xustar0030 mtime=1752569012.384861924 29 atime=1764931165.56271299 30 ctime=1764935934.207745341 rsyslog-8.2512.0/tests/abort-uncleancfg-badcfg-check.sh0000775000175000017500000000073015035412264021371 0ustar00rgerrger#!/bin/bash # Copyright 2015-01-29 by Tim Eifler # This file is part of the rsyslog project, released under ASL 2.0 # The configuration test should fail because of the invalid config file. . ${srcdir:=.}/diag.sh init ../tools/rsyslogd -C -N1 -f$srcdir/testsuites/abort-uncleancfg-badcfg.conf -M../runtime/.libs:../.libs if [ $? == 0 ]; then echo "Error: config check should fail" error_exit 1 fi printf 'unclean config lead to exit, as expected - OK\n' exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-rule_invld-data.sh0000644000000000000000000000013115035412264021635 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.903654323 29 ctime=1764935933.16172933 rsyslog-8.2512.0/tests/pmnormalize-rule_invld-data.sh0000775000175000017500000000201115035412264021277 0ustar00rgerrger#!/bin/bash # added 2019-04-10 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/pmnormalize/.libs/pmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") parser(name="custom.pmnormalize" type="pmnormalize" undefinedPropertyError="on" rule="rule=:<%pri:number%> %fromhost-ip:ipv4% %hostname:word% %syslogtag:char-to:\\x3a%: %msg:rest%") template(name="test" type="string" string="%msg%\n") ruleset(name="ruleset" parser="custom.pmnormalize") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="test") } action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsg") ' startup tcpflood -m1 -M "\" 127.0.0.1 ubuntu tag1: this is a test message\"" shutdown_when_empty wait_shutdown export EXPECTED=' 127.0.0.1 ubuntu tag1: this is a test message' cmp_exact content_check --regex "error .* during ln_normalize" $RSYSLOG_DYNNAME.othermsg exit_test rsyslog-8.2512.0/tests/PaxHeaders/msg-deadlock-headerless-noappname.sh0000644000000000000000000000013215035412264022654 xustar0030 mtime=1752569012.401743799 30 atime=1764931163.602681569 30 ctime=1764935933.646736754 rsyslog-8.2512.0/tests/msg-deadlock-headerless-noappname.sh0000775000175000017500000000115315035412264022323 0ustar00rgerrger#!/bin/bash # this checks against a situation where a deadlock was caused in # practice. # added 2018-10-17 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="input") ruleset(name="input") { set $!tag = $app-name; action(type="omfile" file="'$RSYSLOG_OUT_LOG'") } ' startup tcpflood -p $TCPFLOOD_PORT -M "[2018-10-16 09:59:13] ping pong" shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdropgroupid.sh0000644000000000000000000000013215055602574017477 xustar0030 mtime=1756824956.037451554 30 atime=1764931161.282644361 30 ctime=1764935932.983726605 rsyslog-8.2512.0/tests/privdropgroupid.sh0000775000175000017500000000115515055602574017150 0ustar00rgerrger#!/bin/bash # addd 2016-03-24 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.group.keepsupplemental="on") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) $PrivDropToGroupID '${TESTBENCH_TESTUSER[gid]}' ' #add_conf "\$PrivDropToGroupID ${TESTBENCH_TESTUSER[gid]}" startup shutdown_when_empty wait_shutdown content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/empty-hostname.sh0000644000000000000000000000013215035412264017203 xustar0030 mtime=1752569012.387841078 30 atime=1764931157.769587988 30 ctime=1764935932.003711604 rsyslog-8.2512.0/tests/empty-hostname.sh0000775000175000017500000000227715035412264016662 0ustar00rgerrger#!/bin/bash # This tests checks for a anomaly we have seen in practice: # gethostname() may return an empty string as hostname (""). This broke # some versions of rsyslog, newer ones return "localhost" in that case. # The test is done with the help of a preload library specifically written # for this purpose (liboverride_gethostname.so). It will override # gethostname() and return an empty string. Then, the test checks if the # hardcoded default of "localhost-empty-hostname" is used. # Note that the test may fail if the library is not properly preloaded. # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "AIX" "we cannot preload required dummy lib" generate_conf add_conf ' action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' export RSYSLOG_PRELOAD=.libs/liboverride_gethostname.so startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! grep " localhost-empty-hostname " < $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "expected hostname \"localhost-empty-hostname\" not found in logs, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp_spframingfix.sh0000644000000000000000000000013215035412264020122 xustar0030 mtime=1752569012.397771593 30 atime=1764931163.577681168 30 ctime=1764935933.639736647 rsyslog-8.2512.0/tests/imtcp_spframingfix.sh0000775000175000017500000000152615035412264017575 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 echo ==================================================================================== echo TEST: \[imptcp_spframingfix.sh\]: test imptcp in regard to Cisco ASA framing fix . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" framingfix.cisco.asa="on") template(name="outfmt" type="string" string="%rawmsg:6:7%\n") ruleset(name="remote") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -B -I ${srcdir}/testsuites/spframingfix.testdata shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate seq_check 0 19 exit_test rsyslog-8.2512.0/tests/PaxHeaders/fac_mail.sh0000644000000000000000000000013215055602574015773 xustar0030 mtime=1756824956.028451428 30 atime=1764931161.441646912 30 ctime=1764935933.030727324 rsyslog-8.2512.0/tests/fac_mail.sh0000775000175000017500000000115315055602574015442 0ustar00rgerrger#!/bin/bash # added 2014-09-17 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(type="string" name="outfmt" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") mail.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m$NUMMESSAGES -P 17 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-stop.sh0000644000000000000000000000013215035412264017345 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.371661828 30 ctime=1764935933.292731335 rsyslog-8.2512.0/tests/clickhouse-stop.sh0000775000175000017500000000132515035412264017015 0ustar00rgerrger#!/bin/bash # This is not a real test, but a script to stop clickhouse. It is # implemented as test so that we can stop clickhouse at the time we need # it (do so via Makefile.am). # Copyright (C) 2018 Pascal Withopf and Adiscon GmbH # Released under ASL 2.0 . ${srcdir:=.}/diag.sh init if [ "$CLICKHOUSE_STOP_CMD" == "" ]; then exit_test fi clickhouse-client --query="DROP DATABASE rsyslog" sleep 1 printf 'stopping clickhouse...\n' #$SUDO sed -n -r 's/PID: ([0-9]+\.*)/\1/p' /var/lib/clickhouse/status > /tmp/clickhouse-server.pid #$SUDO kill $($SUDO sed -n -r 's/PID: ([0-9]+\.*)/\1/p' /var/lib/clickhouse/status) eval $CLICKHOUSE_STOP_CMD sleep 1 # cosmetic: give clickhouse a chance to emit shutdown message exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_object-vg.sh0000644000000000000000000000013215055602574021746 xustar0030 mtime=1756824956.039451582 30 atime=1764931160.050624596 30 ctime=1764935932.628721171 rsyslog-8.2512.0/tests/rscript_unflatten_object-vg.sh0000775000175000017500000000012615055602574021414 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_object.sh rsyslog-8.2512.0/tests/PaxHeaders/omfwd-lb-1target-retry-1_byte_buf.sh0000644000000000000000000000013215055603742022472 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.478631463 30 ctime=1764935932.750723038 rsyslog-8.2512.0/tests/omfwd-lb-1target-retry-1_byte_buf.sh0000775000175000017500000000017115055603742022140 0ustar00rgerrger#!/bin/bash export OMFWD_IOBUF_SIZE=10 # triggers edge cases source ${srcdir:-.}/omfwd-lb-1target-retry-test_skeleton.sh rsyslog-8.2512.0/tests/PaxHeaders/omazureeventhubs-interrupt.sh0000644000000000000000000000013215055603742021676 xustar0030 mtime=1756825570.302069124 30 atime=1764931167.003736084 30 ctime=1764935934.636751908 rsyslog-8.2512.0/tests/omazureeventhubs-interrupt.sh0000775000175000017500000001261215055603742021347 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 echo This test must be run as root [raw socket access required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi . ${srcdir:=.}/diag.sh init # --- If test is needed, create helper script to store environment variables for # éventhubs access: # export AZURE_HOST="" # export AZURE_PORT="" # export AZURE_KEY_NAME="" # export AZURE_KEY="" # export AZURE_CONTAINER="" # --- source omazureeventhubs-env.sh export NUMMESSAGES=10000 export NUMMESSAGESFULL=$NUMMESSAGES export WAITTIMEOUT=60 export QUEUESIZE=100000 export DEQUEUESIZE=64 export DEQUEUESIZEMIN=32 export TESTWORKERTHREADS=3 export interrupt_host="$AZURE_HOST" export interrupt_port="$AZURE_PORT" export interrupt_tick="10" # REQUIRES EXTERNAL ENVIRONMENT VARIABLES if [[ -z "${AZURE_HOST}" ]]; then echo "SKIP: AZURE_HOST environment variable not SET! Example: .servicebus.windows.net - SKIPPING" exit 77 fi if [[ -z "${AZURE_PORT}" ]]; then echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY_NAME}" ]]; then echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY}" ]]; then echo "SKIP: AZURE_KEY environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_CONTAINER}" ]]; then echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: - SKIPPING" exit 77 fi export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME" export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME" # --- Create/Start omazureeventhubs sender config generate_conf add_conf ' global( # debug.whitelist="on" # debug.files=["omazureeventhubs.c", "modules.c", "errmsg.c", "action.c", "queue.c", "ruleset.c"] ) # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") $imdiagInjectDelayMode full # Load mods module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs") # templates template(name="outfmt" type="string" string="%msg:F,58:2%\n") local4.* { action( name="omazureeventhubs" type="omazureeventhubs" azurehost="'$AZURE_HOST'" azureport="'$AZURE_PORT'" azure_key_name="'$AZURE_KEY_NAME'" azure_key="'$AZURE_KEY'" container="'$AZURE_CONTAINER'" # amqp_address="amqps://'$AZURE_KEY_NAME':'$AZURE_KEY'@'$AZURE_HOST'/'$AZURE_NAME'" template="outfmt" queue.type="FixedArray" queue.size="'$QUEUESIZE'" queue.saveonshutdown="on" queue.dequeueBatchSize="'$DEQUEUESIZE'" queue.minDequeueBatchSize="'$DEQUEUESIZEMIN'" queue.minDequeueBatchSize.timeout="1000" # 1 sec queue.workerThreads="'$TESTWORKERTHREADS'" queue.workerThreadMinimumMessages="'$DEQUEUESIZEMIN'" queue.timeoutWorkerthreadShutdown="60000" queue.timeoutEnqueue="2000" queue.timeoutshutdown="1000" action.resumeInterval="1" action.resumeRetryCount="2" ) action( type="omfile" file="'$RSYSLOG_OUT_LOG'") stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") ' echo Starting sender instance [omazureeventhubs] startup echo Inject messages into rsyslog sender instance injectmsg 1 $NUMMESSAGES wait_file_lines --interrupt-connection $interrupt_host $interrupt_port $interrupt_tick $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100 timeoutend=$WAITTIMEOUT timecounter=0 lastcurrent_time=0 echo "CHECK $RSYSLOG_DYNNAME.pstats" while [ $timecounter -lt $timeoutend ]; do (( timecounter++ )) if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then # Read IMPSTATS for verification IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5) SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2) FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2) ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2) if ! [[ $SUBMITTED_MSG =~ $re ]] ; then echo "**** omazureeventhubs WAITING FOR IMPSTATS" else if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then if [ "$ACCEPTED_MSG" -ge "$NUMMESSAGESFULL" ]; then echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" shutdown_when_empty wait_shutdown #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log exit_test else echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" fi else echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" current_time=$(date +%s) if [ $interrupt_connection == "YES" ] && [ $current_time -gt $lastcurrent_time ] && [ $((current_time % $interrupt_tick)) -eq 0 ] && [ ${count} -gt 1 ]; then # Interrupt Connection - requires root and linux kernel >= 4.9 in order to work! echo "**** omazureeventhubs WAITING: Interrupt Connection on ${interrupt_host}:${interrupt_port}" sudo ss -K dst ${interrupt_host} dport = ${interrupt_port} fi lastcurrent_time=$current_time fi fi fi $TESTTOOL_DIR/msleep 1000 done unset count shutdown_when_empty wait_shutdown error_exit 1 rsyslog-8.2512.0/tests/PaxHeaders/timegenerated-dateordinal.sh0000644000000000000000000000013215055602574021341 xustar0030 mtime=1756824956.042451623 30 atime=1764931161.676650681 30 ctime=1764935933.098728365 rsyslog-8.2512.0/tests/timegenerated-dateordinal.sh0000775000175000017500000000722715055602574021020 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # addd 2016-03-02 by RGerhards, released under ASL 2.0 # Note: we run several subtests here in order to save us # from creating additional tests # requires faketime echo \[timegenerated-dateordinal\]: check valid dates with ordinal format . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=UTC+00:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%timegenerated:::date-ordinal%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' echo "***SUBTEST: check 1970-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='1970-01-01 00:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact echo "***SUBTEST: check 2000-03-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2000-03-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="061" cmp_exact echo "***SUBTEST: check 2016-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2016-01-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact echo "***SUBTEST: check 2016-02-29" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2016-02-29 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="060" cmp_exact echo "***SUBTEST: check 2016-03-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2016-03-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="061" cmp_exact echo "***SUBTEST: check 2016-03-03" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2016-03-03 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="063" cmp_exact echo "***SUBTEST: check 2016-12-31" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2016-12-31 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="366" cmp_exact echo "***SUBTEST: check 2017-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2017-01-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact echo "***SUBTEST: check 2020-03-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2020-03-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="061" cmp_exact echo "***SUBTEST: check 2038-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2038-01-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact rsyslog_testbench_require_y2k38_support echo "***SUBTEST: check 2038-12-31" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2038-12-31 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="365" cmp_exact echo "***SUBTEST: check 2040-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2040-01-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact echo "***SUBTEST: check 2040-12-31" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2040-12-31 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="366" cmp_exact echo "***SUBTEST: check 2100-01-01" rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest FAKETIME='2100-01-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="001" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-basic-ignorecodes-vg.sh0000644000000000000000000000013215055603742021541 xustar0030 mtime=1756825570.302069124 30 atime=1764931164.951703197 30 ctime=1764935934.025742555 rsyslog-8.2512.0/tests/omhttp-basic-ignorecodes-vg.sh0000775000175000017500000000012615055603742021207 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-basic-ignorecodes.sh rsyslog-8.2512.0/tests/PaxHeaders/imrelp-manyconn.sh0000644000000000000000000000013115035412264017340 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.035688512 30 ctime=1764935933.772738683 rsyslog-8.2512.0/tests/imrelp-manyconn.sh0000775000175000017500000000121115035412264017003 0ustar00rgerrger#!/bin/bash # adddd 2016-06-08 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" export NUMMESSAGES=100000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") input(type="imrelp" port="'$TCPFLOOD_PORT'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -Trelp-plain -c-2000 -p$TCPFLOOD_PORT -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table_no_hup_reload.sh0000644000000000000000000000013215035412264021607 xustar0030 mtime=1752569012.399757696 30 atime=1764931167.790748693 30 ctime=1764935934.857755291 rsyslog-8.2512.0/tests/lookup_table_no_hup_reload.sh0000775000175000017500000000176515035412264021267 0ustar00rgerrger#!/bin/bash # test for lookup-table with HUP based reloading disabled # added 2015-09-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="off") template(name="outfmt" type="string" string="- %msg% %$.lkp%\n") set $.lkp = lookup("xlate", $msg); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown assert_content_missing "foo_new" assert_content_missing "bar_new" assert_content_missing "baz" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_number_comparison_LE-vg.sh0000644000000000000000000000013215055602574022522 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.463615177 30 ctime=1764935932.482718936 rsyslog-8.2512.0/tests/rscript_number_comparison_LE-vg.sh0000775000175000017500000000013215055602574022165 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_number_comparison_LE.sh rsyslog-8.2512.0/tests/PaxHeaders/json-onempty-at-end.sh0000644000000000000000000000013215055602574020050 xustar0030 mtime=1756824956.032451484 30 atime=1764931161.315644891 30 ctime=1764935932.994726773 rsyslog-8.2512.0/tests/json-onempty-at-end.sh0000775000175000017500000000120515055602574017515 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # written 2019-05-10 by Rainer Gerhards . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="json" type="list" option.jsonf="on") { property(outname="empty_null" format="jsonf" name="$!empty" onEmpty="null") property(outname="empty_skip" format="jsonf" name="$!empty" onEmpty="skip") } set $!val0 = 0; set $!val = 42; set $!empty = ""; set $!string = "1.2.3.4"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="json") ' startup shutdown_when_empty wait_shutdown content_check '{"empty_null":null}' check_not_present 'empty_skip' exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdocker-basic-vg.sh0000644000000000000000000000013215035412264017517 xustar0030 mtime=1752569012.390820233 30 atime=1764931168.852765706 30 ctime=1764935935.157759883 rsyslog-8.2512.0/tests/imdocker-basic-vg.sh0000775000175000017500000000011415035412264017162 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/imdocker-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_kafka_multi_topics.sh0000644000000000000000000000013115071746523021467 xustar0029 mtime=1760021843.90842209 30 atime=1764931166.882734145 30 ctime=1764935934.604751418 rsyslog-8.2512.0/tests/sndrcv_kafka_multi_topics.sh0000775000175000017500000001137415071746523021145 0ustar00rgerrger#!/bin/bash # added 2018-08-13 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 : "${STARTUP_MAX_RUNTIME:=300}" export STARTUP_MAX_RUNTIME . ${srcdir:=.}/diag.sh init export TESTMESSAGES=50000 export TESTMESSAGESFULL=100000 # Generate random topic name export RANDTOPIC1="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" export RANDTOPIC2="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. export EXTRA_EXITCHECK=dumpkafkalogs export EXTRA_EXIT=kafka echo STEP: Check and Stop previous instances of kafka/zookeeper download_kafka stop_zookeeper stop_kafka echo STEP: Create kafka/zookeeper instance and topics start_zookeeper start_kafka create_kafka_topic $RANDTOPIC1 '.dep_wrk' '22181' create_kafka_topic $RANDTOPIC2 '.dep_wrk' '22181' # --- Create omkafka sender config export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") $imdiagInjectDelayMode full module(load="../plugins/omkafka/.libs/omkafka") template(name="outfmt" type="string" string="%msg%\n") local4.* action( name="kafka-fwd" type="omkafka" topic="'$RANDTOPIC1'" broker="localhost:29092" template="outfmt" confParam=[ "compression.codec=none", "socket.timeout.ms=10000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "queue.buffering.max.messages=10000", "enable.auto.commit=true", "message.send.max.retries=1"] topicConfParam=["message.timeout.ms=10000"] partitions.auto="on" closeTimeout="60000" resubmitOnFailure="on" keepFailedMessages="on" failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC1'.data" action.resumeInterval="1" action.resumeRetryCount="10" queue.saveonshutdown="on" ) local4.* action( name="kafka-fwd-2" type="omkafka" topic="'$RANDTOPIC2'" broker="localhost:29092" template="outfmt" confParam=[ "compression.codec=none", "socket.timeout.ms=10000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "queue.buffering.max.messages=10000", "enable.auto.commit=true", "message.send.max.retries=1"] topicConfParam=["message.timeout.ms=10000"] partitions.auto="on" closeTimeout="60000" resubmitOnFailure="on" keepFailedMessages="on" failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC2'.data" action.resumeInterval="1" action.resumeRetryCount="10" queue.saveonshutdown="on" ) syslog.* action(type="omfile" file="'$RSYSLOG_DYNNAME.sender.syslog'") ' echo STEP: Starting sender instance [omkafka] startup # --- # Injection messages now before starting receiver, simply because omkafka will take some time and # there is no reason to wait for the receiver to startup first. echo STEP: Inject messages into rsyslog sender instance injectmsg 1 $TESTMESSAGES # --- Create omkafka receiver config export RSYSLOG_DEBUGLOG="log2" generate_conf 2 add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") module(load="../plugins/imkafka/.libs/imkafka") /* Polls messages from kafka server!*/ input( type="imkafka" topic="'$RANDTOPIC1'" broker="localhost:29092" consumergroup="default1" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=10000", "enable.partition.eof=false", "reconnect.backoff.jitter.ms=1000", "socket.keepalive.enable=true"] ) input( type="imkafka" topic="'$RANDTOPIC2'" broker="localhost:29092" consumergroup="default2" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=10000", "enable.partition.eof=false", "reconnect.backoff.jitter.ms=1000", "socket.keepalive.enable=true"] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if ($msg contains "msgnum:") then { action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) } syslog.* action(type="omfile" file="'$RSYSLOG_DYNNAME.receiver.syslog'") ' 2 echo STEP: Starting receiver instance [imkafka] startup 2 # --- echo STEP: Stopping sender instance [omkafka] shutdown_when_empty wait_shutdown echo STEP: Stopping receiver instance [imkafka] kafka_wait_group_coordinator shutdown_when_empty 2 wait_shutdown 2 echo STEP: delete kafka topics delete_kafka_topic $RANDTOPIC1 '.dep_wrk' '22181' delete_kafka_topic $RANDTOPIC2 '.dep_wrk' '22181' kafka_check_broken_broker "$RSYSLOG_DYNNAME.sender.syslog" kafka_check_broken_broker "$RSYSLOG_DYNNAME.receiver.syslog" # Dump Kafka log | uncomment if needed # dump_kafka_serverlog # Do the final sequence check seq_check 1 $TESTMESSAGES -d linecount=$(wc -l < ${RSYSLOG_OUT_LOG}) if [ $linecount -ge $TESTMESSAGESFULL ]; then echo "Info: Count correct: $linecount" else echo "Count error detected in $RSYSLOG_OUT_LOG" echo "number of lines in file: $linecount" error_exit 1 fi echo success exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdocker-new-logs-from-start-vg.sh0000644000000000000000000000013215035412264022265 xustar0030 mtime=1752569012.390820233 30 atime=1764931168.885766234 30 ctime=1764935935.166760021 rsyslog-8.2512.0/tests/imdocker-new-logs-from-start-vg.sh0000775000175000017500000000013215035412264021730 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/imdocker-new-logs-from-start.sh rsyslog-8.2512.0/tests/PaxHeaders/imtuxedoulog_errmsg_no_params.sh0000644000000000000000000000013215035412264022374 xustar0030 mtime=1752569012.397771593 30 atime=1764931157.987591488 30 ctime=1764935932.064712537 rsyslog-8.2512.0/tests/imtuxedoulog_errmsg_no_params.sh0000775000175000017500000000057315035412264022050 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imtuxedoulog/.libs/imtuxedoulog") input(type="imtuxedoulog") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "parameter 'ulogbase' required but not specified" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-retry-timeout-vg.sh0000644000000000000000000000013215055603742021012 xustar0030 mtime=1756825570.302069124 30 atime=1764931164.968703469 30 ctime=1764935934.030742632 rsyslog-8.2512.0/tests/omhttp-retry-timeout-vg.sh0000775000175000017500000000012215055603742020454 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-retry-timeout.sh rsyslog-8.2512.0/tests/PaxHeaders/msgdup.sh0000644000000000000000000000013215055602574015537 xustar0030 mtime=1756824956.033451498 30 atime=1764931162.750667907 30 ctime=1764935933.395732912 rsyslog-8.2512.0/tests/msgdup.sh0000775000175000017500000000240615055602574015210 0ustar00rgerrger#!/bin/bash # This tests the border case that a message is exactly as large as the default # buffer size (101 chars) and is reduced in size afterwards. This has been seen # in practice. # see also https://github.com/rsyslog/rsyslog/issues/1658 # Copyright (C) 2017 by Rainer Gerhards, released under ASL 2.0 (2017-07-11) . ${srcdir:=.}/diag.sh init check_logger_has_option_d generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg%\n") ruleset(name="rs" queue.type="LinkedList") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } *.=notice call rs ' startup logger -d -u $RSYSLOG_DYNNAME-testbench_socket -t RSYSLOG_TESTBENCH 'test 01234567890123456789012345678901234567890123456789012345 ' #Note: LF at end of message is IMPORTANT, it is bug triggering condition # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! export EXPECTED=" test 01234567890123456789012345678901234567890123456789012345" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/incltest_dir.sh0000644000000000000000000000013115035412264016713 xustar0030 mtime=1752569012.397771593 30 atime=1764931162.314660914 29 ctime=1764935933.27673109 rsyslog-8.2512.0/tests/incltest_dir.sh0000775000175000017500000000103515035412264016362 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf env|grep src echo ac_top_srcdir: $ac_top_srcdir echo FULL ENV: env echo FS info: set -x pwd echo "srcdir: $srcdir" ls -l ${srcdir}/testsuites/incltest.d/ ls -l ${srcdir}/testsuites find ../../../.. -name incltest.d set +x add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/ " startup # 100 messages are enough - the question is if the include is read ;) injectmsg 0 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-maxbytes-bulk.sh0000644000000000000000000000013215071746523017435 xustar0030 mtime=1760021843.887421759 30 atime=1764931162.699667089 30 ctime=1764935933.380732682 rsyslog-8.2512.0/tests/es-maxbytes-bulk.sh0000775000175000017500000000152215071746523017104 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export ES_PORT=19200 export NUMMESSAGES=10000 export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check ensure_elasticsearch_ready init_elasticsearch generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") :msg, contains, "msgnum:" action(type="omelasticsearch" template="tpl" serverport="'$ES_PORT'" searchIndex="rsyslog_testbench" bulkmode="on" maxbytes="1k") ' startup injectmsg shutdown_when_empty wait_shutdown es_getdata $NUMMESSAGES $ES_PORT seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omrabbitmq_data_1server-vg.sh0000644000000000000000000000013215035412264021440 xustar0030 mtime=1752569012.405716005 30 atime=1764931160.859637576 30 ctime=1764935932.859724707 rsyslog-8.2512.0/tests/omrabbitmq_data_1server-vg.sh0000775000175000017500000000022115035412264021102 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/omrabbitmq_data_1server.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_b64_decode-vg.sh0000644000000000000000000000013215071746523020317 xustar0030 mtime=1760021843.904422027 30 atime=1764931159.304612625 30 ctime=1764935932.436718232 rsyslog-8.2512.0/tests/rscript_b64_decode-vg.sh0000775000175000017500000000034315071746523017766 0ustar00rgerrger#!/bin/bash # test for b64_decode function in rainerscript # added 2024-06-11 by KGuillemot # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_b64_decode.sh rsyslog-8.2512.0/tests/PaxHeaders/test_id_usage_output.sh0000644000000000000000000000013215035412264020470 xustar0030 mtime=1752569012.416639571 30 atime=1764931160.220627323 30 ctime=1764935932.678721936 rsyslog-8.2512.0/tests/test_id_usage_output.sh0000775000175000017500000000042315035412264020136 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./test_id &> $RSYSLOG_DYNNAME.output grep "usage: test_id" $RSYSLOG_DYNNAME.output if [ ! $? -eq 0 ]; then echo "invalid response generated" error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_ccmiddle_syssock.sh0000644000000000000000000000013215055602574021504 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.606729722 30 ctime=1764935934.525750209 rsyslog-8.2512.0/tests/imuxsock_ccmiddle_syssock.sh0000775000175000017500000000165715055602574021164 0ustar00rgerrger#!/bin/bash # test trailing LF handling in imuxsock # part of rsyslog, released under ASL 2.0 . ${srcdir:=.}/diag.sh init uname if [ $(uname) = "SunOS" ] ; then echo "Solaris: FIX ME" exit 77 fi ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # send a message with trailing LF ./syslog_caller -fsyslog_inject-c -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" shutdown_when_empty wait_shutdown export EXPECTED=" test 1#0112" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-dflt-tpl.sh0000644000000000000000000000013215071746523020116 xustar0030 mtime=1760021843.879421633 30 atime=1764931162.346661428 30 ctime=1764935933.285731228 rsyslog-8.2512.0/tests/clickhouse-dflt-tpl.sh0000775000175000017500000000155515071746523017573 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" bulkmode="off" user="default" pwd="") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.SystemEvents ( severity Int8, facility Int8, timestamp DateTime, hostname String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity order by tuple()" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="SELECT * FROM rsyslog.SystemEvents FORMAT CSV" > $RSYSLOG_OUT_LOG clickhouse-client --query="DROP TABLE rsyslog.SystemEvents" content_check --regex '7,20,"20..-03-01 01:00:00","192.0.2.8","tag"," msgnum:00000000:"' exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-neither_rule_rulebase-vg.sh0000644000000000000000000000013115035412264023544 xustar0030 mtime=1752569012.407702108 29 atime=1764931161.94465498 30 ctime=1764935933.173729514 rsyslog-8.2512.0/tests/pmnormalize-neither_rule_rulebase-vg.sh0000775000175000017500000000023515035412264023214 0ustar00rgerrger#!/bin/bash # added 2019-04-10 by Rainer Gerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/pmnormalize-neither_rule_rulebase.sh rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-kafkarest-retry-vg.sh0000644000000000000000000000013015035412264022347 xustar0030 mtime=1752569012.404722953 29 atime=1764931165.06170496 29 ctime=1764935934.05674303 rsyslog-8.2512.0/tests/omhttp-batch-kafkarest-retry-vg.sh0000775000175000017500000000013215035412264022014 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-batch-kafkarest-retry.sh rsyslog-8.2512.0/tests/PaxHeaders/omprog-single-instance-vg.sh0000644000000000000000000000013115055602574021235 xustar0029 mtime=1756824956.03645154 30 atime=1764931165.236707765 30 ctime=1764935934.109743841 rsyslog-8.2512.0/tests/omprog-single-instance-vg.sh0000775000175000017500000000021315055602574020701 0ustar00rgerrger#!/bin/bash # addd 2019-04-15 by RGerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/omprog-single-instance.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_ossl_cert_chain.sh0000644000000000000000000000013115055602574020755 xustar0030 mtime=1756824956.039451582 30 atime=1764931168.463759474 29 ctime=1764935935.04975823 rsyslog-8.2512.0/tests/sndrcv_ossl_cert_chain.sh0000775000175000017500000000461415055602574020432 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" ### This is important, as it must be exactly the same ### as the ones configured in used certificates export HOSTNAME="fedora" add_conf ' global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="'$srcdir/testsuites/certchain/ca-cert.pem'" DefaultNetstreamDriverCertFile="'$srcdir/testsuites/certchain/server-cert.pem'" DefaultNetstreamDriverKeyFile="'$srcdir/testsuites/certchain/server-key.pem'" NetstreamDriverCAExtraFiles="'$srcdir/testsuites/certchain/ca-root-cert.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" PermittedPeer="'$HOSTNAME'" StreamDriver.AuthMode="x509/name" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/certchain/ca-root-cert.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/certchain/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/certchain/client-key.pem'" ) # Note: no TLS for the listener, this is for tcpflood! $ModLoad ../plugins/imtcp/.libs/imtcp input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/name" StreamDriverPermittedPeers="'$HOSTNAME'" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd-lb-2target-impstats.sh0000644000000000000000000000013215055603742021155 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.528632265 30 ctime=1764935932.764723253 rsyslog-8.2512.0/tests/omfwd-lb-2target-impstats.sh0000775000175000017500000000346615055603742020635 0ustar00rgerrger#!/bin/bash # added 2024-02-24 by rgerhards. Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf export NUMMESSAGES=1000 # MUST be an EVEN number! export STATSFILE="$RSYSLOG_DYNNAME.stats" # starting minitcpsrvr receives so that we can obtain their port # numbers start_minitcpsrvr $RSYSLOG_OUT_LOG 1 start_minitcpsrvr $RSYSLOG2_OUT_LOG 2 # regular startup add_conf ' $MainMsgQueueTimeoutShutdown 10000 module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'" interval="1" ruleset="stats") template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="builtin:omfwd" template="outfmt") if $msg contains "msgnum:" then { action(type="omfwd" target=["127.0.0.1", "127.0.0.1"] port=["'$MINITCPSRVR_PORT1'", "'$MINITCPSRVR_PORT2'"] protocol="tcp" pool.resumeInterval="10" action.resumeRetryCount="-1" action.resumeInterval="5") } ' # now do the usual run startup injectmsg shutdown_when_empty wait_shutdown if [ "$(wc -l < $RSYSLOG_OUT_LOG)" != "$(( NUMMESSAGES / 2 ))" ]; then echo "ERROR: RSYSLOG_OUT_LOG has invalid number of messages $(( NUMMESSAGES / 2 ))" error_exit 100 fi if [ "$(wc -l < $RSYSLOG2_OUT_LOG)" != "$(( NUMMESSAGES / 2 ))" ]; then echo "ERROR: RSYSLOG2_OUT_LOG has invalid number of messages $(( NUMMESSAGES / 2 ))" error_exit 100 fi # combine both files to check for correct message content export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.log-combined" cat "$RSYSLOG_OUT_LOG" "$RSYSLOG2_OUT_LOG" > "$SEQ_CHECK_FILE" seq_check export MSGS_PER_TARGET="$((NUMMESSAGES / 2))" echo msg per target $MSGS_PER_TARGET # check pstats - that's our prime test target echo content_check --regex "TCP-.*origin=omfwd .*messages.sent=$MSGS_PER_TARGET" "$STATSFILE" content_check --regex "TCP-.*origin=omfwd .*messages.sent=$MSGS_PER_TARGET" "$STATSFILE" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-logrotate-multiple.sh0000644000000000000000000000013115035412264021324 xustar0030 mtime=1752569012.392806336 30 atime=1764931166.178722863 29 ctime=1764935934.39974828 rsyslog-8.2512.0/tests/imfile-logrotate-multiple.sh0000775000175000017500000000375415035412264021005 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . $srcdir/diag.sh check-inotify-only . ${srcdir:=.}/diag.sh init check_command_available logrotate export IMFILEROTATES="10" export TESTMESSAGES=10000 export TESTMESSAGESFULL=$((IMFILEROTATES * TESTMESSAGES-1)) generate_conf add_conf ' global( workDirectory="'$RSYSLOG_DYNNAME'.spool" /* Filter out busy debug output */ debug.whitelist="off" debug.files=["omfile.c", "queue.c", "rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"] ) module(load="../plugins/imfile/.libs/imfile" mode="inotify") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" Severity="error" Facility="local7" addMetadata="on") $template outfmt,"%msg:F,58:2%\n" if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' # Write logrotate config file echo '"./'$RSYSLOG_DYNNAME'.input" { create daily missingok rotate 14 notifempty compress delaycompress }' > $RSYSLOG_DYNNAME.logrotate display_file() { printf '\nFILE %s content:\n' $1 cat -n $1 } startup TESTMESSAGESSTART=0 for i in $(seq 1 $IMFILEROTATES); do #printf 'PRESS ENTER TO CONTINUE\n' #read printf '\n\nNEW RUN:\n' ./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGESSTART > $RSYSLOG_DYNNAME.input ls -li $RSYSLOG_DYNNAME.input* echo ls ${RSYSLOG_DYNNAME}.spool: ls -li ${RSYSLOG_DYNNAME}.spool echo STATE FILE CONTENT: shopt -s extglob for filename in "$RSYSLOG_DYNNAME.spool"/imfile-state:*; do display_file $filename; done # Wait until testmessages are processed by imfile! msgcount=$((i * TESTMESSAGES-1)) # echo "TESTMESSAGESSTART: $TESTMESSAGESSTART - TotalMsgCount: $msgcount" wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES # Logrotate on logfile logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate TESTMESSAGESSTART=$((TESTMESSAGESSTART+TESTMESSAGES)) done shutdown_when_empty wait_shutdown seq_check 0 $TESTMESSAGESFULL exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmkubernetes-basic-vg.sh0000644000000000000000000000013215055602574020432 xustar0030 mtime=1756824956.033451498 30 atime=1764931168.776764488 30 ctime=1764935935.135759546 rsyslog-8.2512.0/tests/mmkubernetes-basic-vg.sh0000775000175000017500000002404115055602574020102 0ustar00rgerrger#!/bin/bash # added 2018-04-06 by richm, released under ASL 2.0 # # Note: on buildbot VMs (where there is no environment cleanup), the # kubernetes test server may be kept running if the script aborts or # is aborted (buildbot master failure!) for some reason. As such we # execute it under "timeout" control, which ensure it always is # terminated. It's not a 100% great method, but hopefully does the # trick. -- rgerhards, 2018-07-21 #export RSYSLOG_DEBUG="debug" USE_VALGRIND=true . ${srcdir:=.}/diag.sh init check_command_available timeout pwd=$( pwd ) k8s_srv_port=$( get_free_port ) generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") module(load="../plugins/impstats/.libs/impstats" interval="1" log.file="'"$RSYSLOG_DYNNAME.spool"'/mmkubernetes-stats.log" log.syslog="off" format="cee") module(load="../plugins/imfile/.libs/imfile") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../contrib/mmkubernetes/.libs/mmkubernetes") template(name="mmk8s_template" type="list") { property(name="$!all-json-plain") constant(value="\n") } input(type="imfile" file="'$RSYSLOG_DYNNAME.spool'/pod-*.log" tag="kubernetes" addmetadata="on") action(type="mmjsonparse" cookie="") action(type="mmkubernetes" busyretryinterval="1" token="dummy" kubernetesurl="http://localhost:'$k8s_srv_port'" filenamerules=["rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:.%.%container_hash:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log", "rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log"] ) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="mmk8s_template") ' testsrv=mmk8s-test-server echo starting kubernetes \"emulator\" timeout 2m $PYTHON -u $srcdir/mmkubernetes_test_server.py $k8s_srv_port ${RSYSLOG_DYNNAME}${testsrv}.pid ${RSYSLOG_DYNNAME}${testsrv}.started > ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log 2>&1 & BGPROCESS=$! wait_process_startup ${RSYSLOG_DYNNAME}${testsrv} ${RSYSLOG_DYNNAME}${testsrv}.started echo background mmkubernetes_test_server.py process id is $BGPROCESS cat > ${RSYSLOG_DYNNAME}.spool/pod-error1.log < ${RSYSLOG_DYNNAME}.spool/pod-error2.log < ${RSYSLOG_DYNNAME}.spool/pod-name1_namespace-name1_container-name1-id1.log < ${RSYSLOG_DYNNAME}.spool/pod-name2.container-hash2_namespace-name2_container-name2-id2.log < ${RSYSLOG_DYNNAME}.spool/pod-name3.log < ${RSYSLOG_DYNNAME}.spool/pod-name4.log < ${RSYSLOG_DYNNAME}.spool/pod-name5.log < ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-error.log <= 0: hsh = json.loads(line[jstart:]) if hsh["origin"] == "mmkubernetes": actual = hsh assert(expected == actual) ' $k8s_srv_port || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log; } else echo error: stats file ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log not found rc=1 fi if [ ${rc:-0} -ne 0 ]; then echo echo "FAIL: expected data not found. $RSYSLOG_OUT_LOG is:" cat ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log cat $RSYSLOG_OUT_LOG cat ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_re_match_i.sh0000644000000000000000000000013215055602574020100 xustar0030 mtime=1756824956.038451568 30 atime=1764931167.749748036 30 ctime=1764935934.846755122 rsyslog-8.2512.0/tests/rscript_re_match_i.sh0000775000175000017500000000123015055602574017543 0ustar00rgerrger#!/bin/bash # added 2015-09-29 by singh.janmejay # test re_match rscript-fn, using single quotes for the match # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="*Matched*\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if (re_match_i($msg, "RANDOM NUMBER")) then { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup tcpflood -m 1 -I $srcdir/testsuites/date_time_msg shutdown_when_empty wait_shutdown content_check "*Matched*" exit_test rsyslog-8.2512.0/tests/PaxHeaders/discard-rptdmsg-vg.sh0000644000000000000000000000013115055602574017740 xustar0030 mtime=1756824956.026451401 29 atime=1764931163.81168492 30 ctime=1764935933.703737626 rsyslog-8.2512.0/tests/discard-rptdmsg-vg.sh0000775000175000017500000000022015055602574017402 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/discard-rptdmsg.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_http_request-vg.sh0000644000000000000000000000013215055602574021147 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.271612096 30 ctime=1764935932.426718079 rsyslog-8.2512.0/tests/rscript_http_request-vg.sh0000775000175000017500000000016215055602574020615 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export TB_TEST_MAX_RUNTIME=1500 source ${srcdir:-.}/rscript_http_request.sh rsyslog-8.2512.0/tests/PaxHeaders/inputname-imtcp.sh0000644000000000000000000000013215055602574017352 xustar0030 mtime=1756824956.032451484 30 atime=1764931163.652682371 30 ctime=1764935933.660736968 rsyslog-8.2512.0/tests/inputname-imtcp.sh0000775000175000017500000000216215055602574017022 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1" name="l1") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" ruleset="ruleset1" name="l2") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port3" ruleset="ruleset1" name="l3") template(name="outfmt" type="string" string="%inputname%\n") ruleset(name="ruleset1") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2" assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3" tcpflood -p $TCPFLOOD_PORT -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\"" tcpflood -p $TCPFLOOD_PORT2 -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\"" tcpflood -p $RS_PORT -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: MSG\"" shutdown_when_empty wait_shutdown export EXPECTED='l1 l2 l3' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-basic-ha-vg.sh0000644000000000000000000000013215071746523016727 xustar0030 mtime=1760021843.884421711 30 atime=1764931162.691666961 30 ctime=1764935933.378732651 rsyslog-8.2512.0/tests/es-basic-ha-vg.sh0000775000175000017500000000140215071746523016373 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 export ES_PORT=19200 ensure_elasticsearch_ready init_elasticsearch generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") :msg, contains, "msgnum:" action(type="omelasticsearch" template="tpl" serverport=`echo $ES_PORT` searchIndex="rsyslog_testbench" bulkmode="on") ' startup_vg injectmsg wait_queueempty shutdown_when_empty wait_shutdown_vg es_getdata $NUMMESSAGES $ES_PORT seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_delete_params.sh0000644000000000000000000000013215035412264023340 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.119593606 30 ctime=1764935932.101713104 rsyslog-8.2512.0/tests/imbatchreport_errmsg_delete_params.sh0000775000175000017500000000066715035412264023020 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" reports="*.done" delete=".done$") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "'delete' must specify TWO parameters separated by spaces or tabs" exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-const-jsonf.sh0000644000000000000000000000013115035412264020304 xustar0030 mtime=1752569012.416639571 30 atime=1764931161.390646094 29 ctime=1764935933.01672711 rsyslog-8.2512.0/tests/template-const-jsonf.sh0000775000175000017500000000070615035412264017757 0ustar00rgerrger#!/bin/bash # added 2018-02-10 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { constant(outname="@version" value="1" format="jsonf") constant(value="\n") } local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='"@version": "1"' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-bulk.sh0000644000000000000000000000013215035412264017315 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.397662245 30 ctime=1764935933.299731442 rsyslog-8.2512.0/tests/clickhouse-bulk.sh0000775000175000017500000000304415035412264016765 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.bulk (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, ' add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" user="default" pwd="" template="outfmt") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.bulk ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="SELECT id, severity, facility, ipaddress, tag, message FROM rsyslog.bulk ORDER BY id" > $RSYSLOG_OUT_LOG export EXPECTED='0 7 20 127.0.0.1 tag msgnum:00000000: 1 7 20 127.0.0.1 tag msgnum:00000001: 2 7 20 127.0.0.1 tag msgnum:00000002: 3 7 20 127.0.0.1 tag msgnum:00000003: 4 7 20 127.0.0.1 tag msgnum:00000004: 5 7 20 127.0.0.1 tag msgnum:00000005: 6 7 20 127.0.0.1 tag msgnum:00000006: 7 7 20 127.0.0.1 tag msgnum:00000007: 8 7 20 127.0.0.1 tag msgnum:00000008: 9 7 20 127.0.0.1 tag msgnum:00000009:' cmp_exact $RSYSLOG_OUT_LOG clickhouse-client --query="DROP TABLE rsyslog.bulk" exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl-oversizeMsg-split.sh0000644000000000000000000000013215035412264020615 xustar0030 mtime=1752569012.389827181 30 atime=1764931164.135690115 30 ctime=1764935933.801739127 rsyslog-8.2512.0/tests/glbl-oversizeMsg-split.sh0000775000175000017500000000366215035412264020273 0ustar00rgerrger#!/bin/bash # add 2018-05-03 by PascalWithopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./have_relpSrvSetOversizeMode if [ $? -eq 1 ]; then echo "imrelp parameter oversizeMode not available. Test stopped" exit 77 fi; generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") global(maxMessageSize="230" oversizemsg.input.mode="split") input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="300") template(name="outfmt" type="string" string="%rawmsg%\n") action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # TODO: add tcpflood option to specific EXACT test message size! startup tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end # because otherwise we won't know if it was truncated at the right length. #First part of message is checked grep "^<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi #Split part of message is checked grep "^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi #Error message is checked grep "message too long.*begin of message is:" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmlastmsg-udp.sh0000644000000000000000000000013215035412264017026 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.604761733 30 ctime=1764935935.090758857 rsyslog-8.2512.0/tests/pmlastmsg-udp.sh0000775000175000017500000000333715035412264016503 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/pmlastmsg/.libs/pmlastmsg") module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%msg%\n") ruleset(name="ruleset1" parser=["rsyslog.lastline","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times\"" tcpflood -m1 -T "udp" -M "\"<13>last message repeated 0090909787348927349875 times\"" tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times\"" tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5 times -- more data\"" tcpflood -m1 -T "udp" -M "\"<13>last message repeated 5.2 times\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG long message ================================================================================\"" tcpflood -m1 -T "udp" -M "\"<34>1 2003-11-11T22:14:15.003Z mymachine.example.com su - ID47 last message repeated 5 times\"" shutdown_when_empty wait_shutdown echo 'last message repeated 5 times last message repeated 0090909787348927349875 times repeated 5 times repeated 5 times -- more data repeated 5.2 times Rest of message... long message ================================================================================ last message repeated 5 times' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/tcp_forwarding_retries.sh0000644000000000000000000000013215035412264020776 xustar0030 mtime=1752569012.416639571 30 atime=1764931158.825604938 30 ctime=1764935932.299716134 rsyslog-8.2512.0/tests/tcp_forwarding_retries.sh0000775000175000017500000000233215035412264020445 0ustar00rgerrger#!/bin/bash # added 2016-06-21 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init messages=20000 # how many messages to inject? # Note: we need to inject a somewhat larger number of messages in order # to ensure that we receive some messages in the actual output file, # as batching can (validly) cause a larger loss in the non-writable # file generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" { action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="TCP" action.resumeRetryCount="10" template="outfmt") } ' # we start a small receiver process ./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG -s4 & BGPROCESS=$! echo background minitcpsrvr process id is $BGPROCESS startup injectmsg 0 $messages shutdown_when_empty wait_shutdown # note: minitcpsrvr shuts down automatically if the connection is closed, but # we still try to kill it in case the test did not connect to it! Note that we # do not need an extra wait, as the rsyslog shutdown process should have taken # far long enough. echo waiting on background process kill $BGPROCESS &> /dev/null wait $BGPROCESS seq_check 0 $(($messages-1)) exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-readmode2-with-persists.sh0000644000000000000000000000013215035412264022161 xustar0030 mtime=1752569012.392806336 30 atime=1764931165.722715555 30 ctime=1764935934.253746045 rsyslog-8.2512.0/tests/imfile-readmode2-with-persists.sh0000775000175000017500000000474315035412264021640 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 echo ====================================================================== echo [imfile-readmode2-with-persists.sh] . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing sleep 1 # now stop and restart rsyslog so that the file info must be # persisted and read again on startup. Results should still be # correct ;) echo stopping rsyslog shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo spool: ls -l ${RSYSLOG_DYNNAME}.spool echo restarting rsyslog startup echo restarted rsyslog, continuing with test # write some more lines (see https://github.com/rsyslog/rsyslog/issues/144) echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2 # give it time to finish sleep 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! # give it time to write the output file sleep 1 ## check if we have the correct number of messages NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" cat $RSYSLOG_OUT_LOG exit 1 else if [ ! $NUMLINES -eq 3 ]; then echo "ERROR: expecting 3 headers, got $NUMLINES" cat $RSYSLOG_OUT_LOG exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {1..4}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" cat $RSYSLOG_OUT_LOG exit 1 fi done ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_anon_ipv4.sh0000644000000000000000000000013215103346332021425 xustar0030 mtime=1762512090.634176013 30 atime=1764931163.205675203 30 ctime=1764935933.530734978 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_anon_ipv4.sh0000775000175000017500000000433515103346332021101 0ustar00rgerrger#!/bin/bash # testing sending and receiving via TLS with anon auth using bare ipv4, no SNI # rgerhards, 2011-04-04 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # Force IPv4 only when not explicitly running the IPv6 variant if [ "${TARGET:=127.0.0.1}" != "[::1]" ]; then export RSTB_FORCE_IPV4=1 fi if [ "${TARGET:=127.0.0.1}" == "[::1]" ]; then . $srcdir/diag.sh check-ipv6-available fi export NUMMESSAGES=10000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="ossl" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup export PORT_RCVR=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="ossl" ) # set up the action $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon *.* @@'${TARGET}':'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_wrap2.sh0000644000000000000000000000013215035412264017032 xustar0030 mtime=1752569012.413660417 30 atime=1764931167.514744271 30 ctime=1764935934.778754081 rsyslog-8.2512.0/tests/rscript_wrap2.sh0000775000175000017500000000154715035412264016510 0ustar00rgerrger#!/bin/bash # added 2014-11-03 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_wrap2.sh\]: a test for wrap\(2\) script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.replaced_msg%\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.replaced_msg = wrap("foo says" & $msg, "*" & "*"); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 1 -I $srcdir/testsuites/date_time_msg echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "**foo says at Thu Oct 30 13:20:18 IST 2014 random number is 19597**" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-NUL.sh0000644000000000000000000000013115035412264016000 xustar0029 mtime=1752569012.39578549 30 atime=1764931162.937670906 30 ctime=1764935933.454733815 rsyslog-8.2512.0/tests/imtcp-NUL.sh0000775000175000017500000000127115035412264015451 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message <167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input tcpflood -B -I $RSYSLOG_DYNNAME.input shutdown_when_empty wait_shutdown seq_check 0 1 exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-pure-json.sh0000644000000000000000000000013115071746523017773 xustar0030 mtime=1760021843.910422121 30 atime=1764931161.331645147 29 ctime=1764935932.99972685 rsyslog-8.2512.0/tests/template-pure-json.sh0000775000175000017500000000177415071746523017454 0ustar00rgerrger#!/bin/bash # added 2018-02-10 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list" option.jsonftree="on") { property(outname="message" name="msg" format="jsonf") constant(outname="@version" value="1" format="jsonf") } local4.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED_JSON='{"message":" msgnum:00000000:", "@version": "1"}' python3 - "$RSYSLOG_OUT_LOG" <<'PY' import json import os import sys expected = json.loads(os.environ['EXPECTED_JSON']) with open(sys.argv[1], 'r', encoding='utf-8') as fh: actual = json.loads(fh.read()) if actual != expected: print('invalid response generated') print('################# actual JSON is:') print(json.dumps(actual, indent=2, sort_keys=True)) print('################# expected JSON was:') print(json.dumps(expected, indent=2, sort_keys=True)) sys.exit(1) PY exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_parse_time.sh0000644000000000000000000000013215035412264020127 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.727619413 30 ctime=1764935932.546719915 rsyslog-8.2512.0/tests/rscript_parse_time.sh0000775000175000017500000001066215035412264017603 0ustar00rgerrger#!/bin/bash # Added 2017-10-28 by Stephen Workman, released under ASL 2.0 # Because this script tests functionality that depends on the current date, # we cannot use static values for the expected results. They have to be # calculated. Also, because we cannot depend on the GNU version of the # 'date' command on all of our test systems (think FreeBSD, and Solaris), # we need a method of converting given date/time strings to UNIX timestamps. # For that we use an external Python 2.x script to do the job. . ${srcdir:=.}/diag.sh init getts="$PYTHON $srcdir/rscript_parse_time_get-ts.py" # Run the Python script's self-tests $getts selftest if [[ $? -ne 0 ]]; then printf "Failed own self-test(s)!\n" error_exit 1 fi # Since the RFC 3164 date/time format does not include a year, we need to # try to "guess" an appropriate one based on the incoming date and the # current date. So, we'll use a reasonable spread of RFC 3164 date/time # strings to ensure that we test as much of our year "guessing" as # possible. Since this uses the CURRENT DATE (as in, the date this) # script was invoked, we need to calculate our expected results to # compare them with the values returned by the parse_time() RainerScript # function. rfc3164_1="Oct 5 01:10:11" rfc3164_1_r=$($getts "$rfc3164_1") rfc3164_2="Jan 31 13:00:00" rfc3164_2_r=$($getts "$rfc3164_2") rfc3164_3="Feb 28 14:35:00" rfc3164_3_r=$($getts "$rfc3164_3") rfc3164_4="Mar 1 14:00:00" rfc3164_4_r=$($getts "$rfc3164_4") rfc3164_5="Apr 3 15:00:00" rfc3164_5_r=$($getts "$rfc3164_5") rfc3164_6="May 5 16:00:00" rfc3164_6_r=$($getts "$rfc3164_6") rfc3164_7="Jun 11 03:00:00" rfc3164_7_r=$($getts "$rfc3164_7") rfc3164_8="Jul 15 05:00:00" rfc3164_8_r=$($getts "$rfc3164_8") rfc3164_9="Aug 17 08:00:00" rfc3164_9_r=$($getts "$rfc3164_9") rfc3164_10="Sep 20 18:00:00" rfc3164_10_r=$($getts "$rfc3164_10") rfc3164_11="Nov 23 19:00:00" rfc3164_11_r=$($getts "$rfc3164_11") rfc3164_12="Dec 25 20:00:00" rfc3164_12_r=$($getts "$rfc3164_12") generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omstdout/.libs/omstdout") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # $DebugLevel 2 # RFC 3164 Parse Tests (using fixed input values - see above) set $!datetime!rfc3164_1 = parse_time("'"$rfc3164_1"'"); set $!datetime!rfc3164_2 = parse_time("'"$rfc3164_2"'"); set $!datetime!rfc3164_3 = parse_time("'"$rfc3164_3"'"); set $!datetime!rfc3164_4 = parse_time("'"$rfc3164_4"'"); set $!datetime!rfc3164_5 = parse_time("'"$rfc3164_5"'"); set $!datetime!rfc3164_6 = parse_time("'"$rfc3164_6"'"); set $!datetime!rfc3164_7 = parse_time("'"$rfc3164_7"'"); set $!datetime!rfc3164_8 = parse_time("'"$rfc3164_8"'"); set $!datetime!rfc3164_9 = parse_time("'"$rfc3164_9"'"); set $!datetime!rfc3164_10 = parse_time("'"$rfc3164_10"'"); set $!datetime!rfc3164_11 = parse_time("'"$rfc3164_11"'"); set $!datetime!rfc3164_12 = parse_time("'"$rfc3164_12"'"); # RFC 3339 Parse Tests (these provide their own year) set $!datetime!rfc3339 = parse_time("2017-10-05T01:10:11Z"); set $!datetime!rfc3339tz1 = parse_time("2017-10-05T01:10:11+04:00"); set $!datetime!rfc3339tz2 = parse_time("2017-10-05T01:10:11+00:00"); # Test invalid date strings, these should return 0 set $!datetime!inval1 = parse_time("not a date/time"); set $!datetime!inval2 = parse_time("2017-10-05T01:10:11"); set $!datetime!inval3 = parse_time("2017-SOMETHING: 42"); template(name="outfmt" type="string" string="%!datetime%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") local4.* :omstdout:;outfmt ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown # Our fixed and calculated expected results export EXPECTED='{ "rfc3164_1": '"$rfc3164_1_r"', "rfc3164_2": '"$rfc3164_2_r"', "rfc3164_3": '"$rfc3164_3_r"', "rfc3164_4": '"$rfc3164_4_r"', "rfc3164_5": '"$rfc3164_5_r"', "rfc3164_6": '"$rfc3164_6_r"', "rfc3164_7": '"$rfc3164_7_r"', "rfc3164_8": '"$rfc3164_8_r"', "rfc3164_9": '"$rfc3164_9_r"', "rfc3164_10": '"$rfc3164_10_r"', "rfc3164_11": '"$rfc3164_11_r"', "rfc3164_12": '"$rfc3164_12_r"', "rfc3339": 1507165811, "rfc3339tz1": 1507151411, "rfc3339tz2": 1507165811, "inval1": 0, "inval2": 0, "inval3": 0 }' # FreeBSD's cmp does not support reading from STDIN cmp <(echo "$EXPECTED") $RSYSLOG_OUT_LOG if [[ $? -ne 0 ]]; then printf "Invalid function output detected!\n" printf "Expected: $EXPECTED\n" printf "Got: " cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-persist.sh0000644000000000000000000000013115035412264017043 xustar0030 mtime=1752569012.409688211 29 atime=1764931163.92768678 30 ctime=1764935933.740738193 rsyslog-8.2512.0/tests/queue-persist.sh0000775000175000017500000000115115035412264016511 0ustar00rgerrger#!/bin/bash # Test for queue data persisting at shutdown. We use the actual driver # to carry out multiple tests with different queue modes # added 2009-05-27 by Rgerhards # This file is part of the rsyslog project, released ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/queue-persist-drvr.sh LinkedList . $srcdir/queue-persist-drvr.sh FixedArray # the disk test should not fail, however, the config is extreme and using # it more or less is a config error . $srcdir/queue-persist-drvr.sh Disk # we do not test Direct mode because this absolute can not work in direct mode # (maybe we should do a fail-type of test?) rsyslog-8.2512.0/tests/PaxHeaders/uxsock_multiple_netns.sh0000644000000000000000000000013215114522477020675 xustar0030 mtime=1764926783.046632128 30 atime=1764926783.497643201 30 ctime=1764935934.166744714 rsyslog-8.2512.0/tests/uxsock_multiple_netns.sh0000775000175000017500000000711515114522477020350 0ustar00rgerrger#!/bin/bash # This tests basic omuxsock functionality with namespaces. # Multiple socket receivers are started which sends all data # to an output file, then a rsyslog instance is started which # generates messages and sends them to multiple unix sockets. # Multiple socket types are being used. # Based on uxsock_simple.sh added 2010-08-06 by Rgerhards # Updated 2025-04-16 for abstract sockets and multiple socket # types. echo =============================================================================== echo \[uxsock_multiple_netns.sh\]: test for transmitting to another namespace echo This test must be run with CAP_SYS_ADMIN capabilities [network namespace creation/change required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi . ${srcdir:=.}/diag.sh init check_command_available timeout uname if [ $(uname) != "Linux" ] ; then echo "This test requires Linux (AF_UNIX abstract addresses)" exit 77 fi NS_PREFIX=$(basename ${RSYSLOG_DYNNAME}) SOCKET_NAMES=( "$RSYSLOG_DYNNAME-testbench-dgram-uxsock.0" "$RSYSLOG_DYNNAME-testbench-dgram-uxsock.DGRAM" "$RSYSLOG_DYNNAME-testbench-dgram-uxsock.STREAM" "$RSYSLOG_DYNNAME-testbench-dgram-uxsock.SEQPACKET" ) # create the pipe and start a background process that copies data from # it to the "regular" work file generate_conf for name in "${SOCKET_NAMES[@]}"; do ext=${name##*.} NS=${NS_PREFIX}.${ext} if [ ${ext} == "0" ]; then add_conf ' $template outfmt,"%msg:F,58:2%\n" module( load = "../plugins/omuxsock/.libs/omuxsock" template = "outfmt" SocketName = "'${name}'" abstract = "1" NetworkNamespace="'${NS}'" ) :msg, contains, "msgnum:" { action( type = "omuxsock" ) ' else add_conf ' action( type = "omuxsock" SocketName = "'$name'" abstract = "1" SocketType = "'$ext'" NetworkNamespace="'${NS}'" ) action( type = "omuxsock" SocketName = "'$name'" abstract = "1" SocketType = "'$ext'" NetworkNamespace="'${NS}.fail'" ) ' fi done add_conf ' } ' BGPROCESS=() for name in "${SOCKET_NAMES[@]}"; do ext=${name##*.} NS=${NS_PREFIX}.${ext} ip netns add "${NS}" ip netns exec "${NS}" ip link set dev lo up ip netns delete "${NS}.fail" > /dev/null 2>&1 if [ "${ext}" == "0" ]; then type="" else type="-T${ext}" fi timeout 30s ip netns exec "${NS}" ./uxsockrcvr -a -s$name ${type} -o ${RSYSLOG_OUT_LOG}.${ext} -t 60 & PID=($!) BGPROCESS+=($PID) echo background uxsockrcvr ${name} process id is $PID done # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # wait for the cp process to finish, do pipe-specific cleanup echo shutting down uxsockrcvr... # TODO: we should do this more reliable in the long run! (message counter? timeout?) for pid in ${BGPROCESS[@]}; do kill $pid wait $pid done echo background processes have terminated, continue test... # Remove namespaces for name in "${SOCKET_NAMES[@]}"; do ext=${name##*.} NS=${NS_PREFIX}.${ext} ip netns delete "${NS}" > /dev/null 2>&1 done # and continue the usual checks BASE=${RSYSLOG_OUT_LOG} for name in "${SOCKET_NAMES[@]}"; do RSYSLOG_OUT_LOG=${BASE}.${name##*.} seq_check 0 9999 done exit_test rsyslog-8.2512.0/tests/PaxHeaders/smtradfile-vg.sh0000644000000000000000000000013215035412264016775 xustar0030 mtime=1752569012.413660417 30 atime=1764931157.620585596 30 ctime=1764935931.963710991 rsyslog-8.2512.0/tests/smtradfile-vg.sh0000775000175000017500000000017715035412264016451 0ustar00rgerrger#!/bin/bash # addd 2019-04-15 by RGerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/smtradfile.sh rsyslog-8.2512.0/tests/PaxHeaders/dynfile_invld_sync.sh0000644000000000000000000000013215055603742020120 xustar0030 mtime=1756825570.301069108 30 atime=1764931166.296724754 30 ctime=1764935934.432748785 rsyslog-8.2512.0/tests/dynfile_invld_sync.sh0000775000175000017500000000345215055603742017573 0ustar00rgerrger#!/bin/bash # This test checks if omfile segfaults when a file open() in dynacache mode fails. # The test is mimiced after a real-life scenario (which, of course, was much more # complex). # # added 2010-03-09 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $template outfmt,"%msg:F,58:3%\n" $template dynfile,"%msg:F,58:2%.log" # complete name is in message $OMFileFlushOnTXEnd on $OMFileAsyncWriting off $DynaFileCacheSize 4 local0.* ?dynfile;outfmt ' startup # we send handcrafted message. We have a dynafile cache of 4, and now send one message # each to fill up the cache. injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3" # the next one has caused a segfault in practice # note that /proc/rsyslog.error.file must not be creatable injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom" # some more writes injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6" injectmsg_literal "<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7" # done message generation shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG seq_check 0 7 exit_test rsyslog-8.2512.0/tests/PaxHeaders/array_lookup_table-vg.sh0000644000000000000000000000013215035412264020521 xustar0030 mtime=1752569012.384861924 30 atime=1764931167.888750263 30 ctime=1764935934.886755735 rsyslog-8.2512.0/tests/array_lookup_table-vg.sh0000775000175000017500000000027015035412264020167 0ustar00rgerrger#!/bin/bash # added 2015-10-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/array_lookup_table.sh rsyslog-8.2512.0/tests/PaxHeaders/zstd.sh0000644000000000000000000000013115055602574015223 xustar0030 mtime=1756824956.043451637 29 atime=1764931160.64863419 30 ctime=1764935932.798723773 rsyslog-8.2512.0/tests/zstd.sh0000775000175000017500000000306515055602574014677 0ustar00rgerrger#!/bin/bash # This tests writing large data records in zst mode. We use up to 10K # record size. # # added 2022-06-21 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=${NUMMESSAGES:-50000} export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf # Note: we right now use the non-compressed file as indicator for "processing complete" #export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.zst add_conf ' $MaxMessageSize 10k $MainMsgQueueTimeoutShutdown 10000 module(load="builtin:omfile" compression.driver="zstd" compression.zstd.workers="5") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'.zst" template="outfmt" zipLevel="20" iobuffersize="64k" veryRobustZIP="off") local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' # rgerhards, 2019-08-14: Note: veryRobustZip may need to be "on". Do this if the test # still prematurely terminates. In that case it is likely that gunzip got confused # by the missing zip close record. My initial testing shows that while gunzip emits an # error message, everything is properly extracted. Only stressed CI runs will show how # it works in reality. startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES -r -d10000 -P129 shutdown_when_empty wait_shutdown seq_check 0 $((NUMMESSAGES - 1)) -E exit_test rsyslog-8.2512.0/tests/PaxHeaders/execonlywhenprevsuspended_multiwrkr.sh0000644000000000000000000000013015035412264023667 xustar0029 mtime=1752569012.38883413 30 atime=1764931166.391726276 29 ctime=1764935934.46374926 rsyslog-8.2512.0/tests/execonlywhenprevsuspended_multiwrkr.sh0000775000175000017500000000170715035412264023345 0ustar00rgerrger#!/bin/bash # rgerhards, 2013-12-05 echo ===================================================================================== echo \[execonlywhenprevsuspended_multiwrkr.sh\]: test execonly...suspended functionality multiworker case . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # omtesting provides the ability to cause "SUSPENDED" action state $ModLoad ../plugins/omtesting/.libs/omtesting $MainMsgQueueTimeoutShutdown 100000 $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" :omtesting:fail 2 0 $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"';outfmt ' startup # we initially send only 10 messages. It has shown that if we send more, # we cannot really control which are the first two messages imdiag sees, # and so we do not know for sure which numbers are skipped. So we inject # those 10 to get past that point. injectmsg 0 10 ./msleep 500 injectmsg 10 990 shutdown_when_empty wait_shutdown seq_check 1 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/dynstats_prevent_premature_eviction-vg.sh0000644000000000000000000000013215055602574024252 xustar0030 mtime=1756824956.027451414 30 atime=1764931167.186739016 30 ctime=1764935934.686752673 rsyslog-8.2512.0/tests/dynstats_prevent_premature_eviction-vg.sh0000775000175000017500000000531715055602574023727 0ustar00rgerrger#!/bin/bash # added 2016-04-13 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[dynstats_prevent_premature_eviction-vg.sh\]: test for ensuring metrics are not evicted before unused-ttl with valgrind . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on") template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n") dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off") set $.msg_prefix = field($msg, 32, 1); if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then { set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix); } else { set $.increment_successful = -1; } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log . $srcdir/diag.sh block-stats-flush injectmsg_file $srcdir/testsuites/dynstats_input_1 . $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it injectmsg_file $srcdir/testsuites/dynstats_input_2 . $srcdir/diag.sh allow-single-stats-flush-after-block-and-wait-for-it injectmsg_file $srcdir/testsuites/dynstats_input_3 . $srcdir/diag.sh await-stats-flush-after-block wait_queueempty wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log content_check "foo 001 0" content_check "foo 006 0" echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg # because dyn-accumulators for existing metrics were posted-to under a second, they should not have been evicted custom_content_check 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log" custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log" custom_content_check 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log" # sum is high because accumulators were never reset, and we expect them to last specific number of cycles(when we posted before ttl expiry) first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 6 first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1 first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 0 first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/now_family_utc.sh0000644000000000000000000000013215055602574017257 xustar0030 mtime=1756824956.034451512 30 atime=1764931161.534648403 30 ctime=1764935933.057727738 rsyslog-8.2512.0/tests/now_family_utc.sh0000775000175000017500000000160515055602574016730 0ustar00rgerrger#!/bin/bash # test $NOW family of system properties # addd 2016-01-12 by RGerhards, released under ASL 2.0 # requires faketime . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$hour%:%$minute%,%$hour-utc%:%$minute-utc%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' . $srcdir/faketime_common.sh export TZ=TEST+06:30 FAKETIME='2016-01-01 01:00:00' startup # what we send actually is irrelevant, as we just use system properties. # but we need to send one message in order to gain output! tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="01:00,07:30" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_relp_tls_prio.sh0000644000000000000000000000013215055602574020474 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.160690516 30 ctime=1764935933.808739234 rsyslog-8.2512.0/tests/sndrcv_relp_tls_prio.sh0000775000175000017500000000242715055602574020150 0ustar00rgerrger#!/bin/bash # added 2013-12-10 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo testing sending and receiving via relp with TLS enabled and priority string set # uncomment for debugging support: # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' module(load="../plugins/imrelp/.libs/imrelp") # then SENDER sends to this port (not tcpflood!) input(type="imrelp" port="'$PORT_RCVR'" tls="on" tls.prioritystring="NORMAL:+ANON-DH") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' module(load="../plugins/omrelp/.libs/omrelp") action(type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on" tls.prioritystring="NORMAL:+ANON-DH") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 50000 # shut down sender shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 50000 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-feedback-vg.sh0000644000000000000000000000013215035412264017670 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.161706563 30 ctime=1764935934.087743504 rsyslog-8.2512.0/tests/omprog-feedback-vg.sh0000775000175000017500000000144015035412264017336 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Same test than 'omprog-feedback.sh', but checking for memory # problems using valgrind. Note it is not necessary to repeat the # rest of checks (this simplifies the maintenance of the tests). . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-feedback-bin.sh` template="outfmt" name="omprog_action" queue.type="Direct" confirmMessages="on" action.resumeInterval="1" ) } ' startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd_impstats-udp.sh0000644000000000000000000000013115055602574020065 xustar0030 mtime=1756824956.034451512 29 atime=1764931167.27874049 30 ctime=1764935934.712753071 rsyslog-8.2512.0/tests/omfwd_impstats-udp.sh0000775000175000017500000000172415055602574017541 0ustar00rgerrger#!/bin/bash # This test tests impstats omfwd counters in UPD mode # added 2021-02-11 by rgerhards. Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf export STATSFILE="$RSYSLOG_DYNNAME.stats" add_conf ' $MainMsgQueueTimeoutShutdown 10000 module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'" interval="1" ruleset="stats") ruleset(name="stats") { stop # nothing to do here } template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="builtin:omfwd" template="outfmt") if $msg contains "msgnum:" then action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="udp") ' # note: there must be no actual data - it's fine for this test if all data is lost # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty wait_shutdown # check pstats - that's our prime test target content_check --regex "UDP-.*origin=omfwd .*bytes.sent=[1-9][0-9][0-9]" "$STATSFILE" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_conflict3-vg.sh0000644000000000000000000000013215055602574022364 xustar0030 mtime=1756824956.039451582 30 atime=1764931160.015624034 30 ctime=1764935932.618721018 rsyslog-8.2512.0/tests/rscript_unflatten_conflict3-vg.sh0000775000175000017500000000013115055602574022026 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_conflict3.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-symlink-multi.sh0000644000000000000000000000013215055602574020321 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.143722302 30 ctime=1764935934.387748096 rsyslog-8.2512.0/tests/imfile-symlink-multi.sh0000775000175000017500000000474515055602574020002 0ustar00rgerrger#!/bin/bash # This test points multiple symlinks (all watched by rsyslog via wildcard) # to single file and checks that message is reported once for each symlink # with correct corresponding metadata. # This is part of the rsyslog testbench, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify export IMFILEINPUTFILES="10" mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' # comment out if you need more debug info: global( debug.whitelist="on" debug.files=["imfile.c"]) global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile" mode="inotify" normalizePath="off") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input-symlink.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value=", filename: ") property(name="$!metadata!filename") constant(value=", fileoffset: ") property(name="$!metadata!fileoffset") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file="'${RSYSLOG_OUT_LOG}'" template="outfmt") ' # generate input files first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). imfilebefore="$RSYSLOG_DYNNAME.input-symlink.log" ./inputfilegen -m 1 > $imfilebefore mkdir $RSYSLOG_DYNNAME.targets # Start rsyslog now before adding more files startup cp $imfilebefore $RSYSLOG_DYNNAME.targets/target.log for i in `seq 2 $IMFILEINPUTFILES`; do ln -s $RSYSLOG_DYNNAME.targets/target.log $RSYSLOG_DYNNAME.input.$i.log # Wait little for correct timing ./msleep 50 done shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! sort ${RSYSLOG_OUT_LOG} > ${RSYSLOG_OUT_LOG}.sorted echo HEADER msgnum:00000000:, filename: ./$RSYSLOG_DYNNAME.input-symlink.log, fileoffset: 0 > $RSYSLOG_DYNNAME.expected for i in `seq 2 $IMFILEINPUTFILES` ; do echo HEADER msgnum:00000000:, filename: ./$RSYSLOG_DYNNAME.input.${i}.log, fileoffset: 0 >> $RSYSLOG_DYNNAME.expected done sort < $RSYSLOG_DYNNAME.expected | cmp - ${RSYSLOG_OUT_LOG}.sorted if [ ! $? -eq 0 ]; then echo "invalid output generated, ${RSYSLOG_OUT_LOG} is:" cat -n $RSYSLOG_OUT_LOG echo EXPECTED: cat -n $RSYSLOG_DYNNAME.expected error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-sessionbreak-vg.sh0000644000000000000000000000013115055602574020627 xustar0029 mtime=1756824956.03145147 30 atime=1764931164.102689586 30 ctime=1764935933.791738973 rsyslog-8.2512.0/tests/imrelp-sessionbreak-vg.sh0000775000175000017500000000331115055602574020275 0ustar00rgerrger#!/bin/bash # added 2020-04-10 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000000 export USE_VALGRIND="YES" # TODO remote leak check skip and fix memory leaks caused by session break export RS_TESTBENCH_LEAK_CHECK=no mkdir $RSYSLOG_DYNNAME.workdir generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") global( workDirectory="'$RSYSLOG_DYNNAME.workdir'" maxMessageSize="256k" ) main_queue(queue.type="Direct") $LocalHostName test $AbortOnUncleanConfig on $PreserveFQDN on input( type="imrelp" name="imrelp" port="'$TCPFLOOD_PORT'" ruleset="spool" MaxDataSize="256k" KeepAlive="on" ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="spool" queue.type="direct") { if $msg contains "msgnum:" then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } } ' startup # How many tcpfloods we run at the same tiem for ((i=1;i<=5;i++)); do # How many times tcpflood runs in each threads ./tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$NUMMESSAGES -s & tcpflood_pid=$! echo "started tcpflood instance $i (PID $tcpflood_pid)" # Give it time to actually connect ./msleep 500; kill -9 $tcpflood_pid # >/dev/null 2>&1; echo "killed tcpflood instance $i (PID $tcpflood_pid)" done; wait_queueempty netstatresult=$(netstat --all --program 2>&1 | grep "ESTABLISHED" | grep $(cat $RSYSLOG_PIDBASE.pid) | grep $TCPFLOOD_PORT) openfd=$(ls -l "/proc/$(cat $RSYSLOG_PIDBASE$1.pid)/fd" | wc -l) shutdown_when_empty wait_shutdown if [[ "$netstatresult" == "" ]] then echo "OK!" else echo "STILL OPENED Connections: " echo $netstatresult echo "Open files at the end: " echo $openfd error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rfc5424parser-sp_at_msg_start.sh0000644000000000000000000000013215055602574021735 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.145610074 30 ctime=1764935932.390717528 rsyslog-8.2512.0/tests/rfc5424parser-sp_at_msg_start.sh0000775000175000017500000000156115055602574021407 0ustar00rgerrger#!/bin/bash # checks that in RFC5424 mode SP at beginning of MSG part is properly handled # This file is part of the rsyslog project, released under ASL 2.0 # rgerhards, 2019-05-17 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%--END\n") if $syslogtag == "tag" then action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - - nosd-nosp' injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - [abc@123 a="b"] sd-nosp' injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - - nosd-sp' injectmsg literal '<13>1 2019-05-15T11:21:57+03:00 domain.tld tag - - [abc@123 a="b"] sd-sp' shutdown_when_empty wait_shutdown export EXPECTED='nosd-nosp--END sd-nosp--END nosd-sp--END sd-sp--END' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdtls-error-cert.sh0000644000000000000000000000013215055603742017614 xustar0030 mtime=1756825570.301069108 30 atime=1764931164.401694379 30 ctime=1764935933.873740229 rsyslog-8.2512.0/tests/imdtls-error-cert.sh0000775000175000017500000000151415055603742017264 0ustar00rgerrger#!/bin/bash # added 2018-11-07 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert-fail.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'" ) module( load="../plugins/imdtls/.libs/imdtls" ) input( type="imdtls" port="'$PORT_RCVR'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' # note: we do not need to generate any messages, config error occurs on startup startup sleep 5 # TODO: FIXME - just checking if we terminate too early shutdown_when_empty wait_shutdown content_check "Error: Certificate file could not be accessed" content_check "OpenSSL Error Stack:" exit_test rsyslog-8.2512.0/tests/PaxHeaders/allowed-sender-tcp-ok.sh0000644000000000000000000000013215035412264020331 xustar0030 mtime=1752569012.384861924 30 atime=1764931162.824669094 30 ctime=1764935933.417733249 rsyslog-8.2512.0/tests/allowed-sender-tcp-ok.sh0000775000175000017500000000134015035412264017776 0ustar00rgerrger#!/bin/bash # check that we are able to receive messages from allowed sender # added 2019-08-15 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5 # it's just important that we get any messages at all generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $AllowedSender TCP,127.0.0.1/16,[::1] template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-logrotate.sh0000644000000000000000000000013115035412264017473 xustar0030 mtime=1752569012.392806336 29 atime=1764931166.16172259 30 ctime=1764935934.393748188 rsyslog-8.2512.0/tests/imfile-logrotate.sh0000775000175000017500000000346415035412264017152 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . $srcdir/diag.sh check-inotify-only . ${srcdir:=.}/diag.sh init check_command_available logrotate export TESTMESSAGES=10000 export RETRIES=50 export TESTMESSAGESFULL=19999 generate_conf add_conf ' $WorkDirectory '$RSYSLOG_DYNNAME'.spool /* Filter out busy debug output */ global( debug.whitelist="off" debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"] ) module( load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on" ) $template outfmt,"%msg:F,58:2%\n" if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' # Write logrotate config file echo '"./'$RSYSLOG_DYNNAME'.input.*.log" { rotate 7 create daily missingok notifempty compress }' > $RSYSLOG_DYNNAME.logrotate # generate input file first. ./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log ls -l $RSYSLOG_DYNNAME.input* startup # Wait until testmessages are processed by imfile! wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES # Logrotate on logfile logrotate --state $RSYSLOG_DYNNAME.logrotate.state -f $RSYSLOG_DYNNAME.logrotate # generate more input after logrotate into new logfile ./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.1.log ls -l $RSYSLOG_DYNNAME.input* echo ls ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool msgcount=$((2* TESTMESSAGES)) wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! seq_check 0 $TESTMESSAGESFULL exit_test rsyslog-8.2512.0/tests/PaxHeaders/incltest.sh0000644000000000000000000000013215035412264016056 xustar0030 mtime=1752569012.397771593 30 atime=1764931162.306660786 30 ctime=1764935933.273731044 rsyslog-8.2512.0/tests/incltest.sh0000775000175000017500000000043015035412264015522 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/include.conf " startup # 100 messages are enough - the question is if the include is read ;) injectmsg 0 100 shutdown_when_empty wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-minbatch-queuefull.sh0000644000000000000000000000013215035412264021145 xustar0030 mtime=1752569012.409688211 30 atime=1764931158.857605452 30 ctime=1764935932.308716272 rsyslog-8.2512.0/tests/queue-minbatch-queuefull.sh0000775000175000017500000000123315035412264020613 0ustar00rgerrger#!/bin/bash # added 2019-01-14 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris - see https://github.com/rsyslog/rsyslog/issues/3513" export NUMMESSAGES=10000 generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" queue.type="linkedList" queue.size="2001" queue.dequeuebatchsize="2001" queue.mindequeuebatchsize="2001" queue.minDequeueBatchSize.timeout="2000" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmrm1stspace-basic.sh0000644000000000000000000000013115035412264017723 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.735651628 29 ctime=1764935933.11472861 rsyslog-8.2512.0/tests/mmrm1stspace-basic.sh0000775000175000017500000000200115035412264017364 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") module(load="../plugins/mmrm1stspace/.libs/mmrm1stspace") template(name="outfmt" type="string" string="-%msg%-\n") action(type="mmrm1stspace") :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:3\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag4:\"" shutdown_when_empty wait_shutdown echo '-msgnum:1- - msgnum:2- -msgnum:3- --' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_key_truncated.sh0000644000000000000000000000013215055602574022727 xustar0030 mtime=1756824956.039451582 30 atime=1764931159.943622879 30 ctime=1764935932.600720742 rsyslog-8.2512.0/tests/rscript_unflatten_key_truncated.sh0000775000175000017500000000336615055602574022406 0ustar00rgerrger#!/bin/bash # added 2021-03-09 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $!a.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb255ccccc.d = "bar"; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 1 wait_file_lines "$RSYSLOG_OUT_LOG" 1 60 shutdown_when_empty wait_shutdown # this test may need changes to produce a more deterministic # output by sorting keys EXPECTED=' msgnum:00000000: 0 { "a": { "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb255": { "d": "bar" } } }' cmp_exact "$RSYSLOG_OUT_LOG" EXPECTED='fmunflatten.c: warning: flat key "a.bbbbbbbbbbbbbbbbbb..." truncated at depth #1, buffer too small (max 256)' if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then echo "GREP FAILED" echo " => FILE: $RSYSLOG_DEBUGLOG" echo " => EXPECTED: $EXPECTED" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdtls-basic-tlscommands.sh0000644000000000000000000000013215055603742021133 xustar0030 mtime=1756825570.301069108 30 atime=1764931164.385694123 30 ctime=1764935933.868740152 rsyslog-8.2512.0/tests/imdtls-basic-tlscommands.sh0000775000175000017500000000241215055603742020601 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imdtls/.libs/imdtls" ) input( type="imdtls" tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.1,-TLSv1.3 Options=Bugs" port="'$PORT_RCVR'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup # now inject the messages which will fail due protocol configuration tcpflood --check-only -k "Protocol=-ALL,TLSv1.3" -p$PORT_RCVR -m$NUMMESSAGES -Tdtls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown if content_check --check-only "TLS library does not support SSL_CONF_cmd" then echo "SKIP: TLS library does not support SSL_CONF_cmd" skip_test else if content_check --check-only "DTLSv1_listen" then # Found DTLSv1_listen error, no further check needed exit_test else # Check for OpenSSL Error Stack content_check "OpenSSL Error Stack:" fi fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-numstr.sh0000644000000000000000000000013215055602574022372 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.514615995 30 ctime=1764935932.497719166 rsyslog-8.2512.0/tests/rscript_compare_numstr-numstr.sh0000775000175000017500000000015115055602574022036 0ustar00rgerrger#!/bin/bash export LOWER_VAL='"1"' export HIGHER_VAL='"2"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/mysql-basic-cnf6.sh0000644000000000000000000000013215035412264017307 xustar0030 mtime=1752569012.402736851 30 atime=1764931166.682730939 30 ctime=1764935934.547750546 rsyslog-8.2512.0/tests/mysql-basic-cnf6.sh0000775000175000017500000000072315035412264016760 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 generate_conf add_conf ' $ModLoad ../plugins/ommysql/.libs/ommysql if $msg contains "msgnum" then { action(type="ommysql" server="127.0.0.1" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench") } ' mysql_prep_for_test startup injectmsg shutdown_when_empty wait_shutdown mysql_get_data seq_check mysql_cleanup_test exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_12_ipv4.sh0000644000000000000000000000013215055602574020030 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.261627981 30 ctime=1764935932.689722105 rsyslog-8.2512.0/tests/mmanon_zero_12_ipv4.sh0000775000175000017500000000152415055602574017501 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.bits="12") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255 <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.\"" shutdown_when_empty wait_shutdown export EXPECTED=' 1.1.0.0 0.0.0.0 172.0.224.0 111.1.0.0.' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-encryption-disk_keyfile.sh0000644000000000000000000000013115035412264022204 xustar0030 mtime=1752569012.408695159 29 atime=1764931163.85968569 30 ctime=1764935933.719737871 rsyslog-8.2512.0/tests/queue-encryption-disk_keyfile.sh0000775000175000017500000000172415035412264021660 0ustar00rgerrger#!/bin/bash # addd 2018-09-30 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.filename="mainq" queue.type="disk" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutenqueue="300000" queue.lowwatermark="5000" queue.cry.provider="gcry" queue.cry.keyfile="'$RSYSLOG_DYNNAME.keyfile'" queue.saveonshutdown="on" ) template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :omtesting:sleep 0 5000 :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' printf "1234567890123456" > $RSYSLOG_DYNNAME.keyfile startup injectmsg 0 1000 shutdown_immediate wait_shutdown echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0* exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdropuser.sh0000644000000000000000000000013115055602574017003 xustar0030 mtime=1756824956.037451554 29 atime=1764931161.25764396 30 ctime=1764935932.976726498 rsyslog-8.2512.0/tests/privdropuser.sh0000775000175000017500000000111515055602574016451 0ustar00rgerrger#!/bin/bash # addd 2016-03-24 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) $PrivDropToUser '${TESTBENCH_TESTUSER[username]}' ' startup shutdown_when_empty wait_shutdown content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omsendertrack-statefile-vg.sh0000644000000000000000000000013215055603742021467 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.639634046 30 ctime=1764935932.795723727 rsyslog-8.2512.0/tests/omsendertrack-statefile-vg.sh0000775000175000017500000000012515055603742021134 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/omsendertrack-statefile.sh rsyslog-8.2512.0/tests/PaxHeaders/omfwd-subtree-tpl.sh0000644000000000000000000000013215062756615017624 xustar0030 mtime=1758190989.236641616 30 atime=1764931160.572632971 30 ctime=1764935932.776723436 rsyslog-8.2512.0/tests/omfwd-subtree-tpl.sh0000775000175000017500000000117015062756615017272 0ustar00rgerrger#!/bin/bash # Verify omfwd forwards messages when using subtree-type templates unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 template(name="csl-subtree" type="subtree" subtree="$!csl") if $msg contains "msgnum:" then { set $!csl!foo = "bar"; action(type="omfwd" template="csl-subtree" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp") } ' ./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG & BGPROCESS=$! startup injectmsg 0 1 shutdown_when_empty wait_shutdown content_check '{ "foo": "bar" }' "$RSYSLOG_OUT_LOG" exit_test rsyslog-8.2512.0/tests/PaxHeaders/no-dynstats.sh0000644000000000000000000000013215055602574016523 xustar0030 mtime=1756824956.033451498 30 atime=1764931167.270740362 30 ctime=1764935934.710753041 rsyslog-8.2512.0/tests/no-dynstats.sh0000775000175000017500000000160415055602574016173 0ustar00rgerrger#!/bin/bash # added 2016-03-10 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[no-dynstats.sh\]: test for verifying stats are reported correctly in legacy format in absence of any dynstats buckets being configured . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown custom_content_check 'global: origin=dynstats' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_dtls_certvalid_ciphers.sh0000644000000000000000000000013215055603742022335 xustar0030 mtime=1756825570.303069141 30 atime=1764931164.447695117 30 ctime=1764935933.887740443 rsyslog-8.2512.0/tests/sndrcv_dtls_certvalid_ciphers.sh0000775000175000017500000000423415055603742022007 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # start up the instances # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" export NUMMESSAGES=1 generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imdtls/.libs/imdtls" tls.AuthMode="anon") input( type="imdtls" tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_256_GCM_SHA384" port="'$PORT_RCVR'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/omdtls/.libs/omdtls" ) action( name="omdtls" type="omdtls" target="127.0.0.1" port="'$PORT_RCVR'" tls.tlscfgcmd="CipherString=ECDHE-RSA-AES128-GCM-SHA256\nCiphersuites=TLS_AES_128_GCM_SHA256" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg 0 $NUMMESSAGES shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # IMPORTANT: this test will generate many error messages. This is exactly it's # intent. So do not think something is wrong. The content_check below checks # these error codes. content_check --check-only "TLS library does not support SSL_CONF_cmd" ret=$? if [ $ret == 0 ]; then echo "SKIP: TLS library does not support SSL_CONF_cmd" skip_test else # Kindly check for a failed session content_check "OpenSSL Error Stack" content_check "no shared cipher" fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl-invld-param.sh0000644000000000000000000000013215035412264017361 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.947590846 30 ctime=1764935932.052712354 rsyslog-8.2512.0/tests/glbl-invld-param.sh0000775000175000017500000000070615035412264017033 0ustar00rgerrger#!/bin/bash # make sure we do not abort on invalid parameter (we # once had this problem) # addd 2016-03-03 by RGerhards, released under ASL 2.0 echo \[glbl-invld-param\]: . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(invalid="off") global(debug.unloadModules="invalid") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup sleep 1 shutdown_when_empty wait_shutdown # if we reach this point, we consider this a success. exit_test rsyslog-8.2512.0/tests/PaxHeaders/minitcpsrv_usage_output.sh0000644000000000000000000000013115035412264021232 xustar0030 mtime=1752569012.399757696 30 atime=1764931160.211627179 29 ctime=1764935932.67572189 rsyslog-8.2512.0/tests/minitcpsrv_usage_output.sh0000775000175000017500000000044115035412264020701 0ustar00rgerrger#!/bin/bash # add 2018-11-15 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./minitcpsrv&> $RSYSLOG_DYNNAME.output grep -q -- "-t parameter missing" $RSYSLOG_DYNNAME.output if [ ! $? -eq 0 ]; then echo "invalid response generated" error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_simple_mallformed_ipv4.sh0000644000000000000000000000013215055602574022242 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.310628767 30 ctime=1764935932.703722319 rsyslog-8.2512.0/tests/mmanon_simple_mallformed_ipv4.sh0000775000175000017500000000262415055602574021715 0ustar00rgerrger#!/bin/bash # add 2022-07-28 by Andre Lorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init #export USE_VALGRIND="YES" # this test only makes sense with valgrind enabled #export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes" #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.bits="32" ipv4.mode="simple") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: 165874883373.1.15599155266856607338.91@whatever <129>Mar 10 01:00:00 172.20.245.8 tag: 1.165874883373.15599155266856607338.91@whatever <129>Mar 10 01:00:00 172.20.245.8 tag: 15599155266856607338.165874883373.1.91@whatever <129>Mar 10 01:00:00 172.20.245.8 tag: 91.165874883373.1.15599155266856607338.@whatever\"" shutdown_when_empty wait_shutdown export EXPECTED=' 165874883373.1.15599155266856607338.91@whatever 1.165874883373.15599155266856607338.91@whatever 15599155266856607338.165874883373.1.91@whatever 91.165874883373.1.15599155266856607338.@whatever' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/action-tx-errfile-maxsize.sh0000644000000000000000000000013215055602574021252 xustar0030 mtime=1756824956.025451386 30 atime=1764931164.509696111 30 ctime=1764935933.903740688 rsyslog-8.2512.0/tests/action-tx-errfile-maxsize.sh0000775000175000017500000000203715055602574020723 0ustar00rgerrger#!/bin/bash # part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50 # enough to generate big file export MAX_ERROR_SIZE=100 generate_conf add_conf ' $ModLoad ../plugins/ommysql/.libs/ommysql global(errormessagestostderr.maxnumber="5") template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on") if((not($msg contains "error")) and ($msg contains "msgnum:")) then { set $.num = field($msg, 58, 2); if $.num % 2 == 0 then { set $!facility = $syslogfacility; } else { set $/cntr = 0; } action(type="ommysql" name="mysql_action_errfile_maxsize" server="127.0.0.1" template="tpl" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" action.errorfile="'$RSYSLOG2_OUT_LOG'" action.errorfile.maxsize="'$MAX_ERROR_SIZE'") } ' mysql_prep_for_test startup injectmsg shutdown_when_empty wait_shutdown mysql_get_data check_file_exists ${RSYSLOG2_OUT_LOG} file_size_check ${RSYSLOG2_OUT_LOG} ${MAX_ERROR_SIZE} exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-error-ca.sh0000644000000000000000000000012715055602574020646 xustar0029 mtime=1756824956.03145147 29 atime=1764931163.33267724 29 ctime=1764935933.56873556 rsyslog-8.2512.0/tests/imtcp-tls-ossl-error-ca.sh0000775000175000017500000000146715055602574020321 0ustar00rgerrger#!/bin/bash # added 2018-11-07 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca-fail.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'" ) module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' # note: we do not need to generate any messages, config error occurs on startup startup shutdown_when_empty wait_shutdown content_check "Error: CA certificate could not be accessed" content_check "OpenSSL Error Stack:" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_lt.sh0000644000000000000000000000013215035412264016416 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.405614246 30 ctime=1764935932.466718691 rsyslog-8.2512.0/tests/rscript_lt.sh0000775000175000017500000000131315035412264016063 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_lt.sh\]: testing rainerscript LT statement . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); if $!usr!msgnum < "00005000" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 8000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_certless_clientonly.sh0000644000000000000000000000013215035412264022556 xustar0030 mtime=1752569012.414653468 30 atime=1764931168.368757953 30 ctime=1764935935.023757832 rsyslog-8.2512.0/tests/sndrcv_tls_certless_clientonly.sh0000775000175000017500000000362215035412264022230 0ustar00rgerrger#!/bin/bash # all we want to test is if certless communication works. So we do # not need to send many messages. # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf # receiver export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="gtls" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup # sender export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 #export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global(defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'") # Note: no TLS for the listener, this is for tcpflood! $ModLoad ../plugins/imtcp/.libs/imtcp input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="anon") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_parse_time_get-ts.py0000644000000000000000000000013215055603742021435 xustar0030 mtime=1756825570.303069141 30 atime=1764931159.745619702 30 ctime=1764935932.548719946 rsyslog-8.2512.0/tests/rscript_parse_time_get-ts.py0000664000175000017500000001274015055603742021105 0ustar00rgerrger# call this via "python[3] script name" # Added 2017-11-05 by Stephen Workman, released under ASL 2.0 # # Produces a UNIX timestamp representing the specified RFC 3164 date/time # string. Since this date/time format does not include a year, a simple # algorithm is used to "guess" an appropriate one and append it to the # date/time string to calculate a timestamp value. # # If the incoming date is within one month in the future (from now), # it is assumed that it's either for the current year, or the next # year (depending on whether it is December or not). # - For example: # * If today is December 13th 2017 and we get passed the date/time # string "Jan 4 01:00:00", we assume that it is for the next # year (2018). # * If today is October 5th 2017, and we get passed the date/time # string "Nov 5 01:10:11", we assume that it is for this year. # If the incoming date has a month "before" the current month, or does # not fall into the situation above, it's assumed it's from the past. # - For example: # * If today is July 10th 2017, and the incoming date is for # a time in April, the year is assumed to be 2017. # * If today is July 10th 2017, and the incoming date is for # a time in September, the year is assumed to be 2016. # import re import sys from datetime import datetime, timedelta err = 0 # Make tests below a little easier to read. JAN = 1; FEB = 2; MAR = 3; APR = 4 MAY = 5; JUN = 6; JUL = 7; AUG = 8 SEP = 9; OCT = 10; NOV = 11; DEC = 12 # Run the provided expression and compare its result with the # expected value. The function expects the expression to be # passed in as a string so it can be printed to the screen # as-is when there is an error. def do_test(expr, val): global err # Run the expression and record the result result = eval(expr) # Print a message identifying the failing "test" if result != val: print("Error: %s. Expected %4d, got %4d!" % (expr, val, result)) err += 1 # Use a sliding 12-month window (offset by one month) # to determine the year that should be returned. # cy - Current Year # cm - Current Month # im - Incoming Month def estimate_year(cy, cm, im): im += 12 if (im - cm) == 1: if cm == 12 and im == 13: return cy + 1 if (im - cm) > 13: return cy - 1 return cy # A quick and dirty unit test to validate that our # estimate_year() function is working as it should. def self_test(): # Where the incoming month is within one month # in the future. Should be the NEXT year if # the current date is in December, or the SAME # year if it's not December. do_test("estimate_year(2017, DEC, JAN)", 2018) do_test("estimate_year(2017, NOV, DEC)", 2017) do_test("estimate_year(2017, OCT, NOV)", 2017) do_test("estimate_year(2017, SEP, OCT)", 2017) do_test("estimate_year(2017, AUG, SEP)", 2017) # These tests validate months that are MORE than # one month in the future OR are before the current # month. If, numerically, the month comes after the # current month, it's assumed to be for the year # PRIOR, otherwise it's assumed to be from THIS year. do_test("estimate_year(2017, NOV, JAN)", 2017) do_test("estimate_year(2017, NOV, FEB)", 2017) do_test("estimate_year(2017, AUG, OCT)", 2016) do_test("estimate_year(2017, AUG, MAR)", 2017) do_test("estimate_year(2017, APR, JUL)", 2016) do_test("estimate_year(2017, AUG, JAN)", 2017) do_test("estimate_year(2017, APR, FEB)", 2017) # Additional validations based on what was described # above. do_test("estimate_year(2017, JAN, DEC)", 2016) do_test("estimate_year(2017, JAN, FEB)", 2017) do_test("estimate_year(2017, JAN, MAR)", 2016) # Convert a datetime.timedelta object to a UNIX timestamp def get_total_seconds(dt): # timedelta.total_seconds() wasn't added until # Python 2.7, which CentOS 6 doesn't have. if hasattr(timedelta, "total_seconds"): return dt.total_seconds() return dt.seconds + dt.days * 24 * 3600 if __name__ == "__main__": if len(sys.argv) != 2: print("Invalid number of arguments!") sys.exit(1) if sys.argv[1] == "selftest": self_test() # Exit with non-zero if there were failures, # zero otherwise. sys.exit(err) months = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] current_datetime = datetime.utcnow() # The argument is expected to be an RFC 3164 timestamp # such as "Oct 5 01:10:11". incoming_datetime = sys.argv[1] # Get the name of the month from the date/time string that was passed in # and convert it to its ordinal number (1 for Jan, 10 for Oct, etc...) incoming_month = re.search(r"^([^ ]+) ", incoming_datetime).group(1) incoming_month = months.index(incoming_month) # Assume a year for the date/time passed in based off of today's date. estimated_year = estimate_year( current_datetime.year, current_datetime.month, incoming_month ) # Convert the date/time string (now with a year, e.g. "Oct 5 01:10:11 2017") to # a python datetime object that we can use to calculate a UNIX timestamp calculated_datetime = datetime.strptime("%s %d" % (incoming_datetime, estimated_year), "%b %d %H:%M:%S %Y") # Convert the datetime object to a UNIX timestamp by subtracting it from the epoch print(int( get_total_seconds(calculated_datetime - datetime(1970,1,1)) )) rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-wrong-insert-syntax.sh0000644000000000000000000000013215055602574022351 xustar0030 mtime=1756824956.026451401 30 atime=1764931162.457663208 30 ctime=1764935933.315731687 rsyslog-8.2512.0/tests/clickhouse-wrong-insert-syntax.sh0000775000175000017500000000233115055602574022017 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo looks like clickhouse does no longer generate exceptions on error - skip until investigated exit 77 export NUMMESSAGES=1 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.wrongInsertSyntax (id, severity, facility, timestamp, ipaddress, tag, message) VLUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, ' add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" user="default" pwd="" template="outfmt" bulkmode="off" errorfile="'$RSYSLOG_OUT_LOG'") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.wrongInsertSyntax ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="DROP TABLE rsyslog.wrongInsertSyntax" content_check "DB::Exception: Syntax error" exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_parsesuccess.sh0000644000000000000000000000013215035412264021346 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.761652045 30 ctime=1764935933.121728717 rsyslog-8.2512.0/tests/mmnormalize_parsesuccess.sh0000775000175000017500000000151015035412264021012 0ustar00rgerrger#!/bin/bash # added 2019-04-11 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmnormalize/.libs/mmnormalize") action(type="mmnormalize" rule= ["rule=: %-:char-to{\"extradata\":\":\"}%:00000000:", "rule=: %-:char-to{\"extradata\":\":\"}%:00000010:"] ) if not ($rawmsg contains "rsyslog") then if $parsesuccess == "OK" then action(type="omfile" file="'$RSYSLOG_OUT_LOG'") else action(type="omfile" file="'$RSYSLOG_DYNNAME'.failed") ' startup injectmsg 0 20 shutdown_when_empty wait_shutdown content_check "msgnum:00000000:" $RSYSLOG_OUT_LOG content_check "msgnum:00000010:" $RSYSLOG_OUT_LOG content_check "msgnum:00000001:" $RSYSLOG_DYNNAME.failed content_check "msgnum:00000012:" $RSYSLOG_DYNNAME.failed exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_tokenized.sh0000644000000000000000000000013215035412264020637 xustar0030 mtime=1752569012.401743799 30 atime=1764931167.399742428 30 ctime=1764935934.744753561 rsyslog-8.2512.0/tests/mmnormalize_tokenized.sh0000775000175000017500000000366615035412264020321 0ustar00rgerrger#!/bin/bash # added 2014-11-03 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[mmnormalize_tokenized.sh\]: test for mmnormalize tokenized field_type . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="ips" type="string" string="%$.ips%\n") template(name="paths" type="string" string="%$!fragments% %$!user%\n") template(name="numbers" type="string" string="nos: %$!some_nos%\n") module(load="../plugins/mmnormalize/.libs/mmnormalize") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_tokenized.rulebase`) if ( $!only_ips != "" ) then { set $.ips = $!only_ips; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips") } else if ( $!local_ips != "" ) then { set $.ips = $!local_ips; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips") } else if ( $!external_ips != "" ) then { set $.ips = $!external_ips; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="ips") } else if ( $!some_nos != "" ) then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="numbers") } else { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="paths") } ' startup tcpflood -m 1 -I $srcdir/testsuites/tokenized_input echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown cp $RSYSLOG_OUT_LOG /tmp/ content_check '[ "10.20.30.40", "50.60.70.80", "90.100.110.120", "130.140.150.160" ]' content_check '[ "192.168.1.2", "192.168.1.3", "192.168.1.4" ]' content_check '[ "10.20.30.40", "50.60.70.80", "190.200.210.220" ]' content_check '[ "\/bin", "\/usr\/local\/bin", "\/usr\/bin" ] foo' content_check '[ [ [ "10" ] ], [ [ "20" ], [ "30", "40", "50" ], [ "60", "70", "80" ] ], [ [ "90" ], [ "100" ] ] ]' exit_test rsyslog-8.2512.0/tests/PaxHeaders/dynstats-json.sh0000644000000000000000000000013115055602574017057 xustar0030 mtime=1756824956.027451414 29 atime=1764931167.37174198 30 ctime=1764935934.736753438 rsyslog-8.2512.0/tests/dynstats-json.sh0000775000175000017500000000356715055602574016542 0ustar00rgerrger#!/bin/bash # added 2016-03-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[dynstats-json.sh\]: test for verifying stats are reported correctly in json format . ${srcdir:=.}/diag.sh init generate_conf add_conf ' dyn_stats(name="stats_one") dyn_stats(name="stats_two") ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="2" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json") template(name="outfmt" type="string" string="%msg%\n") set $.p = field($msg, 32, 1); if ($.p == "foo") then { set $.ign = dyn_inc("stats_one", $.p); set $.ign = dyn_inc("stats_two", $.p); } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log injectmsg_file $srcdir/testsuites/dynstats_input_1 wait_queueempty wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown custom_content_check '{ "name": "global", "origin": "dynstats", "values": { "stats_one.ops_overflow": 0, "stats_one.new_metric_add": 1, "stats_one.no_metric": 0, "stats_one.metrics_purged": 0, "stats_one.ops_ignored": 0, "stats_one.purge_triggered": 0, "stats_two.ops_overflow": 0, "stats_two.new_metric_add": 1, "stats_two.no_metric": 0, "stats_two.metrics_purged": 0, "stats_two.ops_ignored": 0, "stats_two.purge_triggered": 0 } }' "${RSYSLOG_DYNNAME}.out.stats.log" custom_content_check '{ "name": "stats_one", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log" custom_content_check '{ "name": "stats_two", "origin": "dynstats.bucket", "values": { "foo": 1 } }' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-tls-chainedcert.sh0000644000000000000000000000013115055602574020576 xustar0029 mtime=1756824956.03145147 30 atime=1764931164.257692071 30 ctime=1764935933.832739601 rsyslog-8.2512.0/tests/imrelp-tls-chainedcert.sh0000775000175000017500000000234715055602574020254 0ustar00rgerrger#!/bin/bash # addd 2020-08-25 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init require_relpEngineVersion "1.7.0" export NUMMESSAGES=1000 # uncomment for debugging support: # export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # export RSYSLOG_DEBUGLOG="log" # export TCPFLOOD_EXTRA_OPTS="-v" do_skip=0 generate_conf add_conf ' # uncomment for debugging support: # $DebugFile debug.log # $DebugLevel 2 module( load="../plugins/imrelp/.libs/imrelp" tls.tlslib="openssl" ) input(type="imrelp" port="'$TCPFLOOD_PORT'" tls="on" tls.mycert="'$srcdir'/tls-certs/certchained.pem" tls.myprivkey="'$srcdir'/tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup ./tcpflood -u openssl -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/certchained.pem" -Ersyslog 2> $RSYSLOG_DYNNAME.tcpflood cat -n $RSYSLOG_DYNNAME.tcpflood shutdown_when_empty wait_shutdown # uncomment for debugging support: # cat debug.log if [ $do_skip -eq 1 ]; then skip_test fi seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_trim-vg.sh0000644000000000000000000000013115035412264017363 xustar0030 mtime=1752569012.412667365 30 atime=1764931167.839749478 29 ctime=1764935934.87275552 rsyslog-8.2512.0/tests/rscript_trim-vg.sh0000775000175000017500000000566715035412264017051 0ustar00rgerrger#!/bin/bash # add 2017-08-14 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!str!l1 = ltrim(""); set $!str!l2 = ltrim("test"); set $!str!l3 = ltrim(" test"); set $!str!l4 = ltrim("test "); set $!str!l5 = ltrim(" test "); set $!str!l6 = ltrim(" test"); set $!str!l7 = ltrim("test "); set $!str!l8 = ltrim(" "); set $!str!l9 = ltrim("te st"); set $!str!l10 = ltrim(" te st"); set $!str!l11 = ltrim(" a"); set $!str!l12 = ltrim("a "); set $!str!r1 = rtrim(""); set $!str!r2 = rtrim("test"); set $!str!r3 = rtrim(" test"); set $!str!r4 = rtrim("test "); set $!str!r5 = rtrim(" test "); set $!str!r6 = rtrim(" test"); set $!str!r7 = rtrim("test "); set $!str!r8 = rtrim(" "); set $!str!r9 = rtrim("te st"); set $!str!r10 = rtrim("te st "); set $!str!r11 = rtrim(" a"); set $!str!r12 = rtrim("a "); set $!str!b1 = ltrim(" "); set $!str!b1 = rtrim($!str!b1); set $!str!b2 = ltrim(" test "); set $!str!b2 = rtrim($!str!b2); set $!str!b3 = ltrim(" test "); set $!str!b3 = rtrim($!str!b3); set $!str!b4 = ltrim("te st"); set $!str!b4 = rtrim($!str!b4); set $!str!b5 = rtrim(" "); set $!str!b5 = ltrim($!str!b5); set $!str!b6 = rtrim(" test "); set $!str!b6 = ltrim($!str!b6); set $!str!b7 = rtrim(" test "); set $!str!b7 = ltrim($!str!b7); set $!str!b8 = rtrim("te st"); set $!str!b8 = ltrim($!str!b8); set $!str!b9 = rtrim(ltrim("test")); set $!str!b10 = rtrim(ltrim("te st")); set $!str!b11 = rtrim(ltrim(" test")); set $!str!b12 = rtrim(ltrim("test ")); set $!str!b13 = rtrim(ltrim(" test ")); set $!str!b14 = rtrim(ltrim(" te st ")); set $!str!b15 = ltrim(rtrim("test")); set $!str!b16 = ltrim(rtrim("te st")); set $!str!b17 = ltrim(rtrim(" test")); set $!str!b18 = ltrim(rtrim("test ")); set $!str!b19 = ltrim(rtrim(" test ")); set $!str!b20 = ltrim(rtrim(" te st ")); template(name="outfmt" type="string" string="%!str%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg tcpflood -m1 -y shutdown_when_empty wait_shutdown_vg check_exit_vg echo '{ "l1": "", "l2": "test", "l3": "test", "l4": "test ", "l5": "test ", "l6": "test", "l7": "test ", "l8": "", "l9": "te st", "l10": "te st", "l11": "a", "l12": "a ", "r1": "", "r2": "test", "r3": " test", "r4": "test", "r5": " test", "r6": " test", "r7": "test", "r8": "", "r9": "te st", "r10": "te st", "r11": " a", "r12": "a", "b1": "", "b2": "test", "b3": "test", "b4": "te st", "b5": "", "b6": "test", "b7": "test", "b8": "te st", "b9": "test", "b10": "te st", "b11": "test", "b12": "test", "b13": "test", "b14": "te st", "b15": "test", "b16": "te st", "b17": "test", "b18": "test", "b19": "test", "b20": "te st" }' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid function output detected, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/config_output-o-option.sh0000644000000000000000000000013215035412264020660 xustar0030 mtime=1752569012.385854976 30 atime=1764931159.238611566 30 ctime=1764935932.417717941 rsyslog-8.2512.0/tests/config_output-o-option.sh0000775000175000017500000000127415035412264020333 0ustar00rgerrger#!/bin/bash # check that the -o command line option works # added 2019-04-26 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then { include(file="'${srcdir}'/testsuites/include-std-omfile-actio*.conf") continue } ' ../tools/rsyslogd -N1 -f${TESTCONF_NM}.conf -o$RSYSLOG_DYNNAME.fullconf -M../runtime/.libs:../.libs content_check 'if $msg contains "msgnum:" then' $RSYSLOG_DYNNAME.fullconf content_check 'action(type="omfile"' $RSYSLOG_DYNNAME.fullconf content_check --regex "BEGIN CONFIG: .*include-std-omfile-action.conf" $RSYSLOG_DYNNAME.fullconf exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmpstrucdata.sh0000644000000000000000000000013215035412264016735 xustar0030 mtime=1752569012.401743799 30 atime=1764931167.032736548 30 ctime=1764935934.643752015 rsyslog-8.2512.0/tests/mmpstrucdata.sh0000775000175000017500000000127215035412264016406 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # rgerhards, 2013-11-22 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata") module(load="../plugins/imtcp/.libs/imtcp") template(name="outfmt" type="string" string="%$!rfc5424-sd!tcpflood@32473!msgnum%\n") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmpstrucdata") if $msg contains "msgnum" then action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m100 -y shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omjournal-abort-template.sh0000644000000000000000000000013215035412264021155 xustar0030 mtime=1752569012.404722953 30 atime=1764931161.617649735 30 ctime=1764935933.081728105 rsyslog-8.2512.0/tests/omjournal-abort-template.sh0000775000175000017500000000120315035412264020620 0ustar00rgerrger#!/bin/bash # a very basic test for omjournal. Right now, we have no # reliable way of verifying that data was actually written # to the journal, but at least we check that rsyslog does # not abort when trying to use omjournal. Not high tech, # but better than nothing. # addd 2016-03-16 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omjournal/.libs/omjournal") template(name="outfmt" type="string" string="%msg%") action(type="omjournal" template="outfmt") ' startup ./msleep 500 shutdown_when_empty wait_shutdown # if we reach this, we have at least not aborted exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-basic.sh0000644000000000000000000000013115035412264016577 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.001687967 30 ctime=1764935933.762738529 rsyslog-8.2512.0/tests/imrelp-basic.sh0000775000175000017500000000104615035412264016250 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 # MUST be an even number! generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") input(type="imrelp" port="'$TCPFLOOD_PORT'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/now-utc-ymd.sh0000644000000000000000000000013215055602574016423 xustar0030 mtime=1756824956.034451512 30 atime=1764931161.542648532 30 ctime=1764935933.060727784 rsyslog-8.2512.0/tests/now-utc-ymd.sh0000775000175000017500000000161615055602574016076 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # addd 2016-02-23 by RGerhards, released under ASL 2.0 # requires faketime . ${srcdir:=.}/diag.sh init echo \[now-utc-ymd\]: test \$year-utc, \$month-utc, \$day-utc . $srcdir/faketime_common.sh export TZ=TEST-02:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$year%-%$month%-%$day%,%$year-utc%-%$month-utc%-%$day-utc%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' FAKETIME='2016-01-01 01:00:00' startup # what we send actually is irrelevant, as we just use system properties. # but we need to send one message in order to gain output! tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="2016-01-01,2015-12-31" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_trim.sh0000644000000000000000000000013215035412264016752 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.668618466 30 ctime=1764935932.537719778 rsyslog-8.2512.0/tests/rscript_trim.sh0000775000175000017500000000564315035412264016431 0ustar00rgerrger#!/bin/bash # add 2017-08-14 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!str!l1 = ltrim(""); set $!str!l2 = ltrim("test"); set $!str!l3 = ltrim(" test"); set $!str!l4 = ltrim("test "); set $!str!l5 = ltrim(" test "); set $!str!l6 = ltrim(" test"); set $!str!l7 = ltrim("test "); set $!str!l8 = ltrim(" "); set $!str!l9 = ltrim("te st"); set $!str!l10 = ltrim(" te st"); set $!str!l11 = ltrim(" a"); set $!str!l12 = ltrim("a "); set $!str!r1 = rtrim(""); set $!str!r2 = rtrim("test"); set $!str!r3 = rtrim(" test"); set $!str!r4 = rtrim("test "); set $!str!r5 = rtrim(" test "); set $!str!r6 = rtrim(" test"); set $!str!r7 = rtrim("test "); set $!str!r8 = rtrim(" "); set $!str!r9 = rtrim("te st"); set $!str!r10 = rtrim("te st "); set $!str!r11 = rtrim(" a"); set $!str!r12 = rtrim("a "); set $!str!b1 = ltrim(" "); set $!str!b1 = rtrim($!str!b1); set $!str!b2 = ltrim(" test "); set $!str!b2 = rtrim($!str!b2); set $!str!b3 = ltrim(" test "); set $!str!b3 = rtrim($!str!b3); set $!str!b4 = ltrim("te st"); set $!str!b4 = rtrim($!str!b4); set $!str!b5 = rtrim(" "); set $!str!b5 = ltrim($!str!b5); set $!str!b6 = rtrim(" test "); set $!str!b6 = ltrim($!str!b6); set $!str!b7 = rtrim(" test "); set $!str!b7 = ltrim($!str!b7); set $!str!b8 = rtrim("te st"); set $!str!b8 = ltrim($!str!b8); set $!str!b9 = rtrim(ltrim("test")); set $!str!b10 = rtrim(ltrim("te st")); set $!str!b11 = rtrim(ltrim(" test")); set $!str!b12 = rtrim(ltrim("test ")); set $!str!b13 = rtrim(ltrim(" test ")); set $!str!b14 = rtrim(ltrim(" te st ")); set $!str!b15 = ltrim(rtrim("test")); set $!str!b16 = ltrim(rtrim("te st")); set $!str!b17 = ltrim(rtrim(" test")); set $!str!b18 = ltrim(rtrim("test ")); set $!str!b19 = ltrim(rtrim(" test ")); set $!str!b20 = ltrim(rtrim(" te st ")); template(name="outfmt" type="string" string="%!str%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown echo '{ "l1": "", "l2": "test", "l3": "test", "l4": "test ", "l5": "test ", "l6": "test", "l7": "test ", "l8": "", "l9": "te st", "l10": "te st", "l11": "a", "l12": "a ", "r1": "", "r2": "test", "r3": " test", "r4": "test", "r5": " test", "r6": " test", "r7": "test", "r8": "", "r9": "te st", "r10": "te st", "r11": " a", "r12": "a", "b1": "", "b2": "test", "b3": "test", "b4": "te st", "b5": "", "b6": "test", "b7": "test", "b8": "te st", "b9": "test", "b10": "te st", "b11": "test", "b12": "test", "b13": "test", "b14": "te st", "b15": "test", "b16": "te st", "b17": "test", "b18": "test", "b19": "test", "b20": "te st" }' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid function output detected, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-redis-restart.sh0000644000000000000000000000013215055602574021003 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.958639164 30 ctime=1764935932.888725151 rsyslog-8.2512.0/tests/imhiredis-redis-restart.sh0000775000175000017500000000275615055602574020464 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init # Start redis once to be able to generate configuration start_redis redis_command "RPUSH mykey message1" redis_command "RPUSH mykey message2" redis_command "RPUSH mykey message3" generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mykey" mode="queue" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup wait_content '3 message1' # Stop Redis and wait a short moment for imhiredis to notice Redis went down stop_redis rst_msleep 1500 start_redis redis_command "RPUSH mykey message4" redis_command "RPUSH mykey message5" redis_command "RPUSH mykey message6" wait_content '4 message6' shutdown_when_empty wait_shutdown stop_redis content_check '1 message3' content_check '2 message2' content_check '3 message1' content_check 'sleeping 10 seconds before retrying' content_check '4 message6' content_check '5 message5' content_check '6 message4' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-close-unresponsive.sh0000644000000000000000000000013215035412264021375 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.177706819 30 ctime=1764935934.092743581 rsyslog-8.2512.0/tests/omprog-close-unresponsive.sh0000775000175000017500000000310415035412264021042 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test checks that omprog sends a TERM signal to the external # program when signalOnClose=on, closes the pipe, and kills the # child if unresponsive. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") main_queue( queue.timeoutShutdown="60000" # give time to omprog to wait for the child ) :msg, contains, "msgnum:" { action( type="omprog" binary="'$RSYSLOG_DYNNAME.'omprog-close-unresponsive-bin.sh" template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process confirmMessages="on" # facilitates sync with the child process signalOnClose="on" closeTimeout="1000" # ms #killUnresponsive="on" # default value: the value of signalOnClose ) } ' cp -f $srcdir/testsuites/omprog-close-unresponsive-bin.sh $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh startup injectmsg 0 10 shutdown_when_empty wait_shutdown . $srcdir/diag.sh ensure-no-process-exists $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh export EXPECTED="Starting Received msgnum:00000000: Received msgnum:00000001: Received msgnum:00000002: Received msgnum:00000003: Received msgnum:00000004: Received msgnum:00000005: Received msgnum:00000006: Received msgnum:00000007: Received msgnum:00000008: Received msgnum:00000009: Received SIGTERM Terminating unresponsively" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-jsonarray-compress-vg.sh0000644000000000000000000000013215035412264023074 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.035704543 30 ctime=1764935934.049742923 rsyslog-8.2512.0/tests/omhttp-batch-jsonarray-compress-vg.sh0000775000175000017500000000013515035412264022542 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-batch-jsonarray-compress.sh rsyslog-8.2512.0/tests/PaxHeaders/localvar-concurrency.sh0000644000000000000000000000013215035412264020364 xustar0030 mtime=1752569012.399757696 30 atime=1764931161.133641971 30 ctime=1764935932.939725932 rsyslog-8.2512.0/tests/localvar-concurrency.sh0000775000175000017500000000225515035412264020037 0ustar00rgerrger#!/bin/bash # Test concurrency of message variables # Added 2015-11-03 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[localvar-concurrency.sh\]: testing concurrency of local variables uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$.tree!here!nbr%\n") if $msg contains "msgnum:" then { set $.tree!here!nbr = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList") set $.tree!here!save = $.tree!here!nbr; set $.tree!here!nbr = ""; set $.tree!here!nbr = $.tree!here!save; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup sleep 1 tcpflood -m500000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 499999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-multiplehttpheaders.sh0000644000000000000000000000013115055602574021637 xustar0030 mtime=1756824956.035451526 29 atime=1764931164.99370387 30 ctime=1764935934.037742739 rsyslog-8.2512.0/tests/omhttp-multiplehttpheaders.sh0000775000175000017500000000152415055602574021311 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 omhttp_start_server 0 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../contrib/omhttp/.libs/omhttp") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" httpheaders=[ "X-Insert-Key: dummy-value", "X-Event-Source: logs" ] server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="off" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/NoExistFile.cfgtest0000644000000000000000000000013215035412264017447 xustar0030 mtime=1752569012.384861924 30 atime=1764931158.793604424 30 ctime=1764935932.289715982 rsyslog-8.2512.0/tests/NoExistFile.cfgtest0000664000175000017500000000030415035412264017110 0ustar00rgerrgerrsyslogd: CONFIG ERROR: could not interpret master config file '/This/does/not/exist'. [try https://www.rsyslog.com/e/2013 ] rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file! rsyslog-8.2512.0/tests/PaxHeaders/omjournal-abort-no-template.sh0000644000000000000000000000013215035412264021567 xustar0030 mtime=1752569012.404722953 30 atime=1764931161.625649863 30 ctime=1764935933.084728151 rsyslog-8.2512.0/tests/omjournal-abort-no-template.sh0000775000175000017500000000107415035412264021240 0ustar00rgerrger#!/bin/bash # a very basic test for omjournal. Right now, we have no # reliable way of verifying that data was actually written # to the journal, but at least we check that rsyslog does # not abort when trying to use omjournal. Not high tech, # but better than nothing. # addd 2016-03-16 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omjournal/.libs/omjournal") action(type="omjournal") ' startup ./msleep 500 shutdown_when_empty wait_shutdown # if we reach this, we have at least not aborted exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmdarwin_errmsg_no_sock-vg.sh0000644000000000000000000000013215035412264021553 xustar0030 mtime=1752569012.400750748 30 atime=1764931160.169626505 30 ctime=1764935932.664721722 rsyslog-8.2512.0/tests/mmdarwin_errmsg_no_sock-vg.sh0000775000175000017500000000022115035412264021215 0ustar00rgerrger#!/bin/bash # add 2019-04-02 by Rainer Gerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/mmdarwin_errmsg_no_sock.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-basic-vg.sh0000644000000000000000000000013215035412264017167 xustar0030 mtime=1752569012.391813284 30 atime=1764931165.837717398 30 ctime=1764935934.288746581 rsyslog-8.2512.0/tests/imfile-basic-vg.sh0000775000175000017500000000011215035412264016630 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/imfile-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/ruleset-direct-queue.sh0000644000000000000000000000013215055602574020315 xustar0030 mtime=1756824956.039451582 30 atime=1764931162.775668308 30 ctime=1764935933.403733034 rsyslog-8.2512.0/tests/ruleset-direct-queue.sh0000775000175000017500000000121015055602574017756 0ustar00rgerrger#!/bin/bash # check that ruleset is called synchronously when queue.type="direct" is # specified in ruleset. # added 2021-09-17 by rgerhards. Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf export STATSFILE="$RSYSLOG_DYNNAME.stats" add_conf ' template(name="outfmt" type="string" string="%msg%,%$.msg%\n") ruleset(name="rs1" queue.type="direct") { set $.msg = "TEST"; } if $msg contains "msgnum:" then { set $.msg = $msg; call rs1 action(type="omfile" name="main-action" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown content_check "msgnum:00000000:,TEST" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imkafka_multi_group.sh0000644000000000000000000000013215071746523020272 xustar0030 mtime=1760021843.890421806 30 atime=1764931166.865733872 30 ctime=1764935934.599751342 rsyslog-8.2512.0/tests/imkafka_multi_group.sh0000775000175000017500000000637115071746523017750 0ustar00rgerrger#!/bin/bash # added 2018-08-29 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init check_command_available kcat echo TEST unclear in regard to load balancing - currently skipping it. exit 77 export KEEP_KAFKA_RUNNING="YES" # False positive codefactor.io export RSYSLOG_OUT_LOG_1="${RSYSLOG_OUT_LOG:-default}.1" export RSYSLOG_OUT_LOG_2="${RSYSLOG_OUT_LOG:-default}.2" export TESTMESSAGES=100000 # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. #export EXTRA_EXITCHECK=dumpkafkalogs #export EXTRA_EXIT=kafka download_kafka stop_zookeeper stop_kafka start_zookeeper start_kafka export RANDTOPIC="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" create_kafka_topic $RANDTOPIC '.dep_wrk' '22181' # Create FIRST rsyslog instance export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") module(load="../plugins/imkafka/.libs/imkafka") /* Polls messages from kafka server!*/ input( type="imkafka" topic="'$RANDTOPIC'" broker="127.0.0.1:29092" consumergroup="rsysloggroup" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=5000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "enable.partition.eof=false" ] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if ($msg contains "msgnum:") then { action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) action( type="omfile" file=`echo $RSYSLOG_OUT_LOG_1` template="outfmt" ) } ' echo Starting first rsyslog instance [imkafka] startup # Create SECOND rsyslog instance export RSYSLOG_DEBUGLOG="log2" generate_conf 2 add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") module(load="../plugins/imkafka/.libs/imkafka") /* Polls messages from kafka server!*/ input( type="imkafka" topic="'$RANDTOPIC'" broker="localhost:29092" consumergroup="rsysloggroup" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=5000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "enable.partition.eof=false" ] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if ($msg contains "msgnum:") then { action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) action( type="omfile" file=`echo $RSYSLOG_OUT_LOG_2` template="outfmt" ) } ' 2 echo Starting second rsyslog instance [imkafka] startup 2 TIMESTART=$(date +%s.%N) injectmsg_kcat # special case: number of test messages differs from file output wait_file_lines $RSYSLOG_OUT_LOG $((TESTMESSAGES)) ${RETRIES:-200} # Check that at least 25% messages are in both logfiles, otherwise load balancing hasn't worked wait_file_lines $RSYSLOG_OUT_LOG_1 $((TESTMESSAGES/4)) ${RETRIES:-200} wait_file_lines $RSYSLOG_OUT_LOG_2 $((TESTMESSAGES/4)) ${RETRIES:-200} echo Stopping first rsyslog instance [imkafka] shutdown_when_empty wait_shutdown echo Stopping second rsyslog instance [imkafka] shutdown_when_empty 2 wait_shutdown 2 TIMEEND=$(date +%s.%N) TIMEDIFF=$(echo "$TIMEEND - $TIMESTART" | bc) echo "*** imkafka time to process all data: $TIMEDIFF seconds!" delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181' seq_check 1 $TESTMESSAGES -d exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_re_match-dbl_quotes.sh0000644000000000000000000000013215035412264021720 xustar0030 mtime=1752569012.412667365 30 atime=1764931167.766748309 30 ctime=1764935934.850755184 rsyslog-8.2512.0/tests/rscript_re_match-dbl_quotes.sh0000775000175000017500000000105315035412264021366 0ustar00rgerrger#!/bin/bash # Test that '$' in double-quoted string constants raise a meaningful # error message and do not cause rsyslog to segfault. # added 2019-12-30 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' action(type="omfile" file="'$RSYSLOG_OUT_LOG'") # order is important ... set $!test="test$" # ... as after this syntax error nothing is really taken up ' startup shutdown_when_empty wait_shutdown content_check '$-sign in double quotes must be escaped' exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_ruleset.sh0000644000000000000000000000013215035412264021175 xustar0030 mtime=1752569012.397771593 30 atime=1764931166.518728311 30 ctime=1764935934.499749811 rsyslog-8.2512.0/tests/imuxsock_logger_ruleset.sh0000775000175000017500000000144115035412264020644 0ustar00rgerrger#!/bin/bash # test imuxsock with ruleset definition # rgerhards, 2016-02-02 released under ASL 2.0 . ${srcdir:=.}/diag.sh init check_logger_has_option_d generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket" useSpecialParser="off" ruleset="testruleset" parseHostname="on") template(name="outfmt" type="string" string="%msg:%\n") ruleset(name="testruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup # send a message with trailing LF logger -d -u $RSYSLOG_DYNNAME-testbench_socket test # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty wait_shutdown export EXPECTED=" test" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdropabortonidfaillegacy.sh0000644000000000000000000000013215055602574022030 xustar0030 mtime=1756824956.037451554 30 atime=1764931161.299644634 30 ctime=1764935932.988726681 rsyslog-8.2512.0/tests/privdropabortonidfaillegacy.sh0000775000175000017500000000174615055602574021507 0ustar00rgerrger#!/bin/bash # add 2021-10-12 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" skip_platform "SunOS" "This test currently does not work on Solaris." export TESTBENCH_TESTUSER1="USER_${RSYSLOG_DYNNAME}_1" export TESTBENCH_TESTUSER2="USER_${RSYSLOG_DYNNAME}_2" generate_conf add_conf ' global( security.abortOnIDResolutionFail="off" ) template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } $FileOwner '${TESTBENCH_TESTUSER1}' $FileGroup '${TESTBENCH_TESTUSER1}' $DirOwner '${TESTBENCH_TESTUSER2}' $DirGroup '${TESTBENCH_TESTUSER2}' action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup shutdown_when_empty wait_shutdown content_check --regex "ID for user '${TESTBENCH_TESTUSER1}' could not be found" content_check --regex "ID for user '${TESTBENCH_TESTUSER2}' could not be found" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_number_comparison_LT.sh0000644000000000000000000000013215055602574022127 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.471615305 30 ctime=1764935932.485718982 rsyslog-8.2512.0/tests/rscript_number_comparison_LT.sh0000775000175000017500000000104215055602574021573 0ustar00rgerrger#!/bin/bash # added 2022-01-27 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!result") constant(value="\n") } set $!lower_nr = 1111; set $!higher_nr = 2222; if $!higher_nr < $!lower_nr then { set $!result = "WRONG"; } else { set $!result = "RIGHT"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup shutdown_when_empty wait_shutdown content_check 'RIGHT' exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_errmsg_no_params-vg.sh0000644000000000000000000000013215035412264021556 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.565697008 30 ctime=1764935933.920740948 rsyslog-8.2512.0/tests/improg_errmsg_no_params-vg.sh0000775000175000017500000000023015035412264021220 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/improg_errmsg_no_params.sh rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream.sh0000644000000000000000000000013215055602574017506 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.009639982 30 ctime=1764935932.902725365 rsyslog-8.2512.0/tests/imhiredis-stream.sh0000775000175000017500000000246115055602574017160 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis # Won't be logged by Rsyslog redis_command "XADD mystream * msg message1" redis_command "XADD mystream * msg message2" redis_command "XADD mystream * msg message3" generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %$!msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mystream" mode="stream" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup redis_command "XADD mystream * msg message4" redis_command "XADD mystream * msg message5" redis_command "XADD mystream * msg message6" shutdown_when_empty wait_shutdown stop_redis check_not_present "message1" check_not_present "message2" check_not_present "message3" content_check '1 message4' content_check '2 message5' content_check '3 message6' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-multi-drvr-basic.sh0000644000000000000000000000013115055602574020535 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.008672044 30 ctime=1764935933.473734106 rsyslog-8.2512.0/tests/imtcp-multi-drvr-basic.sh0000775000175000017500000000246415055602574020213 0ustar00rgerrger#!/bin/bash # This test checks imtcp functionality with multiple drivers running together. It is # a minimal test. # added 2021-04-27 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 # must be even number! export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2" tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem tcpflood -p$TCPFLOOD_PORT2 -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2)) shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-if-error.sh0000644000000000000000000000013215055603742017264 xustar0030 mtime=1756825570.302069124 30 atime=1764931165.253708037 30 ctime=1764935934.114743917 rsyslog-8.2512.0/tests/omprog-if-error.sh0000775000175000017500000000227315055603742016737 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests omprog if omprog detects errors in the calling # interface, namely a missing LF on input messages . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%") if (prifilt("local4.*") and $msg contains "msgnum:") then { action(type="omprog" binary="'$srcdir'/testsuites/omprog-defaults-bin.sh p1 p2 p3" template="outfmt" name="omprog_action") } else { action(type="omfile" file="'$RSYSLOG_DYNNAME'.othermsg") } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown cat $RSYSLOG_DYNNAME.othermsg content_check 'must be terminated with \n' $RSYSLOG_DYNNAME.othermsg export EXPECTED="Starting with parameters: p1 p2 p3 Next parameter is \"p1\" Next parameter is \"p2\" Next parameter is \"p3\" Received msgnum:00000000: Received msgnum:00000001: Received msgnum:00000002: Received msgnum:00000003: Received msgnum:00000004: Received msgnum:00000005: Received msgnum:00000006: Received msgnum:00000007: Received msgnum:00000008: Received msgnum:00000009: Terminating normally" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_traillf_root.sh0000644000000000000000000000013215035412264020653 xustar0030 mtime=1752569012.397771593 30 atime=1764931166.566729081 30 ctime=1764935934.513750025 rsyslog-8.2512.0/tests/imuxsock_traillf_root.sh0000775000175000017500000000216615035412264020327 0ustar00rgerrger#!/bin/bash # note: we must be root and no other syslogd running in order to # carry out this test echo \[imuxsock_traillf_root.sh\]: test trailing LF handling in imuxsock echo This test must be run as root with no other active syslogd if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imuxsock/.libs/imuxsock $template outfmt,"%msg:%\n" local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # send a message with trailing LF ./syslog_caller -fsyslog_inject-l -m1 # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_traillf.log if [ ! $? -eq 0 ]; then echo "imuxsock_traillf_root.sh failed" exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-x509name.sh0000644000000000000000000000013215055603742020474 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.300676727 30 ctime=1764935933.558735407 rsyslog-8.2512.0/tests/imtcp-tls-ossl-x509name.sh0000775000175000017500000000231515055603742020144 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/name" PermittedPeer=["/CN=rsyslog-client/OU=Adiscon GmbH/O=Adiscon GmbH/L=Grossrinderfeld/ST=BW/C=DE/DC=rsyslog.com","rsyslog.com"] ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/asynwr_timeout.sh0000644000000000000000000000013215055602574017331 xustar0030 mtime=1756824956.026451401 30 atime=1764931165.453711243 30 ctime=1764935934.176744867 rsyslog-8.2512.0/tests/asynwr_timeout.sh0000775000175000017500000000220215055602574016774 0ustar00rgerrger#!/bin/bash # This test writes to the output buffers, let's the output # write timeout (and write data) and then continue. The conf file # has a 2 second timeout, so we wait 4 seconds to be on the save side. # # added 2010-03-09 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # send 35555 messages, make sure file size is not a multiple of # 10K, the buffer size! export NUMMESSAGES=15555 generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 10000 input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'") $OMFileFlushOnTXEnd off $OMFileFlushInterval 2 $OMFileIOBufferSize 10k $OMFileAsyncWriting on :msg, contains, "msgnum:" ?dynfile;outfmt ' startup tcpflood -m $NUMMESSAGES printf 'waiting for timeout to occur\n' sleep 15 # GOOD SLEEP - we wait for the timeout! long to take care of slow test machines... printf 'timeout should now have occurred - check file state\n' seq_check shutdown_when_empty wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/msgvar-concurrency.sh0000644000000000000000000000013215035412264020060 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.092641313 30 ctime=1764935932.927725748 rsyslog-8.2512.0/tests/msgvar-concurrency.sh0000775000175000017500000000172315035412264017532 0ustar00rgerrger#!/bin/bash # Test concurrency of message variables # Added 2015-11-03 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$!tree!here!nbr%\n") if $msg contains "msgnum:" then { set $!tree!here!nbr = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList") set $!tree!here!save = $!tree!here!nbr; set $!tree!here!nbr = ""; set $!tree!here!nbr = $!tree!here!save; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m500000 shutdown_when_empty wait_shutdown seq_check 0 499999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_ipv6_port.sh0000644000000000000000000000013215055602574017535 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.391630067 30 ctime=1764935932.727722686 rsyslog-8.2512.0/tests/mmanon_ipv6_port.sh0000775000175000017500000000342315055602574017206 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv6.anonmode="zero") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f:4024:d991:ec2e:4922 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f:4024:d991:ec2e <129>Mar 10 01:00:00 172.20.245.8 tag: [1a00:c820:1180:c84c:ad3f:4024:d991:ec2e]:4922 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f::d991:ec2e:4922 <129>Mar 10 01:00:00 172.20.245.8 tag: [1a00:c820:1180:c84c:ad3f::d991:ec2e]:4922 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:1180:c84c:ad3f::d991:ec2e:49225 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:4922:4922:c84c:ad3f::d991:ec2e:49225 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:4922:1180:c84c:ad3f::d991:4922:49225 <129>Mar 10 01:00:00 172.20.245.8 tag: 1a00:c820:49225:c84c:ad3f::d991:ec2e:49225\"" # see this github comment on limits of IP address detection: # https://github.com/rsyslog/rsyslog/issues/4856#issuecomment-1108445473 shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk 1a00:c820:0:0:0:0:0:0:4922 1a00:c820:0:0:0:0:0:0 [1a00:c820:0:0:0:0:0:0]:4922 1a00:c820:1180:0:0:0:0:0:0 [1a00:c820:0:0:0:0:0:0]:4922 1a00:c820:0:0:0:0:0:0:49225 1a00:4922:0:0:0:0:0:0:49225 1a00:4922:0:0:0:0:0:0:49225 1a00:c820:49225:c84c:0:0:0:0:0:0:49225' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-transactions.sh0000644000000000000000000000013215035412264020242 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.262708182 30 ctime=1764935934.116743948 rsyslog-8.2512.0/tests/omprog-transactions.sh0000775000175000017500000001001215035412264017703 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests omprog with the confirmMessages=on and useTransactions=on # parameters, with the external program successfully confirming all messages # and transactions. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh` template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process queue.dequeueBatchSize="6" confirmMessages="on" useTransactions="on" beginTransactionMark="BEGIN TRANSACTION" commitTransactionMark="COMMIT TRANSACTION" action.resumeRetryCount="10" action.resumeInterval="1" ) } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown # Since the transaction boundaries are not deterministic, we cannot check for # an exact expected output. We must check the output programmatically. transaction_state="NONE" status_expected=true messages_to_commit=() messages_processed=() line_num=1 error= while IFS= read -r line; do if [[ $status_expected == true ]]; then case "$transaction_state" in "NONE") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi ;; "STARTED") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi transaction_state="ACTIVE" ;; "ACTIVE") if [[ "$line" != "<= DEFER_COMMIT" ]]; then error="expecting a DEFER_COMMIT status from script" break fi ;; "COMMITTED") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi messages_processed+=("${messages_to_commit[@]}") messages_to_commit=() transaction_state="NONE" ;; esac status_expected=false; else if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then if [[ "$transaction_state" != "NONE" ]]; then error="unexpected transaction start" break fi transaction_state="STARTED" elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected transaction commit" break fi transaction_state="COMMITTED" else if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected message outside a transaction" break fi if [[ "$line" != "=> msgnum:"* ]]; then error="unexpected message contents" break fi prefix_to_remove="=> " messages_to_commit+=("${line#$prefix_to_remove}") fi status_expected=true; fi ((line_num++)) done < $RSYSLOG_OUT_LOG if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then error="unexpected end of file (transaction state: $transaction_state)" fi if [[ -n "$error" ]]; then echo "$RSYSLOG_OUT_LOG: line $line_num: $error" cat $RSYSLOG_OUT_LOG error_exit 1 fi expected_messages=( "msgnum:00000000:" "msgnum:00000001:" "msgnum:00000002:" "msgnum:00000003:" "msgnum:00000004:" "msgnum:00000005:" "msgnum:00000006:" "msgnum:00000007:" "msgnum:00000008:" "msgnum:00000009:" ) if [[ "${messages_processed[*]}" != "${expected_messages[*]}" ]]; then echo "unexpected set of processed messages:" printf '%s\n' "${messages_processed[@]}" echo "contents of $RSYSLOG_OUT_LOG:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-dynrestpath.sh0000644000000000000000000000013215055602574021175 xustar0030 mtime=1756824956.035451526 30 atime=1764931165.010704142 30 ctime=1764935934.042742815 rsyslog-8.2512.0/tests/omhttp-batch-dynrestpath.sh0000775000175000017500000000203515055602574020644 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" omhttp_start_server 0 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") template(name="dynrestpath" type="string" string="my/endpoint") module(load="../contrib/omhttp/.libs/omhttp") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" dynrestpath = "on" restpath="dynrestpath" batch="on" batch.format="jsonarray" batch.maxsize="1000" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_conflict1.sh0000644000000000000000000000013215055602574021750 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.914622414 30 ctime=1764935932.593720635 rsyslog-8.2512.0/tests/rscript_unflatten_conflict1.sh0000775000175000017500000000245415055602574021424 0ustar00rgerrger#!/bin/bash # added 2021-03-09 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $!a!b = "foo"; set $!a.b.c = "bar"; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 1 wait_file_lines "$RSYSLOG_OUT_LOG" 1 60 shutdown_when_empty wait_shutdown # this test may need changes to produce a more deterministic # output by sorting keys EXPECTED=' msgnum:00000000: 0 { "a": { "b": { "c": "bar" } } }' cmp_exact "$RSYSLOG_OUT_LOG" EXPECTED='fmunflatten.c: warning: while processing flat key "a.b.c" at depth #1 (intermediate node), overriding existing value of type string by an object' if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then echo "GREP FAILED" echo " => FILE: $RSYSLOG_DEBUGLOG" echo " => EXPECTED: $EXPECTED" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/proprepltest-rfctag.sh0000644000000000000000000000013215035412264020240 xustar0030 mtime=1752569012.408695159 30 atime=1764931159.072608902 30 ctime=1764935932.368717191 rsyslog-8.2512.0/tests/proprepltest-rfctag.sh0000775000175000017500000000211015035412264017701 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="+%syslogtag:1:32%+\n") :pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\"" shutdown_when_empty wait_shutdown echo '+TAG:+ +0+ +01234567890123456789012345678901+ +01234567890123456789012345678901+' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_random.sh0000644000000000000000000000013115035412264017256 xustar0030 mtime=1752569012.412667365 30 atime=1764931167.441743102 29 ctime=1764935934.75575373 rsyslog-8.2512.0/tests/rscript_random.sh0000775000175000017500000000142115035412264016724 0ustar00rgerrger#!/bin/bash # added 2015-06-22 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_random.sh\]: test for random-number-generator script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.random_no%\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.random_no = random(10); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 20 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown . $srcdir/diag.sh content-pattern-check "^[0-9]$" exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_prog_simple-vg.sh0000644000000000000000000000013115035412264020537 xustar0030 mtime=1752569012.394792439 29 atime=1764931164.61069773 30 ctime=1764935933.932741132 rsyslog-8.2512.0/tests/improg_prog_simple-vg.sh0000775000175000017500000000022315035412264020204 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/improg_prog_simple.sh rsyslog-8.2512.0/tests/PaxHeaders/abort-uncleancfg-goodcfg-check.sh0000644000000000000000000000013215035412264022124 xustar0030 mtime=1752569012.384861924 30 atime=1764931165.554712862 30 ctime=1764935934.204745295 rsyslog-8.2512.0/tests/abort-uncleancfg-goodcfg-check.sh0000775000175000017500000000070715035412264021577 0ustar00rgerrger#!/bin/bash # Copyright 2015-01-29 by Tim Eifler # This file is part of the rsyslog project, released under ASL 2.0 # The configuration test should pass because of the good config file. . ${srcdir:=.}/diag.sh init echo "testing a good Configuration verification run" ../tools/rsyslogd -C -N1 -f$srcdir/testsuites/abort-uncleancfg-goodcfg.conf -M../runtime/.libs:../.libs if [ $? -ne 0 ]; then echo "Error: config check fail" exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/perctile-simple-vg.sh0000644000000000000000000000013115055602574017747 xustar0029 mtime=1756824956.03645154 30 atime=1764931167.308740971 30 ctime=1764935934.720753194 rsyslog-8.2512.0/tests/perctile-simple-vg.sh0000775000175000017500000000011515055602574017414 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/perctile-simple.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-endregex-save-lf.sh0000644000000000000000000000013215055602574020637 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.730715683 30 ctime=1764935934.256746091 rsyslog-8.2512.0/tests/imfile-endregex-save-lf.sh0000775000175000017500000000313015055602574020303 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # This test mimics the test imfile-readmode2.sh, but works via # endmsg.regex. It's kind of a base test for the regex functionality. echo ====================================================================== echo [imfile-endregex-save-lf.sh] . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" startmsg.regex="^[^ ]") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1 msgnum:2' > $RSYSLOG_DYNNAME.input # the next line terminates our test. It is NOT written to the output file, # as imfile waits whether or not there is a follow-up line that it needs # to combine. echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing ./msleep 500 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! printf 'HEADER msgnum:0\\\\n msgnum:1\\\\n msgnum:2\n' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-bulk-load.sh0000644000000000000000000000013115035412264020231 xustar0030 mtime=1752569012.385854976 29 atime=1764931162.40666239 30 ctime=1764935933.301731473 rsyslog-8.2512.0/tests/clickhouse-bulk-load.sh0000775000175000017500000000171615035412264017706 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100000 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.bulkLoad (id, ipaddress, message) VALUES (%msg:F,58:2%, ' add_conf "'%fromhost-ip%', '%msg:F,58:2%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" user="default" pwd="" template="outfmt") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.bulkLoad ( id Int32, ipaddress String, message String ) ENGINE = MergeTree() PARTITION BY ipaddress Order By id" startup injectmsg shutdown_when_empty wait_shutdown clickhouse-client --query="SELECT message FROM rsyslog.bulkLoad ORDER BY id" > $RSYSLOG_OUT_LOG clickhouse-client --query="DROP TABLE rsyslog.bulkLoad" seq_check 0 $(( NUMMESSAGES - 1 )) exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-rule_and_rulebase-vg.sh0000644000000000000000000000013215035412264022651 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.936654852 30 ctime=1764935933.170729467 rsyslog-8.2512.0/tests/pmnormalize-rule_and_rulebase-vg.sh0000775000175000017500000000023115035412264022314 0ustar00rgerrger#!/bin/bash # added 2019-04-10 by Rainer Gerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/pmnormalize-rule_and_rulebase.sh rsyslog-8.2512.0/tests/PaxHeaders/fac_ftp.sh0000644000000000000000000000013215055602574015642 xustar0030 mtime=1756824956.027451414 30 atime=1764931161.458647184 30 ctime=1764935933.035727401 rsyslog-8.2512.0/tests/fac_ftp.sh0000775000175000017500000000105715055602574015314 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" ftp.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m$NUMMESSAGES -P 89 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-snare_ccoff_udp2.sh0000644000000000000000000000013215035412264021625 xustar0030 mtime=1752569012.406709056 30 atime=1764931159.020608068 30 ctime=1764935932.354716976 rsyslog-8.2512.0/tests/parsertest-snare_ccoff_udp2.sh0000775000175000017500000000537315035412264021304 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") $EscapeControlCharactersOnReceive off template(name="outfmt" type="string" string="insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (%msg:::space-cc%, %syslogfacility%, %HOSTNAME%,%syslogpriority%, 20100321185328, 20100321185328, %iut%, %syslogtag:::space-cc%)\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"test\"" tcpflood -m1 -T "udp" -M "\"UX=Abcd-efg-hij-klmno; XXXXX=1111111111, Z123=192.12.231.245:11111, S1234=123456789, XXXXXX=111111111\"" tcpflood -m1 -T "udp" -M "\"windowsserver MSWinEventLog 1 Security 1167 Fri Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733\\\n\"" shutdown_when_empty wait_shutdown export EXPECTED="insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (, 1, test,5, 20100321185328, 20100321185328, 1, ) insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ( XXXXX=1111111111, Z123=192.12.231.245:11111, S1234=123456789, XXXXXX=111111111, 1, $RS_HOSTNAME,5, 20100321185328, 20100321185328, 1, UX=Abcd-efg-hij-klmno;) insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ( Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733\n, 1, $RS_HOSTNAME,5, 20100321185328, 20100321185328, 1, windowsserver MSWinEventLog 1 Security 1167 Fri)" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream-from-beginning.sh0000644000000000000000000000013215055602574022405 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.025640239 30 ctime=1764935932.907725442 rsyslog-8.2512.0/tests/imhiredis-stream-from-beginning.sh0000775000175000017500000000250715055602574022060 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis # WILL be logged by Rsyslog redis_command "XADD mystream * msg message1" redis_command "XADD mystream * msg message2" redis_command "XADD mystream * msg message3" generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %$!msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mystream" mode="stream" stream.readFrom="0-0" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup redis_command "XADD mystream * msg message4" redis_command "XADD mystream * msg message5" redis_command "XADD mystream * msg message6" shutdown_when_empty wait_shutdown stop_redis content_check '1 message1' content_check '2 message2' content_check '3 message3' content_check '4 message4' content_check '5 message5' content_check '6 message6' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp_multi_line.sh0000644000000000000000000000013115055602574017754 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.517680206 30 ctime=1764935933.621736371 rsyslog-8.2512.0/tests/imptcp_multi_line.sh0000775000175000017500000000220215055602574017420 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="remote" multiline="on") template(name="outfmt" type="string" string="NEWMSG: %rawmsg%\n") ruleset(name="remote") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -B -I ${srcdir}/testsuites/imptcp_multi_line.testdata shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate export EXPECTED='NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test1 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test2 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012line1 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012l#012i#012n#012#012e2 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test3 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag multi#012line3 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test4 NEWMSG: <133>Mar 1 01:00:00 172.20.245.8 tag test end' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omrabbitmq_params_missing2.sh0000644000000000000000000000013215035412264021544 xustar0030 mtime=1752569012.405716005 30 atime=1764931160.808636757 30 ctime=1764935932.844724477 rsyslog-8.2512.0/tests/omrabbitmq_params_missing2.sh0000775000175000017500000000060415035412264021213 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/omrabbitmq/.libs/omrabbitmq") action(type="omrabbitmq" exchange="in" routing_key="jk") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "parameter host must be specified" exit_testrsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-sysmon.sh0000644000000000000000000000013215114522477020262 xustar0030 mtime=1764926783.044632079 30 atime=1764926783.492643078 30 ctime=1764935932.143713746 rsyslog-8.2512.0/tests/mmsnareparse-sysmon.sh0000775000175000017500000001075115114522477017735 0ustar00rgerrger#!/bin/bash # Validate mmsnareparse parsing against Microsoft Sysmon events using definition file. unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmsnareparse/.libs/mmsnareparse") template(name="outfmt" type="list") { property(name="$!win!Event!EventID") constant(value=",") property(name="$!win!Event!Channel") constant(value=",") property(name="$!win!Event!Category") constant(value=",") property(name="$!win!Event!Subtype") constant(value=",") property(name="$!win!EventData!ProcessId") constant(value=",") property(name="$!win!EventData!Image") constant(value=",") property(name="$!win!EventData!CommandLine") constant(value=",") property(name="$!win!EventData!User") constant(value=",") property(name="$!win!Network!SourceIp") constant(value=",") property(name="$!win!Network!SourcePort") constant(value=",") property(name="$!win!Network!DestinationIp") constant(value=",") property(name="$!win!Network!DestinationPort") constant(value=",") property(name="$!win!Network!Protocol") constant(value="\n") } action(type="mmsnareparse" definition.file="../plugins/mmsnareparse/sysmon_definitions.json") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup cat <<'MSG' > ${RSYSLOG_DYNNAME}.input <14>Nov 25 05:54:32 DC-01 MSWinEventLog 1 Microsoft-Windows-Sysmon/Operational 10448 Tue Nov 25 05:54:32 2025 1 Windows SYSTEM User Information DC-01 CORP\NETWORK SERVICE Process creation Sysmon Event ID 1 - Process creation: UtcTime: 2024-04-28 22:08:22.025 ProcessGuid: {b34fbf9a-ce67-6a14-1111-1121f0a06f11} ProcessId: 6228 Image: C:\Windows\System32\wbem\WmiPrvSE.exe FileVersion: 10.0.22621.1 (WinBuild.160101.0800) Description: WMI Provider Host Product: Microsoft® Windows® Operating System Company: Microsoft Corporation OriginalFileName: Wmiprvse.exe CommandLine: C:\Windows\system32\wbem\wmiprvse.exe -secured -Embedding CurrentDirectory: C:\Windows\system32\ User: CORP\NETWORK SERVICE LogonGuid: {d56hdh1c-eg89-8c36-3333-3343h2c28h33} LogonId: 0x7EB05 TerminalSessionId: 1 IntegrityLevel: System Hashes: SHA1=A3F7B2C8D9E1F4A5B6C7D8E9F0A1B2C3D4E5F6A7,MD5=8E4F2A1B3C5D6E7F8A9B0C1D2E3F4A5,SHA256=7B9C2D4E5F6A7B8C9D0E1F2A3B4C5D6E7F8A9B0C1D2E3F4A5B6C7D8E9F0A1B2C3D4,IMPHASH=6A5B4C3D2E1F0A9B8C7D6E5F4A3B2C1D0E9F8A7B6C5 ParentProcessGuid: {c45gcg0b-df78-7b25-2222-2232g1b17g22} ParentProcessId: 580 ParentImage: C:\Windows\System32\svchost.exe ParentCommandLine: C:\Windows\system32\svchost.exe -k DcomLaunch -p ParentUser: NT INTERNAL\SYSTEM 10448 <14>Mar 10 22:36:54 SQL-01 MSWinEventLog 1 Microsoft-Windows-Sysmon/Operational 30692 Mon Mar 10 22:36:54 2025 3 Windows SYSTEM User Information SQL-01 LAB\Administrator Network connection detected Sysmon Event ID 3 - Network connection detected: RuleName: RDP UtcTime: 2017-04-28 22:12:22.557 ProcessGuid: {c45gcg0b-df78-7b25-2222-2232g1b17g22} ProcessId: 13220 Image: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe Description: Sysmon Event ID 3 User: LAB\Administrator SourceIp: 10.0.0.20 SourcePort: 3328 DestinationIp: 192.168.1.20 DestinationPort: 3389 Protocol: tcp Initiated: true SourceIsIpv6: 192.168.1.20 SourceHostname: DC-03 DestinationIsIpv6: 10.0.0.20 DestinationPortName: ms-wbt-server 30692 <14>Jun 27 04:55:00 SERVER-01 MSWinEventLog 1 Microsoft-Windows-Sysmon/Operational 50518 Fri Jun 27 04:55:00 2025 5 Windows SYSTEM User Information SERVER-01 Process terminated Sysmon Event ID 5 - Process terminated: UtcTime: 2017-04-28 22:13:20.895 ProcessGuid: {02de4fd3-bd56-5903-0000-0010e9d95e00} ProcessId: 12684 Image: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe Description: Sysmon Event ID 5 50518 MSG injectmsg_file ${RSYSLOG_DYNNAME}.input shutdown_when_empty wait_shutdown # Test Event ID 1 (Process Creation) content_check '1,Microsoft-Windows-Sysmon/Operational,Process,Creation,6228,C:\Windows\System32\wbem\WmiPrvSE.exe,C:\Windows\system32\wbem\wmiprvse.exe -secured -Embedding,CORP\NETWORK SERVICE,,,,,' $RSYSLOG_OUT_LOG # Test Event ID 3 (Network Connection) content_check '3,Microsoft-Windows-Sysmon/Operational,Network,Connection,13220,C:\Program Files (x86)\Google\Chrome\Application\chrome.exe,,LAB\Administrator,10.0.0.20,,192.168.1.20,,tcp' $RSYSLOG_OUT_LOG # Test Event ID 5 (Process Termination) content_check '5,Microsoft-Windows-Sysmon/Operational,Process,Termination,12684,C:\Program Files (x86)\Google\Chrome\Application\chrome.exe,,,,,,' $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/cfg2.testin0000644000000000000000000000013215035412264015746 xustar0030 mtime=1752569012.384861924 30 atime=1764931158.743603622 30 ctime=1764935932.274715752 rsyslog-8.2512.0/tests/cfg2.testin0000664000175000017500000000003315035412264015406 0ustar00rgerrger$includeconfig cfg1.testin rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_rule_from_array.sh0000644000000000000000000000013215035412264022033 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.786652446 30 ctime=1764935933.128728825 rsyslog-8.2512.0/tests/mmnormalize_rule_from_array.sh0000775000175000017500000000220015035412264021474 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="norm") template(name="outfmt" type="string" string="%hostname% %syslogtag%\n") ruleset(name="norm") { action(type="mmnormalize" rule=["rule=: no longer listening on %ip:ipv4%#%port:number%", "rule=: is sending messages on %ip:ipv4%", "rule=: apfelkuchen"]) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 ubuntu tag1: no longer listening on 127.168.0.1#10514\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 debian tag2: is sending messages on 127.168.0.1\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 centos tag3: apfelkuchen\"" shutdown_when_empty wait_shutdown echo 'ubuntu tag1: debian tag2: centos tag3:' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-transactions-failed-messages.sh0000644000000000000000000000013115062756615023303 xustar0029 mtime=1758190989.23764163 30 atime=1764931165.279708454 30 ctime=1764935934.121744025 rsyslog-8.2512.0/tests/omprog-transactions-failed-messages.sh0000775000175000017500000001044315062756615022755 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests omprog with the confirmMessages=on and useTransactions=on # parameters, with the external program returning an error on certain # messages. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh --failed_messages` template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process queue.dequeueBatchSize="6" confirmMessages="on" useTransactions="on" action.resumeRetryCount="10" action.resumeInterval="1" ) } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown # Since the transaction boundaries are not deterministic, we cannot check for # an exact expected output. We must check the output programmatically. transaction_state="NONE" status_expected=true messages_to_commit=() messages_processed=() line_num=1 error= while IFS= read -r line; do if [[ $status_expected == true ]]; then case "$transaction_state" in "NONE") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi ;; "STARTED") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi transaction_state="ACTIVE" ;; "ACTIVE") if [[ "$line" == "<= Error: could not process log message" ]]; then messages_to_commit=() transaction_state="NONE" elif [[ "$line" != "<= DEFER_COMMIT" ]]; then error="expecting a DEFER_COMMIT status from script" break fi ;; "COMMITTED") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi messages_processed+=("${messages_to_commit[@]}") messages_to_commit=() transaction_state="NONE" ;; esac status_expected=false; else if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then if [[ "$transaction_state" != "NONE" ]]; then error="unexpected transaction start" break fi transaction_state="STARTED" elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected transaction commit" break fi transaction_state="COMMITTED" else if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected message outside a transaction" break fi if [[ "$line" != "=> msgnum:"* ]]; then error="unexpected message contents" break fi prefix_to_remove="=> " messages_to_commit+=("${line#$prefix_to_remove}") fi status_expected=true; fi ((line_num++)) done < $RSYSLOG_OUT_LOG if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then error="unexpected end of file (transaction state: $transaction_state)" fi if [[ -n "$error" ]]; then echo "$RSYSLOG_OUT_LOG: line $line_num: $error" cat $RSYSLOG_OUT_LOG error_exit 1 fi # Since the order in which failed messages are retried by rsyslog is not # deterministic, we sort the processed messages before checking them. IFS=$'\n' messages_sorted=($(sort <<<"${messages_processed[*]}")) unset IFS expected_messages=( "msgnum:00000000:" "msgnum:00000001:" "msgnum:00000002:" "msgnum:00000003:" "msgnum:00000004:" "msgnum:00000005:" "msgnum:00000006:" "msgnum:00000007:" "msgnum:00000008:" "msgnum:00000009:" ) if [[ "${messages_sorted[*]}" != "${expected_messages[*]}" ]]; then echo "unexpected set of processed messages:" printf '%s\n' "${messages_processed[@]}" echo "contents of $RSYSLOG_OUT_LOG:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/operatingstate-unclean.sh0000644000000000000000000000013215035412264020705 xustar0030 mtime=1752569012.406709056 30 atime=1764931157.680586559 30 ctime=1764935931.979711236 rsyslog-8.2512.0/tests/operatingstate-unclean.sh0000775000175000017500000000161315035412264020355 0ustar00rgerrger#!/bin/bash # added 2018-10-24 by Rainer Gerhards # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(operatingStateFile="'$RSYSLOG_DYNNAME.osf'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' # create an unclean file err_osf_content="20180924-160109: STATE INITIALIZING 8.39.0.master 20180924-160110: STATE" printf '%s\n' "$err_osf_content" > $RSYSLOG_DYNNAME.osf startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! check_file_exists "$RSYSLOG_DYNNAME.osf.previous" export EXPECTED="$err_osf_content" cmp_exact "$RSYSLOG_DYNNAME.osf.previous" check_file_exists "$RSYSLOG_DYNNAME.osf" content_check "does not end with 'CLEAN CLOSE, instead it has '0110: STATE'" "$RSYSLOG_OUT_LOG" content_check "CLEAN CLOSE" "$RSYSLOG_DYNNAME.osf" exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_rule_from_string.sh0000644000000000000000000000013215035412264022223 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.778652317 30 ctime=1764935933.126728794 rsyslog-8.2512.0/tests/mmnormalize_rule_from_string.sh0000775000175000017500000000212315035412264021670 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="norm") template(name="outfmt" type="string" string="%hostname% %syslogtag%\n") ruleset(name="norm") { action(type="mmnormalize" useRawMsg="on" rule="rule=:%host:word% %tag:char-to:\\x3a%: no longer listening on %ip:ipv4%#%port:number%") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"ubuntu tag1: no longer listening on 127.168.0.1#10514\"" tcpflood -m1 -M "\"debian tag2: no longer listening on 127.168.0.2#10514\"" tcpflood -m1 -M "\"centos tag3: no longer listening on 192.168.0.1#10514\"" shutdown_when_empty wait_shutdown echo 'ubuntu tag1: debian tag2: centos tag3:' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/libdbi-basic-vg.sh0000644000000000000000000000013215035412264017147 xustar0030 mtime=1752569012.398764645 30 atime=1764931167.077737269 30 ctime=1764935934.656752214 rsyslog-8.2512.0/tests/libdbi-basic-vg.sh0000775000175000017500000000036115035412264016616 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 # this test is currently not included in the testbench as libdbi # itself seems to have a memory leak export USE_VALGRIND="YES" source ${srcdir:=.}/libdbi-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/Makefile.am0000644000000000000000000000013115114522477015736 xustar0029 mtime=1764926783.04263203 30 atime=1764926784.239661412 30 ctime=1764935931.889709858 rsyslog-8.2512.0/tests/Makefile.am0000664000175000017500000027011215114522477015406 0ustar00rgerrgerTEST_EXTENSIONS=.sh if ENABLE_TESTBENCH CLEANFILES=\ *_*.conf \ rsyslog*.started work-*.conf rsyslog.random.data \ rsyslog*.pid.save xlate*.lkp_tbl \ log log* *.log \ work \ test-spool test-logdir stat-file1 \ rsyslog.pipe rsyslog.input.* \ rsyslog.input rsyslog.input.* imfile-state:* omkafka-failed.data \ rsyslog.input-symlink.log rsyslog-link.*.log targets \ HOSTNAME \ rstb_* \ zookeeper.pid \ tmp.qi nocert CLEANFILES+= \ IN_AUTO_DEBUG # IN_AUTO_DEBUG should be deleted each time make check is run, but # there exists no such hook. Se we at least delete it on make clean. pkglib_LTLIBRARIES = pkglib_LTLIBRARIES += liboverride_gethostname.la liboverride_gethostname_la_SOURCES = override_gethostname.c liboverride_gethostname_la_CFLAGS = liboverride_gethostname_la_LDFLAGS = -avoid-version -shared pkglib_LTLIBRARIES += liboverride_gethostname_nonfqdn.la liboverride_gethostname_nonfqdn_la_SOURCES = override_gethostname_nonfqdn.c liboverride_gethostname_nonfqdn_la_CFLAGS = liboverride_gethostname_nonfqdn_la_LDFLAGS = -avoid-version -shared pkglib_LTLIBRARIES += liboverride_getaddrinfo.la liboverride_getaddrinfo_la_SOURCES = override_getaddrinfo.c liboverride_getaddrinfo_la_CFLAGS = liboverride_getaddrinfo_la_LDFLAGS = -avoid-version -shared # TODO: reenable TESTRUNS = rt_init rscript check_PROGRAMS = $(TESTRUNS) ourtail tcpflood chkseq msleep randomgen \ diagtalker uxsockrcvr syslog_caller inputfilegen minitcpsrv \ omrelp_dflt_port \ mangle_qi \ have_relpSrvSetOversizeMode \ have_relpEngineSetTLSLibByName \ have_relpSrvSetTlsConfigCmd \ check_relpEngineVersion \ test_id if ENABLE_JOURNAL_TESTS if ENABLE_IMJOURNAL check_PROGRAMS += journal_print endif endif # if ENABLE_JOURNAL_TESTS TESTS = $(TESTRUNS) if ENABLE_ELASTICSEARCH_TESTS_MINIMAL TESTS += \ es-duplicated-ruleset.sh # the following test need to be serialized: TESTS += \ es-basic-es7.14.sh \ es-basic.sh \ es-basic-bulk.sh es-basic.log: es-basic-es7.14.log es-basic-bulk.log: es-basic.log es-basic-server.log: es-basic-bulk.log # special "test" for stopping ES once all ES tests are done TESTS += elasticsearch-stop.sh elasticsearch-stop.log: es-basic-bulk.log if HAVE_VALGRIND TESTS += \ es-duplicated-ruleset-vg.sh \ es-basic-vg.sh es-basic-vg.log: es-basic-bulk.log # for next if block: es-basic-server.log: es-basic-vg.log elasticsearch-stop.log: es-basic-vg.log if ENABLE_HELGRIND TESTS += \ es-basic-vgthread.sh es-basic-vgthread.log: es-basic-vg.log # for next if block: es-basic-server.log: es-basic-vgthread.log elasticsearch-stop.log: es-basic-vgthread.log endif # ENABLE_HELGRIND endif # HAVE_VALGRIND endif # ENABLE_ELASTICSEARCH_TESTS_MINIMAL if ENABLE_ELASTICSEARCH_TESTS TESTS += \ es-basic-server.sh \ es-execOnlyWhenPreviousSuspended.sh \ es-maxbytes-bulk.sh \ es-basic-errfile-empty.sh \ es-basic-errfile-popul.sh \ es-bulk-errfile-empty.sh \ es-bulk-errfile-popul.sh \ diskqueue-multithread-es.sh \ es-writeoperation.sh es-basic-server.log: es-basic-bulk.log es-execOnlyWhenPreviousSuspended.log: es-basic-server.log es-maxbytes-bulk.log: es-execOnlyWhenPreviousSuspended.log es-basic-errfile-empty.log: es-maxbytes-bulk.log es-basic-errfile-popul.log: es-basic-errfile-empty.log es-bulk-errfile-empty.log: es-basic-errfile-popul.log es-bulk-errfile-popul.log: es-bulk-errfile-empty.log diskqueue-multithread-es.log: es-bulk-errfile-popul.log es-writeoperation.log: diskqueue-multithread-es.log elasticsearch-stop.log: es-writeoperation.log if ENABLE_IMPSTATS TESTS += \ es-basic-ha.sh \ es-bulk-retry.sh es-basic-ha.log: es-writeoperation.log es-bulk-retry.log: es-basic-ha.log elasticsearch-stop.log: es-bulk-retry.log endif if ENABLE_IMFILE TESTS += \ es-bulk-errfile-popul-def-format.sh \ es-bulk-errfile-popul-erronly.sh \ es-bulk-errfile-popul-erronly-interleaved.sh \ es-bulk-errfile-popul-def-interleaved.sh es-bulk-errfile-popul-def-format.log: es-bulk-retry.log es-bulk-errfile-popul-erronly.log: es-bulk-errfile-popul-def-format.log es-bulk-errfile-popul-erronly-interleaved.log: es-bulk-errfile-popul-erronly.log es-bulk-errfile-popul-def-interleaved.log: es-bulk-errfile-popul-erronly-interleaved.log elasticsearch-stop.log: es-bulk-errfile-popul-def-interleaved.log endif if HAVE_VALGRIND TESTS += \ es-basic-bulk-vg.sh \ es-basic-ha-vg.sh es-basic-bulk-vg.log: es-writeoperation.log es-basic-bulk-vg.log: es-bulk-retry.log es-basic-bulk-vg.log: es-bulk-errfile-popul-def-interleaved.log es-basic-ha-vg.log: es-basic-bulk-vg.log elasticsearch-stop.log: es-basic-ha-vg.log endif endif # if ENABLE_ELASTICSEARCH_TESTS if ENABLE_DEFAULT_TESTS TESTS += \ immark.sh \ immark-inputname.sh \ immark-ruleset.sh \ immark-ruleset-custom-msg.sh \ operatingstate-basic.sh \ operatingstate-empty.sh \ operatingstate-unclean.sh \ smtradfile.sh \ loadbalance.sh \ empty-hostname.sh \ timestamp-3164.sh \ timestamp-3339.sh \ timestamp-isoweek.sh \ timestamp-mysql.sh \ timestamp-pgsql.sh \ timestamp-subseconds.sh \ msleep_usage_output.sh \ mangle_qi_usage_output.sh \ minitcpsrv_usage_output.sh \ test_id_usage_output.sh \ prop-programname.sh \ prop-programname-with-slashes.sh \ hostname-with-slash-pmrfc5424.sh \ hostname-with-slash-pmrfc3164.sh \ hostname-with-slash-dflt-invld.sh \ func-substring-invld-startpos.sh \ func-substring-large-endpos.sh \ func-substring-large-neg-endpos.sh \ func-substring-relative-endpos.sh \ hostname-with-slash-dflt-slash-valid.sh \ empty-app-name.sh \ endswith-basic.sh \ stop-localvar.sh \ stop-msgvar.sh \ glbl-ruleset-queue-defaults.sh \ glbl-internalmsg_severity-info-shown.sh \ glbl-internalmsg_severity-debug-shown.sh \ glbl-internalmsg_severity-debug-not_shown.sh \ glbl-umask.sh \ glbl-unloadmodules.sh \ glbl-invld-param.sh \ glbl_setenv_2_vars.sh \ glbl_setenv_err.sh \ glbl_setenv_err_too_long.sh \ glbl_setenv.sh \ mmexternal-SegFault.sh \ nested-call-shutdown.sh \ dnscache-TTL-0.sh \ invalid_nested_include.sh \ omfwd-lb-1target-retry-full_buf.sh \ omfwd-lb-1target-retry-1_byte_buf.sh \ omfwd-lb-1target-retry-1_byte_buf-TargetFail.sh \ omfwd-lb-susp.sh \ omfwd-lb-2target-basic.sh \ omfwd-lb-2target-retry.sh \ omfwd-lb-2target-one_fail.sh \ omfwd-tls-invalid-permitExpiredCerts.sh \ omfwd-keepalive.sh \ omfwd-subtree-tpl.sh \ omfile-subtree-jsonf.sh \ omusrmsg-errmsg-no-params.sh \ omusrmsg-noabort.sh \ omfile-module-params.sh \ omfile-read-only-errmsg.sh \ omfile-null-filename.sh \ omfile-whitespace-filename.sh \ omfile-read-only.sh \ omfile-outchannel.sh \ omfile_both_files_set.sh \ omfile_hup.sh \ msgvar-concurrency.sh \ localvar-concurrency.sh \ exec_tpl-concurrency.sh \ rscript_privdropuser.sh \ rscript_privdropuserid.sh \ rscript_privdropgroup.sh \ rscript_privdropgroupid.sh \ privdropuser.sh \ privdropuserid.sh \ privdropgroup.sh \ privdropgroupid.sh \ privdropabortonidfail.sh \ privdropabortonidfaillegacy.sh \ json-nonstring.sh \ json-onempty-at-end.sh \ template-json.sh \ template-pure-json.sh \ template-jsonf-nested.sh \ template-pos-from-to.sh \ template-pos-from-to-lowercase.sh \ template-pos-from-to-oversize.sh \ template-pos-from-to-oversize-lowercase.sh \ template-pos-from-to-missing-jsonvar.sh \ template-const-jsonf.sh \ template-topos-neg.sh \ fac_authpriv.sh \ fac_local0.sh \ fac_local7.sh \ fac_mail.sh \ fac_news.sh \ fac_ftp.sh \ fac_ntp.sh \ fac_uucp.sh \ fac_invld1.sh \ fac_invld2.sh \ fac_invld3.sh \ fac_invld4_rfc5424.sh \ rfc5424parser-sp_at_msg_start.sh \ compresssp.sh \ compresssp-stringtpl.sh \ rawmsg-after-pri.sh \ rfc5424parser.sh \ pmrfc3164-msgFirstSpace.sh \ pmrfc3164-AtSignsInHostname.sh \ pmrfc3164-AtSignsInHostname_off.sh \ pmrfc3164-tagEndingByColon.sh \ pmrfc3164-defaultTag.sh \ pmrfc3164-headerless.sh \ pmrfc3164-drop.sh \ pmrfc3164-json.sh \ tcp_forwarding_tpl.sh \ tcp_forwarding_dflt_tpl.sh \ tcp_forwarding_retries.sh \ mainq_actq_DA.sh \ queue_warnmsg-oversize.sh \ queue-minbatch.sh \ queue-minbatch-queuefull.sh \ queue-direct-with-no-params.sh \ queue-direct-with-params-given.sh \ arrayqueue.sh \ global_vars.sh \ no-parser-errmsg.sh \ da-mainmsg-q.sh \ validation-run.sh \ msgdup.sh \ msgdup_props.sh \ empty-ruleset.sh \ ruleset-direct-queue.sh \ imtcp-listen-port-file-2.sh \ allowed-sender-tcp-ok.sh \ allowed-sender-tcp-fail.sh \ allowed-sender-tcp-hostname-ok.sh \ allowed-sender-tcp-hostname-fail.sh \ imtcp-discard-truncated-msg.sh \ da-queue-persist.sh \ daqueue-persist.sh \ daqueue-invld-qi.sh \ daqueue-dirty-shutdown.sh \ diskq-rfc5424.sh \ diskqueue.sh \ diskqueue-fsync.sh \ diskqueue-full.sh \ diskqueue-fail.sh \ diskqueue-non-unique-prefix.sh \ rulesetmultiqueue.sh \ rulesetmultiqueue-v6.sh \ manytcp.sh \ rsf_getenv.sh \ msg-deadlock-headerless-noappname.sh \ sndrcv.sh \ sndrcv_failover.sh \ sndrcv_gzip.sh \ sndrcv_udp_nonstdpt.sh \ sndrcv_udp_nonstdpt_v6.sh \ imudp_thread_hang.sh \ sndrcv_udp_nonstdpt_v6.sh \ asynwr_simple.sh \ asynwr_simple_2.sh \ asynwr_timeout.sh \ asynwr_timeout_2.sh \ asynwr_small.sh \ asynwr_tinybuf.sh \ wr_large_async.sh \ wr_large_sync.sh \ asynwr_deadlock.sh \ asynwr_deadlock_2.sh \ asynwr_deadlock2.sh \ asynwr_deadlock4.sh \ asynwr_dynfile_flushtxend-off.sh \ abort-uncleancfg-goodcfg.sh \ abort-uncleancfg-goodcfg-check.sh \ abort-uncleancfg-badcfg-check.sh \ abort-uncleancfg-badcfg-check_1.sh \ variable_leading_underscore.sh \ gzipwr_hup_multi_file.sh \ gzipwr_hup_single_file.sh \ gzipwr_rscript.sh \ gzipwr_flushInterval.sh \ gzipwr_flushOnTXEnd.sh \ gzipwr_large.sh \ gzipwr_large_dynfile.sh \ gzipwr_hup.sh \ dynfile_invld_async.sh \ dynfile_invld_sync.sh \ dynfile_invalid2.sh \ complex1.sh \ queue-persist.sh \ pipeaction.sh \ execonlyonce.sh \ execonlywhenprevsuspended.sh \ execonlywhenprevsuspended2.sh \ execonlywhenprevsuspended3.sh \ execonlywhenprevsuspended4.sh \ execonlywhenprevsuspended_multiwrkr.sh \ execonlywhenprevsuspended-queue.sh \ execonlywhenprevsuspended-nonsusp.sh \ execonlywhenprevsuspended-nonsusp-queue.sh \ pipe_noreader.sh \ dircreate_dflt.sh \ dircreate_off.sh \ imuxsock_legacy.sh \ imuxsock_logger.sh \ imuxsock_logger_ratelimit.sh \ imuxsock_logger_ruleset.sh \ imuxsock_logger_ruleset_ratelimit.sh \ imuxsock_logger_err.sh \ imuxsock_logger_parserchain.sh \ imuxsock_traillf.sh \ imuxsock_ccmiddle.sh \ imuxsock_logger_syssock.sh \ imuxsock_traillf_syssock.sh \ imuxsock_ccmiddle_syssock.sh \ discard-rptdmsg.sh \ discard-allmark.sh \ discard.sh \ stop.sh \ failover-async.sh \ failover-double.sh \ failover-basic.sh \ failover-rptd.sh \ failover-no-rptd.sh \ failover-no-basic.sh \ suspend-via-file.sh \ suspend-omfwd-via-file.sh \ externalstate-failed-rcvr.sh \ rcvr_fail_restore.sh \ rscript_b64_decode.sh \ rscript_contains.sh \ rscript_bare_var_root.sh \ rscript_bare_var_root-empty.sh \ rscript_ipv42num.sh \ rscript_field.sh \ rscript_stop.sh \ rscript_stop2.sh \ rscript_prifilt.sh \ rscript_optimizer1.sh \ rscript_ruleset_call.sh \ rscript_ruleset_call_indirect-basic.sh \ rscript_ruleset_call_indirect-var.sh \ rscript_ruleset_call_indirect-invld.sh \ rscript_set_unset_invalid_var.sh \ rscript_set_modify.sh \ rscript_unaffected_reset.sh \ rscript_replace_complex.sh \ rscript_wrap2.sh \ rscript_wrap3.sh \ rscript_re_extract_i.sh \ rscript_re_extract.sh \ rscript_re_match_i.sh \ rscript_re_match.sh \ rscript_re_match-dbl_quotes.sh \ rscript_eq.sh \ rscript_eq_var.sh \ rscript_ge.sh \ rscript_ge_var.sh \ rscript_gt.sh \ rscript_gt_var.sh \ rscript_le.sh \ rscript_le_var.sh \ rscript_lt.sh \ rscript_lt_var.sh \ rscript_ne.sh \ rscript_ne_var.sh \ rscript_number_comparison_LE.sh \ rscript_number_comparison_LT.sh \ rscript_compare_str-numstr.sh \ rscript_compare_str-num.sh \ rscript_compare_numstr-str.sh \ rscript_compare_num-str.sh \ rscript_compare_numstr-numstr.sh \ rscript_compare_numstr-num.sh \ rscript_compare_num-numstr.sh \ rscript_compare_num-num.sh \ rscript_compare_str-str.sh \ rscript_num2ipv4.sh \ rscript_int2Hex.sh \ rscript_trim.sh \ rscript_substring.sh \ rscript_toupper.sh \ rscript_format_time.sh \ rscript_parse_time.sh \ rscript_is_time.sh \ rscript_script_error.sh \ rscript_parse_json.sh \ rscript_previous_action_suspended.sh \ rscript_str2num_negative.sh \ rscript_exists-yes.sh \ rscript_exists-yes2.sh \ rscript_exists-not1.sh \ rscript_exists-not2.sh \ rscript_exists-not3.sh \ rscript_exists-not4.sh \ rscript-config_enable-on.sh \ rscript_get_property.sh \ config_output-o-option.sh \ rs-cnum.sh \ rs-substring.sh \ rs-int2hex.sh \ empty-prop-comparison.sh \ rs_optimizer_pri.sh \ cee_simple.sh \ cee_diskqueue.sh \ incltest.sh \ incltest_dir.sh \ incltest_dir_wildcard.sh \ incltest_dir_empty_wildcard.sh \ linkedlistqueue.sh \ lookup_table.sh \ lookup_table-hup-backgrounded.sh \ lookup_table_no_hup_reload.sh \ key_dereference_on_uninitialized_variable_space.sh \ array_lookup_table.sh \ sparse_array_lookup_table.sh \ lookup_table_bad_configs.sh \ lookup_table_rscript_reload.sh \ lookup_table_rscript_reload_without_stub.sh \ config_multiple_include.sh \ include-obj-text-from-file.sh \ include-obj-text-from-file-noexist.sh \ multiple_lookup_tables.sh \ parsertest-parse1.sh \ parsertest-parse1-udp.sh \ parsertest-parse2.sh \ parsertest-parse2-udp.sh \ parsertest-parse_8bit_escape.sh \ parsertest-parse_8bit_escape-udp.sh \ parsertest-parse3.sh \ parsertest-parse3-udp.sh \ parsertest-parse_invld_regex.sh \ parsertest-parse_invld_regex-udp.sh \ parsertest-parse-3164-buggyday.sh \ parsertest-parse-3164-buggyday-udp.sh \ parsertest-parse-nodate.sh \ parsertest-parse-nodate-udp.sh \ parsertest-snare_ccoff_udp.sh \ parsertest-snare_ccoff_udp2.sh if ENABLE_MMSNAREPARSE TESTS += \ mmsnareparse-basic.sh \ mmsnareparse-json.sh \ mmsnareparse-syslog.sh \ mmsnareparse-comprehensive.sh \ mmsnareparse-value-types.sh \ mmsnareparse-enhanced-validation.sh \ mmsnareparse-sysmon.sh \ mmsnareparse-kerberos.sh \ mmsnareparse-custom.sh \ mmsnareparse-realworld-4624-4634-5140.sh \ mmsnareparse-trailing-extradata.sh \ mmsnareparse-trailing-extradata-regex.sh if HAVE_VALGRIND TESTS += \ mmsnareparse-comprehensive-vg.sh endif endif if ENABLE_OMSENDERTRACK TESTS += \ omsendertrack-basic.sh TESTS += \ omsendertrack-statefile.sh if HAVE_VALGRIND TESTS += \ omsendertrack-basic-vg.sh TESTS += \ omsendertrack-statefile-vg.sh endif # if HAVE_VALGRIND endif if ENABLE_LIBZSTD TESTS += \ zstd.sh if HAVE_VALGRIND TESTS += \ zstd-vg.sh endif # if HAVE_VALGRIND endif if ENABLE_LIBGCRYPT TESTS += \ queue-encryption-disk.sh \ queue-encryption-disk_keyfile.sh \ queue-encryption-disk_keyprog.sh \ queue-encryption-da.sh endif # ENABLE_LIBGCRYPT if HAVE_VALGRIND # note if the same test is added multiple times, it still is only executed once! if ENABLE_GNUTLS_TESTS TESTS += \ tcpflood_wrong_option_output.sh endif # ENABLE_GNUTLS_TESTS if ENABLE_OPENSSL TESTS += \ tcpflood_wrong_option_output.sh endif # ENABLE_OPENSSL TESTS += \ omusrmsg-noabort-vg.sh \ omfile_hup-vg.sh \ gzipwr_hup-vg.sh \ imtcp-octet-framing-too-long-vg.sh \ smtradfile-vg.sh \ dnscache-TTL-0-vg.sh \ include-obj-outside-control-flow-vg.sh \ include-obj-in-if-vg.sh \ include-obj-text-vg.sh \ rscript_b64_decode-vg.sh \ rscript_parse_json-vg.sh \ rscript_backticks-vg.sh \ rscript_backticks_empty_envvar.sh \ rscript_backticks_static_text.sh \ rscript_backticks_braces_envvar.sh \ rscript-config_enable-off-vg.sh \ rscript_get_property-vg.sh \ prop-jsonmesg-vg.sh \ mmexternal-InvldProg-vg.sh \ internal-errmsg-memleak-vg.sh \ glbl-oversizeMsg-log-vg.sh \ rscript_set_memleak-vg.sh \ no-parser-vg.sh \ discard-rptdmsg-vg.sh \ discard-allmark-vg.sh \ failover-basic-vg.sh \ failover-rptd-vg.sh \ failover-no-basic-vg.sh \ failover-no-rptd-vg.sh \ timereported-utc-vg.sh \ udp-msgreduc-vg.sh \ udp-msgreduc-orgmsg-vg.sh \ tcp-msgreduc-vg.sh \ rscript_field-vg.sh \ rscript_number_comparison_LE-vg.sh \ rscript_compare_str-str-vg.sh \ rscript_compare_str-num-vg.sh \ rscript_compare_str-numstr-vg.sh \ rscript_compare_num-str-vg.sh \ rscript_compare_numstr-str-vg.sh \ rscript_compare_numstr-num-vg.sh \ rscript_compare_numstr-numstr-vg.sh \ rscript_compare_num-num-vg.sh \ rscript_compare_num-numstr-vg.sh \ unused_lookup_table-vg.sh \ lookup_table-vg.sh \ lookup_table_no_hup_reload-vg.sh \ array_lookup_table-vg.sh \ array_lookup_table_misuse-vg.sh \ sparse_array_lookup_table-vg.sh \ lookup_table_bad_configs-vg.sh \ lookup_table_rscript_reload-vg.sh \ lookup_table_rscript_reload_without_stub-vg.sh \ multiple_lookup_tables-vg.sh \ fac_local0-vg.sh \ badqi.sh \ threadingmq.sh \ threadingmqaq.sh \ func-substring-invld-startpos-vg.sh \ rscript_trim-vg.sh if ENABLE_LIBGCRYPT TESTS += \ queue-encryption-disk_keyfile-vg.sh endif # ENABLE_LIBGCRYPT endif # HAVE_VALGRIND endif # ENABLE_DEFAULT_TESTS if ENABLE_IMTCP_TESTS TESTS += \ fromhost-port.sh \ fromhost-port-tuple.sh \ fromhost-port-async-ruleset.sh \ allowed-sender-tcp-ok.sh \ allowed-sender-tcp-fail.sh \ allowed-sender-tcp-hostname-ok.sh \ allowed-sender-tcp-hostname-fail.sh \ imtcp-discard-truncated-msg.sh \ imtcp-basic.sh \ imtcp-basic-hup.sh \ imtcp-impstats-single-thread.sh \ imtcp-starvation-0.sh \ imtcp-starvation-1.sh \ imtcp-maxFrameSize.sh \ imtcp-msg-truncation-on-number.sh \ imtcp-msg-truncation-on-number2.sh \ imtcp-netns.sh \ imtcp-NUL.sh \ imtcp-NUL-rawmsg.sh \ imtcp_incomplete_frame_at_end.sh \ imtcp-multiport.sh \ imtcp-bigmessage-octetcounting.sh \ imtcp-bigmessage-octetstuffing.sh \ manytcp.sh \ imtcp_conndrop.sh \ imtcp_addtlframedelim.sh \ imtcp_no_octet_counted.sh \ imtcp_addtlframedelim_on_input.sh \ imtcp_spframingfix.sh \ imtcp-connection-msg-recieved.sh \ sndrcv.sh \ sndrcv_failover.sh \ sndrcv_gzip.sh \ sndrcv_udp_nonstdpt.sh \ sndrcv_udp_nonstdpt_v6.sh \ sndrcv_udp_nonstdpt_v6.sh if HAVE_VALGRIND TESTS += \ imtcp-octet-framing-too-long-vg.sh endif # HAVE_VALGRIND if ENABLE_IMTCP_EPOLL if ENABLE_IMPSTATS TESTS += \ imtcp-impstats.sh endif # ENABLE_IMPSTATS endif # ENABLE_IMTCP_EPOLL endif # ENABLE_IMTCP_TESTS if ENABLE_SNMP TESTS += \ omsnmp_errmsg_no_params.sh if ENABLE_SNMP_TESTS TESTS += \ sndrcv_omsnmpv1_udp.sh \ sndrcv_omsnmpv1_udp_dynsource.sh \ sndrcv_omsnmpv1_udp_invalidoid.sh endif # if ENABLE_SNMP_TESTS endif # if ENABLE_SNMP if ENABLE_MMUTF8FIX TESTS += \ mmutf8fix_no_error.sh endif # if ENABLE_MAIL if ENABLE_MMAITAG TESTS += \ mmaitag-basic.sh \ mmaitag-invalid-key.sh endif if ENABLE_MAIL TESTS += \ ommail_errmsg_no_params.sh endif # if ENABLE_MAIL if ENABLE_MMANON TESTS += \ mmanon_with_debug.sh \ mmanon_random_32_ipv4.sh \ mmanon_random_cons_32_ipv4.sh \ mmanon_recognize_ipv4.sh \ mmanon_zero_12_ipv4.sh \ mmanon_zero_33_ipv4.sh \ mmanon_zero_8_ipv4.sh \ mmanon_simple_12_ipv4.sh \ mmanon_simple_33_ipv4.sh \ mmanon_simple_8_ipv4.sh \ mmanon_simple_mallformed_ipv4.sh \ mmanon_random_128_ipv6.sh \ mmanon_zero_128_ipv6.sh \ mmanon_zero_96_ipv6.sh \ mmanon_random_cons_128_ipv6.sh \ mmanon_zero_50_ipv6.sh \ mmanon_recognize_ipv6.sh \ mmanon_zero_64_ipv6.sh \ mmanon_both_modes_compatible.sh \ mmanon_recognize_ipembedded.sh \ mmanon_ipv6_port.sh \ mmanon_random_cons_128_ipembedded.sh endif # if ENABLE_MMANON if ENABLE_CLICKHOUSE_TESTS TESTS += \ clickhouse-start.sh \ clickhouse-basic.sh \ clickhouse-dflt-tpl.sh \ clickhouse-retry-error.sh \ clickhouse-load.sh \ clickhouse-bulk.sh \ clickhouse-bulk-load.sh \ clickhouse-limited-batch.sh \ clickhouse-select.sh \ clickhouse-errorfile.sh \ clickhouse-wrong-quotation-marks.sh \ clickhouse-wrong-template-option.sh \ clickhouse-wrong-insert-syntax.sh clickhouse-basic.log: clickhouse-start.log clickhouse-dflt-tpl.log: clickhouse-basic.log clickhouse-retry-error.log: clickhouse-dflt-tpl.log clickhouse-load.log: clickhouse-retry-error.log clickhouse-bulk.log: clickhouse-load.log clickhouse-bulk-load.log: clickhouse-bulk.log clickhouse-limited-batch.log: clickhouse-bulk-load.log clickhouse-select.log: clickhouse-limited-batch.log clickhouse-errorfile.log: clickhouse-select.log clickhouse-wrong-quotation-marks.log: clickhouse-errorfile.log clickhouse-wrong-template-option.log: clickhouse-wrong-quotation-marks.log clickhouse-wrong-insert-syntax.log: clickhouse-wrong-template-option.log clickhouse-stop.log: clickhouse-wrong-insert-syntax.log if HAVE_VALGRIND TESTS += \ clickhouse-basic-vg.sh \ clickhouse-load-vg.sh \ clickhouse-bulk-vg.sh \ clickhouse-bulk-load-vg.sh clickhouse-basic-vg.log: clickhouse-wrong-insert-syntax.log clickhouse-load-vg.log: clickhouse-basic-vg.log clickhouse-bulk-vg.log: clickhouse-load-vg.log clickhouse-bulk-load-vg.log: clickhouse-bulk-vg.log clickhouse-stop.log: clickhouse-bulk-load-vg.log endif # VALGRIND TESTS += clickhouse-stop.sh endif # CLICKHOUSE_TESTS if ENABLE_LIBFAKETIME TESTS += \ now_family_utc.sh \ now-utc.sh \ now-utc-ymd.sh \ now-utc-casecmp.sh \ now-unixtimestamp.sh \ timegenerated-ymd.sh \ timegenerated-uxtimestamp.sh \ timegenerated-uxtimestamp-invld.sh \ timegenerated-dateordinal.sh \ timegenerated-dateordinal-invld.sh \ timegenerated-utc.sh \ timegenerated-utc-legacy.sh \ timereported-utc.sh \ timereported-utc-legacy.sh # now come faketime tests that utilize mmnormalize - aka "no endif here" if ENABLE_MMNORMALIZE TESTS += \ mmnormalize_processing_test1.sh \ mmnormalize_processing_test2.sh \ mmnormalize_processing_test3.sh \ mmnormalize_processing_test4.sh endif endif if ENABLE_PGSQL if ENABLE_PGSQL_TESTS TESTS += \ pgsql-basic.sh \ pgsql-basic-cnf6.sh \ pgsql-basic-threads-cnf6.sh \ pgsql-template.sh \ pgsql-template-cnf6.sh \ pgsql-actq-mt-withpause.sh \ pgsql-template-threads-cnf6.sh pgsql-basic-cnf6.log: pgsql-basic.log pgsql-basic-threads-cnf6.log: pgsql-basic-cnf6.log pgsql-template.log: pgsql-basic-threads-cnf6.log pgsql-template-cnf6.log: pgsql-template.log pgsql-actq-mt-withpause.log: pgsql-template-cnf6.log pgsql-template-threads-cnf6.log: pgsql-actq-mt-withpause.log if HAVE_VALGRIND TESTS += \ pgsql-basic-vg.sh \ pgsql-template-vg.sh \ pgsql-basic-cnf6-vg.sh \ pgsql-template-cnf6-vg.sh \ pgsql-actq-mt-withpause-vg.sh pgsql-basic-vg.log: pgsql-template-threads-cnf6.log pgsql-template-vg.log: pgsql-basic-vg.log pgsql-basic-cnf6-vg.log: pgsql-template-vg.log pgsql-template-cnf6-vg.log: pgsql-basic-cnf6-vg.log pgsql-actq-mt-withpause-vg.log: pgsql-template-cnf6-vg.log endif endif endif if ENABLE_MYSQL_TESTS TESTS += \ mysqld-start.sh \ mysql-basic.sh \ mysql-basic-cnf6.sh \ mysql-asyn.sh \ mysql-actq-mt.sh \ mysql-actq-mt-withpause.sh \ action-tx-single-processing.sh \ action-tx-errfile-maxsize.sh \ action-tx-errfile.sh mysql-basic.log: mysqld-start.log mysql-basic-cnf6.log: mysqld-start.log mysql-asyn.log: mysqld-start.log mysql-actq-mt.log: mysqld-start.log mysql-actq-mt-withpause.log: mysqld-start.log action-tx-single-processing.log: mysqld-start.log action-tx-errfile.log: mysqld-start.log mysqld-stop.log: mysql-basic.log \ mysql-basic-cnf6.log \ mysql-asyn.log \ mysql-actq-mt.log \ mysql-actq-mt-withpause.log \ action-tx-single-processing.log \ action-tx-errfile.log if HAVE_VALGRIND TESTS += \ mysql-basic-vg.sh \ mysql-asyn-vg.sh \ mysql-actq-mt-withpause-vg.sh mysql-basic-vg.log: mysqld-start.log mysql-asyn-vg.log: mysqld-start.log mysql-actq-mt-withpause-vg.log: mysqld-start.log mysqld-stop.log: mysql-basic-vg.log \ mysql-asyn-vg.log \ mysql-actq-mt-withpause-vg.log endif if ENABLE_OMLIBDBI # we piggy-back on MYSQL_TESTS as we need the same environment TESTS += \ libdbi-basic.sh \ libdbi-asyn.sh libdbi-basic.log: mysqld-start.log libdbi-asyn.log: mysqld-start.log mysqld-stop.log: libdbi-basic.log \ libdbi-asyn.log if HAVE_VALGRIND TESTS += \ libdbi-basic-vg.sh libdbi-basic-vg.log: mysqld-start.log mysqld-stop.log: libdbi-basic-vg.log endif endif TESTS += mysqld-stop.sh endif # MYSQL_TESTS if ENABLE_FMHTTP TESTS += \ rscript_http_request.sh if HAVE_VALGRIND TESTS += \ rscript_http_request-vg.sh endif # HAVE_VALGRIND endif # ENABLE_FMHTTP if ENABLE_ROOT_TESTS TESTS += \ sndrcv_udp.sh \ imuxsock_logger_root.sh \ imuxsock_traillf_root.sh \ imuxsock_ccmiddle_root.sh \ imklog_permitnonkernelfacility_root.sh if ENABLE_IP TESTS += tcp_forwarding_ns_tpl.sh endif if HAVE_VALGRIND TESTS += \ mmexternal-SegFault-empty-jroot-vg.sh endif endif # see comments in configure.ac on flaky tests for important details!!! if ENABLE_FLAKY_TESTS #TESTS += # if ENABLE_OMHTTP TESTS += \ omhttp-batch-retry-metadata.sh if HAVE_VALGRIND TESTS += \ omhttp-batch-retry-metadata-vg.sh endif # end if HAVE_VALGRIND endif # end if ENABLE_OMHTTP endif # end if ENABLE_FLAKY_TESTS if ENABLE_JOURNAL_TESTS if ENABLE_IMJOURNAL TESTS += \ imjournal-basic.sh \ imjournal-statefile.sh if HAVE_VALGRIND TESTS += \ imjournal-basic-vg.sh \ imjournal-statefile-vg.sh endif endif if ENABLE_OMJOURNAL TESTS += \ omjournal-abort-template.sh \ omjournal-abort-no-template.sh \ omjournal-basic-template.sh \ omjournal-basic-no-template.sh endif endif #if ENABLE_JOURNAL_TESTS if ENABLE_IMPROG TESTS += \ improg_errmsg_no_params.sh \ improg_prog_simple.sh \ improg_prog_confirm.sh \ improg_prog_confirm_killonclose.sh \ improg_prog_killonclose.sh \ improg_simple_multi.sh if HAVE_VALGRIND TESTS += \ improg_errmsg_no_params-vg.sh \ improg_prog_simple-vg.sh endif # ENABLE_IMPROG endif if ENABLE_MMDARWIN TESTS += \ mmdarwin_errmsg_no_params.sh \ mmdarwin_errmsg_no_sock.sh if HAVE_VALGRIND TESTS += \ mmdarwin_errmsg_no_sock-vg.sh endif # HAVE_VALGRIND endif # ENABLE_IMPROG if ENABLE_OMPROG TESTS += \ omprog-defaults.sh \ omprog-output-capture.sh \ omprog-output-capture-mt.sh \ omprog-feedback.sh \ omprog-feedback-mt.sh \ omprog-feedback-timeout.sh \ omprog-close-unresponsive.sh \ omprog-close-unresponsive-noterm.sh \ omprog-restart-terminated.sh \ omprog-restart-terminated-outfile.sh \ omprog-single-instance.sh \ omprog-single-instance-outfile.sh \ omprog-transactions.sh \ omprog-if-error.sh \ omprog-transactions-failed-messages.sh \ omprog-transactions-failed-commits.sh if HAVE_VALGRIND TESTS += \ omprog-defaults-vg.sh \ omprog-output-capture-vg.sh \ omprog-feedback-vg.sh \ omprog-close-unresponsive-vg.sh \ omprog-restart-terminated-vg.sh \ omprog-single-instance-vg.sh \ omprog-transactions-vg.sh endif endif if ENABLE_OMHTTP TESTS += \ omhttp-auth.sh \ omhttp-basic.sh \ omhttp-basic-ignorecodes.sh \ omhttp-batch-fail-with-400.sh \ omhttp-batch-jsonarray-compress.sh \ omhttp-batch-jsonarray-retry.sh \ omhttp-batch-jsonarray.sh \ omhttp-batch-kafkarest-retry.sh \ omhttp-batch-kafkarest.sh \ omhttp-batch-lokirest-retry.sh \ omhttp-batch-lokirest.sh \ omhttp-profile-loki.sh \ omhttp-batch-newline.sh \ omhttp-retry.sh \ omhttp-retry-timeout.sh \ omhttp-httpheaderkey.sh \ omhttp-multiplehttpheaders.sh \ omhttp-dynrestpath.sh \ omhttp-batch-dynrestpath.sh if HAVE_VALGRIND TESTS += \ omhttp-auth-vg.sh \ omhttp-basic-vg.sh \ omhttp-basic-ignorecodes-vg.sh \ omhttp-batch-jsonarray-compress-vg.sh \ omhttp-batch-jsonarray-retry-vg.sh \ omhttp-batch-jsonarray-vg.sh \ omhttp-batch-kafkarest-retry-vg.sh \ omhttp-batch-lokirest-retry-vg.sh \ omhttp-retry-vg.sh \ omhttp-retry-timeout-vg.sh \ omhttp-batch-lokirest-vg.sh endif endif if ENABLE_OMKAFKA if ENABLE_IMKAFKA if ENABLE_KAFKA_TESTS TESTS += \ kafka-selftest.sh \ omkafka.sh \ omkafkadynakey.sh \ omkafka-headers.sh \ imkafka.sh \ imkafka-backgrounded.sh \ imkafka-config-err-ruleset.sh \ imkafka-config-err-param.sh \ imkafka-hang-on-no-kafka.sh \ imkafka-hang-other-action-on-no-kafka.sh \ imkafka_multi_single.sh \ imkafka_multi_group.sh \ sndrcv_kafka.sh \ sndrcv_kafka_multi_topics.sh # Tests below need to be stable first! # sndrcv_kafka_fail.sh \ # sndrcv_kafka_failresume.sh \ # needs properly to much mempory on arm devices! # sndrcv_kafka_multi.sh omkafka.log: kafka-selftest.log imkafka.log: omkafka.log imkafka-backgrounded.log: imkafka.log imkafka-config-err-ruleset.log: imkafka-backgrounded.log imkafka-config-err-param.log: imkafka-config-err-ruleset.log imkafka-hang-on-no-kafka.log: imkafka-config-err-param.log imkafka-hang-other-action-on-no-kafka.log: imkafka-hang-on-no-kafka.log imkafka_multi_single.log: imkafka-hang-other-action-on-no-kafka.log sndrcv_kafka.log: imkafka_multi_single.log imkafka_multi_group.log: sndrcv_kafka.log sndrcv_kafka_multi_topics.log: imkafka_multi_group.log omkafkadynakey.log: sndrcv_kafka_multi_topics.log omkafka-headers.log: omkafkadynakey.log if HAVE_VALGRIND TESTS += \ omkafka-vg.sh \ imkafka-vg.sh omkafka-vg.log: omkafka-headers.log imkafka-vg.log: omkafka-vg.log endif endif endif endif if ENABLE_OMAZUREEVENTHUBS if ENABLE_OMAZUREEVENTHUBS_TESTS TESTS += \ omazureeventhubs-basic.sh \ omazureeventhubs-basic-url.sh \ omazureeventhubs-list.sh \ omazureeventhubs-stress.sh \ omazureeventhubs-interrupt.sh if HAVE_VALGRIND TESTS += \ omazureeventhubs-basic-vg.sh \ omazureeventhubs-interrupt-vg.sh endif endif endif if ENABLE_IMDOCKER if ENABLE_IMDOCKER_TESTS TESTS += \ imdocker-basic.sh \ imdocker-image-name.sh \ imdocker-long-logline.sh \ imdocker-new-logs-from-start.sh \ imdocker-multi-line.sh if HAVE_VALGRIND TESTS += \ imdocker-basic-vg.sh \ imdocker-image-name-vg.sh \ imdocker-long-logline-vg.sh \ imdocker-new-logs-from-start-vg.sh \ imdocker-multi-line-vg.sh endif # HAVE_VALGRIND endif # ENABLE_IMDOCKER_TESTS endif # ENABLE_IMDOCKER if ENABLE_IMHTTP TESTS += \ imhttp-post-payload.sh \ imhttp-post-payload-basic-auth.sh \ imhttp-post-payload-query-params.sh \ imhttp-post-payload-large.sh \ imhttp-post-payload-multi.sh \ imhttp-post-payload-multi-lf.sh \ imhttp-post-payload-compress.sh \ imhttp-getrequest-file.sh \ imhttp-healthcheck.sh \ imhttp-metrics.sh if HAVE_VALGRIND TESTS += \ imhttp-post-payload-vg.sh \ imhttp-post-payload-basic-auth-vg.sh \ imhttp-post-payload-query-params-vg.sh \ imhttp-post-payload-large-vg.sh \ imhttp-post-payload-multi-vg.sh \ imhttp-post-payload-multi-lf-vg.sh \ imhttp-post-payload-compress-vg.sh \ imhttp-getrequest-file-vg.sh endif # HAVE_VALGRIND endif # ENABLE_IMHTTP if ENABLE_OMRABBITMQ check_PROGRAMS += miniamqpsrvr miniamqpsrvr_SOURCES = miniamqpsrvr.c miniamqpsrvr_CPPFLAGS = $(PTHREADS_CFLAGS) $(RABBITMQ_CFLAGS) $(RSRT_CFLAGS) miniamqpsrvr_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS) TESTS += \ omrabbitmq_no_params.sh \ omrabbitmq_params_missing0.sh \ omrabbitmq_params_missing1.sh \ omrabbitmq_params_missing2.sh \ omrabbitmq_params_invalid0.sh \ omrabbitmq_params_invalid1.sh \ omrabbitmq_params_invalid2.sh \ omrabbitmq_params_invalid3.sh \ omrabbitmq_data_1server.sh \ omrabbitmq_data_2servers.sh \ omrabbitmq_error_server0.sh \ omrabbitmq_error_server1.sh \ omrabbitmq_error_server2.sh \ omrabbitmq_error_server3.sh \ omrabbitmq_json.sh \ omrabbitmq_raw.sh if HAVE_VALGRIND TESTS += \ omrabbitmq_data_1server-vg.sh endif # HAVE_VALGRIND endif # ENABLE_OMRABBITMQ if ENABLE_REDIS_TESTS if ENABLE_IMHIREDIS TESTS += \ imhiredis-queue.sh \ imhiredis-queue-lpop.sh \ imhiredis-redis-restart.sh \ imhiredis-redis-start-after.sh \ imhiredis-subscribe.sh \ imhiredis-stream.sh \ imhiredis-stream-from-beginning.sh \ imhiredis-stream-consumerGroup-ack.sh \ imhiredis-stream-consumerGroup-noack.sh \ imhiredis-stream-consumerGroup-reclaim.sh if HAVE_VALGRIND TESTS += \ imhiredis-queue-vg.sh \ imhiredis-queue-lpop-vg.sh \ imhiredis-redis-restart-vg.sh \ imhiredis-redis-start-after-vg.sh \ imhiredis-subscribe-vg.sh \ imhiredis-stream-vg.sh \ imhiredis-stream-from-beginning-vg.sh \ imhiredis-stream-consumerGroup-ack-vg.sh \ imhiredis-stream-consumerGroup-noack-vg.sh \ imhiredis-stream-consumerGroup-reclaim-vg.sh endif # HAVE_VALGRIND endif # ENABLE_IMHIREDIS if ENABLE_OMHIREDIS TESTS += \ mmdb-reload.sh \ omhiredis-dynakey.sh \ omhiredis-publish.sh \ omhiredis-queue-rpush.sh \ omhiredis-queue.sh \ omhiredis-set.sh \ omhiredis-setex.sh \ omhiredis-template.sh \ omhiredis-withpass.sh \ omhiredis-wrongpass.sh \ omhiredis-stream-ack.sh \ omhiredis-stream-capped.sh \ omhiredis-stream-del.sh \ omhiredis-stream-dynack.sh \ omhiredis-stream-outfield.sh \ omhiredis-stream.sh if HAVE_VALGRIND TESTS += \ mmdb-reload-vg.sh \ omhiredis-dynakey-vg.sh \ omhiredis-publish-vg.sh \ omhiredis-queue-rpush-vg.sh \ omhiredis-queue-vg.sh \ omhiredis-set-vg.sh \ omhiredis-setex-vg.sh \ omhiredis-template-vg.sh \ omhiredis-withpass-vg.sh \ omhiredis-wrongpass-vg.sh \ omhiredis-stream-ack-vg.sh \ omhiredis-stream-capped-vg.sh \ omhiredis-stream-del-vg.sh \ omhiredis-stream-dynack-vg.sh \ omhiredis-stream-outfield-vg.sh \ omhiredis-stream-vg.sh endif # HAVE_VALGRIND endif # ENABLE_OMHIREDIS endif # ENABLE_REDIS_TESTS if ENABLE_IMPSTATS TESTS += \ impstats-hup.sh \ perctile-simple.sh \ dynstats.sh \ dynstats_overflow.sh \ dynstats_reset.sh \ dynstats_ctr_reset.sh \ dynstats_nometric.sh \ no-dynstats-json.sh \ no-dynstats.sh \ stats-json.sh \ stats-prometheus.sh \ dynstats-json.sh \ stats-cee.sh \ stats-json-es.sh \ dynstats_reset_without_pstats_reset.sh \ dynstats_prevent_premature_eviction.sh \ omfwd-lb-2target-impstats.sh \ omfwd_fast_imuxsock.sh \ omfwd_impstats-udp.sh \ omfwd_impstats-tcp.sh if HAVE_VALGRIND TESTS += \ perctile-simple-vg.sh \ dynstats-vg.sh \ dynstats_reset-vg.sh \ dynstats_overflow-vg.sh \ dynstats-json-vg.sh \ stats-json-vg.sh \ stats-cee-vg.sh \ dynstats_prevent_premature_eviction-vg.sh endif endif if ENABLE_IMPTCP # note that some tests simply USE imptcp, but they also # need to be disabled if we do not have this module TESTS += \ manyptcp.sh \ imptcp_framing_regex.sh \ imptcp_framing_regex-oversize.sh \ imptcp_large.sh \ imptcp-connection-msg-disabled.sh \ imptcp-connection-msg-received.sh \ imptcp-discard-truncated-msg.sh \ imptcp_addtlframedelim.sh \ imptcp_conndrop.sh \ imptcp_no_octet_counted.sh \ imptcp_multi_line.sh \ imptcp_spframingfix.sh \ imptcp_maxsessions.sh \ imptcp_nonProcessingPoller.sh \ imptcp_veryLargeOctateCountedMessages.sh \ imptcp-basic-hup.sh \ imptcp-NUL.sh \ imptcp-NUL-rawmsg.sh \ rscript_random.sh \ rscript_hash32.sh \ rscript_hash64.sh \ rscript_replace.sh \ omfile-sizelimitcmd-many.sh \ omfile-outchannel-many.sh if HAVE_VALGRIND TESTS += \ imptcp-octet-framing-too-long-vg.sh \ imptcp_conndrop-vg.sh if ENABLE_FMHASH TESTS += \ rscript_hash32-vg.sh \ rscript_hash64-vg.sh endif # ENABLE_FMHASH endif # HAVE_VALGRIND if ENABLE_FMUNFLATTEN TESTS += \ rscript_unflatten_arg1_unsuitable.sh \ rscript_unflatten_arg2_invalid.sh \ rscript_unflatten_conflict1.sh \ rscript_unflatten_conflict2.sh \ rscript_unflatten_conflict3.sh \ rscript_unflatten_key_truncated.sh \ rscript_unflatten_non_object.sh \ rscript_unflatten_object.sh \ rscript_unflatten_object_exclamation.sh if HAVE_VALGRIND TESTS += \ rscript_unflatten_arg1_unsuitable-vg.sh \ rscript_unflatten_arg2_invalid-vg.sh \ rscript_unflatten_conflict1-vg.sh \ rscript_unflatten_conflict2-vg.sh \ rscript_unflatten_conflict3-vg.sh \ rscript_unflatten_key_truncated-vg.sh \ rscript_unflatten_non_object-vg.sh \ rscript_unflatten_object-vg.sh \ rscript_unflatten_object_exclamation-vg.sh endif # HAVE_VALGRIND endif # ENABLE_FMUNFLATTEN if ENABLE_FFAUP TESTS += \ rscript_faup_all.sh \ rscript_faup_all_2.sh \ rscript_faup_all_empty.sh \ rscript_faup_scheme.sh \ rscript_faup_credential.sh \ rscript_faup_subdomain.sh \ rscript_faup_domain.sh \ rscript_faup_domain_without_tld.sh \ rscript_faup_host.sh \ rscript_faup_tld.sh \ rscript_faup_port.sh \ rscript_faup_resource_path.sh \ rscript_faup_query_string.sh \ rscript_faup_fragment.sh \ rscript_faup_mozilla_tld.sh if HAVE_VALGRIND TESTS += \ rscript_faup_all_vg.sh \ rscript_faup_all_2_vg.sh \ rscript_faup_all_empty_vg.sh \ rscript_faup_scheme_vg.sh \ rscript_faup_credential_vg.sh \ rscript_faup_subdomain_vg.sh \ rscript_faup_domain_vg.sh \ rscript_faup_domain_without_tld_vg.sh \ rscript_faup_host_vg.sh \ rscript_faup_tld_vg.sh \ rscript_faup_port_vg.sh \ rscript_faup_resource_path_vg.sh \ rscript_faup_query_string_vg.sh \ rscript_faup_fragment_vg.sh \ rscript_faup_mozilla_tld_vg.sh endif # HAVE_VALGRIND endif # ENABLE_FFAUP endif if ENABLE_FMPCRE TESTS += \ ffmpcre-basic.sh endif if ENABLE_MMPSTRUCDATA TESTS += \ mmpstrucdata.sh \ mmpstrucdata-escaping.sh \ mmpstrucdata-case.sh if HAVE_VALGRIND TESTS += \ mmpstrucdata-vg.sh \ mmpstrucdata-invalid-vg.sh endif endif if ENABLE_MMRM1STSPACE TESTS += \ mmrm1stspace-basic.sh endif if ENABLE_PMNULL TESTS += \ pmnull-basic.sh \ pmnull-withparams.sh endif if ENABLE_OMSTDOUT TESTS += \ omstdout-basic.sh endif if ENABLE_PMNORMALIZE TESTS += \ pmnormalize-basic.sh \ pmnormalize-invld-rulebase.sh \ pmnormalize-rule.sh \ pmnormalize-rule_and_rulebase.sh \ pmnormalize-neither_rule_rulebase.sh \ pmnormalize-rule_invld-data.sh if HAVE_VALGRIND TESTS += \ pmnormalize-basic-vg.sh \ pmnormalize-invld-rulebase-vg.sh \ pmnormalize-rule-vg.sh \ pmnormalize-rule_and_rulebase-vg.sh \ pmnormalize-neither_rule_rulebase-vg.sh \ pmnormalize-rule_invld-data-vg.sh endif endif if ENABLE_MMNORMALIZE TESTS += msgvar-concurrency-array.sh \ msgvar-concurrency-array-event.tags.sh \ mmnormalize_rule_from_string.sh \ mmnormalize_rule_from_array.sh \ mmnormalize_parsesuccess.sh if HAVE_VALGRIND TESTS += \ mmnormalize_parsesuccess-vg.sh endif if ENABLE_IMPTCP TESTS += \ mmnormalize_regex_defaulted.sh \ mmnormalize_regex_disabled.sh \ mmnormalize_variable.sh \ mmnormalize_tokenized.sh endif if LOGNORM_REGEX_SUPPORTED TESTS += \ mmnormalize_regex.sh endif endif # ENABLE_MMNORMALIZE if ENABLE_MMLEEFPARSE if ENABLE_IMPTCP TESTS += \ mmleefparse_basic.sh endif endif if ENABLE_MMJSONPARSE TESTS += \ mmjsonparse-w-o-cookie.sh \ mmjsonparse-w-o-cookie-multi-spaces.sh \ mmjsonparse-find-json-basic.sh \ mmjsonparse-find-json-trailing.sh \ mmjsonparse-find-json-scan-limit.sh \ mmjsonparse-find-json-invalid.sh \ mmjsonparse-find-json-invalid-mode.sh \ mmjsonparse-find-json-parser-validation.sh if ENABLE_IMPSTATS TESTS += \ mmjsonparse-invalid-containerName.sh \ wtpShutdownAll-assertionFailure.sh endif if ENABLE_IMPTCP TESTS += \ mmjsonparse_simple.sh \ imptcp-oversize-message-display.sh \ imptcp-msg-truncation-on-number.sh \ imptcp-msg-truncation-on-number2.sh \ imtcp-netns.sh \ imptcp-maxFrameSize-parameter.sh \ mmjsonparse_cim.sh \ mmjsonparse_cim2.sh \ mmjsonparse_localvar.sh \ json_array_subscripting.sh \ json_array_looping.sh \ json_object_looping.sh \ json_nonarray_looping.sh endif if HAVE_VALGRIND TESTS += \ mmjsonparse_extra_data-vg.sh \ json_null_array-vg.sh \ json_object_looping-vg.sh \ json_array_looping-vg.sh \ json_object_suicide_in_loop-vg.sh \ json_null-vg.sh endif TESTS += \ stop_when_array_has_element.sh \ json_null_array.sh \ json_null.sh \ json_var_cmpr.sh \ json_var_case.sh endif if ENABLE_MMJSONTRANSFORM if ENABLE_IMTCP_TESTS TESTS += \ mmjsontransform-basic.sh endif endif if ENABLE_MMDBLOOKUP TESTS += \ mmdb.sh \ mmdb-space.sh \ mmdb-container.sh \ mmdb-container-empty.sh if HAVE_VALGRIND TESTS += \ mmdb-vg.sh \ mmdb-multilevel-vg.sh endif endif if ENABLE_GNUTLS_TESTS TESTS += \ imtcp-tls-basic.sh \ imtcp-tls-input-basic.sh \ imtcp-tls-input-2certs.sh \ imtcp-tls-basic-verifydepth.sh \ imtcp_conndrop_tls.sh \ imtcp-tls-gibberish.sh \ sndrcv_tls_anon_rebind.sh \ sndrcv_tls_anon_hostname.sh \ sndrcv_tls_anon_ipv4.sh \ sndrcv_tls_anon_ipv6.sh \ sndrcv_tls_certless_clientonly.sh \ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \ sndrcv_tls_priorityString.sh \ sndrcv_tls_certvalid.sh \ sndrcv_tls_certvalid_action_level.sh \ sndrcv_tls_certvalid_expired.sh \ sndrcv_tls_certvalid_expired_defaultmode.sh \ sndrcv_tls_certvalid_revoked.sh \ sndrcv_tls_client_missing_cert.sh \ imtcp-tls-no-lstn-startup.sh \ imtcp-tls-gtls-x509fingerprint-invld.sh \ imtcp-tls-gtls-x509fingerprint.sh \ imtcp-tls-gtls-x509name-invld.sh \ imtcp-tls-gtls-x509name.sh \ imtcp-tls-gtls-x509name-legacy.sh \ imtcp-drvr-in-input-basic.sh \ imtcp-multi-drvr-basic.sh \ imtcp-multi-drvr-basic-parallel.sh if HAVE_VALGRIND TESTS += \ imtcp-tls-basic-vg.sh \ imtcp_conndrop_tls-vg.sh \ manytcp-too-few-tls-vg.sh endif if ENABLE_OPENSSL TESTS += \ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh endif endif if ENABLE_MBEDTLS TESTS += \ imtcp-multi-drvr-basic-ptcp_gtls_mbedtls.sh \ imtcp-tls-mbedtls-basic.sh \ imtcp-tls-mbedtls-basic-verifydepth.sh \ imtcp-tls-mbedtls-error-ca.sh \ imtcp-tls-mbedtls-error-cert.sh \ imtcp-tls-mbedtls-error-key2.sh \ imtcp-tls-mbedtls-error-key.sh \ imtcp-tls-mbedtls-input-basic.sh \ imtcp-tls-mbedtls-x509invalid.sh \ imtcp-tls-mbedtls-x509name_invalid.sh \ imtcp-tls-mbedtls-x509name.sh \ imtcp-tls-mbedtls-x509valid.sh \ imtcp-tls-mbedtls-x509fingerprint-invld.sh \ imtcp-tls-mbedtls-x509fingerprint.sh \ imtcp-tls-mbedtls-x509name-multi-wildcard.sh \ sndrcv_tls_certless_clientonly_mbedtls.sh \ sndrcv_tls_gtls_serveranon_mbedtls_clientanon.sh \ sndrcv_tls_gtls_servercert_mbedtls_clientanon.sh \ sndrcv_tls_mbedtls_certvalid_action_level.sh \ sndrcv_tls_mbedtls_certvalid_expired.sh \ sndrcv_tls_mbedtls_certvalid_revoked.sh \ sndrcv_tls_mbedtls_certvalid.sh \ sndrcv_tls_mbedtls_servercert_clientcert.sh \ sndrcv_tls_mbedtls_servercert_mbedtls_clientanon.sh \ sndrcv_tls_servercert_mbedtls_clientanon.sh \ sndrcv_tls_mbedtls_certvalid_expired_autrzd.sh \ sndrcv_tls_mbedtls_gnutlspriorityString_no_suite_in_common.sh \ sndrcv_tls_mbedtls_gnutlspriorityString_suite_in_common.sh \ sndrcv_tls_servercert_bad_eku_chk_mbedtls_clientanon.sh \ sndrcv_tls_servercert_bad_eku_no_chk_mbedtls_clientanon.sh if HAVE_VALGRIND TESTS += \ imtcp-tls-mbedtls-basic-vg.sh \ imtcp-tls-mbedtls-basic-brokenhandshake-vg.sh endif endif if ENABLE_OPENSSL TESTS += \ imtcp-tls-ossl-basic.sh \ imtcp-tls-ossl-input-basic.sh \ imtcp-tls-ossl-input-2certs.sh \ imtcp-tls-ossl-basic-tlscommands.sh \ imtcp-tls-ossl-basic-verifydepth.sh \ imtcp-tls-ossl-invalid-verifydepth.sh \ sndrcv_tls_ossl_anon_ipv4.sh \ sndrcv_tls_ossl_anon_ipv6.sh \ sndrcv_tls_ossl_anon_rebind.sh \ sndrcv_tls_ossl_anon_ciphers.sh \ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \ sndrcv_tls_ossl_certvalid.sh \ sndrcv_tls_ossl_certvalid_action_level.sh \ sndrcv_tls_ossl_certvalid_expired.sh \ sndrcv_tls_ossl_certvalid_tlscommand.sh \ sndrcv_tls_ossl_certvalid_ciphers.sh \ sndrcv_tls_ossl_certvalid_revoked.sh \ sndrcv_tls_ossl_intermediate_ca_chain.sh \ imtcp-tls-ossl-x509valid.sh \ imtcp-tls-ossl-x509name.sh \ imtcp-tls-ossl-x509fingerprint.sh \ imtcp-tls-ossl-error-ca.sh \ imtcp-tls-ossl-error-cert.sh \ imtcp-tls-ossl-error-key.sh \ imtcp-tls-ossl-error-key2.sh # imtcp-tls-ossl-basic-stress.sh if HAVE_VALGRIND TESTS += \ imtcp-tls-ossl-basic-vg.sh \ imtcp-tls-ossl-basic-brokenhandshake-vg.sh endif endif if ENABLE_GNUTLS_TESTS if ENABLE_OPENSSL TESTS += \ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh endif endif if ENABLE_OMUXSOCK TESTS += uxsock_simple.sh \ uxsock_simple_abstract.sh \ uxsock_multiple.sh \ uxsock_multiple_netns.sh if HAVE_VALGRIND TESTS += uxsock_simple_abstract-vg.sh \ uxsock_multiple-vg.sh \ uxsock_multiple_netns-vg.sh endif # HAVE_VALGRIND endif if ENABLE_RELP TESTS += sndrcv_relp.sh \ sndrcv_relp_rebind.sh \ omrelp_errmsg_no_connect.sh \ imrelp-basic.sh \ imrelp-basic-oldstyle.sh \ imrelp-basic-hup.sh \ imrelp-manyconn.sh \ imrelp-maxDataSize-error.sh \ imrelp-long-msg.sh \ imrelp-oversizeMode-truncate.sh \ imrelp-oversizeMode-accept.sh \ imrelp-invld-tlslib.sh \ imrelp-bigmessage.sh \ omrelp-invld-tlslib.sh \ sndrcv_relp_dflt_pt.sh \ glbl-oversizeMsg-log.sh \ glbl-oversizeMsg-truncate.sh \ glbl-oversizeMsg-split.sh if ENABLE_GNUTLS TESTS += \ sndrcv_relp_tls.sh \ sndrcv_relp_tls_certvalid.sh \ sndrcv_tls_certvalid_action_level.sh \ sndrcv_relp_tls_prio.sh \ sndrcv_relp_tls_chainedcert.sh \ relp_tls_certificate_not_found.sh \ omrelp_wrong_authmode.sh \ imrelp-tls.sh \ imrelp-tls-chainedcert.sh \ imrelp-tls-mixed-chainedcert.sh \ imrelp-tls-mixed-chainedcert2.sh if USE_RELPENGINESETTLSCFGCMD TESTS += \ imrelp-tls-cfgcmd.sh \ sndrcv_relp_tls-cfgcmd.sh endif # USE_RELPENGINESETTLSCFGCMD endif # ENABLE_GNUTLS if HAVE_VALGRIND TESTS += \ imrelp-basic-vg.sh \ imrelp-sessionbreak-vg.sh \ imrelp-manyconn-vg.sh \ sndrcv_relp-vg-rcvr.sh \ sndrcv_relp-vg-sender.sh endif # HAVE_VALGRIND endif if ENABLE_IMDTLS TESTS += \ imdtls-basic.sh \ imdtls-basic-tlscommands.sh \ imdtls-basic-timeout.sh \ imdtls-error-cert.sh \ imdtls-sessionbreak.sh if HAVE_VALGRIND TESTS += \ imdtls-basic-vg.sh \ imdtls-sessionbreak-vg.sh endif # HAVE_VALGRIND if ENABLE_OMDTLS TESTS += \ sndrcv_dtls_certvalid.sh \ sndrcv_dtls_anon_ciphers.sh \ sndrcv_dtls_certvalid_ciphers.sh \ sndrcv_dtls_certvalid_permitted.sh \ sndrcv_dtls_certvalid_missing.sh \ sndrcv_dtls_anon_ciphers.sh if HAVE_VALGRIND TESTS += \ sndrcv_dtls_certvalid-vg.sh endif # HAVE_VALGRIND endif # ENABLE_OMDTLS endif # ENABLE_IMDTLS if ENABLE_OMUDPSPOOF TESTS += \ omudpspoof_errmsg_no_params.sh \ sndrcv_omudpspoof.sh \ sndrcv_omudpspoof-bigmsg.sh \ sndrcv_omudpspoof_nonstdpt.sh endif #disabled as array-passing mode is no longer supported: omod-if-array.sh # omod-if-array.sh # omod-if-array-udp.sh if ENABLE_IMPTCP TESTS += \ tabescape_dflt.sh \ tabescape_dflt-udp.sh \ tabescape_off.sh \ tabescape_off-udp.sh \ tabescape_on.sh \ inputname-imtcp.sh \ fieldtest.sh \ fieldtest-udp.sh \ proprepltest-nolimittag-udp.sh \ proprepltest-nolimittag.sh \ proprepltest-rfctag-udp.sh \ proprepltest-rfctag.sh endif if ENABLE_OMRULESET TESTS += \ omruleset.sh \ omruleset-queue.sh endif if ENABLE_PMDB2DIAG TESTS += \ pmdb2diag_parse.sh endif if ENABLE_PMSNARE TESTS += \ pmsnare-default.sh \ pmsnare-default-udp.sh \ pmsnare-ccoff.sh \ pmsnare-ccoff-udp.sh \ pmsnare-ccdefault.sh \ pmsnare-ccdefault-udp.sh \ pmsnare-cccstyle.sh \ pmsnare-cccstyle-udp.sh \ pmsnare-ccbackslash.sh \ pmsnare-ccbackslash-udp.sh \ pmsnare-modoverride.sh \ pmsnare-modoverride-udp.sh endif if ENABLE_PMLASTMSG TESTS += \ pmlastmsg.sh \ pmlastmsg-udp.sh endif if ENABLE_EXTENDED_TESTS # random.sh is temporarily disabled as it needs some work # to rsyslog core to complete in reasonable time #TESTS += random.sh if ENABLE_IMFILE_TESTS TESTS += \ imfile-basic-2GB-file.sh \ imfile-truncate-2GB-file.sh endif # ENABLE_IMFILE_TESTS endif if ENABLE_IMFILE_TESTS TESTS += \ imfile-basic.sh \ imfile-basic-legacy.sh \ imfile-discard-truncated-line.sh \ imfile-truncate-line.sh \ imfile-file-not-found-error.sh \ imfile-fileNotFoundError-parameter.sh \ imfile-error-not-repeated.sh \ imfile-truncate.sh \ imfile-truncate-multiple.sh \ imfile-readmode2.sh \ imfile-readmode2-polling.sh \ imfile-readmode2-with-persists-data-during-stop.sh \ imfile-readmode2-with-persists.sh \ imfile-endregex.sh \ imfile-endregex-save-lf.sh \ imfile-endregex-save-lf-persist.sh \ imfile-endregex-timeout-none-polling.sh \ imfile-endregex-timeout-polling.sh \ imfile-endregex-timeout.sh \ imfile-endregex-timeout-none.sh \ imfile-endregex-timeout-with-shutdown.sh \ imfile-endregex-timeout-with-shutdown-polling.sh \ imfile-endmsg.regex.sh \ imfile-escapelf.replacement.sh \ imfile-escapelf.replacement-empty.sh \ imfile-statefile-no-file_id.sh \ imfile-statefile-no-file_id-TO-file_id.sh \ imfile-statefile-directory.sh \ imfile-statefile-delete.sh \ imfile-statefile-no-delete.sh \ imfile-persist-state-1.sh \ imfile-freshStartTail1.sh \ imfile-freshStartTail2.sh \ imfile-freshStartTail3.sh \ imfile-wildcards.sh \ imfile-wildcards-dirs.sh \ imfile-wildcards-dirs2.sh \ imfile-wildcards-dirs-multi.sh \ imfile-wildcards-dirs-multi2.sh \ imfile-wildcards-dirs-multi3.sh \ imfile-wildcards-dirs-multi4.sh \ imfile-wildcards-dirs-multi5.sh \ imfile-wildcards-dirs-multi5-polling.sh \ imfile-old-state-file.sh \ imfile-rename-while-stopped.sh \ imfile-rename.sh \ imfile-symlink.sh \ imfile-symlink-multi.sh \ imfile-symlink-ext-tmp-dir-tree.sh \ imfile-logrotate.sh \ imfile-logrotate-async.sh \ imfile-logrotate-multiple.sh \ imfile-logrotate-copytruncate.sh \ imfile-logrotate-nocopytruncate.sh \ imfile-logrotate-state-files.sh \ imfile-growing-file-id.sh \ imfile-ignore-old-file-1.sh \ imfile-ignore-old-file-2.sh \ imfile-ignore-old-file-3.sh \ imfile-ignore-old-file-4.sh \ imfile-ignore-old-file-5.sh \ imfile-ignore-old-file-6.sh \ imfile-ignore-old-file-7.sh \ glbl-oversizeMsg-truncate-imfile.sh \ config_enabled-on.sh \ config_enabled-off.sh if ENABLE_MMNORMALIZE TESTS += \ imfile-endmsg.regex-with-example.sh endif if HAVE_VALGRIND TESTS += \ imfile-basic-vg.sh \ imfile-endregex-vg.sh \ imfile-endmsg.regex-vg.sh \ imfile-readmode0-vg.sh \ imfile-readmode2-vg.sh if ENABLE_HELGRIND TESTS += \ imfile-basic-vgthread.sh endif # ENABLE_HELGRIND if ENABLE_MMNORMALIZE TESTS += \ imfile-endmsg.regex-with-example-vg.sh endif # ENABLE_MMNORMALIZE endif # HAVE_VALGRIND endif # ENABLE_IMFILE_TESTS if ENABLE_IMBATCHREPORT TESTS += \ imbatchreport_errmsg_no_params.sh \ imbatchreport_errmsg_glob_not_regular.sh \ imbatchreport_errmsg_glob_dir_fake.sh \ imbatchreport_errmsg_glob_dir_not_dir.sh \ imbatchreport_errmsg_regex.match.reject.sh \ imbatchreport_errmsg_regex.match.rename.sh \ imbatchreport_errmsg_regex.nomatch.sh \ imbatchreport_errmsg_not_supported1.sh \ imbatchreport_errmsg_not_supported2.sh \ imbatchreport_errmsg_not_supported3.sh \ imbatchreport_errmsg_delete_params.sh \ imbatchreport_errmsg_rename_params.sh \ imbatchreport_delete_success.sh \ imbatchreport_delete_structdata.sh \ imbatchreport_rename_success.sh \ imbatchreport_delete_toolarge.sh \ imbatchreport_rename_toolarge.sh if HAVE_VALGRIND TESTS += \ imbatchreport_errmsg_no_params-vg.sh endif # ENABLE_IMBATCHREPORT endif if ENABLE_OMTCL TESTS += \ omtcl.sh endif if ENABLE_MMTAGHOSTNAME TESTS += \ mmtaghostname_tag.sh \ mmtaghostname_server.sh endif if ENABLE_MMKUBERNETES if ENABLE_MMJSONPARSE if ENABLE_IMFILE if ENABLE_IMPSTATS TESTS += \ mmkubernetes-basic.sh \ mmkubernetes-cache-expire.sh if HAVE_VALGRIND TESTS += \ mmkubernetes-basic-vg.sh \ mmkubernetes-cache-expire-vg.sh endif endif endif endif endif if ENABLE_IMTUXEDOULOG TESTS += \ imtuxedoulog_errmsg_no_params.sh \ imtuxedoulog_data.sh if HAVE_VALGRIND TESTS += \ imtuxedoulog_errmsg_no_params-vg.sh endif # ENABLE_IMTUXEDOULOG endif if ENABLE_OMAMQP1 TESTS += \ omamqp1-basic.sh if HAVE_VALGRIND TESTS += \ omamqp1-basic-vg.sh endif endif # ENABLE_OMAMQP1 endif # if ENABLE_TESTBENCH TESTS_ENVIRONMENT = RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/ TESTS_ENVIRONMENT+= TOP_BUILDDIR='$(top_builddir)' TESTS_ENVIRONMENT+= TESTTOOL_DIR='$(abs_top_builddir)/tests' test_files = testbench.h runtime-dummy.c DISTCLEANFILES=rsyslog.pid distclean-local: rm -rf .dep_cache .dep_wrk EXTRA_DIST= \ set-envvars.in \ urlencode.py \ dnscache-TTL-0.sh \ dnscache-TTL-0-vg.sh \ loadbalance.sh \ smtradfile.sh \ smtradfile-vg.sh \ immark.sh \ immark-inputname.sh \ immark-ruleset.sh \ immark-ruleset-custom-msg.sh \ operatingstate-basic.sh \ operatingstate-empty.sh \ operatingstate-unclean.sh \ internal-errmsg-memleak-vg.sh \ glbl-ruleset-queue-defaults.sh \ glbl-internalmsg_severity-info-shown.sh \ glbl-internalmsg_severity-debug-shown.sh \ glbl-internalmsg_severity-debug-not_shown.sh \ glbl-oversizeMsg-log-vg.sh \ config_enabled-on.sh \ config_enabled-off.sh \ empty-app-name.sh \ empty-hostname.sh \ endswith-basic.sh \ func-substring-invld-startpos.sh \ func-substring-invld-startpos-vg.sh \ func-substring-large-endpos.sh \ func-substring-large-neg-endpos.sh \ func-substring-relative-endpos.sh \ hostname-with-slash-pmrfc5424.sh \ hostname-with-slash-pmrfc3164.sh \ pmrfc3164-msgFirstSpace.sh \ pmrfc3164-AtSignsInHostname.sh \ pmrfc3164-AtSignsInHostname_off.sh \ pmrfc3164-tagEndingByColon.sh \ pmrfc3164-defaultTag.sh \ pmrfc3164-json.sh \ pmrfc3164-headerless.sh \ pmrfc3164-drop.sh \ hostname-with-slash-dflt-invld.sh \ hostname-with-slash-dflt-slash-valid.sh \ glbl-umask.sh \ glbl-unloadmodules.sh \ glbl-invld-param.sh \ glbl_setenv_2_vars.sh \ glbl_setenv_err.sh \ glbl_setenv_err_too_long.sh \ glbl_setenv.sh \ imtuxedoulog_errmsg_no_params.sh \ imtuxedoulog_data.sh \ imtuxedoulog_errmsg_no_params-vg.sh \ pmdb2diag_parse.sh \ mmtaghostname_tag.sh \ mmtaghostname_server.sh \ imbatchreport_errmsg_no_params.sh \ imbatchreport_errmsg_glob_not_regular.sh \ imbatchreport_errmsg_glob_dir_fake.sh \ imbatchreport_errmsg_glob_dir_not_dir.sh \ imbatchreport_errmsg_regex.match.reject.sh \ imbatchreport_errmsg_regex.match.rename.sh \ imbatchreport_errmsg_regex.nomatch.sh \ imbatchreport_errmsg_not_supported1.sh \ imbatchreport_errmsg_not_supported2.sh \ imbatchreport_errmsg_not_supported3.sh \ imbatchreport_errmsg_delete_params.sh \ imbatchreport_errmsg_rename_params.sh \ imbatchreport_delete_success.sh \ imbatchreport_delete_structdata.sh \ imbatchreport_rename_success.sh \ imbatchreport_delete_toolarge.sh \ imbatchreport_rename_toolarge.sh \ imbatchreport_errmsg_no_params-vg.sh \ mmexternal-SegFault.sh \ mmexternal-SegFault-empty-jroot-vg.sh \ testsuites/mmexternal-SegFault-mm-python.py \ testsuites/mmsnareparse/sample-custom-pattern.data \ mmsnareparse-basic.sh \ mmsnareparse-comprehensive.sh \ mmsnareparse-comprehensive-vg.sh \ mmsnareparse-custom.sh \ mmsnareparse-enhanced-validation.sh \ mmsnareparse-json.sh \ mmsnareparse-sysmon.sh \ mmsnareparse-kerberos.sh \ mmsnareparse-realworld-4624-4634-5140.sh \ mmsnareparse-syslog.sh \ mmsnareparse-value-types.sh \ mmsnareparse-trailing-extradata.sh \ mmsnareparse-trailing-extradata-regex.sh \ mmexternal-InvldProg-vg.sh \ nested-call-shutdown.sh \ 1.rstest 2.rstest 3.rstest err1.rstest \ config_multiple_include.sh \ testsuites/include-std1-omfile-action.conf \ testsuites/include-std2-omfile-action.conf \ invalid_nested_include.sh \ validation-run.sh \ tls-certs/ca-key.pem \ tls-certs/ca.pem \ tls-certs/cert.pem \ tls-certs/certchained.pem \ tls-certs/key.pem \ tls-certs/ca-fail.pem \ tls-certs/cert-fail.pem \ tls-certs/key-fail.pem \ testsuites/x.509/ca.srl \ testsuites/x.509/client-cert-new.pem \ testsuites/x.509/client-new.csr \ testsuites/x.509/client-revoked-key.pem \ testsuites/x.509/client-revoked-valid.pem \ testsuites/x.509/client-revoked.csr \ testsuites/x.509/client-revoked.pem \ testsuites/x.509/crl.pem \ testsuites/x.509/index.txt \ testsuites/x.509/index.txt.attr \ testsuites/x.509/newcerts/01.pem \ testsuites/x.509/newcerts/02.pem \ testsuites/x.509/newcerts/03.pem \ testsuites/x.509/newcerts/04.pem \ testsuites/x.509/openssl-cmds.sh \ testsuites/x.509/openssl.cnf \ testsuites/x.509/serial \ testsuites/x.509/ca.pem \ testsuites/x.509/ca-key.pem \ testsuites/x.509/client-cert.pem \ testsuites/x.509/client-key.pem \ testsuites/x.509/machine-cert.pem \ testsuites/x.509/machine-key.pem \ testsuites/x.509/client-expired-cert.pem \ testsuites/x.509/client-expired-key.pem \ cfg.sh \ cfg1.cfgtest \ cfg1.testin \ cfg2.cfgtest \ cfg2.testin \ cfg3.cfgtest \ cfg3.testin \ cfg4.cfgtest \ cfg4.testin \ DevNull.cfgtest \ err1.rstest \ NoExistFile.cfgtest \ tcp_forwarding_tpl.sh \ tcp_forwarding_ns_tpl.sh \ tcp_forwarding_dflt_tpl.sh \ tcp_forwarding_retries.sh \ mainq_actq_DA.sh \ queue_warnmsg-oversize.sh \ queue-minbatch.sh \ queue-minbatch-queuefull.sh \ queue-direct-with-no-params.sh \ queue-direct-with-params-given.sh \ killrsyslog.sh \ parsertest-parse1.sh \ parsertest-parse1-udp.sh \ parsertest-parse2.sh \ parsertest-parse2-udp.sh \ parsertest-parse_8bit_escape.sh \ parsertest-parse_8bit_escape-udp.sh \ parsertest-parse3.sh \ parsertest-parse3-udp.sh \ parsertest-parse_invld_regex.sh \ parsertest-parse_invld_regex-udp.sh \ parsertest-parse-3164-buggyday.sh \ parsertest-parse-3164-buggyday-udp.sh \ parsertest-parse-nodate.sh \ parsertest-parse-nodate-udp.sh \ parsertest-snare_ccoff_udp.sh \ parsertest-snare_ccoff_udp2.sh \ fieldtest.sh \ fieldtest-udp.sh \ proprepltest-nolimittag-udp.sh \ proprepltest-nolimittag.sh \ proprepltest-rfctag-udp.sh \ proprepltest-rfctag.sh \ timestamp-3164.sh \ timestamp-3339.sh \ timestamp-isoweek.sh \ timestamp-mysql.sh \ timestamp-pgsql.sh \ timestamp-subseconds.sh \ rsf_getenv.sh \ diskq-rfc5424.sh \ rfc5424parser-sp_at_msg_start.sh \ diskqueue-full.sh \ diskqueue-fail.sh \ diskqueue.sh \ diskqueue-non-unique-prefix.sh \ arrayqueue.sh \ include-obj-text-from-file.sh \ include-obj-text-from-file-noexist.sh \ include-obj-outside-control-flow-vg.sh \ include-obj-in-if-vg.sh \ include-obj-text-vg.sh \ config_output-o-option.sh \ rscript-config_enable-off-vg.sh \ rscript-config_enable-on.sh \ rscript_http_request.sh \ rscript_http_request-vg.sh \ rscript_bare_var_root.sh \ rscript_bare_var_root-empty.sh \ rscript_b64_decode.sh \ rscript_b64_decode-vg.sh \ rscript_contains.sh \ rscript_ipv42num.sh \ rscript_field.sh \ rscript_field-vg.sh \ rscript_stop.sh \ rscript_stop2.sh \ stop.sh \ rscript_le.sh \ rscript_le_var.sh \ rscript_ge.sh \ rscript_ge_var.sh \ rscript_lt.sh \ rscript_lt_var.sh \ rscript_gt.sh \ rscript_gt_var.sh \ rscript_ne.sh \ rscript_ne_var.sh \ rscript_number_comparison_LE.sh \ rscript_number_comparison_LE-vg.sh \ rscript_number_comparison_LT.sh \ rscript_compare_str-numstr.sh \ rscript_compare_str-num.sh \ rscript_compare_numstr-str.sh \ rscript_compare_num-str.sh \ rscript_compare_numstr-numstr.sh \ rscript_compare_numstr-num.sh \ rscript_compare_num-numstr.sh \ rscript_compare_num-num.sh \ rscript_compare_str-str.sh \ rscript_compare_str-str-vg.sh \ rscript_compare_str-num-vg.sh \ rscript_compare_str-numstr-vg.sh \ rscript_compare_num-str-vg.sh \ rscript_compare_numstr-str-vg.sh \ rscript_compare_numstr-num-vg.sh \ rscript_compare_numstr-numstr-vg.sh \ rscript_compare_num-num-vg.sh \ rscript_compare_num-numstr-vg.sh \ rscript_compare-common.sh \ rscript_num2ipv4.sh \ rscript_int2Hex.sh \ rscript_trim.sh \ rscript_substring.sh \ rscript_toupper.sh \ rscript_format_time.sh \ rscript_parse_time.sh \ rscript_parse_time_get-ts.py \ rscript_is_time.sh \ rscript_script_error.sh \ rscript_parse_json.sh \ rscript_parse_json-vg.sh \ rscript_backticks-vg.sh \ rscript_backticks_empty_envvar.sh \ rscript_backticks_static_text.sh \ rscript_backticks_braces_envvar.sh \ rscript_previous_action_suspended.sh \ rscript_str2num_negative.sh \ rscript_exists-yes.sh \ rscript_exists-yes2.sh \ rscript_exists-not1.sh \ rscript_exists-not2.sh \ rscript_exists-not3.sh \ rscript_exists-not4.sh \ rscript_unflatten_arg1_unsuitable.sh \ rscript_unflatten_arg2_invalid.sh \ rscript_unflatten_conflict1.sh \ rscript_unflatten_conflict2.sh \ rscript_unflatten_conflict3.sh \ rscript_unflatten_key_truncated.sh \ rscript_unflatten_non_object.sh \ rscript_unflatten_object_exclamation.sh \ rscript_unflatten_object.sh \ rscript_unflatten_arg1_unsuitable-vg.sh \ rscript_unflatten_arg2_invalid-vg.sh \ rscript_unflatten_conflict1-vg.sh \ rscript_unflatten_conflict2-vg.sh \ rscript_unflatten_conflict3-vg.sh \ rscript_unflatten_key_truncated-vg.sh \ rscript_unflatten_non_object-vg.sh \ rscript_unflatten_object_exclamation-vg.sh \ rscript_unflatten_object-vg.sh \ rscript_get_property.sh \ rscript_get_property-vg.sh \ rs-cnum.sh \ rs-int2hex.sh \ rs-substring.sh \ omsnmp_errmsg_no_params.sh \ sndrcv_omsnmpv1_udp.sh \ sndrcv_omsnmpv1_udp_dynsource.sh \ sndrcv_omsnmpv1_udp_invalidoid.sh \ snmptrapreceiver.py \ ommail_errmsg_no_params.sh \ mmdarwin_errmsg_no_params.sh \ mmdarwin_errmsg_no_sock.sh \ mmdarwin_errmsg_no_sock-vg.sh \ mmutf8fix_no_error.sh \ tcpflood_wrong_option_output.sh \ msleep_usage_output.sh \ mangle_qi_usage_output.sh \ minitcpsrv_usage_output.sh \ test_id_usage_output.sh \ mmanon_with_debug.sh \ mmanon_random_32_ipv4.sh \ mmanon_random_cons_32_ipv4.sh \ mmanon_recognize_ipv4.sh \ mmanon_zero_12_ipv4.sh \ mmanon_zero_33_ipv4.sh \ mmanon_zero_8_ipv4.sh \ mmanon_simple_12_ipv4.sh \ mmanon_simple_33_ipv4.sh \ mmanon_simple_8_ipv4.sh \ mmanon_simple_mallformed_ipv4.sh \ mmanon_random_128_ipv6.sh \ mmanon_zero_128_ipv6.sh \ mmanon_zero_96_ipv6.sh \ mmanon_random_cons_128_ipv6.sh \ mmanon_zero_50_ipv6.sh \ mmanon_recognize_ipv6.sh \ mmanon_zero_64_ipv6.sh \ mmanon_both_modes_compatible.sh \ mmanon_recognize_ipembedded.sh \ mmanon_ipv6_port.sh \ mmanon_random_cons_128_ipembedded.sh \ rscript_eq.sh \ rscript_eq_var.sh \ rscript_set_memleak-vg.sh \ rscript_set_unset_invalid_var.sh \ rscript_set_modify.sh \ stop-localvar.sh \ stop-msgvar.sh \ omfwd-lb-1target-retry-full_buf.sh \ omfwd-lb-1target-retry-1_byte_buf.sh \ omfwd-lb-1target-retry-test_skeleton.sh \ omfwd-lb-1target-retry-1_byte_buf-TargetFail.sh \ omfwd-lb-1target-retry-test_skeleton-TargetFail.sh \ omfwd-lb-susp.sh \ omfwd-lb-2target-basic.sh \ omfwd-lb-2target-impstats.sh \ omfwd-lb-2target-retry.sh \ omfwd-lb-2target-one_fail.sh \ omfwd-tls-invalid-permitExpiredCerts.sh \ omfwd-keepalive.sh \ omfwd-subtree-tpl.sh \ omfile-subtree-jsonf.sh \ omfwd_fast_imuxsock.sh \ omfile_hup-vg.sh \ omrelp-keepalive.sh \ omsendertrack-basic.sh \ omsendertrack-basic-vg.sh \ omsendertrack-statefile.sh \ omsendertrack-statefile-vg.sh \ zstd.sh \ zstd-vg.sh \ gzipwr_hup-vg.sh \ omusrmsg-errmsg-no-params.sh \ omusrmsg-noabort.sh \ omusrmsg-noabort-vg.sh \ omfile-module-params.sh \ omfile-read-only-errmsg.sh \ omfile-null-filename.sh \ omfile-whitespace-filename.sh \ omfile-read-only.sh \ omfile-outchannel.sh \ omfile-outchannel-many.sh \ omfile-sizelimitcmd-many.sh \ omfile_both_files_set.sh \ omfile_hup.sh \ omrabbitmq_no_params.sh \ omrabbitmq_params_missing0.sh \ omrabbitmq_params_missing1.sh \ omrabbitmq_params_missing2.sh \ omrabbitmq_params_invalid0.sh \ omrabbitmq_params_invalid1.sh \ omrabbitmq_params_invalid2.sh \ omrabbitmq_params_invalid3.sh \ omrabbitmq_data_1server.sh \ omrabbitmq_data_1server-vg.sh \ omrabbitmq_data_2servers.sh \ omrabbitmq_error_server0.sh \ omrabbitmq_error_server1.sh \ omrabbitmq_error_server2.sh \ omrabbitmq_error_server3.sh \ omrabbitmq_json.sh \ omrabbitmq_raw.sh \ imhiredis-queue.sh \ imhiredis-queue-vg.sh \ imhiredis-queue-lpop.sh \ imhiredis-queue-lpop-vg.sh \ imhiredis-redis-restart.sh \ imhiredis-redis-restart-vg.sh \ imhiredis-redis-start-after.sh \ imhiredis-redis-start-after-vg.sh \ imhiredis-subscribe.sh \ imhiredis-subscribe-vg.sh \ imhiredis-stream.sh \ imhiredis-stream-vg.sh \ imhiredis-stream-from-beginning.sh \ imhiredis-stream-from-beginning-vg.sh \ imhiredis-stream-consumerGroup-ack.sh \ imhiredis-stream-consumerGroup-ack-vg.sh \ imhiredis-stream-consumerGroup-noack.sh \ imhiredis-stream-consumerGroup-noack-vg.sh \ imhiredis-stream-consumerGroup-reclaim.sh \ imhiredis-stream-consumerGroup-reclaim-vg.sh \ msgvar-concurrency.sh \ msgvar-concurrency-array.sh \ testsuites/msgvar-concurrency-array.rulebase \ msgvar-concurrency-array-event.tags.sh \ testsuites/msgvar-concurrency-array-event.tags.rulebase \ localvar-concurrency.sh \ exec_tpl-concurrency.sh \ prop-jsonmesg-vg.sh \ prop-all-json-concurrency.sh \ no-parser-errmsg.sh \ global_vars.sh \ no-parser-errmsg.sh \ no-parser-vg.sh \ prop-programname.sh \ prop-programname-with-slashes.sh \ rfc5424parser.sh \ rscript_privdropuser.sh \ rscript_privdropuserid.sh \ rscript_privdropgroup.sh \ rscript_privdropgroupid.sh \ privdrop_common.sh \ privdropuser.sh \ privdropuserid.sh \ privdropgroup.sh \ privdropgroupid.sh \ privdropabortonidfail.sh \ privdropabortonidfaillegacy.sh \ json-nonstring.sh \ json-onempty-at-end.sh \ template-json.sh \ template-pure-json.sh \ template-jsonf-nested.sh \ template-pos-from-to.sh \ template-pos-from-to-lowercase.sh \ template-pos-from-to-oversize.sh \ template-pos-from-to-oversize-lowercase.sh \ template-pos-from-to-missing-jsonvar.sh \ template-const-jsonf.sh \ template-topos-neg.sh \ fac_authpriv.sh \ fac_local0.sh \ fac_local0-vg.sh \ fac_local7.sh \ fac_mail.sh \ fac_news.sh \ fac_ftp.sh \ fac_ntp.sh \ fac_uucp.sh \ fac_invld1.sh \ fac_invld2.sh \ fac_invld3.sh \ fac_invld4_rfc5424.sh \ compresssp.sh \ compresssp-stringtpl.sh \ now_family_utc.sh \ now-utc-ymd.sh \ now-utc-casecmp.sh \ now-utc.sh \ now-unixtimestamp.sh \ faketime_common.sh \ imjournal-basic.sh \ imjournal-statefile.sh \ imjournal-statefile-vg.sh \ imjournal-basic-vg.sh \ omjournal-abort-template.sh \ omjournal-abort-no-template.sh \ omjournal-basic-template.sh \ omjournal-basic-no-template.sh \ timegenerated-ymd.sh \ timegenerated-uxtimestamp.sh \ timegenerated-uxtimestamp-invld.sh \ timegenerated-dateordinal.sh \ timegenerated-dateordinal-invld.sh \ timegenerated-utc.sh \ timegenerated-utc-legacy.sh \ timereported-utc.sh \ timereported-utc-legacy.sh \ timereported-utc-vg.sh \ mmrm1stspace-basic.sh \ mmaitag-basic.sh \ mmaitag-invalid-key.sh \ mmnormalize_parsesuccess.sh \ mmnormalize_parsesuccess-vg.sh \ mmnormalize_rule_from_string.sh \ mmnormalize_rule_from_array.sh \ pmnull-basic.sh \ pmnull-withparams.sh \ omstdout-basic.sh \ testsuites/mmnormalize_processing_tests.rulebase \ mmnormalize_processing_test1.sh \ mmnormalize_processing_test2.sh \ mmnormalize_processing_test3.sh \ mmnormalize_processing_test4.sh \ pmnormalize-basic.sh \ pmnormalize-rule.sh \ pmnormalize-rule_and_rulebase.sh \ pmnormalize-neither_rule_rulebase.sh \ pmnormalize-invld-rulebase.sh \ pmnormalize-rule_invld-data.sh \ testsuites/pmnormalize_basic.rulebase \ pmnormalize-basic-vg.sh \ pmnormalize-rule-vg.sh\ pmnormalize-rule_and_rulebase-vg.sh \ pmnormalize-neither_rule_rulebase-vg.sh \ pmnormalize-invld-rulebase-vg.sh \ pmnormalize-rule_invld-data-vg.sh \ rawmsg-after-pri.sh \ rs_optimizer_pri.sh \ rscript_prifilt.sh \ rscript_optimizer1.sh \ rscript_ruleset_call.sh \ rscript_ruleset_call_indirect-basic.sh \ rscript_ruleset_call_indirect-var.sh \ rscript_ruleset_call_indirect-invld.sh \ cee_simple.sh \ cee_diskqueue.sh \ mmleefparse_basic.sh \ mmjsonparse-w-o-cookie.sh \ mmjsonparse-w-o-cookie-multi-spaces.sh \ mmjsonparse-find-json-basic.sh \ mmjsonparse-find-json-trailing.sh \ mmjsonparse-find-json-scan-limit.sh \ mmjsonparse-find-json-invalid.sh \ mmjsonparse-find-json-invalid-mode.sh \ mmjsonparse-find-json-parser-validation.sh \ mmjsonparse_simple.sh \ mmjsonparse-invalid-containerName.sh \ wtpShutdownAll-assertionFailure.sh \ imptcp-octet-framing-too-long-vg.sh \ imptcp-oversize-message-display.sh \ imptcp-msg-truncation-on-number.sh \ imptcp-msg-truncation-on-number2.sh \ imtcp-netns.sh \ imptcp-maxFrameSize-parameter.sh \ mmjsonparse_cim.sh \ mmjsonparse_cim2.sh \ mmjsonparse_localvar.sh \ mmdb.sh \ mmdb-space.sh \ mmdb.rb \ test.mmdb \ with_space.mmdb \ mmdb-vg.sh \ mmdb-container.sh \ mmdb-container-empty.sh \ mmdb-multilevel-vg.sh \ incltest.sh \ incltest_dir.sh \ incltest_dir_empty_wildcard.sh \ incltest_dir_wildcard.sh \ testsuites/es.yml \ clickhouse-dflt-tpl.sh \ clickhouse-retry-error.sh \ clickhouse-start.sh \ clickhouse-stop.sh \ clickhouse-basic.sh \ clickhouse-load.sh \ clickhouse-bulk.sh \ clickhouse-bulk-load.sh \ clickhouse-limited-batch.sh \ clickhouse-select.sh \ clickhouse-wrong-quotation-marks.sh \ clickhouse-wrong-template-option.sh \ clickhouse-errorfile.sh \ clickhouse-wrong-insert-syntax.sh \ clickhouse-basic-vg.sh \ clickhouse-load-vg.sh \ clickhouse-bulk-vg.sh \ clickhouse-bulk-load-vg.sh \ es_response_get_msgnum.py \ elasticsearch-error-format-check.py \ es-duplicated-ruleset.sh \ es-duplicated-ruleset-vg.sh \ es-basic-es7.14.sh \ es-basic.sh \ es-basic-vgthread.sh \ es-basic-server.sh \ es-execOnlyWhenPreviousSuspended.sh \ es-basic-ha.sh \ es-basic-bulk.sh \ es-basic-errfile-empty.sh \ es-basic-errfile-popul.sh \ es-bulk-errfile-empty.sh \ es-bulk-errfile-popul.sh \ es-bulk-errfile-popul-def-format.sh \ es-bulk-errfile-popul-erronly.sh \ es-bulk-errfile-popul-erronly-interleaved.sh \ es-bulk-errfile-popul-def-interleaved.sh \ diskqueue-multithread-es.sh \ es-basic-vg.sh \ es-basic-bulk-vg.sh \ es-basic-ha-vg.sh \ es-maxbytes-bulk.sh \ es-bulk-retry.sh \ elasticsearch-stop.sh \ linkedlistqueue.sh \ da-mainmsg-q.sh \ diskqueue-fsync.sh \ msgdup.sh \ msgdup_props.sh \ empty-ruleset.sh \ ruleset-direct-queue.sh \ fromhost-port.sh \ fromhost-port-tuple.sh \ fromhost-port-async-ruleset.sh \ imtcp-tls-gibberish.sh \ imtcp-listen-port-file-2.sh \ allowed-sender-tcp-ok.sh \ allowed-sender-tcp-fail.sh \ allowed-sender-tcp-hostname-ok.sh \ allowed-sender-tcp-hostname-fail.sh \ imtcp-octet-framing-too-long-vg.sh \ imtcp-discard-truncated-msg.sh \ imtcp-basic.sh \ imtcp-basic-hup.sh \ imtcp-impstats.sh \ imtcp-impstats-single-thread.sh \ imtcp-starvation-0.sh \ imtcp-starvation-1.sh \ imtcp-maxFrameSize.sh \ imtcp-msg-truncation-on-number.sh \ imtcp-msg-truncation-on-number2.sh \ imtcp-netns.sh \ imtcp-NUL.sh \ imtcp-NUL-rawmsg.sh \ imtcp-tls-gtls-x509fingerprint-invld.sh \ imtcp-tls-gtls-x509fingerprint.sh \ imtcp-tls-gtls-x509name-invld.sh \ imtcp-tls-gtls-x509name.sh \ imtcp-tls-gtls-x509name-legacy.sh \ imtcp-drvr-in-input-basic.sh \ imtcp-multi-drvr-basic.sh \ imtcp-multi-drvr-basic-parallel.sh \ imtcp-multi-drvr-basic-ptcp_gtls_ossl.sh \ imtcp-tls-basic.sh \ imtcp-tls-input-basic.sh \ imtcp-tls-input-2certs.sh \ imtcp-tls-basic-verifydepth.sh \ imtcp-tls-basic-vg.sh \ imtcp-tls-no-lstn-startup.sh \ imtcp_incomplete_frame_at_end.sh \ imtcp-multiport.sh \ imtcp-bigmessage-octetcounting.sh \ imtcp-bigmessage-octetstuffing.sh \ udp-msgreduc-orgmsg-vg.sh \ udp-msgreduc-vg.sh \ manytcp-too-few-tls-vg.sh \ imtcp-tls-ossl-basic.sh \ imtcp-tls-ossl-input-basic.sh \ imtcp-tls-ossl-input-2certs.sh \ imtcp-tls-ossl-basic-tlscommands.sh \ imtcp-tls-ossl-basic-verifydepth.sh \ imtcp-tls-ossl-invalid-verifydepth.sh \ imtcp-tls-ossl-basic-stress.sh \ sndrcv_tls_ossl_anon_ipv4.sh \ sndrcv_tls_ossl_anon_ipv6.sh \ sndrcv_tls_ossl_anon_rebind.sh \ sndrcv_tls_ossl_anon_ciphers.sh \ sndrcv_tls_ossl_certvalid.sh \ sndrcv_tls_ossl_certvalid_action_level.sh \ sndrcv_tls_ossl_certvalid_expired.sh \ sndrcv_tls_ossl_certvalid_tlscommand.sh \ sndrcv_tls_ossl_certvalid_ciphers.sh \ sndrcv_tls_ossl_certvalid_revoked.sh \ imtcp-tls-ossl-x509valid.sh \ imtcp-tls-ossl-x509name.sh \ imtcp-tls-ossl-x509fingerprint.sh \ imtcp-tls-ossl-basic-vg.sh \ imtcp-tls-ossl-basic-brokenhandshake-vg.sh \ imtcp-tls-ossl-error-ca.sh \ imtcp-tls-ossl-error-cert.sh \ imtcp-tls-ossl-error-key.sh \ imtcp-tls-ossl-error-key2.sh \ manytcp.sh \ imtcp-tls-gtls-manycon.sh \ imtcp-tls-ossl-manycon.sh \ manyptcp.sh \ imptcp-basic-hup.sh \ imptcp-NUL.sh \ imptcp-NUL-rawmsg.sh \ imptcp_framing_regex.sh \ testsuites/imptcp_framing_regex.testdata \ imptcp_framing_regex-oversize.sh \ testsuites/imptcp_framing_regex-oversize.testdata \ imptcp_large.sh \ imptcp-connection-msg-disabled.sh \ imptcp-connection-msg-received.sh \ imptcp-discard-truncated-msg.sh \ imptcp_addtlframedelim.sh \ imptcp_conndrop-vg.sh \ imptcp_conndrop.sh \ imptcp_multi_line.sh \ testsuites/imptcp_multi_line.testdata \ imptcp_no_octet_counted.sh \ imtcp_addtlframedelim_on_input.sh \ testsuites/no_octet_counted.testdata \ imtcp_no_octet_counted.sh \ testsuites/spframingfix.testdata \ imtcp_spframingfix.sh \ imtcp-connection-msg-recieved.sh \ imptcp_spframingfix.sh \ msg-deadlock-headerless-noappname.sh \ imtcp_conndrop.sh \ imtcp_conndrop_tls.sh \ imtcp_conndrop_tls-vg.sh \ imtcp_addtlframedelim.sh \ tcp-msgreduc-vg.sh \ inputname-imtcp.sh \ omod-if-array.sh \ omod-if-array-udp.sh \ discard.sh \ failover-no-rptd.sh \ failover-no-rptd-vg.sh \ failover-no-basic.sh \ failover-no-basic-vg.sh \ failover-rptd.sh \ failover-rptd-vg.sh \ failover-basic.sh \ failover-basic-vg.sh \ failover-async.sh \ failover-double.sh \ suspend-via-file.sh \ suspend-omfwd-via-file.sh \ externalstate-failed-rcvr.sh \ discard-rptdmsg.sh \ discard-rptdmsg-vg.sh \ discard-allmark.sh \ discard-allmark-vg.sh \ diag.sh \ rcvr_fail_restore.sh \ queue-encryption-disk.sh \ queue-encryption-disk_keyfile.sh \ queue-encryption-disk_keyfile-vg.sh \ queue-encryption-disk_keyprog.sh \ queue-encryption-da.sh \ da-queue-persist.sh \ daqueue-dirty-shutdown.sh \ daqueue-invld-qi.sh \ daqueue-persist.sh \ daqueue-persist-drvr.sh \ queue-persist.sh \ queue-persist-drvr.sh \ threadingmq.sh \ threadingmqaq.sh \ sndrcv_drvr.sh \ sndrcv_drvr_noexit.sh \ sndrcv_failover.sh \ sndrcv.sh \ omrelp_errmsg_no_connect.sh \ imrelp-basic.sh \ imrelp-basic-hup.sh \ imrelp-basic-vg.sh \ imrelp-basic-oldstyle.sh \ imrelp-manyconn.sh \ imrelp-manyconn-vg.sh \ imrelp-maxDataSize-error.sh \ imrelp-long-msg.sh \ imrelp-oversizeMode-truncate.sh \ imrelp-oversizeMode-accept.sh \ imrelp-invld-tlslib.sh \ imrelp-bigmessage.sh \ imrelp-sessionbreak-vg.sh \ omrelp-invld-tlslib.sh \ glbl-oversizeMsg-log.sh \ glbl-oversizeMsg-truncate.sh \ glbl-oversizeMsg-split.sh \ sndrcv_relp.sh \ sndrcv_relp_rebind.sh \ sndrcv_relp_tls_prio.sh \ sndrcv_relp_tls_chainedcert.sh \ sndrcv_relp_tls.sh \ sndrcv_relp_tls_certvalid.sh \ sndrcv_relp-vg-rcvr.sh \ sndrcv_relp-vg-sender.sh \ relp_tls_certificate_not_found.sh \ omrelp_wrong_authmode.sh \ imrelp-tls.sh \ imrelp-tls-cfgcmd.sh \ imrelp-tls-chainedcert.sh \ imrelp-tls-mixed-chainedcert.sh \ imrelp-tls-mixed-chainedcert2.sh \ sndrcv_relp_tls-cfgcmd.sh \ sndrcv_relp_dflt_pt.sh \ sndrcv_udp.sh \ imudp_thread_hang.sh \ sndrcv_udp_nonstdpt.sh \ sndrcv_udp_nonstdpt_v6.sh \ omudpspoof_errmsg_no_params.sh \ sndrcv_omudpspoof.sh \ sndrcv_omudpspoof-bigmsg.sh \ sndrcv_omudpspoof_nonstdpt.sh \ sndrcv_gzip.sh \ imdtls-basic.sh \ imdtls-basic-tlscommands.sh \ imdtls-basic-timeout.sh \ imdtls-error-cert.sh \ imdtls-sessionbreak.sh \ imdtls-basic-vg.sh \ imdtls-sessionbreak-vg.sh \ sndrcv_dtls_certvalid.sh \ sndrcv_dtls_anon_ciphers.sh \ sndrcv_dtls_certvalid_ciphers.sh \ sndrcv_dtls_certvalid_permitted.sh \ sndrcv_dtls_certvalid_missing.sh \ sndrcv_dtls_anon_ciphers.sh \ sndrcv_dtls_certvalid-vg.sh \ action-tx-single-processing.sh \ omfwd-errfile-maxsize.sh \ omfwd-errfile-maxsize-filled.sh \ action-tx-errfile-maxsize.sh \ action-tx-errfile.sh \ testsuites/action-tx-errfile.result \ pipeaction.sh \ improg-simul.sh \ improg-multiline-test.py \ improg_errmsg_no_params.sh \ improg_errmsg_no_params-vg.sh \ improg_prog_simple.sh \ improg_prog_confirm.sh \ improg_prog_confirm_killonclose.sh \ improg_prog_killonclose.sh \ improg_prog_simple-vg.sh \ improg_simple_multi.sh \ imhttp-post-payload.sh \ imhttp-post-payload-vg.sh \ imhttp-post-payload-basic-auth.sh \ imhttp-post-payload-basic-auth-vg.sh \ imhttp-post-payload-query-params.sh \ imhttp-post-payload-query-params-vg.sh \ imhttp-post-payload-large.sh \ imhttp-post-payload-large-vg.sh \ testsuites/imhttp-large-data.txt \ imhttp-post-payload-multi.sh \ imhttp-post-payload-multi-vg.sh \ imhttp-getrequest-file.sh \ imhttp-getrequest-file-vg.sh \ imhttp-post-payload-multi-lf.sh \ imhttp-post-payload-multi-lf-vg.sh \ imhttp-post-payload-compress.sh \ imhttp-post-payload-compress-vg.sh \ imhttp-healthcheck.sh \ imhttp-metrics.sh \ testsuites/docroot/file.txt \ testsuites/htpasswd \ omhttp-auth.sh \ omhttp-basic.sh \ omhttp-basic-ignorecodes.sh \ omhttp-batch-fail-with-400.sh \ omhttp-batch-jsonarray-compress.sh \ omhttp-batch-jsonarray-retry.sh \ omhttp-batch-jsonarray.sh \ omhttp-batch-kafkarest-retry.sh \ omhttp-batch-kafkarest.sh \ omhttp-batch-lokirest-retry.sh \ omhttp-batch-lokirest.sh \ omhttp-batch-lokirest-vg.sh \ omhttp-profile-loki.sh \ omhttp-batch-newline.sh \ omhttp-batch-retry-metadata.sh \ omhttp-retry-timeout.sh \ omhttp-basic-ignorecodes-vg.sh \ omhttp-batch-retry-metadata-vg.sh \ omhttp-retry-timeout-vg.sh \ omhttp-retry.sh \ omhttp-httpheaderkey.sh \ omhttp-multiplehttpheaders.sh \ omhttp-dynrestpath.sh \ omhttp-batch-dynrestpath.sh \ omhttp-auth-vg.sh \ omhttp-basic-vg.sh \ omhttp-batch-jsonarray-compress-vg.sh \ omhttp-batch-jsonarray-retry-vg.sh \ omhttp-batch-jsonarray-vg.sh \ omhttp-batch-kafkarest-retry-vg.sh \ omhttp-batch-lokirest-retry-vg.sh \ omhttp-retry-vg.sh \ omhttp_server.py \ omhttp-validate-response.py \ omprog-defaults.sh \ omprog-defaults-vg.sh \ omprog-output-capture.sh \ omprog-output-capture-mt.sh \ omprog-output-capture-vg.sh \ omprog-feedback.sh \ omprog-feedback-mt.sh \ omprog-feedback-vg.sh \ omprog-feedback-timeout.sh \ omprog-close-unresponsive.sh \ omprog-close-unresponsive-vg.sh \ omprog-close-unresponsive-noterm.sh \ omprog-restart-terminated.sh \ omprog-restart-terminated-vg.sh \ omprog-restart-terminated-outfile.sh \ omprog-single-instance.sh \ omprog-single-instance-vg.sh \ omprog-single-instance-outfile.sh \ omprog-if-error.sh \ omprog-transactions.sh \ omprog-transactions-vg.sh \ omprog-transactions-failed-messages.sh \ omprog-transactions-failed-commits.sh \ testsuites/omprog-defaults-bin.sh \ testsuites/omprog-output-capture-bin.sh \ testsuites/omprog-output-capture-mt-bin.py \ testsuites/omprog-feedback-bin.sh \ testsuites/omprog-feedback-mt-bin.sh \ testsuites/omprog-feedback-timeout-bin.sh \ testsuites/omprog-close-unresponsive-bin.sh \ testsuites/omprog-restart-terminated-bin.sh \ testsuites/omprog-single-instance-bin.sh \ testsuites/omprog-transactions-bin.sh \ pipe_noreader.sh \ uxsock_simple.sh \ uxsock_simple_abstract.sh \ uxsock_simple_abstract-vg.sh \ uxsock_multiple.sh \ uxsock_multiple-vg.sh \ uxsock_multiple_netns.sh \ uxsock_multiple_netns-vg.sh \ asynwr_simple.sh \ asynwr_simple_2.sh \ asynwr_timeout.sh \ asynwr_timeout_2.sh \ asynwr_small.sh \ asynwr_tinybuf.sh \ wr_large_async.sh \ wr_large_sync.sh \ asynwr_deadlock.sh \ asynwr_deadlock_2.sh \ asynwr_deadlock2.sh \ asynwr_deadlock4.sh \ asynwr_dynfile_flushtxend-off.sh \ abort-uncleancfg-goodcfg.sh \ abort-uncleancfg-goodcfg-check.sh \ abort-uncleancfg-badcfg-check.sh \ abort-uncleancfg-badcfg-check_1.sh \ variable_leading_underscore.sh \ gzipwr_hup_multi_file.sh \ gzipwr_hup_single_file.sh \ gzipwr_rscript.sh \ gzipwr_flushInterval.sh \ gzipwr_flushOnTXEnd.sh \ gzipwr_large.sh \ gzipwr_large_dynfile.sh \ gzipwr_hup.sh \ complex1.sh \ random.sh \ testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input \ imfile-readmode0-vg.sh \ imfile-readmode2.sh \ imfile-readmode2-polling.sh \ imfile-readmode2-vg.sh \ imfile-readmode2-with-persists-data-during-stop.sh \ imfile-readmode2-with-persists.sh \ imfile-endregex-save-lf.sh \ imfile-endregex-save-lf-persist.sh \ imfile-endregex.sh \ imfile-endregex-vg.sh \ imfile-basic.sh \ imfile-basic-legacy.sh \ imfile-basic-2GB-file.sh \ imfile-truncate-2GB-file.sh \ imfile-discard-truncated-line.sh \ imfile-truncate-line.sh \ imfile-file-not-found-error.sh \ imfile-fileNotFoundError-parameter.sh \ imfile-error-not-repeated.sh \ imfile-basic-vg.sh \ imfile-basic-vgthread.sh \ imfile-endregex-timeout-none-polling.sh \ imfile-endregex-timeout-polling.sh \ imfile-endregex-timeout.sh \ imfile-endregex-timeout-none.sh \ imfile-endregex-timeout-with-shutdown.sh \ imfile-endregex-timeout-with-shutdown-polling.sh \ imfile-escapelf.replacement.sh \ imfile-escapelf.replacement-empty.sh \ imfile-endmsg.regex.sh \ imfile-endmsg.regex-vg.sh \ imfile-endmsg.regex-with-example.sh \ imfile-endmsg.regex-with-example-vg.sh \ imfile-endmsg.regex.crio.rulebase \ imfile-endmsg.regex.json.rulebase \ imfile-statefile-no-file_id.sh \ imfile-statefile-no-file_id-TO-file_id.sh \ imfile-statefile-directory.sh \ imfile-statefile-delete.sh \ imfile-statefile-no-delete.sh \ imfile-persist-state-1.sh \ imfile-freshStartTail1.sh \ imfile-freshStartTail2.sh \ imfile-freshStartTail3.sh \ imfile-truncate.sh \ imfile-truncate-multiple.sh \ imfile-wildcards.sh \ imfile-wildcards-dirs.sh \ imfile-wildcards-dirs2.sh \ imfile-wildcards-dirs-multi.sh \ imfile-wildcards-dirs-multi2.sh \ imfile-wildcards-dirs-multi3.sh \ imfile-wildcards-dirs-multi4.sh \ imfile-wildcards-dirs-multi5.sh \ imfile-wildcards-dirs-multi5-polling.sh \ imfile-old-state-file.sh \ imfile-rename-while-stopped.sh \ imfile-rename.sh \ imfile-symlink.sh \ imfile-symlink-multi.sh \ imfile-symlink-ext-tmp-dir-tree.sh \ imfile-logrotate.sh \ imfile-logrotate-async.sh \ imfile-logrotate-multiple.sh \ imfile-logrotate-copytruncate.sh \ imfile-logrotate-nocopytruncate.sh \ imfile-logrotate-state-files.sh \ imfile-growing-file-id.sh \ imfile-ignore-old-file-1.sh \ imfile-ignore-old-file-2.sh \ imfile-ignore-old-file-3.sh \ imfile-ignore-old-file-4.sh \ imfile-ignore-old-file-5.sh \ imfile-ignore-old-file-6.sh \ imfile-ignore-old-file-7.sh \ glbl-oversizeMsg-truncate-imfile.sh \ dynfile_invld_async.sh \ dynfile_invld_sync.sh \ dynfile_invalid2.sh \ rulesetmultiqueue.sh \ rulesetmultiqueue-v6.sh \ omruleset.sh \ omruleset-queue.sh \ badqi.sh \ bad_qi/dbq.qi \ execonlyonce.sh \ execonlywhenprevsuspended.sh \ execonlywhenprevsuspended2.sh \ execonlywhenprevsuspended3.sh \ execonlywhenprevsuspended4.sh \ execonlywhenprevsuspended_multiwrkr.sh \ execonlywhenprevsuspended-queue.sh \ execonlywhenprevsuspended-nonsusp.sh \ execonlywhenprevsuspended-nonsusp-queue.sh \ tabescape_dflt.sh \ tabescape_dflt-udp.sh \ tabescape_off.sh \ tabescape_off-udp.sh \ tabescape_on.sh \ dircreate_dflt.sh \ dircreate_off.sh \ imuxsock_legacy.sh \ imuxsock_logger_parserchain.sh \ imuxsock_logger.sh \ imuxsock_logger_ratelimit.sh \ imuxsock_logger_ruleset.sh \ imuxsock_logger_ruleset_ratelimit.sh \ imuxsock_logger_err.sh \ imuxsock_logger_root.sh \ imuxsock_logger_syssock.sh \ imuxsock_traillf.sh \ imuxsock_traillf_root.sh \ imuxsock_traillf_syssock.sh \ imuxsock_ccmiddle.sh \ imuxsock_ccmiddle_root.sh \ imklog_permitnonkernelfacility_root.sh \ imuxsock_ccmiddle_syssock.sh \ imuxsock_hostname.sh \ testsuites/mysql-truncate.sql \ testsuites/mysql-select-msg.sql \ libdbi-basic.sh \ libdbi-asyn.sh \ mysqld-start.sh \ mysqld-stop.sh \ mysql-basic.sh \ mysql-basic-cnf6.sh \ mysql-basic-vg.sh \ mysql-asyn.sh \ mysql-asyn-vg.sh \ mysql-actq-mt.sh \ mysql-actq-mt-withpause.sh \ mysql-actq-mt-withpause-vg.sh \ kafka-selftest.sh \ omkafka.sh \ omkafkadynakey.sh \ omkafka-headers.sh \ omkafka-vg.sh \ imkafka-hang-on-no-kafka.sh \ imkafka-hang-other-action-on-no-kafka.sh \ imkafka-backgrounded.sh \ imkafka-config-err-ruleset.sh \ imkafka-config-err-param.sh \ imkafka.sh \ imkafka-vg.sh \ imkafka_multi_single.sh \ imkafka_multi_group.sh \ sndrcv_kafka.sh \ sndrcv_kafka_multi_topics.sh \ testsuites/kafka-server.properties \ testsuites/kafka-server.dep_wrk1.properties \ testsuites/kafka-server.dep_wrk2.properties \ testsuites/kafka-server.dep_wrk3.properties \ testsuites/zoo.cfg \ testsuites/zoo.dep_wrk1.cfg \ testsuites/zoo.dep_wrk2.cfg \ testsuites/zoo.dep_wrk3.cfg \ omazureeventhubs-basic.sh \ omazureeventhubs-basic-url.sh \ omazureeventhubs-list.sh \ omazureeventhubs-stress.sh \ omazureeventhubs-interrupt.sh \ omazureeventhubs-basic-vg.sh \ omazureeventhubs-interrupt-vg.sh \ mmpstrucdata.sh \ mmpstrucdata-escaping.sh \ mmpstrucdata-case.sh \ mmpstrucdata-vg.sh \ mmpstrucdata-invalid-vg.sh \ libdbi-basic-vg.sh \ dynstats_ctr_reset.sh \ dynstats_reset_without_pstats_reset.sh \ dynstats_nometric.sh \ dynstats_overflow.sh \ dynstats_overflow-vg.sh \ dynstats_reset.sh \ dynstats_reset-vg.sh \ impstats-hup.sh \ dynstats.sh \ dynstats-vg.sh \ dynstats_prevent_premature_eviction.sh \ dynstats_prevent_premature_eviction-vg.sh \ testsuites/dynstats_empty_input \ testsuites/dynstats_input \ testsuites/dynstats_input_1 \ testsuites/dynstats_input_2 \ testsuites/dynstats_input_3 \ testsuites/dynstats_input_more_0 \ testsuites/dynstats_input_more_1 \ testsuites/dynstats_input_more_2 \ no-dynstats-json.sh \ no-dynstats.sh \ omfwd_impstats-udp.sh \ omfwd_impstats-tcp.sh \ perctile-simple.sh \ perctile-simple-vg.sh \ stats-json.sh \ stats-json-vg.sh \ stats-prometheus.sh \ stats-cee.sh \ stats-cee-vg.sh \ stats-json-es.sh \ dynstats-json.sh \ dynstats-json-vg.sh \ mmnormalize_variable.sh \ mmnormalize_tokenized.sh \ testsuites/mmnormalize_variable.rulebase \ testsuites/date_time_msg \ testsuites/mmnormalize_tokenized.rulebase \ testsuites/tokenized_input \ rscript_random.sh \ rscript_hash32.sh \ rscript_hash32-vg.sh \ rscript_hash64.sh \ rscript_hash64-vg.sh \ rscript_replace.sh \ rscript_replace_complex.sh \ testsuites/complex_replace_input \ rscript_unaffected_reset.sh \ rscript_wrap2.sh \ rscript_wrap3.sh \ testsuites/wrap3_input\ json_array_subscripting.sh \ testsuites/json_array_input \ testsuites/json_object_input \ testsuites/json_nonarray_input \ json_array_looping.sh \ json_object_looping.sh \ json_object_looping-vg.sh \ json_array_looping-vg.sh \ json_object_suicide_in_loop-vg.sh \ json_nonarray_looping.sh \ json_null.sh \ json_null-vg.sh \ json_null_array.sh \ json_null_array-vg.sh \ mmjsonparse_extra_data-vg.sh \ mmnormalize_regex.sh \ testsuites/mmnormalize_regex.rulebase \ testsuites/regex_input \ mmnormalize_regex_disabled.sh \ mmnormalize_regex_defaulted.sh \ stop_when_array_has_element.sh \ testsuites/stop_when_array_has_elem_input \ key_dereference_on_uninitialized_variable_space.sh \ rscript_re_extract_i.sh \ rscript_re_extract.sh \ rscript_re_match_i.sh \ rscript_re_match.sh \ rscript_re_match-dbl_quotes.sh \ lookup_table.sh \ lookup_table-hup-backgrounded.sh \ lookup_table_no_hup_reload.sh \ lookup_table_no_hup_reload-vg.sh \ lookup_table_rscript_reload.sh \ lookup_table_rscript_reload_without_stub.sh \ lookup_table_rscript_reload-vg.sh \ lookup_table_rscript_reload_without_stub-vg.sh \ rscript_trim-vg.sh \ testsuites/xlate.lkp_tbl \ testsuites/xlate_more.lkp_tbl \ unused_lookup_table-vg.sh \ lookup_table-vg.sh \ array_lookup_table.sh \ array_lookup_table-vg.sh \ array_lookup_table_misuse-vg.sh \ multiple_lookup_tables.sh \ multiple_lookup_tables-vg.sh \ testsuites/xlate_array.lkp_tbl \ testsuites/xlate_array_more.lkp_tbl \ testsuites/xlate_array_misuse.lkp_tbl \ testsuites/xlate_array_more_misuse.lkp_tbl \ sparse_array_lookup_table.sh \ sparse_array_lookup_table-vg.sh \ testsuites/xlate_sparse_array.lkp_tbl \ testsuites/xlate_sparse_array_more.lkp_tbl \ lookup_table_bad_configs.sh \ lookup_table_bad_configs-vg.sh \ testsuites/xlate_array_empty_table.lkp_tbl \ testsuites/xlate_array_no_index.lkp_tbl \ testsuites/xlate_array_no_table.lkp_tbl \ testsuites/xlate_array_no_value.lkp_tbl \ testsuites/xlate_empty_file.lkp_tbl \ testsuites/xlate_incorrect_type.lkp_tbl \ testsuites/xlate_incorrect_version.lkp_tbl \ testsuites/xlate_sparseArray_empty_table.lkp_tbl \ testsuites/xlate_sparseArray_no_index.lkp_tbl \ testsuites/xlate_sparseArray_no_table.lkp_tbl \ testsuites/xlate_sparseArray_no_value.lkp_tbl \ testsuites/xlate_string_empty_table.lkp_tbl \ testsuites/xlate_string_no_index.lkp_tbl \ testsuites/xlate_string_no_table.lkp_tbl \ testsuites/xlate_string_no_value.lkp_tbl \ testsuites/xlate_invalid_json.lkp_tbl \ testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl \ testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl \ testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl \ json_var_cmpr.sh \ imptcp_maxsessions.sh \ imptcp_nonProcessingPoller.sh \ imptcp_veryLargeOctateCountedMessages.sh \ known_issues.supp \ libmaxmindb.supp \ travis/trusty.supp \ linux_localtime_r.supp \ CI/centos6-9.supp \ CI/centos7.supp \ CI/gcov.supp \ CI/ubuntu20.04.supp \ json_var_case.sh \ cfg.sh \ empty-prop-comparison.sh \ sndrcv_tls_anon_rebind.sh \ sndrcv_tls_anon_hostname.sh \ sndrcv_tls_anon_ipv4.sh \ sndrcv_tls_anon_ipv6.sh \ sndrcv_tls_priorityString.sh \ sndrcv_tls_certvalid.sh \ sndrcv_tls_certvalid_action_level.sh \ sndrcv_tls_certvalid_expired.sh \ sndrcv_tls_certvalid_expired_defaultmode.sh \ sndrcv_tls_certvalid_revoked.sh \ sndrcv_tls_certless_clientonly.sh \ sndrcv_tls_gtls_servercert_gtls_clientanon.sh \ sndrcv_tls_gtls_servercert_gtls_clientanon_legacy.sh \ sndrcv_tls_gtls_serveranon_gtls_clientanon.sh \ sndrcv_tls_ossl_serveranon_ossl_clientanon.sh \ sndrcv_tls_ossl_servercert_ossl_clientanon.sh \ sndrcv_tls_ossl_servercert_gtls_clientanon.sh \ sndrcv_tls_ossl_serveranon_gtls_clientanon.sh \ sndrcv_tls_gtls_servercert_ossl_clientanon.sh \ sndrcv_tls_gtls_serveranon_ossl_clientanon.sh \ sndrcv_tls_client_missing_cert.sh \ sndrcv_ossl_cert_chain.sh \ sndrcv_tls_ossl_intermediate_ca_chain.sh \ omtcl.sh \ omtcl.tcl \ pmsnare-default.sh \ pmsnare-default-udp.sh \ pmsnare-ccoff.sh \ pmsnare-ccoff-udp.sh \ pmsnare-ccdefault.sh \ pmsnare-ccdefault-udp.sh \ pmsnare-cccstyle.sh \ pmsnare-cccstyle-udp.sh \ pmsnare-ccbackslash.sh \ pmsnare-ccbackslash-udp.sh \ pmsnare-modoverride.sh \ pmsnare-modoverride-udp.sh \ pmlastmsg.sh \ pmlastmsg-udp.sh \ pgsql-basic.sh \ testsuites/pgsql-basic.sql \ testsuites/pgsql-select-msg.sql \ testsuites/pgsql-select-syslogtag.sql \ pgsql-basic-cnf6.sh \ pgsql-basic-threads-cnf6.sh \ pgsql-template.sh \ pgsql-template-cnf6.sh \ pgsql-actq-mt-withpause.sh \ pgsql-template-threads-cnf6.sh \ pgsql-basic-vg.sh \ pgsql-template-vg.sh \ pgsql-basic-cnf6-vg.sh \ pgsql-template-cnf6-vg.sh \ pgsql-actq-mt-withpause-vg.sh \ ../devtools/prep-mysql-db.sh \ ../devtools/prepare_clickhouse.sh \ mmkubernetes-basic.sh \ mmkubernetes-basic-vg.sh \ mmkubernetes_test_server.py \ mmkubernetes-basic.out.json \ mmkubernetes-cache-expire.sh \ mmkubernetes-cache-expire-vg.sh \ mmkubernetes-cache-expire.out.expected \ mmkubernetes.supp \ es-writeoperation.sh \ imdocker-basic.sh \ imdocker-basic-vg.sh \ imdocker-long-logline.sh \ imdocker-long-logline-vg.sh \ imdocker-new-logs-from-start.sh \ imdocker-new-logs-from-start-vg.sh \ imdocker-multi-line.sh \ imdocker-multi-line-vg.sh \ testsuites/incltest.d/include.conf \ testsuites/abort-uncleancfg-goodcfg.conf \ testsuites/include-std-omfile-action.conf \ testsuites/invalid.conf \ testsuites/valid.conf \ testsuites/variable_leading_underscore.conf \ omamqp1-common.sh \ omamqp1-basic.sh \ omamqp1-basic-vg.sh ourtail_SOURCES = ourtail.c msleep_SOURCES = msleep.c omrelp_dflt_port_SOURCES = omrelp_dflt_port.c mangle_qi_SOURCES = mangle_qi.c chkseq_SOURCES = chkseq.c check_relpEngineVersion = check_relpEngineVersion.c have_relpSrvSetOversizeMode = have_relpSrvSetOversizeMode.c have_relpEngineSetTLSLibByName = have_relpEngineSetTLSLibByName.c have_relpSrvSetTlsConfigCmd = have_relpSrvSetTlsConfigCmd.c test_id_SOURCES = test_id.c uxsockrcvr_SOURCES = uxsockrcvr.c uxsockrcvr_LDADD = $(SOL_LIBS) tcpflood_SOURCES = tcpflood.c tcpflood_CFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS) tcpflood_CPPFLAGS = $(PTHREADS_CFLAGS) $(RELP_CFLAGS) tcpflood_LDADD = $(SOL_LIBS) $(PTHREADS_LIBS) $(RELP_LIBS) if ENABLE_GNUTLS tcpflood_CFLAGS += $(GNUTLS_CFLAGS) tcpflood_CPPFLAGS += $(GNUTLS_CFLAGS) tcpflood_LDADD += $(GNUTLS_LIBS) endif if ENABLE_OPENSSL tcpflood_CFLAGS += $(OPENSSL_CFLAGS) tcpflood_CPPFLAGS += $(OPENSSL_CFLAGS) tcpflood_LDADD += $(OPENSSL_LIBS) endif minitcpsrv_SOURCES = minitcpsrvr.c minitcpsrv_LDADD = $(SOL_LIBS) syslog_caller_SOURCES = syslog_caller.c syslog_caller_CPPFLAGS = $(LIBLOGGING_STDLOG_CFLAGS) syslog_caller_LDADD = $(SOL_LIBS) $(LIBLOGGING_STDLOG_LIBS) journal_print_SOURCES = journal_print.c journal_print_CPPFLAGS = $(LIBSYSTEMD_JOURNAL_CFLAGS) journal_print_LDADD = $(LIBSYSTEMD_JOURNAL_LIBS) diagtalker_SOURCES = diagtalker.c diagtalker_LDADD = $(SOL_LIBS) randomgen_SOURCES = randomgen.c randomgen_LDADD = $(SOL_LIBS) inputfilegen_SOURCES = inputfilegen.c inputfilegen_LDADD = $(SOL_LIBS) # rtinit tests disabled for the moment - also questionable if they # really provide value (after all, everything fails if rtinit fails...) #rt_init_SOURCES = rt-init.c $(test_files) #rt_init_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) #rt_init_LDADD = $(RSRT_LIBS) $(ZLIB_LIBS) $(PTHREADS_LIBS) $(SOL_LIBS) #rt_init_LDFLAGS = -export-dynamic # same for basic rscript tests #rscript_SOURCES = rscript.c getline.c $(test_files) #rscript_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) #rscript_LDADD = $(RSRT_LIBS) $(ZLIB_LIBS) $(PTHREADS_LIBS) $(SOL_LIBS) #rscript_LDFLAGS = -export-dynamic rsyslog-8.2512.0/tests/PaxHeaders/glbl_setenv_err.sh0000644000000000000000000000013115035412264017404 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.963591102 29 ctime=1764935932.05771243 rsyslog-8.2512.0/tests/glbl_setenv_err.sh0000775000175000017500000000121215035412264017050 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # env var is missing equal sign and MUST trigger parsing error! global(environment="http_proxy ERROR") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! grep "http_proxy ERROR" < $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo echo "MESSAGE INDICATING ERROR ON ENVIRONMENT VARIABLE IS MISSING:" echo cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omod-if-array-udp.sh0000644000000000000000000000013215035412264017465 xustar0030 mtime=1752569012.404722953 30 atime=1764931163.669682643 30 ctime=1764935933.665737045 rsyslog-8.2512.0/tests/omod-if-array-udp.sh0000775000175000017500000000154215035412264017136 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%%timestamp%%hostname%%programname%%syslogtag%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\"" shutdown_when_empty wait_shutdown echo '167Mar 6 16:57:54172.20.245.8%PIX-7-710005%PIX-7-710005:' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse_8bit_escape-udp.sh0000644000000000000000000000013215035412264022571 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.936606719 30 ctime=1764935932.330716609 rsyslog-8.2512.0/tests/parsertest-parse_8bit_escape-udp.sh0000775000175000017500000000167415035412264022250 0ustar00rgerrger#!/bin/bash # add 2018-06-28 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") $Escape8BitCharactersOnReceive on template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<6>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\"" shutdown_when_empty wait_shutdown echo '6,kern,info,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: #303#244#303#266#303#274' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmkubernetes-basic.sh0000644000000000000000000000013215055602574020020 xustar0030 mtime=1756824956.033451498 30 atime=1764931168.767764344 30 ctime=1764935935.133759515 rsyslog-8.2512.0/tests/mmkubernetes-basic.sh0000775000175000017500000002404215055602574017471 0ustar00rgerrger#!/bin/bash # added 2018-04-06 by richm, released under ASL 2.0 # # Note: on buildbot VMs (where there is no environment cleanup), the # kubernetes test server may be kept running if the script aborts or # is aborted (buildbot master failure!) for some reason. As such we # execute it under "timeout" control, which ensure it always is # terminated. It's not a 100% great method, but hopefully does the # trick. -- rgerhards, 2018-07-21 #export RSYSLOG_DEBUG="debug" USE_VALGRIND=false . ${srcdir:=.}/diag.sh init check_command_available timeout pwd=$( pwd ) k8s_srv_port=$( get_free_port ) generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") module(load="../plugins/impstats/.libs/impstats" interval="1" log.file="'"$RSYSLOG_DYNNAME.spool"'/mmkubernetes-stats.log" log.syslog="off" format="cee") module(load="../plugins/imfile/.libs/imfile") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../contrib/mmkubernetes/.libs/mmkubernetes") template(name="mmk8s_template" type="list") { property(name="$!all-json-plain") constant(value="\n") } input(type="imfile" file="'$RSYSLOG_DYNNAME.spool'/pod-*.log" tag="kubernetes" addmetadata="on") action(type="mmjsonparse" cookie="") action(type="mmkubernetes" busyretryinterval="1" token="dummy" kubernetesurl="http://localhost:'$k8s_srv_port'" filenamerules=["rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:.%.%container_hash:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log", "rule=:'$pwd/$RSYSLOG_DYNNAME.spool'/%pod_name:char-to:_%_%namespace_name:char-to:_%_%container_name_and_id:char-to:.%.log"] ) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="mmk8s_template") ' testsrv=mmk8s-test-server echo starting kubernetes \"emulator\" timeout 2m $PYTHON -u $srcdir/mmkubernetes_test_server.py $k8s_srv_port ${RSYSLOG_DYNNAME}${testsrv}.pid ${RSYSLOG_DYNNAME}${testsrv}.started > ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log 2>&1 & BGPROCESS=$! wait_process_startup ${RSYSLOG_DYNNAME}${testsrv} ${RSYSLOG_DYNNAME}${testsrv}.started echo background mmkubernetes_test_server.py process id is $BGPROCESS cat > ${RSYSLOG_DYNNAME}.spool/pod-error1.log < ${RSYSLOG_DYNNAME}.spool/pod-error2.log < ${RSYSLOG_DYNNAME}.spool/pod-name1_namespace-name1_container-name1-id1.log < ${RSYSLOG_DYNNAME}.spool/pod-name2.container-hash2_namespace-name2_container-name2-id2.log < ${RSYSLOG_DYNNAME}.spool/pod-name3.log < ${RSYSLOG_DYNNAME}.spool/pod-name4.log < ${RSYSLOG_DYNNAME}.spool/pod-name5.log < ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-not-found-and-busy.log <> ${RSYSLOG_DYNNAME}.spool/pod-test-error.log <= 0: hsh = json.loads(line[jstart:]) if hsh["origin"] == "mmkubernetes": actual = hsh assert(expected == actual) ' $k8s_srv_port || { rc=$?; echo error: expected stats not found in ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log; } else echo error: stats file ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log not found rc=1 fi if [ ${rc:-0} -ne 0 ]; then echo echo "FAIL: expected data not found. $RSYSLOG_OUT_LOG is:" cat ${RSYSLOG_DYNNAME}.spool/mmk8s_srv.log cat $RSYSLOG_OUT_LOG cat ${RSYSLOG_DYNNAME}.spool/mmkubernetes-stats.log error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp_addtlframedelim_on_input.sh0000644000000000000000000000013215055602574022465 xustar0030 mtime=1756824956.032451484 30 atime=1764931163.543680623 30 ctime=1764935933.628736478 rsyslog-8.2512.0/tests/imtcp_addtlframedelim_on_input.sh0000775000175000017500000000111315055602574022130 0ustar00rgerrger#!/bin/bash # added 2010-08-11 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=20000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" addtlframedelimiter="0") template(name="outfmt" type="string" string="%msg:F,58:2%\n") local0.* ./'$RSYSLOG_OUT_LOG';outfmt ' startup tcpflood -m$NUMMESSAGES -F0 -P129 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_exists-not4.sh0000644000000000000000000000013215055602574020207 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.886621965 30 ctime=1764935932.586720528 rsyslog-8.2512.0/tests/rscript_exists-not4.sh0000775000175000017500000000103515055602574017655 0ustar00rgerrger#!/bin/bash # add 2020-10-02 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%!result%\n") set $.somevar = "test"; # this makes matters a bit more complicated if $msg contains "msgnum" then { if not exists($.p1!p2!val) then set $!result = "off"; else set $!result = "on"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='off' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-execOnlyWhenPreviousSuspended.sh0000644000000000000000000000013215103346332022654 xustar0030 mtime=1762512090.633176003 30 atime=1764931162.569665004 30 ctime=1764935933.345732146 rsyslog-8.2512.0/tests/es-execOnlyWhenPreviousSuspended.sh0000775000175000017500000000275515103346332022334 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 #10000 require_elasticsearch_restart_capability ensure_elasticsearch_ready init_elasticsearch generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") template(name="tpl2" type="string" string="%msg:F,58:2%\n") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") if $msg contains "msgnum:" then { action(type="omelasticsearch" server="127.0.0.1" serverport="19200" template="tpl" searchIndex="rsyslog_testbench" action.resumeInterval="2" action.resumeretrycount="1") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="tpl2" action.execOnlyWhenPreviousIsSuspended="on") # this action just to count processed messages action(type="omfile" file="'$RSYSLOG_DYNNAME'.syncfile") } ' startup injectmsg 0 $NUMMESSAGES wait_file_lines $RSYSLOG_DYNNAME.syncfile $NUMMESSAGES stop_elasticsearch ./msleep 1000 injectmsg $NUMMESSAGES 1 wait_file_lines $RSYSLOG_DYNNAME.syncfile $((NUMMESSAGES + 1)) wait_queueempty injectmsg $(( NUMMESSAGES + 1 )) $NUMMESSAGES wait_file_lines $RSYSLOG_DYNNAME.syncfile $((NUMMESSAGES + 1 + NUMMESSAGES)) start_elasticsearch shutdown_when_empty wait_shutdown seq_check $(( NUMMESSAGES + 1 )) $(( NUMMESSAGES * 2 )) es_getdata $NUMMESSAGES 19200 seq_check 0 $(( NUMMESSAGES - 1 )) exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp_conndrop_tls.sh0000644000000000000000000000013115055603742020135 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.619681842 29 ctime=1764935933.65173683 rsyslog-8.2512.0/tests/imtcp_conndrop_tls.sh0000775000175000017500000000246115055603742017610 0ustar00rgerrger#!/bin/bash # Test imtcp/TLS with many dropping connections # added 2011-06-09 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( maxMessageSize="10k" defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem" defaultNetstreamDriver="gtls" debug.whitelist="on" debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100" streamDriver.mode="1" streamDriver.authMode="anon") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup # 100 byte messages to gain more practical data use tcpflood -c20 -p$TCPFLOOD_PORT -m$NUMMESSAGES -r -d100 -P129 -D -l0.995 -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown export SEQ_CHECK_OPTIONS=-E seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-oversizeMode-accept.sh0000644000000000000000000000013115035412264021426 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.078689201 30 ctime=1764935933.784738866 rsyslog-8.2512.0/tests/imrelp-oversizeMode-accept.sh0000775000175000017500000000245115035412264021100 0ustar00rgerrger#!/bin/bash # add 2018-04-25 by PascalWithopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./have_relpSrvSetOversizeMode if [ $? -eq 1 ]; then echo "imrelp parameter oversizeMode not available. Test stopped" exit 77 fi; generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="200" oversizeMode="accept") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end # because otherwise we won't know if it was truncated at the right length. grep "^ msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile-sizelimitcmd-many.sh0000644000000000000000000000013215055602574021150 xustar0030 mtime=1756824956.034451512 30 atime=1764931160.758635955 30 ctime=1764935932.830724263 rsyslog-8.2512.0/tests/omfile-sizelimitcmd-many.sh0000775000175000017500000000315615055602574020624 0ustar00rgerrger#!/bin/bash # addd 2023-01-11 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 echo "ls -l $RSYSLOG_DYNNAME.channel.* mv -f $RSYSLOG_DYNNAME.channel.log.prev.9 $RSYSLOG_DYNNAME.channel.log.prev.10 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.8 $RSYSLOG_DYNNAME.channel.log.prev.9 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.7 $RSYSLOG_DYNNAME.channel.log.prev.8 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.6 $RSYSLOG_DYNNAME.channel.log.prev.7 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.5 $RSYSLOG_DYNNAME.channel.log.prev.6 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.4 $RSYSLOG_DYNNAME.channel.log.prev.5 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.3 $RSYSLOG_DYNNAME.channel.log.prev.4 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.2 $RSYSLOG_DYNNAME.channel.log.prev.3 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev.1 $RSYSLOG_DYNNAME.channel.log.prev.2 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log.prev $RSYSLOG_DYNNAME.channel.log.prev.1 2>/dev/null mv -f $RSYSLOG_DYNNAME.channel.log $RSYSLOG_DYNNAME.channel.log.prev " > $RSYSLOG_DYNNAME.rotate.sh chmod +x $RSYSLOG_DYNNAME.rotate.sh generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then { action(type="omfile" file="'$RSYSLOG_DYNNAME.channel.log'" template="outfmt" rotation.sizeLimit="50k" rotation.sizeLimitCommand="./'$RSYSLOG_DYNNAME.rotate.sh'") } ' startup injectmsg shutdown_when_empty wait_shutdown ls -l $RSYSLOG_DYNNAME.channel.* cat $RSYSLOG_DYNNAME.channel.* > $RSYSLOG_OUT_LOG seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-close-unresponsive-vg.sh0000644000000000000000000000013215035412264022007 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.185706947 30 ctime=1764935934.095743627 rsyslog-8.2512.0/tests/omprog-close-unresponsive-vg.sh0000775000175000017500000000213415035412264021456 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Same test than 'omprog-close-unresponsive.sh', but checking for memory # problems using valgrind. Note it is not necessary to repeat the # rest of checks (this simplifies the maintenance of the tests). . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") main_queue( queue.timeoutShutdown="60000" # give time to omprog to wait for the child ) :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-close-unresponsive-bin.sh` template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process confirmMessages="on" # facilitates sync with the child process signalOnClose="on" closeTimeout="1000" # ms #killUnresponsive="on" # default value: the value of signalOnClose ) } ' startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg exit_test rsyslog-8.2512.0/tests/PaxHeaders/have_relpSrvSetTlsConfigCmd.c0000644000000000000000000000013215055605325021416 xustar0030 mtime=1756826325.656800789 30 atime=1764931157.442582739 30 ctime=1764935931.919710318 rsyslog-8.2512.0/tests/have_relpSrvSetTlsConfigCmd.c0000664000175000017500000000027415055605325021065 0ustar00rgerrger#include "config.h" int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) { #if defined(HAVE_RELPENGINESETTLSCFGCMD) return 0; #else return 1; #endif } rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_str-numstr.sh0000644000000000000000000000013215055602574021652 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.480615449 30 ctime=1764935932.487719012 rsyslog-8.2512.0/tests/rscript_compare_str-numstr.sh0000775000175000017500000000015115055602574021316 0ustar00rgerrger#!/bin/bash export LOWER_VAL='"-"' export HIGHER_VAL='"2"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/rs-int2hex.sh0000644000000000000000000000013215035412264016234 xustar0030 mtime=1752569012.409688211 30 atime=1764931160.085625158 30 ctime=1764935932.638721324 rsyslog-8.2512.0/tests/rs-int2hex.sh0000775000175000017500000000142615035412264015706 0ustar00rgerrger#!/bin/bash # add 2018-04-04 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!var = int2hex(61); set $!var2 = int2hex(-13); template(name="outfmt" type="string" string="-%$!var%- -%$!var2%-\n") :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" shutdown_when_empty wait_shutdown echo '-3d- -fffffffffffffff3-' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rawmsg-after-pri.sh0000644000000000000000000000013215035412264017420 xustar0030 mtime=1752569012.409688211 30 atime=1764931161.969655381 30 ctime=1764935933.180729621 rsyslog-8.2512.0/tests/rawmsg-after-pri.sh0000775000175000017500000000174015035412264017071 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(type="string" name="outfmt" string="%rawmsg-after-pri%\n") if $syslogfacility-text == "local0" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -P 129 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate NUMLINES=$(grep -c "^Mar 1 01:00:00 172.20.245.8 tag msgnum:00000000:$" $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: output file seems not to exist" ls -l $RSYSLOG_OUT_LOG cat $RSYSLOG_OUT_LOG error_exit 1 else if [ ! $NUMLINES -eq 1 ]; then echo "ERROR: output format does not match expectation" cat $RSYSLOG_OUT_LOG error_exit 1 fi fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_hash32.sh0000644000000000000000000000013115035412264017066 xustar0030 mtime=1752569012.411674314 29 atime=1764931167.44974323 30 ctime=1764935934.758753775 rsyslog-8.2512.0/tests/rscript_hash32.sh0000775000175000017500000000174315035412264016543 0ustar00rgerrger#!/bin/bash # added 2018-02-07 by Harshvardhan Shrivastava # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \rscript_hash32.sh\]: test for hash32 and hash64mod script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n") module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmhash/.libs/fmhash") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.hash_no_1 = hash32("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e"); set $.hash_no_2 = hash32mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 20 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown . $srcdir/diag.sh content-pattern-check "^\(746581550 - 50\|3889673532 - 32\)$" exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv.sh0000644000000000000000000000013115055602574015536 xustar0030 mtime=1756824956.039451582 29 atime=1764931163.98568771 30 ctime=1764935933.757738453 rsyslog-8.2512.0/tests/sndrcv.sh0000775000175000017500000000273115055602574015211 0ustar00rgerrger#!/bin/bash # This tests two rsyslog instances. Instance # TWO sends data to instance ONE. A number of messages is injected into # the instance 2 and we finally check if all those messages # arrived at instance 1. # added 2009-11-11 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # start up the instances export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' # then SENDER sends to this port (not tcpflood!) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RCVR_PORT=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' action(type="omfwd" target="127.0.0.1" protocol="tcp" port="'$RCVR_PORT'") ' 2 startup 2 assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # do the final check seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/diskq-rfc5424.sh0000644000000000000000000000013215035412264016433 xustar0030 mtime=1752569012.386848027 30 atime=1764931159.137609945 30 ctime=1764935932.388717497 rsyslog-8.2512.0/tests/diskq-rfc5424.sh0000775000175000017500000000225315035412264016104 0ustar00rgerrger#!/bin/bash # detect queue corruption based on invalid property bag ordering. # Note: this mimics an issue actually seen in practice. # Triggering condition: "json" property (message variables) are present # and "structured-data" property is also present. Caused rsyslog to # thrash the queue file, getting messages stuck in it and loosing all # after the initial problem occurrence. # add 2017-02-08 by Rainer Gerhards, released under ASL 2.0 uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs") template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="rs2" queue.type="disk" queue.filename="rs2_q" queue.spoolDirectory="'${RSYSLOG_DYNNAME}'.spool") { set $!tmp=$msg; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ruleset(name="rs") { set $!tmp=$msg; call rs2 } ' startup tcpflood -m$NUMMESSAGES -y shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/udp-msgreduc-vg.sh0000644000000000000000000000013215035412264017242 xustar0030 mtime=1752569012.420611777 30 atime=1764931163.129673985 30 ctime=1764935933.508734642 rsyslog-8.2512.0/tests/udp-msgreduc-vg.sh0000775000175000017500000000222115035412264016706 0ustar00rgerrger#!/bin/bash # check if valgrind violations occur. Correct output is not checked. # added 2011-03-01 by Rgerhards # This file is part of the rsyslog project, released under GPLv3 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi echo =============================================================================== echo \[udp-msgreduc-vg.sh\]: testing imtcp multiple listeners . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imudp/.libs/imudp $UDPServerRun '$TCPFLOOD_PORT' $RepeatedMsgReduction on $template outfmt,"%msg:F,58:2%\n" *.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") #:msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg tcpflood -t 127.0.0.1 -m 4 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...\"" tcpflood -t 127.0.0.1 -m 1 -r -Tudp -M "\"<133>2011-03-01T11:22:12Z host tag msgh ...x\"" shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown_vg if [ "$RSYSLOGD_EXIT" -eq "10" ] then echo "udp-msgreduc-vg.sh FAILED" exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdtls-basic-vg.sh0000644000000000000000000000013115055603742017222 xustar0030 mtime=1756825570.301069108 29 atime=1764931164.41669462 30 ctime=1764935933.878740305 rsyslog-8.2512.0/tests/imdtls-basic-vg.sh0000775000175000017500000000053115055603742016671 0ustar00rgerrger#!/bin/bash if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n' printf 'a valgrind-internal bug. So we need to skip it.\n' exit 77 fi export USE_VALGRIND="YES" export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes" source ${srcdir:-.}/imdtls-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-redis-start-after-vg.sh0000644000000000000000000000013215055602574022165 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.984639581 30 ctime=1764935932.895725258 rsyslog-8.2512.0/tests/imhiredis-redis-start-after-vg.sh0000775000175000017500000000031415055602574021632 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-redis-start-after.sh rsyslog-8.2512.0/tests/PaxHeaders/imptcp-discard-truncated-msg.sh0000644000000000000000000000013115035412264021706 xustar0029 mtime=1752569012.39578549 30 atime=1764931163.484679677 30 ctime=1764935933.611736218 rsyslog-8.2512.0/tests/imptcp-discard-truncated-msg.sh0000775000175000017500000000321015035412264021352 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MaxMessageSize 128 global(processInternalMessages="on") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1" discardTruncatedMsg="on") template(name="outfmt" type="string" string="%rawmsg%\n") ruleset(name="ruleset1") { action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16\"" tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message\"" tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16\"" tcpflood -m1 -M "\"<120> 2011-03-01T11:22:12Z host tag: this is a way to long message\"" shutdown_when_empty wait_shutdown export EXPECTED='<120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 t <120> 2011-03-01T11:22:12Z host tag: this is a way to long message <120> 2011-03-01T11:22:12Z host tag: this is a way to long message that has abcdefghijklmnopqrstuvwxyz test1 test2 test3 test4 t <120> 2011-03-01T11:22:12Z host tag: this is a way to long message' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-encryption-disk.sh0000644000000000000000000000013115035412264020474 xustar0030 mtime=1752569012.408695159 30 atime=1764931163.850685546 29 ctime=1764935933.71573781 rsyslog-8.2512.0/tests/queue-encryption-disk.sh0000775000175000017500000000162415035412264020147 0ustar00rgerrger#!/bin/bash # addd 2018-09-28 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.filename="mainq" queue.type="disk" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutenqueue="300000" queue.lowwatermark="5000" queue.cry.provider="gcry" queue.cry.key="1234567890123456" queue.saveonshutdown="on" ) template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :omtesting:sleep 0 5000 :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 1000 shutdown_immediate wait_shutdown echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0* exit_test rsyslog-8.2512.0/tests/PaxHeaders/have_relpEngineSetTLSLibByName.c0000644000000000000000000000013115055605325021721 xustar0030 mtime=1756826325.656800789 29 atime=1764931157.41958237 30 ctime=1764935931.914710241 rsyslog-8.2512.0/tests/have_relpEngineSetTLSLibByName.c0000664000175000017500000000027715055605325021374 0ustar00rgerrger#include "config.h" int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused))) { #if defined(HAVE_RELPENGINESETTLSLIBBYNAME) return 0; #else return 1; #endif } rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-jsonarray.sh0000644000000000000000000000013215055602574020640 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.860701738 30 ctime=1764935934.001742188 rsyslog-8.2512.0/tests/omhttp-batch-jsonarray.sh0000775000175000017500000000155515055602574020315 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 omhttp_start_server 0 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="2048") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.format="jsonarray" batch.maxsize="1000" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-encryption-disk_keyprog.sh0000644000000000000000000000013215035412264022235 xustar0030 mtime=1752569012.408695159 30 atime=1764931163.875685946 30 ctime=1764935933.724737948 rsyslog-8.2512.0/tests/queue-encryption-disk_keyprog.sh0000775000175000017500000000207515035412264021710 0ustar00rgerrger#!/bin/bash # addd 2018-10-01 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.filename="mainq" queue.type="disk" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutenqueue="300000" queue.lowwatermark="5000" queue.cry.provider="gcry" queue.cry.keyprogram="./'$RSYSLOG_DYNNAME.keyprogram'" queue.saveonshutdown="on" ) template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :omtesting:sleep 0 5000 :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' echo '#!/bin/bash echo RSYSLOG-KEY-PROVIDER:0 echo 16 echo "1234567890123456"' >> $RSYSLOG_DYNNAME.keyprogram chmod +x $RSYSLOG_DYNNAME.keyprogram startup injectmsg 0 1000 shutdown_immediate wait_shutdown echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0* exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_intermediate_ca_chain.sh0000644000000000000000000000013115071746523024020 xustar0029 mtime=1760021843.90842209 30 atime=1764931168.472759619 30 ctime=1764935935.052758276 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_intermediate_ca_chain.sh0000775000175000017500000001562115071746523023475 0ustar00rgerrger#!/bin/bash # Test for issue #5207: multiple intermediate CA certificates # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="log" # Prepare certificate workspace (dynamic, auto-cleaned by testbench) CERTDIR="$RSYSLOG_DYNNAME.certwork" mkdir -p "$CERTDIR" # Create minimal OpenSSL extfiles cat >"$CERTDIR/ca_ext.cnf" <<'EOF' [v3_ca] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, cRLSign, keyCertSign EOF cat >"$CERTDIR/leaf_ext.cnf" <<'EOF' [server_cert] basicConstraints = CA:false keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [client_cert] basicConstraints = CA:false keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth EOF # Generate root CA openssl genpkey -algorithm RSA -out "$CERTDIR/ca-root-key.pem" >/dev/null 2>&1 openssl req -new -key "$CERTDIR/ca-root-key.pem" -out "$CERTDIR/ca-root.csr" -subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=Root-CA" >/dev/null 2>&1 openssl x509 -req -in "$CERTDIR/ca-root.csr" -signkey "$CERTDIR/ca-root-key.pem" -days 3650 \ -extfile "$CERTDIR/ca_ext.cnf" -extensions v3_ca -out "$CERTDIR/ca-root-cert.pem" >/dev/null 2>&1 # Create intermediate CA 1 openssl genpkey -algorithm RSA -out "$CERTDIR/intermediate-ca1-key.pem" >/dev/null 2>&1 openssl req -new -key "$CERTDIR/intermediate-ca1-key.pem" -out "$CERTDIR/intermediate-ca1.csr" -subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=Intermediate-CA1" >/dev/null 2>&1 openssl x509 -req -in "$CERTDIR/intermediate-ca1.csr" -CA "$CERTDIR/ca-root-cert.pem" -CAkey "$CERTDIR/ca-root-key.pem" -CAcreateserial -days 1825 \ -extfile "$CERTDIR/ca_ext.cnf" -extensions v3_ca -out "$CERTDIR/intermediate-ca1-cert.pem" >/dev/null 2>&1 # Create intermediate CA 2 openssl genpkey -algorithm RSA -out "$CERTDIR/intermediate-ca2-key.pem" >/dev/null 2>&1 openssl req -new -key "$CERTDIR/intermediate-ca2-key.pem" -out "$CERTDIR/intermediate-ca2.csr" -subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=Intermediate-CA2" >/dev/null 2>&1 openssl x509 -req -in "$CERTDIR/intermediate-ca2.csr" -CA "$CERTDIR/ca-root-cert.pem" -CAkey "$CERTDIR/ca-root-key.pem" -CAcreateserial -days 1825 \ -extfile "$CERTDIR/ca_ext.cnf" -extensions v3_ca -out "$CERTDIR/intermediate-ca2-cert.pem" >/dev/null 2>&1 # Create server certificate signed by intermediate CA 1 openssl genpkey -algorithm RSA -out "$CERTDIR/server-int1-key.pem" >/dev/null 2>&1 openssl req -new -key "$CERTDIR/server-int1-key.pem" -out "$CERTDIR/server-int1.csr" -subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=rsyslogserver" >/dev/null 2>&1 openssl x509 -req -in "$CERTDIR/server-int1.csr" -CA "$CERTDIR/intermediate-ca1-cert.pem" -CAkey "$CERTDIR/intermediate-ca1-key.pem" -CAcreateserial -days 365 \ -extfile "$CERTDIR/leaf_ext.cnf" -extensions server_cert -out "$CERTDIR/server-int1-cert.pem" >/dev/null 2>&1 cat "$CERTDIR/server-int1-cert.pem" "$CERTDIR/intermediate-ca1-cert.pem" > "$CERTDIR/server-int1-chain.pem" # Create client certificate signed by intermediate CA 2 openssl genpkey -algorithm RSA -out "$CERTDIR/client-int2-key.pem" >/dev/null 2>&1 openssl req -new -key "$CERTDIR/client-int2-key.pem" -out "$CERTDIR/client-int2.csr" -subj "/C=US/ST=State/L=City/O=Org/OU=Unit/CN=rsyslogclient" >/dev/null 2>&1 openssl x509 -req -in "$CERTDIR/client-int2.csr" -CA "$CERTDIR/intermediate-ca2-cert.pem" -CAkey "$CERTDIR/intermediate-ca2-key.pem" -CAcreateserial -days 365 \ -extfile "$CERTDIR/leaf_ext.cnf" -extensions client_cert -out "$CERTDIR/client-int2-cert.pem" >/dev/null 2>&1 cat "$CERTDIR/client-int2-cert.pem" "$CERTDIR/intermediate-ca2-cert.pem" > "$CERTDIR/client-int2-chain.pem" # Debug: dump generated certificates and verify chains { echo "==== CERT DEBUG: Subjects/Issuers/Dates/Fingerprints ====" echo "-- Root CA --"; openssl x509 -in "$CERTDIR/ca-root-cert.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Intermediate CA 1 --"; openssl x509 -in "$CERTDIR/intermediate-ca1-cert.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Intermediate CA 2 --"; openssl x509 -in "$CERTDIR/intermediate-ca2-cert.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Server leaf --"; openssl x509 -in "$CERTDIR/server-int1-cert.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Server chain (top of file) --"; openssl x509 -in "$CERTDIR/server-int1-chain.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Client leaf --"; openssl x509 -in "$CERTDIR/client-int2-cert.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "-- Client chain (top of file) --"; openssl x509 -in "$CERTDIR/client-int2-chain.pem" -noout -subject -issuer -dates -serial -fingerprint -sha256; echo "==== OPENSSL VERIFY ====" echo "Verify server leaf against Root + Intermediate1"; openssl verify -CAfile "$CERTDIR/ca-root-cert.pem" -untrusted "$CERTDIR/intermediate-ca1-cert.pem" "$CERTDIR/server-int1-cert.pem"; echo "Verify client leaf against Root + Intermediate2"; openssl verify -CAfile "$CERTDIR/ca-root-cert.pem" -untrusted "$CERTDIR/intermediate-ca2-cert.pem" "$CERTDIR/client-int2-cert.pem"; } generate_conf export PORT_RCVR="$(get_free_port)" export SERVER_CN="rsyslogserver" export CLIENT_CN="rsyslogclient" add_conf ' global( DefaultNetstreamDriver="ossl" DefaultNetstreamDriverCAFile="'$CERTDIR'/ca-root-cert.pem" DefaultNetstreamDriverCertFile="'$CERTDIR'/server-int1-chain.pem" DefaultNetstreamDriverKeyFile="'$CERTDIR'/server-int1-key.pem" NetstreamDriverCAExtraFiles="'$CERTDIR'/intermediate-ca1-cert.pem,'$CERTDIR'/intermediate-ca2-cert.pem" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" PermittedPeer="'$CLIENT_CN'" StreamDriver.AuthMode="x509/name" ) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$CERTDIR'/ca-root-cert.pem" defaultNetstreamDriverCertFile="'$CERTDIR'/client-int2-chain.pem" defaultNetstreamDriverKeyFile="'$CERTDIR'/client-int2-key.pem" ) $ModLoad ../plugins/imtcp/.libs/imtcp input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/name" StreamDriverPermittedPeers="'$SERVER_CN'" ) ' 2 startup 2 tcpflood -m$NUMMESSAGES -i1 wait_file_lines shutdown_when_empty 2 wait_shutdown 2 shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_key_truncated-vg.sh0000644000000000000000000000013215055602574023341 xustar0030 mtime=1756824956.039451582 30 atime=1764931160.024624179 30 ctime=1764935932.621721064 rsyslog-8.2512.0/tests/rscript_unflatten_key_truncated-vg.sh0000775000175000017500000000013515055602574023007 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_key_truncated.sh rsyslog-8.2512.0/tests/PaxHeaders/omhttp-retry-vg.sh0000644000000000000000000000013215035412264017321 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.078705232 30 ctime=1764935934.061743106 rsyslog-8.2512.0/tests/omhttp-retry-vg.sh0000775000175000017500000000011215035412264016762 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-retry.sh rsyslog-8.2512.0/tests/PaxHeaders/imtcp_conndrop.sh0000644000000000000000000000013215055602574017256 xustar0030 mtime=1756824956.032451484 30 atime=1764931163.610681697 30 ctime=1764935933.648736785 rsyslog-8.2512.0/tests/imtcp_conndrop.sh0000775000175000017500000000164315055602574016731 0ustar00rgerrger#!/bin/bash # Test imtcp with many dropping connections # added 2010-08-10 by Rgerhards # # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' $MaxMessageSize 10k module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! $OMFileFlushInterval 2 $OMFileIOBufferSize 256k local0.* ?dynfile;outfmt ' startup # 100 byte messages to gain more practical data use tcpflood -c20 -m$NUMMESSAGES -r -d100 -P129 -D shutdown_when_empty wait_shutdown export SEQ_CHECK_OPTIONS=-E seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_arg2_invalid-vg.sh0000644000000000000000000000013215055602574023041 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.987623585 30 ctime=1764935932.611720911 rsyslog-8.2512.0/tests/rscript_unflatten_arg2_invalid-vg.sh0000775000175000017500000000013415055602574022506 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_arg2_invalid.sh rsyslog-8.2512.0/tests/PaxHeaders/known_issues.supp0000644000000000000000000000013215071746523017345 xustar0030 mtime=1760021843.892421838 30 atime=1764931168.200755261 30 ctime=1764935934.976757112 rsyslog-8.2512.0/tests/known_issues.supp0000664000175000017500000000347315071746523017020 0ustar00rgerrger{ Memcheck:Leak ... fun:dlopen* ... } { Memcheck:Leak fun:malloc fun:CRYPTO_malloc fun:EC_KEY_new fun:EC_KEY_new_by_curve_name fun:SetAuthMode fun:LstnInit fun:create_tcp_socket fun:tcpsrvConstructFinalize fun:activate fun:initAll fun:main } { Memcheck:Param pselect6(sig) fun:pselect64_syscall fun:pselect fun:wait_timeout fun:mainloop fun:main } { Memcheck:Param pselect6(sig) fun:pselect fun:wait_timeout fun:mainloop fun:main } { Memcheck:Leak ... fun:checkInstance fun:activateCnf fun:tellModulesActivateConfig fun:activate fun:initAll } { Helgrind:Misc obj:/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so fun:_dl_fini fun:__run_exit_handlers fun:exit fun:(below main) } { Helgrind:Misc obj:/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_helgrind-amd64-linux.so obj:/usr/lib/x86_64-linux-gnu/libp11-kit.so.0.3.0 fun:_dl_fini fun:__run_exit_handlers fun:exit fun:(below main) } { Memcheck:Leak match-leak-kinds: definite fun:malloc fun:UnknownInlinedFun fun:_dl_map_object_deps fun:dl_open_worker_begin fun:_dl_catch_exception fun:dl_open_worker fun:_dl_catch_exception fun:_dl_open fun:do_dlopen fun:_dl_catch_exception fun:_dl_catch_error fun:dlerror_run fun:__libc_dlopen_mode } rsyslog-8.2512.0/tests/PaxHeaders/es-basic-vg.sh0000644000000000000000000000013115035412264016330 xustar0030 mtime=1752569012.387841078 29 atime=1764931162.67166664 30 ctime=1764935933.373732575 rsyslog-8.2512.0/tests/es-basic-vg.sh0000775000175000017500000000010615035412264015775 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/es-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/omrabbitmq_error_server0.sh0000644000000000000000000000013215071746523021255 xustar0030 mtime=1760021843.903422011 30 atime=1764931160.875637832 30 ctime=1764935932.864724783 rsyslog-8.2512.0/tests/omrabbitmq_error_server0.sh0000775000175000017500000000317415071746523020731 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init cmd="./miniamqpsrvr -b 4 -f $RSYSLOG_DYNNAME.amqp.log -d" echo $cmd eval $cmd > $RSYSLOG_DYNNAME.source if [ ! $? -eq 0 ]; then exit 77 fi . $RSYSLOG_DYNNAME.source export OMRABBITMQ_TEST=1 generate_conf add_conf ' global(localhostname="server") module(load="../contrib/omrabbitmq/.libs/omrabbitmq") template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%") # rfc5424 without Timestamp : unable to manage template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n") ruleset(name="rmq") { action(type="omrabbitmq" host="localhost" port="'$PORT_AMQP1'" user="mtr" password="mtr" exchange="in" expiration="5000" exchange_type="topic" durable="off" auto_delete="off" body_template="" content_type="rfc5424" virtual_host="/metrologie" routing_key_template="rkTpl" populate_properties="on" delivery_mode="transient" ) } if $msg contains "msgrmq" then { call rmq } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg literal "<167>Mar 1 01:00:00 192.0.2.8 tag msgrmq" shutdown_when_empty wait_shutdown export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:192.0.2.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 192.0.2.8 tag msgrmq' cmp_exact $RSYSLOG_DYNNAME.amqp.log content_check "exchange declare failed PRECONDITION_FAILED" exit_test rsyslog-8.2512.0/tests/PaxHeaders/pipeaction.sh0000644000000000000000000000013215035412264016364 xustar0030 mtime=1752569012.407702108 30 atime=1764931164.533696495 30 ctime=1764935933.910740795 rsyslog-8.2512.0/tests/pipeaction.sh0000775000175000017500000000241215035412264016032 0ustar00rgerrger#!/bin/bash # Test for the pipe output action. # will create a fifo in the current directory, write to it and # then do the usual sequence checks. # added 2009-11-05 by RGerhards # create the pipe and start a background process that copies data from # it to the "regular" work file . ${srcdir:=.}/diag.sh init export NUMMESSAGES=20000 generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 # set spool locations and switch queue to disk-only mode $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueFilename mainq $MainMsgQueueType disk $template outfmt,"%msg:F,58:2%\n" # with pipes, we do not need to use absolute path names, so # we can simply refer to our working pipe via the usual relative # path name :msg, contains, "msgnum:" |rsyslog-testbench-fifo;outfmt ' rm -f rsyslog-testbench-fifo mkfifo rsyslog-testbench-fifo cp rsyslog-testbench-fifo $RSYSLOG_OUT_LOG & CPPROCESS=$! echo background cp process id is $CPPROCESS # now do the usual run startup injectmsg 0 $NUMMESSAGES shutdown_when_empty wait_shutdown # wait for the cp process to finish, do pipe-specific cleanup echo waiting for background cp to terminate... wait $CPPROCESS rm -f rsyslog-testbench-fifo echo background cp has terminated, continue test... # and continue the usual checks seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh0000644000000000000000000000013115035412264025165 xustar0029 mtime=1752569012.41564652 30 atime=1764931168.402758497 30 ctime=1764935935.033757985 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_serveranon_ossl_clientanon.sh0000775000175000017500000000311015035412264024630 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' # Note: no TLS for the listener, this is for tcpflood! module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="anon" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-basic-cnf6.sh0000644000000000000000000000013215035412264017270 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.654762534 30 ctime=1764935935.101759026 rsyslog-8.2512.0/tests/pgsql-basic-cnf6.sh0000775000175000017500000000123615035412264016741 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' module(load="../plugins/ompgsql/.libs/ompgsql") if $msg contains "msgnum" then { action(type="ompgsql" server="127.0.0.1" db="syslogtest" user="postgres" pass="testbench") }' startup injectmsg 0 5000 shutdown_when_empty wait_shutdown psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/rs-substring.sh0000644000000000000000000000013215035412264016673 xustar0030 mtime=1752569012.409688211 30 atime=1764931160.094625302 30 ctime=1764935932.640721354 rsyslog-8.2512.0/tests/rs-substring.sh0000775000175000017500000000134715035412264016347 0ustar00rgerrger#!/bin/bash # add 2018-04-04 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!var = substring($msg, 3, 2); template(name="outfmt" type="string" string="-%$!var%-\n") :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" shutdown_when_empty wait_shutdown echo '-gn-' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/fromhost-port.sh0000644000000000000000000000013215071746523017064 xustar0030 mtime=1760021843.887421759 30 atime=1764931162.783668436 30 ctime=1764935933.405733065 rsyslog-8.2512.0/tests/fromhost-port.sh0000775000175000017500000000133115071746523016531 0ustar00rgerrger#!/bin/bash ## fromhost-port.sh ## Check that fromhost-port property records sender port . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="list") { property(name="fromhost-port") constant(value="\n") } :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -m $NUMMESSAGES -w "${RSYSLOG_DYNNAME}.tcpflood-port" shutdown_when_empty wait_shutdown export EXPECTED="$(cat "${RSYSLOG_DYNNAME}.tcpflood-port")" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_simple_multi.sh0000644000000000000000000000013215035412264020311 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.619697874 30 ctime=1764935933.935741177 rsyslog-8.2512.0/tests/improg_simple_multi.sh0000775000175000017500000000115315035412264017760 0ustar00rgerrger#!/bin/bash # . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/improg/.libs/improg") template(name="outfmt" type="string" string="#%msg%#\n") input(type="improg" tag="tag" ruleset="ruleset" binary="'$PYTHON' '$srcdir'/improg-multiline-test.py" confirmmessages="off" closetimeout="2000" ) ruleset(name="ruleset") { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' startup shutdown_when_empty wait_shutdown NUM_ITEMS=10 echo "expected: $NUM_EXPECTED" echo "file: $RSYSLOG_OUT_LOG" content_check_with_count "#multi-line-string#" $NUM_EXPECTED $NUM_ITEMS exit_test rsyslog-8.2512.0/tests/PaxHeaders/mysql-asyn-vg.sh0000644000000000000000000000013215035412264016760 xustar0030 mtime=1752569012.402736851 30 atime=1764931166.708731356 30 ctime=1764935934.554750653 rsyslog-8.2512.0/tests/mysql-asyn-vg.sh0000775000175000017500000000021315035412264016423 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/mysql-asyn.sh rsyslog-8.2512.0/tests/PaxHeaders/execonlywhenprevsuspended4.sh0000644000000000000000000000013115035412264021634 xustar0029 mtime=1752569012.38883413 30 atime=1764931166.383726148 30 ctime=1764935934.461749229 rsyslog-8.2512.0/tests/execonlywhenprevsuspended4.sh0000775000175000017500000000204415035412264021304 0ustar00rgerrger#!/bin/bash # we test the execonly if previous is suspended directive. # This test checks if multiple backup actions can be defined. # rgerhards, 2010-06-24 echo =============================================================================== echo \[execonlywhenprevsuspended4.sh\]: test execonly..suspended multi backup action . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # omtesting provides the ability to cause "SUSPENDED" action state $ModLoad ../plugins/omtesting/.libs/omtesting $MainMsgQueueTimeoutShutdown 100000 $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" :omtesting:fail 2 0 $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"';outfmt # note that $ActionExecOnlyWhenPreviousIsSuspended on is still active! & ./'"${RSYSLOG2_OUT_LOG}"';outfmt ' startup injectmsg 0 1000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 1 999 if [[ -s ${RSYSLOG2_OUT_LOG} ]] ; then echo failure: second output file has data where it should be empty exit 1 fi ; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtuxedoulog_data.sh0000644000000000000000000000013215035412264017747 xustar0030 mtime=1752569012.397771593 30 atime=1764931157.995591616 30 ctime=1764935932.066712568 rsyslog-8.2512.0/tests/imtuxedoulog_data.sh0000775000175000017500000000435515035412264017425 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imtuxedoulog/.libs/imtuxedoulog") input(type="imtuxedoulog" ruleset="ruleset" severity="info" facility="local0" maxlinesatonce="100" persiststateinterval="10" maxsubmitatonce="100" tag="domain" ulogbase="./'$RSYSLOG_DYNNAME'") ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format") } ' { echo '164313.15.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree' echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree' echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)' echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1' echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)' } > $RSYSLOG_DYNNAME.$(date "+%m%d%y") logdate=$(date "+%Y-%m-%d") startup shutdown_when_empty wait_shutdown { echo '<134>1 '${logdate}'T16:43:13.15 tst-tmsm1 domain ARTIMPP_UDB.40042721.1 - - TRACE:at: } tpfree' echo '<134>1 '${logdate}'T16:43:13.151 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003UF^"] TRACE:at: } tpfree' echo '<134>1 '${logdate}'T16:43:13.152 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02B003UF^"] TRACE:at: { tpcommit(0x0)' echo '<134>1 '${logdate}'T16:43:13.153 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003SF^"] TRACE:at: } tpcommit = 1' echo '<134>1 '${logdate}'T16:43:13.154 tst-tmsm1 domain ARTIMPP_UDB.40042722.1 - [ECID="000001833E1D4i^5pVl3iY00f02M003VF^"] TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)' } | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-basic.sh0000644000000000000000000000013115055602574016432 xustar0029 mtime=1756824956.03145147 30 atime=1764931162.857669623 30 ctime=1764935933.432733478 rsyslog-8.2512.0/tests/imtcp-basic.sh0000775000175000017500000000107615055602574016106 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -m $NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-jsonarray-retry.sh0000644000000000000000000000013215055602574022003 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.852701609 30 ctime=1764935933.999742157 rsyslog-8.2512.0/tests/omhttp-batch-jsonarray-retry.sh0000775000175000017500000000320315055602574021450 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 omhttp_start_server 0 --fail-every 100 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="2048") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") # Echo message as-is for retry template(name="tpl_echo" type="string" string="%msg%") ruleset(name="ruleset_omhttp_retry") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl_echo" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="jsonarray" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } ruleset(name="ruleset_omhttp") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="jsonarray" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint jsonarray omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/multiple_lookup_tables.sh0000644000000000000000000000013215035412264021007 xustar0030 mtime=1752569012.402736851 30 atime=1764931167.905750536 30 ctime=1764935934.891755811 rsyslog-8.2512.0/tests/multiple_lookup_tables.sh0000775000175000017500000000310415035412264020454 0ustar00rgerrger#!/bin/bash # test for multiple lookup-table and HUP based reloading of it # added 2016-01-20 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate_0" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl") lookup_table(name="xlate_1" file="'$RSYSLOG_DYNNAME'.xlate_1.lkp_tbl") template(name="outfmt" type="string" string="- %msg% 0_%$.lkp_0% 1_%$.lkp_1%\n") set $.lkp_0 = lookup("xlate_0", $msg); set $.lkp_1 = lookup("xlate_1", $msg); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate_1.lkp_tbl startup injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: 0_foo_old 1_foo_old" content_check "msgnum:00000001: 0_bar_old 1_bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: 0_foo_new 1_foo_old" content_check "msgnum:00000001: 0_bar_new 1_bar_old" content_check "msgnum:00000002: 0_baz" assert_content_missing "1_baz" cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_1.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: 0_foo_new 1_foo_new" content_check "msgnum:00000001: 0_bar_new 1_bar_new" content_check "msgnum:00000002: 0_baz 1_baz" exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_dtls_certvalid.sh0000644000000000000000000000013215055603742020620 xustar0030 mtime=1756825570.303069141 30 atime=1764931164.432694876 30 ctime=1764935933.883740382 rsyslog-8.2512.0/tests/sndrcv_dtls_certvalid.sh0000775000175000017500000000513315055603742020271 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls} export NUMMESSAGES=1000 export NUMMESSAGESFULL=$NUMMESSAGES export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" # debug.whitelist="on" # debug.files=["imdtls.c", "modules.c", "errmsg.c", "action.c"] ) module( load="../plugins/imdtls/.libs/imdtls" ) input( type="imdtls" port="'$PORT_RCVR'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" # debug.whitelist="on" # debug.files=["omdtls.c", "modules.c", "errmsg.c", "action.c"] ) # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") $imdiagInjectDelayMode full # Load modules module( load="../plugins/omdtls/.libs/omdtls" ) local4.* { action( name="omdtls" type="omdtls" target="127.0.0.1" port="'$PORT_RCVR'" action.resumeInterval="1" action.resumeRetryCount="2" queue.type="FixedArray" queue.size="10000" queue.dequeueBatchSize="1" queue.minDequeueBatchSize.timeout="1000" # 1 sec queue.timeoutWorkerthreadShutdown="1000" # 1 sec queue.timeoutshutdown="1000" # Slow down, do not lose UDP messages queue.dequeueSlowDown="1000" ) # action( type="omfile" file="'$RSYSLOG_OUT_LOG'") stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-basic.sh0000644000000000000000000000013215055602574016632 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.818701064 30 ctime=1764935933.990742019 rsyslog-8.2512.0/tests/omhttp-basic.sh0000775000175000017500000000141015055602574016275 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 omhttp_start_server 0 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../contrib/omhttp/.libs/omhttp") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="off" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_regex.match.rename.sh0000644000000000000000000000013115035412264024205 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.079592964 29 ctime=1764935932.08971292 rsyslog-8.2512.0/tests/imbatchreport_errmsg_regex.match.rename.sh0000775000175000017500000000072015035412264023654 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" rename=".done$ .s.done .r" reports="./*.done") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "Normal renaming leaves files in glob scope: Instance ignored to avoid loops." exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-impstats.sh0000644000000000000000000000013215103061376017207 xustar0030 mtime=1762419454.860381364 30 atime=1764931162.877669944 30 ctime=1764935933.437733555 rsyslog-8.2512.0/tests/imtcp-impstats.sh0000775000175000017500000000310315103061376016653 0ustar00rgerrger#!/bin/bash # added 2025-02-27 by RGerhards, released under ASL 2.0 # This checks primarily that impstats and imtcp work together. There is little # we can tell about the actual stats. . ${srcdir:=.}/diag.sh init export NUM_WORKERS=${NUM_WORKERS:-4} export NUMMESSAGES=40000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines export STATSFILE="$RSYSLOG_DYNNAME.stats" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/impstats/.libs/impstats" log.file="'$STATSFILE'" interval="1") input(type="imtcp" name="pstats-test" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" workerthreads="'$NUM_WORKERS'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -m $NUMMESSAGES echo sleeping 2secs to ensure we have at least one stats interval sleep 2 shutdown_when_empty wait_shutdown cat -n $STATSFILE | grep 'w./pstats-test' NUM_STATS=$(grep 'w./pstats-test' "$STATSFILE" | wc -l) if [ "$NUM_WORKERS" -gt 1 ]; then EXPECTED_COUNT=$NUM_WORKERS else EXPECTED_COUNT=0 fi # Check if the count matches NUM_WORKERS if [ "$EXPECTED_COUNT" -gt 0 ]; then if [ "$NUM_STATS" -le "$EXPECTED_COUNT" ]; then echo "ERROR: Expected at most $EXPECTED_COUNT lines, but found $NUM_STATS in pstats" error_exit 1 fi else if [ "$NUM_STATS" -ne "$EXPECTED_COUNT" ]; then echo "ERROR: Expected $EXPECTED_COUNT lines, but found $NUM_STATS in pstats" error_exit 1 fi fi seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-basic.sh0000644000000000000000000000013115055602574017232 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.034672461 30 ctime=1764935933.480734213 rsyslog-8.2512.0/tests/imtcp-tls-basic.sh0000775000175000017500000000221215055602574016677 0ustar00rgerrger#!/bin/bash # added 2011-02-28 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export TB_TEST_MAX_RUNTIME=1500 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem") module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_ruleset_ratelimit.sh0000644000000000000000000000013115035412264023246 xustar0030 mtime=1752569012.397771593 29 atime=1764931166.52672844 30 ctime=1764935934.501749842 rsyslog-8.2512.0/tests/imuxsock_logger_ruleset_ratelimit.sh0000775000175000017500000000222615035412264022720 0ustar00rgerrger#!/bin/bash # rgerhards, 2016-02-18 released under ASL 2.0 echo \[imuxsock_logger_ruleset_ratelimit.sh\]: test imuxsock with ruleset definition . ${srcdir:=.}/diag.sh init check_logger_has_option_d generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket" useSpecialParser="off" ruleset="testruleset" rateLimit.Interval="2" parseHostname="on") template(name="outfmt" type="string" string="%msg:%\n") ruleset(name="testruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup # send a message with trailing LF logger -d -u $RSYSLOG_DYNNAME-testbench_socket test # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! cmp $RSYSLOG_OUT_LOG $srcdir/resultdata/imuxsock_logger.log echo \"$(cat $RSYSLOG_OUT_LOG)\" if [ ! $? -eq 0 ]; then echo "imuxsock_logger.sh failed" echo "contents of $RSYSLOG_OUT_LOG:" echo \"$(cat $RSYSLOG_OUT_LOG)\" exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/failover-rptd.sh0000644000000000000000000000013215035412264017007 xustar0030 mtime=1752569012.389827181 30 atime=1764931163.722683493 30 ctime=1764935933.679737259 rsyslog-8.2512.0/tests/failover-rptd.sh0000775000175000017500000000100315035412264016450 0ustar00rgerrger#!/bin/bash # rptd test for failover functionality # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init NUMMESSAGES=5000 generate_conf add_conf ' $RepeatedMsgReduction on $template outfmt,"%msg:F,58:2%\n" # note: the target server shall not be available! :msg, contains, "msgnum:" @@127.0.0.1:'$TCPFLOOD_PORT' $ActionExecOnlyWhenPreviousIsSuspended on & ./'$RSYSLOG_OUT_LOG';outfmt ' startup injectmsg 0 $NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imjournal-basic-vg.sh0000644000000000000000000000013215035412264017722 xustar0030 mtime=1752569012.393799388 30 atime=1764931161.608649591 30 ctime=1764935933.079728075 rsyslog-8.2512.0/tests/imjournal-basic-vg.sh0000775000175000017500000000011515035412264017366 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/imjournal-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-statefile-delete.sh0000644000000000000000000000013215055602574020723 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.984719754 30 ctime=1764935934.335747301 rsyslog-8.2512.0/tests/imfile-statefile-delete.sh0000775000175000017500000000263515055602574020400 0ustar00rgerrger#!/bin/bash # added 2019-02-28 # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init export TESTMESSAGES=1000 export TESTMESSAGESFULL=999 export RETRIES=50 # Uncomment fdor debuglogs #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input") template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' ./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input inode=$(get_inode "$RSYSLOG_DYNNAME.input") startup wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES rm $RSYSLOG_DYNNAME.input sleep_time_ms=0 while ls $RSYSLOG_DYNNAME.spool/imfile-state:$inode:* 1> /dev/null 2>&1; do ./msleep 100 ((sleep_time_ms+=100)) if [ $sleep_time_ms -ge 6000 ]; then touch $RSYSLOG_DYNNAME:.tmp fi if [ $sleep_time_ms -ge 30000 ]; then printf 'FAIL: state file still exists when it should have been deleted\nspool dir is:\n' ls -l $RSYSLOG_DYNNAME.spool error_exit 1 fi done shutdown_when_empty wait_shutdown seq_check 0 $TESTMESSAGESFULL # check we got the message correctly exit_test rsyslog-8.2512.0/tests/PaxHeaders/uxsock_simple.sh0000644000000000000000000000013215114522477017124 xustar0030 mtime=1764926783.046632128 30 atime=1764926784.241661461 30 ctime=1764935934.153744515 rsyslog-8.2512.0/tests/uxsock_simple.sh0000775000175000017500000000267215114522477016602 0ustar00rgerrger#!/bin/bash # This tests basic omuxsock functionality. A socket receiver is started which sends # all data to an output file, then a rsyslog instance is started which generates # messages and sends them to the unix socket. Datagram sockets are being used. # added 2010-08-06 by Rgerhards . ${srcdir:=.}/diag.sh init check_command_available timeout uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi # create the pipe and start a background process that copies data from # it to the "regular" work file generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 $ModLoad ../plugins/omuxsock/.libs/omuxsock $template outfmt,"%msg:F,58:2%\n" $OMUXSockSocket '$RSYSLOG_DYNNAME'-testbench-dgram-uxsock :msg, contains, "msgnum:" :omuxsock:;outfmt ' timeout 30s ./uxsockrcvr -s$RSYSLOG_DYNNAME-testbench-dgram-uxsock -o $RSYSLOG_OUT_LOG -t 60 & BGPROCESS=$! echo background uxsockrcvr process id is $BGPROCESS # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # wait for the cp process to finish, do pipe-specific cleanup echo shutting down uxsockrcvr... # TODO: we should do this more reliable in the long run! (message counter? timeout?) kill $BGPROCESS wait $BGPROCESS echo background process has terminated, continue test... # and continue the usual checks seq_check 0 9999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-basic-vg.sh0000644000000000000000000000013215035412264017050 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.704763335 30 ctime=1764935935.116759255 rsyslog-8.2512.0/tests/pgsql-basic-vg.sh0000775000175000017500000000116515035412264016522 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' $ModLoad ../plugins/ompgsql/.libs/ompgsql :msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench ' startup_vg injectmsg 0 5000 shutdown_when_empty wait_shutdown_vg check_exit_vg psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/diagtalker.c0000644000000000000000000000013115103346332016145 xustar0030 mtime=1762512090.633176003 30 atime=1764931157.410582225 29 ctime=1764935931.91271021 rsyslog-8.2512.0/tests/diagtalker.c0000664000175000017500000001127615103346332015621 0ustar00rgerrger/* A yet very simple tool to talk to imdiag (this replaces the * previous Java implementation in order to get fewer dependencies). * * Copyright 2010-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif static char *targetIP = "localhost"; static int targetPort = 13500; /* open a single tcp connection */ int openConn(int *fd) { char service[16]; struct addrinfo hints, *res = NULL, *rp = NULL; int retries = 0; int sock = -1; snprintf(service, sizeof(service), "%d", targetPort); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* Try IPv6, then IPv4 */ hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; for (;;) { if (res == NULL) { if (getaddrinfo(targetIP, service, &hints, &res) != 0 || res == NULL) { /* Fallback: try explicit loopback families */ if (getaddrinfo("127.0.0.1", service, &hints, &res) != 0 || res == NULL) { if (getaddrinfo("::1", service, &hints, &res) != 0 || res == NULL) { fprintf(stderr, "name resolution failed for 'localhost' and loopback addresses\n"); exit(1); } } } } for (rp = res; rp != NULL; rp = rp->ai_next) { sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sock == -1) { continue; } if (connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) { *fd = sock; if (retries > 0) { fprintf(stderr, "[%d] connection established.\n", targetPort); } freeaddrinfo(res); return 0; } close(sock); sock = -1; } if (retries++ == 200) { perror("connect()"); fprintf(stderr, "[%d] connect() failed\n", targetPort); freeaddrinfo(res); exit(1); } else { fprintf(stderr, "[%d] connect failed, retrying...\n", targetPort); usleep(100000); } /* retry with same resolved list to keep overhead low */ } } /* send a string */ static void sendCmd(int fd, char *buf, int len) { int lenSend; lenSend = send(fd, buf, len, 0); if (lenSend != len) { perror("sending string"); exit(1); } } /* wait for a response from remote system */ static void waitRsp(int fd, char *buf, int len) { int ret; ret = recv(fd, buf, len - 1, 0); if (ret < 0) { perror("receiving response"); exit(1); } /* we assume the message was complete, it may be better to wait * for a LF... */ buf[ret] = '\0'; } /* do the actual processing */ static void doProcessing(void) { int fd; int len; char line[10 * 1024]; openConn(&fd); while (!feof(stdin)) { if (fgets(line, sizeof(line) - 1, stdin) == NULL) break; len = strlen(line); sendCmd(fd, line, len); waitRsp(fd, line, sizeof(line)); printf("imdiag[%d]: %s", targetPort, line); if (strstr(line, "imdiag::error") != NULL) { exit(1); } } } /* Run the test. * rgerhards, 2009-04-03 */ int main(int argc, char *argv[]) { int ret = 0; int opt; while ((opt = getopt(argc, argv, "t:p:")) != -1) { switch (opt) { case 't': targetIP = optarg; break; case 'p': targetPort = atoi(optarg); break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit(1); break; } } doProcessing(); exit(ret); } rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-input-2certs.sh0000644000000000000000000000013015055602574020507 xustar0029 mtime=1756824956.03145147 29 atime=1764931163.05267275 30 ctime=1764935933.485734289 rsyslog-8.2512.0/tests/imtcp-tls-input-2certs.sh0000775000175000017500000000256715055602574020172 0ustar00rgerrger#!/bin/bash # added 2021-08-03 by Rgerhards # check that we do use the proper set of certificates # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' # The default shall NOT be used - if so, tcpflood would err out! global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/machine-cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/machine-key.pem") module(load="../plugins/imtcp/.libs/imtcp" permittedPeer="SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/fingerprint" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem" streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem" streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-gtls-x509fingerprint.sh0000644000000000000000000000013215055603742022074 xustar0030 mtime=1756825570.301069108 30 atime=1764931162.963671323 30 ctime=1764935933.461733922 rsyslog-8.2512.0/tests/imtcp-tls-gtls-x509fingerprint.sh0000775000175000017500000000226215055603742021545 0ustar00rgerrger#!/bin/bash # added 2018-12-22 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/fingerprint" PermittedPeer=["SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"] ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-gtls-x509name-legacy.sh0000644000000000000000000000013015055602574021727 xustar0029 mtime=1756824956.03145147 29 atime=1764931162.98967174 30 ctime=1764935933.468734029 rsyslog-8.2512.0/tests/imtcp-tls-gtls-x509name-legacy.sh0000775000175000017500000000221515055602574021400 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) # NOTE: we intentionally use legacy statements here! This *IS* what we want to test! $ModLoad ../plugins/imtcp/.libs/imtcp $DefaultNetstreamDriver gtls $inputTcpserverStreamdriverPermittedPeer rsyslog-client $InputTCPServerStreamDriverAuthMode x509/name $InputTCPServerStreamDriverPermittedPeer Log_Streaming_Client $InputTCPServerStreamDriverMode 1 $InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port $InputTCPServerRun 0 template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-basic-vg.sh0000644000000000000000000000013215055603742020621 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.316676983 30 ctime=1764935933.563735483 rsyslog-8.2512.0/tests/imtcp-tls-ossl-basic-vg.sh0000775000175000017500000000057315055603742020275 0ustar00rgerrger#!/bin/bash if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n' printf 'a valgrind-internal bug. So we need to skip it.\n' exit 77 fi export USE_VALGRIND="YES" # not working on CENTOS 7 export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes" source ${srcdir:-.}/imtcp-tls-ossl-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-basic.sh0000644000000000000000000000013215055603742020207 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.145674241 30 ctime=1764935933.513734718 rsyslog-8.2512.0/tests/imtcp-tls-ossl-basic.sh0000775000175000017500000000215715055603742017663 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "nsd_ptcp.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-syslog.sh0000644000000000000000000000013215103346332020242 xustar0030 mtime=1762512090.634176013 30 atime=1764931158.295596431 30 ctime=1764935932.150713854 rsyslog-8.2512.0/tests/mmsnareparse-syslog.sh0000775000175000017500000000262515103346332017716 0ustar00rgerrger#!/bin/bash # Validate mmsnareparse when receiving raw syslog messages over TCP. unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmsnareparse/.libs/mmsnareparse") template(name="outfmt" type="list") { property(name="$!win!Event!EventID") constant(value=",") property(name="$!win!Event!Channel") constant(value=",") property(name="$!win!Event!EventType") constant(value=",") property(name="$!win!Event!CategoryText") constant(value=",") property(name="$!win!Event!Computer") constant(value="\n") } ruleset(name="winsec") { action(type="mmsnareparse") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="winsec") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port cat "$srcdir/testsuites/mmsnareparse/sample-windows2022-security.data" \ "$srcdir/testsuites/mmsnareparse/sample-windows2025-security.data" \ > ${RSYSLOG_DYNNAME}.payload tcpflood -m 1 -I ${RSYSLOG_DYNNAME}.payload rm -f ${RSYSLOG_DYNNAME}.payload shutdown_when_empty wait_shutdown content_check '4608,Security,Success Audit,Security State Change,WIN-5SB1I3G0V7U' $RSYSLOG_OUT_LOG content_check '4616,Security,Success Audit,Security State Change,WIN-5SB1I3G0V7U' $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp-connection-msg-received.sh0000644000000000000000000000013115035412264022231 xustar0029 mtime=1752569012.39578549 30 atime=1764931163.476679549 30 ctime=1764935933.609736187 rsyslog-8.2512.0/tests/imptcp-connection-msg-received.sh0000775000175000017500000000202015035412264021673 0ustar00rgerrger#!/bin/bash # addd 2017-03-31 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" notifyonconnectionclose="on" notifyonconnectionopen="on") :msg, contains, "msgnum:" { action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m1 -M"\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" shutdown_when_empty wait_shutdown grep "imptcp: connection established" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi grep "imptcp: session on socket.* closed" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/omrabbitmq_params_missing1.sh0000644000000000000000000000013215035412264021543 xustar0030 mtime=1752569012.405716005 30 atime=1764931160.800636629 30 ctime=1764935932.842724447 rsyslog-8.2512.0/tests/omrabbitmq_params_missing1.sh0000775000175000017500000000062415035412264021214 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/omrabbitmq/.libs/omrabbitmq") action(type="omrabbitmq" exchange="in" host="host") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "routing_key or routing_key_template must be specified" exit_testrsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_regex.sh0000644000000000000000000000013115035412264017754 xustar0030 mtime=1752569012.401743799 30 atime=1764931167.663746658 29 ctime=1764935934.82175474 rsyslog-8.2512.0/tests/mmnormalize_regex.sh0000775000175000017500000000220715035412264017425 0ustar00rgerrger#!/bin/bash # added 2014-11-17 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[mmnormalize_regex.sh\]: test for mmnormalize regex field_type . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="hosts_and_ports" type="string" string="host and port list: %$!hps%\n") template(name="paths" type="string" string="%$!fragments% %$!user%\n") template(name="numbers" type="string" string="nos: %$!some_nos%\n") module(load="../plugins/mmnormalize/.libs/mmnormalize" allowRegex="on") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_regex.rulebase`) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="hosts_and_ports") ' startup tcpflood -m 1 -I $srcdir/testsuites/regex_input echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check 'host and port list: 192.168.1.2:80, 192.168.1.3, 192.168.1.4:443, 192.168.1.5' exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-x509fingerprint.sh0000644000000000000000000000013215055603742022103 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.308676855 30 ctime=1764935933.560735437 rsyslog-8.2512.0/tests/imtcp-tls-ossl-x509fingerprint.sh0000775000175000017500000000225315055603742021554 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/fingerprint" PermittedPeer=["SHA1:5C:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"] ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse-w-o-cookie-multi-spaces.sh0000644000000000000000000000013215055602574023151 xustar0030 mtime=1756824956.033451498 30 atime=1764931162.072657033 30 ctime=1764935933.208730049 rsyslog-8.2512.0/tests/mmjsonparse-w-o-cookie-multi-spaces.sh0000775000175000017500000000134115055602574022617 0ustar00rgerrger#!/bin/bash # addd 2016-03-22 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' template(name="outfmt" type="string" string="%$!msgnum%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse" cookie="") if $parsesuccess == "OK" then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' rm -f $RSYSLOG_OUT_LOG # do cleanup of previous subtest startup tcpflood -m $NUMMESSAGES "-j \" \"" shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/dnscache-TTL-0-vg.sh0000644000000000000000000000013215035412264017211 xustar0030 mtime=1752569012.386848027 30 atime=1764931157.595585195 30 ctime=1764935931.956710884 rsyslog-8.2512.0/tests/dnscache-TTL-0-vg.sh0000775000175000017500000000021215035412264016653 0ustar00rgerrger#!/bin/bash # added 2019-04-12 by Rainer Gerhards, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/dnscache-TTL-0.sh rsyslog-8.2512.0/tests/PaxHeaders/diskqueue-non-unique-prefix.sh0000644000000000000000000000013215035412264021617 xustar0030 mtime=1752569012.386848027 30 atime=1764931159.178610603 30 ctime=1764935932.400717681 rsyslog-8.2512.0/tests/diskqueue-non-unique-prefix.sh0000775000175000017500000000173615035412264021275 0ustar00rgerrger#!/bin/bash # Test for config parser to check that disk queue file names are # unique. # added 2019-05-02 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") if 0 then { action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused" queue.filename="qf1" queue.type="linkedList") action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused" queue.filename="qf1" queue.type="linkedList") action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused" queue.filename="qf2" queue.type="linkedList") action(type="omfile" file="'$RSYSLOG_DYNNAME'.notused" queue.spooldirectory="'$RSYSLOG_DYNNAME'.spool2" queue.filename="qf2" queue.type="linkedList") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "and file name prefix 'qf1' already used" check_not_present "and file name prefix 'qf2' already used" exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg-simul.sh0000644000000000000000000000013215035412264016655 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.541696624 30 ctime=1764935933.913740841 rsyslog-8.2512.0/tests/improg-simul.sh0000775000175000017500000000234215035412264016325 0ustar00rgerrger#! /bin/bash # add 2019-04-04 by Philippe DUVEAU, released under ASL 2.0 mysleep=./msleep ACK=0 SLEEP=0 DELAY=500 NB=1 MESSAGE="program datas" SIGNALED=0 ERR=$0.stderr while getopts "cd:e:s:n:m:g" OPTION; do case "${OPTION}" in g) SIGNALED=1 ;; c) ACK=1 ;; d) DELAY=${OPTARG} ;; e) ERR=${OPTARG} ;; s) SLEEP=${OPTARG} ;; n) NB=${OPTARG} ;; m) MESSAGE=${OPTARG} ;; *) exit 0 esac done trap 'echo "SIGTERM Received" >> '$ERR';echo $0" SIGTERM Received" >&2;exit 0' 15 if (( DELAY > 0 )); then $mysleep ${DELAY}; fi if [ ${ACK} == 1 ]; then while [ "x$order" != "xSTART" ]; do read -r order echo $order' Received' >> $ERR echo $0' '$order' Received' >&2 done while [ "x$order" != "xSTOP" ]; do if (( NB > 0 )); then echo ${MESSAGE} echo "Message sent" >&2 (( NB-- )) fi unset order read -r order echo $order' Received' >> $ERR echo $0' '$order' Received' >&2 if (( SLEEP > 0 )); then $mysleep ${SLEEP}; fi done else while (( NB > 0 )); do echo ${MESSAGE} echo $0" Message sent" >&2 if (( SLEEP > 0 )); then $mysleep ${SLEEP}; fi (( NB-- )) done if [ ${SIGNALED} == 1 ]; then $mysleep 100000 & wait fi fi echo "Leaving improg_sender" >&2 rsyslog-8.2512.0/tests/PaxHeaders/imfile-readmode2-polling.sh0000644000000000000000000000013215035412264021000 xustar0030 mtime=1752569012.392806336 30 atime=1764931165.696715138 30 ctime=1764935934.246745938 rsyslog-8.2512.0/tests/imfile-readmode2-polling.sh0000775000175000017500000000363015035412264020451 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global( debug.whitelist="on" debug.files=["imfile.c"]) module(load="../plugins/imfile/.libs/imfile" mode="polling" PollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing sleep 2 # write some more lines (see https://github.com/rsyslog/rsyslog/issues/144) echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2 # give it time to finish sleep 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! # give it time to write the output file sleep 1 ## check if we have the correct number of messages NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" exit_test exit 1 else if [ ! $NUMLINES -eq 3 ]; then echo "ERROR: expecting 3 headers, got $NUMLINES" exit_test exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {1..4}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" exit_test exit 1 fi done ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/omtcl.tcl0000644000000000000000000000013215035412264015517 xustar0030 mtime=1752569012.406709056 30 atime=1764931168.488759875 30 ctime=1764935935.056758337 rsyslog-8.2512.0/tests/omtcl.tcl0000664000175000017500000000036415035412264015166 0ustar00rgerrgerproc doAction {msg} { set fd [open $::env(RSYSLOG_OUT_LOG) a] puts $fd "message processed:" foreach {k v} $msg { puts $fd " $k: <<$v>>" } puts $fd " uppercase message: <<[string toupper [dict get $msg message]]>>" close $fd } rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_certvalid_tlscommand.sh0000644000000000000000000000013215055603742023735 xustar0030 mtime=1756825570.303069141 30 atime=1764931163.266676181 30 ctime=1764935933.548735254 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_certvalid_tlscommand.sh0000775000175000017500000000473615055603742023416 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" # start up the instances # export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="ossl" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" StreamDriver.PermitExpiredCerts="off" gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2\nOptions=Bugs" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export PORT_RCVR=$TCPFLOOD_PORT # save this, will be rewritten with next config export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="ossl" ) action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriverMode="1" StreamDriverAuthMode="x509/certvalid" gnutlsPriorityString="Protocol=-ALL,TLSv1.2" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 0 1 shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # IMPORTANT: this test will generate many error messages. This is exactly it's # intent. So do not think something is wrong. The content_check below checks # these error codes. content_check --check-only "TLS library does not support SSL_CONF_cmd" ret=$? if [ $ret == 0 ]; then echo "SKIP: TLS library does not support SSL_CONF_cmd" skip_test else content_check --check-only "SSL_ERROR_SYSCALL" ret=$? if [ $ret == 0 ]; then # Found SSL_ERROR_SYSCALL errorcode, no further check needed exit_test else # Check for a SSL_ERROR_SSL error code content_check "SSL_ERROR_SSL" content_check "OpenSSL Error Stack:" fi fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/prop-jsonmesg-vg.sh0000644000000000000000000000013215035412264017446 xustar0030 mtime=1752569012.408695159 30 atime=1764931161.149642228 30 ctime=1764935932.944726008 rsyslog-8.2512.0/tests/prop-jsonmesg-vg.sh0000775000175000017500000000112115035412264017110 0ustar00rgerrger#!/bin/bash # Added 2018-01-17 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="list"){ property(name="jsonmesg") constant(value="\n") } local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg tcpflood -m1 -y shutdown_when_empty wait_shutdown_vg check_exit_vg export EXPECTED='"msg": "msgnum:00000000:", ' . $srcdir/diag.sh grep-check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmleefparse_basic.sh0000644000000000000000000000013215071746523017702 xustar0030 mtime=1760021843.898421932 30 atime=1764931162.054656745 30 ctime=1764935933.203729973 rsyslog-8.2512.0/tests/mmleefparse_basic.sh0000775000175000017500000001270215071746523017353 0ustar00rgerrger#!/bin/bash # added 2025-09-?? by AI assistant, released under ASL 2.0 # Basic parsing test for the mmleefparse module using Palo Alto Networks samples. # The regression covers allow, drop and reset-both events provided with the task. . ${srcdir:=.}/diag.sh init export NUMMESSAGES=3 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/mmleefparse/.libs/mmleefparse") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") #template(name="outfmt" type="subtree" subtree="$!leef" option.forceEndOfLine="on") template(name="outfmt" type="string" string="%$!leef!header!vendor%|%$!leef!header!productVersion%|%$!leef!fields!src%|%$!leef!fields!dst%|%$!leef!fields!action%|%$!leef!fields!cat%|%$!leef!fields!proto%|%$!leef!fields!SessionID%\n") if $syslogtag == "LEEF:" then { action(type="mmleefparse" container="!leef" delimiter="|") if $parsesuccess == "OK" then { action(name="write-leef" type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } else { action(name="write-non-leef" type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) } } ' startup tcpflood -m1 -M "\"<14>Sep 17 13:45:35 firewall.domain.local LEEF:1.0|Palo Alto Networks|PAN-OS Syslog Integration|11.1.6-h14|allow|cat=TRAFFIC|ReceiveTime=2025/09/17 13:45:34|SerialNumber=010108010025|Type=TRAFFIC|Subtype=start|devTime=Sep 17 2025 11:45:34 GMT|src=172.19.50.39|dst=172.19.5.50|srcPostNAT=0.0.0.157|dstPostNAT=0.0.0.157|RuleName=interzone-default|usrName=|SourceUser=|DestinationUser=|Application=ssl|VirtualSystem=vsys3|SourceZone=x-def|DestinationZone=z-def|IngressInterface=iu1.6751|EgressInterface=iu1.6723|LogForwardingProfile=default|SessionID=74879677|RepeatCount=1|srcPort=62126|dstPort=443|srcPostNATPort=0|dstPostNATPort=0|Flags=0x0|proto=tcp|action=allow|totalBytes=460|dstBytes=70|srcBytes=390|totalPackets=4|StartTime=2025/09/17 13:45:33|ElapsedTime=0|URLCategory=any|sequence=7548503197945820434|ActionFlags=0x8000000000000000|SourceLocation=172.0.0.20-172.255.255.1|DestinationLocation=172.0.0.20-172.255.255.1|dstPackets=1|srcPackets=3|SessionEndReason=n/a|DeviceGroupHierarchyL1=177|DeviceGroupHierarchyL2=235|DeviceGroupHierarchyL3=236|DeviceGroupHierarchyL4=239|vSrcName=firewall.domain.local|DeviceName=firewall.domain.local|ActionSource=from-policy|SrcUUID=|DstUUID=|TunnelID=0|MonitorTag=|ParentSessionID=0|ParentStartTime=|TunnelType=N/A\"" tcpflood -m1 -M "\"<14>Sep 17 13:48:38 firewall.domain.local LEEF:1.0|Palo Alto Networks|PAN-OS Syslog Integration|11.1.6-h14|deny|cat=TRAFFIC|ReceiveTime=2025/09/17 13:48:37|SerialNumber=010108010025|Type=TRAFFIC|Subtype=drop|devTime=Sep 17 2025 11:48:37 GMT|src=172.39.129.169|dst=172.224.141.39|srcPostNAT=0.0.0.157|dstPostNAT=0.0.0.157|RuleName=interzone-default|usrName=|SourceUser=|DestinationUser=|Application=not-applicable|VirtualSystem=vsys7|SourceZone=wan|DestinationZone=partner-gw|IngressInterface=zz8.2012|EgressInterface=|LogForwardingProfile=default|SessionID=0|RepeatCount=1|srcPort=63219|dstPort=3367|srcPostNATPort=0|dstPostNATPort=0|Flags=0x0|proto=tcp|action=deny|totalBytes=0|dstBytes=0|srcBytes=0|totalPackets=1|StartTime=2025/09/17 13:48:38|ElapsedTime=0|URLCategory=any|sequence=7548503197948374938|ActionFlags=0x8000000000000000|SourceLocation=172.0.0.20-172.255.255.1|DestinationLocation=172.0.0.20-172.255.255.1|dstPackets=0|srcPackets=1|SessionEndReason=policy-deny|DeviceGroupHierarchyL1=177|DeviceGroupHierarchyL2=235|DeviceGroupHierarchyL3=48936|DeviceGroupHierarchyL4=36126|vSrcName=firewall.domain.local|DeviceName=firewall.domain.local|ActionSource=from-policy|SrcUUID=|DstUUID=|TunnelID=0|MonitorTag=|ParentSessionID=0|ParentStartTime=|TunnelType=N/A\"" tcpflood -m1 -M "\"<14>Sep 17 13:47:11 firewall.domain.local LEEF:1.0|Palo Alto Networks|PAN-OS Syslog Integration|11.1.6-h14|reset-both|cat=TRAFFIC|ReceiveTime=2025/09/17 13:47:10|SerialNumber=010108000243|Type=TRAFFIC|Subtype=deny|devTime=Sep 17 2025 11:47:10 GMT|src=172.35.163.110|dst=172.42.1.234|srcPostNAT=0.0.0.157|dstPostNAT=0.0.0.157|RuleName=interzone-default|usrName=|SourceUser=|DestinationUser=|Application=ssl|VirtualSystem=vsys7|SourceZone=client-vpn|DestinationZone=gdcbb|IngressInterface=zz8.1083|EgressInterface=zz8.1001|LogForwardingProfile=default|SessionID=336519782|RepeatCount=1|srcPort=61567|dstPort=9997|srcPostNATPort=0|dstPostNATPort=0|Flags=0x100400|proto=tcp|action=reset-both|totalBytes=6689|dstBytes=5964|srcBytes=725|totalPackets=14|StartTime=2025/09/17 13:47:10|ElapsedTime=0|URLCategory=any|sequence=7548134123908109690|ActionFlags=0x8000000000000000|SourceLocation=172.0.0.20-172.255.255.1|DestinationLocation=172.0.0.20-172.255.255.1|dstPackets=7|srcPackets=7|SessionEndReason=policy-deny|DeviceGroupHierarchyL1=177|DeviceGroupHierarchyL2=235|DeviceGroupHierarchyL3=48936|DeviceGroupHierarchyL4=36126|vSrcName=firewall.domain.local|DeviceName=firewall.domain.local|ActionSource=from-application|SrcUUID=|DstUUID=|TunnelID=0|MonitorTag=|ParentSessionID=0|ParentStartTime=|TunnelType=N/A\"" shutdown_when_empty wait_shutdown EXPECTED=$'Palo Alto Networks|11.1.6-h14|172.19.50.39|172.19.5.50|allow|TRAFFIC|tcp|74879677\nPalo Alto Networks|11.1.6-h14|172.39.129.169|172.224.141.39|deny|TRAFFIC|tcp|0\nPalo Alto Networks|11.1.6-h14|172.35.163.110|172.42.1.234|reset-both|TRAFFIC|tcp|336519782' cmp_exact if [ -s "$RSYSLOG2_OUT_LOG" ]; then echo "unexpected data in secondary output log:" cat "$RSYSLOG2_OUT_LOG" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream-consumerGroup-ack.sh0000644000000000000000000000013215055602574023110 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.042640511 30 ctime=1764935932.912725518 rsyslog-8.2512.0/tests/imhiredis-stream-consumerGroup-ack.sh0000775000175000017500000000304415055602574022560 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %$!msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mystream" mode="stream" stream.consumerGroup="mygroup" stream.consumerName="myName" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup redis_command "XADD mystream * msg message1" redis_command "XADD mystream * msg message2" redis_command "XADD mystream * msg message3" shutdown_when_empty wait_shutdown output="$(redis_command 'hello 3\nXINFO groups mystream' | grep 'pending')" if [ -z "$output" ]; then echo "Could not get group result from redis, cannot tell if entries ware acknowledged!" error_exit 1 fi if ! echo "$output" | grep -q "pending 0"; then echo "ERROR: entries werent acknowledged!" echo "ERROR: output from Redis is '$output'" echo "ERROR: expected 'pending 0'" error_exit 1 fi stop_redis content_check '1 message1' content_check '2 message2' content_check '3 message3' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/test_id.c0000644000000000000000000000013215055605325015500 xustar0030 mtime=1756826325.658800819 30 atime=1764931157.563584681 30 ctime=1764935931.946710731 rsyslog-8.2512.0/tests/test_id.c0000664000175000017500000000156315055605325015151 0ustar00rgerrger#include #include #include #include /* one provided by Aaaron Wiebe based on perl's hashing algorithm * (so probably pretty generic). Not for excessively large strings! */ #if defined(__clang__) #pragma GCC diagnostic ignored "-Wunknown-attributes" #endif static unsigned __attribute__((nonnull(1))) int #if defined(__clang__) __attribute__((no_sanitize("unsigned-integer-overflow"))) #endif hash_from_string(void *k) { char *rkey = (char *)k; unsigned hashval = 1; while (*rkey) hashval = hashval * 33 + *rkey++; return hashval; } int main(int argc, char *argv[]) { struct timeval tv; gettimeofday(&tv, NULL); if (argc != 2) { fprintf(stderr, "usage: test_id test-file-name\n"); exit(1); } printf("%06ld_%4.4x", tv.tv_usec, hash_from_string(argv[1])); return 0; } rsyslog-8.2512.0/tests/PaxHeaders/dynfile_invalid2.sh0000644000000000000000000000013215055602574017462 xustar0030 mtime=1756824956.027451414 30 atime=1764931166.304724882 30 ctime=1764935934.435748831 rsyslog-8.2512.0/tests/dynfile_invalid2.sh0000775000175000017500000000367515055602574017144 0ustar00rgerrger#!/bin/bash # This test checks if omfile segfaults when a file open() in dynacache mode fails. # The test is mimiced after a real-life scenario (which, of course, was much more # complex). # # added 2010-03-22 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:3%\n" $template dynfile,"%msg:F,58:2%.log" # complete name is in message $OMFileFlushOnTXEnd off $DynaFileCacheSize 4 $omfileFlushInterval 1 local0.* ?dynfile;outfmt ' startup # we send handcrafted message. We have a dynafile cache of 4, and now send one message # each to fill up the cache. tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:0\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:3\"" # the next one has caused a segfault in practice # note that /proc/rsyslog.error.file must not be creatable tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:/proc/rsyslog.error.file:boom\"" # some more writes tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.0.log:4\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.1.log:5\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.2.log:6\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag msg:$RSYSLOG_DYNNAME.out.3.log:7\"" # done message generation shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate cat $RSYSLOG_DYNNAME.out.*.log > $RSYSLOG_OUT_LOG seq_check 0 7 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-retry-metadata-vg.sh0000644000000000000000000000013215055603742022163 xustar0030 mtime=1756825570.302069124 30 atime=1764931164.960703341 30 ctime=1764935934.028742601 rsyslog-8.2512.0/tests/omhttp-batch-retry-metadata-vg.sh0000775000175000017500000000013115055603742021625 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-batch-retry-metadata.sh rsyslog-8.2512.0/tests/PaxHeaders/imrelp-basic-hup.sh0000644000000000000000000000013015035412264017370 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.010688111 29 ctime=1764935933.76473856 rsyslog-8.2512.0/tests/imrelp-basic-hup.sh0000775000175000017500000000121515035412264017040 0ustar00rgerrger#!/bin/bash # added 2019-07-30 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=4000 # MUST be an even number! generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") input(type="imrelp" port="'$TCPFLOOD_PORT'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) issue_HUP tcpflood -Trelp-plain -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2)) shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_gtls_servercert_ossl_clientanon.sh0000644000000000000000000000013215035412264025161 xustar0030 mtime=1752569012.414653468 30 atime=1764931168.436759042 30 ctime=1764935935.042758123 rsyslog-8.2512.0/tests/sndrcv_tls_gtls_servercert_ossl_clientanon.sh0000775000175000017500000000352715035412264024637 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" ) # Note: no TLS for the listener, this is for tcpflood! module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/certvalid" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/linkedlistqueue.sh0000644000000000000000000000013215055602574017447 xustar0030 mtime=1756824956.032451484 30 atime=1764931162.725667506 30 ctime=1764935933.388732805 rsyslog-8.2512.0/tests/linkedlistqueue.sh0000775000175000017500000000114315055602574017115 0ustar00rgerrger#!/bin/bash # Test for Linkedlist queue mode # added 2009-05-20 by rgerhards # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=40000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' # set spool locations and switch queue to disk-only mode $MainMsgQueueType LinkedList $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/no-dynstats-json.sh0000644000000000000000000000013115055602574017471 xustar0030 mtime=1756824956.033451498 30 atime=1764931167.262740233 29 ctime=1764935934.70875301 rsyslog-8.2512.0/tests/no-dynstats-json.sh0000775000175000017500000000166715055602574017153 0ustar00rgerrger#!/bin/bash # added 2016-03-10 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[no-dynstats-json.sh\]: test for verifying stats are reported correctly in json format in absence of any dynstats buckets being configured . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown custom_content_check '{ "name": "global", "origin": "dynstats", "values": { } }' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_privdropuser.sh0000644000000000000000000000013215055602574020552 xustar0030 mtime=1756824956.038451568 30 atime=1764931161.216643303 30 ctime=1764935932.964726314 rsyslog-8.2512.0/tests/rscript_privdropuser.sh0000775000175000017500000000113015055602574020214 0ustar00rgerrger#!/bin/bash # added 2021-09-23 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.user.name="'${TESTBENCH_TESTUSER[username]}'") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-template.sh0000644000000000000000000000013115035412264017167 xustar0030 mtime=1752569012.407702108 29 atime=1764931168.67076279 30 ctime=1764935935.106759102 rsyslog-8.2512.0/tests/pgsql-template.sh0000775000175000017500000000166515035412264016647 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' # putting the message in the SyslogTag field, so we know the template is actually used $template mytemplate,"insert into SystemEvents (SysLogTag) values ' add_conf "('%msg%')" add_conf '",STDSQL $ModLoad ../plugins/ompgsql/.libs/ompgsql :msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench;mytemplate ' startup injectmsg 0 5000 shutdown_when_empty wait_shutdown # we actually put the message in the SysLogTag field, so we know it doesn't use the default # template, like in pgsql-basic psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/libdbi-asyn.sh0000644000000000000000000000013215035412264016426 xustar0030 mtime=1752569012.398764645 30 atime=1764931166.648730395 30 ctime=1764935934.537750392 rsyslog-8.2512.0/tests/libdbi-asyn.sh0000775000175000017500000000134415035412264016077 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 # this test is veeeeery slow, value is a compromise generate_conf add_conf ' $ModLoad ../plugins/omlibdbi/.libs/omlibdbi $ActionQueueType LinkedList $ActionQueueTimeoutEnqueue 15000 $ActionLibdbiDriver mysql $ActionLibdbiHost 127.0.0.1 $ActionLibdbiUserName rsyslog $ActionLibdbiPassword testbench $ActionLibdbiDBName '$RSYSLOG_DYNNAME' :msg, contains, "msgnum:" { :omlibdbi: action(type="omfile" file="'$RSYSLOG_DYNNAME'.syncfile") } ' mysql_prep_for_test startup injectmsg wait_file_lines $RSYSLOG_DYNNAME.syncfile $NUMMESSAGES 2500 shutdown_when_empty wait_shutdown mysql_get_data seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-wildcards-dirs-multi5.sh0000644000000000000000000000013215055602574021633 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.112721805 30 ctime=1764935934.373747882 rsyslog-8.2512.0/tests/imfile-wildcards-dirs-multi5.sh0000775000175000017500000000526115055602574021306 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . ${srcdir:=.}/diag.sh init export IMFILEINPUTFILES="8" #"8" export IMFILEINPUTFILESSTEPS="5" #"5" #export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS)) export IMFILECHECKTIMEOUT="60" # Start rsyslog now before adding more files mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global( workDirectory="./'"$RSYSLOG_DYNNAME"'.work" debug.whitelist="on" debug.files=["imfile.c"]) module(load="../plugins/imfile/.libs/imfile" mode="inotify" pollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.dir?/*/*.logfile" Tag="file:" Severity="error" Facility="local7" addMetadata="on") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.alt/alt*file" Tag="file:" Severity="error" Facility="local7" addMetadata="on") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="'"'"', ") property(name="$!metadata!filename") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") #*.* action(type="omfile" file="rsyslog.debug") ' # create first directory and file before startup, so ensure we will NOT # get an initial inotify notify for it! mkdir $RSYSLOG_DYNNAME.input.alt #./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.alt/altfile.logfile mkdir $RSYSLOG_DYNNAME.input.dir1 # the following is INVALID, as this is a file, but must be a directory! ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir0 startup for j in $(seq 1 $IMFILEINPUTFILESSTEPS); do echo "Loop Num $j" for i in $(seq 1 $IMFILEINPUTFILES); do mkdir $RSYSLOG_DYNNAME.input.dir$i mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$i touch $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile done ls -d $RSYSLOG_DYNNAME.input.* # Check correct amount of input files each time IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j)) content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT # Delete all but first! for i in $(seq 1 $IMFILEINPUTFILES); do # slow systems (NFS) do not reliably do rm -r (unfortunately...) rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i/file.logfile ./msleep 100 rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$i ./msleep 100 rm -vrf $RSYSLOG_DYNNAME.input.dir$i done # Helps in testbench parallel mode. # Otherwise sometimes directories are not marked deleted in imfile before they get created again. # This is properly a real issue in imfile when FILE IO is high. ./msleep 1000 done shutdown_when_empty wait_shutdown #echo rsyslog.debug: #cat rsyslog.debug exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnull-basic.sh0000644000000000000000000000013215035412264016617 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.794652574 30 ctime=1764935933.131728871 rsyslog-8.2512.0/tests/pmnull-basic.sh0000775000175000017500000000224415035412264016270 0ustar00rgerrger#!/bin/bash # add 2016-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/pmnull/.libs/pmnull") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") parser(name="custom.pmnull.withOrigin" type="pmnull") template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n") ruleset(name="ruleset" parser=["custom.pmnull.withOrigin", "rsyslog.pmnull"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test") } ' startup tcpflood -m1 -M "\"<189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\"" shutdown_when_empty wait_shutdown echo 'tag: , pri: 13, syslogfacility: 1, syslogseverity: 5 msg: <189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/msleep_usage_output.sh0000644000000000000000000000013215035412264020322 xustar0030 mtime=1752569012.402736851 30 atime=1764931160.194626906 30 ctime=1764935932.671721829 rsyslog-8.2512.0/tests/msleep_usage_output.sh0000775000175000017500000000042115035412264017766 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./msleep &> $RSYSLOG_DYNNAME.output grep "usage: msleep" $RSYSLOG_DYNNAME.output if [ ! $? -eq 0 ]; then echo "invalid response generated" error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-rule_and_rulebase.sh0000644000000000000000000000013215035412264022237 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.876653889 30 ctime=1764935933.154729222 rsyslog-8.2512.0/tests/pmnormalize-rule_and_rulebase.sh0000775000175000017500000000064615035412264021714 0ustar00rgerrger#!/bin/bash # add 2019-04-10 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/pmnormalize/.libs/pmnormalize") parser(name="custom.pmnormalize" type="pmnormalize" rule="" rulebase="") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "pmnormalize:.*you need to specify one of" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omusrmsg-noabort.sh0000644000000000000000000000013215055603742017554 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.682634736 30 ctime=1764935932.808723926 rsyslog-8.2512.0/tests/omusrmsg-noabort.sh0000775000175000017500000000131315055603742017221 0ustar00rgerrger#!/bin/bash # same as omusrmsg-noabort, but with legacy syntax. # addd 2018-08-05 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" { action(type="omusrmsg" users="nouser" template="outfmt") action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' startup injectmsg shutdown_when_empty wait_shutdown # while we cannot check if the messages arrived in user sessions, we # can check that all messages arrive in the file, which we consider as # an indication that everything went well. seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-numstr-vg.sh0000644000000000000000000000013215055602574023004 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.613617584 30 ctime=1764935932.523719564 rsyslog-8.2512.0/tests/rscript_compare_numstr-numstr-vg.sh0000775000175000017500000000020315055602574022446 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='"1"' export HIGHER_VAL='"2"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/dynstats_reset-vg.sh0000644000000000000000000000013115055602574017724 xustar0030 mtime=1756824956.027451414 30 atime=1764931167.139738263 29 ctime=1764935934.67475249 rsyslog-8.2512.0/tests/dynstats_reset-vg.sh0000775000175000017500000000443315055602574017400 0ustar00rgerrger#!/bin/bash # added 2015-11-13 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[dynstats_reset-vg.sh\]: test for gathering stats with a known-dyn-metrics reset in-between . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on") template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n") dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off") set $.msg_prefix = field($msg, 32, 1); if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then { set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix); } else { set $.increment_successful = -1; } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log injectmsg_file $srcdir/testsuites/dynstats_input_1 rst_msleep 8100 #two seconds for unused-metrics to be kept under observation, another two them to be cleared off injectmsg_file $srcdir/testsuites/dynstats_input_2 rst_msleep 8100 injectmsg_file $srcdir/testsuites/dynstats_input_3 rst_msleep 8100 wait_queueempty content_check "foo 001 0" content_check "bar 002 0" content_check "baz 003 0" content_check "foo 004 0" content_check "baz 005 0" content_check "foo 006 0" echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg # because dyn-metrics would be reset before it can accumulate and report high counts, sleep between msg-injection ensures that custom_assert_content_missing 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing 'foo=2' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log" # but actual reported stats (aggregate) should match first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1 first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2 exit_test rsyslog-8.2512.0/tests/PaxHeaders/incltest_dir_empty_wildcard.sh0000644000000000000000000000013215035412264022003 xustar0030 mtime=1752569012.397771593 30 atime=1764931162.322661043 30 ctime=1764935933.278731121 rsyslog-8.2512.0/tests/incltest_dir_empty_wildcard.sh0000775000175000017500000000117315035412264021454 0ustar00rgerrger#!/bin/bash # This test checks if an empty includeConfig directory causes problems. It # should not, as this is a valid situation that by default exists on many # distros. . ${srcdir:=.}/diag.sh init generate_conf add_conf "\$IncludeConfig ${srcdir}/testsuites/incltest.d/*.conf-not-there " add_conf '$template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")' startup # 100 messages are enough - the question is if the include is read ;) injectmsg 0 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_no_params-vg.sh0000644000000000000000000000013115035412264023123 xustar0030 mtime=1752569012.390820233 29 atime=1764931158.17959457 30 ctime=1764935932.117713348 rsyslog-8.2512.0/tests/imbatchreport_errmsg_no_params-vg.sh0000775000175000017500000000023715035412264022575 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/imbatchreport_errmsg_no_params.sh rsyslog-8.2512.0/tests/PaxHeaders/failover-rptd-vg.sh0000644000000000000000000000013215035412264017421 xustar0030 mtime=1752569012.389827181 30 atime=1764931163.732683653 30 ctime=1764935933.682737305 rsyslog-8.2512.0/tests/failover-rptd-vg.sh0000775000175000017500000000140615035412264017071 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi echo =============================================================================== echo \[failover-rptd.sh\]: rptd test for failover functionality . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $RepeatedMsgReduction on $template outfmt,"%msg:F,58:2%\n" # note: the target server shall not be available! :msg, contains, "msgnum:" @@127.0.0.1:13514 $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"';outfmt ' startup_vg injectmsg 0 5000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_str2num_negative.sh0000644000000000000000000000013215035412264021273 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.833621114 30 ctime=1764935932.572720313 rsyslog-8.2512.0/tests/rscript_str2num_negative.sh0000775000175000017500000000123015035412264020736 0ustar00rgerrger#!/bin/bash # add 2017-02-09 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.n = "-1"; set $!ip!v1 = 1 + $.n; template(name="outfmt" type="string" string="%!ip%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 shutdown_when_empty wait_shutdown echo '{ "v1": 0 }' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid function output detected, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_traillf_syssock.sh0000644000000000000000000000013215055602574021375 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.574729209 30 ctime=1764935934.516750071 rsyslog-8.2512.0/tests/imuxsock_traillf_syssock.sh0000775000175000017500000000142315055602574021044 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test does not work on Solaris" ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" SysSock.name="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup ./syslog_caller -fsyslog_inject-l -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" shutdown_when_empty wait_shutdown export EXPECTED=" test" cmp_exact rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse3.sh0000644000000000000000000000013115035412264017617 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.945606864 29 ctime=1764935932.33271664 rsyslog-8.2512.0/tests/parsertest-parse3.sh0000775000175000017500000000214415035412264017270 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%timereported:1:19:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9]+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<175>Oct 16 2009 23:47:31 hostname tag This is a message\"" tcpflood -m1 -M "\"<175>Oct 16 2009 23:47:31 hostname tag[1234] This is a message\"" shutdown_when_empty wait_shutdown echo '"2009-10-16T23:47:31", "hostname", "tag", "", "7", " This is a message" "2009-10-16T23:47:31", "hostname", "tag", "1234", "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-basic-verifydepth.sh0000644000000000000000000000013115035412264021552 xustar0030 mtime=1752569012.396778542 30 atime=1764931163.060672878 29 ctime=1764935933.48773432 rsyslog-8.2512.0/tests/imtcp-tls-basic-verifydepth.sh0000775000175000017500000000200015035412264021212 0ustar00rgerrger#!/bin/bash # added 2011-02-28 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.TlsVerifyDepth="5" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' # Begin actual testcase startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmutf8fix_no_error.sh0000644000000000000000000000013215035412264020065 xustar0030 mtime=1752569012.401743799 30 atime=1764931160.177626633 30 ctime=1764935932.666721753 rsyslog-8.2512.0/tests/mmutf8fix_no_error.sh0000775000175000017500000001407315035412264017541 0ustar00rgerrger#!/bin/bash # add 2018-10-10 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmutf8fix/.libs/mmutf8fix") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmutf8fix" replacementChar="?") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: this is a test message <129>Mar 10 01:00:00 172.20.245.8 tag: valid mixed length UTF-8: foo bar řÃꙀ䆑ðŒ°ðž¨ <129>Mar 10 01:00:00 172.20.245.8 tag: valid 2-byte UTF-8: řà <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x00) 0xC0 0x80: À€ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x2E) 0xC0 0xAE: À® <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong = 0x4E) 0xC1 0x8E: ÁŽ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation) 0xC0 0xEE: Àî <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0x2E: À. <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0xC2 0xA7: À§ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (overlong, not enough bytes) 0xC0: À <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation) 0xC2 0xEE: Âî <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0x2E: Â. <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0xC2 0xA7: § <129>Mar 10 01:00:00 172.20.245.8 tag: valid 3-byte UTF-8: Ꙁ䆑 <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (overlong = 0x2E) 0xE0 0x80 0xAE: à€® <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (overlong = 0x2E0) 0xE0 0x8B 0xA0: à‹  <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation) 0xE0 0xE2 0x81: àâ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0x41 0xA7: àA§ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0xC2 0xA7: à§ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation) 0xE1 0x85 0xE1: á…á <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0x41: á…A <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0xD5 0xB6: á…Õ¶ <129>Mar 10 01:00:00 172.20.245.8 tag: valid 4-byte UTF-8: ðŒ°ðž¨ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E) 0xF0 0x80 0x80 0xAE: ð€€® <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E0) 0xF0 0x80 0x8B 0xA0: ð€‹  <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (overlong = 0x2E00) 0xF0 0x82 0xB8 0x80: ð‚¸€ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0x41 0xC5 0xB0: ðAŰ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0xEC 0x8C 0xB0: ð쌰 <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xF0 0x90 0xC5 0xB0: ðŰ <129>Mar 10 01:00:00 172.20.245.8 tag: invalid 4-byte UTF-8 (invalid 4rd continuation but valid utf8) 0xF0 0x90 0xC5 0x2E: ðŒ. <129>Mar 10 01:00:00 172.20.245.8 tag: special characters: ??%%,,.. <129>Mar 10 01:00:00 172.20.245.8 tag: numbers: 1234567890\"" shutdown_when_empty wait_shutdown echo ' this is a test message valid mixed length UTF-8: foo bar řÃꙀ䆑ðŒ°ðž¨ valid 2-byte UTF-8: řà invalid 2-byte UTF-8 (overlong = 0x00) 0xC0 0x80: ?? invalid 2-byte UTF-8 (overlong = 0x2E) 0xC0 0xAE: ?? invalid 2-byte UTF-8 (overlong = 0x4E) 0xC1 0x8E: ?? invalid 2-byte UTF-8 (overlong, invalid continuation) 0xC0 0xEE: ?? invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0x2E: ?. invalid 2-byte UTF-8 (overlong, invalid continuation but valid utf8) 0xC0 0xC2 0xA7: ?§ invalid 2-byte UTF-8 (overlong, not enough bytes) 0xC0: ? invalid 2-byte UTF-8 (invalid continuation) 0xC2 0xEE: ?? invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0x2E: ?. invalid 2-byte UTF-8 (invalid continuation but valid utf8) 0xC2 0xC2 0xA7: ?§ valid 3-byte UTF-8: Ꙁ䆑 invalid 3-byte UTF-8 (overlong = 0x2E) 0xE0 0x80 0xAE: ??? invalid 3-byte UTF-8 (overlong = 0x2E0) 0xE0 0x8B 0xA0: ??? invalid 3-byte UTF-8 (invalid 2nd continuation) 0xE0 0xE2 0x81: ??? invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0x41 0xA7: ?A? invalid 3-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xE0 0xC2 0xA7: ?§ invalid 3-byte UTF-8 (invalid 3rd continuation) 0xE1 0x85 0xE1: ??? invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0x41: ??A invalid 3-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xE1 0x85 0xD5 0xB6: ??Õ¶ valid 4-byte UTF-8: ðŒ°ðž¨ invalid 4-byte UTF-8 (overlong = 0x2E) 0xF0 0x80 0x80 0xAE: ???? invalid 4-byte UTF-8 (overlong = 0x2E0) 0xF0 0x80 0x8B 0xA0: ???? invalid 4-byte UTF-8 (overlong = 0x2E00) 0xF0 0x82 0xB8 0x80: ???? invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0x41 0xC5 0xB0: ?AŰ invalid 4-byte UTF-8 (invalid 2nd continuation but valid utf8) 0xF0 0xEC 0x8C 0xB0: ?쌰 invalid 4-byte UTF-8 (invalid 3rd continuation but valid utf8) 0xF0 0x90 0xC5 0xB0: ??Ű invalid 4-byte UTF-8 (invalid 4rd continuation but valid utf8) 0xF0 0x90 0xC5 0x2E: ???. special characters: ??%%,,.. numbers: 1234567890' > "$RSYSLOG_OUT_LOG.expect" if ! cmp "$RSYSLOG_OUT_LOG.expect" $RSYSLOG_OUT_LOG; then echo "invalid response generated, $RSYSLOG_OUT_LOG diff:" # Use LANG=C for binary matching LANG=C diff --text -u "$RSYSLOG_OUT_LOG.expect" $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test exit 0 rsyslog-8.2512.0/tests/PaxHeaders/imfile-file-not-found-error.sh0000644000000000000000000000013215035412264021451 xustar0030 mtime=1752569012.391813284 30 atime=1764931165.813717013 30 ctime=1764935934.281746474 rsyslog-8.2512.0/tests/imfile-file-not-found-error.sh0000775000175000017500000000223115035412264021116 0ustar00rgerrger#!/bin/bash # add 2017-04-28 by Pascal Withopf, released under ASL 2.0 echo [imfile-file-not-found-error.sh] . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1") template(name="tmpl1" type="string" string="%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) ' startup ./msleep 2000 echo 'testmessage1 testmessage2 testmessage3' > $RSYSLOG_DYNNAME.input ./msleep 2000 shutdown_when_empty wait_shutdown grep "file.*$RSYSLOG_DYNNAME.input.*No such file or directory" ${RSYSLOG2_OUT_LOG} > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi printf 'testmessage1 testmessage2 testmessage3\n' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_privdropgroupid.sh0000644000000000000000000000013215055602574021245 xustar0030 mtime=1756824956.038451568 30 atime=1764931161.241643704 30 ctime=1764935932.971726421 rsyslog-8.2512.0/tests/rscript_privdropgroupid.sh0000775000175000017500000000117015055602574020713 0ustar00rgerrger#!/bin/bash # added 2021-09-23 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.group.keepsupplemental="on" privdrop.group.id="'${TESTBENCH_TESTUSER[gid]}'") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-queue-vg.sh0000644000000000000000000000013215055602574017751 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.934638779 30 ctime=1764935932.880725028 rsyslog-8.2512.0/tests/imhiredis-queue-vg.sh0000775000175000017500000000030015055602574017411 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-queue.sh rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-large.sh0000644000000000000000000000013215055602574021247 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.679698836 30 ctime=1764935933.951741423 rsyslog-8.2512.0/tests/imhttp-post-payload-large.sh0000775000175000017500000000224115055602574020715 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf IMHTTP_PORT="$(get_free_port)" add_conf ' #template(name="outfmt" type="string" string="%msg%\n") template(name="outfmt" type="string" string="%rawmsg%\n") module(load="../contrib/imhttp/.libs/imhttp" ports="'$IMHTTP_PORT'") input(type="imhttp" endpoint="/postrequest" ruleset="ruleset") ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup NUMMESSAGES=25 DATA_SOURCE=$srcdir/testsuites/imhttp-large-data.txt for (( i=1; i<=NUMMESSAGES; i++ )) do curl -si -X POST -H Content-Type:application/json http://localhost:$IMHTTP_PORT/postrequest --data-binary @$DATA_SOURCE & pids[${i}]=$! done # wait for all pids for pid in ${pids[*]}; do wait $pid # echo "$pid cleaned up" done sleep 2 wait_queueempty echo "doing shutdown" shutdown_when_empty wait_shutdown # reference file for comparison TMPFILE=${RSYSLOG_DYNNAME}.tmp for (( i=1; i <= NUMMESSAGES; i++ )) do cat $DATA_SOURCE >> $TMPFILE done if diff -q $TMPFILE $RSYSLOG_OUT_LOG; then echo "files match!" exit_test else error_exit 1 fi rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh0000644000000000000000000000013115035412264025156 xustar0029 mtime=1752569012.41564652 30 atime=1764931168.428758914 30 ctime=1764935935.040758092 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_serveranon_gtls_clientanon.sh0000775000175000017500000000351615035412264024633 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" ) # Note: no TLS for the listener, this is for tcpflood! module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="anon" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp-basic-hup.sh0000644000000000000000000000013215035412264017376 xustar0030 mtime=1752569012.394792439 30 atime=1764931163.399678314 30 ctime=1764935933.587735851 rsyslog-8.2512.0/tests/imptcp-basic-hup.sh0000775000175000017500000000131315035412264017043 0ustar00rgerrger#!/bin/bash # added 2019-07-30 by RGerhards, released under ASL 2.0 export NUMMESSAGES=4000 # MUST be an even number! . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) issue_HUP tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2)) shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_stop2.sh0000644000000000000000000000013215035412264017046 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.353613411 30 ctime=1764935932.451718461 rsyslog-8.2512.0/tests/rscript_stop2.sh0000775000175000017500000000166515035412264016525 0ustar00rgerrger#!/bin/bash # added 2012-09-20 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_stop2.sh\]: testing rainerscript STOP statement, alternate method . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } if not ($msg contains "msgnum") then stop set $!usr!msgnum = field($msg, 58, 2); if cnum($!usr!msgnum) >= 5000 then stop /* We could use yet another method, but we like to have the action statement * without a filter in rsyslog.conf top level hierarchy - so this test, as * a side-effect, also tests this ability. */ action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg 0 8000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-basic-vg.sh0000644000000000000000000000013215035412264017235 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.026704399 30 ctime=1764935934.047742892 rsyslog-8.2512.0/tests/omhttp-basic-vg.sh0000775000175000017500000000011215035412264016676 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_object.sh0000644000000000000000000000013215055602574021334 xustar0030 mtime=1756824956.039451582 30 atime=1764931159.969623296 30 ctime=1764935932.607720849 rsyslog-8.2512.0/tests/rscript_unflatten_object.sh0000775000175000017500000000267015055602574021010 0ustar00rgerrger#!/bin/bash # added 2020-08-16 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init #export RSYSLOG_DEBUG="debug nostdout" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $!source.ip = "1.2.3.4"; set $!source.bytes = 3258; set $!source.geo.country_iso_code = "FR"; set $!destination.ip = "4.3.2.1"; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 3 wait_file_lines "$RSYSLOG_OUT_LOG" 3 60 shutdown_when_empty wait_shutdown # this test may need changes to produce a more deterministic # output by sorting keys EXPECTED=' msgnum:00000000: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } } msgnum:00000001: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } } msgnum:00000002: 0 { "source": { "ip": "1.2.3.4", "bytes": 3258, "geo": { "country_iso_code": "FR" } }, "destination": { "ip": "4.3.2.1" } }' cmp_exact "$RSYSLOG_OUT_LOG" exit_test rsyslog-8.2512.0/tests/PaxHeaders/multiple_lookup_tables-vg.sh0000644000000000000000000000013215035412264021421 xustar0030 mtime=1752569012.402736851 30 atime=1764931167.913750664 30 ctime=1764935934.893755842 rsyslog-8.2512.0/tests/multiple_lookup_tables-vg.sh0000775000175000017500000000027415035412264021073 0ustar00rgerrger#!/bin/bash # added 2016-01-20 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/multiple_lookup_tables.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_failover.sh0000644000000000000000000000013215055602574017426 xustar0030 mtime=1756824956.039451582 30 atime=1764931163.977687582 30 ctime=1764935933.755738422 rsyslog-8.2512.0/tests/sndrcv_failover.sh0000775000175000017500000000426315055602574017102 0ustar00rgerrger#!/bin/bash # This tests failover capabilities. Data is sent to a local port, where # no process shall listen. Then it fails over to a second instance, then to # a file. The second instance is started. So all data should be received # there and none be logged to the file. # This builds on the basic sndrcv.sh test, but adds a first, failing, # location to the conf file. # added 2011-06-20 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines export DEAD_PORT=4 # a port unassigned by IANA and very unlikely to be used export RSYSLOG_DEBUGLOG="log" # uncomment for debugging support: # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' # then SENDER sends to this port (not tcpflood!) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" export PORT_RCVR=$TCPFLOOD_PORT generate_conf 2 add_conf ' *.* @@127.0.0.1:'$DEAD_PORT' # this must be DEAD $ActionExecOnlyWhenPreviousIsSuspended on & @@127.0.0.1:'$PORT_RCVR' & ./'${RSYSLOG_DYNNAME}'.empty $ActionExecOnlyWhenPreviousIsSuspended off ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # do the final check seq_check ls -l ${RSYSLOG_DYNNAME}.empty if [[ -s ${RSYSLOG_DYNNAME}.empty ]] ; then echo "FAIL: ${RSYSLOG_DYNNAME}.empty has data. Failover handling failed. Data is written" echo " even though the previous action (in a failover chain!) properly" echo " worked." error_exit 1 else echo "${RSYSLOG_DYNNAME}.empty is empty - OK" fi ; exit_test rsyslog-8.2512.0/tests/PaxHeaders/hostname-with-slash-dflt-slash-valid.sh0000644000000000000000000000013215035412264023264 xustar0030 mtime=1752569012.390820233 30 atime=1764931157.920590412 30 ctime=1764935932.045712246 rsyslog-8.2512.0/tests/hostname-with-slash-dflt-slash-valid.sh0000775000175000017500000000165315035412264022740 0ustar00rgerrger#!/bin/bash # addd 2016-07-11 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%hostname%\n") # note: we use the default parser chain, which includes RFC5424 and that parser # should be selected AND detect the hostname with slashes as valid. local4.debug action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup echo '<167>1 2003-03-01T01:00:00.000Z hostname1/hostname2 tcpflood - tag [tcpflood@32473 MSGNUM="0"] data' > $RSYSLOG_DYNNAME.input tcpflood -B -I $RSYSLOG_DYNNAME.input shutdown_when_empty wait_shutdown echo "hostname1/hostname2" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid hostname generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_with_debug.sh0000644000000000000000000000013215055602574017726 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.228627452 30 ctime=1764935932.680721967 rsyslog-8.2512.0/tests/mmanon_with_debug.sh0000775000175000017500000000515615055602574017404 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on all flavors of Solaris." export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" mode="zero" ipv4.bits="32") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: before 172.9.6.4 <129>Mar 10 01:00:00 172.20.245.8 tag: 75.123.123.0 after <129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after <129>Mar 10 01:00:00 172.20.245.8 tag: nothingnothingnothing <129>Mar 10 01:00:00 172.20.245.8 tag: before 181.23.1.4 after 172.1.3.4 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.9 <129>Mar 10 01:00:00 172.20.245.8 tag: 0.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.2.3.4.5.6.7.8.76 <129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.225.225.225 <129>Mar 10 01:00:00 172.20.245.8 tag: 172.0.234.255 <129>Mar 10 01:00:00 172.20.245.8 tag: 3.4.5.6 <129>Mar 10 01:00:00 172.20.245.8 tag: 256.0.0.0 <129>Mar 10 01:00:00 172.20.245.8 tag: 1....1....1....8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1..1..1..8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1..1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1..1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1..8 <129>Mar 10 01:00:00 172.20.245.8 tag: 1111.1.1.8.1 <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8.1 <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8. <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank1.1.1.9stillnoblank\"" shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk before 0.0.0.0 0.0.0.0 after before 0.0.0.0 after nothingnothingnothing before 0.0.0.0 after 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0.0.0.0.0.76 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 20.0.0.0 1....1....1....8 1..1..1..8 1..1.1.8 1.1..1.8 1.1.1..8 10.0.0.0.1 0.0.0.0.1 0.0.0.0. textnoblank0.0.0.0stillnoblank' cmp_exact if [ ! -e "$RSYSLOG_DEBUGLOG" ]; then echo "error: file '$RSYSLOG_DEBUGLOG' (Debuglog) not found (should be generated)" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile-subtree-jsonf.sh0000644000000000000000000000013215103346332020266 xustar0030 mtime=1762512090.634176013 30 atime=1764931160.581633115 30 ctime=1764935932.778723467 rsyslog-8.2512.0/tests/omfile-subtree-jsonf.sh0000775000175000017500000000231515103346332017736 0ustar00rgerrger#!/bin/bash # Validate that subtree templates provide data to jsonf list templates unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 template(name="eventSubtree" type="subtree" subtree="$!event") template(name="jsonfList" type="list" option.jsonf="on") { property(outname="message" name="$.payload" format="jsonf") } if $msg contains "msgnum:" then { set $!event!level = "error"; set $!event!code = 500; set $.payload = exec_template("eventSubtree"); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="jsonfList") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown python3 - "$RSYSLOG_OUT_LOG" <<'PY' import json import sys with open(sys.argv[1], 'r', encoding='utf-8') as fh: payload = json.load(fh) expected_message = '{ "level": "error", "code": 500 }' if payload.get("message") != expected_message: print('invalid JSON generated') print('################# actual JSON is:') print(json.dumps(payload, indent=2, sort_keys=True)) print('################# expected JSON was:') print(json.dumps({"message": expected_message}, indent=2, sort_keys=True)) sys.exit(1) PY exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp_conndrop_tls-vg.sh0000644000000000000000000000013115055602574020551 xustar0030 mtime=1756824956.032451484 29 atime=1764931163.62768197 30 ctime=1764935933.653736861 rsyslog-8.2512.0/tests/imtcp_conndrop_tls-vg.sh0000775000175000017500000000035515055602574020224 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" export TB_TEST_MAX_RUNTIME=1500 export NUMMESSAGES=10000 # reduce for slower valgrind run source ${srcdir:-.}/imtcp_conndrop_tls.sh rsyslog-8.2512.0/tests/PaxHeaders/array_lookup_table.sh0000644000000000000000000000013215035412264020107 xustar0030 mtime=1752569012.384861924 30 atime=1764931167.880750135 30 ctime=1764935934.884755704 rsyslog-8.2512.0/tests/array_lookup_table.sh0000775000175000017500000000335215035412264017561 0ustar00rgerrger#!/bin/bash # test for array lookup-table and HUP based reloading of it # added 2015-10-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate_array.lkp_tbl") template(name="outfmt" type="string" string="%msg% %$.lkp%\n") set $.num = field($msg, 58, 2); set $.lkp = lookup("xlate", $.num); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate_array.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl startup injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_array_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: bar_new" content_check "msgnum:00000002: baz" cp -f $srcdir/testsuites/xlate_array_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 12 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: quux" content_check "msgnum:00000001: quux" content_check "msgnum:00000002: foo_latest" content_check "msgnum:00000003: baz_latest" content_check "msgnum:00000004: foo_latest" content_check "msgnum:00000005: foo_latest" content_check "msgnum:00000006: baz_latest" content_check "msgnum:00000007: foo_latest" content_check "msgnum:00000008: baz_latest" content_check "msgnum:00000009: baz_latest" content_check "msgnum:00000010: quux" content_check "msgnum:00000011: quux" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omazureeventhubs-list.sh0000644000000000000000000000013215071746523020620 xustar0030 mtime=1760021843.899421948 30 atime=1764931166.985735795 30 ctime=1764935934.631751831 rsyslog-8.2512.0/tests/omazureeventhubs-list.sh0000775000175000017500000001124215071746523020267 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 export NUMMESSAGESFULL=$NUMMESSAGES export WAITTIMEOUT=20 # REQUIRES EXTERNAL ENVIRONMENT VARIABLES if [[ -z "${AZURE_HOST}" ]]; then echo "SKIP: AZURE_HOST environment variable not SET! Example: .servicebus.windows.net - SKIPPING" exit 77 fi if [[ -z "${AZURE_PORT}" ]]; then echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY_NAME}" ]]; then echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY}" ]]; then echo "SKIP: AZURE_KEY environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_CONTAINER}" ]]; then echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: - SKIPPING" exit 77 fi export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME" export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME" # --- Create/Start omazureeventhubs sender config generate_conf add_conf ' # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") $imdiagInjectDelayMode full # Load mods module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs") # imtcp input( type="imtcp" port="0" ruleset="default" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # templates template(name="outfmt" type="string" string="%msg:F,58:2%\n") template(name="generic" type="list" option.jsonf="on") { property(outname="timestamp" name="timereported" dateFormat="rfc3339" format="jsonf") constant(value="\"source\": \"EventHubMessage\", ") property(outname="host" name="hostname" format="jsonf") property(outname="severity" name="syslogseverity" caseConversion="upper" format="jsonf" datatype="number") property(outname="facility" name="syslogfacility" format="jsonf" datatype="number") property(outname="appname" name="syslogtag" format="jsonf") property(outname="message" name="msg" format="jsonf" ) property(outname="etlsource" name="$myhostname" format="jsonf")} # ruleset ruleset(name="default") { if $msg contains "msgnum:" then { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") action(type="omfile" template="generic" file="'$RSYSLOG_OUT_LOG'-generic.log") action(name="omazureeventhubs" type="omazureeventhubs" azurehost="'$AZURE_HOST'" azureport="'$AZURE_PORT'" azure_key_name="'$AZURE_KEY_NAME'" azure_key="'$AZURE_KEY'" container="'$AZURE_CONTAINER'" template="generic" eventproperties=[ "Table=TestTable", "Format=JSON"] ) } else { action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") } stop } ' echo Starting sender instance [omazureeventhubs] startup echo Inject messages into rsyslog sender instance # injectmsg 1 $NUMMESSAGES tcpflood -m$NUMMESSAGES -i1 wait_file_lines $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100 # experimental: wait until kcat receives everything timeoutend=$WAITTIMEOUT timecounter=0 echo "CHECK $RSYSLOG_DYNNAME.pstats" while [ $timecounter -lt $timeoutend ]; do (( timecounter++ )) if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then # Read IMPSTATS for verification IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5) SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2) FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2) ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2) if ! [[ $SUBMITTED_MSG =~ $re ]] ; then echo "**** omazureeventhubs WAITING FOR IMPSTATS" else if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then if [ "$ACCEPTED_MSG" -eq "$NUMMESSAGESFULL" ]; then echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" shutdown_when_empty wait_shutdown #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log exit_test else echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" fi else echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" fi fi fi $TESTTOOL_DIR/msleep 1000 done unset count shutdown_when_empty wait_shutdown error_exit 1 rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-basic-stress.sh0000644000000000000000000000013215055603742021530 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.195675043 30 ctime=1764935933.528734947 rsyslog-8.2512.0/tests/imtcp-tls-ossl-basic-stress.sh0000775000175000017500000000301415055603742021175 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 # # List available valid OpenSSL Engines for defaultopensslengine with this command: # openssl engine -t # . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultopensslengine="rdrand" debug.whitelist="on" debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" gnutlsPriorityString="Protocol=-ALL,TLSv1.3,TLSv1.2 Ciphersuites=TLS_AES_256_GCM_SHA384 " ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # SignatureAlgorithms=RSA+SHA384 # Begin actual testcase startup tcpflood -p$TCPFLOOD_PORT -d8192 -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/threadingmq.sh0000644000000000000000000000013215035412264016534 xustar0030 mtime=1752569012.419618726 30 atime=1764931163.943687037 30 ctime=1764935933.745738269 rsyslog-8.2512.0/tests/threadingmq.sh0000775000175000017500000000235615035412264016211 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # we send 100,000 messages in the hopes that his puts at least a little bit # of pressure on the threading subsystem. To really prove it, we would need to # push messages for several minutes, but that takes too long during the # automated tests (hint: do this manually after suspect changes). Thankfully, # in practice many threading bugs result in an abort rather quickly and these # should be covered by this test here. # rgerhards, 2009-06-26 echo \[threadingmq.sh\]: main queue concurrency . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 1 #$MainMsgQueueTimeoutShutdown 100000 $MainMsgQueueWorkerThreadMinimumMessages 10 $MainMsgQueueWorkerThreads 5 $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! # write quickly to the output file: $OMFileFlushOnTXEnd off $OMFileIOBufferSize 256k :msg, contains, "msgnum:" ?dynfile;outfmt ' startup injectmsg 0 100000 shutdown_when_empty # shut down rsyslogd when done processing messages # we give an extra seconds for things to settle, especially # important on slower test machines ./msleep 5000 wait_shutdown seq_check 0 99999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmsnare-modoverride-udp.sh0000644000000000000000000000013215035412264021001 xustar0030 mtime=1752569012.408695159 30 atime=1764931168.587761461 30 ctime=1764935935.085758781 rsyslog-8.2512.0/tests/pmsnare-modoverride-udp.sh0000775000175000017500000001256615035412264020462 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/pmsnare/.libs/pmsnare") module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") global( parser.escapeControlCharactersOnReceive="off" parser.escapeControlCharacterTab="off" parser.escapeControlCharactersCStyle="on" parser.controlCharacterEscapePrefix="#" ) parser( name="modoverride.snare" type="pmsnare" parser.escapeControlCharactersOnReceive="on" parser.escapeControlCharacterTab="on" parser.escapeControlCharactersCStyle="off" parser.controlCharacterEscapePrefix="\\" ) template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1" parser=["modoverride.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\"" tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\"" tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\"" tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog\\\\0111\\\\011Security\\\\01100000000\\\\011Sun May 21 12:00:01.123\\\\0114624\\\\011Microsoft-Windows-Security-Auditing\\\\011N/A\\\\011N/A\\\\011Success Audit\\\\011hostname.domain\\\\011Logon\\\\011\\\\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\"" shutdown_when_empty wait_shutdown export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti 14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]}; 14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................ 14,user,info,MSWinEventLog,MSWinEventLog, 1\011Security\01100000000\011Sun May 21 12:00:01.123\0114624\011Microsoft-Windows-Security-Auditing\011N/A\011N/A\011Success Audit\011hostname.domain\011Logon\011\011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_glob_dir_not_dir.sh0000644000000000000000000000013215035412264024032 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.063592708 30 ctime=1764935932.085712859 rsyslog-8.2512.0/tests/imbatchreport_errmsg_glob_dir_not_dir.sh0000775000175000017500000000070115035412264023477 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" rename=".done$ .s .r.done" reports="'$RSYSLOG_DYNNAME'_.conf/*.done") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "Configured directory is NOT a directory" exit_test rsyslog-8.2512.0/tests/PaxHeaders/now-unixtimestamp.sh0000644000000000000000000000013215055602574017750 xustar0030 mtime=1756824956.034451512 30 atime=1764931161.567648933 30 ctime=1764935933.067727891 rsyslog-8.2512.0/tests/now-unixtimestamp.sh0000775000175000017500000000160115055602574017415 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # addd 2016-02-23 by RGerhards, released under ASL 2.0 # requires faketime echo \[now-utc\]: test \$NOW-UTC . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.tnow = $$now-unixtimestamp + 1; template(name="outfmt" type="string" string="%$now-unixtimestamp%,%$.tnow%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' . $srcdir/faketime_common.sh export TZ=TEST-02:00 FAKETIME='2016-01-01 01:00:00' startup # what we send actually is irrelevant, as we just use system properties. # but we need to send one message in order to gain output! tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="1451602800,1451602801" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-queue.sh0000644000000000000000000000013115055602574017336 xustar0030 mtime=1756824956.030451456 29 atime=1764931160.92663865 30 ctime=1764935932.878724998 rsyslog-8.2512.0/tests/imhiredis-queue.sh0000775000175000017500000000204615055602574017010 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis redis_command "RPUSH mykey message1" redis_command "RPUSH mykey message2" redis_command "RPUSH mykey message3" generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mykey" mode="queue" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup shutdown_when_empty wait_shutdown stop_redis # Opposite order content_check '1 message3' content_check '2 message2' content_check '3 message1' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-queue-lpop.sh0000644000000000000000000000013215055602574020307 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.942638907 30 ctime=1764935932.883725074 rsyslog-8.2512.0/tests/imhiredis-queue-lpop.sh0000775000175000017500000000206715055602574017763 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis redis_command "RPUSH mykey message1" redis_command "RPUSH mykey message2" redis_command "RPUSH mykey message3" generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mykey" mode="queue" uselpop="on" ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup shutdown_when_empty wait_shutdown stop_redis # Same order content_check '1 message1' content_check '2 message2' content_check '3 message3' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/imkafka-hang-on-no-kafka.sh0000644000000000000000000000013015035412264020644 xustar0030 mtime=1752569012.394792439 29 atime=1764931166.79073267 29 ctime=1764935934.57875102 rsyslog-8.2512.0/tests/imkafka-hang-on-no-kafka.sh0000775000175000017500000000156715035412264020326 0ustar00rgerrger#!/bin/bash # added 2018-10-22 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . $srcdir/diag.sh init export RSTB_GLOBAL_INPUT_SHUTDOWN_TIMEOUT=5000 # 5sec generate_conf add_conf ' main_queue(queue.type="direct") module(load="../plugins/imkafka/.libs/imkafka") input( type="imkafka" ruleset="kafka" topic="irrelevant" broker="localhost:29092" consumergroup="default" confParam=[ "socket.timeout.ms=5000", "socket.keepalive.enable=true" ] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="kafka") { action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) } action( type="omfile" file="'$RSYSLOG_OUT_LOG.syslog.log'" template="outfmt" ) ' export RSTB_DAEMONIZE="YES" startup shutdown_when_empty wait_shutdown # the main point is to see if we can terminate, so no further checks down here! exit_test rsyslog-8.2512.0/tests/PaxHeaders/with_space.mmdb0000644000000000000000000000013215035412264016664 xustar0030 mtime=1752569012.420611777 30 atime=1764931162.265660129 30 ctime=1764935933.262730876 rsyslog-8.2512.0/tests/with_space.mmdb0000664000175000017500000000066015035412264016332 0ustar00rgerrger                     0 áDcityGBei ing«ÍïMaxMind.comé[binary_format_major_version¡[binary_format_minor_version Kbuild_epochUÑS Mdatabase_typeDMMDBKdescriptionáBen]Rsyslog MaxMindDB for testingJip_version¡IlanguagesJnode_countÁ Krecord_size¡rsyslog-8.2512.0/tests/PaxHeaders/pmnull-withparams.sh0000644000000000000000000000013215035412264017715 xustar0030 mtime=1752569012.407702108 30 atime=1764931161.802652703 30 ctime=1764935933.133728901 rsyslog-8.2512.0/tests/pmnull-withparams.sh0000775000175000017500000000230515035412264017364 0ustar00rgerrger#!/bin/bash # add 2016-12-08 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/pmnull/.libs/pmnull") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") parser(name="custom.pmnull" type="pmnull" tag="mytag" syslogfacility="3" syslogseverity="1") template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n") ruleset(name="ruleset" parser=["custom.pmnull", "rsyslog.pmnull"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test") } ' startup tcpflood -m1 -M "\"<189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\"" shutdown_when_empty wait_shutdown echo 'tag: mytag, pri: 25, syslogfacility: 3, syslogseverity: 1 msg: <189>16261: May 28 16:09:56.185: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imkafka-backgrounded.sh0000644000000000000000000000013215071746523020272 xustar0030 mtime=1760021843.888421775 30 atime=1764931166.810732991 30 ctime=1764935934.583751097 rsyslog-8.2512.0/tests/imkafka-backgrounded.sh0000775000175000017500000000304315071746523017741 0ustar00rgerrger#!/bin/bash # added 2018-10-24 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init check_command_available kcat export KEEP_KAFKA_RUNNING="YES" export TESTMESSAGES=100000 export RANDTOPIC="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. export EXTRA_EXITCHECK=dumpkafkalogs export EXTRA_EXIT=kafka echo Check and Stop previous instances of kafka/zookeeper download_kafka stop_zookeeper stop_kafka echo Create kafka/zookeeper instance and $RANDTOPIC topic start_zookeeper start_kafka create_kafka_topic $RANDTOPIC '.dep_wrk' '22181' export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") module(load="../plugins/imkafka/.libs/imkafka") input( type="imkafka" topic="'$RANDTOPIC'" broker="localhost:29092" consumergroup="default" confParam=[ "compression.codec=none", "session.timeout.ms=10000", "socket.timeout.ms=5000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "enable.partition.eof=false" ] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") if ($msg contains "msgnum:") then { action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) } ' export RSTB_DAEMONIZE="YES" startup injectmsg_kcat --wait 1 $TESTMESSAGES -d shutdown_when_empty wait_shutdown # Delete topic to remove old traces before delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181' seq_check 1 $TESTMESSAGES -d exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmsnare-ccbackslash.sh0000644000000000000000000000013215035412264020135 xustar0030 mtime=1752569012.408695159 30 atime=1764931168.563761076 30 ctime=1764935935.078758674 rsyslog-8.2512.0/tests/pmsnare-ccbackslash.sh0000775000175000017500000001201015035412264017576 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../contrib/pmsnare/.libs/pmsnare") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") global(localHostname="localhost" parser.escapeControlCharactersCStyle="on") $EscapeControlCharactersOnReceive on template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\"" tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\"" shutdown_when_empty wait_shutdown export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti 14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]}; 14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................ 14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmsnare-cccstyle.sh0000644000000000000000000000013215035412264017505 xustar0030 mtime=1752569012.408695159 30 atime=1764931168.546760804 30 ctime=1764935935.073758597 rsyslog-8.2512.0/tests/pmsnare-cccstyle.sh0000775000175000017500000001430215035412264017154 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../contrib/pmsnare/.libs/pmsnare") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") $EscapeControlCharactersOnReceive on global( parser.escapeControlCharactersCStyle="on" ) template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\"" tcpflood -m1 -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\"" tcpflood -m1 -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]\"" tcpflood -m1 -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\"" shutdown_when_empty wait_shutdown export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti 14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................ 14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group local_in [0x0, 0x0] 14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]}; 14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................ 14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain 14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_client_missing_cert.sh0000644000000000000000000000013215055603742022523 xustar0030 mtime=1756825570.303069141 30 atime=1764931168.453759314 30 ctime=1764935935.047758199 rsyslog-8.2512.0/tests/sndrcv_tls_client_missing_cert.sh0000775000175000017500000000412715055603742022176 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo "This test is under review - it seems to have some issues" exit 77 printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls} # start up the instances # export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="'$RS_TLS_DRIVER'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="'$RS_TLS_DRIVER'" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" StreamDriver.PermitExpiredCerts="off" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export PORT_RCVR=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" #valgrind="valgrind" generate_conf 2 add_conf ' global( /* defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'" */ defaultNetstreamDriver="'$RS_TLS_DRIVER'" ) # set up the action $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon *.* @@127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown content_check --regex "peer .* did not provide a certificate," exit_test rsyslog-8.2512.0/tests/PaxHeaders/stats-cee-vg.sh0000644000000000000000000000013215055602574016542 xustar0030 mtime=1756824956.040451596 30 atime=1764931167.355741723 30 ctime=1764935934.731753362 rsyslog-8.2512.0/tests/stats-cee-vg.sh0000775000175000017500000000242615055602574016215 0ustar00rgerrger#!/bin/bash # added 2016-03-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi echo =============================================================================== echo \[stats-cee-vg.sh\]: test for verifying stats are reported correctly cee format with valgrind . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="cee") if ($msg == "this condition will never match") then { action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`) } ' startup_vg injectmsg_file $srcdir/testsuites/dynstats_input_1 wait_queueempty wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg custom_content_check '@cee: { "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended.duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table-hup-backgrounded.sh0000644000000000000000000000013115055602574022137 xustar0030 mtime=1756824956.032451484 30 atime=1764931167.782748565 29 ctime=1764935934.85575526 rsyslog-8.2512.0/tests/lookup_table-hup-backgrounded.sh0000775000175000017500000000320515055602574021607 0ustar00rgerrger#!/bin/bash # test for lookup-table and HUP based reloading of it # added 2015-09-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_TSAN generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on") template(name="outfmt" type="string" string="- %msg% %$.lkp%\n") set $.lkp = lookup("xlate", $msg); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl export RSTB_DAEMONIZE="YES" startup injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: bar_new" content_check "msgnum:00000002: baz" cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 10 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: foo_latest" content_check "msgnum:00000001: quux" content_check "msgnum:00000002: baz_latest" content_check "msgnum:00000003: foo_latest" content_check "msgnum:00000004: foo_latest" content_check "msgnum:00000005: baz_latest" content_check "msgnum:00000006: foo_latest" content_check "msgnum:00000007: baz_latest" content_check "msgnum:00000008: baz_latest" content_check "msgnum:00000009: quux" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-basic-auth-vg.sh0000644000000000000000000000013215055602574022607 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.654698435 30 ctime=1764935933.944741315 rsyslog-8.2512.0/tests/imhttp-post-payload-basic-auth-vg.sh0000775000175000017500000000025215055602574022255 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" #export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all" source ${srcdir:-.}/imhttp-post-payload-basic-auth.sh rsyslog-8.2512.0/tests/PaxHeaders/no-parser-vg.sh0000644000000000000000000000013215035412264016551 xustar0030 mtime=1752569012.402736851 30 atime=1764931161.183642773 30 ctime=1764935932.954726161 rsyslog-8.2512.0/tests/no-parser-vg.sh0000775000175000017500000000121215035412264016214 0ustar00rgerrger#!/bin/bash # add 2017-03-06 by Rainer Gerhards, released under ASL 2.0 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") ruleset(name="ruleset" parser="rsyslog.rfc5424") { action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) } ' startup_vg tcpflood -m10 shutdown_when_empty wait_shutdown_vg # note: we just check the valgrind output, the log file itself does not # interest us exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table.sh0000644000000000000000000000013115035412264016710 xustar0030 mtime=1752569012.399757696 30 atime=1764931167.774748437 29 ctime=1764935934.85375523 rsyslog-8.2512.0/tests/lookup_table.sh0000775000175000017500000000313715035412264016364 0ustar00rgerrger#!/bin/bash # test for lookup-table and HUP based reloading of it # added 2015-09-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on") template(name="outfmt" type="string" string="- %msg% %$.lkp%\n") set $.lkp = lookup("xlate", $msg); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 3 wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: bar_new" content_check "msgnum:00000002: baz" cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 10 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: foo_latest" content_check "msgnum:00000001: quux" content_check "msgnum:00000002: baz_latest" content_check "msgnum:00000003: foo_latest" content_check "msgnum:00000004: foo_latest" content_check "msgnum:00000005: baz_latest" content_check "msgnum:00000006: foo_latest" content_check "msgnum:00000007: baz_latest" content_check "msgnum:00000008: baz_latest" content_check "msgnum:00000009: quux" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omstdout-basic.sh0000644000000000000000000000013215035412264017166 xustar0030 mtime=1752569012.406709056 30 atime=1764931161.811652847 30 ctime=1764935933.135728932 rsyslog-8.2512.0/tests/omstdout-basic.sh0000775000175000017500000000130015035412264016627 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omstdout/.libs/omstdout") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="-%msg%-\n") action(type="omstdout" template="outfmt") ' startup > $RSYSLOG_OUT_LOG tcpflood -m1 shutdown_when_empty wait_shutdowna grep "msgnum:00000000:" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_hash64-vg.sh0000644000000000000000000000013215035412264017506 xustar0030 mtime=1752569012.411674314 30 atime=1764931167.473743614 30 ctime=1764935934.765753882 rsyslog-8.2512.0/tests/rscript_hash64-vg.sh0000775000175000017500000000201215035412264017150 0ustar00rgerrger#!/bin/bash # added 2018-02-07 by Harshvardhan Shrivastava # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \rscript_hash64.sh\]: test for hash64 and hash64mod script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n") module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmhash/.libs/fmhash") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.hash_no_1 = hash64("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e"); set $.hash_no_2 = hash64mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg tcpflood -m 20 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg . $srcdir/diag.sh content-pattern-check "^\(-2574714428477944902 - 14\|-50452361579464591 - 25\)$" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream-consumerGroup-reclaim-vg.sh0000644000000000000000000000013215055602574024400 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.084641185 30 ctime=1764935932.925725717 rsyslog-8.2512.0/tests/imhiredis-stream-consumerGroup-reclaim-vg.sh0000775000175000017500000000032715055602574024051 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-stream-consumerGroup-reclaim.sh rsyslog-8.2512.0/tests/PaxHeaders/timestamp-pgsql.sh0000644000000000000000000000013115055602574017366 xustar0030 mtime=1756824956.042451623 30 atime=1764931159.112609544 29 ctime=1764935932.38171739 rsyslog-8.2512.0/tests/timestamp-pgsql.sh0000775000175000017500000000076215055602574017043 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%timestamp:::date-pgsql%\n") :syslogtag, contains, "su" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg_literal "<34>1 2003-01-23T12:34:56.003Z mymachine.example.com su - ID47 - MSG\"" shutdown_when_empty wait_shutdown export EXPECTED='2003-01-23 12:34:56' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-truncate-2GB-file.sh0000644000000000000000000000013215055602574020615 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.789716628 30 ctime=1764935934.273746351 rsyslog-8.2512.0/tests/imfile-truncate-2GB-file.sh0000775000175000017500000000341315055602574020265 0ustar00rgerrger#!/bin/bash # written 2018-11-09 by Rainer Gerhards # this test checks that 2GiB (31 bit) file size region is handled correctly # it first generates a file that is 2GiB-64 bytes, processes it, and then # adds a couple of messages to get it over 2GiB. # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init export TB_TEST_MAX_RUNTIME=3600 # test is very slow as it works on large files generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" reopenOnTruncate="on") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' touch $RSYSLOG_DYNNAME.input startup # initial file: 2GiB - 1 message (54 byte) ./inputfilegen -s 2147483584 -d47 -M $RSYSLOG_DYNNAME.msgcnt > $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input export NUMMESSAGES="$(cat $RSYSLOG_DYNNAME.msgcnt)" wait_file_lines --delay 2500 --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES 3000 # add one message --> exactly 2GB ./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input (( NUMMESSAGES++ )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES # add one more message --> now we go over 2GB ./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input (( NUMMESSAGES++ )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES # add even more messages ./inputfilegen -m10000 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input NUMMESSAGES=$(( NUMMESSAGES + 10000 )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES shutdown_when_empty wait_shutdown seq_check 0 $(( NUMMESSAGES - 1)) exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_set_unset_invalid_var.sh0000644000000000000000000000013215035412264022366 xustar0030 mtime=1752569012.412667365 30 atime=1764931160.434630757 30 ctime=1764935932.738722855 rsyslog-8.2512.0/tests/rscript_set_unset_invalid_var.sh0000775000175000017500000000226515035412264022042 0ustar00rgerrger#!/bin/bash # Check that invalid variable names are detected. # Copyright 2017-01-24 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="json" type="string" string="%$!%\n") ruleset(name="rcvr" queue.type="LinkedList") { set $@timestamp="test"; unset $@timestamp2; action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown grep "@timestamp" $RSYSLOG_OUT_LOG > /dev/null if [ ! $? -eq 0 ]; then echo "expected error message on \"@timestamp\" not found, output is:" echo "------------------------------------------------------------" cat $RSYSLOG_OUT_LOG echo "------------------------------------------------------------" error_exit 1 fi; grep "@timestamp2" $RSYSLOG_OUT_LOG > /dev/null if [ ! $? -eq 0 ]; then echo "expected error message on \"@timestamp2\" not found, output is:" echo "------------------------------------------------------------" cat $RSYSLOG_OUT_LOG echo "------------------------------------------------------------" error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/faketime_common.sh0000644000000000000000000000013215035412264017366 xustar0030 mtime=1752569012.389827181 30 atime=1764931161.575649061 30 ctime=1764935933.069727921 rsyslog-8.2512.0/tests/faketime_common.sh0000664000175000017500000000445215035412264017037 0ustar00rgerrger#!/bin/bash # addd 2016-03-11 by Thomas D., released under ASL 2.0 # Several tests make use of faketime. They all need to know when # faketime is missing or the system isn't year-2038 complaint. # This script can be sourced to prevent duplicated code. rsyslog_testbench_preload_libfaketime() { local missing_requirements= if ! hash find 2>/dev/null ; then missing_requirements="'find' is missing in PATH; Make sure you have findutils/coreutils installed! Skipping test ..." fi if ! hash $RS_SORTCMD 2>/dev/null ; then missing_requirements="'sort' is missing in PATH; Make sure you have coreutils installed! Skipping test ..." fi if ! hash $RS_HEADCMD 2>/dev/null ; then missing_requirements="'head' is missing in PATH; Make sure you have coreutils installed! Skipping test ..." fi if [ -n "${missing_requirements}" ]; then printf '%s\n' "${missing_requirements}" exit 77 fi RSYSLOG_LIBFAKETIME=$(find /usr -name 'libfaketime.so*' -type f | $RS_SORTCMD --reverse | $RS_HEADCMD --lines 1) if [ -z "${RSYSLOG_LIBFAKETIME}" ]; then echo "Could not determine libfaketime library, skipping test!" exit 77 fi echo "Testing '${RSYSLOG_LIBFAKETIME}' library ..." local faketime_testtime=$(LD_PRELOAD="${RSYSLOG_LIBFAKETIME}" FAKETIME="1991-08-25 20:57:08" TZ=GMT date +%s 2>/dev/null) if [ ${faketime_testtime} -ne 683153828 ] ; then echo "'${RSYSLOG_LIBFAKETIME}' failed sanity check, skipping test!" exit 77 else echo "Test passed! Will use '${RSYSLOG_LIBFAKETIME}' library!" export RSYSLOG_PRELOAD="${RSYSLOG_LIBFAKETIME}" fi # GMT-1 (POSIX TIME) is GMT+1 in "Human Time" faketime_testtime=$(LD_PRELOAD="${RSYSLOG_LIBFAKETIME}" FAKETIME="2040-01-01 16:00:00" TZ=GMT-1 date +%s 2>/dev/null) if [ ${faketime_testtime} -eq -1 ]; then echo "Note: System is not year-2038 compliant" RSYSLOG_TESTBENCH_Y2K38_INCOMPATIBLE="yes" else echo "Note: System is year-2038 compliant" fi } rsyslog_testbench_require_y2k38_support() { if [ -n "${RSYSLOG_TESTBENCH_Y2K38_INCOMPATIBLE}" ]; then echo "Skipping further tests because system doesn't support year 2038 ..." exit_test exit 0 fi } rsyslog_testbench_preload_libfaketime rsyslog-8.2512.0/tests/PaxHeaders/fromhost-port-async-ruleset.sh0000644000000000000000000000013215071746523021660 xustar0030 mtime=1760021843.887421759 30 atime=1764931162.800668709 30 ctime=1764935933.410733141 rsyslog-8.2512.0/tests/fromhost-port-async-ruleset.sh0000775000175000017500000000164715071746523021337 0ustar00rgerrger#!/bin/bash ## fromhost-port.sh ## Check that fromhost-port property records sender port and that it ## can properly be carried over to a second asnc ruleset. . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="list") { property(name="fromhost-port") constant(value="\n") } call async # Note: a disk-type queue is selected to test even more rsyslog core features ruleset(name="async" queue.type="disk") { :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' startup tcpflood -m $NUMMESSAGES -w "${RSYSLOG_DYNNAME}.tcpflood-port" shutdown_when_empty wait_shutdown export EXPECTED="$(cat "${RSYSLOG_DYNNAME}.tcpflood-port")" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_relp_tls_chainedcert.sh0000644000000000000000000000013215055602574021774 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.168690644 30 ctime=1764935933.810739264 rsyslog-8.2512.0/tests/sndrcv_relp_tls_chainedcert.sh0000775000175000017500000000356615055602574021455 0ustar00rgerrger#!/bin/bash # addd 2020-08-25 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init require_relpEngineVersion "1.7.0" export NUMMESSAGES=1000 export TB_TEST_MAX_RUNTIME=30 # uncomment for debugging support: # export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' module( load="../plugins/imrelp/.libs/imrelp" tls.tlslib="openssl") # then SENDER sends to this port (not tcpflood!) input(type="imrelp" port="'$PORT_RCVR'" tls="on" tls.mycert="'$srcdir'/tls-certs/certchained.pem" tls.myprivkey="'$srcdir'/tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' module( load="../plugins/omrelp/.libs/omrelp" tls.tlslib="openssl") :msg, contains, "msgnum:" action(type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on" tls.mycert="'$srcdir'/tls-certs/certchained.pem" tls.myprivkey="'$srcdir'/tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog") action(type="omfile" file="'$RSYSLOG_DYNNAME.errmsgs'") ' 2 startup 2 if grep "omrelp error: invalid authmode" < "$RSYSLOG_DYNNAME.errmsgs" ; then echo "SKIP: librelp does not support "certvalid" auth mode" # mini-cleanup to not leave dangling processes shutdown_immediate 2 shutdown_immediate rm $RSYSLOG_DYNNAME* &> /dev/null exit 77 fi # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 $NUMMESSAGES # shut down sender shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_exists-yes2.sh0000644000000000000000000000013215055602574020205 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.851621403 30 ctime=1764935932.576720375 rsyslog-8.2512.0/tests/rscript_exists-yes2.sh0000775000175000017500000000075415055602574017662 0ustar00rgerrger#!/bin/bash # add 2020-10-02 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%!result%\n") set $.p1!p2!val="yes!"; if $msg contains "msgnum" then { if exists($.p1!p2!val) then set $!result = "on"; else set $!result = "off"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='on' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger_ratelimit.sh0000644000000000000000000000013215055602574021513 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.509728167 30 ctime=1764935934.496749765 rsyslog-8.2512.0/tests/imuxsock_logger_ratelimit.sh0000775000175000017500000000253615055602574021170 0ustar00rgerrger#!/bin/bash echo \[imuxsock_logger_ratelimit.sh\]: test rate limiting with imuxsock . ${srcdir:=.}/diag.sh init ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi export EXPECTED=" test message nbr 0, severity=6 test message nbr 1, severity=6 test message nbr 2, severity=6 test message nbr 3, severity=6 test message nbr 4, severity=6" for use_special_parser in on off; do echo \[imuxsock_logger_ratelimit.sh\]: test rate limiting with imuxsock with useSpecialParser="$use_special_parser" echo -n >"$RSYSLOG_OUT_LOG" generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input( type="imuxsock" socket="'$RSYSLOG_DYNNAME'-testbench_socket" useSpecialParser="'$use_special_parser'" ruleset="testruleset" ratelimit.interval="10" ratelimit.burst="5") template(name="outfmt" type="string" string="%msg:%\n") ruleset(name="testruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup ./syslog_caller -m20 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" -s6 # the sleep below is needed to prevent too-early termination of rsyslogd ./msleep 100 shutdown_when_empty wait_shutdown cmp_exact done exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_anon_ipv4.sh0000644000000000000000000000013215055602574020376 xustar0030 mtime=1756824956.040451596 30 atime=1764931168.304756928 30 ctime=1764935935.004757541 rsyslog-8.2512.0/tests/sndrcv_tls_anon_ipv4.sh0000775000175000017500000000403515055602574020047 0ustar00rgerrger#!/bin/bash # rgerhards, 2011-04-04 # testing sending and receiving via TLS with anon auth using bare ipv4, no SNI # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=25000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="gtls" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RCVR_PORT=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="gtls" ) # set up the action $DefaultNetstreamDriver gtls # use gtls netstream driver $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon *.* @@127.0.0.1:'$RCVR_PORT' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mysql-actq-mt.sh0000644000000000000000000000013015035412264016740 xustar0030 mtime=1752569012.402736851 28 atime=1764931166.7177315 30 ctime=1764935934.557750699 rsyslog-8.2512.0/tests/mysql-actq-mt.sh0000775000175000017500000000132215035412264016407 0ustar00rgerrger#!/bin/bash # test for mysql with multithread actionq # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=150000 generate_conf add_conf ' module(load="../plugins/ommysql/.libs/ommysql") :msg, contains, "msgnum:" { action(type="ommysql" server="127.0.0.1" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" queue.size="10000" queue.type="linkedList" queue.workerthreads="5" queue.workerthreadMinimumMessages="500" queue.timeoutWorkerthreadShutdown="1000" queue.timeoutEnqueue="10000" queue.timeoutShutdown="30000" ) } ' mysql_prep_for_test startup injectmsg shutdown_when_empty wait_shutdown mysql_get_data seq_check mysql_cleanup_test exit_test rsyslog-8.2512.0/tests/PaxHeaders/dynstats_reset.sh0000644000000000000000000000013215055602574017313 xustar0030 mtime=1756824956.027451414 30 atime=1764931167.129738102 30 ctime=1764935934.672752459 rsyslog-8.2512.0/tests/dynstats_reset.sh0000775000175000017500000000460315055602574016765 0ustar00rgerrger#!/bin/bash # added 2015-11-13 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="4" severity="7" resetCounters="on" Ruleset="stats" bracketing="on") template(name="outfmt" type="string" string="%msg% %$.increment_successful%\n") dyn_stats(name="msg_stats" unusedMetricLife="1" resettable="off") set $.msg_prefix = field($msg, 32, 1); if (re_match($.msg_prefix, "foo|bar|baz|quux|corge|grault")) then { set $.increment_successful = dyn_inc("msg_stats", $.msg_prefix); } else { set $.increment_successful = -1; } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log injectmsg_file "$srcdir/testsuites/dynstats_input_1" rst_msleep 8100 injectmsg_file "$srcdir/testsuites/dynstats_input_2" rst_msleep 8100 injectmsg_file "$srcdir/testsuites/dynstats_input_3" rst_msleep 8100 wait_queueempty content_check "foo 001 0" content_check "bar 002 0" content_check "baz 003 0" content_check "foo 004 0" content_check "baz 005 0" content_check "foo 006 0" shutdown_when_empty wait_shutdown # because dyn-metrics would be reset before it can accumulate and report high counts, sleep between msg-injection ensures that custom_assert_content_missing 'baz=2' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing 'foo=2' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing 'foo=3' "${RSYSLOG_DYNNAME}.out.stats.log" # but actual reported stats (aggregate) should match first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'foo=' ${RSYSLOG_DYNNAME}.out.stats.log 3 first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'bar=' ${RSYSLOG_DYNNAME}.out.stats.log 1 first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'baz=' ${RSYSLOG_DYNNAME}.out.stats.log 2 first_column_sum_check 's/.*new_metric_add=\([0-9]*\)/\1/g' 'new_metric_add=' "${RSYSLOG_DYNNAME}.out.stats.log" 6 first_column_sum_check 's/.*ops_overflow=\([0-9]*\)/\1/g' 'ops_overflow=' "${RSYSLOG_DYNNAME}.out.stats.log" 0 first_column_sum_check 's/.*no_metric=\([0-9]*\)/\1/g' 'no_metric=' "${RSYSLOG_DYNNAME}.out.stats.log" 0 first_column_sum_check 's/.*metrics_purged=\([0-9]*\)/\1/g' 'metrics_purged=' "${RSYSLOG_DYNNAME}.out.stats.log" 6 exit_test rsyslog-8.2512.0/tests/PaxHeaders/override_getaddrinfo.c0000644000000000000000000000013015055605325020230 xustar0030 mtime=1756826325.657800804 28 atime=1764931120.5579884 30 ctime=1764935931.901710042 rsyslog-8.2512.0/tests/override_getaddrinfo.c0000664000175000017500000000147515055605325017705 0ustar00rgerrger// we need this for dlsym(): #include #include "config.h" #include #include #include #include #include int getaddrinfo(const char *node __attribute__((unused)), const char *service __attribute__((unused)), const struct addrinfo *hints __attribute__((unused)), struct addrinfo **res __attribute__((unused))) { return EAI_MEMORY; } static void __attribute__((constructor)) my_init(void) { /* we currently do not need this entry point, but keep it as * a "template". It can be used, e.g. to emit some diagnostic * information: printf("loaded\n"); * or - more importantly - obtain a pointer to the overriden * API: orig_etry = dlsym(RTLD_NEXT, "original_entry_point"); */ } rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-num.sh0000644000000000000000000000013215055602574021641 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.522616123 30 ctime=1764935932.499719196 rsyslog-8.2512.0/tests/rscript_compare_numstr-num.sh0000775000175000017500000000014715055602574021312 0ustar00rgerrger#!/bin/bash export LOWER_VAL='"1"' export HIGHER_VAL='2' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/imjournal-basic.sh0000644000000000000000000000013215055603742017315 xustar0030 mtime=1756825570.301069108 30 atime=1764931161.583649189 30 ctime=1764935933.072727967 rsyslog-8.2512.0/tests/imjournal-basic.sh0000775000175000017500000000334615055603742016772 0ustar00rgerrger#!/bin/bash # This test injects a message and checks if it is received by # imjournal. We use a special test string which we do not expect # to be present in the regular log stream. So we do not expect that # any other journal content matches our test message. We skip the # test in case message does not make it even to journal which may # sometimes happen in some environments. # addd 2017-10-25 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh require-journalctl generate_conf add_conf ' module(load="../plugins/imjournal/.libs/imjournal" IgnorePreviousMessages="on" RateLimit.Burst="1000000") template(name="outfmt" type="string" string="%msg%\n") action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' TESTMSG="TestBenCH-RSYSLog imjournal This is a test message - $(date +%s) - $RSYSLOG_DYNNAME" startup printf 'a quick glimpse at journal content at rsyslog startup:\n' journalctl -n 20 --no-pager printf '\n\n' printf '++++++++++++++++++++++ Printing to the journal! +++++++++++++++++++++++++\n' # inject message into journal and check that it is recorded ./journal_print "$TESTMSG" journal_write_state=$? if [ $journal_write_state -ne 0 ]; then printf 'SKIP: journal_print returned state %d writing message: %s\n' "$journal_write_state" "$TESTMSG" printf 'skipping test, journal probably not working\n' exit 77 fi # check state later - we must not terminate the test until we have terminated rsyslog # give the journal ~5 minutes to forward the message, see # https://github.com/rsyslog/rsyslog/issues/2564#issuecomment-435849660 content_check_with_count "$TESTMSG" 1 300 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown check_journal_testmsg_received exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp-msg-truncation-on-number2.sh0000644000000000000000000000013215071746523022467 xustar0030 mtime=1760021843.891421822 30 atime=1764931162.183658813 30 ctime=1764935933.239730524 rsyslog-8.2512.0/tests/imptcp-msg-truncation-on-number2.sh0000775000175000017500000000345115071746523022141 0ustar00rgerrger#!/bin/bash # addd 2017-03-01 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "Darwin" "Test fails on MacOS 13, TCP chunking causes false octet-counting detection with sequence 9876543210" generate_conf add_conf ' $MaxMessageSize 128 global(processInternalMessages="on" oversizemsg.input.mode="accept") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="templ1" type="string" string="%rawmsg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="templ1") } ' startup tcpflood -m2 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"2000000010 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"4000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"0 <120> 2011-03-01T11:22:12Z host msgnum:1\"" shutdown_when_empty wait_shutdown echo '<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 214000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 214000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 2000000010<120> 2011-03-01T11:22:12Z host msgnum:1 4000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/da-mainmsg-q.sh0000644000000000000000000000013215035412264016504 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.733667634 30 ctime=1764935933.390732835 rsyslog-8.2512.0/tests/da-mainmsg-q.sh0000775000175000017500000000341715035412264016160 0ustar00rgerrger#!/bin/bash # Test for DA mode on the main message queue # This test checks if DA mode operates correctly. To do so, # it uses a small in-memory queue size, so that DA mode is initiated # rather soon, and disk spooling used. There is some uncertainty (based # on machine speeds), but in general the test should work rather well. # We add a few messages after the initial run, just so that we can # check everything recovers from DA mode correctly. # added 2009-04-22 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 10000 input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # set spool locations and switch queue to disk assisted mode $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueSize 200 # this *should* trigger moving on to DA mode... # note: we must set QueueSize sufficiently high, so that 70% (light delay mark) # is high enough above HighWatermark! $MainMsgQueueHighWatermark 80 $MainMsgQueueLowWatermark 40 $MainMsgQueueFilename mainq $MainMsgQueueType linkedlist $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup # part1: send first 50 messages (in memory, only) injectmsg 0 50 wait_file_lines $RSYSLOG_OUT_LOG 50 # let queue drain for this test case # part 2: send bunch of messages. This should trigger DA mode injectmsg 50 2000 ls -l ${RSYSLOG_DYNNAME}.spool # for manual review wait_file_lines $RSYSLOG_OUT_LOG 2050 # wait to ensure DA queue is "empty" # send another handful injectmsg 2050 50 shutdown_when_empty wait_shutdown seq_check 0 2099 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmkubernetes-basic.out.json0000644000000000000000000000013215055602574021165 xustar0030 mtime=1756824956.033451498 30 atime=1764931168.794764777 30 ctime=1764935935.140759623 rsyslog-8.2512.0/tests/mmkubernetes-basic.out.json0000664000175000017500000002661415055602574020642 0ustar00rgerrger[{ "log": "not in right format", "testid": 1 }, { "message": "not in right format", "testid": 2 }, { "kubernetes": { "namespace_id": "namespace-name2-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name2-id", "labels": { "custom_label": "pod-name2-label-value", "deploymentconfig": "pod-name2-dc", "component": "pod-name2-component", "label_with_empty_value": "", "deployment": "pod-name2-deployment" }, "pod_name": "pod-name2", "namespace_name": "namespace-name2", "container_name": "container-name2", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id2" }, "testid": 4 }, { "message": "a message from container 4", "CONTAINER_NAME": "some-prefix_container-name4_pod-name4_namespace-name4_unused4_unused44", "CONTAINER_ID_FULL": "id4", "kubernetes": { "namespace_id": "namespace-name4-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name4-id", "labels": { "custom_label": "pod-name4-label-value", "deploymentconfig": "pod-name4-dc", "component": "pod-name4-component", "label_with_empty_value": "", "deployment": "pod-name4-deployment" }, "pod_name": "pod-name4", "namespace_name": "namespace-name4", "container_name": "container-name4", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id4" }, "testid": 6 }, { "kubernetes": { "namespace_id": "namespace-name1-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name1-id", "labels": { "custom_label": "pod-name1-label-value", "deploymentconfig": "pod-name1-dc", "component": "pod-name1-component", "label_with_empty_value": "", "deployment": "pod-name1-deployment" }, "pod_name": "pod-name1", "namespace_name": "namespace-name1", "container_name": "container-name1", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id1" }, "testid": 3 }, { "message": "a message from container 3", "CONTAINER_NAME": "some-prefix_container-name3.container-hash3_pod-name3_namespace-name3_unused3_unused33", "CONTAINER_ID_FULL": "id3", "kubernetes": { "namespace_id": "namespace-name3-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name3-id", "labels": { "custom_label": "pod-name3-label-value", "deploymentconfig": "pod-name3-dc", "component": "pod-name3-component", "label_with_empty_value": "", "deployment": "pod-name3-deployment" }, "pod_name": "pod-name3", "namespace_name": "namespace-name3", "container_name": "container-name3", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id3" }, "testid": 5 }, { "message": "a message from container 5", "CONTAINER_NAME": "some-prefix_container-name5_pod-name5.with.dot.in.pod.name_namespace-name5_unused5_unused55", "CONTAINER_ID_FULL": "id5", "kubernetes": { "namespace_id": "namespace-name5-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name5.with.dot.in.pod.name-id", "labels": { "custom_label": "pod-name5.with.dot.in.pod.name-label-value", "deploymentconfig": "pod-name5.with.dot.in.pod.name-dc", "component": "pod-name5.with.dot.in.pod.name-component", "label_with_empty_value": "", "deployment": "pod-name5.with.dot.in.pod.name-deployment" }, "pod_name": "pod-name5.with.dot.in.pod.name", "namespace_name": "namespace-name5", "container_name": "container-name5", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id5" }, "testid": 7 }, { "message":"this record should have no namespace metadata", "CONTAINER_NAME":"some-prefix_container-name-6_pod-name-6_namespace-name-6-not-found_unused6_unused66", "CONTAINER_ID_FULL":"id6", "kubernetes": { "pod_id":"pod-name-6-id", "labels": { "custom_label":"pod-name-6-label-value", "deploymentconfig":"pod-name-6-dc", "component":"pod-name-6-component", "label_with_empty_value":"", "deployment":"pod-name-6-deployment" }, "pod_name":"pod-name-6", "namespace_name":"namespace-name-6-not-found", "container_name":"container-name-6", "master_url":"http://localhost:{k8s_srv_port}" }, "docker": { "container_id":"id6" }, "testid": 8 }, { "message": "this record should have no pod metadata", "CONTAINER_NAME": "some-prefix_container-name-7_pod-name-7-not-found_namespace-name-7_unused7_unused77", "CONTAINER_ID_FULL": "id7", "kubernetes": { "namespace_id": "namespace-name-7-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_name": "pod-name-7-not-found", "namespace_name": "namespace-name-7", "container_name": "container-name-7", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id7" }, "testid": 9 }, { "message": "this record should have no namespace or pod metadata and retry", "CONTAINER_NAME": "some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88", "CONTAINER_ID_FULL": "id8", "kubernetes": { "pod_name": "pod-name-8", "namespace_name": "namespace-name-8-busy", "container_name": "container-name-8", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id8" }, "testid": 10 }, { "message": "this record should have namespace and pod metadata after retry", "CONTAINER_NAME": "some-prefix_container-name-8_pod-name-8_namespace-name-8-busy_unused8_unused88", "CONTAINER_ID_FULL": "id8", "kubernetes": { "namespace_id": "namespace-name-8-busy-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name-8-id", "labels": { "custom_label": "pod-name-8-label-value", "deploymentconfig": "pod-name-8-dc", "component": "pod-name-8-component", "label_with_empty_value": "", "deployment": "pod-name-8-deployment" }, "pod_name": "pod-name-8", "namespace_name": "namespace-name-8-busy", "container_name": "container-name-8", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id8" }, "testid": 11 }, { "message": "this record should have no pod metadata and retry", "CONTAINER_NAME": "some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99", "CONTAINER_ID_FULL": "id9", "kubernetes": { "namespace_id": "namespace-name-9-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_name": "pod-name-9-busy", "namespace_name": "namespace-name-9", "container_name": "container-name-9", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id9" }, "testid": 12 }, { "message": "this record should have pod metadata after retry", "CONTAINER_NAME": "some-prefix_container-name-9_pod-name-9-busy_namespace-name-9_unused9_unused99", "CONTAINER_ID_FULL": "id9", "kubernetes": { "namespace_id": "namespace-name-9-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name-9-busy-id", "labels": { "custom_label": "pod-name-9-busy-label-value", "deploymentconfig": "pod-name-9-busy-dc", "component": "pod-name-9-busy-component", "label_with_empty_value": "", "deployment": "pod-name-9-busy-deployment" }, "pod_name": "pod-name-9-busy", "namespace_name": "namespace-name-9", "container_name": "container-name-9", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id9" }, "testid": 13 }, { "message": "this record should process normally", "CONTAINER_NAME": "some-prefix_container-name-10_pod-name-10_namespace-name-10_unused10_unused100", "CONTAINER_ID_FULL": "id10", "kubernetes": { "namespace_id": "namespace-name-10-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name-10-id", "labels": { "custom_label": "pod-name-10-label-value", "deploymentconfig": "pod-name-10-dc", "component": "pod-name-10-component", "label_with_empty_value": "", "deployment": "pod-name-10-deployment" }, "pod_name": "pod-name-10", "namespace_name": "namespace-name-10", "container_name": "container-name-10", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id10" }, "testid": 14 }, { "message": "this record should have no pod metadata", "CONTAINER_NAME": "some-prefix_container-name-11_pod-name-11-error_namespace-name-11_unused11_unused111", "CONTAINER_ID_FULL": "id11", "kubernetes": { "namespace_id": "namespace-name-11-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_name": "pod-name-11-error", "namespace_name": "namespace-name-11", "container_name": "container-name-11", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id11" }, "testid": 15 }, { "message": "this record should process normally", "CONTAINER_NAME": "some-prefix_container-name-12_pod-name-12_namespace-name-12_unused12_unused112", "CONTAINER_ID_FULL": "id12", "kubernetes": { "namespace_id": "namespace-name-12-id", "namespace_labels": { "label_1_key": "label 1 value", "label_with_empty_value": "", "label_2_key": "label 2 value" }, "creation_timestamp": "2018-04-09T21:56:39Z", "pod_id": "pod-name-12-id", "labels": { "custom_label": "pod-name-12-label-value", "deploymentconfig": "pod-name-12-dc", "component": "pod-name-12-component", "label_with_empty_value": "", "deployment": "pod-name-12-deployment" }, "pod_name": "pod-name-12", "namespace_name": "namespace-name-12", "container_name": "container-name-12", "master_url": "http://localhost:{k8s_srv_port}" }, "docker": { "container_id": "id12" }, "testid": 16 }] rsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-json.sh0000644000000000000000000000013215103346332017673 xustar0030 mtime=1762512090.634176013 30 atime=1764931158.263595918 30 ctime=1764935932.141713716 rsyslog-8.2512.0/tests/mmsnareparse-json.sh0000775000175000017500000001307715103346332017352 0ustar00rgerrger#!/bin/bash ## Test mmsnareparse module with JSON template output ## Validates that the module correctly parses Windows security events and outputs them in JSON format unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmsnareparse/.libs/mmsnareparse") template(name="jsonfmt" type="list" option.jsonf="on") { property(outname="EventID" name="$!win!Event!EventID" format="jsonf") property(outname="TimeCreatedNormalized" name="$!win!Event!TimeCreated!Normalized" format="jsonf") property(outname="LogonType" name="$!win!LogonInformation!LogonType" format="jsonf") property(outname="LogonTypeName" name="$!win!LogonInformation!LogonTypeName" format="jsonf") property(outname="LAPSPolicyVersion" name="$!win!LAPS!PolicyVersion" format="jsonf") property(outname="LAPSCredentialRotation" name="$!win!LAPS!CredentialRotation" format="jsonf") property(outname="TLSReason" name="$!win!TLSInspection!Reason" format="jsonf") property(outname="WDACPolicyVersion" name="$!win!WDAC!PolicyVersion" format="jsonf") property(outname="WDACPID" name="$!win!WDAC!PID" format="jsonf") property(outname="WUFBPolicyID" name="$!win!WUFB!PolicyID" format="jsonf") property(outname="RemoteCredentialGuard" name="$!win!Logon!RemoteCredentialGuard" format="jsonf") property(outname="NetworkSourcePort" name="$!win!Network!SourcePort" format="jsonf") } action(type="mmsnareparse") action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="jsonfmt") ' startup cat <<'MSG' > ${RSYSLOG_DYNNAME}.input <13>1 2025-02-18T06:42:17.554128Z DC25-PREVIEW - - - - MSWinEventLog 1 Security 802301 Tue Feb 18 06:42:17 2025 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit DC25-PREVIEW Logon An account was successfully logged on. Subject: Security ID: S-1-5-18 Account Name: SYSTEM Account Domain: NT AUTHORITY Logon ID: 0x3E7 Logon Information: Logon Type: 2 Restricted Admin Mode: - Virtual Account: %%1843 Elevated Token: %%1843 New Logon: Security ID: S-1-5-21-88997766-1122334455-6677889900-500 Account Name: ADMIN-LAPS$ Account Domain: FABRIKAM Logon ID: 0x52F1A Linked Logon ID: 0x0 Network Account Name: - Network Account Domain: - Logon GUID: {5a8f0679-9b23-4cb7-a8c7-3d650c9b52ec} Process Information: Process ID: 0x66c Process Name: C:\Windows\System32\winlogon.exe Network Information: Workstation Name: CORE25-01 Source Network Address: 192.168.50.12 Source Port: 59122 Detailed Authentication Information: Logon Process: User32 Authentication Package: Negotiate Transited Services: - Package Name (NTLM only): - Key Length: 0 Remote Credential Guard: Enabled LAPS Context: PolicyVersion=2; CredentialRotation=True -802301 <13>1 2025-02-18T07:01:55.771903Z EDGE25-01 - - - - MSWinEventLog 1 Security 301221 Tue Feb 18 07:01:55 2025 5157 Microsoft-Windows-Security-Auditing N/A N/A Failure Audit EDGE25-01 Filtering Platform Packet Drop The Windows Filtering Platform has blocked a connection. Application Information: Process ID: 948 Application Name: C:\Program Files\Contoso\edgegateway.exe Network Information: Direction: Outbound Source Address: 10.15.5.20 Source Port: 57912 Destination Address: 104.45.23.110 Destination Port: 443 Protocol: 6 Filter Information: Filter Run-Time ID: 89041 Layer Name: %%14596 Layer Run-Time ID: 44 TLS Inspection: Reason: Unapproved Root Authority Policy: ContosoOutboundTLS -301221 <13>1 2025-02-18T07:05:44.888234Z APP25-API - - - - MSWinEventLog 1 Security 402991 Tue Feb 18 07:05:44 2025 6281 Microsoft-Windows-CodeIntegrity N/A N/A Error APP25-API Application Control Code Integrity determined that a process (\Device\HarddiskVolume4\Program Files\LegacyERP\erp.exe) attempted to load \Device\HarddiskVolume4\Temp\unsigned.dll that did not meet the Enterprise signing level requirements. Policy Name: FABRIKAM-WDAC-BaseV3 Policy Version: 3.2.0 Enforcement Mode: Audit+Enforce User: FABRIKAM\svc_batch PID: 4128 -402991 <13>1 2025-02-18T06:59:13.332719Z DC25-PREVIEW - - - - MSWinEventLog 1 Security 802340 Tue Feb 18 06:59:13 2025 1243 Microsoft-Windows-WindowsUpdateClient N/A N/A Information DC25-PREVIEW WUFB Deployment Windows Update for Business deployment policy enforced. Policy ID: 2f9c4414-3f71-4f2b-9a7e-cc98a6d96970 Ring: SecureBaseline From Service: Windows Update for Business deployment service Enforcement Result: Success -802340 MSG injectmsg_file ${RSYSLOG_DYNNAME}.input shutdown_when_empty wait_shutdown # Check JSON output format (field-by-field for robustness) # 4624 content_check '"eventid":"4624"' $RSYSLOG_OUT_LOG content_check '"timecreatednormalized":"2025-02-18T06:42:17' $RSYSLOG_OUT_LOG content_check '"logontype":"2"' $RSYSLOG_OUT_LOG content_check '"logontypename":"Interactive"' $RSYSLOG_OUT_LOG content_check '"lapspolicyversion":"2"' $RSYSLOG_OUT_LOG content_check '"lapscredentialrotation":"true"' $RSYSLOG_OUT_LOG content_check '"remotecredentialguard":"true"' $RSYSLOG_OUT_LOG content_check '"networksourceport":"59122"' $RSYSLOG_OUT_LOG # 5157 content_check '"eventid":"5157"' $RSYSLOG_OUT_LOG content_check '"tlsreason":"Unapproved Root Authority"' $RSYSLOG_OUT_LOG content_check '"networksourceport":"57912"' $RSYSLOG_OUT_LOG # 6281 content_check '"eventid":"6281"' $RSYSLOG_OUT_LOG content_check '"wdacpolicyversion":"3.2.0"' $RSYSLOG_OUT_LOG content_check '"wdacpid":"4128"' $RSYSLOG_OUT_LOG # 1243 content_check '"eventid":"1243"' $RSYSLOG_OUT_LOG content_check '"wufbpolicyid":"2f9c4414-3f71-4f2b-9a7e-cc98a6d96970"' $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/gzipwr_large.sh0000644000000000000000000000013215035412264016725 xustar0030 mtime=1752569012.390820233 30 atime=1764931165.629714064 30 ctime=1764935934.226745632 rsyslog-8.2512.0/tests/gzipwr_large.sh0000775000175000017500000000242215035412264016374 0ustar00rgerrger#!/bin/bash # This tests writing large data records in gzip mode. We use up to 10K # record size. # # added 2010-03-10 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=4000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf export SEQ_CHECK_FILE=$RSYSLOG_OUT_LOG.gz add_conf ' $MaxMessageSize 10k $MainMsgQueueTimeoutShutdown 10000 module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") local0.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'.gz" template="outfmt" zipLevel="6" veryRobustZip="on") ' # rgerhards, 2019-08-14: Note: veryRobustZip may need to be "on". Do this if the test # still prematurely terminates. In that case it is likely that gunzip got confused # by the missing zip close record. My initial testing shows that while gunzip emits an # error message, everything is properly extracted. Only stressed CI runs will show how # it works in reality. startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES -r -d10000 -P129 shutdown_when_empty wait_shutdown seq_check 0 $((NUMMESSAGES - 1)) -E exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-restart-terminated.sh0000644000000000000000000000013115035412264021347 xustar0030 mtime=1752569012.405716005 29 atime=1764931165.20270722 30 ctime=1764935934.100743703 rsyslog-8.2512.0/tests/omprog-restart-terminated.sh0000775000175000017500000001065515035412264021026 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test checks that omprog restarts the external program when it # terminates prematurely, and that it does so without leaking file # descriptors. Two cases are checked: termination of the program when # omprog is going to write to the pipe (to send a message to the # program), and when omprog is going to read from the pipe (when it # is expecting the program to confirm the last message). . ${srcdir:=.}/diag.sh init check_command_available lsof generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary="'$RSYSLOG_DYNNAME'.omprog-restart-terminated-bin.sh" template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process confirmMessages="on" # facilitates sync with the child process action.resumeRetryCount="3" action.resumeInterval="1" action.reportSuspensionContinuation="on" signalOnClose="off" ) } syslog.* { action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG`) } ' # We need a test-specific program name, as the test needs to signal the child process cp -f $srcdir/testsuites/omprog-restart-terminated-bin.sh $RSYSLOG_DYNNAME.omprog-restart-terminated-bin.sh # On Solaris 10, the output of ps is truncated for long process names; use /usr/ucb/ps instead: if [[ $(uname) = "SunOS" && $(uname -r) = "5.10" ]]; then function get_child_pid { /usr/ucb/ps -awwx | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $1 }' } else function get_child_pid { ps -ef | grep "$RSYSLOG_DYNNAME.[o]mprog-restart-terminated-bin.sh" | awk '{ print $2 }' } fi startup injectmsg 0 1 wait_queueempty pid=$(getpid) echo PID: $pid start_fd_count=$(lsof -p $pid | wc -l) injectmsg 1 1 injectmsg 2 1 wait_queueempty child_pid_1=$(get_child_pid) kill -s USR1 $child_pid_1 ./msleep 100 injectmsg 3 1 injectmsg 4 1 wait_queueempty child_pid_2=$(get_child_pid) kill -s TERM $child_pid_2 ./msleep 100 injectmsg 5 1 injectmsg 6 1 injectmsg 7 1 wait_queueempty child_pid_3=$(get_child_pid) kill -s KILL $child_pid_3 ./msleep 100 injectmsg 8 1 injectmsg 9 1 wait_queueempty end_fd_count=$(lsof -p $pid | wc -l) child_pid_4=$(get_child_pid) child_lsof=$(lsof -a -d 0-65535 -p $child_pid_4 | awk '$4 != "255r" { print $4 " " $9 }') shutdown_when_empty wait_shutdown export EXPECTED="Starting Received msgnum:00000000: Received msgnum:00000001: Received msgnum:00000002: Received SIGUSR1, will terminate after the next message Received msgnum:00000003: Terminating without confirming the last message Starting Received msgnum:00000003: Received msgnum:00000004: Received SIGTERM, terminating Starting Received msgnum:00000005: Received msgnum:00000006: Received msgnum:00000007: Starting Received msgnum:00000008: Received msgnum:00000009: Terminating normally" cmp_exact $RSYSLOG_OUT_LOG if [[ "$start_fd_count" != "$end_fd_count" ]]; then echo "file descriptor leak: started with $start_fd_count open files, ended with $end_fd_count" error_exit 1 fi # Check that the child process does not inherit open fds from rsyslog # (apart from the pipes), and that stderr is redirected to /dev/null. # Ignore fd 255, which bash opens for internal use. EXPECTED_CHILD_LSOF="FD NAME 0r pipe 1w pipe 2w /dev/null" # On Solaris, lsof gives this alternate output: EXPECTED_CHILD_LSOF_2="FD NAME 0u (fifofs) 1u (fifofs) 2w " if [[ "$child_lsof" != "$EXPECTED_CHILD_LSOF" && "$child_lsof" != "$EXPECTED_CHILD_LSOF_2" ]]; then echo "unexpected open files for child process:" echo "$child_lsof" error_exit 1 fi # Check also that child process terminations are reported correctly. # When the reportChildProcessExits global parameter is "errors" (the default), # only non-zero exit codes are reported. content_check "(pid $child_pid_1) terminated; will be restarted" $RSYSLOG2_OUT_LOG custom_assert_content_missing "(pid $child_pid_1) exited with status" $RSYSLOG2_OUT_LOG content_check "(pid $child_pid_2) terminated; will be restarted" $RSYSLOG2_OUT_LOG content_check "(pid $child_pid_2) exited with status 1" $RSYSLOG2_OUT_LOG content_check "(pid $child_pid_3) terminated; will be restarted" $RSYSLOG2_OUT_LOG content_check "(pid $child_pid_3) terminated by signal 9" $RSYSLOG2_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-retry-timeout.sh0000644000000000000000000000013215062756615020406 xustar0030 mtime=1758190989.236641616 30 atime=1764931164.943703068 30 ctime=1764935934.023742525 rsyslog-8.2512.0/tests/omhttp-retry-timeout.sh0000775000175000017500000000172715062756615020064 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 export SEQ_CHECK_OPTIONS="-d" port="$(get_free_port)" omhttp_start_server $port --fail-every 1000 --fail-with-delay-secs 2 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="500") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") if $msg contains "msgnum:" then action( # Payload action.resumeRetryCount="-1" action.resumeInterval="1" name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$port'" restpath="my/endpoint" restpathtimeout="1000" checkpath="ping" batch="off" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $port my/endpoint omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmjsonparse_localvar.sh0000644000000000000000000000013215055602574020461 xustar0030 mtime=1756824956.033451498 30 atime=1764931162.224659471 30 ctime=1764935933.251730707 rsyslog-8.2512.0/tests/mmjsonparse_localvar.sh0000775000175000017500000000130415055602574020126 0ustar00rgerrger#!/bin/bash # added 2018-04-16 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' template(name="outfmt" type="string" string="%$.msgnum%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse" cookie="@cim:" container="$.") if $parsesuccess == "OK" then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m $NUMMESSAGES -j "@cim: " shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/fac_invld2.sh0000644000000000000000000000013215055602574016247 xustar0030 mtime=1756824956.028451428 30 atime=1764931161.493647746 30 ctime=1764935933.045727554 rsyslog-8.2512.0/tests/fac_invld2.sh0000775000175000017500000000114115055602574015713 0ustar00rgerrger#!/bin/bash # added 2014-10-01 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(type="string" name="outfmt" string="%msg:F,58:4%\n") invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m$NUMMESSAGES -P 3500000000 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-basic-2GB-file.sh0000644000000000000000000000013015055602574020047 xustar0030 mtime=1756824956.028451428 28 atime=1764931165.7817165 30 ctime=1764935934.271746321 rsyslog-8.2512.0/tests/imfile-basic-2GB-file.sh0000775000175000017500000000336515055602574017527 0ustar00rgerrger#!/bin/bash # written 2018-11-09 by Rainer Gerhards # this test checks that 2GiB (31 bit) file size region is handled correctly # it first generates a file that is 2GiB-64 bytes, processes it, and then # adds a couple of messages to get it over 2GiB. # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init export TB_TEST_MAX_RUNTIME=3600 # test is very slow as it works on large files generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' touch $RSYSLOG_DYNNAME.input startup # initial file: 2GiB - 1 message (54 byte) ./inputfilegen -s 2147483584 -d47 -M $RSYSLOG_DYNNAME.msgcnt > $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input export NUMMESSAGES="$(cat $RSYSLOG_DYNNAME.msgcnt)" wait_file_lines --delay 2500 --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES 3000 # add one message --> exactly 2GB ./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input (( NUMMESSAGES++ )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES # add one more message --> now we go over 2GB ./inputfilegen -m1 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input (( NUMMESSAGES++ )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES # add even more messages ./inputfilegen -m10000 -d47 -i$NUMMESSAGES>> $RSYSLOG_DYNNAME.input ls -lh $RSYSLOG_DYNNAME.input NUMMESSAGES=$(( NUMMESSAGES + 10000 )) wait_file_lines --abort-on-oversize "$RSYSLOG_OUT_LOG" $NUMMESSAGES shutdown_when_empty wait_shutdown seq_check 0 $(( NUMMESSAGES - 1)) exit_test rsyslog-8.2512.0/tests/PaxHeaders/omazureeventhubs-basic-url.sh0000644000000000000000000000013215071746523021526 xustar0030 mtime=1760021843.899421948 30 atime=1764931166.976735651 30 ctime=1764935934.628751786 rsyslog-8.2512.0/tests/omazureeventhubs-basic-url.sh0000775000175000017500000000733415071746523021204 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 export NUMMESSAGESFULL=$NUMMESSAGES export WAITTIMEOUT=20 # REQUIRES EXTERNAL ENVIRONMENT VARIABLES if [[ -z "${AZURE_HOST}" ]]; then echo "SKIP: AZURE_HOST environment variable not SET! Example: .servicebus.windows.net - SKIPPING" exit 77 fi if [[ -z "${AZURE_PORT}" ]]; then echo "SKIP: AZURE_PORT environment variable not SET! Example: 5671 - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY_NAME}" ]]; then echo "SKIP: AZURE_KEY_NAME environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_KEY}" ]]; then echo "SKIP: AZURE_KEY environment variable not SET! Example: - SKIPPING" exit 77 fi if [[ -z "${AZURE_CONTAINER}" ]]; then echo "SKIP: AZURE_CONTAINER environment variable not SET! Example: - SKIPPING" exit 77 fi export AMQPS_ADRESS="amqps://$AZURE_KEY_NAME:$AZURE_KEY@$AZURE_HOST:$AZURE_PORT/$AZURE_NAME" export AZURE_ENDPOINT="Endpoint=sb://$AZURE_HOST/;SharedAccessKeyName=$AZURE_KEY_NAME;SharedAccessKey=$AZURE_KEY;EntityPath=$AZURE_NAME" # --- Create/Start omazureeventhubs sender config generate_conf add_conf ' global( debug.whitelist="on" debug.files=["omazureeventhubs.c", "modules.c", "errmsg.c", "action.c"] ) # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") $imdiagInjectDelayMode full # Load mods module(load="../plugins/omazureeventhubs/.libs/omazureeventhubs") # templates template(name="outfmt" type="string" string="%msg:F,58:2%\n") local4.* { action( name="omazureeventhubs" type="omazureeventhubs" amqp_address="amqps://'$AZURE_KEY_NAME':'$AZURE_KEY'@'$AZURE_HOST'/'$AZURE_CONTAINER'" template="outfmt" action.resumeInterval="1" action.resumeRetryCount="2" ) action( type="omfile" file="'$RSYSLOG_OUT_LOG'") stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") ' echo Starting sender instance [omazureeventhubs] startup echo Inject messages into rsyslog sender instance injectmsg 1 $NUMMESSAGES wait_file_lines $RSYSLOG_OUT_LOG $NUMMESSAGESFULL 100 # experimental: wait until kcat receives everything timeoutend=$WAITTIMEOUT timecounter=0 echo "CHECK $RSYSLOG_DYNNAME.pstats" while [ $timecounter -lt $timeoutend ]; do (( timecounter++ )) if [ -f "$RSYSLOG_DYNNAME.pstats" ] ; then # Read IMPSTATS for verification IMPSTATSLINE=$(cat $RSYSLOG_DYNNAME.pstats | grep "origin\=omazureeventhubs" | tail -1 | cut -d: -f5) SUBMITTED_MSG=$(echo $IMPSTATSLINE | grep "submitted" | cut -d" " -f2 | cut -d"=" -f2) FAILED_MSG=$(echo $IMPSTATSLINE | grep "failures" | cut -d" " -f3 | cut -d"=" -f2) ACCEPTED_MSG=$(echo $IMPSTATSLINE | grep "accepted" | cut -d" " -f4 | cut -d"=" -f2) if ! [[ $SUBMITTED_MSG =~ $re ]] ; then echo "**** omazureeventhubs WAITING FOR IMPSTATS" else if [ "$SUBMITTED_MSG" -ge "$NUMMESSAGESFULL" ]; then if [ "$ACCEPTED_MSG" -eq "$NUMMESSAGESFULL" ]; then echo "**** omazureeventhubs SUCCESS: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" shutdown_when_empty wait_shutdown #cp $RSYSLOG_DEBUGLOG DEBUGDEBUG.log exit_test else echo "**** omazureeventhubs FAIL: NUMMESSAGESFULL: $NUMMESSAGESFULL, SUBMITTED/WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" fi else echo "**** omazureeventhubs WAITING: SUBMITTED_MSG:$SUBMITTED_MSG, ACCEPTED_MSG: $ACCEPTED_MSG, FAILED_MSG: $FAILED_MSG" fi fi fi $TESTTOOL_DIR/msleep 1000 done unset count shutdown_when_empty wait_shutdown error_exit 1 rsyslog-8.2512.0/tests/PaxHeaders/func-substring-invld-startpos.sh0000644000000000000000000000013115055602574022177 xustar0030 mtime=1756824956.028451428 30 atime=1764931157.787588277 29 ctime=1764935932.00871168 rsyslog-8.2512.0/tests/func-substring-invld-startpos.sh0000775000175000017500000000102115055602574021641 0ustar00rgerrger#!/bin/bash # addd 2023-01-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="data:%$!my_struc_data%\n") set $!my_struc_data = substring($STRUCTURED-DATA, 2000, -3); local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data' shutdown_when_empty wait_shutdown export EXPECTED='data:' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/incltest_dir_wildcard.sh0000644000000000000000000000013215035412264020565 xustar0030 mtime=1752569012.397771593 30 atime=1764931162.330661171 30 ctime=1764935933.280731151 rsyslog-8.2512.0/tests/incltest_dir_wildcard.sh0000775000175000017500000000050715035412264020236 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf add_conf "include(file=\"${srcdir}/testsuites/incltest.d/*.conf\") " startup # 100 messages are enough - the question is if the include is read ;) injectmsg 0 100 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-basic-cnf6-vg.sh0000644000000000000000000000013215035412264017702 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.720763591 30 ctime=1764935935.121759332 rsyslog-8.2512.0/tests/pgsql-basic-cnf6-vg.sh0000775000175000017500000000126015035412264017350 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' module(load="../plugins/ompgsql/.libs/ompgsql") if $msg contains "msgnum" then { action(type="ompgsql" server="127.0.0.1" db="syslogtest" user="postgres" pass="testbench") }' startup_vg injectmsg 0 5000 shutdown_when_empty wait_shutdown_vg check_exit_vg psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-msg.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/func-substring-large-neg-endpos.sh0000644000000000000000000000013115055602574022335 xustar0030 mtime=1756824956.028451428 29 atime=1764931157.81458871 30 ctime=1764935932.015711787 rsyslog-8.2512.0/tests/func-substring-large-neg-endpos.sh0000775000175000017500000000102415055602574022002 0ustar00rgerrger#!/bin/bash # addd 2023-01-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="data:%$!my_struc_data%\n") set $!my_struc_data = substring($STRUCTURED-DATA, 1, -9999999); local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data' shutdown_when_empty wait_shutdown export EXPECTED='data:' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_set_memleak-vg.sh0000644000000000000000000000013215055602574020706 xustar0030 mtime=1756824956.038451568 30 atime=1764931160.426630628 30 ctime=1764935932.736722824 rsyslog-8.2512.0/tests/rscript_set_memleak-vg.sh0000775000175000017500000000205715055602574020361 0ustar00rgerrger#!/bin/bash # A test that checks for memory leaks # created based on real world case: # https://github.com/rsyslog/rsyslog/issues/1376 # Copyright 2017-01-24 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 generate_conf add_conf ' template(name="json" type="string" string="%$!%\n") template(name="ts" type="string" string="%timestamp:::date-rfc3339%") ruleset(name="rcvr" queue.type="LinkedList" queue.timeoutShutdown="'$RSTB_GLOBAL_QUEUE_SHUTDOWN_TIMEOUT'") { set $.index="unknown"; set $.type="unknown"; set $.interval=$$now & ":" & $$hour; set $!host_forwarded=$hostname; set $!host_received=$$myhostname; set $!time_received=$timegenerated; set $!@timestamp=exec_template("ts"); action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="json" ) }' startup_vg injectmsg shutdown_when_empty wait_shutdown_vg check_exit_vg # note: we check only the valgrind result, we are not really interested # in the output data (non-standard format in any way...) exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtuxedoulog_errmsg_no_params-vg.sh0000644000000000000000000000013215035412264023006 xustar0030 mtime=1752569012.397771593 30 atime=1764931158.003591745 30 ctime=1764935932.068712599 rsyslog-8.2512.0/tests/imtuxedoulog_errmsg_no_params-vg.sh0000775000175000017500000000023615035412264022456 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/imtuxedoulog_errmsg_no_params.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_anon_ipv6.sh0000644000000000000000000000013215055603742020376 xustar0030 mtime=1756825570.303069141 30 atime=1764931168.312757055 30 ctime=1764935935.007757587 rsyslog-8.2512.0/tests/sndrcv_tls_anon_ipv6.sh0000775000175000017500000000437615055603742020057 0ustar00rgerrger#!/bin/bash # rgerhards, 2011-04-04 # testing sending and receiving via TLS with anon auth using bare ipv6, no SNI # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-ipv6-available export NUMMESSAGES=25000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # start up the instances export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem" defaultNetstreamDriver="gtls" debug.whitelist="on" debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100" streamDriver.mode="1" streamDriver.authMode="anon") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup #unset RSYSLOG_DEBUG # suppress this debug log, if you want export PORT_RCVR=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" defaultNetstreamDriver="gtls" ) # set up the action $DefaultNetstreamDriver gtls # use gtls netstream driver $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon *.* @@[::1]:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_drvr.sh0000644000000000000000000000013215035412264016565 xustar0030 mtime=1752569012.413660417 30 atime=1764931163.961687325 30 ctime=1764935933.750738346 rsyslog-8.2512.0/tests/sndrcv_drvr.sh0000775000175000017500000000006515035412264016235 0ustar00rgerrger#!/bin/bash . $srcdir/sndrcv_drvr_noexit.sh $1 $2 $3 rsyslog-8.2512.0/tests/PaxHeaders/pmrfc3164-tagEndingByColon.sh0000644000000000000000000000013215035412264021042 xustar0030 mtime=1752569012.407702108 30 atime=1764931157.871589626 30 ctime=1764935932.032712047 rsyslog-8.2512.0/tests/pmrfc3164-tagEndingByColon.sh0000775000175000017500000000222315035412264020510 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser") parser(name="custom.rfc3164" type="pmrfc3164" force.tagEndingByColon="on") template(name="outfmt" type="string" string="-%syslogtag%-%msg%-\n") ruleset(name="customparser" parser="custom.rfc3164") { :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 tag1: msgnum:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname2 tag2: msgnum:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag3 msgnum:3\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname4 tag4 :\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname5 tag5:msgnum:5\"" shutdown_when_empty wait_shutdown echo '-tag1:- msgnum:1- -tag2:- msgnum:2- -tag5:-msgnum:5-' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmsnare-ccoff.sh0000644000000000000000000000013215035412264016754 xustar0030 mtime=1752569012.408695159 30 atime=1764931168.514760291 30 ctime=1764935935.064758459 rsyslog-8.2512.0/tests/pmsnare-ccoff.sh0000775000175000017500000001311415035412264016423 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/pmsnare/.libs/pmsnare") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") global(localHostname="localhost") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\"" tcpflood -m1 -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\"" tcpflood -m1 -M "\"hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 5061 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain System Integrity Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0 -0000000000\"" shutdown_when_empty wait_shutdown echo '14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti 14,user,info,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0114624#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011Logon#011#011An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................ 13,user,notice,MSWinEventLog,MSWinEventLog, 1#011Security#01100000000#011Sun May 21 12:00:01.123#0115061#011Microsoft-Windows-Security-Auditing#011N/A#011N/A#011Success Audit#011hostname.domain#011System Integrity#011#011Cryptographic operation. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Cryptographic Parameters: Provider Name: Microsoft Software Key Storage Provider Algorithm Name: RSA Key Name: le-c6bdb786-1851-4159-b5ea-5e3966571698 Key Type: Machine key. Cryptographic Operation: Operation: Open Key. Return Code: 0x0#011-0000000000' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/fieldtest.sh0000644000000000000000000000013215035412264016214 xustar0030 mtime=1752569012.389827181 30 atime=1764931159.028608196 30 ctime=1764935932.357717023 rsyslog-8.2512.0/tests/fieldtest.sh0000775000175000017500000000166215035412264015670 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%msg:F,32:2%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: DROP_url_www.sina.com.cn:IN=eth1 OUT=eth0 SRC=192.168.10.78 DST=61.172.201.194 LEN=1182 TOS=0x00 PREC=0x00 TTL=63 ID=14368 DF PROTO=TCP SPT=33343 DPT=80 WINDOW=92 RES=0x00 ACK PSH URGP=0\"" shutdown_when_empty wait_shutdown echo 'DROP_url_www.sina.com.cn:IN=eth1' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_not_supported3.sh0000644000000000000000000000013215035412264023523 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.111593478 30 ctime=1764935932.099713073 rsyslog-8.2512.0/tests/imbatchreport_errmsg_not_supported3.sh0000775000175000017500000000061615035412264023175 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" reports="*.done") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "either 'rename' or 'delete' must be set" exit_test rsyslog-8.2512.0/tests/PaxHeaders/include-obj-text-vg.sh0000644000000000000000000000013215035412264020020 xustar0030 mtime=1752569012.398764645 30 atime=1764931159.230611438 30 ctime=1764935932.414717895 rsyslog-8.2512.0/tests/include-obj-text-vg.sh0000775000175000017500000000104615035412264017470 0ustar00rgerrger#!/bin/bash # added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf INCLFILE="${srcdir}/testsuites/include-std-omfile-action.conf" export CONF_SNIPPET=`cat $INCLFILE` printf "\nThis SNIPPET will be included via env var:\n$CONF_SNIPPET\n\nEND SNIPPET\n" add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then { include(text=`echo $CONF_SNIPPET`) } ' startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg seq_check 0 9 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_exists-not2.sh0000644000000000000000000000013215055602574020205 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.868621676 30 ctime=1764935932.581720451 rsyslog-8.2512.0/tests/rscript_exists-not2.sh0000775000175000017500000000103115055602574017647 0ustar00rgerrger#!/bin/bash # add 2020-10-02 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%!result%\n") set $!somevar = "test"; # this makes matters a bit more complicated if $msg contains "msgnum" then { if exists($!p1!p2!val) then set $!result = "on"; else set $!result = "off"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='off' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmtaghostname_server.sh0000644000000000000000000000013215035412264020463 xustar0030 mtime=1752569012.401743799 30 atime=1764931158.030592178 30 ctime=1764935932.075712706 rsyslog-8.2512.0/tests/mmtaghostname_server.sh0000775000175000017500000000211515035412264020131 0ustar00rgerrger#!/bin/bash # add 2016-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/mmtaghostname/.libs/mmtaghostname") global(localhostname="frontAPP") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") template(name="test" type="string" string="tag: %syslogtag%, server: %hostname%, msg: %msg%\n") ruleset(name="ruleset") { action(type="mmtaghostname" forcelocalhostname="on") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="test") } ' startup tcpflood -m1 -M "\"<189>1 2019-03-03T16:09:56.185+00:00 server app 123.4 msgid - %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)\"" shutdown_when_empty wait_shutdown echo 'tag: app[123.4], server: frontAPP, msg: %SYS-5-CONFIG_I: Configured from console by adminsepp on vty0 (10.23.214.226)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-old-state-file.sh0000644000000000000000000000013215035412264020305 xustar0030 mtime=1752569012.392806336 30 atime=1764931166.118721901 30 ctime=1764935934.377747943 rsyslog-8.2512.0/tests/imfile-old-state-file.sh0000775000175000017500000000515115035412264017756 0ustar00rgerrger#!/bin/bash # this test checks that old (v1, pre 8.34.0) imfile state files are # properly read in. It is based on imfile-readmode2-with-persists.sh, # where the first part before the shutdown is removed, and an old state # file is populated. Note that in contrast to the original test the # initial set of lines from the input file is missing - this is # exactly what shall happen. # This is part of the rsyslog testbench, licensed under ASL 2.0 # added 2018-03-29 by rgerhards . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' # do mock-up setup echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input # we need to patch the state file to match the current inode number inode=$(ls -i $RSYSLOG_DYNNAME.input|awk '{print $1}') leninode=${#inode} newline="+inode:2:${leninode}:${inode}:" sed s/+inode:2:7:4464465:/${newline}/ <$srcdir/testsuites/imfile-old-state-file_imfile-state_.-rsyslog.input > ${RSYSLOG_DYNNAME}.spool/imfile-state\:.-$RSYSLOG_DYNNAME.input printf "info: new input file: $(ls -i $RSYSLOG_DYNNAME.input)\n" printf "info: new inode line: ${newline}\n" printf "info: patched state file:\n" cat ${RSYSLOG_DYNNAME}.spool/imfile-state\:.-$RSYSLOG_DYNNAME.input startup echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" cat $RSYSLOG_OUT_LOG error_exit 1 else # note: we expect only 2 headers as the first file part if NOT processed! if [ ! $NUMLINES -eq 2 ]; then echo "ERROR: expecting 2 headers, got $NUMLINES" cat $RSYSLOG_OUT_LOG error_exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {2..4}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" cat $RSYSLOG_OUT_LOG error_exit 1 fi done exit_test rsyslog-8.2512.0/tests/PaxHeaders/omrelp-invld-tlslib.sh0000644000000000000000000000013215035412264020130 xustar0030 mtime=1752569012.406709056 30 atime=1764931164.110689714 30 ctime=1764935933.793739004 rsyslog-8.2512.0/tests/omrelp-invld-tlslib.sh0000775000175000017500000000070415035412264017600 0ustar00rgerrger#!/bin/bash # see that we can an error message if wrong tls lib is selected # addd 2019-02-09 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init require_relpEngineSetTLSLibByName generate_conf add_conf ' module(load="../plugins/omrelp/.libs/omrelp" tls.tlslib="invalid-tlslib-name") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty content_check --regex "omrelp.*invalid-tlslib-name.*not accepted" exit_test rsyslog-8.2512.0/tests/PaxHeaders/timereported-utc.sh0000644000000000000000000000013215055602574017534 xustar0030 mtime=1756824956.042451623 30 atime=1764931161.710651227 30 ctime=1764935933.107728503 rsyslog-8.2512.0/tests/timereported-utc.sh0000775000175000017500000000157615055602574017214 0ustar00rgerrger#!/bin/bash # addd 2016-03-22 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=3 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' template(name="outfmt" type="list") { property(name="timereported" dateformat="rfc3339" date.inUTC="on") constant(value="\n") } :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg_literal "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000" injectmsg_literal "<165>1 2016-03-01T12:00:00-02:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000" injectmsg_literal "<165>1 2016-03-01T12:00:00Z 192.0.2.1 tcpflood 8710 - - msgnum:0000000" shutdown_when_empty wait_shutdown export EXPECTED="2003-08-24T12:14:15.000003+00:00 2016-03-01T14:00:00.000000+00:00 2016-03-01T12:00:00.000000+00:00" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_both_modes_compatible.sh0000644000000000000000000000013115055602574022126 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.374629794 29 ctime=1764935932.72272261 rsyslog-8.2512.0/tests/mmanon_both_modes_compatible.sh0000775000175000017500000000202315055602574021573 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv4.enable="on" ipv4.mode="zero" ipv4.bits="32" ipv6.bits="128" ipv6.anonmode="zero" ipv6.enable="on") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 tag: 1.1.1.8 space 61:34:ad::7:F <129>Mar 10 01:00:00 172.20.245.8 tag: 111.1.1.8 <129>Mar 10 01:00:00 172.20.245.8 tag: abf:3:002::500F:ce 1.1.1.9\"" shutdown_when_empty wait_shutdown export EXPECTED=' 0:0:0:0:0:0:0:0 0.0.0.0 space 0:0:0:0:0:0:0:0 0.0.0.0 0:0:0:0:0:0:0:0 0.0.0.0' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-basic-hup.sh0000644000000000000000000000013115035412264017215 xustar0029 mtime=1752569012.39578549 30 atime=1764931162.868669799 30 ctime=1764935933.434733509 rsyslog-8.2512.0/tests/imtcp-basic-hup.sh0000775000175000017500000000131315035412264016663 0ustar00rgerrger#!/bin/bash # added 2019-07-30 by RGerhards, released under ASL 2.0 export NUMMESSAGES=4000 # MUST be an even number! . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) issue_HUP tcpflood -p$TCPFLOOD_PORT -m$((NUMMESSAGES / 2)) -i$((NUMMESSAGES / 2)) shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-basic-legacy.sh0000644000000000000000000000013115055602574020025 xustar0030 mtime=1756824956.028451428 30 atime=1764931165.773716372 29 ctime=1764935934.26974629 rsyslog-8.2512.0/tests/imfile-basic-legacy.sh0000775000175000017500000000153015055602574017474 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init NUMMESSAGES=50000 mkdir WorkDirectory $RSYSLOG_DYNNAME.work generate_conf add_conf ' $WorkDirectory '$RSYSLOG_DYNNAME'.work $ModLoad ../plugins/imfile/.libs/imfile $InputFileName ./'$RSYSLOG_DYNNAME'.input $InputFileTag file: $InputFileStateFile stat-file1 $InputFileSeverity error $InputFileFacility local7 $InputFileMaxLinesAtOnce 100000 $InputRunFileMonitor $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' # generate input file first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). ./inputfilegen -m $NUMMESSAGES > $RSYSLOG_DYNNAME.input startup wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl_setenv_2_vars.sh0000644000000000000000000000013215035412264020011 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.955590974 30 ctime=1764935932.054712384 rsyslog-8.2512.0/tests/glbl_setenv_2_vars.sh0000775000175000017500000000142415035412264017461 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(environment=["http_proxy=http://127.0.0.1", "SECOND=OK OK"]) set $!prx = getenv("http_proxy"); set $!second = getenv("SECOND"); template(name="outfmt" type="string" string="%$!prx%, %$!second%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo 'http://127.0.0.1, OK OK' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid content seen, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mysql-actq-mt-withpause.sh0000644000000000000000000000013215055602574020760 xustar0030 mtime=1756824956.033451498 30 atime=1764931166.726731645 30 ctime=1764935934.559750729 rsyslog-8.2512.0/tests/mysql-actq-mt-withpause.sh0000775000175000017500000000157415055602574020436 0ustar00rgerrger#!/bin/bash # test for mysql with multithread actionq # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=150000 generate_conf add_conf ' module(load="../plugins/ommysql/.libs/ommysql") :msg, contains, "msgnum:" { action(type="ommysql" server="127.0.0.1" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench" queue.size="10000" queue.type="linkedList" queue.workerthreads="5" queue.workerthreadMinimumMessages="500" queue.timeoutWorkerthreadShutdown="1000" queue.timeoutEnqueue="20000" ) } ' mysql_prep_for_test startup injectmsg 0 50000 wait_queueempty echo waiting for worker threads to timeout ./msleep 3000 injectmsg 50000 50000 wait_queueempty echo waiting for worker threads to timeout ./msleep 2000 injectmsg 100000 50000 shutdown_when_empty wait_shutdown mysql_get_data seq_check mysql_cleanup_test exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_prog_confirm_killonclose.sh0000644000000000000000000000013215035412264022670 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.593697457 30 ctime=1764935933.928741071 rsyslog-8.2512.0/tests/improg_prog_confirm_killonclose.sh0000775000175000017500000000133015035412264022334 0ustar00rgerrger#!/bin/bash # add 2019-04-04 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/improg/.libs/improg") input(type="improg" tag="tag" ruleset="ruleset" binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -c -n 1 -g" confirmmessages="on" signalonclose="on" killunresponsive="on" ) ruleset(name="ruleset") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'") } ' startup shutdown_when_empty wait_shutdown content_check "program data" if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then echo $RSYSLOG_DYNNAME'.stderr missing' error_exit 1 fi export EXPECTED='START Received ACK Received SIGTERM Received' cmp_exact $RSYSLOG_DYNNAME.stderr exit_test rsyslog-8.2512.0/tests/PaxHeaders/tcp_forwarding_ns_tpl.sh0000644000000000000000000000013215071746523020630 xustar0030 mtime=1760021843.909422106 30 atime=1764931158.809604681 30 ctime=1764935932.294716058 rsyslog-8.2512.0/tests/tcp_forwarding_ns_tpl.sh0000775000175000017500000000344715071746523020307 0ustar00rgerrger#!/bin/bash # This test tests tcp forwarding in a network namespace with assigned template. # To do so, a simple tcp listener service is started in a network namespace. # Released under GNU GPLv3+ echo =============================================================================== echo \[tcp_forwarding_ns_tpl.sh\]: test for tcp forwarding in a network namespace with assigned template echo This test must be run as root [network namespace creation/change required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi # create the pipe and start a background process that copies data from # it to the "regular" work file . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfwd" template="outfmt" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp" networknamespace="rsyslog_test_ns") ' # create network namespace and bring it up ip netns add rsyslog_test_ns ip netns exec rsyslog_test_ns ip link set dev lo up # run server in namespace ip netns exec rsyslog_test_ns ./minitcpsrv -t127.0.0.1 -p"$TCPFLOOD_PORT" -f $RSYSLOG_OUT_LOG & BGPROCESS=$! echo background minitcpsrvr process id is $BGPROCESS # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # note: minitcpsrvr shuts down automatically if the connection is closed! # (we still leave the code here in in case we need it later) #echo shutting down minitcpsrv... #kill $BGPROCESS #wait $BGPROCESS #echo background process has terminated, continue test... # remove network namespace ip netns delete rsyslog_test_ns # and continue the usual checks seq_check 0 9999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-input-basic.sh0000644000000000000000000000013115055603742021343 xustar0030 mtime=1756825570.301069108 29 atime=1764931163.15367437 30 ctime=1764935933.516734764 rsyslog-8.2512.0/tests/imtcp-tls-ossl-input-basic.sh0000775000175000017500000000212415055603742021012 0ustar00rgerrger#!/bin/bash # added 2011-02-28 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "nsd_ptcp.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" streamDriver.CAFile="'$srcdir'/tls-certs/ca.pem" streamDriver.CertFile="'$srcdir'/tls-certs/cert.pem" streamDriver.KeyFile="'$srcdir'/tls-certs/key.pem") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-pos-from-to.sh0000644000000000000000000000013215035412264020224 xustar0030 mtime=1752569012.416639571 30 atime=1764931161.347645404 30 ctime=1764935933.004726927 rsyslog-8.2512.0/tests/template-pos-from-to.sh0000775000175000017500000000103115035412264017666 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # addd 2016-03-28 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:9:16:%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m9 shutdown_when_empty wait_shutdown seq_check 0 8 exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-retry-error.sh0000644000000000000000000000013215035412264020654 xustar0030 mtime=1752569012.385854976 30 atime=1764931162.355661572 30 ctime=1764935933.287731259 rsyslog-8.2512.0/tests/clickhouse-retry-error.sh0000775000175000017500000000127715035412264020332 0ustar00rgerrger#!/bin/bash # add 2018-12-31 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 generate_conf add_conf ' module(load="../plugins/omclickhouse/.libs/omclickhouse") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.retryerror (id, severity, message) VALUES (%msg:F,58:2%, %syslogseverity%, ' add_conf "'%msg%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" bulkmode="off" user="default" pwd="" template="outfmt") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg shutdown_when_empty wait_shutdown content_check "omclickhouse: checkConn failed." exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmaitag-invalid-key.sh0000644000000000000000000000013215055605325020066 xustar0030 mtime=1756826325.657800804 30 atime=1764931161.753651917 30 ctime=1764935933.119728687 rsyslog-8.2512.0/tests/mmaitag-invalid-key.sh0000775000175000017500000000121115055605325017530 0ustar00rgerrger#!/bin/bash ## test gemini provider with invalid API key . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmaitag/.libs/mmaitag") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg% [%$.aitag%]\n") if($msg contains "msgnum:00") then { action(type="mmaitag" provider="gemini" apikey="dummy") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -m 1 shutdown_when_empty wait_shutdown content_check "request for a message failed" "$RSYSLOG_OUT_LOG" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_parse_json.sh0000644000000000000000000000013215035412264020142 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.772620135 30 ctime=1764935932.555720053 rsyslog-8.2512.0/tests/rscript_parse_json.sh0000775000175000017500000000112715035412264017612 0ustar00rgerrger#!/bin/bash # Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$!%\n") local4.* { set $.ret = parse_json("{ \"c1\":\"data\" }", "\$!parsed"); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED='{ "parsed": { "c1": "data" } }' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse-nodate-udp.sh0000644000000000000000000000013015035412264021571 xustar0030 mtime=1752569012.406709056 30 atime=1764931159.003607795 28 ctime=1764935932.3497169 rsyslog-8.2512.0/tests/parsertest-parse-nodate-udp.sh0000775000175000017500000000215715035412264021247 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<27>xapi: [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)\"" tcpflood -m1 -T "udp" -M "\"This is a message!\"" shutdown_when_empty wait_shutdown export EXPECTED="27,daemon,err,$RS_HOSTNAME,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message) 13,user,notice,This,is,is, a message!" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/dircreate_dflt.sh0000644000000000000000000000013115035412264017203 xustar0030 mtime=1752569012.386848027 29 atime=1764931166.46872751 30 ctime=1764935934.484749581 rsyslog-8.2512.0/tests/dircreate_dflt.sh0000775000175000017500000000157115035412264016657 0ustar00rgerrger#!/bin/bash # Test for automatic creation of dynafile directories # note that we use the "'${RSYSLOG_DYNNAME}'.spool" directory, because it is handled by diag.sh # in any case, so we do not need to add any extra new test dir. # added 2009-11-30 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # set spool locations and switch queue to disk-only mode $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueFilename mainq $MainMsgQueueType disk $template dynfile,"'$RSYSLOG_DYNNAME'.logdir/'$RSYSLOG_OUT_LOG'" *.* ?dynfile ' startup injectmsg 0 1 # a single message is sufficient shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown if [ ! -e $RSYSLOG_DYNNAME.logdir/$RSYSLOG_OUT_LOG ] then echo "$RSYSLOG_DYNNAME.logdir or logfile not created!" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/tabescape_dflt-udp.sh0000644000000000000000000000013115035412264017756 xustar0029 mtime=1752569012.41564652 30 atime=1764931166.433726949 30 ctime=1764935934.475749444 rsyslog-8.2512.0/tests/tabescape_dflt-udp.sh0000775000175000017500000000137415035412264017433 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\"" shutdown_when_empty wait_shutdown echo ' before HT#011after HT (do NOT remove TAB!)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmdb-container.sh0000644000000000000000000000013215035412264017130 xustar0030 mtime=1752569012.400750748 30 atime=1764931162.282660401 30 ctime=1764935933.267730952 rsyslog-8.2512.0/tests/mmdb-container.sh0000775000175000017500000000152115035412264016576 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$!mmdb_root%\n") module(load="../plugins/mmdblookup/.libs/mmdblookup" container="!mmdb_root") module(load="../plugins/mmnormalize/.libs/mmnormalize") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmnormalize" rulebase=`echo $srcdir/mmdb.rb`) action(type="mmdblookup" mmdbfile=`echo $srcdir/test.mmdb` key="$!ip" fields="city" ) action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m 1 -j "202.106.0.20\ " shutdown_when_empty wait_shutdown content_check '{ "city": "Beijing" }' exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmdb-multilevel-vg.sh0000644000000000000000000000013215035412264017742 xustar0030 mtime=1752569012.400750748 30 atime=1764931162.298660658 30 ctime=1764935933.271731014 rsyslog-8.2512.0/tests/mmdb-multilevel-vg.sh0000775000175000017500000000251615035412264017415 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # we libmaxminddb, in packaged versions, has a small cosmetic memory leak, # thus we need a suppressions file: export RS_TESTBENCH_VALGRIND_EXTRA_OPTS="$RS_TESTBENCH_VALGRIND_EXTRA_OPTS --suppressions=$srcdir/libmaxmindb.supp" generate_conf add_conf ' template(name="outfmt" type="string" string="%$!iplocation%\n") module(load="../plugins/mmdblookup/.libs/mmdblookup") module(load="../plugins/mmnormalize/.libs/mmnormalize") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmnormalize" rulebase="'$srcdir'/mmdb.rb") # Uncomment this action when using the real GeoLite2 city database; # we have not included it into the testbench for licensing concerns. # action(type="mmdblookup" mmdbfile="/home/USR/GeoLite2-City_20170502/GeoLite2-City.mmdb" key="$!ip" fields=":city:!city!names!en" ) action(type="mmdblookup" mmdbfile="'$srcdir'/test.mmdb" key="$!ip" fields=":city_name:city" ) action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") }' startup_vg tcpflood -m 100 -j "202.106.0.20\ " shutdown_when_empty wait_shutdown_vg check_exit_vg content_check '{ "city_name": "Beijing" }' exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_certvalid.sh0000644000000000000000000000013215055602574020456 xustar0030 mtime=1756824956.040451596 30 atime=1764931168.328757312 30 ctime=1764935935.011757648 rsyslog-8.2512.0/tests/sndrcv_tls_certvalid.sh0000775000175000017500000000373615055602574020136 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls} export NUMMESSAGES=10000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="'$RS_TLS_DRIVER'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="'$RS_TLS_DRIVER'" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup export PORT_RCVR=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="'$RS_TLS_DRIVER'" ) # set up the action $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode x509/certvalid *.* @@127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/manytcp-too-few-tls-vg.sh0000644000000000000000000000013215103346332020472 xustar0030 mtime=1762512090.634176013 30 atime=1764931163.137674113 30 ctime=1764935933.510734672 rsyslog-8.2512.0/tests/manytcp-too-few-tls-vg.sh0000775000175000017500000000366615103346332020154 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # released under ASL 2.0 export USE_VALGRIND="YES" . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test does not work on FreeBSD" export NUMMESSAGES=40000 # we unfortunately need many messages as we have many connections export TB_TEST_MAX_RUNTIME=1800 # this test is VERY slow, so we need to override max runtime generate_conf add_conf ' $MaxOpenFiles 200 global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem" defaultNetstreamDriver="gtls" debug.whitelist="on" debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module(load="../plugins/imtcp/.libs/imtcp" maxSessions="1100" streamDriver.mode="1" streamDriver.authMode="anon") input(type="imtcp" socketBacklog="1000" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup_vg # the config file specifies exactly 1100 connections tcpflood -c1000 -m$NUMMESSAGES -Ttls -x$srcdir/testsuites/x.509/ca.pem -Z$srcdir/testsuites/x.509/client-cert.pem -z$srcdir/testsuites/x.509/client-key.pem # the sleep below is needed to prevent too-early termination of the tcp listener # note: this must not be precise, as message loss is acceptable sleep 5 shutdown_when_empty wait_shutdown_vg check_exit_vg # we do not do a seq check, as of the design of this test some messages # will be lost. So there is no point in checking if all were received. The # point is that we look at the valgrind result, to make sure we do not # have a mem leak in those error cases (we had in the past, thus the test # to prevent that in the future). exit_test rsyslog-8.2512.0/tests/PaxHeaders/discard-rptdmsg.sh0000644000000000000000000000013215055602574017327 xustar0030 mtime=1756824956.026451401 30 atime=1764931163.802684776 30 ctime=1764935933.701737596 rsyslog-8.2512.0/tests/discard-rptdmsg.sh0000775000175000017500000000122215055602574016773 0ustar00rgerrger#!/bin/bash # testing discard-rptdmsg functionality when no repeated message is present # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") $RepeatedMsgReduction on :msg, contains, "00000001" ~ :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -m10 -i1 shutdown_when_empty wait_shutdown seq_check 2 10 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_privdropuserid.sh0000644000000000000000000000013215055602574021067 xustar0030 mtime=1756824956.038451568 30 atime=1764931161.224643431 30 ctime=1764935932.966726345 rsyslog-8.2512.0/tests/rscript_privdropuserid.sh0000775000175000017500000000112115055602574020531 0ustar00rgerrger#!/bin/bash # added 2021-09-23 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.user.id="'${TESTBENCH_TESTUSER[uid]}'") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_relp_tls.sh0000644000000000000000000000013115055602574017442 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.176690772 29 ctime=1764935933.81373931 rsyslog-8.2512.0/tests/sndrcv_relp_tls.sh0000775000175000017500000000230715055602574017114 0ustar00rgerrger#!/bin/bash # added 2013-12-10 by Rgerhards # testing sending and receiving via relp with TLS enabled # This file is part of the rsyslog project, released under ASL 2.0 # uncomment for debugging support: . ${srcdir:=.}/diag.sh init # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' module(load="../plugins/imrelp/.libs/imrelp") # then SENDER sends to this port (not tcpflood!) input(type="imrelp" port="'$PORT_RCVR'" tls="on") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' module(load="../plugins/omrelp/.libs/omrelp") action(type="omrelp" target="127.0.0.1" port="'$PORT_RCVR'" tls="on") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 50000 # shut down sender shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # do the final check seq_check 1 50000 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omjournal-basic-no-template.sh0000644000000000000000000000013215035412264021541 xustar0030 mtime=1752569012.404722953 30 atime=1764931161.642650136 30 ctime=1764935933.089728228 rsyslog-8.2512.0/tests/omjournal-basic-no-template.sh0000775000175000017500000000142015035412264021205 0ustar00rgerrger#!/bin/bash # a basic test for omjournal. # addd 2016-03-18 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh require-journalctl generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omjournal/.libs/omjournal") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omjournal") ' startup tcpflood -m1 -M "\"<133>2011-03-01T11:22:12Z host tag msgh RsysLoG-TESTBENCH $COOKIE\"" ./msleep 500 shutdown_when_empty wait_shutdown # if we reach this, we have at least not aborted journalctl -r -t rsyslogd: |grep "RsysLoG-TESTBENCH $COOKIE" if [ $? -ne 1 ]; then echo "error: cookie $COOKIE not found. Head of journal:" journalctl -r -t rsyslogd: | head exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/manyptcp.sh0000644000000000000000000000013115055603742016070 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.391678186 29 ctime=1764935933.58573582 rsyslog-8.2512.0/tests/manyptcp.sh0000775000175000017500000000122615055603742015541 0ustar00rgerrger#!/bin/bash # test imptcp with large connection count # test many concurrent tcp connections # released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=40000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' $MaxOpenFiles 2000 module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" SocketBacklog="1000" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -c1000 -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_omudpspoof.sh0000644000000000000000000000013215035412264020003 xustar0030 mtime=1752569012.414653468 30 atime=1764931164.341693417 30 ctime=1764935933.857739984 rsyslog-8.2512.0/tests/sndrcv_omudpspoof.sh0000775000175000017500000000420415035412264017452 0ustar00rgerrger#!/bin/bash # This runs sends and receives messages via UDP to the standard # ports. Note that with UDP we can always have message loss. While this is # less likely in a local environment, we strongly limit the amount of data # we send in the hope to not lose any messages. However, failure of this # test does not necessarily mean that the code is wrong (but it is very likely!) # added 2009-11-11 by Rgerhards # This file is part of the rsyslog project, released under GPLv3 echo =============================================================================== echo \[sndrcv_omudpspoof.sh\]: testing sending and receiving via omudp echo This test must be run as root [raw socket access required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi export TCPFLOOD_EXTRA_OPTS="-b1 -W1" # uncomment for debugging support: . ${srcdir:=.}/diag.sh init # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' $ModLoad ../plugins/imudp/.libs/imudp # then SENDER sends to this port (not tcpflood!) $UDPServerRun 514 $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp # this listener is for message generation by the test framework! $InputTCPServerRun '$TCPFLOOD_PORT' $ModLoad ../plugins/omudpspoof/.libs/omudpspoof $template spoofaddr,"127.0.0.1" #begin action definition $ActionOMUDPSpoofSourceNameTemplate spoofaddr $ActionOMUDPSpoofTargetHost 127.0.0.1 $ActionOMUDPSpoofSourcePortStart 514 $ActionOMUDPSpoofSourcePortEnd 514 *.* :omudpspoof: ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m50 -i1 sleep 5 # make sure all data is received in input buffers # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # do the final check seq_check 1 50 rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_priorityString.sh0000644000000000000000000000013115035412264021541 xustar0029 mtime=1752569012.41564652 30 atime=1764931168.320757184 30 ctime=1764935935.009757618 rsyslog-8.2512.0/tests/sndrcv_tls_priorityString.sh0000775000175000017500000000436715035412264021223 0ustar00rgerrger#!/bin/bash # Pascal Withopf, 2017-07-25 # testing sending and receiving via TLS with anon auth # NOTE: When this test fails, it could be due to the priorityString being outdated! # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=2500 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # start up the instances export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' # certificates global( defaultNetstreamDriverCAFile="'$srcdir'/testsuites/x.509/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/testsuites/x.509/client-cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/testsuites/x.509/client-key.pem" defaultNetstreamDriver="gtls" ) module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" gnutlspriorityString="NORMAL:-MD5") input(type="imtcp" port="'$PORT_RCVR'") template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum" then { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh add_conf ' #certificates global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="gtls" ) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfwd" Target="127.0.0.1" port="'$PORT_RCVR'" Protocol="tcp" streamdriver="gtls" StreamDriverAuthMode="anon" StreamDriverMode="1" gnutlsprioritystring="NORMAL:-MD5") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 wait_file_lines # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-basic.sh0000644000000000000000000000013215055603742017652 xustar0030 mtime=1756825570.302069124 30 atime=1764931161.860653633 30 ctime=1764935933.149729146 rsyslog-8.2512.0/tests/pmnormalize-basic.sh0000775000175000017500000000267615055603742017334 0ustar00rgerrger#!/bin/bash # add 2016-12-08 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/pmnormalize/.libs/pmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") parser(name="custom.pmnormalize" type="pmnormalize" rulebase="'$srcdir'/testsuites/pmnormalize_basic.rulebase") template(name="test" type="string" string="host: %hostname%, ip: %fromhost-ip%, tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n") ruleset(name="ruleset" parser="custom.pmnormalize") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="test") } ' startup tcpflood -m1 -M "\"<189> ubuntu tag1: is no longer listening on 127.0.0.1 test\"" tcpflood -m1 -M "\"<112> debian tag2: is no longer listening on 255.255.255.255 test\"" tcpflood -m1 -M "\"<177> centos tag3: is no longer listening on 192.168.0.9 test\"" shutdown_when_empty wait_shutdown sort < $RSYSLOG_OUT_LOG > ${RSYSLOG_OUT_LOG}.sorted export EXPECTED='host: centos, ip: 192.168.0.9, tag: tag3, pri: 177, syslogfacility: 22, syslogseverity: 1 msg: test host: debian, ip: 255.255.255.255, tag: tag2, pri: 112, syslogfacility: 14, syslogseverity: 0 msg: test host: ubuntu, ip: 127.0.0.1, tag: tag1, pri: 189, syslogfacility: 23, syslogseverity: 5 msg: test' cmp_exact ${RSYSLOG_OUT_LOG}.sorted exit_test rsyslog-8.2512.0/tests/PaxHeaders/fac_invld3.sh0000644000000000000000000000013215055602574016250 xustar0030 mtime=1756824956.028451428 30 atime=1764931161.501647874 30 ctime=1764935933.047727585 rsyslog-8.2512.0/tests/fac_invld3.sh0000775000175000017500000000113215055602574015714 0ustar00rgerrger#!/bin/bash # added 2014-10-01 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(type="string" name="outfmt" string="%msg:F,58:4%\n") invld.=debug action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m$NUMMESSAGES -P x112 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_gt_var.sh0000644000000000000000000000013215035412264017261 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.429614631 30 ctime=1764935932.473718798 rsyslog-8.2512.0/tests/rscript_gt_var.sh0000775000175000017500000000275715035412264016743 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_gt.sh\]: testing rainerscript GT statement for two JSON variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } set $!var1 = "43"; set $!var2 = "42"; if $!var1 > $!var2 then { if $!var2 > $!var1 then { # Failure stop } else { unset $!var1; unset $!var2; } } else { # Failure stop } set $.var1 = "43"; set $.var2 = "42"; if $.var1 > $.var2 then { if $.var2 > $.var1 then { # Failure stop } else { unset $.var1; unset $.var2; } } else { # Failure stop } set $/var1 = "43"; set $/var2 = "42"; if $/var1 > $/var2 then { if $/var2 > $/var1 then { # Failure stop } else { unset $/var1; unset $/var2; } } else { # Failure stop } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 1 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-netns.sh0000644000000000000000000000013215114522477016500 xustar0030 mtime=1764926783.043632054 30 atime=1764926783.489643004 30 ctime=1764935933.241730554 rsyslog-8.2512.0/tests/imtcp-netns.sh0000775000175000017500000000622415114522477016153 0ustar00rgerrger#!/bin/bash # This test tests listening on ports in another network namespace. echo =============================================================================== echo \[imtcp-netns.sh\]: test for listening in another network namespace echo This test must be run with CAP_SYS_ADMIN capabilities [network namespace creation/change required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi . ${srcdir:=.}/diag.sh init generate_conf NS_PREFIX=$(basename ${RSYSLOG_DYNNAME}) NS_DEFAULT="${NS_PREFIX}.rsyslog_ns_default" NS_FAIL=( "${NS_PREFIX}.rsyslog_ns_a_fail" "${NS_PREFIX}.rsyslog_ns_b_fail" ) NS_GOOD=( "${NS_PREFIX}.rsyslog_ns_c" "${NS_PREFIX}.rsyslog_ns_d" ) add_conf ' $MainMsgQueueTimeoutShutdown 10000 module( load="../plugins/imtcp/.libs/imtcp" NetworkNamespace="'${NS_DEFAULT}'" ) input( Type="imtcp" Port="0" Address="127.0.0.1" ListenPortFileName="'${NS_DEFAULT}'.port" ) ' for ns in "${NS_GOOD[@]}" "${NS_FAIL[@]}"; do add_conf ' input( Type="imtcp" Port="0" Address="127.0.0.1" NetworkNamespace="'${ns}'" ListenPortFileName="'${ns}'.port" ) ' done add_conf ' input( Type="imtcp" Port="0" Address="127.0.0.1" NetworkNamespace="" ListenPortFileName="'$RSYSLOG_DYNNAME'.port" ) template(name="outfmt" type="string" string="%msg:%\n") :msg, contains, "imtcp-netns:" action( type="omfile" file="'${RSYSLOG_OUT_LOG}'" template="outfmt" ) ' # # create network namespace and bring it up NS=( "${NS_DEFAULT}" "${NS_GOOD[@]}" ) for ns in "${NS[@]}"; do ip netns add "${ns}" ip netns exec "${ns}" ip link set dev lo up done for ns in "${NS_FAIL[@]}"; do ip netns delete "${ns}" > /dev/null 2>&1 done # now do the usual run RS_REDIR="> ${RSYSLOG_DYNNAME}.log 2>&1" startup wait_file_exists "${RSYSLOG_DYNNAME}.port" for ns in "${NS[@]}"; do wait_file_exists "${ns}.port" done MSGS=() function logmsg() { local ns=$1 local msg=$2 local logger_cmd=() local port_file=${RSYSLOG_DYNNAME}.port if [[ -n "${ns}" ]]; then logger_cmd+=(ip netns exec "${ns}") port_file="${ns}.port" fi logger_cmd+=( logger --tcp --server 127.0.0.1 --octet-count --tag "$0" --port "$(cat ${port_file})" -- "imtcp-netns: ${msg}" ) "${logger_cmd[@]}" MSGS+=("imtcp-netns: ${msg}") } # Inject a few messages logmsg "" "start message from local namespace" for ns in "${NS[@]}"; do logmsg "${ns}" "test message from namespace ${ns}" # Try to keep them ordered sleep 1 done logmsg "" "end message from local namespace" shutdown_when_empty wait_shutdown # remove network namespaces for ns in "${NS[@]}"; do ip netns delete "${ns}" done EXPECTED=$(printf "%s\n" "${MSGS[@]}") cmp_exact # Verify we have error messages for the missing namespaces # We don't redirect with valgrind, so skip this check with valgrind if [[ "${USE_VALGRIND}" != "YES" ]]; then for ns in "${NS_FAIL[@]}"; do content_check "netns_switch: could not open namespace '${ns}':" ${RSYSLOG_DYNNAME}.log done fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-subscribe-vg.sh0000644000000000000000000000013215055602574020606 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.001639854 30 ctime=1764935932.900725334 rsyslog-8.2512.0/tests/imhiredis-subscribe-vg.sh0000775000175000017500000000030415055602574020252 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-subscribe.sh rsyslog-8.2512.0/tests/PaxHeaders/mysql-actq-mt-withpause-vg.sh0000644000000000000000000000013215035412264021363 xustar0030 mtime=1752569012.402736851 30 atime=1764931166.734731773 30 ctime=1764935934.562750775 rsyslog-8.2512.0/tests/mysql-actq-mt-withpause-vg.sh0000775000175000017500000000023015035412264021025 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:=.}/mysql-actq-mt-withpause.sh rsyslog-8.2512.0/tests/PaxHeaders/imrelp-manyconn-vg.sh0000644000000000000000000000013115035412264017752 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.044688656 30 ctime=1764935933.774738713 rsyslog-8.2512.0/tests/imrelp-manyconn-vg.sh0000775000175000017500000000060315035412264017421 0ustar00rgerrger#!/bin/bash if [ "$CI_ENV" == "Centos7VM" ]; then # we give up, for some reason we see errors in this env but in no other Centos 7 env # this is a hack for rsyslog official CI - sorry for that -- rgerhards, 2019-01-24 echo "SKIP test, as for some reason it does not work here - this should be investigated" exit 77 fi export USE_VALGRIND="YES" source ${srcdir:=.}/imrelp-manyconn.sh rsyslog-8.2512.0/tests/PaxHeaders/uxsock_multiple-vg.sh0000644000000000000000000000013215114522477020100 xustar0030 mtime=1764926783.046632128 30 atime=1764926783.496643176 30 ctime=1764935934.164744683 rsyslog-8.2512.0/tests/uxsock_multiple-vg.sh0000775000175000017500000000011515114522477017544 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/uxsock_multiple.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-readmode2-vg.sh0000644000000000000000000000013215035412264017750 xustar0030 mtime=1752569012.392806336 30 atime=1764931165.705715282 30 ctime=1764935934.248745969 rsyslog-8.2512.0/tests/imfile-readmode2-vg.sh0000775000175000017500000000335015035412264017420 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup_vg # write the beginning of the file echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input wait_file_lines $RSYSLOG_OUT_LOG 1 # write some more lines (see https://github.com/rsyslog/rsyslog/issues/144) echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2 wait_file_lines $RSYSLOG_OUT_LOG 3 shutdown_when_empty wait_shutdown_vg check_exit_vg ## check if we have the correct number of messages NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" cat $RSYSLOG_OUT_LOG error_exit 1 else if [ ! $NUMLINES -eq 3 ]; then echo "ERROR: expecting 3 headers, got $NUMLINES" cat $RSYSLOG_OUT_LOG error_exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {1..4}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" cat $RSYSLOG_OUT_LOG error_exit 1 fi done ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-num-vg.sh0000644000000000000000000000013215055602574022253 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.604617439 30 ctime=1764935932.520719518 rsyslog-8.2512.0/tests/rscript_compare_numstr-num-vg.sh0000775000175000017500000000020115055602574021713 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='"1"' export HIGHER_VAL='2' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/imdocker-new-logs-from-start.sh0000644000000000000000000000013115055602574021661 xustar0030 mtime=1756824956.028451428 30 atime=1764931168.877766106 29 ctime=1764935935.16475999 rsyslog-8.2512.0/tests/imdocker-new-logs-from-start.sh0000775000175000017500000000317515055602574021337 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # imdocker unit tests are enabled with --enable-imdocker-tests . ${srcdir:=.}/diag.sh init export COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 10 | head -n 1) generate_conf add_conf ' #template(name="template_msg_only" type="string" string="%msg%\n") template(name="outfmt" type="string" string="%$!metadata!Names% %msg%\n") module(load="../contrib/imdocker/.libs/imdocker" PollingInterval="1" ListContainersOptions="all=true" GetContainerLogOptions="tail=1×tamps=0&follow=1&stdout=1&stderr=0&tail=1" RetrieveNewLogsFromStart="on" ) action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") if $!metadata!Names == "'$COOKIE'" then { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' #NUM_ITEMS=1000 # launch a docker runtime to generate some logs. # these log items should be tailed. docker run \ --rm \ -e seq_start=101 \ -e seq_end=200 \ alpine \ /bin/sh -c 'for i in `seq $seq_start $seq_end`; do echo "tailed item $i"; sleep .01; done' > /dev/null & sleep 1 #export RS_REDIR=-d startup NUMMESSAGES=1000 # launch a docker runtime to generate some logs. # These logs started after start-up should get from beginning docker run \ --name $COOKIE \ -e NUMMESSAGES=$NUMMESSAGES \ alpine \ /bin/sh -c 'for i in `seq 1 $NUMMESSAGES`; do echo "log item $i"; done' > /dev/null shutdown_when_empty wait_shutdown echo "file name: $RSYSLOG_OUT_LOG" echo "\"tailed item\" occurred: $(grep -c 'tailed item ' $RSYSLOG_OUT_LOG)/100 (expect less)." docker container rm $COOKIE exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table_rscript_reload.sh0000644000000000000000000000013215035412264022005 xustar0030 mtime=1752569012.399757696 30 atime=1764931167.807748965 30 ctime=1764935934.862755367 rsyslog-8.2512.0/tests/lookup_table_rscript_reload.sh0000775000175000017500000000332215035412264021454 0ustar00rgerrger#!/bin/bash # test for lookup-table reload by rscript-fn # added 2015-12-18 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl") template(name="outfmt" type="string" string="- %msg% %$.lkp%\n") set $.lkp = lookup("xlate", $msg); if ($msg == " msgnum:00000002:") then { reload_lookup_table("xlate", "reload_failed"); } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup # the last message ..002 should cause successful lookup-table reload cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl injectmsg 0 3 await_lookup_table_reload wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl injectmsg 0 3 await_lookup_table_reload wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: bar_new" content_check "msgnum:00000002: baz" rm -f $RSYSLOG_DYNNAME.xlate.lkp_tbl # this should lead to unsuccessful reload injectmsg 0 3 await_lookup_table_reload wait_queueempty injectmsg 0 2 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: foo_latest" content_check "msgnum:00000001: quux" content_check "msgnum:00000002: baz_latest" content_check "msgnum:00000000: reload_failed" content_check "msgnum:00000000: reload_failed" exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse1-udp.sh0000644000000000000000000000013215035412264020404 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.901606158 30 ctime=1764935932.320716456 rsyslog-8.2512.0/tests/parsertest-parse1-udp.sh0000775000175000017500000001434615035412264020063 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") global(localHostname="localhost") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 27 19:06:53 source_server sshd(pam_unix)[12750]: session opened for user foo by (uid=0)\"" tcpflood -m1 -T "udp" -M "\"<167>Apr 6 15:07:10 lxcvs07 sshd(pam_unix)[31738]: session closed for user cvsadmin\"" tcpflood -m1 -T "udp" -M "\"<167>Jul 31 21:39:21 example-b example-gw[10538]: disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0\"" tcpflood -m1 -T "udp" -M "\"<167>AUG 10 22:18:24 host tag This msg contains 8-bit European chars: äöü\"" tcpflood -m1 -T "udp" -M "\"<167> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 7 2008 19:06:53: example tag: testmessage (only date actually tested)\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 7 2008 19:06:53 example tag: testmessage (only date actually tested)\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 7 19:06:53: example tag: testmessage (only date actually tested)\"" tcpflood -m1 -T "udp" -M "\"<14>Jan 6 2009 15:22:26 localhost\"" tcpflood -m1 -T "udp" -M "\"<167>Oct 8 23:05:06 10.321.1.123 05\\\",result_code=200,b\"" tcpflood -m1 -T "udp" -M "\"<167>Feb 18 16:01:59 serverX -- MARK --\"" tcpflood -m1 -T "udp" -M "\"Feb 18 16:01:59 serverX -- MARK --\"" tcpflood -m1 -T "udp" -M "\"<38>Mar 27 19:06:53 source_server 0123456789012345678901234567890123456789: MSG part\"" tcpflood -m1 -T "udp" -M "\"<29>Oct 16 20:47:24 example-p exam-pl[12345]: connect host= /192.0.2.1\"" tcpflood -m1 -T "udp" -M "\"<34>Oct 11 22:14:15 mymachine su: su root failed for lonvick on /dev/pts/8\"" tcpflood -m1 -T "udp" -M "\"<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOMsu root failed for lonvick on /dev/pts/8\"" tcpflood -m1 -T "udp" -M "\"<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - %% Its time to make the do-nuts.\"" tcpflood -m1 -T "udp" -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"][examplePriority@32473 class=\\\"high\\\"]\"" tcpflood -m1 -T "udp" -M "\"<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut=\\\"3\\\" eventSource= \\\"Application\\\" eventID=\\\"1011\\\"] BOMAn application event log entry...\"" tcpflood -m1 -T "udp" -M "\"<6>AUG 10 22:18:24 2009 netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset\"" tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"" tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711 \"" tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 X4711\"" tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05 \"" tcpflood -m1 -T "udp" -M "\"<14>Aug 30 23:00:05\"" tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"" tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711 \"" tcpflood -m1 -T "udp" -M "\"<14>2010-08-30T23:00:05Z X4711\"" shutdown_when_empty wait_shutdown export EXPECTED="167,local4,debug,Mar 6 16:57:54,172.20.245.8,%PIX-7-710005,%PIX-7-710005:, UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601 167,local4,debug,Mar 27 19:06:53,source_server,sshd(pam_unix),sshd(pam_unix)[12750]:, session opened for user foo by (uid=0) 167,local4,debug,Apr 6 15:07:10,lxcvs07,sshd(pam_unix),sshd(pam_unix)[31738]:, session closed for user cvsadmin 167,local4,debug,Jul 31 21:39:21,example-b,example-gw,example-gw[10538]:, disconnect host=/192.0.2.1 destination=192.0.2.2/11282 in=3274 out=1448 duration=0 167,local4,debug,Aug 10 22:18:24,host,tag,tag, This msg contains 8-bit European chars: äöü 167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested) 167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested) 167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested) 167,local4,debug,Mar 7 19:06:53,example,tag,tag:, testmessage (only date actually tested) 14,user,info,Jan 6 15:22:26,localhost,,, 167,local4,debug,Oct 8 23:05:06,10.321.1.123,05\",result_code=200,b,05\",result_code=200,b, 167,local4,debug,Feb 18 16:01:59,serverX,--,--, MARK -- 13,user,notice,Feb 18 16:01:59,serverX,--,--, MARK -- 38,auth,info,Mar 27 19:06:53,source_server,0123456789012345678901234567890123456789,0123456789012345678901234567890123456789:, MSG part 29,daemon,notice,Oct 16 20:47:24,example-p,exam-pl,exam-pl[12345]:, connect host= /192.0.2.1 34,auth,crit,Oct 11 22:14:15,mymachine,su,su:, su root failed for lonvick on /dev/pts/8 34,auth,crit,Oct 11 22:14:15,mymachine.example.com,su,su,BOMsu root failed for lonvick on /dev/pts/8 165,local4,notice,Aug 24 05:14:15,192.0.2.1,myproc,myproc[8710],%% Its time to make the do-nuts. 165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog, 165,local4,notice,Oct 11 22:14:15,mymachine.example.com,evntslog,evntslog,BOMAn application event log entry... 6,kern,info,Aug 10 22:18:24,2009,,, netips-warden2-p [audit] user=[*SMS] src=192.168.11.11 iface=5 access=9 Update State Reset 14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, 14,user,info,Aug 30 23:00:05,X4711,,, 14,user,info,Aug 30 23:00:05,X4711,,, 14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,, 14,user,info,Aug 30 23:00:05,$RS_HOSTNAME,,, 14,user,info,Aug 30 23:00:05,X4711,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, 14,user,info,Aug 30 23:00:05,X4711,,, 14,user,info,Aug 30 23:00:05,X4711,,," cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_exists-not1.sh0000644000000000000000000000013215055602574020204 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.859621531 30 ctime=1764935932.579720421 rsyslog-8.2512.0/tests/rscript_exists-not1.sh0000775000175000017500000000102315055602574017647 0ustar00rgerrger#!/bin/bash # add 2020-10-02 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%!result%\n") # ensure that in this test there is NO variable define at all if $msg contains "msgnum" then { if exists($!p1!p2!val) then set $!result = "on"; else set $!result = "off"; action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup injectmsg 0 1 shutdown_when_empty wait_shutdown export EXPECTED='off' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-statefile-no-delete.sh0000644000000000000000000000013215055602574021335 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.992719882 30 ctime=1764935934.337747331 rsyslog-8.2512.0/tests/imfile-statefile-no-delete.sh0000775000175000017500000000227415055602574021011 0ustar00rgerrger#!/bin/bash # Added 2019-02-28 # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init export TESTMESSAGES=1000 export TESTMESSAGESFULL=999 export RETRIES=50 generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" tag="file:" file="./'$RSYSLOG_DYNNAME'.input" deleteStateOnFileDelete="off") template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' ./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input inode=$(get_inode "$RSYSLOG_DYNNAME.input") startup wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES rm $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to notice the deleted file ./msleep 2000 shutdown_when_empty wait_shutdown seq_check 0 $TESTMESSAGESFULL # check we got the message correctly if ! ls $RSYSLOG_DYNNAME.spool/imfile-state:$inode:* 1> /dev/null 2>&1; then printf 'FAIL: state file was deleted when it should not have been\nspool dir is:\n' ls -l $RSYSLOG_DYNNAME.spool error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_udp_nonstdpt.sh0000644000000000000000000000013215055602574020340 xustar0030 mtime=1756824956.040451596 30 atime=1764931164.317693033 30 ctime=1764935933.849739861 rsyslog-8.2512.0/tests/sndrcv_udp_nonstdpt.sh0000775000175000017500000000266615055602574020021 0ustar00rgerrger#!/bin/bash # This runs sends and receives messages via UDP to the non-standard port 2514 # Note that with UDP we can always have message loss. While this is # less likely in a local environment, we strongly limit the amount of data # we send in the hope to not lose any messages. However, failure of this # test does not necessarily mean that the code is wrong (but it is very likely!) # added 2009-11-11 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export TCPFLOOD_EXTRA_OPTS="-b1 -W1" export NUMMESSAGES=50 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' $ModLoad ../plugins/imudp/.libs/imudp # then SENDER sends to this port (not tcpflood!) $UDPServerRun '$TCPFLOOD_PORT' $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" export PORT_RCVR="$TCPFLOOD_PORT" #valgrind="valgrind" generate_conf 2 add_conf ' *.* @127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-drvr-in-input-basic.sh0000644000000000000000000000013115055602574021146 xustar0029 mtime=1756824956.03145147 30 atime=1764931162.997671868 30 ctime=1764935933.471734075 rsyslog-8.2512.0/tests/imtcp-drvr-in-input-basic.sh0000775000175000017500000000172715055602574020625 0ustar00rgerrger#!/bin/bash # added 2021-04-27 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5000 export QUEUE_EMPTY_CHECK_FUNC=wait_seq_check generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_64_ipv6.sh0000644000000000000000000000013215055602574020041 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.366629666 30 ctime=1764935932.720722579 rsyslog-8.2512.0/tests/mmanon_zero_64_ipv6.sh0000775000175000017500000000232015055602574017505 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv6.bits="64" ipv6.anonmode="zero") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") }' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0 <129>Mar 10 01:00:00 172.20.245.8 tag: :: <129>Mar 10 01:00:00 172.20.245.8 tag: 0:: <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45: <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\"" shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk ffff:ffff:ffff:ffff:0:0:0:0 61:34:ad:0:0:0:0:0 aa:ff43:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 13:abd:45: textnoblank72:8374:adc7:47ff:0:0:0:0stillnoblank' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-error-cert.sh0000644000000000000000000000013015055602574021212 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.341677384 29 ctime=1764935933.57073559 rsyslog-8.2512.0/tests/imtcp-tls-ossl-error-cert.sh0000775000175000017500000000157115055602574020667 0ustar00rgerrger#!/bin/bash # added 2018-11-07 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert-fail.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/cert.pem'" ) module(load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' # note: we do not need to generate any messages, config error occurs on startup startup sleep 5 # TODO: FIXME - just checking if we terminate too early shutdown_when_empty wait_shutdown content_check "Error: Certificate file could not be accessed" content_check "OpenSSL Error Stack:" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-profile-loki.sh0000644000000000000000000000013215071746523020146 xustar0030 mtime=1760021843.901421979 30 atime=1764931164.912702571 30 ctime=1764935934.016742417 rsyslog-8.2512.0/tests/omhttp-profile-loki.sh0000775000175000017500000000261715071746523017623 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Test the profile="loki" configuration # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 # Start a mock Loki server (enable decompression as profile enables compression) omhttp_start_server 0 --decompress generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") # Simplified loki payload to match test harness lokirest parser template(name="loki_template" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") ruleset(name="ruleset_omhttp_loki") { action( name="action_omhttp_loki" type="omhttp" # Use the Loki profile profile="loki" template="loki_template" server="localhost" serverport="'$omhttp_server_lstnport'" # The profile should set these defaults: # - batch.format="lokirest" # - restpath="loki/api/v1/push" # - batch="on" # - compress="on" # Our mock server is plain HTTP usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp_loki ' startup injectmsg 0 $NUMMESSAGES shutdown_when_empty wait_shutdown # Verify data was sent to the Loki endpoint; parse as lokirest omhttp_get_data $omhttp_server_lstnport loki/api/v1/push lokirest omhttp_stop_server # Verify all messages were sent seq_check 0 $(( NUMMESSAGES - 1 )) exit_test rsyslog-8.2512.0/tests/PaxHeaders/omrelp_wrong_authmode.sh0000644000000000000000000000013115055602574020637 xustar0029 mtime=1756824956.03645154 30 atime=1764931164.230691638 30 ctime=1764935933.824739478 rsyslog-8.2512.0/tests/omrelp_wrong_authmode.sh0000775000175000017500000000116015055602574020305 0ustar00rgerrger#!/bin/bash # add 2018-09-13 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omrelp/.libs/omrelp") ruleset(name="ruleset") { action(type="omrelp" target="127.0.0.1" port="'$TCPFLOOD_PORT'" tls="on" tls.authMode="INVALID_AUTH_MODE" tls.caCert="tls-certs/ca.pem" tls.myCert="tls-certs/cert.pem" tls.myPrivKey="tls-certs/key.pem" tls.permittedPeer=["rsyslog-test-root-ca"]) } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "omrelp.* invalid auth.*mode .*INVALID_AUTH_MODE" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_stop.sh0000644000000000000000000000013215035412264016764 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.345613283 30 ctime=1764935932.449718431 rsyslog-8.2512.0/tests/rscript_stop.sh0000775000175000017500000000132615035412264016435 0ustar00rgerrger#!/bin/bash # added 2012-09-20 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_stop.sh\]: testing rainerscript STOP statement . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); if cnum($!usr!msgnum) >= 5000 then stop action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 8000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-truncate-line.sh0000644000000000000000000000013215035412264020246 xustar0030 mtime=1752569012.392806336 30 atime=1764931165.805716885 30 ctime=1764935934.278746428 rsyslog-8.2512.0/tests/imfile-truncate-line.sh0000775000175000017500000000547215035412264017725 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # This test mimics the test imfile-readmode2.sh, but works via # endmsg.regex. It's kind of a base test for the regex functionality. echo ====================================================================== # Check if inotify header exist echo [imfile-truncate-line.sh] . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MaxMessageSize 128 global(oversizemsg.input.mode="accept" oversizemsg.report="on") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" discardTruncatedMsg="off" Tag="file:" startmsg.regex="^[^ ]" ruleset="ruleset") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt") ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1 msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb msgnum:4 cccccccccccccccccccccccccccccccccccccccccccc msgnum:5 dddddddddddddddddddddddddddddddddddddddddddd msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff msgnum:8 gggggggggggggggggggggggggggggggggggggggggggg msgnum:9' > $RSYSLOG_DYNNAME.input # the next line terminates our test. It is NOT written to the output file, # as imfile waits whether or not there is a follow-up line that it needs # to combine. echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing ./msleep 500 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! printf 'HEADER msgnum:0 HEADER msgnum:1 HEADER msgnum:2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\\n msgnum:3 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\\\\n msgnum:4 ccccccc HEADER ccccccccccccccccccccccccccccccccccccc\\\\n msgnum:5 dddddddddddddddddddddddddddddddddddddddddddd HEADER msgnum:6 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\\\\n msgnum:7 ffffffffffffffffffffffffffffffffffffffffffff\\\\n msgnum:8 ggggggg HEADER ggggggggggggggggggggggggggggggggggggg HEADER msgnum:9\n' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; grep "imfile error:.*message will be split and processed" ${RSYSLOG2_OUT_LOG} > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message from missing input file not found. ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/stop-localvar.sh0000644000000000000000000000013115035412264017016 xustar0029 mtime=1752569012.41564652 30 atime=1764931160.453631062 30 ctime=1764935932.743722931 rsyslog-8.2512.0/tests/stop-localvar.sh0000775000175000017500000000165015035412264016470 0ustar00rgerrger#!/bin/bash # Test for "stop" statement # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[stop-localvar.sh\]: testing stop statement together with local variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.nbr%\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if $msg contains "msgnum:" then { set $.nbr = field($msg, 58, 2); if cnum($.nbr) < 100 then stop /* check is intentionally more complex than needed! */ else if not (cnum($.nbr) > 999) then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } } ' startup sleep 1 tcpflood -m2000 -i1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 100 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-bigmessage-octetstuffing.sh0000644000000000000000000000013115055602574022341 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.113673728 30 ctime=1764935933.502734549 rsyslog-8.2512.0/tests/imtcp-bigmessage-octetstuffing.sh0000775000175000017500000000303415055602574022011 0ustar00rgerrger#!/bin/bash # add 2020-05-14 by alorbach, released under ASL 2.0 export NUMMESSAGES=10 export TEST_BYTES_SENDSIZE=4037 export TEST_BYTES_EXPECTED=$(((TEST_BYTES_SENDSIZE/2 - 420) * NUMMESSAGES)) # 262152 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global( workDirectory="'$RSYSLOG_DYNNAME.spool'" maxMessageSize="4k" ) module( load="../plugins/imtcp/.libs/imtcp" MaxSessions="10000" discardTruncatedMsg="on" ) input( type="imtcp" name="imtcp" port="'$TCPFLOOD_PORT'" ruleset="print" ) template(name="print_message" type="list"){ constant(value="inputname: ") property(name="inputname") constant(value=", strlen: ") property(name="$!strlen") constant(value=", message: ") property(name="msg") constant(value="\n") } ruleset(name="print") { set $!strlen = strlen($msg); action( type="omfile" template="print_message" file=`echo $RSYSLOG_OUT_LOG` ) } ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -d $TEST_BYTES_SENDSIZE shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown content_count_check --regex "inputname: imtcp, strlen:" ${NUMMESSAGES} count=$(wc -c < $RSYSLOG_OUT_LOG) if [ $count -lt $TEST_BYTES_EXPECTED ]; then echo echo "FAIL: expected bytes count $count did not match $TEST_BYTES_EXPECTED. " echo echo "First 100 bytes of $RSYSLOG_OUT_LOG are: " head -c 100 $RSYSLOG_OUT_LOG echo echo "Last 100 bytes of $RSYSLOG_OUT_LOG are: " tail -c 100 $RSYSLOG_OUT_LOG error_exit 1 else echo "Found $count bytes (Expected $TEST_BYTES_EXPECTED) in $RSYSLOG_OUT_LOG" fi exit_testrsyslog-8.2512.0/tests/PaxHeaders/clickhouse-errorfile.sh0000644000000000000000000000013215055602574020360 xustar0030 mtime=1756824956.026451401 30 atime=1764931162.449663079 30 ctime=1764935933.312731641 rsyslog-8.2512.0/tests/clickhouse-errorfile.sh0000775000175000017500000000257615055602574020041 0ustar00rgerrger#!/bin/bash # add 2018-12-07 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo looks like clickhouse does no longer generate exceptions on error - skip until investigated exit 77 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omclickhouse/.libs/omclickhouse") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" option.stdsql="on" type="string" string="INSERT INTO rsyslog.errorfile (id, severity, facility, timestamp, ipaddress, tag, message) VALUES (%msg:F,58:2%, %syslogseverity%, %syslogfacility%, ' add_conf "'%timereported:::date-unixtimestamp%', '%fromhost-ip%', '%syslogtag%', '%msg%')" add_conf '") :syslogtag, contains, "tag" action(type="omclickhouse" server="localhost" port="8443" user="default" pwd="" template="outfmt" bulkmode="off" errorfile="'$RSYSLOG_OUT_LOG'") ' clickhouse-client --query="CREATE TABLE IF NOT EXISTS rsyslog.errorfile ( id Int32, severity Int8, facility Int8, timestamp DateTime, ipaddress String, tag String, message String ) ENGINE = MergeTree() PARTITION BY severity Order By id" startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:NoInteger\"" shutdown_when_empty wait_shutdown content_check --regex "msgnum:NoInteger.*DB::Exception:" clickhouse-client --query="DROP TABLE rsyslog.errorfile" exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmrfc3164-msgFirstSpace.sh0000644000000000000000000000013115035412264020425 xustar0030 mtime=1752569012.407702108 29 atime=1764931157.84758924 30 ctime=1764935932.024711925 rsyslog-8.2512.0/tests/pmrfc3164-msgFirstSpace.sh0000775000175000017500000000207115035412264020075 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser") parser(name="custom.rfc3164" type="pmrfc3164" remove.msgFirstSpace="on") template(name="outfmt" type="string" string="-%msg%-\n") ruleset(name="customparser" parser="custom.rfc3164") { :syslogtag, contains, "tag" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag:msgnum:3\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag4:\"" shutdown_when_empty wait_shutdown echo '-msgnum:1- - msgnum:2- -msgnum:3- --' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-oversizeMode-truncate.sh0000644000000000000000000000013015035412264022013 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.070689073 29 ctime=1764935933.78173882 rsyslog-8.2512.0/tests/imrelp-oversizeMode-truncate.sh0000775000175000017500000000241015035412264021461 0ustar00rgerrger#!/bin/bash # add 2018-04-19 by PascalWithopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ./have_relpSrvSetOversizeMode if [ $? -eq 1 ]; then echo "imrelp parameter oversizeMode not available. Test stopped" exit 77 fi; generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") global(maxMessageSize="150" oversizemsg.input.mode="accept") input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="200" oversizeMode="truncate") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m1 -d 240 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # We need the ^-sign to symbolize the beginning and the $-sign to symbolize the end # because otherwise we won't know if it was truncated at the right length. grep "^ msgnum:00000000:240:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-httpheaderkey.sh0000644000000000000000000000013215055602574020412 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.984703726 30 ctime=1764935934.035742708 rsyslog-8.2512.0/tests/omhttp-httpheaderkey.sh0000775000175000017500000000150515055602574020062 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 omhttp_start_server 0 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../contrib/omhttp/.libs/omhttp") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" httpheaderkey="X-Insert-Key" httpheadervalue="dummy-value" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="off" # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/random.sh0000644000000000000000000000013215055602574015520 xustar0030 mtime=1756824956.037451554 30 atime=1764931165.662714593 30 ctime=1764935934.236745785 rsyslog-8.2512.0/tests/random.sh0000775000175000017500000000217515055602574015174 0ustar00rgerrger#!/bin/bash # Test if rsyslog survives sending truly random data to it... # # added 2010-04-01 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # The random data will generate TCP framing error messages. We will # not clutter the test output with them. So we disable error messages # to stderr. $ErrorMessagesToStderr off module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%rawmsg%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! *.* /dev/null ' startup # generate random data ./randomgen -f $RSYSLOG_DYNNAME.random.data -s 100000 ls -l $RSYSLOG_DYNNAME.random.data tcpflood -B -I $RSYSLOG_DYNNAME.random.data -c5 -C10 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # and wait for it to terminate # we do not check anything yet, the point is if rsyslog survived ;) # TODO: check for exit message, but we'll notice an abort anyhow, so not that important exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-manycon.sh0000644000000000000000000000013215055603742020572 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.383678057 30 ctime=1764935933.582735774 rsyslog-8.2512.0/tests/imtcp-tls-ossl-manycon.sh0000775000175000017500000000246415055603742020247 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100000 ulimit -n 2048 # may or may not work ;-) generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "nsd_ptcp.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/name" PermittedPeer=["/CN=rsyslog-client/OU=Adiscon GmbH/O=Adiscon GmbH/L=Grossrinderfeld/ST=BW/C=DE/DC=rsyslog.com","rsyslog.com"] ) input(type="imtcp" socketBacklog="1000" maxsessions="1000" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase startup tcpflood -c-1000 -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-direct-with-params-given.sh0000644000000000000000000000013215035412264022165 xustar0030 mtime=1752569012.408695159 30 atime=1764931158.874605724 30 ctime=1764935932.313716349 rsyslog-8.2512.0/tests/queue-direct-with-params-given.sh0000775000175000017500000000050415035412264021633 0ustar00rgerrger#!/bin/bash # added 2019-11-14 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' action(type="omfile" file="'$RSYSLOG_OUT_LOG'" queue.mindequeuebatchsize="20") ' startup shutdown_when_empty wait_shutdown content_check "queue is in direct mode, but parameters have been set" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_delete_success.sh0000644000000000000000000000013115035412264022145 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.136593879 29 ctime=1764935932.10671318 rsyslog-8.2512.0/tests/imbatchreport_delete_success.sh0000775000175000017500000000570615035412264021625 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # 804/805 fail/sent with space dedup global(maxmessagesize="820") module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1") global(localhostname="server") input(type="imbatchreport" ruleset="ruleset" tag="batch" severity="info" facility="local0" reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on" programkey="KSH" timestampkey="START" delete=".done$ .rejected" ) ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format") } ' { echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)' echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree' echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)' echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree' echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)' echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1' } > $RSYSLOG_DYNNAME.dsu.done case $(uname) in FreeBSD) datelog=$(date -r $(stat -f %m $RSYSLOG_DYNNAME.dsu.done) "+%Y-%m-%dT%H:%M:%S") ;; *) datelog=$(date "+%Y-%m-%dT%H:%M:%S" -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.dsu.done)) ;; esac echo "Batch report to consume ${RSYSLOG_DYNNAME}.dsu.done for ${datelog}" startup shutdown_when_empty wait_shutdown export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - 164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree\n164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree\n164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)\n164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1' cmp_exact if [ -e $RSYSLOG_DYNNAME.dsu.sent ] || [ -e $RSYSLOG_DYNNAME.dsu.rejected ] || [ -e $RSYSLOG_DYNNAME.dsu.done ]; then echo "The batch report was not deleted" ls $RSYSLOG_DYNNAME* error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/minitcpsrvr.c0000644000000000000000000000013115055605325016424 xustar0030 mtime=1756826325.657800804 29 atime=1764931157.50058367 30 ctime=1764935931.930710486 rsyslog-8.2512.0/tests/minitcpsrvr.c0000664000175000017500000002752315055605325016102 0ustar00rgerrger/* a very simplistic tcp receiver for the rsyslog testbench. * * Copyright 2016,2024 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #define MAX_CONNECTIONS 10 #define BUFFER_SIZE 1024 /* OK, we use a lot of global. But after all, this is "just" a small * testing ... that has evolved a bit ;-) */ char wrkBuf[4096]; ssize_t nRead; size_t nRcv = 0; int nConnDrop; /* how often has the connection already been dropped? */ int abortListener = 0; /* act like listener was totally aborted */ int sleepAfterConnDrop = 0; /* number of seconds to sleep() when a connection was dropped */ int dropConnection_NbrRcv = 0; int dropConnection_MaxTimes = 0; int opt; int sleepStartup = 0; char *targetIP = NULL; int targetPort = -1; char *portFileName = NULL; size_t totalWritten = 0; int listen_fd, conn_fd, fd, file_fd, nfds, port = 8080; struct sockaddr_in server_addr; struct pollfd fds[MAX_CONNECTIONS + 1]; // +1 for the listen socket char buffer[MAX_CONNECTIONS][BUFFER_SIZE]; int buffer_offs[MAX_CONNECTIONS]; static void errout(char *reason) { perror(reason); fprintf(stderr, "minitcpsrv ABORTS!!!\n\n\n"); exit(1); } static void usage(void) { fprintf(stderr, "usage: minitcpsrv -t ip-addr -p port -P portFile -f outfile\n"); exit(1); } static void createListenSocket(void) { struct sockaddr_in srvAddr; unsigned int srvAddrLen; static int portFileWritten = 0; int r; listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { errout("Failed to create listen socket"); } /* Set SO_REUSEADDR and SO_REUSEPORT options - these are vital for some * Tests. If not both are supported by the OS (e.g. Solaris 10), some tests * will fail. Those need to be excluded. */ int opt = 1; if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { errout("setsockopt failed for SO_REUSEADDR"); } #ifdef SO_REUSEPORT if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) { errout("setsockopt failed for SO_REUSEPORT"); } #endif fprintf(stderr, "listen on target port %d\n", targetPort); memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(targetIP); // htonl(INADDR_ANY); server_addr.sin_port = htons(targetPort); srvAddrLen = sizeof(server_addr); int sockBound = 0; int try = 0; do { r = bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (r < 0) { if (errno == EADDRINUSE) { perror("minitcpsrv bind listen socket"); if (try++ < 10) { sleep(1); } else { fprintf(stderr, "minitcpsrv could not bind socket " "after trying hard - terminating\n\n"); exit(2); } } else { errout("bind"); } } else { sockBound = 1; } } while (!sockBound); if (listen(listen_fd, MAX_CONNECTIONS) < 0) { errout("Listen failed"); } if (getsockname(listen_fd, (struct sockaddr *)&srvAddr, &srvAddrLen) == -1) { errout("getsockname"); } targetPort = ntohs(srvAddr.sin_port); if (portFileName != NULL && !portFileWritten) { FILE *fp; if (getsockname(listen_fd, (struct sockaddr *)&srvAddr, &srvAddrLen) == -1) { errout("getsockname"); } if ((fp = fopen(portFileName, "w+")) == NULL) { errout(portFileName); } fprintf(fp, "%d", ntohs(srvAddr.sin_port)); fclose(fp); portFileWritten = 1; } fds[0].fd = listen_fd; fds[0].events = POLLIN; } int main(int argc, char *argv[]) { int fdc; int fdf = -1; struct sockaddr_in cliAddr; unsigned int cliAddrLen; memset(fds, 0, sizeof(fds)); memset(buffer_offs, 0, sizeof(buffer_offs)); while ((opt = getopt(argc, argv, "aB:D:t:p:P:f:s:S:")) != -1) { switch (opt) { case 'a': // abort listener: act like the server has died (shutdown and re-open listen socket) abortListener = 1; break; case 'S': // sleep time after connection drop sleepAfterConnDrop = atoi(optarg); break; case 's': // sleep time immediately after startup sleepStartup = atoi(optarg); break; case 'B': // max number of time the connection shall be dropped dropConnection_MaxTimes = atoi(optarg); break; case 'D': // drop connection after this number of recv() operations (not messages) dropConnection_NbrRcv = atoi(optarg); break; case 't': targetIP = optarg; break; case 'p': targetPort = atoi(optarg); break; case 'P': portFileName = optarg; break; case 'f': if (!strcmp(optarg, "-")) { fdf = 1; } else { fprintf(stderr, "writing to file %s\n", optarg); fdf = open(optarg, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (fdf == -1) errout(argv[3]); } break; default: fprintf(stderr, "invalid option '%c' or value missing - terminating...\n", opt); usage(); break; } } if (targetIP == NULL) { fprintf(stderr, "-t parameter missing -- terminating\n"); usage(); } if (targetPort == -1) { fprintf(stderr, "-p parameter missing -- terminating\n"); usage(); } if (fdf == -1) { fprintf(stderr, "-f parameter missing -- terminating\n"); usage(); } if (sleepStartup) { printf("minitcpsrv: deliberate sleep of %d seconds\n", sleepStartup); sleep(sleepStartup); printf("minitcpsrv: end sleep\n"); } createListenSocket(); nfds = 1; int bKeepRunning; while (1) { int poll_count = poll(fds, nfds, -1); // -1 means no timeout if (poll_count < 0) { errout("poll"); } bKeepRunning = 0; /* terminate on last connection close */ for (int i = 0; i < nfds; i++) { if (fds[i].revents == 0) continue; if (fds[i].revents != POLLIN) { fprintf(stderr, "Error! revents = %d\n", fds[i].revents); exit(EXIT_FAILURE); } if (fds[i].fd == listen_fd) { // Accept new connection fprintf(stderr, "minitcpsrv: NEW CONNECT\n"); conn_fd = accept(listen_fd, (struct sockaddr *)NULL, NULL); if (conn_fd < 0) { perror("Accept failed"); continue; } fds[nfds].fd = conn_fd; fds[nfds].events = POLLIN; nfds++; } else { // Handle data from a client fd = fds[i].fd; const size_t bytes_to_read = sizeof(buffer[i]) - buffer_offs[i] - 1; int read_bytes = read(fd, &(buffer[i][buffer_offs[i]]), bytes_to_read); nRcv += read_bytes; if (read_bytes < 0) { perror("Read error"); close(fd); fds[i].fd = -1; // Remove from poll set } else if (read_bytes == 0) { // Connection closed close(fd); fds[i].fd = -1; // Remove from poll set } else { // last valid char in rcv buffer const int last_byte = read_bytes + buffer_offs[i] - 1; int last_lf = last_byte; while (last_lf > -1 && buffer[i][last_lf] != '\n') { --last_lf; } if (last_lf == -1) { /* no LF found at all */ buffer_offs[i] = last_byte; } else { const int bytes_to_write = last_lf + 1; const int written_bytes = write(fdf, buffer[i], bytes_to_write); if (written_bytes != bytes_to_write) errout("write"); totalWritten += bytes_to_write; if (bytes_to_write == last_byte + 1) { buffer_offs[i] = 0; } else { /* keep data in buffer, move it to start * and adjust offset. */ int unfinished_bytes = last_byte - bytes_to_write + 1; memmove(buffer[i], &(buffer[i][bytes_to_write]), unfinished_bytes); buffer_offs[i] = unfinished_bytes; } } } /* simulate connection abort, if requested */ if ((buffer_offs[i] == 0) && (dropConnection_NbrRcv > 0) && (nRcv >= dropConnection_NbrRcv) && (dropConnection_MaxTimes > 0) && (nConnDrop < dropConnection_MaxTimes)) { nConnDrop++; nRcv = 0; if (abortListener) { fprintf(stderr, "minitcpsrv: simulating died client\n"); shutdown(listen_fd, SHUT_RDWR); } close(fd); fds[i].fd = -1; // Remove from poll set if (sleepAfterConnDrop > 0) { sleep(sleepAfterConnDrop); } if (abortListener) { /* we hope that when we close and immediately re-open, we will * can use the some port again. */ close(listen_fd); createListenSocket(); fprintf(stderr, "minitcpsrv: reactivated\n"); } bKeepRunning = 1; /* do not abort if sole connection! */ } } } // Compact the array of monitored file descriptors for (int i = 0; i < nfds; i++) { if (fds[i].fd == -1) { for (int j = i; j < nfds - 1; j++) { fds[j] = fds[j + 1]; } i--; nfds--; } } // terminate if all connections have been closed if (nfds == 1 && !bKeepRunning) break; } /* -------------------------------------------------- */ /* let the OS do the cleanup */ fprintf(stderr, "minitcpsrv on port %d terminates itself, %zu bytes written\n", targetPort, totalWritten); return 0; } rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_non_object-vg.sh0000644000000000000000000000013215055602574022620 xustar0030 mtime=1756824956.039451582 30 atime=1764931160.033624323 30 ctime=1764935932.623721094 rsyslog-8.2512.0/tests/rscript_unflatten_non_object-vg.sh0000775000175000017500000000013215055602574022263 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_non_object.sh rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_errmsg_regex.match.reject.sh0000644000000000000000000000013215035412264024213 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.071592836 30 ctime=1764935932.087712889 rsyslog-8.2512.0/tests/imbatchreport_errmsg_regex.match.reject.sh0000775000175000017500000000072015035412264023661 0ustar00rgerrger#!/bin/bash # add 2019-02-26 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/imbatchreport/.libs/imbatchreport") input(type="imbatchreport" tag="t" rename=".done$ .s .r.done" reports="./*.done") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check "Reject renaming leaves files in glob scope: Instance ignored to avoid loops." exit_test rsyslog-8.2512.0/tests/PaxHeaders/failover-no-rptd-vg.sh0000644000000000000000000000013215035412264020033 xustar0030 mtime=1752569012.389827181 30 atime=1764931163.696683076 30 ctime=1764935933.672737152 rsyslog-8.2512.0/tests/failover-no-rptd-vg.sh0000775000175000017500000000125115035412264017501 0ustar00rgerrger#!/bin/bash # rptd test for failover functionality - no failover # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $RepeatedMsgReduction on # second action should never execute :msg, contains, "msgnum:" /dev/null $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"' ' startup_vg injectmsg 0 5000 shutdown_when_empty wait_shutdown_vg check_exit_vg # now we need our custom logic to see if the result file is empty # (what it should be!) if [ -f $RSYSLOG_OUT_LOG -a "$(cat $RSYSLOG_OUT_LOG)" != "" ]; then echo "ERROR, output file not empty" cat -n "$RSYSLOG_OUT_LOG" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-listen-port-file-2.sh0000644000000000000000000000013215035412264020677 xustar0030 mtime=1752569012.396778542 30 atime=1764931162.816668965 30 ctime=1764935933.415733218 rsyslog-8.2512.0/tests/imtcp-listen-port-file-2.sh0000775000175000017500000000230515035412264020346 0ustar00rgerrger#!/bin/bash # This test checks if more than one port file names work correctly for # imtcp. See also: # https://github.com/rsyslog/rsyslog/issues/3817 # added 2019-08-14 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.rcvr_port" ruleset="rs1") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.rcvr_port2" ruleset="rs2") ruleset(name="rs1") { action(type="omfile" file="'$RSYSLOG_DYNNAME.1.log'" template="outfmt") } ruleset(name="rs2") { action(type="omfile" file="'$RSYSLOG_DYNNAME.2.log'" template="outfmt") } ' startup assign_file_content RCVR_PORT "$RSYSLOG_DYNNAME.rcvr_port" assign_file_content RCVR_PORT2 "$RSYSLOG_DYNNAME.rcvr_port2" ./tcpflood -p $RCVR_PORT -m10 ./tcpflood -p $RCVR_PORT2 -m10 -i10 shutdown_when_empty wait_shutdown printf 'checking receiver 1\n' export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.1.log" seq_check 0 9 printf 'checking receiver 2\n' export SEQ_CHECK_FILE="$RSYSLOG_DYNNAME.2.log" seq_check 10 19 exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-pos-from-to-missing-jsonvar.sh0000644000000000000000000000013215035412264023353 xustar0030 mtime=1752569012.416639571 30 atime=1764931161.382645965 30 ctime=1764935933.013727064 rsyslog-8.2512.0/tests/template-pos-from-to-missing-jsonvar.sh0000775000175000017500000000126215035412264023023 0ustar00rgerrger#!/bin/bash # addd 2016-03-28 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="-%$!non!existing!var:109:116:%-\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 shutdown_when_empty wait_shutdown echo "--" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid output generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG echo "expected was:" echo "--" exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/allowed-sender-tcp-fail.sh0000644000000000000000000000013215055602574020642 xustar0030 mtime=1756824956.025451386 30 atime=1764931162.833669238 30 ctime=1764935933.420733294 rsyslog-8.2512.0/tests/allowed-sender-tcp-fail.sh0000775000175000017500000000170515055602574020314 0ustar00rgerrger#!/bin/bash # check that we are able to receive messages from allowed sender # added 2019-08-15 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=5 # it's just important that we get any messages at all generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs") $AllowedSender TCP,128.66.0.0/16 # this IP range is reserved by RFC5737 template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="rs") { action(type="omfile" template="outfmt" file="'$RSYSLOG_DYNNAME.must-not-be-created'") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES shutdown_when_empty wait_shutdown content_check --regex "connection request from disallowed sender .* discarded" check_file_not_exists "$RSYSLOG_DYNNAME.must-not-be-created" exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmpstrucdata-vg.sh0000644000000000000000000000013215035412264017347 xustar0030 mtime=1752569012.401743799 30 atime=1764931167.059736981 30 ctime=1764935934.652752153 rsyslog-8.2512.0/tests/mmpstrucdata-vg.sh0000775000175000017500000000171315035412264017020 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # rgerhards, 2013-11-22 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi echo =============================================================================== echo \[mmpstrucdata.sh\]: testing mmpstrucdata . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata") module(load="../plugins/imtcp/.libs/imtcp") template(name="outfmt" type="string" string="%$!rfc5424-sd!tcpflood@32473!msgnum%\n") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmpstrucdata") if $msg contains "msgnum" then action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup_vg sleep 1 tcpflood -m100 -y shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown_vg check_exit_vg seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmnormalize-neither_rule_rulebase.sh0000644000000000000000000000013115035412264023132 xustar0030 mtime=1752569012.407702108 29 atime=1764931161.88665405 30 ctime=1764935933.156729253 rsyslog-8.2512.0/tests/pmnormalize-neither_rule_rulebase.sh0000775000175000017500000000062215035412264022602 0ustar00rgerrger#!/bin/bash # add 2019-04-10 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/pmnormalize/.libs/pmnormalize") parser(name="custom.pmnormalize" type="pmnormalize") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex "pmnormalize:.*you need to specify either" exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdrop_common.sh0000644000000000000000000000013215055602574017455 xustar0030 mtime=1756824956.037451554 30 atime=1764931161.249643832 30 ctime=1764935932.973726452 rsyslog-8.2512.0/tests/privdrop_common.sh0000775000175000017500000000627715055602574017140 0ustar00rgerrger#!/bin/bash # added 2016-04-15 by Thomas D., released under ASL 2.0 # Several tests need another user/group to test impersonation. # This script can be sourced to prevent duplicated code. # To support /dev/null) if [ -z "${testusername}" ]; then echo "'id' did not find user \"${testuser}\" ... skipping, trying next user!" continue fi testgroupname=$(id --group --name ${testuser} 2>/dev/null) if [ -z "${testgroupname}" ]; then echo "'id' did not find a primary group for \"${testuser}\" ... skipping, trying next user!" continue fi has_testuser="${testuser}" break done if [ -z "${has_testuser}" ]; then echo "ERROR: running as root and no suiteable testuser found - skipping test" echo 'You mas set a testuser via the RSYSLOG_TESTUSER environment variable' exit 77 fi echo "WARNING: making work directory world-writable, as we need this to be able to" echo " open and process files after privilege drop. This is NOT automatically" echo " undone." chmod a+w . fi if [ -z "${has_testuser}" ]; then testgroupname=$(id --group --name ${EUID} 2>/dev/null) if [ -z "${testgroupname}" ]; then echo "Skipping ... please set RSYSLOG_TESTUSER or make sure the user running the testbench has a primary group!" exit_test exit 0 else has_testuser="${EUID}" fi fi _rsyslog_testbench_declare_testuser ${has_testuser} } _rsyslog_testbench_declare_testuser() { local testuser=$1 local testusername=$(id --user --name ${testuser} 2>/dev/null) if [ -z "${testusername}" ]; then # Should never happen echo "FATAL ERROR: Could not get username for user \"${testuser}\"!" exit 1 fi local testuid=$(id --user ${testuser} 2>/dev/null) if [ -z "${testuid}" ]; then # Should never happen echo "FATAL ERROR: Could not get uid for user \"${testuser}\"!" exit 1 fi local testgroupname=$(id --group --name ${testuser} 2>/dev/null) if [ -z "${testgroupname}" ]; then # Should never happen echo "FATAL ERROR: Could not get uid of user \"${testuser}\"!" exit 1 fi local testgid=$(id --group ${testuser} 2>/dev/null) if [ -z "${testgid}" ]; then # Should never happen echo "FATAL ERROR: Could not get primary gid of user \"${testuser}\"!" exit 1 fi echo "Will use user \"${testusername}\" (#${testuid}) and group \"${testgroupname}\" (#${testgid})" TESTBENCH_TESTUSER[username]=${testusername} TESTBENCH_TESTUSER[uid]=${testuid} TESTBENCH_TESTUSER[groupname]=${testgroupname} TESTBENCH_TESTUSER[gid]=${testgid} } rsyslog-8.2512.0/tests/PaxHeaders/mmanon_zero_128_ipv6.sh0000644000000000000000000000013215055602574020122 xustar0030 mtime=1756824956.033451498 30 atime=1764931160.325629008 30 ctime=1764935932.708722395 rsyslog-8.2512.0/tests/mmanon_zero_128_ipv6.sh0000775000175000017500000000273215055602574017575 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv6.bits="129" ipv6.anonmode="zero") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`)' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: asdfghjk <129>Mar 10 01:00:00 172.20.245.8 tag: FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 tag: 61:34:ad::7:F aa:ff43::756:99:0 <129>Mar 10 01:00:00 172.20.245.8 tag: :: <129>Mar 10 01:00:00 172.20.245.8 tag: 0:: <129>Mar 10 01:00:00 172.20.245.8 tag: 13:abd:45: <129>Mar 10 01:00:00 172.20.245.8 tag: textnoblank72:8374:adc7:47FF::43:0:1AFEstillnoblank\"" shutdown_when_empty wait_shutdown export EXPECTED=' asdfghjk 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 0:0:0:0:0:0:0:0 13:abd:45: textnoblank0:0:0:0:0:0:0:0stillnoblank' cmp_exact grep 'invalid number of ipv6.bits (129), corrected to 128' ${RSYSLOG2_OUT_LOG} > /dev/null if [ $? -ne 0 ]; then echo "invalid correction of bits parameter generated, ${RSYSLOG2_OUT_LOG} is:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-defaults.sh0000644000000000000000000000013215055603742017346 xustar0030 mtime=1756825570.302069124 30 atime=1764931165.102705617 30 ctime=1764935934.068743213 rsyslog-8.2512.0/tests/omprog-defaults.sh0000775000175000017500000000405415055603742017020 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests omprog using the default values for all non-mandatory # settings. It also checks that command-line parameters are correctly # passed to the external program. # NOTE: Because the omprog feedback mode is not used in this test # (confirmMessages=off), it is difficult to synchronize the execution # of the external program with the test code. For this reason, it would # be difficult to test for negative cases (e.g. restart of the program # if it terminates prematurely) without making the test racy. So, we # only test a happy case: the program processes all logs received and # exits when the pipe is closed. After closing the pipe, omprog will # wait for the program to terminate during a timeout of 5 seconds # (default value of closeTimeout), which should be sufficient for the # program to write its output. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary="'$srcdir'/testsuites/omprog-defaults-bin.sh \"p1 with spaces\"'\ ' p2 \"\" --p4=\"middle quote\" \"--p6=\"proper middle quote\"\" \"p7 is last\"" template="outfmt" name="omprog_action" ) } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown export EXPECTED="Starting with parameters: p1 with spaces p2 --p4=\"middle quote\" --p6=\"proper middle quote\" p7 is last Next parameter is \"p1 with spaces\" Next parameter is \"p2\" Next parameter is \"\" Next parameter is \"--p4=\"middle\" Next parameter is \"quote\"\" Next parameter is \"--p6=\"proper middle quote\"\" Next parameter is \"p7 is last\" Received msgnum:00000000: Received msgnum:00000001: Received msgnum:00000002: Received msgnum:00000003: Received msgnum:00000004: Received msgnum:00000005: Received msgnum:00000006: Received msgnum:00000007: Received msgnum:00000008: Received msgnum:00000009: Terminating normally" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/tcp_forwarding_dflt_tpl.sh0000644000000000000000000000013015035412264021127 xustar0029 mtime=1752569012.41564652 29 atime=1764931158.81760481 30 ctime=1764935932.296716089 rsyslog-8.2512.0/tests/tcp_forwarding_dflt_tpl.sh0000775000175000017500000000231715035412264020603 0ustar00rgerrger#!/bin/bash # This test tests tcp forwarding with assigned default template. # added 2015-05-30 by rgerhards. Released under ASL 2.0 # create the pipe and start a background process that copies data from # it to the "regular" work file . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 template(name="outfmt" type="string" string="%msg:F,58:2%\n") #this is what we want to test: setting the default template module(load="builtin:omfwd" template="outfmt") if $msg contains "msgnum:" then action(type="omfwd" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp") ' ./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG & BGPROCESS=$! echo background minitcpsrv process id is $BGPROCESS # now do the usual run startup # 10000 messages should be enough injectmsg 0 10000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # note: minitcpsrv shuts down automatically if the connection is closed! # (we still leave the code here in in case we need it later) #echo shutting down minitcpsrv... #kill $BGPROCESS #wait $BGPROCESS #echo background process has terminated, continue test... # and continue the usual checks seq_check 0 9999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-logrotate-state-files.sh0000644000000000000000000000013215055603742021717 xustar0030 mtime=1756825570.301069108 30 atime=1764931166.203723263 30 ctime=1764935934.406748387 rsyslog-8.2512.0/tests/imfile-logrotate-state-files.sh0000775000175000017500000001131115055603742021363 0ustar00rgerrger#!/bin/bash . $srcdir/diag.sh check-inotify-only . ${srcdir:=.}/diag.sh init export TESTMESSAGES=1000 export RETRIES=50 export TESTMESSAGESFULL=$((3 * $TESTMESSAGES - 1)) # export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" # export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' $WorkDirectory '$RSYSLOG_DYNNAME'.spool # Enable debug for state file operations global( debug.whitelist="on" debug.files=["imfile.c"] ) module( load="../plugins/imfile/.libs/imfile" mode="inotify" ) input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on" PersistStateInterval="100" deleteStateOnFileMove="on" ) $template outfmt,"%msg:F,58:2%\n" if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' print_state_files() { local round=$1 echo "=== State files after round $round ===" if [ -d "$RSYSLOG_DYNNAME.spool" ]; then echo "State files in spool directory:" local state_count=$(ls -1 "$RSYSLOG_DYNNAME.spool/"imfile-state* 2>/dev/null | wc -l) echo "Total state files found: $state_count" if [ $state_count -eq 0 ]; then echo "No state files found" else ls -la "$RSYSLOG_DYNNAME.spool/"imfile-state* 2>/dev/null echo "" for statefile in "$RSYSLOG_DYNNAME.spool/"imfile-state*; do if [ -f "$statefile" ]; then echo "State file: $(basename "$statefile")" echo " Size: $(stat -c%s "$statefile" 2>/dev/null || echo "unknown") bytes" echo " Modified: $(stat -c%y "$statefile" 2>/dev/null || echo "unknown")" echo " Contents:" if [ -r "$statefile" ]; then cat "$statefile" 2>/dev/null | jq . 2>/dev/null | sed 's/^/ /' || { echo " Raw contents (not valid JSON):" cat "$statefile" 2>/dev/null | sed 's/^/ /' } else echo " Cannot read file (permissions?)" fi echo "" fi done fi else echo "Spool directory does not exist" fi echo "" } print_inode_info() { local round=$1 echo "=== Inode information after round $round ===" for file in "$RSYSLOG_DYNNAME".input.log*; do if [ -f "$file" ]; then local inode=$(stat -c%i "$file" 2>/dev/null || echo "N/A") local size=$(stat -c%s "$file" 2>/dev/null || echo "N/A") echo "File: $file - Inode: $inode - Size: $size bytes" fi done echo "" } write_log_lines() { local round=$1 local start_num=$((($round - 1) * $TESTMESSAGES)) echo "Writing $TESTMESSAGES log lines for round $round (starting from msgnum $start_num)" ./inputfilegen -m $TESTMESSAGES -i $start_num >> "$RSYSLOG_DYNNAME.input.log" } rotate_logs() { echo "Rotating logs..." if [ -f "$RSYSLOG_DYNNAME.input.log.3" ]; then echo " Removing $RSYSLOG_DYNNAME.input.log.3" rm -f "$RSYSLOG_DYNNAME.input.log.3" fi if [ -f "$RSYSLOG_DYNNAME.input.log.2" ]; then echo " Moving $RSYSLOG_DYNNAME.input.log.2 to $RSYSLOG_DYNNAME.input.log.3" mv "$RSYSLOG_DYNNAME.input.log.2" "$RSYSLOG_DYNNAME.input.log.3" fi if [ -f "$RSYSLOG_DYNNAME.input.log.1" ]; then echo " Moving $RSYSLOG_DYNNAME.input.log.1 to $RSYSLOG_DYNNAME.input.log.2" mv "$RSYSLOG_DYNNAME.input.log.1" "$RSYSLOG_DYNNAME.input.log.2" fi if [ -f "$RSYSLOG_DYNNAME.input.log" ]; then echo " Moving $RSYSLOG_DYNNAME.input.log to $RSYSLOG_DYNNAME.input.log.1" mv "$RSYSLOG_DYNNAME.input.log" "$RSYSLOG_DYNNAME.input.log.1" fi } # Create initial empty input file touch "$RSYSLOG_DYNNAME.input.log" startup echo "Started rsyslog, waiting 1 second for initialization..." ./msleep 1000 # Perform 3 rounds of write->rotate cycle for round in 1 2 3; do echo "" echo "=== ROUND $round ===" # Write log lines write_log_lines $round # Print inode information print_inode_info "round $round (after write)" # Wait for processing echo "Waiting 1 second for processing..." ./msleep 1000 # Rotate logs rotate_logs # Wait after rotation echo "Waiting 1 second after rotation..." ./msleep 1000 # Check state files print_state_files $round # Print inode information after rotation print_inode_info "round $round (after rotation)" done # Verify we got the expected number of messages expected_messages=$((3 * $TESTMESSAGES)) wait_file_lines $RSYSLOG_OUT_LOG $expected_messages $RETRIES shutdown_when_empty wait_shutdown seq_check 0 $TESTMESSAGESFULL print_state_files "after shutdown" # Validate that there is exactly one state file after shutdown state_count=$(ls -1 "$RSYSLOG_DYNNAME.spool/"imfile-state* 2>/dev/null | wc -l) if [ $state_count -gt 1 ]; then echo "FAIL: Multiple state files found ($state_count) - expected max 1" error_exit 1 fi # Cleanup echo "" echo "=== CLEANUP ===" echo "Removing generated files..." rm -f "$RSYSLOG_DYNNAME".input.log* rm -rf "$RSYSLOG_DYNNAME.spool" echo "Cleanup completed" exit_test rsyslog-8.2512.0/tests/PaxHeaders/uxsock_multiple_netns-vg.sh0000644000000000000000000000013215114522477021307 xustar0030 mtime=1764926783.046632128 30 atime=1764926783.496643176 30 ctime=1764935934.169744759 rsyslog-8.2512.0/tests/uxsock_multiple_netns-vg.sh0000775000175000017500000000012315114522477020752 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/uxsock_multiple_netns.sh rsyslog-8.2512.0/tests/PaxHeaders/include-obj-text-from-file.sh0000644000000000000000000000013215035412264021264 xustar0030 mtime=1752569012.398764645 30 atime=1764931159.196610892 30 ctime=1764935932.405717757 rsyslog-8.2512.0/tests/include-obj-text-from-file.sh0000775000175000017500000000061415035412264020734 0ustar00rgerrger#!/bin/bash # added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then {' add_conf " include(text=\`cat ${srcdir}/testsuites/include-std-omfile-action.conf\`) } " startup injectmsg 0 10 shutdown_when_empty wait_shutdown seq_check 0 9 exit_test rsyslog-8.2512.0/tests/PaxHeaders/tabescape_on.sh0000644000000000000000000000013015035412264016652 xustar0029 mtime=1752569012.41564652 30 atime=1764931166.460727382 29 ctime=1764935934.48274955 rsyslog-8.2512.0/tests/tabescape_on.sh0000775000175000017500000000134315035412264016324 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(parser.EscapeControlCharacterTab="on") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") $ErrorMessagesToStderr off template(name="outfmt" type="string" string="%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 test: before HT after HT (do NOT remove TAB!)\"" shutdown_when_empty wait_shutdown export EXPECTED=' before HT#011after HT (do NOT remove TAB!)' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/snmptrapreceiver.py0000644000000000000000000000013215055603742017645 xustar0030 mtime=1756825570.303069141 30 atime=1764931160.137625992 30 ctime=1764935932.652721538 rsyslog-8.2512.0/tests/snmptrapreceiver.py0000664000175000017500000000742315055603742017317 0ustar00rgerrger# call this via "python[3] script name" import sys from pysnmp.entity import engine, config from pysnmp.carrier.asyncore.dgram import udp from pysnmp.entity.rfc3413 import ntfrcv from pysnmp.smi import builder, view, compiler, rfc1902 from pyasn1.type.univ import OctetString # Global variables snmpport = 10162 snmpip = "127.0.0.1" szOutputfile = "snmp.out" szSnmpLogfile = "snmp_server.log" # For vrebose output bDebug = False # Read command line params if len(sys.argv) > 1: snmpport = int(sys.argv[1]) if len(sys.argv) > 2: snmpip = sys.argv[2] if len(sys.argv) > 3: szOutputfile = sys.argv[3] if len(sys.argv) > 4: szSnmpLogfile = sys.argv[4] # Create output files outputFile = open(szOutputfile,"w+") logFile = open(szSnmpLogfile,"a+") # Assemble MIB viewer mibBuilder = builder.MibBuilder() compiler.addMibCompiler(mibBuilder, sources=['file:///usr/share/snmp/mibs', 'file:///var/lib/snmp/mibs', '/usr/local/share/snmp/mibs/']) mibViewController = view.MibViewController(mibBuilder) # Pre-load MIB modules we expect to work with try: mibBuilder.loadModules('SNMPv2-MIB', 'SNMP-COMMUNITY-MIB', 'SYSLOG-MSG-MIB') except Exception: print("Failed loading MIBs") # Create SNMP engine with autogenernated engineID and pre-bound to socket transport dispatcher snmpEngine = engine.SnmpEngine() # Transport setup # UDP over IPv4, add listening interface/port config.addTransport( snmpEngine, udp.domainName + (1,), udp.UdpTransport().openServerMode((snmpip, snmpport)) ) # SNMPv1/2c setup # SecurityName <-> CommunityName mapping config.addV1System(snmpEngine, 'my-area', 'public') print("Started SNMP Trap Receiver: %s, %s, Output: %s" % (snmpport, snmpip, szOutputfile)) logFile.write("Started SNMP Trap Receiver: %s, %s, Output: %s" % (snmpport, snmpip, szOutputfile)) logFile.flush() # Add PID file creation after startup message import os with open(szSnmpLogfile + ".started", "w") as f: f.write(str(os.getpid())) # Callback function for receiving notifications # noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal def cbReceiverSnmp(snmpEngine, stateReference, contextEngineId, contextName, varBinds, cbCtx): transportDomain, transportAddress = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference) if (bDebug): szDebug = str("Notification From: %s, Domain: %s, SNMP Engine: %s, Context: %s" % (transportAddress, transportDomain, contextEngineId.prettyPrint(), contextName.prettyPrint())) print(szDebug) logFile.write(szDebug) logFile.flush() # Create output String szOut = "Trap Source{}, Trap OID {}".format(transportAddress, transportDomain) varBinds = [rfc1902.ObjectType(rfc1902.ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController) for x in varBinds] for name, val in varBinds: # Append to output String szOut = szOut + ", Oid: {}, Value: {}".format(name.prettyPrint(), val.prettyPrint()) if isinstance(val, OctetString): if (name.prettyPrint() != "SNMP-COMMUNITY-MIB::snmpTrapAddress.0"): szOctets = val.asOctets()#.rstrip('\r').rstrip('\n') szOut = szOut + ", Octets: {}".format(szOctets) if (bDebug): print('%s = %s' % (name.prettyPrint(), val.prettyPrint())) outputFile.write(szOut) if "\n" not in szOut: outputFile.write("\n") outputFile.flush() # Register SNMP Application at the SNMP engine ntfrcv.NotificationReceiver(snmpEngine, cbReceiverSnmp) # this job would never finish snmpEngine.transportDispatcher.jobStarted(1) # Run I/O dispatcher which would receive queries and send confirmations try: snmpEngine.transportDispatcher.runDispatcher() except: os.remove(szOutputfile + ".started") # Remove PID file on shutdown snmpEngine.transportDispatcher.closeDispatcher() raisersyslog-8.2512.0/tests/PaxHeaders/rscript_hash64.sh0000644000000000000000000000013215035412264017074 xustar0030 mtime=1752569012.411674314 30 atime=1764931167.465743486 30 ctime=1764935934.763753852 rsyslog-8.2512.0/tests/rscript_hash64.sh0000775000175000017500000000176615035412264016555 0ustar00rgerrger#!/bin/bash # added 2018-02-07 by Harshvardhan Shrivastava # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \rscript_hash64.sh\]: test for hash64 and hash64mod script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n") module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmhash/.libs/fmhash") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.hash_no_1 = hash64("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e"); set $.hash_no_2 = hash64mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 20 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown . $srcdir/diag.sh content-pattern-check "^\(-2574714428477944902 - 14\|-50452361579464591 - 25\)$" exit_test rsyslog-8.2512.0/tests/PaxHeaders/daqueue-invld-qi.sh0000644000000000000000000000013215035412264017403 xustar0030 mtime=1752569012.385854976 30 atime=1764931163.902686379 30 ctime=1764935933.733738086 rsyslog-8.2512.0/tests/daqueue-invld-qi.sh0000775000175000017500000000315015035412264017051 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on all flavors of Solaris." generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 1 $MainMsgQueueSaveOnShutdown on input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $ModLoad ../plugins/omtesting/.libs/omtesting # set spool locations and switch queue to disk-only mode $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueFilename mainq $IncludeConfig '${RSYSLOG_DYNNAME}'work-queuemode.conf $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt $IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf ' #export RSYSLOG_DEBUG="debug nologfuncflow nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="log" # prepare config echo \$MainMsgQueueType LinkedList > ${RSYSLOG_DYNNAME}work-queuemode.conf echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf # inject 10000 msgs, so that DO hit the high watermark startup injectmsg 0 10000 shutdown_immediate wait_shutdown check_mainq_spool ./mangle_qi -d -q ${RSYSLOG_DYNNAME}.spool/mainq.qi > tmp.qi mv tmp.qi ${RSYSLOG_DYNNAME}.spool/mainq.qi echo "Enter phase 2, rsyslogd restart" # restart engine and have rest processed #remove delay echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 9999 -d exit_test rsyslog-8.2512.0/tests/PaxHeaders/rsf_getenv.sh0000644000000000000000000000013215055602574016402 xustar0030 mtime=1756824956.039451582 30 atime=1764931159.129609817 30 ctime=1764935932.385717451 rsyslog-8.2512.0/tests/rsf_getenv.sh0000775000175000017500000000133715055602574016055 0ustar00rgerrger#!/bin/bash # Test for the getenv() rainerscript function # this is a quick test, but it guarantees that the code path is # at least progressed (but we do not check for unset envvars!) # added 2009-11-03 by Rgerhards # This file is part of the rsyslog project, released under GPLv3 # uncomment for debugging support: export NUMMESSAGES=10000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines export MSGNUM="msgnum:" . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! if $msg contains getenv("MSGNUM") then ?dynfile;outfmt ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/msgvar-concurrency-array-event.tags.sh0000644000000000000000000000013115035412264023247 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.117641715 29 ctime=1764935932.93572587 rsyslog-8.2512.0/tests/msgvar-concurrency-array-event.tags.sh0000775000175000017500000000261015035412264022716 0ustar00rgerrger#!/bin/bash # Test concurrency of message variables # Added 2015-11-03 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 export TCPFLOOD_EXTRA_OPTS="-M'msg:msg: 1:2, 3:4, 5:6, 7:8 b test'" echo =============================================================================== echo \[msgvar-concurrency-array-event.tags.sh\]: testing concurrency of local variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/mmnormalize/.libs/mmnormalize") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$!%\n") #action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList") action(type="mmnormalize" ruleBase="testsuites/msgvar-concurrency-array-event.tags.rulebase") if $msg contains "msg:" then { # set $!tree!here!nbr = field($msg, 58, 2); # Delimiter = : action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="outfmt" queue.type="linkedList") set $!tree!here!save = $!tree!here!nbr; set $!tree!here!nbr = ""; set $!tree!here!nbr = $!tree!here!save; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" queue.type="linkedList") } ' startup sleep 1 tcpflood -m500000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown #seq_check 0 499999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/json_array_looping.sh0000644000000000000000000000013215035412264020127 xustar0030 mtime=1752569012.398764645 30 atime=1764931167.571745184 30 ctime=1764935934.794754326 rsyslog-8.2512.0/tests/json_array_looping.sh0000775000175000017500000000421615035412264017601 0ustar00rgerrger#!/bin/bash # added 2014-11-11 by singh.janmejay # basic test for looping over json array # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="garply" type="string" string="garply: %$.garply%\n") template(name="grault" type="string" string="grault: %$.grault%\n") template(name="prefixed_grault" type="string" string="prefixed_grault: %$.grault%\n") template(name="quux" type="string" string="quux: %$.quux%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse") set $.garply = ""; ruleset(name="prefixed_writer" queue.type="linkedlist" queue.workerthreads="5") { action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.prefixed.log" template="prefixed_grault" queue.type="linkedlist") } foreach ($.quux in $!foo) do { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="quux") foreach ($.corge in $.quux!bar) do { reset $.grault = $.corge; action(type="omfile" file="'$RSYSLOG_DYNNAME'.out.async.log" template="grault" queue.type="linkedlist" action.copyMsg="on") call prefixed_writer if ($.garply != "") then set $.garply = $.garply & ", "; reset $.garply = $.garply & $.grault!baz; } } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="garply") ' startup tcpflood -m 1 -I $srcdir/testsuites/json_array_input echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check 'quux: abc0' content_check 'quux: def1' content_check 'quux: ghi2' content_check 'quux: { "bar": [ { "baz": "important_msg" }, { "baz": "other_msg" } ] }' custom_content_check 'grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.async.log custom_content_check 'grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.async.log custom_content_check 'prefixed_grault: { "baz": "important_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log custom_content_check 'prefixed_grault: { "baz": "other_msg" }' $RSYSLOG_DYNNAME.out.prefixed.log content_check 'garply: important_msg, other_msg' exit_test rsyslog-8.2512.0/tests/PaxHeaders/ommail_errmsg_no_params.sh0000644000000000000000000000013115035412264021124 xustar0030 mtime=1752569012.404722953 29 atime=1764931160.14562612 30 ctime=1764935932.654721569 rsyslog-8.2512.0/tests/ommail_errmsg_no_params.sh0000775000175000017500000000066315035412264020601 0ustar00rgerrger#!/bin/bash # add 2018-09-25 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../plugins/ommail/.libs/ommail") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") action(type="ommail") ' startup shutdown_when_empty wait_shutdown content_check "parameter 'mailto' required but not specified" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-maxFrameSize.sh0000644000000000000000000000013215035412264017736 xustar0030 mtime=1752569012.396778542 30 atime=1764931162.912670505 30 ctime=1764935933.446733692 rsyslog-8.2512.0/tests/imtcp-maxFrameSize.sh0000775000175000017500000000137115035412264017407 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(processInternalMessages="on") module(load="../plugins/imtcp/.libs/imtcp" maxFrameSize="100") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 -M "\"1005 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message\"" shutdown_when_empty wait_shutdown grep "Framing Error.*change to octet stuffing" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message from imtcp not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_conflict2.sh0000644000000000000000000000013215055602574021751 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.923622558 30 ctime=1764935932.595720666 rsyslog-8.2512.0/tests/rscript_unflatten_conflict2.sh0000775000175000017500000000245415055602574021425 0ustar00rgerrger#!/bin/bash # added 2021-03-09 by Julien Thomas, released under ASL 2.0 source "${srcdir:=.}/diag.sh" init export RSYSLOG_DEBUG="debug nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debug" generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmunflatten/.libs/fmunflatten") input(type="imtcp" port="0" listenPortFileName="'"$RSYSLOG_DYNNAME"'.tcpflood_port") template(name="outfmt" type="string" string="%msg% %$.ret% %$.unflatten%\n") if (not($msg contains "msgnum:")) then stop set $.x!a = 21; set $!a!b = "foo"; set $!a.b = $.x; set $.unflatten = unflatten($!, "."); set $.ret = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m 1 wait_file_lines "$RSYSLOG_OUT_LOG" 1 60 shutdown_when_empty wait_shutdown # this test may need changes to produce a more deterministic # output by sorting keys EXPECTED=' msgnum:00000000: 0 { "a": { "b": { "a": 21 } } }' cmp_exact "$RSYSLOG_OUT_LOG" EXPECTED='fmunflatten.c: warning: while processing flat key "a.b" at depth #1 (final node), overriding existing value of type string by an object' if ! grep -F "$EXPECTED" "$RSYSLOG_DEBUGLOG"; then echo "GREP FAILED" echo " => FILE: $RSYSLOG_DEBUGLOG" echo " => EXPECTED: $EXPECTED" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/gzipwr_hup-vg.sh0000644000000000000000000000013115055602574017047 xustar0030 mtime=1756824956.028451428 30 atime=1764931160.665634463 29 ctime=1764935932.80372385 rsyslog-8.2512.0/tests/gzipwr_hup-vg.sh0000775000175000017500000000020315055602574016512 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export NUMMESSAGES=200000 # reduce for slower valgrind run source ${srcdir:-.}/gzipwr_hup.sh rsyslog-8.2512.0/tests/PaxHeaders/threadingmqaq.sh0000644000000000000000000000013215035412264017056 xustar0030 mtime=1752569012.419618726 30 atime=1764931163.952687181 30 ctime=1764935933.748738315 rsyslog-8.2512.0/tests/threadingmqaq.sh0000775000175000017500000000310215035412264016521 0ustar00rgerrger#!/bin/bash # test many concurrent tcp connections # we send 100,000 messages in the hopes that his puts at least a little bit # of pressure on the threading subsystem. To really prove it, we would need to # push messages for several minutes, but that takes too long during the # automated tests (hint: do this manually after suspect changes). Thankfully, # in practice many threading bugs result in an abort rather quickly and these # should be covered by this test here. # rgerhards, 2009-06-26 uname if [ $(uname) = "SunOS" ] ; then echo "This test currently does not work on all flavors of Solaris." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MainMsgQueueTimeoutShutdown 10000 $MainMsgQueueWorkerThreadMinimumMessages 10 $MainMsgQueueWorkerThreads 5 $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! # write quickly to the output file: $OMFileFlushOnTXEnd off $OMFileIOBufferSize 256k # This time, also run the action queue detached $ActionQueueWorkerThreadMinimumMessages 10 $ActionQueueWorkerThreads 5 $ActionQueueTimeoutEnqueue 10000 $ActionQueueType LinkedList :msg, contains, "msgnum:" ?dynfile;outfmt ' startup #tcpflood -c2 -m100000 #shutdown_when_empty # shut down rsyslogd when done processing messages injectmsg 0 100000 # we need to sleep a bit on some environments, as imdiag can not correctly # diagnose when the action queues are empty... sleep 3 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream-consumerGroup-reclaim.sh0000644000000000000000000000013215055602574023766 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.076641057 30 ctime=1764935932.922725671 rsyslog-8.2512.0/tests/imhiredis-stream-consumerGroup-reclaim.sh0000775000175000017500000000432215055602574023436 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d . ${srcdir:=.}/diag.sh init start_redis generate_conf add_conf ' global(localhostname="server") module(load="../contrib/imhiredis/.libs/imhiredis") template(name="outfmt" type="string" string="%$/num% %$!msg%\n") input(type="imhiredis" server="127.0.0.1" port="'$REDIS_RANDOM_PORT'" key="mystream" mode="stream" stream.consumerGroup="mygroup" stream.consumerName="myName" stream.autoclaimIdleTime="5000" #5 seconds ruleset="redis") ruleset(name="redis") { set $/num = cnum($/num + 1); action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' redis_command "XADD mystream * msg message1" redis_command "XADD mystream * msg message2" redis_command "XADD mystream * msg message3" redis_command "XADD mystream * msg message4" redis_command "XADD mystream * msg message5" redis_command "XADD mystream * msg message6" redis_command "XGROUP CREATE mystream mygroup 0-0" # Read and claim message1 and message2 redis_command "XREADGROUP GROUP mygroup otherConsumer COUNT 2 STREAMS mystream >" rst_msleep 5500 # Read and claim message3 and message4 redis_command "XREADGROUP GROUP mygroup otherConsumer COUNT 2 STREAMS mystream >" startup shutdown_when_empty wait_shutdown output="$(redis_command 'hello 3\nXINFO groups mystream' | grep 'pending')" if [ -z "$output" ]; then echo "Could not get group result from redis, cannot tell if entries ware acknowledged!" error_exit 1 fi # Should still have 2 pending messages: message3 and message4 if ! echo "$output" | grep -q "pending 2"; then echo "ERROR: entries weren't acknowledged!" echo "ERROR: output from Redis is '$output'" echo "ERROR: expected 'pending 2'" error_exit 1 fi stop_redis # Should reclaim message1 and message2 # then claim and acknowledge message5 and message6 normally content_check '1 message1' content_check '2 message2' content_check '3 message5' content_check '4 message6' # Removes generated configuration file, log and pid files cleanup_redis exit_test rsyslog-8.2512.0/tests/PaxHeaders/rcvr_fail_restore.sh0000644000000000000000000000013215055603742017750 xustar0030 mtime=1756825570.302069124 30 atime=1764931163.842685417 30 ctime=1764935933.713737779 rsyslog-8.2512.0/tests/rcvr_fail_restore.sh0000775000175000017500000001170415055603742017422 0ustar00rgerrger#!/bin/bash # Copyright (C) 2011 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test does not work on FreeBSD - problems with os utility option switches" # # STEP1: start both instances and send 1000 messages. # Note: receiver is instance 1, sender instance 2. # # start up the instances. Note that the environment settings can be changed to # set instance-specific debugging parameters! #export RSYSLOG_DEBUG="debug nostdout" #export RSYSLOG_DEBUGLOG="log2" echo starting receiver generate_conf add_conf ' # then SENDER sends to this port (not tcpflood!) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" ./'$RSYSLOG_OUT_LOG';outfmt ' startup export PORT_RCVR="$TCPFLOOD_PORT" #export RSYSLOG_DEBUG="debug nostdout" #export RSYSLOG_DEBUGLOG="log" #valgrind="valgrind" echo starting sender generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueSize 2000 $MainMsgQueueLowWaterMark 800 $MainMsgQueueHighWaterMark 1000 $MainMsgQueueDequeueBatchSize 1 $MainMsgQueueMaxFileSize 1g $MainMsgQueueWorkerThreads 1 $MainMsgQueueFileName mainq # we use the shortest resume interval a) to let the test not run too long # and b) make sure some retries happen before the reconnect $ActionResumeInterval 1 $ActionSendResendLastMsgOnReconnect on $ActionResumeRetryCount -1 *.* @@127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # re-set params so that new instances do not thrash it... #unset RSYSLOG_DEBUG #unset RSYSLOG_DEBUGLOG # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 1000 wait_queueempty ./msleep 1000 # let things settle down a bit # # Step 2: shutdown receiver, then send some more data, which then # needs to go into the queue. # echo step 2 shutdown_when_empty wait_shutdown injectmsg2 1001 10000 ./msleep 3000 # make sure some retries happen (retry interval is set to 3 second) get_mainqueuesize 2 ls -l ${RSYSLOG_DYNNAME}.spool # # Step 3: restart receiver, wait that the sender drains its queue $InputTCPServerRun '$PORT_RCVR' # echo step 3 #export RSYSLOG_DEBUGLOG="log2" generate_conf add_conf ' # then SENDER sends to this port (not tcpflood!) module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="'$PORT_RCVR'") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" ./'$RSYSLOG_OUT_LOG';outfmt ' startup echo waiting for sender to drain queue [may need a short while] wait_queueempty 2 ls -l ${RSYSLOG_DYNNAME}.spool OLDFILESIZE=$(stat -c%s ${RSYSLOG_DYNNAME}.spool/mainq.00000001) echo file size to expect is $OLDFILESIZE # # Step 4: send new data. Queue files are not permitted to grow now # (but one file continuous to exist). # echo step 4 injectmsg2 11001 10 wait_queueempty 2 # at this point, the queue file shall not have grown. Note # that we MUST NOT shut down the instance right now, because it # would clean up the queue files! So we need to do our checks # first (here!). ls -l ${RSYSLOG_DYNNAME}.spool NEWFILESIZE=$(stat -c%s ${RSYSLOG_DYNNAME}.spool/mainq.00000001) if [ $NEWFILESIZE != $OLDFILESIZE ] then echo file sizes do not match, expected $OLDFILESIZE, actual $NEWFILESIZE echo this means that data has been written to the queue file where it echo no longer should be written. # abort will happen below, because we must ensure proper system shutdown # HOWEVER, during actual testing it may be useful to do an exit here (so # that e.g. the debug log is pointed right at the correct spot). # exit 1 fi # # We now do an extra test (so this is two in one ;)) to see if the DA # queue can be reactivated after its initial shutdown. In essence, we # redo steps 2 and 3. # # Step 5: stop receiver again, then send some more data, which then # needs to go into the queue. # echo step 5 echo "*** done primary test *** now checking if DA can be restarted" shutdown_when_empty wait_shutdown injectmsg2 11011 10000 sleep 1 # we need to wait, otherwise we may be so fast that the receiver # comes up before we have finally suspended the action get_mainqueuesize 2 ls -l ${RSYSLOG_DYNNAME}.spool # # Step 6: restart receiver, wait that the sender drains its queue # echo step 6 startup echo waiting for sender to drain queue [may need a short while] wait_queueempty 2 ls -l ${RSYSLOG_DYNNAME}.spool # # Queue file size checks done. Now it is time to terminate the system # and see if everything could be received (the usual check, done here # for completeness, more or less as a bonus). # shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # now abort test if we need to (due to filesize predicate) if [ $NEWFILESIZE != $OLDFILESIZE ]; then error_exit 1 fi # do the final check export SEQ_CHECK_OPTIONS=-d seq_check 1 21010 -m 100 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-wildcards-dirs-multi3.sh0000644000000000000000000000013115055602574021630 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.096721549 29 ctime=1764935934.36774779 rsyslog-8.2512.0/tests/imfile-wildcards-dirs-multi3.sh0000775000175000017500000000543415055602574021306 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . ${srcdir:=.}/diag.sh init export IMFILEINPUTFILES="1" export IMFILEINPUTFILESSTEPS="5" #export IMFILEINPUTFILESALL=$(($IMFILEINPUTFILES * $IMFILEINPUTFILESSTEPS)) export IMFILECHECKTIMEOUT="60" mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' /* Filter out busy debug output, comment out if needed */ global( debug.whitelist="off" debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"] ) global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module( load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*/*/testdir/*/file.logfile" Tag="file:" Severity="error" Facility="local7" addMetadata="on" ) template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value=", ") property(name="$!metadata!filename") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' # generate input files first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). for i in $(seq 1 $IMFILEINPUTFILES); do echo "Make $RSYSLOG_DYNNAME.input.dir$i" mkdir $RSYSLOG_DYNNAME.input.dir$i echo created! done # Start rsyslog now before adding more files startup # sleep a little to give rsyslog a chance to begin processing sleep 2 for j in $(seq 1 $IMFILEINPUTFILESSTEPS); do echo "Loop Num $j" for i in $(seq 1 $IMFILEINPUTFILES); do echo "Make $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir" mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir mkdir $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j touch $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile ls -l $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile done ls -d $RSYSLOG_DYNNAME.input.* # Check correct amount of input files each time IMFILEINPUTFILESALL=$((IMFILEINPUTFILES * j)) content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILESALL $IMFILECHECKTIMEOUT # Delete all but first! for i in $(seq 1 $IMFILEINPUTFILES); do rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j/testdir/subdir$j/file.logfile rm -rf $RSYSLOG_DYNNAME.input.dir$i/dir$j done # Helps in testbench parallel mode. # Otherwise sometimes directories are not marked deleted in imfile before they get created again. # This is properly a real issue in imfile when FILE IO is high. ./msleep 1000 done shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! exit_test rsyslog-8.2512.0/tests/PaxHeaders/nested-call-shutdown.sh0000644000000000000000000000013215035412264020275 xustar0030 mtime=1752569012.402736851 30 atime=1764931158.334597057 30 ctime=1764935932.162714037 rsyslog-8.2512.0/tests/nested-call-shutdown.sh0000775000175000017500000000165715035412264017755 0ustar00rgerrger#!/bin/bash # addd 2017-10-18 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="rs3" queue.type="linkedList") { action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ruleset(name="rs2" queue.type="linkedList") { call rs3 } ruleset(name="rs1" queue.type="linkedList") { call rs2 :omtesting:sleep 0 1000 } if $msg contains "msgnum:" then call rs1 ' startup #tcpflood -p'$TCPFLOOD_PORT' -m10000 injectmsg 0 1000 shutdown_immediate wait_shutdown # wo do not check reception - the main point is that we do not abort. The actual # message count is unknown (as the point is to shut down while still in processing). exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-transactions-failed-commits.sh0000644000000000000000000000013215035412264023135 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.287708582 30 ctime=1764935934.124744071 rsyslog-8.2512.0/tests/omprog-transactions-failed-commits.sh0000775000175000017500000001122415035412264022604 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests omprog with the confirmMessages=on and useTransactions=on # parameters, with the external program returning an error on certain # transaction commits. . ${srcdir:=.}/diag.sh init uname if [ $(uname) = "SunOS" ] ; then # On Solaris, this test causes rsyslog to hang. This is presumably due # to issue #2356 in the rsyslog core, which doesn't seem completely # corrected. TODO: re-enable this test when the issue is corrected. echo "Solaris: FIX ME" exit 77 fi generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-transactions-bin.sh --failed_commits` template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process queue.dequeueBatchSize="6" confirmMessages="on" useTransactions="on" action.resumeRetryCount="10" action.resumeInterval="1" ) } ' startup injectmsg 0 10 shutdown_when_empty wait_shutdown # Since the transaction boundaries are not deterministic, we cannot check for # an exact expected output. We must check the output programmatically. transaction_state="NONE" status_expected=true messages_to_commit=() messages_processed=() line_num=1 error= while IFS= read -r line; do if [[ $status_expected == true ]]; then case "$transaction_state" in "NONE") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi ;; "STARTED") if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi transaction_state="ACTIVE" ;; "ACTIVE") if [[ "$line" != "<= DEFER_COMMIT" ]]; then error="expecting a DEFER_COMMIT status from script" break fi ;; "COMMITTED") if [[ "$line" == "<= Error: could not commit transaction" ]]; then messages_to_commit=() transaction_state="NONE" else if [[ "$line" != "<= OK" ]]; then error="expecting an OK status from script" break fi messages_processed+=("${messages_to_commit[@]}") messages_to_commit=() transaction_state="NONE" fi ;; esac status_expected=false; else if [[ "$line" == "=> BEGIN TRANSACTION" ]]; then if [[ "$transaction_state" != "NONE" ]]; then error="unexpected transaction start" break fi transaction_state="STARTED" elif [[ "$line" == "=> COMMIT TRANSACTION" ]]; then if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected transaction commit" break fi transaction_state="COMMITTED" else if [[ "$transaction_state" != "ACTIVE" ]]; then error="unexpected message outside a transaction" break fi if [[ "$line" != "=> msgnum:"* ]]; then error="unexpected message contents" break fi prefix_to_remove="=> " messages_to_commit+=("${line#$prefix_to_remove}") fi status_expected=true; fi ((line_num++)) done < $RSYSLOG_OUT_LOG if [[ -z "$error" && "$transaction_state" != "NONE" ]]; then error="unexpected end of file (transaction state: $transaction_state)" fi if [[ -n "$error" ]]; then echo "$RSYSLOG_OUT_LOG: line $line_num: $error" cat $RSYSLOG_OUT_LOG error_exit 1 fi # Since the order in which failed messages are retried by rsyslog is not # deterministic, we sort the processed messages before checking them. IFS=$'\n' messages_sorted=($(sort <<<"${messages_processed[*]}")) unset IFS expected_messages=( "msgnum:00000000:" "msgnum:00000001:" "msgnum:00000002:" "msgnum:00000003:" "msgnum:00000004:" "msgnum:00000005:" "msgnum:00000006:" "msgnum:00000007:" "msgnum:00000008:" "msgnum:00000009:" ) if [[ "${messages_sorted[*]}" != "${expected_messages[*]}" ]]; then echo "unexpected set of processed messages:" printf '%s\n' "${messages_processed[@]}" echo "contents of $RSYSLOG_OUT_LOG:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmsnareparse-comprehensive.sh0000644000000000000000000000013215103346332021571 xustar0030 mtime=1762512090.634176013 30 atime=1764931158.229595372 30 ctime=1764935932.131713563 rsyslog-8.2512.0/tests/mmsnareparse-comprehensive.sh0000775000175000017500000002412115103346332021240 0ustar00rgerrger#!/bin/bash # Comprehensive test for mmsnareparse module field extraction capabilities # This test validates the module's ability to extract structured fields from # Windows Security Event Log description sections using dynamic test data from # sample-windows2022-security.data and sample-windows2025-security.data files. unset RSYSLOG_DYNNAME . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmsnareparse/.libs/mmsnareparse") # Template to extract comprehensive structured JSON output template(name="jsonfmt" type="list" option.jsonf="on") { # Event fields property(outname="eventid" name="$!win!Event!EventID" format="jsonf") property(outname="channel" name="$!win!Event!Channel" format="jsonf") property(outname="eventtype" name="$!win!Event!EventType" format="jsonf") property(outname="categorytext" name="$!win!Event!CategoryText" format="jsonf") property(outname="computer" name="$!win!Event!Computer" format="jsonf") property(outname="provider" name="$!win!Event!Provider" format="jsonf") # Subject fields property(outname="subjectsecurityid" name="$!win!Subject!SecurityID" format="jsonf") property(outname="subjectaccountname" name="$!win!Subject!AccountName" format="jsonf") property(outname="subjectaccountdomain" name="$!win!Subject!AccountDomain" format="jsonf") property(outname="subjectlogonid" name="$!win!Subject!LogonID" format="jsonf") # LogonInformation fields property(outname="logontype" name="$!win!LogonInformation!LogonType" format="jsonf") property(outname="logontypename" name="$!win!LogonInformation!LogonTypeName" format="jsonf") property(outname="restrictedadminmode" name="$!win!LogonInformation!RestrictedAdminMode" format="jsonf") property(outname="virtualaccount" name="$!win!LogonInformation!VirtualAccount" format="jsonf") property(outname="elevatedtoken" name="$!win!LogonInformation!ElevatedToken" format="jsonf") property(outname="impersonationlevel" name="$!win!LogonInformation!ImpersonationLevel" format="jsonf") # NewLogon fields property(outname="newlogonsecurityid" name="$!win!NewLogon!SecurityID" format="jsonf") property(outname="newlogonaccountname" name="$!win!NewLogon!AccountName" format="jsonf") property(outname="newlogonaccountdomain" name="$!win!NewLogon!AccountDomain" format="jsonf") property(outname="newlogonlogonid" name="$!win!NewLogon!LogonID" format="jsonf") property(outname="linkedlogonid" name="$!win!NewLogon!LinkedLogonID" format="jsonf") property(outname="networkaccountname" name="$!win!NewLogon!NetworkAccountName" format="jsonf") property(outname="logonguid" name="$!win!NewLogon!LogonGUID" format="jsonf") # Process fields property(outname="processid" name="$!win!Process!ProcessID" format="jsonf") property(outname="processname" name="$!win!Process!ProcessName" format="jsonf") property(outname="processcommandline" name="$!win!Process!ProcessCommandLine" format="jsonf") property(outname="tokenelevationtype" name="$!win!Process!TokenElevationType" format="jsonf") property(outname="mandatorylabel" name="$!win!Process!MandatoryLabel" format="jsonf") # Network fields property(outname="workstationname" name="$!win!Network!WorkstationName" format="jsonf") property(outname="sourcenetworkaddress" name="$!win!Network!SourceNetworkAddress" format="jsonf") property(outname="sourceport" name="$!win!Network!SourcePort" format="jsonf") # DetailedAuthentication fields property(outname="logonprocess" name="$!win!DetailedAuthentication!LogonProcess" format="jsonf") property(outname="authenticationpackage" name="$!win!DetailedAuthentication!AuthenticationPackage" format="jsonf") property(outname="transitedservices" name="$!win!DetailedAuthentication!TransitedServices" format="jsonf") property(outname="packagename" name="$!win!DetailedAuthentication!PackageName" format="jsonf") property(outname="keylength" name="$!win!DetailedAuthentication!KeyLength" format="jsonf") # Privileges fields property(outname="privilegelist" name="$!win!Privileges!PrivilegeList" format="jsonf") } # Template for basic field extraction (for comparison) template(name="basicfmt" type="list") { property(name="$!win!Event!EventID") constant(value=",") property(name="$!win!Event!Channel") constant(value=",") property(name="$!win!Event!EventType") constant(value=",") property(name="$!win!Event!CategoryText") constant(value=",") property(name="$!win!Event!Computer") constant(value=",") property(name="$!win!Event!Provider") constant(value="\n") } ruleset(name="winsec") { action(type="mmsnareparse") action(type="omfile" file="'$RSYSLOG_OUT_LOG'.json" template="jsonfmt") action(type="omfile" file="'$RSYSLOG_OUT_LOG'.basic" template="basicfmt") } input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="winsec") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port # Use dynamic test data from sample files echo "Using Windows 2022 sample data..." tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-windows2022-security.data echo "Using Windows 2025 sample data..." tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-windows2025-security.data echo "Using sample events with detailed field information..." tcpflood -m 1 -I ${srcdir}/testsuites/mmsnareparse/sample-events.data shutdown_when_empty wait_shutdown # Validate basic fields are extracted correctly from Windows 2022 data content_check '4624,Security,Success Audit,Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4634,Security,Success Audit,Logoff,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4647,Security,Success Audit,Logoff,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4648,Security,Success Audit,Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4672,Security,Success Audit,Special Logon,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4688,Security,Success Audit,Process Creation,WIN-5SB1I3G0V7U,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic # Validate basic fields are extracted correctly from Windows 2025 data content_check '4624,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4647,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4648,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4672,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic content_check '4688,Security,Success Audit,Audit Policy Change,WIN-IKCCUTRJI52,Microsoft-Windows-Security-Auditing' $RSYSLOG_OUT_LOG.basic # Validate that both Windows versions are properly parsed content_check 'WIN-5SB1I3G0V7U' $RSYSLOG_OUT_LOG.json content_check 'WIN-IKCCUTRJI52' $RSYSLOG_OUT_LOG.json # Validate structured JSON extraction from Windows 2022 data # Check for complete records with specific field combinations that actually exist content_check '"eventid":"4624"' $RSYSLOG_OUT_LOG.json content_check '"categorytext":"Logon"' $RSYSLOG_OUT_LOG.json content_check '"computer":"DC25-PREVIEW"' $RSYSLOG_OUT_LOG.json content_check '"subjectaccountname":"WIN-IKCCUTRJI52$"' $RSYSLOG_OUT_LOG.json content_check '"logontype":"5"' $RSYSLOG_OUT_LOG.json content_check '"logontypename":"Service"' $RSYSLOG_OUT_LOG.json content_check '"processname":"C:\\Windows\\System32\\services.exe"' $RSYSLOG_OUT_LOG.json content_check '"newlogonaccountname":"SYSTEM"' $RSYSLOG_OUT_LOG.json content_check '"newlogonaccountdomain":"NT AUTHORITY"' $RSYSLOG_OUT_LOG.json content_check '"logonprocess":"Advapi"' $RSYSLOG_OUT_LOG.json content_check '"authenticationpackage":"Negotiate"' $RSYSLOG_OUT_LOG.json # Placeholder tokens such as "-" should now be dropped entirely by the parser. # The JSON template still emits empty strings when a property is missing, so we # assert that hyphen placeholders never surface in the flattened output. check_not_present '"restrictedadminmode":"-"' "$RSYSLOG_OUT_LOG.json" check_not_present '"networkaccountname":"-"' "$RSYSLOG_OUT_LOG.json" check_not_present '"sourcenetworkaddress":"-"' "$RSYSLOG_OUT_LOG.json" check_not_present '"sourceport":"-"' "$RSYSLOG_OUT_LOG.json" check_not_present '"transitedservices":"-"' "$RSYSLOG_OUT_LOG.json" check_not_present '"packagename":"-"' "$RSYSLOG_OUT_LOG.json" # Validate structured JSON extraction from Windows 2025 data content_check '"categorytext":"Audit Policy Change"' $RSYSLOG_OUT_LOG.json content_check '"computer":"WIN-IKCCUTRJI52"' $RSYSLOG_OUT_LOG.json content_check '"subjectaccountname":"WIN-IKCCUTRJI52$"' $RSYSLOG_OUT_LOG.json content_check '"subjectaccountdomain":"WORKGROUP"' $RSYSLOG_OUT_LOG.json # Validate privileges extraction for 4672 events content_check '"privilegelist":"SeAssignPrimaryTokenPrivilege' $RSYSLOG_OUT_LOG.json # Validate that DWM-1 account is extracted correctly for virtual accounts content_check '"newlogonaccountname":"DWM-1"' $RSYSLOG_OUT_LOG.json content_check '"newlogonaccountdomain":"Window Manager"' $RSYSLOG_OUT_LOG.json # Validate that Administrator account is extracted correctly content_check '"subjectaccountname":"Administrator"' $RSYSLOG_OUT_LOG.json content_check '"subjectaccountdomain":"WIN-5SB1I3G0V7U"' $RSYSLOG_OUT_LOG.json # Validate various logon types are present content_check '"virtualaccount":"No"' $RSYSLOG_OUT_LOG.json content_check '"elevatedtoken":"Yes"' $RSYSLOG_OUT_LOG.json # Validate different event types have appropriate fields content_check '"eventid":"4634"' $RSYSLOG_OUT_LOG.json content_check '"eventid":"4647"' $RSYSLOG_OUT_LOG.json content_check '"eventid":"4648"' $RSYSLOG_OUT_LOG.json content_check '"eventid":"4672"' $RSYSLOG_OUT_LOG.json content_check '"eventid":"4688"' $RSYSLOG_OUT_LOG.json exit_test rsyslog-8.2512.0/tests/PaxHeaders/stop_when_array_has_element.sh0000644000000000000000000000013115035412264022000 xustar0029 mtime=1752569012.41564652 30 atime=1764931167.706747347 30 ctime=1764935934.834754939 rsyslog-8.2512.0/tests/stop_when_array_has_element.sh0000775000175000017500000000201315035412264021444 0ustar00rgerrger#!/bin/bash # added 2015-05-22 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[stop_when_array_has_element.sh\]: loop detecting presence of an element and stopping ruleset execution . ${srcdir:=.}/diag.sh init stop_when_array_has_element.sh generate_conf add_conf ' template(name="foo" type="string" string="%$!foo%\n") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmjsonparse") foreach ($.quux in $!foo) do { if ($.quux == "xyz0") then stop } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="foo") ' startup tcpflood -m 1 -I $srcdir/testsuites/stop_when_array_has_elem_input echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check '"abc0"' content_check '"abc2"' assert_content_missing 'xyz0' exit_test rsyslog-8.2512.0/tests/PaxHeaders/empty-ruleset.sh0000644000000000000000000000013215055602574017057 xustar0030 mtime=1756824956.027451414 30 atime=1764931162.767668179 30 ctime=1764935933.400732988 rsyslog-8.2512.0/tests/empty-ruleset.sh0000775000175000017500000000201715055602574016526 0ustar00rgerrger#!/bin/bash # Copyright 2014-11-20 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init custom_wait_file_lines() { wait_file_lines "$RSYSLOG_OUT_LOG" 10000 } export QUEUE_EMPTY_CHECK_FUNC=custom_wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") $MainMsgQueueTimeoutShutdown 10000 input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="real") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port2" ruleset="empty") $template outfmt,"%msg:F,58:2%\n" ruleset(name="empty") { } ruleset(name="real") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' startup assign_tcpflood_port2 "${RSYSLOG_DYNNAME}.tcpflood_port2" tcpflood -p$TCPFLOOD_PORT2 -m5000 -i0 # these should NOT show up tcpflood -p$TCPFLOOD_PORT -m10000 -i5000 tcpflood -p$TCPFLOOD_PORT2 -m500 -i15000 # these should NOT show up shutdown_when_empty wait_shutdown seq_check 5000 14999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmrfc3164-drop.sh0000644000000000000000000000013215055605325016624 xustar0030 mtime=1756826325.657800804 30 atime=1764931157.904590155 30 ctime=1764935932.041712185 rsyslog-8.2512.0/tests/pmrfc3164-drop.sh0000775000175000017500000000161415055605325016275 0ustar00rgerrger#!/bin/bash # added 2025-07-18 by Codex, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="input") parser(name="p3164" type="pmrfc3164" detect.headerless="on" headerless.errorfile="'$RSYSLOG_OUT_LOG'.err" headerless.drop="on") ruleset(name="input" parser="p3164") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'") } ' startup tcpflood -p $TCPFLOOD_PORT -m1 -M "\"this is not syslog\"" tcpflood -p $TCPFLOOD_PORT -m1 -M "\"<13>Oct 11 22:14:15 host tag: normal\"" shutdown_when_empty wait_shutdown ! grep -q 'this is not syslog' $RSYSLOG_OUT_LOG grep -q 'normal' $RSYSLOG_OUT_LOG || { cat $RSYSLOG_OUT_LOG; error_exit 1; } grep -q 'this is not syslog' ${RSYSLOG_OUT_LOG}.err || { cat ${RSYSLOG_OUT_LOG}.err; error_exit 1; } exit_test rsyslog-8.2512.0/tests/PaxHeaders/proprepltest-rfctag-udp.sh0000644000000000000000000000013115035412264021025 xustar0030 mtime=1752569012.408695159 30 atime=1764931159.064608774 29 ctime=1764935932.36671716 rsyslog-8.2512.0/tests/proprepltest-rfctag-udp.sh0000775000175000017500000000210515035412264020473 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'") template(name="outfmt" type="string" string="+%syslogtag:1:32%+\n") :pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\"" tcpflood -m1 -T "udp" -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\"" shutdown_when_empty wait_shutdown echo '+TAG:+ +0+ +01234567890123456789012345678901+ +01234567890123456789012345678901+' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_backticks-vg.sh0000644000000000000000000000013115062756615020361 xustar0030 mtime=1758190989.238641644 30 atime=1764931159.790620424 29 ctime=1764935932.56072013 rsyslog-8.2512.0/tests/rscript_backticks-vg.sh0000775000175000017500000000056215062756615020034 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if `echo $DO_WORK` == "on" and $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' export DO_WORK=on startup_vg injectmsg 0 1000 shutdown_when_empty wait_shutdown_vg seq_check 0 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omsendertrack-basic-vg.sh0000644000000000000000000000013215055603742020570 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.623633789 30 ctime=1764935932.791723666 rsyslog-8.2512.0/tests/omsendertrack-basic-vg.sh0000775000175000017500000000020315055603742020232 0ustar00rgerrger#!/bin/bash set -x pwd ls -l omsender*sh echo srcdir: $srcdir export USE_VALGRIND="YES" source ${srcdir:-.}/omsendertrack-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/sparse_array_lookup_table.sh0000644000000000000000000000013215055605325021470 xustar0030 mtime=1756826325.658800819 30 atime=1764931167.955751337 30 ctime=1764935934.905756025 rsyslog-8.2512.0/tests/sparse_array_lookup_table.sh0000775000175000017500000000423315055605325021141 0ustar00rgerrger#!/bin/bash # test for sparse-array lookup-table and HUP based reloading of it # added 2015-10-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate_array.lkp_tbl") template(name="outfmt" type="string" string="%msg% %$.lkp%\n") set $.num = field($msg, 58, 2); set $.lkp = lookup("xlate", $.num); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate_sparse_array.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl startup injectmsg 0 1 wait_queueempty assert_content_missing "foo" injectmsg 0 5 wait_queueempty content_check "msgnum:00000001: foo_old" content_check "msgnum:00000002: foo_old" content_check "msgnum:00000003: bar_old" content_check "msgnum:00000004: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_sparse_array_more.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 6 wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: foo_new" content_check "msgnum:00000002: bar_new" content_check "msgnum:00000003: bar_new" content_check "msgnum:00000004: baz" content_check "msgnum:00000005: baz" cp -f $srcdir/testsuites/xlate_sparse_array_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate_array.lkp_tbl issue_HUP await_lookup_table_reload injectmsg 0 15 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "msgnum:00000000: quux" content_check "msgnum:00000001: quux" content_check "msgnum:00000002: foo_latest" content_check "msgnum:00000003: baz_latest" content_check "msgnum:00000004: foo_latest" content_check "msgnum:00000005: foo_latest" content_check "msgnum:00000006: foo_latest" content_check "msgnum:00000007: foo_latest" content_check "msgnum:00000008: baz_latest" content_check "msgnum:00000009: baz_latest" content_check "msgnum:00000010: baz_latest" content_check "msgnum:00000011: baz_latest" content_check "msgnum:00000012: foo_latest" content_check "msgnum:00000013: foo_latest" content_check "msgnum:00000014: foo_latest" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd-lb-1target-retry-1_byte_buf-TargetFail.sh0000644000000000000000000000013215055603742024512 xustar0030 mtime=1756825570.302069124 30 atime=1764931160.496631752 30 ctime=1764935932.754723099 rsyslog-8.2512.0/tests/omfwd-lb-1target-retry-1_byte_buf-TargetFail.sh0000775000175000017500000000020615055603742024157 0ustar00rgerrger#!/bin/bash export OMFWD_IOBUF_SIZE=1000 # triggers edge cases source ${srcdir:-.}/omfwd-lb-1target-retry-test_skeleton-TargetFail.sh rsyslog-8.2512.0/tests/PaxHeaders/queue-direct-with-no-params.sh0000644000000000000000000000013215035412264021471 xustar0030 mtime=1752569012.408695159 30 atime=1764931158.866605596 30 ctime=1764935932.311716318 rsyslog-8.2512.0/tests/queue-direct-with-no-params.sh0000775000175000017500000000045115035412264021140 0ustar00rgerrger#!/bin/bash # added 2019-11-14 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown check_not_present "queue is in direct mode, but parameters have been set" exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse_invld_regex.sh0000644000000000000000000000013215035412264022123 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.961607121 30 ctime=1764935932.337716716 rsyslog-8.2512.0/tests/parsertest-parse_invld_regex.sh0000775000175000017500000000174715035412264021603 0ustar00rgerrger#!/bin/bash # add 2018-06-28 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%timereported:1:19:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<175>Feb 08 2008 23:47:31 hostname tag This is a message\"" shutdown_when_empty wait_shutdown echo '"2008-02-08T23:47:31", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/include-obj-outside-control-flow-vg.sh0000644000000000000000000000013215035412264023133 xustar0030 mtime=1752569012.397771593 30 atime=1764931159.213611165 30 ctime=1764935932.409717818 rsyslog-8.2512.0/tests/include-obj-outside-control-flow-vg.sh0000775000175000017500000000104515035412264022602 0ustar00rgerrger#!/bin/bash # added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") if not ($msg contains "msgnum:") then { stop } # Note: the point of this test is to have this include outside of # a control flow construct -- this the "strange" if above.' add_conf " include(file=\"${srcdir}/testsuites/include-std-omfile-actio*.conf\") " startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg seq_check 0 9 exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse-nodate.sh0000644000000000000000000000013215035412264021005 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.995607667 30 ctime=1764935932.347716869 rsyslog-8.2512.0/tests/parsertest-parse-nodate.sh0000775000175000017500000000220315035412264020451 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<27>xapi: [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message)\"" tcpflood -m1 -M "\"This is a message!\"" shutdown_when_empty wait_shutdown export EXPECTED="27,daemon,err,$RS_HOSTNAME,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (suppressing future logging of this message) 13,user,notice,This,is,is, a message!" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/cfg3.cfgtest0000644000000000000000000000013115055602574016106 xustar0030 mtime=1756824956.026451401 29 atime=1764931158.75160375 30 ctime=1764935932.277715798 rsyslog-8.2512.0/tests/cfg3.cfgtest0000664000175000017500000000072515055602574015557 0ustar00rgerrgerrsyslogd: error accessing config file or directory 'file-does-not-exist': No such file or directory [try https://www.rsyslog.com/e/2040 ] rsyslogd: the last error occurred in ./cfg3.testin, line 1 rsyslogd: CONFIG ERROR: there are no active actions configured. Inputs will run, but no output whatsoever is created. [try https://www.rsyslog.com/e/2103 ] rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file! rsyslogd: End of config validation run. Bye. rsyslog-8.2512.0/tests/PaxHeaders/linux_localtime_r.supp0000644000000000000000000000013115035412264020316 xustar0030 mtime=1752569012.398764645 30 atime=1764931168.226755678 29 ctime=1764935934.98375722 rsyslog-8.2512.0/tests/linux_localtime_r.supp0000664000175000017500000000436515035412264017773 0ustar00rgerrger{ linux-localtime_r-apparently-modifies-TZ Helgrind:Race ... fun:__tz_convert fun:timeval2syslogTime ... } { linux-localtime_r-apparently-modifies-TZ Helgrind:Race fun:strlen fun:__tzset_parse_tz fun:__tzfile_compute fun:__tz_convert ... } { linux-localtime_r-apparently-modifies-TZ Helgrind:Race ... fun:__tzstring fun:__tzfile_compute fun:__tz_convert ... } { linux-localtime_r-apparently-modifies-TZ-2 Helgrind:Race fun:__GI_strcmp fun:__tzfile_compute fun:__tz_convert ... } { CENTOS_6_only_report Helgrind:Misc fun:pthread_cond_destroy_WRK fun:pthread_cond_destroy@* fun:modExit fun:modUnlinkAndDestroy fun:Release fun:ReleaseObj fun:modExit ... } { CENTOS_6_only_report Helgrind:Misc fun:pthread_cond_destroy_WRK fun:pthread_cond_destroy@* fun:qqueueDestruct fun:actionDestruct fun:cnfstmtDestruct fun:cnfstmtDestructLst fun:cnfstmtDestruct fun:cnfstmtDestructLst fun:rulesetDestruct fun:rulesetDestructForLinkedList fun:llDestroyElt fun:llDestroy } { CENTOS_6_only_report Helgrind:Misc fun:pthread_cond_destroy_WRK fun:pthread_cond_destroy@* fun:modExit fun:modUnlinkAndDestroy fun:modUnloadAndDestructAll fun:main } { CENTOS_7_github_rsyslog_issue_2012 Helgrind:Race fun:GetLocalHostIP fun:logmsgInternalSubmit fun:logmsgInternal fun:doLogMsg.constprop.0 fun:LogMsg fun:wtpAdviseMaxWorkers fun:qqueueAdviseMaxWorkers fun:qqueueMultiEnqObjNonDirect fun:multiSubmitMsg2 fun:ratelimitAddMsg fun:enqLine fun:pollFileReal fun:pollFile fun:doPolling fun:runInput fun:thrdStarter } { CENTOS_7_github_rsyslog_issue_2012 Helgrind:Race fun:AddRef fun:MsgSetRcvFromIP fun:logmsgInternalSubmit fun:logmsgInternal fun:doLogMsg.constprop.0 fun:LogMsg fun:wtpAdviseMaxWorkers fun:qqueueAdviseMaxWorkers fun:qqueueMultiEnqObjNonDirect fun:multiSubmitMsg2 fun:ratelimitAddMsg fun:enqLine fun:pollFileReal fun:pollFile fun:doPolling fun:runInput } { CENTOS_7_github_rsyslog_issue_2012 Helgrind:Race fun:thrdDestruct fun:llDestroyElt fun:llDestroy fun:thrdTerminateAll fun:deinitAll fun:main } rsyslog-8.2512.0/tests/PaxHeaders/pmrfc3164-defaultTag.sh0000644000000000000000000000013215042442413017731 xustar0030 mtime=1753892107.727890831 30 atime=1764931157.879589754 30 ctime=1764935932.034712078 rsyslog-8.2512.0/tests/pmrfc3164-defaultTag.sh0000775000175000017500000000204415042442413017400 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="customparser") parser(name="custom.rfc3164" type="pmrfc3164" permit.AtSignsInHostname="off" force.tagEndingByColon="on") template(name="outfmt" type="string" string="?%hostname%?%syslogtag%?%msg%?\n") ruleset(name="customparser" parser="custom.rfc3164") { :hostname, contains, "Hostname" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) } ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname1 msgnum:1\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname2 msgnum:2\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname3 tag msgnum:3\"" tcpflood -m1 -M "\"<129>Mar 10 01:00:00 Hostname4 tag: msg\"" shutdown_when_empty wait_shutdown export EXPECTED='?Hostname1?-? msgnum:1? ?Hostname2?-? msgnum:2? ?Hostname3?-? tag msgnum:3? ?Hostname4?tag:? msg?' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_certvalid_expired.sh0000644000000000000000000000013215055603742022174 xustar0030 mtime=1756825570.303069141 30 atime=1764931168.344757568 30 ctime=1764935935.016757725 rsyslog-8.2512.0/tests/sndrcv_tls_certvalid_expired.sh0000775000175000017500000000405615055603742021650 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init printf 'using TLS driver: %s\n' ${RS_TLS_DRIVER:=gtls} # start up the instances # export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-key.pem'" defaultNetstreamDriver="'$RS_TLS_DRIVER'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="'$RS_TLS_DRIVER'" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" StreamDriver.PermitExpiredCerts="off" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export PORT_RCVR=$TCPFLOOD_PORT export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" #valgrind="valgrind" generate_conf 2 add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/testsuites/x.509/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/testsuites/x.509/client-expired-cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/testsuites/x.509/client-expired-key.pem'" defaultNetstreamDriver="'$RS_TLS_DRIVER'" ) # set up the action $ActionSendStreamDriverMode 1 # require TLS for the connection $ActionSendStreamDriverAuthMode anon *.* @@127.0.0.1:'$PORT_RCVR' ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown content_check --regex "not permitted to talk to peer '.*', certificate invalid: certificate expired" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-jsonarray-vg.sh0000644000000000000000000000013215035412264021243 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.052704816 30 ctime=1764935934.054742999 rsyslog-8.2512.0/tests/omhttp-batch-jsonarray-vg.sh0000775000175000017500000000012415035412264020707 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:=.}/omhttp-batch-jsonarray.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-endregex.sh0000644000000000000000000000013215055602574017304 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.748715971 30 ctime=1764935934.261746168 rsyslog-8.2512.0/tests/imfile-endregex.sh0000775000175000017500000000434215055602574016756 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 # This test mimics the test imfile-readmode2.sh, but works via # endmsg.regex. It's kind of a base test for the regex functionality. echo ====================================================================== echo [imfile-endregex.sh] . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" startmsg.regex="^[^ ]") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing sleep 1 # write some more lines (see https://github.com/rsyslog/rsyslog/issues/144) echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo 'msgnum:5' >> $RSYSLOG_DYNNAME.input # this one shouldn't be written to the output file because of ReadMode 2 # give it time to finish sleep 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! # give it time to write the output file sleep 1 ## check if we have the correct number of messages NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" cat $RSYSLOG_OUT_LOG exit 1 else if [ ! $NUMLINES -eq 3 ]; then echo "ERROR: expecting 3 headers, got $NUMLINES" cat $RSYSLOG_OUT_LOG exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {1..4}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" cat $RSYSLOG_OUT_LOG exit 1 fi done ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile-read-only.sh0000644000000000000000000000013015055602574017401 xustar0030 mtime=1756824956.034451512 29 atime=1764931160.73463557 29 ctime=1764935932.82272414 rsyslog-8.2512.0/tests/omfile-read-only.sh0000775000175000017500000000232015055602574017047 0ustar00rgerrger#!/bin/bash # addd 2016-06-16 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init messages=20000 # how many messages to inject? # Note: we need to inject a somewhat larger number of messages in order # to ensure that we receive some messages in the actual output file, # as batching can (validly) cause a larger loss in the non-writable # file generate_conf add_conf ' template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" { action(type="omfile" template="outfmt" file="'$RSYSLOG2_OUT_LOG'") action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'" action.execOnlyWhenPreviousIsSuspended="on" ) } ' touch ${RSYSLOG2_OUT_LOG} chmod 0400 ${RSYSLOG2_OUT_LOG} ls -l rsyslog.ou* startup injectmsg 0 $messages shutdown_when_empty wait_shutdown # we know that the output file is missing some messages, but it # MUST have some more, and these be in sequence. So we now read # the first message number and calculate based on it what must be # present in the output file. presort let firstnum=$((10#$($RS_HEADCMD -n1 $RSYSLOG_DYNNAME.presort))) echo "info: first message expected to be number $firstnum, using that value." seq_check $firstnum $((messages-1)) exit_test rsyslog-8.2512.0/tests/PaxHeaders/timegenerated-utc-legacy.sh0000644000000000000000000000013215035412264021101 xustar0030 mtime=1752569012.419618726 30 atime=1764931161.701651082 30 ctime=1764935933.105728473 rsyslog-8.2512.0/tests/timegenerated-utc-legacy.sh0000775000175000017500000000214715035412264020554 0ustar00rgerrger#!/bin/bash # added 2016-03-22 by RGerhards, released under ASL 2.0 # # NOTE: faketime does NOT properly support subseconds, # so we must ensure we do not use them. Actually, what we # see is uninitialized data value in tv_usec, which goes # away as soon as we do not run under faketime control. # FOR THE SAME REASON, there is NO VALGRIND EQUIVALENT # of this test, as valgrind would abort with reports # of faketime. # # IMPORTANT: we use legacy style for the template to ensure # that subseconds works properly for this as well. This is # a frequent use case. # . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=TEST+02:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%timegenerated:::date-utc%\n" :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' echo "***SUBTEST: check 2016-03-01" FAKETIME='2016-03-01 12:00:00' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED="Mar 1 14:00:00" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdropgroup.sh0000644000000000000000000000013215055602574017162 xustar0030 mtime=1756824956.037451554 30 atime=1764931161.274644233 30 ctime=1764935932.981726574 rsyslog-8.2512.0/tests/privdropgroup.sh0000775000175000017500000000147115055602574016634 0ustar00rgerrger#!/bin/bash # addd 2016-03-24 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' global(privdrop.group.keepsupplemental="on") template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) $PrivDropToGroup '${TESTBENCH_TESTUSER[groupname]}' ' startup shutdown_when_empty wait_shutdown content_check --regex "groupid.*${TESTBENCH_TESTUSER[gid]}" if [ ! $? -eq 0 ]; then echo "message indicating drop to group \"${TESTBENCH_TESTUSER[groupname]}\" (#${TESTBENCH_TESTUSER[gid]}) is missing:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl_setenv.sh0000644000000000000000000000013215035412264016535 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.979591359 30 ctime=1764935932.061712491 rsyslog-8.2512.0/tests/glbl_setenv.sh0000775000175000017500000000131515035412264016204 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(environment="http_proxy=http://127.0.0.1") set $!prx = getenv("http_proxy"); template(name="outfmt" type="string" string="%$!prx%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo 'http://127.0.0.1' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid content seen, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-queue-lpop-vg.sh0000644000000000000000000000013215055602574020721 xustar0030 mtime=1756824956.030451456 30 atime=1764931160.950639035 30 ctime=1764935932.885725105 rsyslog-8.2512.0/tests/imhiredis-queue-lpop-vg.sh0000775000175000017500000000030515055602574020366 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-queue-lpop.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_gt.sh0000644000000000000000000000013215035412264016411 xustar0030 mtime=1752569012.410681262 30 atime=1764931159.421614503 30 ctime=1764935932.470718752 rsyslog-8.2512.0/tests/rscript_gt.sh0000775000175000017500000000131615035412264016061 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_gt.sh\]: testing rainerscript GT statement . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); if $!usr!msgnum > "00004999" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 8000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 5000 7999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/action-tx-single-processing.sh0000644000000000000000000000013215055603742021575 xustar0030 mtime=1756825570.300069092 30 atime=1764931164.483695694 30 ctime=1764935933.896740581 rsyslog-8.2512.0/tests/action-tx-single-processing.sh0000775000175000017500000000240215055603742021242 0ustar00rgerrger#!/bin/bash # part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_TSAN # for some reason, this test is extremely slow under tsan, causing timeout fail export NUMMESSAGES=2000 export SEQ_CHECK_OPTIONS=-i2 check_sql_data_ready() { mysql_get_data seq_check --check-only 0 $((NUMMESSAGES - 2)) } export QUEUE_EMPTY_CHECK_FUNC=check_sql_data_ready generate_conf add_conf ' module(load="../plugins/ommysql/.libs/ommysql") global(errormessagestostderr.maxnumber="50") template(type="string" name="tpl" string="insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)" option.sql="on") template(type="string" name="tpl2" string="%$.num%|%$!facility%|insert into SystemEvents (Message, Facility) values (\"%msg%\", %$!facility%)\n" option.sql="on") if($msg contains "msgnum:") then { set $.num = field($msg, 58, 2); if $.num % 2 == 0 then { set $!facility = $syslogfacility; } else { set $/cntr = 0; } action(type="ommysql" name="mysql_action" server="127.0.0.1" template="tpl" db="'$RSYSLOG_DYNNAME'" uid="rsyslog" pwd="testbench") } action(type="omfile" file="'$RSYSLOG2_OUT_LOG'") ' mysql_prep_for_test startup injectmsg shutdown_when_empty wait_shutdown mysql_get_data seq_check 0 $((NUMMESSAGES - 2)) exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-basic-ignorecodes.sh0000644000000000000000000000013115055603742021126 xustar0030 mtime=1756825570.302069124 30 atime=1764931164.827701209 29 ctime=1764935933.99274205 rsyslog-8.2512.0/tests/omhttp-basic-ignorecodes.sh0000775000175000017500000000152315055603742020577 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 port="$(get_free_port)" omhttp_start_server $port --fail-with-401-or-403-after 5000 generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../contrib/omhttp/.libs/omhttp") if $msg contains "msgnum:" then action( # Payload name="my_http_action" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$port'" restpath="my/endpoint" batch="off" httpignorablecodes=["401", "NA", "403"] # Auth usehttps="off" ) ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $port my/endpoint omhttp_stop_server seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/no-parser-errmsg.sh0000644000000000000000000000013215035412264017434 xustar0030 mtime=1752569012.402736851 30 atime=1764931161.166642501 30 ctime=1764935932.949726085 rsyslog-8.2512.0/tests/no-parser-errmsg.sh0000775000175000017500000000155315035412264017107 0ustar00rgerrger#!/bin/bash # add 2017-03-06 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset") template(name="test" type="string" string="tag: %syslogtag%, pri: %pri%, syslogfacility: %syslogfacility%, syslogseverity: %syslogseverity% msg: %msg%\n") ruleset(name="ruleset" parser="rsyslog.rfc5424") { action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG` template="test") } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -m1 shutdown_when_empty wait_shutdown grep 'one message could not be processed by any parser' $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omtcl.sh0000644000000000000000000000013215071746523015357 xustar0030 mtime=1760021843.903422011 30 atime=1764931168.480759747 30 ctime=1764935935.054758306 rsyslog-8.2512.0/tests/omtcl.sh0000775000175000017500000000132215071746523015024 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../contrib/omtcl/.libs/omtcl $template tcldict, "message \"%msg:::json%\" fromhost \"%HOSTNAME:::json%\" facility \"%syslogfacility-text%\" priority \"%syslogpriority-text%\" timereported \"%timereported:::date-rfc3339%\" timegenerated \"%timegenerated:::date-rfc3339%\" raw \"%rawmsg:::json%\" tag \"%syslogtag:::json%\"" ' add_conf "*.* :omtcl:$srcdir/omtcl.tcl,doAction;tcldict " startup echo 'injectmsg literal <167>Mar 1 01:00:00 192.0.2.8 tag hello world' | \ ./diagtalker -p$IMDIAG_PORT || error_exit $? echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check 'HELLO WORLD' cat $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_backticks_static_text.sh0000644000000000000000000000013215062756615022363 xustar0030 mtime=1758190989.238641644 30 atime=1764931159.806620681 30 ctime=1764935932.565720207 rsyslog-8.2512.0/tests/rscript_backticks_static_text.sh0000775000175000017500000000106715062756615022036 0ustar00rgerrger#!/bin/bash ## Validate that backticks with `echo` expand environment variables even ## when punctuation is directly attached to the name. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" field.delimiter="58" field.number="2") constant(value="\n") } if `echo Prefix-$MYVAR!` == "Prefix-42!" and $msg contains "msgnum" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' export MYVAR=42 startup injectmsg 0 1 shutdown_when_empty wait_shutdown seq_check 0 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_processing_test2.sh0000644000000000000000000000013215035412264022140 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.836653248 30 ctime=1764935933.142729039 rsyslog-8.2512.0/tests/mmnormalize_processing_test2.sh0000775000175000017500000000651215035412264021613 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=TEST+02:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n") template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n") template(name="t_fromhost-ip" type="string" string="%fromhost-ip%") template(name="t_analytics_msg_default" type="string" string="%$!v_analytics_prefix%%rawmsg-after-pri%") template(name="t_analytics_tag_prefix" type="string" string="%$!v_tag%: ") template(name="t_analytics_msg_normalized" type="string" string="%timereported% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%") template(name="t_analytics_msg_normalized_vc" type="string" string="%timereported:1:6% %$year% %timereported:8:$% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%") template(name="t_analytics" type="string" string="[][][%$!v_fromhost-ip%][%timestamp:::date-unixtimestamp%][] %$!v_analytics_msg%\n") ruleset(name="ruleset1") { action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on") if ($!v_file == "") then { set $!v_file=$!v_tag; } action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record") action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path") set $!v_forward="PCI"; if ($!v_forward contains "PCI") then { if ($!v_fromhost-ip == "") then { set $!v_fromhost-ip=exec_template("t_fromhost-ip"); } if ($!v_msg == "" or $!v_tag == "") then { set $!v_analytics_msg=exec_template("t_analytics_msg_default"); } else { if ($!v_analytics_prefix == "") then { set $!v_analytics_prefix=exec_template("t_analytics_tag_prefix"); } if ($!v_hostname == "") then { # needed for vCenter logs with custom hostname set $!v_hostname=exec_template("t_fromhost-ip"); } if ($!v_exception == "VC") then { set $!v_analytics_msg=exec_template("t_analytics_msg_normalized_vc"); } else { set $!v_analytics_msg=exec_template("t_analytics_msg_normalized"); } } action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_analytics") } } ' FAKETIME='2017-03-08 12:18:47' startup tcpflood -m1 -M "\"<166>2017-03-08T12:18:47.165Z Host2.domain.com Process1: [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback\"" shutdown_when_empty wait_shutdown echo '2017-03-08T12:18:47.165Z 2017-03-08T12:18:47.165Z Host2.domain.com Process1 [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback /sb/logs/incoming/2017/03/08/svc_SER2/ret_Y01/os_ESX/127.0.0.1/r_relay1/esx.gz [][][127.0.0.1][1488975527][] Mar 8 12:18:47 127.0.0.1 Process1: [FFB87B70 verbose Process1HalCnxHostagent opID=WFU-abfbbece] [WaitForUpdatesDone] Completed callback' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-escapelf.replacement.sh0000644000000000000000000000013215035412264021554 xustar0030 mtime=1752569012.391813284 30 atime=1764931165.893718295 30 ctime=1764935934.308746887 rsyslog-8.2512.0/tests/imfile-escapelf.replacement.sh0000775000175000017500000000154515035412264021230 0ustar00rgerrger#!/bin/bash # Written in 2019 by Rainer Gerhards # This is part of the rsyslog testbench, licensed under ASL 2.0 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" ruleset="output" escapelf.replacement="[LF]" File="./'$RSYSLOG_DYNNAME'.input" tag="file:" startmsg.regex="^msg") template(name="outfmt" type="string" string="%msg%\n") ruleset(name="output") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' # make sure file exists when rsyslog starts up echo 'msg 1 part 1 msg 1 part 2 msg 2 msg INVISIBLE by design' > $RSYSLOG_DYNNAME.input startup export NUMMESSAGES=2 shutdown_when_empty wait_shutdown export EXPECTED='msg 1 part 1[LF] msg 1 part 2 msg 2' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-compress.sh0000644000000000000000000000013215055602574022010 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.758700102 30 ctime=1764935933.973741759 rsyslog-8.2512.0/tests/imhttp-post-payload-compress.sh0000775000175000017500000000202115055602574021452 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUG="debug" . ${srcdir:=.}/diag.sh init generate_conf IMHTTP_PORT="$(get_free_port)" add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../contrib/imhttp/.libs/imhttp" ports="'$IMHTTP_PORT'") #input(type="imhttp" endpoint="/postrequest" ruleset="ruleset" disablelfdelimiter="on") input(type="imhttp" endpoint="/postrequest" ruleset="ruleset") ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup NUMMESSAGES=50 for (( i=1; i<=NUMMESSAGES; i++ )) do echo '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' | gzip | curl -si --data-binary @- -H "Content-Encoding: gzip" http://localhost:$IMHTTP_PORT/postrequest done wait_queueempty shutdown_when_empty echo "file name: $RSYSLOG_OUT_LOG" content_count_check '[{"foo":"bar","bar":"foo"},{"one":"two","three":"four"}]' $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/daqueue-persist-drvr.sh0000644000000000000000000000013215035412264020324 xustar0030 mtime=1752569012.385854976 30 atime=1764931163.918686636 30 ctime=1764935933.738738162 rsyslog-8.2512.0/tests/daqueue-persist-drvr.sh0000775000175000017500000000324315035412264017775 0ustar00rgerrger#!/bin/bash # Test for queue data persisting at shutdown. The # plan is to start an instance, emit some data, do a relatively # fast shutdown and then re-start the engine to process the # remaining data. # added 2009-05-27 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 # uncomment for debugging support: . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 1 $MainMsgQueueSaveOnShutdown on input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $ModLoad ../plugins/omtesting/.libs/omtesting # set spool locations and switch queue to disk-only mode $WorkDirectory '$RSYSLOG_DYNNAME'.spool $MainMsgQueueFilename mainq $IncludeConfig '${RSYSLOG_DYNNAME}'work-queuemode.conf $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt $IncludeConfig '${RSYSLOG_DYNNAME}'work-delay.conf ' #export RSYSLOG_DEBUG="debug nologfuncflow nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="log" # prepare config echo \$MainMsgQueueType $1 > ${RSYSLOG_DYNNAME}work-queuemode.conf echo "*.* :omtesting:sleep 0 1000" > ${RSYSLOG_DYNNAME}work-delay.conf # inject 10000 msgs, so that DO hit the high watermark startup injectmsg 0 10000 shutdown_immediate wait_shutdown check_mainq_spool echo "Enter phase 2, rsyslogd restart" # restart engine and have rest processed #remove delay echo "#" > ${RSYSLOG_DYNNAME}work-delay.conf startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 9999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-long-msg.sh0000644000000000000000000000013015035412264017240 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.061688929 29 ctime=1764935933.77973879 rsyslog-8.2512.0/tests/imrelp-long-msg.sh0000775000175000017500000000113615035412264016712 0ustar00rgerrger#!/bin/bash # adddd 2018-04-16 by PascalWithopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(maxMessageSize="214800") module(load="../plugins/imrelp/.libs/imrelp") input(type="imrelp" port="'$TCPFLOOD_PORT'" maxdatasize="214800") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup tcpflood -Trelp-plain -p'$TCPFLOOD_PORT' -m2 -d 204800 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 1 exit_test rsyslog-8.2512.0/tests/PaxHeaders/timereported-utc-legacy.sh0000644000000000000000000000013215055602574020776 xustar0030 mtime=1756824956.042451623 30 atime=1764931161.718651355 30 ctime=1764935933.110728549 rsyslog-8.2512.0/tests/timereported-utc-legacy.sh0000775000175000017500000000146015055602574020446 0ustar00rgerrger#!/bin/bash # addd 2016-03-22 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%timereported:::date-rfc3339,date-utc%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' echo "*** SUBTEST 2003 ****" startup injectmsg_literal "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000" injectmsg_literal "<165>1 2016-03-01T12:00:00-02:00 192.0.2.1 tcpflood 8710 - - msgnum:0000000" injectmsg_literal "<165>1 2016-03-01T12:00:00Z 192.0.2.1 tcpflood 8710 - - msgnum:0000000" shutdown_when_empty wait_shutdown export EXPECTED="2003-08-24T12:14:15.000003+00:00 2016-03-01T14:00:00.000000+00:00 2016-03-01T12:00:00.000000+00:00" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/stop.sh0000644000000000000000000000013015035412264015214 xustar0029 mtime=1752569012.41564652 29 atime=1764931159.36161354 30 ctime=1764935932.454718507 rsyslog-8.2512.0/tests/stop.sh0000775000175000017500000000137515035412264014673 0ustar00rgerrger#!/bin/bash # Test for "stop" statement # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[stop.sh\]: testing stop statement . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if $msg contains "00000001" then stop template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup sleep 1 tcpflood -m10 -i1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 2 10 exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse_invld_regex-udp.sh0000644000000000000000000000013215035412264022711 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.970607265 30 ctime=1764935932.340716762 rsyslog-8.2512.0/tests/parsertest-parse_invld_regex-udp.sh0000775000175000017500000000171115035412264022360 0ustar00rgerrger#!/bin/bash # add 2018-06-28 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%timereported:1:19:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<175>Feb 08 2008 23:47:31 hostname tag This is a message\"" shutdown_when_empty wait_shutdown echo '"2008-02-08T23:47:31", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message"' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-close-unresponsive-noterm.sh0000644000000000000000000000013215035412264022677 xustar0030 mtime=1752569012.404722953 30 atime=1764931165.194707092 30 ctime=1764935934.097743657 rsyslog-8.2512.0/tests/omprog-close-unresponsive-noterm.sh0000775000175000017500000000311715035412264022350 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test checks that omprog does NOT send a TERM signal to the # external program when signalOnClose=off, closes the pipe, and kills # the unresponsive child if killUnresponsive=on. . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") main_queue( queue.timeoutShutdown="60000" # give time to omprog to wait for the child ) :msg, contains, "msgnum:" { action( type="omprog" binary="'$RSYSLOG_DYNNAME.'omprog-close-unresponsive-bin.sh" template="outfmt" name="omprog_action" queue.type="Direct" # the default; facilitates sync with the child process confirmMessages="on" # facilitates sync with the child process signalOnClose="off" closeTimeout="1000" # ms killUnresponsive="on" # default value: the value of signalOnClose ) } ' cp -f $srcdir/testsuites/omprog-close-unresponsive-bin.sh $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh startup injectmsg 0 10 shutdown_when_empty wait_shutdown . $srcdir/diag.sh ensure-no-process-exists $RSYSLOG_DYNNAME.omprog-close-unresponsive-bin.sh export EXPECTED="Starting Received msgnum:00000000: Received msgnum:00000001: Received msgnum:00000002: Received msgnum:00000003: Received msgnum:00000004: Received msgnum:00000005: Received msgnum:00000006: Received msgnum:00000007: Received msgnum:00000008: Received msgnum:00000009: Terminating unresponsively" cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse-3164-buggyday-udp.sh0000644000000000000000000000013215035412264022527 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.986607522 30 ctime=1764935932.344716824 rsyslog-8.2512.0/tests/parsertest-parse-3164-buggyday-udp.sh0000775000175000017500000000213515035412264022177 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp:::date-rfc3164-buggyday%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<38> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\"" tcpflood -m1 -T "udp" -M "\"<38> Mar 17 19:06:53 example tag: testmessage (only date actually tested)\"" shutdown_when_empty wait_shutdown echo '38,auth,info,Mar 07 19:06:53,example,tag,tag:, testmessage (only date actually tested) 38,auth,info,Mar 17 19:06:53,example,tag,tag:, testmessage (only date actually tested)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp-NUL.sh0000644000000000000000000000013215035412264016161 xustar0030 mtime=1752569012.394792439 30 atime=1764931163.407678442 30 ctime=1764935933.589735881 rsyslog-8.2512.0/tests/imptcp-NUL.sh0000775000175000017500000000127415035412264015634 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup echo '<167>Mar 6 16:57:54 172.20.245.8 test: msgnum:0 X test message <167>Mar 6 16:57:54 172.20.245.8 Xtest: msgnum:1 test message' | tr X '\000' > $RSYSLOG_DYNNAME.input tcpflood -B -I $RSYSLOG_DYNNAME.input shutdown_when_empty wait_shutdown seq_check 0 1 exit_test rsyslog-8.2512.0/tests/PaxHeaders/immark.sh0000644000000000000000000000013115035412264015510 xustar0030 mtime=1752569012.394792439 29 atime=1764931157.62958574 30 ctime=1764935931.965711022 rsyslog-8.2512.0/tests/immark.sh0000775000175000017500000000103615035412264015160 0ustar00rgerrger#!/bin/bash # very basic check for immark module - nevertheless, there is not # much more to test for... # add 2019-08-20 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/immark/.libs/immark" interval="1") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup printf 'sleeping a bit so we get mark messages...\n' sleep 3 # this should be good even on slow machines - we need just one shutdown_when_empty wait_shutdown content_check "rsyslogd: -- MARK --" exit_test rsyslog-8.2512.0/tests/PaxHeaders/improg_prog_killonclose.sh0000644000000000000000000000013215035412264021153 xustar0030 mtime=1752569012.394792439 30 atime=1764931164.602697602 30 ctime=1764935933.930741101 rsyslog-8.2512.0/tests/improg_prog_killonclose.sh0000775000175000017500000000127115035412264020623 0ustar00rgerrger#!/bin/bash # add 2019-04-04 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../contrib/improg/.libs/improg") input(type="improg" tag="tag" ruleset="ruleset" binary="'${srcdir:=.}'/improg-simul.sh -e '$RSYSLOG_DYNNAME'.stderr -n 1 -g" confirmmessages="off" signalonclose="on" killunresponsive="on" ) ruleset(name="ruleset") { action(type="omfile" file="'$RSYSLOG_OUT_LOG'") } ' startup shutdown_when_empty wait_shutdown content_check "program data" if [ ! -e $RSYSLOG_DYNNAME.stderr ]; then echo $RSYSLOG_DYNNAME'.stderr missing' error_exit 1 fi export EXPECTED='SIGTERM Received' cmp_exact $RSYSLOG_DYNNAME.stderr exit_test rsyslog-8.2512.0/tests/PaxHeaders/tcpflood.c0000644000000000000000000000013015071746523015661 xustar0030 mtime=1760021843.909422106 30 atime=1764931157.554584537 28 ctime=1764935931.9447107 rsyslog-8.2512.0/tests/tcpflood.c0000664000175000017500000024340415071746523015336 0ustar00rgerrger/* Opens a large number of tcp connections and sends * messages over them. This is used for stress-testing. * * NOTE: the following part is actually the SPEC (or call it man page). * It's not random comments. So if the code behavior does not match what * is written here, it should be considered a bug. * * Params * -h hostname to use inside message * -t target address (default 127.0.0.1) * -p target port(s) (default 13514), multiple via port1:port2:port3... * -n number of target ports (all target ports must be given in -p!) * Note -c must also be set to at LEAST the number of -n! * -c number of connections (default 1), use negative number * to set a "soft limit": if tcpflood cannot open the * requested number of connections, gracefully degrade to * whatever number could be opened. This is useful in environments * where system config constraints cannot be overriden (e.g. * vservers, non-admin users, ...) * -m number of messages to send (connection is random) * -i initial message number (optional) * -P PRI to be used for generated messages (default is 167). * Specify the plain number without leading zeros * -d amount of extra data to add to message. If present, the * number itself will be added as third field, and the data * bytes as forth. Add -r to randomize the amount of extra * data included in the range 1..(value of -d). * -r randomize amount of extra data added (-d must be > 0) * -s (silent) do not show progress indicator (never done on non-tty) * -f support for testing dynafiles. If given, include a dynafile ID * in the range 0..(f-1) as the SECOND field, shifting all field values * one field to the right. Zero (default) disables this functionality. * -M the message to be sent. Disables all message format options, as * only that exact same message is sent. * -I read specified input file, do NOT generate own test data. The test * completes when eof is reached. * -B The specified file (-I) is binary. No data processing is done by * tcpflood. If multiple connections are specified, data is read in * chunks and spread across the connections without taking any record * delimiters into account. * -C when input from a file is read, this file is transmitted -C times * (C like cycle, running out of meaningful option switches ;)) * -D randomly drop and re-establish connections. Useful for stress-testing * the TCP receiver. * -F USASCII value for frame delimiter (in octet-stuffing mode), default LF * -R number of times the test shall be run (very useful for gathering performance * data and other repetitive things). Default: 1 * -S number of seconds to sleep between different runs (-R) Default: 30 * -X generate sTats data records. Default: off * -e encode output in CSV (not yet everywhere supported) * for performance data: * each inidividual line has the runtime of one test * the last line has 0 in field 1, followed by numberRuns,TotalRuntime, * Average,min,max * -T transport to use. Currently supported: "udp", "tcp" (default), "tls" (tcp+tls), relp-plain, relp-tls * Note: UDP supports a single target port, only * -H * initiate a TLS ClientHello and exit once it is sent (requires -Ttls) * -u Set RELP TLS Library to gnutls or openssl * -W wait time between sending batches of messages, in microseconds (Default: 0) * -b number of messages within a batch (default: 100,000,000 millions) * -Y use multiple threads, one per connection (which means 1 if one only connection * is configured!) * -y use RFC5424 style test message * -x CA Cert File for verification (TLS Mode / OpenSSL only) * -z private key file for TLS mode * -Z cert (public key) file for TLS mode * -a Authentication Mode for relp-tls * -A do NOT abort if an error occured during sending messages * -E Permitted Peer for relp-tls * -L loglevel to use for GnuTLS troubleshooting (0-off to 10-all, 0 default) * -j format message in json, parameter is JSON cookie * -o number of threads to use for connection establishment (default: 25) * -O Use octet-count framing * -v verbose output, possibly useful for troubleshooting. Most importantly, * this gives insight into librelp actions (if relp is selected as protocol). * -k Custom Configuration string passwed through the TLS library. * Currently only OpenSSL is supported, possible configuration commands and values can be found here: * https://www.openssl.org/docs/man1.0.2/man3/SSL_CONF_cmd.html * Sample: -k"Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.1" * Works for LIBRELP now as well! * -w write the locally used port number to the specified file. The file * contains the port number followed by a line feed and is only valid * when a single connection is created. Works with TCP and UDP transports; * using it with RELP results in an error. * * Part of the testbench for rsyslog. * * Copyright 2009-2025 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Rsyslog is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Rsyslog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Rsyslog. If not, see . * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_RELP #include #endif #include #include #include #ifdef ENABLE_GNUTLS #include #if GNUTLS_VERSION_NUMBER <= 0x020b00 #include GCRY_THREAD_OPTION_PTHREAD_IMPL; #endif #endif #ifdef ENABLE_OPENSSL #include #include #include #ifndef OPENSSL_NO_ENGINE #include #endif /* OpenSSL API differences */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L #define RSYSLOG_X509_NAME_oneline(X509CERT) X509_get_subject_name(X509CERT) #define RSYSLOG_BIO_method_name(SSLBIO) BIO_method_name(SSLBIO) #define RSYSLOG_BIO_number_read(SSLBIO) BIO_number_read(SSLBIO) #define RSYSLOG_BIO_number_written(SSLBIO) BIO_number_written(SSLBIO) #else #define RSYSLOG_X509_NAME_oneline(X509CERT) (X509CERT != NULL ? X509CERT->cert_info->subject : NULL) #define RSYSLOG_BIO_method_name(SSLBIO) SSLBIO->method->name #define RSYSLOG_BIO_number_read(SSLBIO) SSLBIO->num #define RSYSLOG_BIO_number_written(SSLBIO) SSLBIO->num #endif #endif char *test_rs_strerror_r(int errnum, char *buf, size_t buflen) { #ifndef HAVE_STRERROR_R char *pszErr; pszErr = strerror(errnum); snprintf(buf, buflen, "%s", pszErr); #else #ifdef STRERROR_R_CHAR_P char *p = strerror_r(errnum, buf, buflen); if (p != buf) { strncpy(buf, p, buflen); buf[buflen - 1] = '\0'; } #else strerror_r(errnum, buf, buflen); #endif #endif /* #ifdef __hpux */ return buf; } #define INVALID_SOCKET -1 /* Name of input file, must match $IncludeConfig in test suite .conf files */ #define NETTEST_INPUT_CONF_FILE "nettest.input.conf" /* name of input file, must match $IncludeConfig in .conf files */ #define MAX_EXTRADATA_LEN 512 * 1024 #define MAX_SENDBUF 2 * MAX_EXTRADATA_LEN #define MAX_RCVBUF 16 * 1024 + 1 /* TLS RFC 8449: max size of buffer for message reception */ static int nThreadsConnOpen = 25; /* Number for threads for openeing the connections */ static char *targetIP = "127.0.0.1"; static char *msgPRI = "167"; static int targetPort[5] = {13514}; static int numTargetPorts = 1; static int verbose = 0; static int dynFileIDs = 0; static int extraDataLen = 0; /* amount of extra data to add to message */ static int useRFC5424Format = 0; /* should the test message be in RFC5424 format? */ static int bRandomizeExtraData = 0; /* randomize amount of extra data added */ static int numMsgsToSend = 1; /* number of messages to send */ static int numConnections = 1; /* number of connections to create */ static int softLimitConnections = 0; /* soft connection limit, see -c option description */ static int *sockArray; /* array of sockets to use */ #ifdef ENABLE_RELP static relpClt_t **relpCltArray; /* array of sockets to use */ #endif static int msgNum = 0; /* initial message number to start with */ static int bShowProgress = 1; /* show progress messages */ static int bSilent = 0; /* completely silent operation */ static int bRandConnDrop = 0; /* randomly drop connections? */ static double dbRandConnDrop = 0.95; /* random drop probability */ static char *MsgToSend = NULL; /* if non-null, this is the actual message to send */ static char *hostname = "172.20.245.8"; /* this is the "tratditional" default, as bad is it is... */ static int bBinaryFile = 0; /* is -I file binary */ static char *dataFile = NULL; /* name of data file, if NULL, generate own data */ static char *portFile = NULL; /* file to store local port number */ static int numFileIterations = 1; /* how often is file data to be sent? */ static char frameDelim = '\n'; /* default frame delimiter */ FILE *dataFP = NULL; /* file pointer for data file, if used */ static long nConnDrops = 0; /* counter: number of time connection was dropped (-D option) */ static int numRuns = 1; /* number of times the test shall be run */ static int sleepBetweenRuns = 30; /* number of seconds to sleep between runs */ static int bStatsRecords = 0; /* generate stats records */ static int bCSVoutput = 0; /* generate output in CSV (where applicable) */ static long long batchsize = 100000000ll; static int waittime = 0; static int runMultithreaded = 0; /* run tests in multithreaded mode */ static int numThrds = 1; /* number of threads to use */ static int abortOnSendFail = 1; /* abort run if sending fails? */ static char *tlsCAFile = NULL; static char *tlsCertFile = NULL; static char *tlsKeyFile = NULL; static char *relpAuthMode = NULL; static char *relpPermittedPeer = NULL; #if defined(HAVE_RELPENGINESETTLSLIBBYNAME) static char *relpTlsLib = NULL; #endif static int tlsLogLevel = 0; static char *jsonCookie = NULL; /* if non-NULL, use JSON format with this cookie */ static int octateCountFramed = 0; static char *customConfig = NULL; /* Stores a string with custom configuration passed through the TLS driver */ static bool handshakeOnly = false; #ifdef ENABLE_GNUTLS static gnutls_session_t *sessArray; /* array of TLS sessions to use */ static gnutls_certificate_credentials_t tlscred; #endif #ifdef ENABLE_OPENSSL /* Main OpenSSL CTX pointer */ static SSL_CTX *ctx; static SSL **sslArray; static struct sockaddr_in dtls_client_addr; /* socket address sender for receiving DTLS data */ static int udpsockin; /* socket for receiving messages in DTLS mode */ #endif /* serialize TLS session setup to avoid races inside the TLS library */ static pthread_mutex_t tlsSessInitMutex = PTHREAD_MUTEX_INITIALIZER; /* variables for managing multi-threaded operations */ int runningThreads; /* number of threads currently running */ int doRun; /* shall sender thread begin to run? */ pthread_mutex_t thrdMgmt; /* mutex for controling startup/shutdown */ pthread_cond_t condStarted; pthread_cond_t condDoRun; /* the following struct provides information for a generator instance (thread) */ struct instdata { /* lower and upper bounds for the thread in question */ unsigned long long lower; unsigned long long numMsgs; /* number of messages to send */ unsigned long long numSent; /* number of messages already sent */ unsigned idx; /**< index of fd to be used for sending */ pthread_t thread; /**< thread processing this instance */ } *instarray = NULL; /* the following structure is used to gather performance data */ struct runstats { unsigned long long totalRuntime; unsigned long minRuntime; unsigned long maxRuntime; int numRuns; }; static int udpsockout; /* socket for sending in UDP mode */ static struct sockaddr_in udpRcvr; /* remote receiver in UDP mode */ static enum { TP_UDP, TP_TCP, TP_TLS, TP_RELP_PLAIN, TP_RELP_TLS, TP_DTLS } transport = TP_TCP; /* forward definitions */ static void initTLSSess(int); static int sendTLS(int i, char *buf, size_t lenBuf); static void closeTLSSess(int __attribute__((unused)) i); static void initDTLSSess(void); static int sendDTLS(char *buf, size_t lenBuf); static void closeDTLSSess(void); #ifdef ENABLE_RELP /* RELP subsystem */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-security" static void relp_dbgprintf(char __attribute__((unused)) * fmt, ...) { printf(fmt); } #pragma GCC diagnostic pop static relpEngine_t *pRelpEngine; #define CHKRELP(f) \ if (f != RELP_RET_OK) { \ fprintf(stderr, "%s\n", #f); \ exit(1); \ } static void onErr(void *pUsr, char *objinfo, char *errmesg, __attribute__((unused)) relpRetVal errcode) { fprintf(stderr, "tcpflood: onErr '%s'\n", errmesg); } static void onGenericErr(char *objinfo, char *errmesg, __attribute__((unused)) relpRetVal errcode) { fprintf(stderr, "tcpflood: onGenericErr '%s'\n", errmesg); } static void onAuthErr(void *pUsr, char *authinfo, char *errmesg, __attribute__((unused)) relpRetVal errcode) { fprintf(stderr, "tcpflood: onAuthErr '%s' peer '%s'\n", errmesg, authinfo); } static void initRELP_PLAIN(void) { CHKRELP(relpEngineConstruct(&pRelpEngine)); CHKRELP(relpEngineSetDbgprint(pRelpEngine, verbose ? relp_dbgprintf : NULL)); CHKRELP(relpEngineSetEnableCmd(pRelpEngine, (unsigned char *)"syslog", eRelpCmdState_Required)); /* Error output support */ CHKRELP(relpEngineSetOnErr(pRelpEngine, onErr)); CHKRELP(relpEngineSetOnGenericErr(pRelpEngine, onGenericErr)); CHKRELP(relpEngineSetOnAuthErr(pRelpEngine, onAuthErr)); } #endif /* #ifdef ENABLE_RELP */ /* prepare send subsystem for UDP send */ static int setupUDP(void) { struct sockaddr_in lcl; if ((udpsockout = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return 1; memset(&lcl, 0, sizeof(lcl)); lcl.sin_family = AF_INET; lcl.sin_addr.s_addr = htonl(INADDR_ANY); lcl.sin_port = htons(0); if (bind(udpsockout, (struct sockaddr *)&lcl, sizeof(lcl)) == -1) { perror("bind()"); return 1; } memset((char *)&udpRcvr, 0, sizeof(udpRcvr)); udpRcvr.sin_family = AF_INET; udpRcvr.sin_port = htons(targetPort[0]); if (inet_aton(targetIP, &udpRcvr.sin_addr) == 0) { fprintf(stderr, "inet_aton() failed\n"); return (1); } return 0; } #if defined(ENABLE_OPENSSL) static int setupDTLS(void) { // Setup receiving Socket for DTLS if ((udpsockin = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return 1; memset(&dtls_client_addr, 0, sizeof(dtls_client_addr)); dtls_client_addr.sin_family = AF_INET; dtls_client_addr.sin_port = htons(0); dtls_client_addr.sin_addr.s_addr = INADDR_ANY; if (bind(udpsockin, (struct sockaddr *)&dtls_client_addr, sizeof(dtls_client_addr)) < 0) { perror("bind()"); fprintf(stderr, "Unable to bind DTLS CLient socket\n"); return (1); } memset((char *)&udpRcvr, 0, sizeof(udpRcvr)); udpRcvr.sin_family = AF_INET; udpRcvr.sin_port = htons(targetPort[0]); if (inet_aton(targetIP, &udpRcvr.sin_addr) == 0) { fprintf(stderr, "inet_aton() failed\n"); return (1); } // Init Socket Connection (Which technically does not connect but prepares socket for DTLS) printf("[DEBUG] Init Session to %s:%d ...\n", targetIP, targetPort[0]); udpsockout = socket(AF_INET, SOCK_DGRAM, 0); // Connect the UDP socket to the server's address if (connect(udpsockout, (const struct sockaddr *)&udpRcvr, sizeof(udpRcvr)) < 0) { perror("connect()"); fprintf(stderr, "connect to %s:%d failed\n", targetIP, targetPort[0]); return (1); } sockArray[0] = -1; return 0; } #endif /* open a single tcp connection */ int openConn(const int connIdx) { int sock; struct sockaddr_in addr; int port; int retries = 0; int rnd; /* randomize port if required */ if (numTargetPorts > 1) { rnd = rand(); /* easier if we need value for debug messages ;) */ port = targetPort[(rnd % numTargetPorts)]; } else { port = targetPort[0]; } if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) { #ifdef ENABLE_RELP relpRetVal relp_r; relpClt_t *relpClt; char relpPort[16]; snprintf(relpPort, sizeof(relpPort), "%d", port); CHKRELP(relpEngineCltConstruct(pRelpEngine, &relpClt)); if (transport == TP_RELP_TLS) { #if defined(HAVE_RELPENGINESETTLSLIBBYNAME) if (relpTlsLib != NULL && relpEngineSetTLSLibByName(pRelpEngine, relpTlsLib) != RELP_RET_OK) { fprintf(stderr, "relpTlsLib not accepted by librelp, using default\n"); } #endif if (relpCltEnableTLS(relpClt) != RELP_RET_OK) { fprintf(stderr, "error while enabling TLS for relp\n"); exit(1); } if (relpAuthMode != NULL && relpCltSetAuthMode(relpClt, relpAuthMode) != RELP_RET_OK) { fprintf(stderr, "could not set Relp Authentication mode: %s\n", relpAuthMode); exit(1); } if (tlsCAFile != NULL && relpCltSetCACert(relpClt, tlsCAFile) != RELP_RET_OK) { fprintf(stderr, "could not set CA File: %s\n", tlsCAFile); exit(1); } if (tlsCertFile != NULL && relpCltSetOwnCert(relpClt, tlsCertFile) != RELP_RET_OK) { fprintf(stderr, "could not set Cert File: %s\n", tlsCertFile); exit(1); } if (tlsKeyFile != NULL && relpCltSetPrivKey(relpClt, tlsKeyFile) != RELP_RET_OK) { fprintf(stderr, "could not set Key File: %s\n", tlsKeyFile); exit(1); } if (relpPermittedPeer != NULL && relpCltAddPermittedPeer(relpClt, relpPermittedPeer) != RELP_RET_OK) { fprintf(stderr, "could not set Permitted Peer: %s\n", relpPermittedPeer); exit(1); } #if defined(HAVE_RELPENGINESETTLSCFGCMD) /* Check for Custom Config string */ if (customConfig != NULL && relpCltSetTlsConfigCmd(relpClt, customConfig) != RELP_RET_OK) { fprintf(stderr, "could not set custom tls command: %s\n", customConfig); exit(1); } #endif } relpCltArray[connIdx] = relpClt; relp_r = relpCltConnect(relpCltArray[connIdx], 2, (unsigned char *)relpPort, (unsigned char *)targetIP); if (relp_r != RELP_RET_OK) { fprintf(stderr, "relp connect failed with return %d\n", relp_r); return (1); } sockArray[connIdx] = 1; /* mimic "all ok" state TODO: this looks invalid! */ #endif } else { /* TCP, with or without TLS */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { return (1); } memset((char *)&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (inet_aton(targetIP, &addr.sin_addr) == 0) { fprintf(stderr, "inet_aton() failed\n"); return (1); } while (1) { /* loop broken inside */ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { break; } else { fprintf(stderr, "warning: connect failed, retrying... %s\n", strerror(errno)); if (retries++ == 50) { perror("connect()"); fprintf(stderr, "connect(%d) failed\n", port); return (1); } else { usleep(100000); /* ms = 1000 us! */ } } } sockArray[connIdx] = sock; if (transport == TP_TLS) { pthread_mutex_lock(&tlsSessInitMutex); initTLSSess(connIdx); pthread_mutex_unlock(&tlsSessInitMutex); } } return 0; } static int progressCounter = 0; static pthread_mutex_t counterLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t reportedConnOpenErrLock = PTHREAD_MUTEX_INITIALIZER; typedef struct { int startIdx; int endIdx; } ThreadArgsOpen; /* Thread function to handle a range of connections */ void *connectionWorker(void *arg) { ThreadArgsOpen *args = (ThreadArgsOpen *)arg; int i; static int reportedConnOpenErr = 0; for (i = args->startIdx; i <= args->endIdx; i++) { if (openConn(i) != 0) { pthread_mutex_lock(&reportedConnOpenErrLock); if (reportedConnOpenErr++ == 0) { fprintf(stderr, "Error opening connection %d; %s\n", i, strerror(errno)); } pthread_mutex_unlock(&reportedConnOpenErrLock); pthread_exit(NULL); } /* Update progress counter */ pthread_mutex_lock(&counterLock); const int ctr_fixed = progressCounter++; pthread_mutex_unlock(&counterLock); if (bShowProgress && i % 10 == 0) { printf("\r%5.5d", ctr_fixed); } } pthread_exit(NULL); } /* open all requested tcp connections * this includes allocating the connection array */ int openConnections(void) { int i; char msgBuf[128]; size_t lenMsg; pthread_t threads[nThreadsConnOpen]; ThreadArgsOpen threadArgs[nThreadsConnOpen]; int threadCount = nThreadsConnOpen; if (transport == TP_UDP) return setupUDP(); #if defined(ENABLE_OPENSSL) sslArray = calloc(numConnections, sizeof(SSL *)); #elif defined(ENABLE_GNUTLS) sessArray = calloc(numConnections, sizeof(gnutls_session_t)); #endif sockArray = calloc(numConnections, sizeof(int)); #if defined(ENABLE_OPENSSL) // Use setupDTLS on DTLS if (transport == TP_DTLS) return setupDTLS(); #endif #ifdef ENABLE_RELP if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) relpCltArray = calloc(numConnections, sizeof(relpClt_t *)); #endif // Adjust the number of threads if there are fewer connections if (numConnections < threadCount) { threadCount = numConnections; } if (bShowProgress) if (write(1, " open connections", sizeof(" open connections") - 1)) { } // Divide connections among threads int connectionsPerThread = numConnections / threadCount; int remainder = numConnections % threadCount; int startIdx = 0; for (i = 0; i < threadCount; i++) { int endIdx = startIdx + connectionsPerThread - 1; endIdx += remainder; remainder = 0; threadArgs[i].startIdx = startIdx; threadArgs[i].endIdx = endIdx; if (pthread_create(&threads[i], NULL, connectionWorker, &threadArgs[i]) != 0) { fprintf(stderr, "Error creating thread: %s\n", strerror(errno)); return 1; } startIdx = endIdx + 1; } /* Wait for all connection open threads to finish */ for (i = 0; i < threadCount; i++) { pthread_join(threads[i], NULL); } return 0; } /* we also close all connections because otherwise we may get very bad * timing for the syslogd - it may not be able to process all incoming * messages fast enough if we immediately shut down. * TODO: it may be an interesting excercise to handle that situation * at the syslogd level, too * rgerhards, 2009-04-14 */ void closeConnections(void) { int i; size_t lenMsg; struct linger ling; char msgBuf[128]; if (transport == TP_UDP) { return; } #if defined(ENABLE_OPENSSL) else if (transport == TP_DTLS) { closeDTLSSess(); return; } #endif if (bShowProgress) if (write(1, " close connections", sizeof(" close connections") - 1)) { } for (i = 0; i < numConnections; ++i) { if (i % 10 == 0 && bShowProgress) { lenMsg = sprintf(msgBuf, "\r%5.5d", i); if (write(1, msgBuf, lenMsg)) { } } if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) { #ifdef ENABLE_RELP relpRetVal relpr; if (sockArray[i] != -1) { relpr = relpEngineCltDestruct(pRelpEngine, relpCltArray + i); if (relpr != RELP_RET_OK) { fprintf(stderr, "relp error %d on close\n", relpr); } sockArray[i] = -1; } #endif } else { /* TCP and TLS modes */ if (sockArray[i] != -1) { /* we try to not overrun the receiver by trying to flush buffers * *during* close(). -- rgerhards, 2010-08-10 */ ling.l_onoff = 1; ling.l_linger = 1; setsockopt(sockArray[i], SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); if (transport == TP_TLS) { closeTLSSess(i); } close(sockArray[i]); } } } if (bShowProgress) { lenMsg = sprintf(msgBuf, "\r%5.5d close connections\n", i); if (write(1, msgBuf, lenMsg)) { } } } /* generate the message to be sent according to program command line parameters. * this has been moved to its own function as we now have various different ways * of constructing test messages. -- rgerhards, 2010-03-31 */ static void genMsg(char *buf, size_t maxBuf, size_t *pLenBuf, struct instdata *inst) { int edLen; /* actual extra data length to use */ char extraData[MAX_EXTRADATA_LEN + 1]; char dynFileIDBuf[128] = ""; int done; char payloadLen[32]; int payloadStringLen; if (dataFP != NULL) { /* get message from file */ do { done = 1; *pLenBuf = fread(buf, 1, MAX_EXTRADATA_LEN + 1024, dataFP); if (*pLenBuf == 0) { if (--numFileIterations > 0) { rewind(dataFP); done = 0; /* need new iteration */ } else { *pLenBuf = 0; goto finalize_it; } } } while (!done); /* Attention: do..while()! */ } else if (jsonCookie != NULL) { if (useRFC5424Format) { *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z mymachine.example.com " "tcpflood - tag [tcpflood@32473 MSGNUM" "=\"%8.8d\"] %s{\"msgnum\":%d}%c", msgPRI, msgNum, jsonCookie, msgNum, frameDelim); } else { *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 %s tag %s{\"msgnum\":%d}%c", msgPRI, hostname, jsonCookie, msgNum, frameDelim); } } else if (MsgToSend == NULL) { if (dynFileIDs > 0) { snprintf(dynFileIDBuf, sizeof(dynFileIDBuf), "%d:", rand() % dynFileIDs); } if (extraDataLen == 0) { if (useRFC5424Format) { *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z " "mymachine.example.com tcpflood - tag [tcpflood@32473 " "MSGNUM=\"%8.8d\"] msgnum:%s%8.8d:%c", msgPRI, msgNum, dynFileIDBuf, msgNum, frameDelim); } else { *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 %s tag " "msgnum:%s%8.8d:%c", msgPRI, hostname, dynFileIDBuf, msgNum, frameDelim); } } else { if (bRandomizeExtraData) edLen = ((unsigned long)rand() + extraDataLen) % extraDataLen + 1; else edLen = extraDataLen; memset(extraData, 'X', edLen); extraData[edLen] = '\0'; if (useRFC5424Format) { *pLenBuf = snprintf(buf, maxBuf, "<%s>1 2003-03-01T01:00:00.000Z " "mymachine.example.com tcpflood - tag [tcpflood@32473 " "MSGNUM=\"%8.8d\"] msgnum:%s%8.8d:%c", msgPRI, msgNum, dynFileIDBuf, msgNum, frameDelim); } else { *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 %s tag msgnum" ":%s%8.8d:%d:%s%c", msgPRI, hostname, dynFileIDBuf, msgNum, edLen, extraData, frameDelim); } } } else { /* use fixed message format from command line */ *pLenBuf = snprintf(buf, maxBuf, "%s%c", MsgToSend, frameDelim); } if (octateCountFramed == 1) { size_t actual_len; /* when using octet-counted framing, omit the delimiter from the * payload itself. the delimiter is included in the default message * format to support traditional plain TCP framing. remove it here * before we prefix the payload length. */ actual_len = *pLenBuf; if (actual_len > 0 && buf[actual_len - 1] == frameDelim) { buf[--actual_len] = '\0'; } payloadStringLen = snprintf(payloadLen, sizeof(payloadLen), "%zu ", actual_len); if (payloadStringLen < 0 || payloadStringLen >= sizeof(payloadLen)) { fprintf(stderr, "tcpflood: payloadLen buffer too short or error - cannot continue " "(internal error), snprintf return %d\n", payloadStringLen); exit(1); } memmove(buf + payloadStringLen, buf, actual_len); memcpy(buf, payloadLen, payloadStringLen); *pLenBuf = actual_len + payloadStringLen; } ++inst->numSent; finalize_it: /*EMPTY to keep the compiler happy */; } static int sendPlainTCP(const int socknum, const char *const buf, const size_t lenBuf, int *const ret_errno) { size_t lenSent; int r; lenSent = 0; while (lenSent != lenBuf) { r = send(sockArray[socknum], buf + lenSent, lenBuf - lenSent, 0); if (r > 0) { lenSent += r; } else { *ret_errno = errno; goto finalize_it; } } finalize_it: return lenSent; } /* send messages to the tcp connections we keep open. We use * a very basic format that helps identify the message * (via msgnum:: e.g. msgnum:00000001:). This format is suitable * for extracton to field-based properties. * The first numConnection messages are sent sequentially, as are the * last. All messages in between are sent over random connections. * Note that message numbers start at 0. */ int sendMessages(struct instdata *inst) { unsigned i = 0; int socknum; size_t lenBuf; size_t lenSend = 0; char *statusText = ""; char buf[MAX_EXTRADATA_LEN + 1024]; char sendBuf[MAX_SENDBUF]; int offsSendBuf = 0; char errStr[1024]; int error_number = 0; unsigned show_progress_interval = 100; if (!bSilent) { if (dataFile == NULL) { printf("Sending %llu messages.\n", inst->numMsgs); statusText = "messages"; if ((inst->numMsgs / 100) > show_progress_interval) { show_progress_interval = inst->numMsgs / 100; } } else { printf("Sending file '%s' %d times.\n", dataFile, numFileIterations); statusText = "kb"; } } if (bShowProgress) printf("\r%8.8d %s sent", 0, statusText); while (i < inst->numMsgs) { if (runMultithreaded) { socknum = inst->idx; } else { if ((int)i < numConnections) socknum = i; else if (i >= inst->numMsgs - numConnections) { socknum = i - (inst->numMsgs - numConnections); } else { int rnd = rand(); socknum = rnd % numConnections; } } genMsg(buf, sizeof(buf), &lenBuf, inst); /* generate the message to send according to params */ if (lenBuf == 0) break; /* terminate when no message could be generated */ if (transport == TP_TCP) { if (sockArray[socknum] == -1) { /* connection was dropped, need to re-establish */ if (openConn(socknum) != 0) { printf("error in trying to re-open connection %d\n", socknum); exit(1); } } lenSend = sendPlainTCP(socknum, buf, lenBuf, &error_number); } else if (transport == TP_UDP) { lenSend = sendto(udpsockout, buf, lenBuf, 0, &udpRcvr, sizeof(udpRcvr)); error_number = errno; } else if (transport == TP_TLS) { if (sockArray[socknum] == -1) { /* connection was dropped, need to re-establish */ if (openConn(socknum) != 0) { printf("error in trying to re-open connection %d\n", socknum); exit(1); } } if (offsSendBuf + lenBuf < MAX_SENDBUF) { memcpy(sendBuf + offsSendBuf, buf, lenBuf); offsSendBuf += lenBuf; lenSend = lenBuf; /* simulate "good" call */ } else { lenSend = sendTLS(socknum, sendBuf, offsSendBuf); lenSend = (lenSend == offsSendBuf) ? lenBuf : -1; memcpy(sendBuf, buf, lenBuf); offsSendBuf = lenBuf; } #if defined(ENABLE_OPENSSL) } else if (transport == TP_DTLS) { if (sockArray[0] == -1) { // Init DTLS Session (Bind local listener) initDTLSSess(); } lenSend = sendDTLS(buf, lenBuf); #endif } else if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) { #ifdef ENABLE_RELP relpRetVal relp_ret; if (sockArray[socknum] == -1) { /* connection was dropped, need to re-establish */ if (openConn(socknum) != 0) { printf("error in trying to re-open connection %d\n", socknum); exit(1); } } relp_ret = relpCltSendSyslog(relpCltArray[socknum], (unsigned char *)buf, lenBuf); if (relp_ret == RELP_RET_OK) { lenSend = lenBuf; /* mimic ok */ } else { lenSend = 0; /* mimic fail */ printf("\nrelpCltSendSyslog() failed with relp error code %d\n", relp_ret); } #endif } if (lenSend != lenBuf) { printf("\r%5.5u\n", i); fflush(stdout); test_rs_strerror_r(error_number, errStr, sizeof(errStr)); if (lenSend == 0) { printf("tcpflood: socket %d, index %u, msgNum %lld CLOSED REMOTELY (%s)\n", sockArray[socknum], i, inst->numSent, errStr); } else { printf( "tcpflood: send() failed \"%s\" at socket %d, index %u, " "msgNum %lld, lenSend %zd, lenBuf %zd\n", errStr, sockArray[socknum], i, inst->numSent, lenSend, lenBuf); } fflush(stderr); if (abortOnSendFail) { printf("tcpflood terminates due to send failure\n"); return (1); } } if (i % show_progress_interval == 0) { if (bShowProgress) printf("\r%8.8u", i); } if (!runMultithreaded && bRandConnDrop) { /* if we need to randomly drop connections, see if we * are a victim */ if (rand() > (int)(RAND_MAX * dbRandConnDrop)) { if (transport == TP_TLS && offsSendBuf != 0) { /* send remaining buffer */ lenSend = sendTLS(socknum, sendBuf, offsSendBuf); if (lenSend != offsSendBuf) { fprintf(stderr, "tcpflood: error in send function for conn %d " "causes potential data loss lenSend %zd, " "offsSendBuf %d\n", sockArray[socknum], lenSend, offsSendBuf); } offsSendBuf = 0; } ++nConnDrops; close(sockArray[socknum]); sockArray[socknum] = -1; } } if (inst->numSent % batchsize == 0) { usleep(waittime); } ++msgNum; ++i; } if (transport == TP_TLS && offsSendBuf != 0) { /* send remaining buffer */ lenSend = sendTLS(socknum, sendBuf, offsSendBuf); } if (!bSilent) printf("\r%8.8u %s sent\n", i, statusText); return 0; } /* this is the thread that starts a generator */ static void *thrdStarter(void *arg) { struct instdata *inst = (struct instdata *)arg; pthread_mutex_lock(&thrdMgmt); runningThreads++; pthread_cond_signal(&condStarted); while (doRun == 0) { pthread_cond_wait(&condDoRun, &thrdMgmt); } pthread_mutex_unlock(&thrdMgmt); if (sendMessages(inst) != 0) { printf("error sending messages\n"); } return NULL; } /* This function initializes the actual traffic generators. The function sets up all required * parameter blocks and starts threads. It returns when all threads are ready to run * and the main task must just enable them. */ static void prepareGenerators(void) { int i; long long msgsThrd; long long starting = 0; pthread_attr_t thrd_attr; if (runMultithreaded) { bSilent = 1; numThrds = numConnections; } else { numThrds = 1; } pthread_attr_init(&thrd_attr); pthread_attr_setstacksize(&thrd_attr, 4096 * 1024); runningThreads = 0; doRun = 0; pthread_mutex_init(&thrdMgmt, NULL); pthread_cond_init(&condStarted, NULL); pthread_cond_init(&condDoRun, NULL); if (instarray != NULL) { free(instarray); } instarray = calloc(numThrds, sizeof(struct instdata)); msgsThrd = numMsgsToSend / numThrds; for (i = 0; i < numThrds; ++i) { instarray[i].lower = starting; instarray[i].numMsgs = msgsThrd; instarray[i].numSent = 0; instarray[i].idx = i; pthread_create(&(instarray[i].thread), &thrd_attr, thrdStarter, instarray + i); /*printf("started thread %x\n", (unsigned) instarray[i].thread);*/ starting += msgsThrd; } } /* Let all generators run. Threads must have been started. Here we wait until * all threads are initialized and then broadcast that they can begin to run. */ static void runGenerators(void) { pthread_mutex_lock(&thrdMgmt); while (runningThreads != numThrds) { pthread_cond_wait(&condStarted, &thrdMgmt); } doRun = 1; pthread_cond_broadcast(&condDoRun); pthread_mutex_unlock(&thrdMgmt); } /* Wait for all traffic generators to stop. */ static void waitGenerators(void) { int i; for (i = 0; i < numThrds; ++i) { pthread_join(instarray[i].thread, NULL); /*printf("thread %x stopped\n", (unsigned) instarray[i].thread);*/ } pthread_mutex_destroy(&thrdMgmt); pthread_cond_destroy(&condStarted); pthread_cond_destroy(&condDoRun); } /* functions related to computing statistics on the runtime of a test. This is * a separate function primarily not to mess up the test driver. * rgerhards, 2010-12-08 */ static void endTiming(struct timeval *tvStart, struct runstats *stats) { long sec, usec; unsigned long runtime; struct timeval tvEnd; gettimeofday(&tvEnd, NULL); if (tvStart->tv_usec > tvEnd.tv_usec) { tvEnd.tv_sec--; tvEnd.tv_usec += 1000000; } sec = tvEnd.tv_sec - tvStart->tv_sec; usec = tvEnd.tv_usec - tvStart->tv_usec; runtime = sec * 1000 + (usec / 1000); stats->totalRuntime += runtime; if (runtime < stats->minRuntime) stats->minRuntime = runtime; if (runtime > stats->maxRuntime) stats->maxRuntime = runtime; if (!bSilent || bStatsRecords) { if (bCSVoutput) { printf("%lu.%3.3ld\n", runtime / 1000, runtime % 1000); } else { printf("runtime: %lu.%3.3ld\n", runtime / 1000, runtime % 1000); } } } /* generate stats summary record at end of run */ static void genStats(struct runstats *stats) { long unsigned avg; avg = stats->totalRuntime / stats->numRuns; if (bCSVoutput) { printf("#numRuns,TotalRuntime,AvgRuntime,MinRuntime,MaxRuntime\n"); printf("%d,%llu.%3.3d,%lu.%3.3lu,%lu.%3.3lu,%lu.%3.3lu\n", stats->numRuns, stats->totalRuntime / 1000, (int)stats->totalRuntime % 1000, avg / 1000, avg % 1000, stats->minRuntime / 1000, stats->minRuntime % 1000, stats->maxRuntime / 1000, stats->maxRuntime % 1000); } else { printf("Runs: %d\n", stats->numRuns); printf("Runtime:\n"); printf(" total: %llu.%3.3d\n", stats->totalRuntime / 1000, (int)stats->totalRuntime % 1000); printf(" avg: %lu.%3.3lu\n", avg / 1000, avg % 1000); printf(" min: %lu.%3.3lu\n", stats->minRuntime / 1000, stats->minRuntime % 1000); printf(" max: %lu.%3.3lu\n", stats->maxRuntime / 1000, stats->maxRuntime % 1000); printf("All times are wallclock time.\n"); } } /* Run the actual test. This function handles various meta-parameters, like * a specified number of iterations, performance measurement and so on... * rgerhards, 2010-12-08 */ static int runTests(void) { struct timeval tvStart; struct runstats stats; int run; stats.totalRuntime = 0; stats.minRuntime = 0xffffffffllu; stats.maxRuntime = 0; stats.numRuns = numRuns; run = 1; while (1) { /* loop broken inside */ if (!bSilent) printf("starting run %d\n", run); prepareGenerators(); gettimeofday(&tvStart, NULL); runGenerators(); waitGenerators(); endTiming(&tvStart, &stats); if (run == numRuns) break; if (!bSilent) printf("sleeping %d seconds before next run\n", sleepBetweenRuns); sleep(sleepBetweenRuns); ++run; } if (bStatsRecords) { genStats(&stats); } return 0; } #if defined(ENABLE_OPENSSL) /* OpenSSL implementation of TLS funtions. * alorbach, 2018-06-11 */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) long BIO_debug_callback_ex(BIO *bio, int cmd, const char __attribute__((unused)) * argp, size_t __attribute__((unused)) len, int argi, long __attribute__((unused)) argl, int ret, size_t __attribute__((unused)) * processed) #else long BIO_debug_callback( BIO *bio, int cmd, const char __attribute__((unused)) * argp, int argi, long __attribute__((unused)) argl, long ret) #endif { long r = 1; if (BIO_CB_RETURN & cmd) { r = ret; } printf("tcpflood: openssl debugmsg: BIO[%p]: ", (void *)bio); switch (cmd) { case BIO_CB_FREE: printf("Free - %s\n", RSYSLOG_BIO_method_name(bio)); break; /* Disabled due API changes for OpenSSL 1.1.0+ */ #if OPENSSL_VERSION_NUMBER < 0x10100000L case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) { printf("read(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_read(bio)); } else { printf("read(%d,%lu) - %s\n", RSYSLOG_BIO_number_read(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); } break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) { printf("write(%d,%lu) - %s fd=%d\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio), RSYSLOG_BIO_number_written(bio)); } else { printf("write(%d,%lu) - %s\n", RSYSLOG_BIO_number_written(bio), (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); } break; #else case BIO_CB_READ: printf("read %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_WRITE: printf("write %s\n", RSYSLOG_BIO_method_name(bio)); break; #endif case BIO_CB_PUTS: printf("puts() - %s\n", RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_GETS: printf("gets(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_CTRL: printf("ctrl(%lu) - %s\n", (unsigned long)argi, RSYSLOG_BIO_method_name(bio)); break; case BIO_CB_RETURN | BIO_CB_READ: printf("read return %d\n", (int)ret); break; case BIO_CB_RETURN | BIO_CB_WRITE: printf("write return %d\n", (int)ret); break; case BIO_CB_RETURN | BIO_CB_GETS: printf("gets return %d\n", (int)ret); break; case BIO_CB_RETURN | BIO_CB_PUTS: printf("puts return %d\n", (int)ret); break; case BIO_CB_RETURN | BIO_CB_CTRL: printf("ctrl return %d\n", (int)ret); break; default: printf("bio callback - unknown type (%d)\n", cmd); break; } return r; } void osslLastSSLErrorMsg(int ret, SSL *ssl, const char *pszCallSource) { unsigned long un_error = 0; char psz[256]; if (ssl == NULL) { /* Output Error Info*/ printf("tcpflood: Error in '%s' with ret=%d\n", pszCallSource, ret); } else { long iMyRet = SSL_get_error(ssl, ret); /* Check which kind of error we have */ printf("tcpflood: openssl error '%s' with error code=%ld\n", pszCallSource, iMyRet); if (iMyRet == SSL_ERROR_SYSCALL) { iMyRet = ERR_get_error(); if (ret == 0) { iMyRet = SSL_get_error(ssl, iMyRet); if (iMyRet == 0) { *psz = '\0'; } else { ERR_error_string_n(iMyRet, psz, 256); } printf("tcpflood: Errno %d, SysErr: %s\n", errno, psz); } } else { printf("tcpflood: Unknown SSL Error in '%s' (%d), SSL_get_error: %ld\n", pszCallSource, ret, iMyRet); } } /* Loop through errors */ while ((un_error = ERR_get_error()) > 0) { ERR_error_string_n(un_error, psz, 256); printf("tcpflood: %s Errorstack: %s\n", pszCallSource, psz); } } int verify_callback(int status, X509_STORE_CTX *store) { char szdbgdata1[256]; char szdbgdata2[256]; if (status == 0) { printf("tcpflood: verify_callback certificate validation failed!\n"); X509 *cert = X509_STORE_CTX_get_current_cert(store); int depth = X509_STORE_CTX_get_error_depth(store); int err = X509_STORE_CTX_get_error(store); X509_NAME_oneline(X509_get_issuer_name(cert), szdbgdata1, sizeof(szdbgdata1)); X509_NAME_oneline(RSYSLOG_X509_NAME_oneline(cert), szdbgdata2, sizeof(szdbgdata2)); /* Log Warning only on EXPIRED */ if (err == X509_V_OK || err == X509_V_ERR_CERT_HAS_EXPIRED) { printf( "tcpflood: Certificate warning at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err)); /* Set Status to OK*/ status = 1; } else { printf( "tcpflood: Certificate error at depth: %d \n\t" "issuer = %s\n\t" "subject = %s\n\t" "err %d:%s\n", depth, szdbgdata1, szdbgdata2, err, X509_verify_cert_error_string(err)); exit(1); } } return status; } /* global init OpenSSL */ static void initTLS(const SSL_METHOD *method) { #if OPENSSL_VERSION_NUMBER < 0x10100000L /* Setup OpenSSL library < 1.1.0 */ if (!SSL_library_init()) { #else /* Setup OpenSSL library >= 1.1.0 with system default settings */ if (OPENSSL_init_ssl(0, NULL) == 0) { #endif printf("tcpflood: error openSSL initialization failed!\n"); exit(1); } /* Load readable error strings */ SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) /* * ERR_load_*(), ERR_func_error_string(), ERR_get_error_line(), ERR_get_error_line_data(), ERR_get_state() * OpenSSL now loads error strings automatically so these functions are not needed. * SEE FOR MORE: * https://www.openssl.org/docs/manmaster/man7/migration_guide.html * */ #else /* Load error strings into mem*/ ERR_load_BIO_strings(); ERR_load_crypto_strings(); #endif // Create OpenSSL Context ctx = SSL_CTX_new(method); if (tlsCAFile != NULL && SSL_CTX_load_verify_locations(ctx, tlsCAFile, NULL) != 1) { printf( "tcpflood: Error, Failed loading CA certificate" " Is the file at the right path? And do we have the permissions?"); exit(1); } SSL_CTX_set_ecdh_auto(ctx, 1); if (SSL_CTX_use_certificate_chain_file(ctx, tlsCertFile) != 1) { printf("tcpflood: error cert file could not be accessed -- have you mixed up key and certificate?\n"); printf("If in doubt, try swapping the files in -z/-Z\n"); printf("Certifcate is: '%s'\n", tlsCertFile); printf("Key is: '%s'\n", tlsKeyFile); exit(1); } if (SSL_CTX_use_PrivateKey_file(ctx, tlsKeyFile, SSL_FILETYPE_PEM) != 1) { printf("tcpflood: error key file could not be accessed -- have you mixed up key and certificate?\n"); printf("If in doubt, try swapping the files in -z/-Z\n"); printf("Certifcate is: '%s'\n", tlsCertFile); printf("Key is: '%s'\n", tlsKeyFile); exit(1); } /* Set CTX Options */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); /* Disable insecure SSLv2 Protocol */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); /* Disable insecure SSLv3 Protocol */ SSL_CTX_sess_set_cache_size(ctx, 1024); /* Check for Custom Config string */ if (customConfig != NULL) { #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER) char *pCurrentPos; char *pNextPos; char *pszCmd; char *pszValue; int iConfErr; printf("tcpflood: custom config set to '%s'\n", customConfig); /* Set working pointer */ pCurrentPos = (char *)customConfig; if (strlen(pCurrentPos) > 0) { pNextPos = index(pCurrentPos, '='); if (pNextPos != NULL) { pszCmd = strndup(pCurrentPos, pNextPos - pCurrentPos); pszValue = strdup(++pNextPos); // Create CTX Config Helper SSL_CONF_CTX *cctx; cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SHOW_ERRORS); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); /* Add SSL Conf Command */ iConfErr = SSL_CONF_cmd(cctx, pszCmd, pszValue); if (iConfErr > 0) { printf("tcpflood: Successfully added Command %s:%s\n", pszCmd, pszValue); } else { printf( "tcpflood: error, adding Command: %s:%s " "in SSL_CONF_cmd with error '%d'\n", pszCmd, pszValue, iConfErr); osslLastSSLErrorMsg(0, NULL, "initTLS"); } /* Finalize SSL Conf */ iConfErr = SSL_CONF_CTX_finish(cctx); if (!iConfErr) { printf("tcpflood: error, setting openssl command parameters: %s\n", customConfig); } free(pszCmd); free(pszValue); } else { printf("tcpflood: error, invalid value for -k: %s\n", customConfig); } } else { printf("tcpflood: error, invalid value for -k: %s\n", customConfig); } #else printf("tcpflood: TLS library does not support SSL_CONF_cmd API (maybe it is too old?)."); #endif } /* DO ONLY SUPPORT DEFAULT CIPHERS YET * SSL_CTX_set_cipher_list(ctx,"ALL"); Support all ciphers */ /* // Create Extra Length DH! pDH = DH_new(); if ( !DH_generate_parameters_ex(pDH, 768, DH_GENERATOR_2, NULL) ) { if(pDH) DH_free(pDH); fprintf(stderr, "Failed to generated dynamic DH\n"); exit(1); } else { int iErrCheck = 0; if ( !DH_check( pDH, &iErrCheck) ) { fprintf(stderr, "Failed to generated dynamic DH - iErrCheck=%d\n", iErrCheck); exit(1); } } */ /* Set default VERIFY Options for OpenSSL CTX - and CALLBACK */ SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback); SSL_CTX_set_timeout(ctx, 30); /* Default Session Timeout, TODO: Make configureable */ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); } static void exitTLS(void) { SSL_CTX_free(ctx); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif ERR_free_strings(); EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" static void initTLSSess(const int i) { int res; BIO *bio_client; SSL *pNewSsl = SSL_new(ctx); sslArray[i] = pNewSsl; if (!sslArray[i]) { osslLastSSLErrorMsg(0, sslArray[i], "initTLSSess1"); } SSL_set_verify(sslArray[i], SSL_VERIFY_NONE, verify_callback); /* Create BIO from socket array! */ const int bioCloseFlag = handshakeOnly ? BIO_NOCLOSE : BIO_CLOSE; bio_client = BIO_new_socket(sockArray[i], bioCloseFlag); if (bio_client == NULL) { osslLastSSLErrorMsg(0, sslArray[i], "initTLSSess2"); exit(1); } else { // printf("initTLSSess: Init client BIO[%p] done\n", (void *)bio_client); } if (tlsLogLevel > 0) { /* Set debug Callback for client BIO as well! */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) BIO_set_callback_ex(bio_client, BIO_debug_callback_ex); #else BIO_set_callback(bio_client, BIO_debug_callback); #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L } BIO_set_nbio(bio_client, handshakeOnly ? 1 : 0); SSL_set_bio(sslArray[i], bio_client, bio_client); SSL_set_connect_state(sslArray[i]); /*sets ssl to work in client mode.*/ /* Perform the TLS handshake */ if ((res = SSL_do_handshake(sslArray[i])) <= 0) { const int err = SSL_get_error(sslArray[i], res); if (handshakeOnly) { int allow = 0; switch (err) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: #ifdef SSL_ERROR_WANT_CONNECT case SSL_ERROR_WANT_CONNECT: #endif #ifdef SSL_ERROR_WANT_ACCEPT case SSL_ERROR_WANT_ACCEPT: #endif case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: allow = 1; break; default: break; } if (!allow) { osslLastSSLErrorMsg(res, sslArray[i], "initTLSSess3"); exit(1); } if (verbose) { switch (err) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: #ifdef SSL_ERROR_WANT_CONNECT case SSL_ERROR_WANT_CONNECT: #endif #ifdef SSL_ERROR_WANT_ACCEPT case SSL_ERROR_WANT_ACCEPT: #endif break; default: osslLastSSLErrorMsg(res, sslArray[i], "initTLSSess3"); break; } } ERR_clear_error(); } else { osslLastSSLErrorMsg(res, sslArray[i], "initTLSSess3"); exit(1); } } if (handshakeOnly) { SSL_free(sslArray[i]); sslArray[i] = NULL; if (sockArray[i] != -1) { close(sockArray[i]); } sockArray[i] = -1; } } #pragma GCC diagnostic pop static int sendTLS(int i, char *buf, size_t lenBuf) { size_t lenSent; int r, err; lenSent = 0; while (lenSent != lenBuf) { r = SSL_write(sslArray[i], buf + lenSent, lenBuf - lenSent); if (r > 0) { lenSent += r; } else { err = SSL_get_error(sslArray[i], r); if (err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { /*SSL_ERROR_ZERO_RETURN: TLS connection has been closed. This * result code is returned only if a closure alert has occurred * in the protocol, i.e. if the connection has been closed cleanly. *SSL_ERROR_WANT_READ/WRITE: The operation did not complete, try * again later. */ printf("Error while sending data: [%d] %s", err, ERR_error_string(err, NULL)); printf("Error is: %s", ERR_reason_error_string(err)); } else { /* Check for SSL Shutdown */ if (SSL_get_shutdown(sslArray[i]) == SSL_RECEIVED_SHUTDOWN) { printf("received SSL_RECEIVED_SHUTDOWN!\n"); } else { printf("[ERROR] while sending data: [%d] %s", err, ERR_error_string(err, NULL)); printf("[ERROR] Reason: %s", ERR_reason_error_string(err)); } } exit(1); } } return lenSent; } static void closeTLSSess(int i) { if (sslArray == NULL || sslArray[i] == NULL) { return; } int r; r = SSL_shutdown(sslArray[i]); if (r <= 0) { /* Shutdown not finished, call SSL_read to do a bidirectional shutdown, see doc for more: * https://www.openssl.org/docs/man1.1.1/man3/SSL_shutdown.html */ char rcvBuf[MAX_RCVBUF]; SSL_read(sslArray[i], rcvBuf, MAX_RCVBUF); } SSL_free(sslArray[i]); sslArray[i] = NULL; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" static void initDTLSSess(void) { int res; BIO *bio_client; // Create new SSL SSL *pNewSsl = SSL_new(ctx); // set to array variables sslArray[0] = pNewSsl; sockArray[0] = udpsockout; if (!sslArray[0]) { fprintf(stderr, "Unable to create SSL\n"); osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess1"); exit(1); } SSL_set_verify(sslArray[0], SSL_VERIFY_NONE, verify_callback); /* Create BIO from socket array! */ bio_client = BIO_new_dgram(udpsockout, BIO_NOCLOSE); if (!bio_client) { fprintf(stderr, "Unable to create BIO\n"); osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess2"); exit(1); } BIO_ctrl(bio_client, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &dtls_client_addr); SSL_set_bio(sslArray[0], bio_client, bio_client); if (tlsLogLevel > 0) { /* Set debug Callback for client BIO as well! */ #if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) BIO_set_callback_ex(bio_client, BIO_debug_callback_ex); #else BIO_set_callback(bio_client, BIO_debug_callback); #endif // OPENSSL_VERSION_NUMBER >= 0x10100000L } /* Blocking socket */ // BIO_set_nbio( bio_client, 0 ); // SSL_set_bio(sslArray[0], bio_client, bio_client); // SSL_set_connect_state(sslArray[0]); /*sets ssl to work in client mode.*/ printf("[DEBUG] Starting DTLS session ...\n"); /* Perform handshake */ if (SSL_connect(sslArray[0]) <= 0) { fprintf(stderr, "SSL_connect failed\n"); osslLastSSLErrorMsg(0, sslArray[0], "initDTLSSess3"); exit(1); } // Print Cipher info const SSL_CIPHER *cipher = SSL_get_current_cipher(sslArray[0]); if (tlsLogLevel > 0) { printf("[DEBUG] Cipher used: %s\n", SSL_CIPHER_get_name(cipher)); } // Print Peer Certificate info if (tlsLogLevel > 0) { X509 *cert = SSL_get_peer_certificate(sslArray[0]); if (cert != NULL) { char *line; line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("[DEBUG] Subject: %s\n", line); OPENSSL_free(line); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("[DEBUG] Issuer: %s\n", line); OPENSSL_free(line); X509_free(cert); } else { printf("[DEBUG] No certificates.\n"); } } /* Set and activate timeouts */ struct timeval timeout; timeout.tv_sec = 3; timeout.tv_usec = 0; BIO_ctrl(bio_client, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); } #pragma GCC diagnostic pop static int sendDTLS(char *buf, size_t lenBuf) { size_t lenSent; int r, err; lenSent = 0; r = SSL_write(sslArray[0], buf + lenSent, lenBuf - lenSent); if (r > 0) { lenSent += r; } else { err = SSL_get_error(sslArray[0], r); switch (err) { case SSL_ERROR_SYSCALL: printf("[ERROR] SSL_write (SSL_ERROR_SYSCALL): %s\n", strerror(errno)); break; default: printf("[ERROR] while sending data: [%d] %s", err, ERR_error_string(err, NULL)); printf("[ERROR] Reason: %s", ERR_reason_error_string(err)); } exit(1); } return lenSent; } static void closeDTLSSess(void) { printf("closeDTLSSess ENTER\n"); int r; r = SSL_shutdown(sslArray[0]); if (r <= 0) { /* Shutdown not finished, call SSL_read to do a bidirectional shutdown, see doc for more: * https://www.openssl.org/docs/man1.1.1/man3/SSL_shutdown.html */ char rcvBuf[MAX_RCVBUF]; SSL_read(sslArray[0], rcvBuf, MAX_RCVBUF); } SSL_free(sslArray[0]); close(udpsockout); close(udpsockin); printf("closeDTLSSess EXIT\n"); } #elif defined(ENABLE_GNUTLS) /* This defines a log function to be provided to GnuTLS. It hopefully * helps us track down hard to find problems. * rgerhards, 2008-06-20 */ static void tlsLogFunction(int level, const char *msg) { printf("GnuTLS (level %d): %s", level, msg); } static void exitTLS(void) {} /* global init GnuTLS */ static void initTLS(void) { int r; /* order of gcry_control and gnutls_global_init matters! */ #if GNUTLS_VERSION_NUMBER <= 0x020b00 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif gnutls_global_init(); /* set debug mode, if so required by the options */ if (tlsLogLevel > 0) { gnutls_global_set_log_function(tlsLogFunction); gnutls_global_set_log_level(tlsLogLevel); } r = gnutls_certificate_allocate_credentials(&tlscred); if (r != GNUTLS_E_SUCCESS) { printf("error allocating credentials\n"); gnutls_perror(r); exit(1); } r = gnutls_certificate_set_x509_key_file(tlscred, tlsCertFile, tlsKeyFile, GNUTLS_X509_FMT_PEM); if (r != GNUTLS_E_SUCCESS) { printf("error setting certificate files -- have you mixed up key and certificate?\n"); printf("If in doubt, try swapping the files in -z/-Z\n"); printf("Certifcate is: '%s'\n", tlsCertFile); printf("Key is: '%s'\n", tlsKeyFile); gnutls_perror(r); r = gnutls_certificate_set_x509_key_file(tlscred, tlsKeyFile, tlsCertFile, GNUTLS_X509_FMT_PEM); if (r == GNUTLS_E_SUCCESS) { printf( "Tried swapping files, this seems to work " "(but results may be unpredictable!)\n"); } else { exit(1); } } } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" static void initTLSSess(const int i) { int r; gnutls_init(sessArray + i, GNUTLS_CLIENT); /* Use default priorities */ gnutls_set_default_priority(sessArray[i]); /* put our credentials to the current session */ r = gnutls_credentials_set(sessArray[i], GNUTLS_CRD_CERTIFICATE, tlscred); if (r != GNUTLS_E_SUCCESS) { fprintf(stderr, "Setting credentials failed\n"); gnutls_perror(r); exit(1); } /* NOTE: the following statement generates a cast warning, but there seems to * be no way around it with current GnuTLS. Do NOT try to "fix" the situation! */ gnutls_transport_set_ptr(sessArray[i], (gnutls_transport_ptr_t)sockArray[i]); if (handshakeOnly) { int flags = fcntl(sockArray[i], F_GETFL, 0); if (flags != -1) { fcntl(sockArray[i], F_SETFL, flags | O_NONBLOCK); } } /* Perform the TLS handshake */ r = gnutls_handshake(sessArray[i]); if (r < 0) { if (handshakeOnly) { int allow = 0; switch (r) { case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: #ifdef GNUTLS_E_PREMATURE_TERMINATION case GNUTLS_E_PREMATURE_TERMINATION: #endif #ifdef GNUTLS_E_FATAL_ALERT_RECEIVED case GNUTLS_E_FATAL_ALERT_RECEIVED: #endif #ifdef GNUTLS_E_UNEXPECTED_PACKET_LENGTH case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: #endif #ifdef GNUTLS_E_PUSH_ERROR case GNUTLS_E_PUSH_ERROR: #endif #ifdef GNUTLS_E_PULL_ERROR case GNUTLS_E_PULL_ERROR: #endif #ifdef GNUTLS_E_HANDSHAKE_FAILED case GNUTLS_E_HANDSHAKE_FAILED: #endif allow = 1; break; default: break; } if (!allow) { fprintf(stderr, "TLS Handshake failed\n"); gnutls_perror(r); exit(1); } if (verbose && r != GNUTLS_E_AGAIN && r != GNUTLS_E_INTERRUPTED) { fprintf(stderr, "TLS handshake ended early: %s\n", gnutls_strerror(r)); } } else { fprintf(stderr, "TLS Handshake failed\n"); gnutls_perror(r); exit(1); } } if (handshakeOnly) { gnutls_deinit(sessArray[i]); sessArray[i] = NULL; if (sockArray[i] != -1) { close(sockArray[i]); } sockArray[i] = -1; return; } if (r < 0) { fprintf(stderr, "TLS Handshake failed\n"); gnutls_perror(r); exit(1); } } #pragma GCC diagnostic pop static int sendTLS(int i, char *buf, size_t lenBuf) { int lenSent; int r; lenSent = 0; while (lenSent != lenBuf) { r = gnutls_record_send(sessArray[i], buf + lenSent, lenBuf - lenSent); if (r < 0) break; lenSent += r; } return lenSent; } static void closeTLSSess(int i) { if (sessArray == NULL || sessArray[i] == NULL) { return; } gnutls_bye(sessArray[i], GNUTLS_SHUT_RDWR); gnutls_deinit(sessArray[i]); sessArray[i] = NULL; } #else /* NO TLS available */ static void initTLS(void) {} static void exitTLS(void) {} static void initTLSSess(int __attribute__((unused)) i) {} static int sendTLS(int __attribute__((unused)) i, char __attribute__((unused)) * buf, size_t __attribute__((unused)) lenBuf) { return 0; } static void closeTLSSess(int __attribute__((unused)) i) {} static void initDTLSSess(void) {} static int sendDTLS(char *buf, size_t lenBuf) {} static void closeDTLSSess(void) {} #endif static void setTargetPorts(const char *const port_arg) { int i = 0; char *saveptr; char *ports = strdup(port_arg); char *port = strtok_r(ports, ":", &saveptr); while (port != NULL) { if (i == sizeof(targetPort) / sizeof(int)) { fprintf(stderr, "too many ports specified, max %d\n", (int)(sizeof(targetPort) / sizeof(int))); exit(1); } targetPort[i] = atoi(port); i++; port = strtok_r(NULL, ":", &saveptr); } free(ports); } /* Run the test. * rgerhards, 2009-04-03 */ int main(int argc, char *argv[]) { int ret = 0; int opt; struct sigaction sigAct; struct rlimit maxFiles; static char buf[1024]; struct rlimit limit; int os_max_fds; if (getrlimit(RLIMIT_NOFILE, &limit) != 0) { perror("Failed to get RLIMIT_NOFILE"); exit(1); } os_max_fds = limit.rlim_cur; // Soft limit srand(time(NULL)); /* seed is good enough for our needs */ /* on Solaris, we do not HAVE MSG_NOSIGNAL, so for this reason * we block SIGPIPE (not an issue for this program) */ memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sigAct, NULL); setvbuf(stdout, buf, _IONBF, 48); while ((opt = getopt(argc, argv, "a:ABb:c:C:d:DeE:f:F:h:i:I:j:k:l:L:m:M:n:o:OP:p:rR:" "sS:t:T:u:vW:w:x:XyYz:Z:H")) != -1) { switch (opt) { case 'b': batchsize = atoll(optarg); break; case 't': targetIP = optarg; break; case 'p': setTargetPorts(optarg); break; case 'n': numTargetPorts = atoi(optarg); break; case 'c': numConnections = atoi(optarg); if (numConnections < 0) { numConnections *= -1; softLimitConnections = 1; } break; case 'C': numFileIterations = atoi(optarg); break; case 'm': numMsgsToSend = atoi(optarg); break; case 'i': msgNum = atoi(optarg); break; case 'P': msgPRI = optarg; break; case 'j': jsonCookie = optarg; break; case 'd': extraDataLen = atoi(optarg); if (extraDataLen > MAX_EXTRADATA_LEN) { fprintf(stderr, "-d max is %d!\n", MAX_EXTRADATA_LEN); exit(1); } break; case 'D': bRandConnDrop = 1; break; case 'l': dbRandConnDrop = atof(optarg); printf("RandConnDrop Level: '%lf' \n", dbRandConnDrop); break; case 'r': bRandomizeExtraData = 1; break; case 'f': dynFileIDs = atoi(optarg); break; case 'F': frameDelim = atoi(optarg); break; case 'h': hostname = optarg; break; case 'L': tlsLogLevel = atoi(optarg); break; case 'M': MsgToSend = optarg; break; case 'I': dataFile = optarg; /* in this mode, we do not know the num messages to send, so * we set a (high) number to keep the code happy. */ numMsgsToSend = 1000000; break; case 's': bSilent = 1; break; case 'B': bBinaryFile = 1; break; case 'R': numRuns = atoi(optarg); break; case 'S': sleepBetweenRuns = atoi(optarg); break; case 'X': bStatsRecords = 1; break; case 'e': bCSVoutput = 1; break; case 'T': if (!strcmp(optarg, "udp")) { transport = TP_UDP; } else if (!strcmp(optarg, "tcp")) { transport = TP_TCP; } else if (!strcmp(optarg, "tls")) { #if defined(ENABLE_OPENSSL) transport = TP_TLS; #elif defined(ENABLE_GNUTLS) transport = TP_TLS; #else fprintf(stderr, "compiled without gnutls/openssl TLS support: " "\"-Ttls\" not supported!\n"); exit(1); #endif } else if (!strcmp(optarg, "relp-plain")) { #if defined(ENABLE_RELP) transport = TP_RELP_PLAIN; #else fprintf(stderr, "compiled without RELP support: " "\"-Trelp-plain\" not supported!\n" "(add --enable-relp to ./configure options " "if desired)\n"); exit(1); #endif } else if (!strcmp(optarg, "relp-tls")) { #if defined(ENABLE_RELP) transport = TP_RELP_TLS; #else fprintf(stderr, "compiled without RELP support: " "\"-Trelp-tls\" not supported!\n" "(add --enable-relp to ./configure options " "if desired)\n"); exit(1); #endif } else if (!strcmp(optarg, "dtls")) { #if defined(ENABLE_OPENSSL) transport = TP_DTLS; #else fprintf(stderr, "compiled without openssl TLS support: " "\"-Tdtls\" not supported!\n"); exit(1); #endif } else { fprintf(stderr, "unknown transport '%s'\n", optarg); exit(1); } break; case 'a': relpAuthMode = optarg; break; case 'A': abortOnSendFail = 0; break; case 'E': relpPermittedPeer = optarg; break; case 'u': #if defined(HAVE_RELPENGINESETTLSLIBBYNAME) relpTlsLib = optarg; #endif break; case 'W': waittime = atoi(optarg); break; case 'Y': runMultithreaded = 1; break; case 'y': useRFC5424Format = 1; break; case 'x': tlsCAFile = optarg; break; case 'z': tlsKeyFile = optarg; break; case 'Z': tlsCertFile = optarg; break; case 'o': nThreadsConnOpen = atoi(optarg); break; case 'O': octateCountFramed = 1; break; case 'v': verbose = 1; break; case 'k': customConfig = optarg; break; case 'w': portFile = optarg; break; case 'H': handshakeOnly = true; break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit(1); break; } } const char *const ci_env = getenv("CI"); if (ci_env != NULL && !strcmp(ci_env, "true")) { bSilent = 1; /* auto-apply silent option during CI runs */ } if (numConnections >= (os_max_fds - 20)) { fprintf(stderr, "We are asked to use %d connections, but the OS permits only %d " "open file descriptors.\n", numConnections, os_max_fds); if (softLimitConnections) { numConnections = os_max_fds - 20; fprintf(stderr, "We reduced the actual number of connections to %d. " "This leaves some room for opening files.\n", numConnections); } else { fprintf(stderr, "Connection count is hard requirement, so we " "error-terminate\n"); exit(1); } } if (handshakeOnly && transport != TP_TLS) { fprintf(stderr, "-H requires TLS transport (-Ttls)\n"); exit(1); } if (handshakeOnly && portFile != NULL) { fprintf(stderr, "-H cannot be combined with -w\n"); exit(1); } if (portFile != NULL && numConnections != 1) { fprintf(stderr, "-w requires exactly one connection\n"); exit(1); } if (portFile != NULL && (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS)) { fprintf(stderr, "-w not supported with RELP\n"); exit(1); } if (tlsCAFile != NULL && transport != TP_RELP_TLS) { #if !defined(ENABLE_OPENSSL) fprintf(stderr, "-x CAFile not supported in GnuTLS mode - ignored.\n" "Note: we do NOT VERIFY the remote peer when compiled for GnuTLS.\n" "When compiled for OpenSSL, we do.\n"); #endif } if (bStatsRecords && waittime) { fprintf(stderr, "warning: generating performance stats and using a waittime " "is somewhat contradictory!\n"); } if (!isatty(1) || bSilent) bShowProgress = 0; if (numConnections > 20) { /* if we use many (whatever this means, 20 is randomly picked) * connections, we need to make sure we have a high enough * limit. -- rgerhards, 2010-03-25 */ maxFiles.rlim_cur = numConnections + 20; maxFiles.rlim_max = numConnections + 20; if (setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { perror("setrlimit to increase file handles failed"); fprintf(stderr, "could not set sufficiently large number of " "open files for required connection count!\n"); if (!softLimitConnections) { exit(1); } } } if (dataFile != NULL) { if ((dataFP = fopen(dataFile, "r")) == NULL) { perror(dataFile); exit(1); } } if (tlsKeyFile != NULL || tlsCertFile != NULL) { if (transport != TP_TLS && transport != TP_DTLS && transport != TP_RELP_TLS) { printf( "error: TLS certificates were specified, but TLS is NOT enabled: " "To enable TLS use parameter -Ttls\n"); exit(1); } } if (transport == TP_TLS) { if (tlsKeyFile == NULL || tlsCertFile == NULL) { printf( "error: transport TLS is specified (-Ttls), -z and -Z must also " "be specified\n"); exit(1); } /* Create main CTX Object. Use SSLv23_method for < Openssl 1.1.0 and TLS_method for newer versions! */ #if defined(ENABLE_OPENSSL) #if OPENSSL_VERSION_NUMBER < 0x10100000L initTLS(SSLv23_method()); #else initTLS(TLS_method()); #endif #else initTLS(); #endif } else if (transport == TP_DTLS) { if (tlsKeyFile == NULL || tlsCertFile == NULL) { printf( "error: transport DTLS is specified (-Tdtls), -z and -Z must also " "be specified\n"); exit(1); } #if defined(ENABLE_OPENSSL) initTLS(DTLS_client_method()); #else printf("error: transport DTLS is specified (-Tdtls) but not supported in GnuTLS driver\n"); exit(1); #endif } else if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) { #ifdef ENABLE_RELP initRELP_PLAIN(); #endif } if (openConnections() != 0) { printf("error opening connections\n"); exit(1); } if (portFile != NULL) { int portSock; struct sockaddr_in sin; socklen_t slen = sizeof(sin); portSock = (transport == TP_UDP) ? udpsockout : sockArray[0]; if (getsockname(portSock, (struct sockaddr *)&sin, &slen) != 0) { perror("getsockname()"); exit(1); } FILE *pf = fopen(portFile, "w"); if (pf == NULL) { perror(portFile); exit(1); } if (fprintf(pf, "%u\n", ntohs(sin.sin_port)) < 0) { perror("fprintf to port file"); exit(1); } fclose(pf); } if (!handshakeOnly) { if (runTests() != 0) { printf("error running tests\n"); exit(1); } } closeConnections(); /* this is important so that we do not finish too early! */ #ifdef ENABLE_RELP if (transport == TP_RELP_PLAIN || transport == TP_RELP_TLS) { CHKRELP(relpEngineDestruct(&pRelpEngine)); } #endif if (nConnDrops > 0 && !bSilent) printf("-D option initiated %ld connection closures\n", nConnDrops); if (!bSilent) printf("End of tcpflood Run\n"); if (transport == TP_TLS) { exitTLS(); } exit(ret); } rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_servercert_gtls_clientanon.sh0000644000000000000000000000013015035412264025157 xustar0029 mtime=1752569012.41564652 29 atime=1764931168.41975877 30 ctime=1764935935.038758062 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_servercert_gtls_clientanon.sh0000775000175000017500000000353115035412264024632 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" ) # Note: no TLS for the listener, this is for tcpflood! module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="gtls" StreamDriverMode="1" StreamDriverAuthMode="x509/certvalid" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmpstrucdata-invalid-vg.sh0000644000000000000000000000013215035412264020773 xustar0030 mtime=1752569012.401743799 30 atime=1764931167.068737125 30 ctime=1764935934.654752183 rsyslog-8.2512.0/tests/mmpstrucdata-invalid-vg.sh0000775000175000017500000000311415035412264020441 0ustar00rgerrger#!/bin/bash # the goal here is to detect memleaks when structured data is not # correctly parsed. # This file is part of the rsyslog project, released under ASL 2.0 # rgerhards, 2015-04-30 . ${srcdir:=.}/diag.sh init #skip_platform "FreeBSD" "This test currently does not work on FreeBSD." export USE_VALGRIND="YES" # this test only makes sense with valgrind enabled # uncomment below to set special valgrind options #export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all" generate_conf add_conf ' module(load="../plugins/mmpstrucdata/.libs/mmpstrucdata") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="mmpstrucdata") if $msg contains "msgnum" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup # we use different message counts as this hopefully aids us # in finding which sample is leaking. For this, check the number # of blocks lost and see what set they match. tcpflood -m100 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM] invalid structured data!\"" tcpflood -m200 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM ] invalid structured data!\"" tcpflood -m300 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 MSGNUM= ] invalid structured data!\"" tcpflood -m400 -M "\"<161>1 2003-03-01T01:00:00.000Z mymachine.example.com tcpflood - tag [tcpflood@32473 = ] invalid structured data!\"" shutdown_when_empty wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/fac_authpriv.sh0000644000000000000000000000013215055602574016713 xustar0030 mtime=1756824956.027451414 30 atime=1764931161.407646366 30 ctime=1764935933.021727187 rsyslog-8.2512.0/tests/fac_authpriv.sh0000775000175000017500000000121615055602574016362 0ustar00rgerrger#!/bin/bash # This tests proper processing of the authpriv facility. # added 2014-09-16 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" authpriv.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m$NUMMESSAGES -P 81 shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/syslog_caller.c0000644000000000000000000000013115055605325016706 xustar0030 mtime=1756826325.658800819 30 atime=1764931157.545584392 29 ctime=1764935931.94271067 rsyslog-8.2512.0/tests/syslog_caller.c0000664000175000017500000001002215055605325016346 0ustar00rgerrger/* A testing tool that just emits a number of * messages to the system log socket. * * Options * * -s severity (0..7 accoding to syslog spec, r "rolling", default 6) * -m number of messages to generate (default 500) * -C liblognorm-stdlog channel description * -f message format to use * * Part of the testbench for rsyslog. * * Copyright 2010-2018 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * -or- * see COPYING.ASL20 in the source distribution * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #if defined(_AIX) #include #else #include #endif #include #include #include #ifdef HAVE_LIBLOGGING_STDLOG #include #endif static enum { FMT_NATIVE, FMT_SYSLOG_INJECT_L, FMT_SYSLOG_INJECT_C } fmt = FMT_NATIVE; static void usage(void) { fprintf(stderr, "usage: syslog_caller num-messages\n"); exit(1); } #ifdef HAVE_LIBLOGGING_STDLOG /* buffer must be large "enough" [4K?] */ static void genMsg(char *buf, const int sev, const int iRun) { switch (fmt) { case FMT_NATIVE: sprintf(buf, "test message nbr %d, severity=%d", iRun, sev); break; case FMT_SYSLOG_INJECT_L: sprintf(buf, "test\n"); break; case FMT_SYSLOG_INJECT_C: sprintf(buf, "test 1\t2"); break; } } #endif int main(int argc, char *argv[]) { int i; int opt; int bRollingSev = 0; int sev = 6; int msgs = 500; #ifdef HAVE_LIBLOGGING_STDLOG stdlog_channel_t logchan = NULL; const char *chandesc = "syslog:"; char msgbuf[4096]; #endif #ifdef HAVE_LIBLOGGING_STDLOG stdlog_init(STDLOG_USE_DFLT_OPTS); while ((opt = getopt(argc, argv, "m:s:C:f:")) != -1) { #else while ((opt = getopt(argc, argv, "m:s:")) != -1) { #endif switch (opt) { case 's': if (*optarg == 'r') { bRollingSev = 1; sev = 0; } else #ifdef HAVE_LIBLOGGING_STDLOG sev = atoi(optarg) % 8; #else sev = atoi(optarg); #endif break; case 'm': msgs = atoi(optarg); break; #ifdef HAVE_LIBLOGGING_STDLOG case 'C': chandesc = optarg; break; case 'f': if (!strcmp(optarg, "syslog_inject-l")) fmt = FMT_SYSLOG_INJECT_L; else if (!strcmp(optarg, "syslog_inject-c")) fmt = FMT_SYSLOG_INJECT_C; else usage(); break; #endif default: usage(); #ifdef HAVE_LIBLOGGING_STDLOG exit(1); #endif break; } } #ifdef HAVE_LIBLOGGING_STDLOG if ((logchan = stdlog_open(argv[0], 0, STDLOG_LOCAL1, chandesc)) == NULL) { fprintf(stderr, "error opening logchannel '%s': %s\n", chandesc, strerror(errno)); exit(1); } #endif for (i = 0; i < msgs; ++i) { #ifdef HAVE_LIBLOGGING_STDLOG genMsg(msgbuf, sev, i); if (stdlog_log(logchan, sev, "%s", msgbuf) != 0) { perror("error writing log record"); exit(1); } #else syslog(sev % 8, "test message nbr %d, severity=%d", i, sev % 8); #endif if (bRollingSev) #ifdef HAVE_LIBLOGGING_STDLOG sev = (sev + 1) % 8; #else sev++; #endif } return (0); } rsyslog-8.2512.0/tests/PaxHeaders/dynstats_ctr_reset.sh0000644000000000000000000000013115055602574020162 xustar0030 mtime=1756824956.027451414 30 atime=1764931167.085737398 29 ctime=1764935934.65975226 rsyslog-8.2512.0/tests/dynstats_ctr_reset.sh0000775000175000017500000000476315055602574017644 0ustar00rgerrger#!/bin/bash # added 2015-11-16 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo \[dynstats_ctr_reset.sh\]: test to ensure correctness of stats-ctr reset . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on") template(name="outfmt" type="string" string="%msg%\n") dyn_stats(name="msg_stats_resettable_on" resettable="on") dyn_stats(name="msg_stats_resettable_off" resettable="off") dyn_stats(name="msg_stats_resettable_default") set $.msg_prefix = field($msg, 32, 1); set $.x = dyn_inc("msg_stats_resettable_on", $.msg_prefix); set $.y = dyn_inc("msg_stats_resettable_off", $.msg_prefix); set $.z = dyn_inc("msg_stats_resettable_default", $.msg_prefix); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg_file $srcdir/testsuites/dynstats_input_1 injectmsg_file $srcdir/testsuites/dynstats_input_2 wait_queueempty sleep 1 injectmsg_file $srcdir/testsuites/dynstats_input_3 wait_queueempty sleep 1 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check "foo 006" custom_content_check 'bar=1' "${RSYSLOG_DYNNAME}.out.stats.log" first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1 first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_on.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2 . $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 . $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1 . $srcdir/diag.sh assert-first-column-sum-greater-than 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_off.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2 first_column_sum_check 's/.*foo=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*foo=' "${RSYSLOG_DYNNAME}.out.stats.log" 3 first_column_sum_check 's/.*bar=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*bar=' "${RSYSLOG_DYNNAME}.out.stats.log" 1 first_column_sum_check 's/.*baz=\([0-9]*\)/\1/g' 'msg_stats_resettable_default.*baz=' "${RSYSLOG_DYNNAME}.out.stats.log" 2 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_int2Hex.sh0000644000000000000000000000013215035412264017320 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.659618322 30 ctime=1764935932.534719732 rsyslog-8.2512.0/tests/rscript_int2Hex.sh0000775000175000017500000000142315035412264016767 0ustar00rgerrger#!/bin/bash # add 2017-02-09 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $!ip!v0 = int2hex(""); set $!ip!v1 = int2hex("0"); set $!ip!v2 = int2hex("1"); set $!ip!v4 = int2hex("375894"); set $!ip!v6 = int2hex("16"); set $!ip!v8 = int2hex("4294967295"); set $!ip!e1 = int2hex("a"); template(name="outfmt" type="string" string="%!ip%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown export EXPECTED='{ "v0": "0", "v1": "0", "v2": "1", "v4": "5bc56", "v6": "10", "v8": "ffffffff", "e1": "NAN" }' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_omudpspoof-bigmsg.sh0000644000000000000000000000013215055602574021260 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.350693562 30 ctime=1764935933.859740014 rsyslog-8.2512.0/tests/sndrcv_omudpspoof-bigmsg.sh0000775000175000017500000003420015055602574020726 0ustar00rgerrger#!/bin/bash # This runs sends and receives big messages via OMUDPSPOOF # added 2020-04-07 alorbach # This file is part of the rsyslog project, released under GPLv3 echo This test must be run as root [raw socket access required] if [ "$EUID" -ne 0 ]; then exit 77 # Not root, skip this test fi export TCPFLOOD_EXTRA_OPTS="-b1 -W1" export NUMMESSAGES=1 export MESSAGESIZE=65000 #65000 #32768 #16384 #export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" #export RSYSLOG_DEBUGLOG="log" . ${srcdir:=.}/diag.sh init # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_UDP="$(get_free_port)" add_conf ' module(load="../plugins/imudp/.libs/imudp") global ( maxMessageSize="64k" ) input(type="imudp" port="'$PORT_UDP'" ruleset="rsImudp") $template outfmt,"%msg%\n" ruleset(name="rsImudp") { action( name="UDPOUT" type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omudpspoof/.libs/omudpspoof") global ( maxMessageSize="64k" ) # this listener is for message generation by the test framework! input(type="imtcp" port="'$TCPFLOOD_PORT'" ruleset="rsImtcp") $template spoofaddr,"127.0.0.1" ruleset(name="rsImtcp") { action( name="MTUTEST" type="omudpspoof" Target="127.0.0.1" Port="'$PORT_UDP'" SourceTemplate="spoofaddr" mtu="1500") # for comparison only -> action(name="MTUTEST" type="omfwd" Target="127.0.0.1" Port="'$PORT_UDP'") } ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. # tcpflood -m$NUMMESSAGES -i1 -d 1024 tcpflood -m$NUMMESSAGES -i1 -d $MESSAGESIZE sleep 5 # make sure all data is received in input buffers # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # do the final check content_count_check "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ${NUMMESSAGES} rsyslog-8.2512.0/tests/PaxHeaders/failover-no-basic-vg.sh0000644000000000000000000000013215035412264020143 xustar0030 mtime=1752569012.389827181 30 atime=1764931163.713683349 30 ctime=1764935933.677737228 rsyslog-8.2512.0/tests/failover-no-basic-vg.sh0000775000175000017500000000160715035412264017616 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi echo =============================================================================== echo \[failover-no-basic.sh\]: basic test for failover functionality - no failover . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $RepeatedMsgReduction off # second action should never execute :msg, contains, "msgnum:" /dev/null $ActionExecOnlyWhenPreviousIsSuspended on & ./'"${RSYSLOG_OUT_LOG}"' ' startup_vg injectmsg 0 5000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg # now we need our custom logic to see if the result file is empty # (what it should be!) cmp $RSYSLOG_OUT_LOG /dev/null if [ $? -eq 1 ] then echo "ERROR, output file not empty" exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/queue-encryption-disk_keyfile-vg.sh0000644000000000000000000000013215035412264022617 xustar0030 mtime=1752569012.408695159 30 atime=1764931163.867685818 30 ctime=1764935933.721737902 rsyslog-8.2512.0/tests/queue-encryption-disk_keyfile-vg.sh0000775000175000017500000000207615035412264022273 0ustar00rgerrger#!/bin/bash # addd 2018-09-30 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omtesting/.libs/omtesting") global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.filename="mainq" queue.type="disk" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutshutdown="20000" queue.timeoutenqueue="300000" queue.lowwatermark="5000" queue.cry.provider="gcry" queue.cry.keyfile="'$RSYSLOG_DYNNAME.keyfile'" queue.saveonshutdown="on" ) template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") :omtesting:sleep 0 5000 :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' printf "1234567890123456" > $RSYSLOG_DYNNAME.keyfile startup_vg_noleak # we WILL leak due to the immediate shutdown injectmsg 0 1000 shutdown_immediate wait_shutdown_vg check_exit_vg echo INFO: queue files in ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool check_not_present "msgnum:0000" ${RSYSLOG_DYNNAME}.spool/mainq.0* exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-symlink.sh0000644000000000000000000000013215055602574017171 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.135722174 30 ctime=1764935934.385748066 rsyslog-8.2512.0/tests/imfile-symlink.sh0000775000175000017500000000501515055602574016641 0ustar00rgerrger#!/bin/bash # This test creates multiple symlinks (all watched by rsyslog via wildcard) # chained to target files via additional symlinks and checks that all files # are recorded with correct corresponding metadata (name of symlink # matching configuration). # This is part of the rsyslog testbench, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify export IMFILEINPUTFILES="10" export IMFILELASTINPUTLINES="3" export IMFILECHECKTIMEOUT="60" # generate input files first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). mkdir $RSYSLOG_DYNNAME.statefiles generate_conf add_conf ' # comment out if you need more debug info: global( debug.whitelist="on" debug.files=["imfile.c"]) module(load="../plugins/imfile/.libs/imfile" statefile.directory="'${RSYSLOG_DYNNAME}'.statefiles" mode="inotify" normalizePath="off") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input-symlink.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value=", filename: ") property(name="$!metadata!filename") constant(value=", fileoffset: ") property(name="$!metadata!fileoffset") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file="'${RSYSLOG_OUT_LOG}'" template="outfmt") ' ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input-symlink.log mkdir $RSYSLOG_DYNNAME.targets # Start rsyslog now before adding more files startup for i in $(seq 2 $IMFILEINPUTFILES); do printf '\ncreating %s\n' $RSYSLOG_DYNNAME.targets/$i.log ./inputfilegen -m 1 -i $((i-1)) > $RSYSLOG_DYNNAME.targets/$i.log ls -l $RSYSLOG_DYNNAME.targets/$i.log ln -sv $RSYSLOG_DYNNAME.targets/$i.log $RSYSLOG_DYNNAME.link.$i.log ln -sv $RSYSLOG_DYNNAME.link.$i.log $RSYSLOG_DYNNAME.input.$i.log printf '%s generated file %s\n' "$(tb_timestamp)" "$i" ls -l $RSYSLOG_DYNNAME.link.$i.log # wait until this file has been processed content_check_with_count "HEADER msgnum:000000" $i $IMFILECHECKTIMEOUT done ./inputfilegen -m $IMFILELASTINPUTLINES > $RSYSLOG_DYNNAME.input.$((IMFILEINPUTFILES + 1)).log ls -l $RSYSLOG_DYNNAME.input.* $RSYSLOG_DYNNAME.link.* $RSYSLOG_DYNNAME.targets # Content check with timeout content_check_with_count "input.11.log" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT shutdown_when_empty wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/json_var_case.sh0000644000000000000000000000013215035412264017045 xustar0030 mtime=1752569012.398764645 30 atime=1764931168.269756367 30 ctime=1764935934.995757403 rsyslog-8.2512.0/tests/json_var_case.sh0000775000175000017500000000273115035412264016517 0ustar00rgerrger#!/bin/bash # added 2015-11-24 by portant # This file is part of the rsyslog project, released under ASL 2.0 echo =========================================================================================== echo \[json_var_case.sh\]: test for JSON upper and lower case variables, and leading underscores . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(variables.casesensitive="on") module(load="../plugins/mmjsonparse/.libs/mmjsonparse") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # we must make sure the template contains references to the variables template(name="outfmt" type="string" string="abc:%$!abc% ABC:%$!ABC% aBc:%$!aBc% _abc:%$!_abc% _ABC:%$!_ABC% _aBc:%$!_aBc%\n" option.casesensitive="on") template(name="outfmt-all-json" type="string" string="%$!all-json%\n") action(type="mmjsonparse") set $!_aBc = "7"; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") if $!_aBc != "7" then action(type="omfile" file="./'"${RSYSLOG2_OUT_LOG}"'" template="outfmt-all-json") ' startup tcpflood -m 1 -M "\"<167>Nov 6 12:34:56 172.0.0.1 test: @cee: { \\\"abc\\\": \\\"1\\\", \\\"ABC\\\": \\\"2\\\", \\\"aBc\\\": \\\"3\\\", \\\"_abc\\\": \\\"4\\\", \\\"_ABC\\\": \\\"5\\\", \\\"_aBc\\\": \\\"6\\\" }\"" echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown # NOTE: conf file updates _aBc to "7" content_check "abc:1 ABC:2 aBc:3 _abc:4 _ABC:5 _aBc:7" exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-rename.sh0000644000000000000000000000013115055602574016751 xustar0030 mtime=1756824956.029451442 30 atime=1764931166.125722014 29 ctime=1764935934.38274802 rsyslog-8.2512.0/tests/imfile-rename.sh0000775000175000017500000000414315055602574016423 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . $srcdir/diag.sh check-inotify-only . ${srcdir:=.}/diag.sh init export TESTMESSAGES=10000 export RETRIES=50 export TESTMESSAGESFULL=19999 generate_conf add_conf ' $WorkDirectory '$RSYSLOG_DYNNAME'.spool /* Filter out busy debug output */ global( debug.whitelist="off" debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"] ) module( load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on" ) input(type="imfile" File="/does/not/exist/*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on" ) $template outfmt,"%msg:F,58:2%\n" if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) if $msg contains "imfile:" then action( type="omfile" file="'$RSYSLOG_DYNNAME.errmsgs'" ) ' # generate input file first. ./inputfilegen -m $TESTMESSAGES > $RSYSLOG_DYNNAME.input.1.log ls -l $RSYSLOG_DYNNAME.input* startup # sleep a little to give rsyslog a chance to begin processing wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGES $RETRIES # Move to another filename mv $RSYSLOG_DYNNAME.input.1.log rsyslog.input.2.log ./msleep 500 # Write into the renamed file echo 'testmessage1 testmessage2' >> rsyslog.input.2.log ./msleep 500 if grep "imfile: internal error? inotify provided watch descriptor" < "$RSYSLOG_DYNNAME.errmsgs" ; then echo "Error: inotify event from renamed file" exit 1 fi # generate some more input into moved file ./inputfilegen -m $TESTMESSAGES -i $TESTMESSAGES >> $RSYSLOG_DYNNAME.input.2.log ls -l $RSYSLOG_DYNNAME.input* echo ls ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool ./msleep 500 let msgcount="2* $TESTMESSAGES" wait_file_lines $RSYSLOG_OUT_LOG $msgcount $RETRIES shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! seq_check 0 $TESTMESSAGESFULL exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-retry-metadata.sh0000644000000000000000000000013215055603742021551 xustar0030 mtime=1756825570.302069124 30 atime=1764931164.929702844 30 ctime=1764935934.021742494 rsyslog-8.2512.0/tests/omhttp-batch-retry-metadata.sh0000775000175000017500000000427115055603742021224 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 port="$(get_free_port)" omhttp_start_server $port --fail-every 100 --fail-with 207 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="2048") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") # Echo message as-is for retry template(name="tpl_echo" type="string" string="%msg%\n") # Echo response as-is for retry template(name="tpl_response" type="string" string="{ \"message\": %msg%, \"response\": %$!omhttp!response% }\n") ruleset(name="ruleset_omhttp_retry") { #action(type="omfile" file="'$RSYSLOG_DYNNAME/omhttp.message.log'" template="tpl_echo") # log the response action(type="omfile" file="'$RSYSLOG_DYNNAME/omhttp.response.log'" template="tpl_response") action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl_echo" server="localhost" serverport="'$port'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="kafkarest" httpretrycodes=["207","500"] retry="on" retry.ruleset="ruleset_omhttp_retry" retry.addmetadata="on" # Auth usehttps="off" ) & stop } ruleset(name="ruleset_omhttp") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$port'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="kafkarest" httpretrycodes=["207", "500"] retry="on" retry.ruleset="ruleset_omhttp_retry" retry.addmetadata="on" # Auth usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $port my/endpoint kafkarest omhttp_stop_server seq_check cat -n ${RSYSLOG_DYNNAME}/omhttp.response.log omhttp_validate_metadata_response exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-x509valid.sh0000644000000000000000000000013215055603742020653 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.292676598 30 ctime=1764935933.556735376 rsyslog-8.2512.0/tests/imtcp-tls-ossl-x509valid.sh0000775000175000017500000000223715055603742020326 0ustar00rgerrger#!/bin/bash # added 2018-04-27 by alorbach # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/certvalid" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_unflatten_arg1_unsuitable-vg.sh0000644000000000000000000000013115055602574023564 xustar0030 mtime=1756824956.038451568 30 atime=1764931159.978623441 29 ctime=1764935932.60972088 rsyslog-8.2512.0/tests/rscript_unflatten_arg1_unsuitable-vg.sh0000775000175000017500000000013715055602574023235 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/rscript_unflatten_arg1_unsuitable.sh rsyslog-8.2512.0/tests/PaxHeaders/imhiredis-stream-consumerGroup-noack-vg.sh0000644000000000000000000000013215055602574024057 xustar0030 mtime=1756824956.030451456 30 atime=1764931161.067640912 30 ctime=1764935932.919725625 rsyslog-8.2512.0/tests/imhiredis-stream-consumerGroup-noack-vg.sh0000775000175000017500000000032515055602574023526 0ustar00rgerrger#!/usr/bin/env bash # added 2023-04-20 by Théo Bertin, released under ASL 2.0 ## Uncomment for debugging #export RS_REDIR=-d export USE_VALGRIND="YES" source ${srcdir:=.}/imhiredis-stream-consumerGroup-noack.sh rsyslog-8.2512.0/tests/PaxHeaders/rscript_script_error.sh0000644000000000000000000000013215035412264020514 xustar0030 mtime=1752569012.412667365 30 atime=1764931159.763619991 30 ctime=1764935932.553720023 rsyslog-8.2512.0/tests/rscript_script_error.sh0000775000175000017500000000173215035412264020166 0ustar00rgerrger#!/bin/bash # Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$!%\n") local4.* { set $!valid!serial = parse_time("2017-10-05T01:10:11Z"); set $!valid!error = script_error(); set $!invalid!serial = parse_time("not a date/time"); set $!invalid!error = script_error(); set $!valid2!serial = parse_time("2017-10-05T01:10:11Z"); set $!valid2!error = script_error(); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 shutdown_when_empty wait_shutdown # Our fixed and calculated expected results export EXPECTED='{ "valid": { "serial": 1507165811, "error": 0 }, "invalid": { "serial": 0, "error": 1 }, "valid2": { "serial": 1507165811, "error": 0 } }' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/suspend-omfwd-via-file.sh0000644000000000000000000000013115035412264020515 xustar0029 mtime=1752569012.41564652 30 atime=1764931163.785684503 30 ctime=1764935933.696737519 rsyslog-8.2512.0/tests/suspend-omfwd-via-file.sh0000775000175000017500000000306715035412264020173 0ustar00rgerrger#!/bin/bash # This tests the action suspension via a file # This file is part of the rsyslog project, released under ASL 2.0 # Written 2019-07-10 by Rainer Gerhards . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10000 #export NUMMESSAGES=100 #00 generate_conf add_conf ' /* Filter out busy debug output, comment out if needed */ global( debug.whitelist="on" debug.files=["ruleset.c", "../action.c", "omfwd.c"] ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" { action(name="forwarder" type="omfwd" template="outfmt" target="127.0.0.1" port="'$TCPFLOOD_PORT'" protocol="tcp" action.externalstate.file="'$RSYSLOG_DYNNAME'.STATE" action.resumeRetryCount="-1" action.resumeinterval="1") } ' ./minitcpsrv -t127.0.0.1 -p$TCPFLOOD_PORT -f $RSYSLOG_OUT_LOG & BGPROCESS=$! echo background minitcpsrv process id is $BGPROCESS startup injectmsg 0 5000 #injectmsg 0 5 printf '\n%s %s\n' "$(tb_timestamp)" \ 'checking that action becomes suspended via external state file' printf "%s" "SUSPENDED" > $RSYSLOG_DYNNAME.STATE ./msleep 2000 # ensure ResumeInterval expired (NOT sensitive to slow machines --> absolute time!) injectmsg 5000 1000 #injectmsg 5 5 printf '\n%s %s\n' "$(tb_timestamp)" \ 'checking that action becomes resumed again via external state file' ./msleep 2000 # ensure ResumeInterval expired (NOT sensitive to slow machines --> absolute time!) printf "%s" "READY" > $RSYSLOG_DYNNAME.STATE injectmsg 6000 4000 #export QUEUE_EMPTY_CHECK_FUNC=check_q_empty_log2 wait_queueempty seq_check shutdown_when_empty wait_shutdown exit_test rsyslog-8.2512.0/tests/PaxHeaders/mainq_actq_DA.sh0000644000000000000000000000013215035412264016712 xustar0030 mtime=1752569012.399757696 30 atime=1764931158.833605066 30 ctime=1764935932.301716165 rsyslog-8.2512.0/tests/mainq_actq_DA.sh0000775000175000017500000000145315035412264016364 0ustar00rgerrger#!/bin/bash # Test to check that mainq and actionq can be disk assisted without # any problems. This was created to reproduce a segfault issue: # https://github.com/rsyslog/rsyslog/issues/3681 # added 2019-06-03 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 # we just need a handful - we primarily test startup generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") main_queue(queue.fileName="main" queue.type="LinkedList") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt" queue.type="linkedList" queue.fileName="action") ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_omsnmpv1_udp.sh0000644000000000000000000000013215055602574020247 xustar0030 mtime=1756824956.039451582 30 atime=1764931160.111625575 30 ctime=1764935932.645721431 rsyslog-8.2512.0/tests/sndrcv_omsnmpv1_udp.sh0000775000175000017500000000220015055602574017710 0ustar00rgerrger#!/bin/bash # alorbach, 2019-11-27 # Required Packages # pip install pysnmp # # Ubuntu 18 Packages needed # apt install snmp libsnmp-dev snmp-mibs-downloader # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export TESTMESSAGES=10 generate_conf export PORT_SNMP="$(get_free_port)" # Start SNMP Trap Receiver snmp_start_trapreceiver ${PORT_SNMP} ${RSYSLOG_OUT_LOG} add_conf ' module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) module( load="../plugins/omsnmp/.libs/omsnmp" ) # set up the action template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omsnmp" name="name" server="127.0.0.1" port="'${PORT_SNMP}'" version="0" community="public" enterpriseOID="1.3.6.1.2.1.192.0.1" messageOID="1.3.6.1.2.1.192.1.2.1.11" TrapType="6" specificType="0" ) ' startup tcpflood -p$TCPFLOOD_PORT -m${TESTMESSAGES} netstat -l shutdown_when_empty wait_shutdown snmp_stop_trapreceiver content_count_check "msgnum:" ${TESTMESSAGES} exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp_maxsessions.sh0000644000000000000000000000013015055602574020166 xustar0029 mtime=1756824956.03145147 30 atime=1764931168.176754877 29 ctime=1764935934.96875699 rsyslog-8.2512.0/tests/imptcp_maxsessions.sh0000775000175000017500000000250715055602574017643 0ustar00rgerrger#!/bin/bash # Test imtcp with many dropping connections # added 2010-08-10 by Rgerhards # # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" export NUMMESSAGES=500 MAXSESSIONS=10 CONNECTIONS=20 EXPECTED_DROPS=$((CONNECTIONS - MAXSESSIONS)) EXPECTED_STR='too many tcp sessions - dropping incoming request' wait_too_many_sessions() { test "$(grep "$EXPECTED_STR" "$RSYSLOG_OUT_LOG" | wc -l)" = "$EXPECTED_DROPS" } export QUEUE_EMPTY_CHECK_FUNC=wait_too_many_sessions generate_conf add_conf ' $MaxMessageSize 10k module(load="../plugins/imptcp/.libs/imptcp" maxsessions="'$MAXSESSIONS'") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) $template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" $OMFileFlushInterval 2 $OMFileIOBufferSize 256k ' startup echo "INFO: RSYSLOG_OUT_LOG: $RSYSLOG_OUT_LOG" echo "About to run tcpflood" tcpflood -c$CONNECTIONS -m$NUMMESSAGES -r -d100 -P129 -A echo "-------> NOTE: CLOSED REMOTELY messages are expected and OK! <-------" echo "done run tcpflood" shutdown_when_empty wait_shutdown content_count_check "$EXPECTED_STR" $EXPECTED_DROPS echo "Got expected drops: $EXPECTED_DROPS, looks good!" exit_test rsyslog-8.2512.0/tests/PaxHeaders/diskqueue-fail.sh0000644000000000000000000000013215055602574017150 xustar0030 mtime=1756824956.027451414 30 atime=1764931159.162610347 30 ctime=1764935932.395717604 rsyslog-8.2512.0/tests/diskqueue-fail.sh0000775000175000017500000000151215055602574016616 0ustar00rgerrger#!/bin/bash # checks that nothing bad happens if a DA (disk) queue runs out # of configured disk space # addd 2017-02-07 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=100 generate_conf add_conf ' module( load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="queuefail") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") ruleset( name="queuefail" queue.type="Disk" queue.filename="fssailstocreate" queue.maxDiskSpace="4m" queue.maxfilesize="1m" queue.timeoutenqueue="300000" queue.lowwatermark="5000" ) { action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") } ' startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_numstr-str-vg.sh0000644000000000000000000000013215055602574022264 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.595617295 30 ctime=1764935932.518719487 rsyslog-8.2512.0/tests/rscript_compare_numstr-str-vg.sh0000775000175000017500000000020515055602574021730 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='"1"' export HIGHER_VAL='"abc"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/parsertest-parse-3164-buggyday.sh0000644000000000000000000000013215035412264021741 xustar0030 mtime=1752569012.406709056 30 atime=1764931158.978607394 30 ctime=1764935932.342716793 rsyslog-8.2512.0/tests/parsertest-parse-3164-buggyday.sh0000775000175000017500000000216215035412264021411 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp:::date-rfc3164-buggyday%,%hostname%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<38> Mar 7 19:06:53 example tag: testmessage (only date actually tested)\"" tcpflood -m1 -M "\"<38> Mar 17 19:06:53 example tag: testmessage (only date actually tested)\"" shutdown_when_empty wait_shutdown echo '38,auth,info,Mar 07 19:06:53,example,tag,tag:, testmessage (only date actually tested) 38,auth,info,Mar 17 19:06:53,example,tag,tag:, testmessage (only date actually tested)' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/diskqueue-multithread-es.sh0000644000000000000000000000013215071746523021165 xustar0030 mtime=1760021843.880421648 30 atime=1764931162.663666512 30 ctime=1764935933.371732544 rsyslog-8.2512.0/tests/diskqueue-multithread-es.sh0000775000175000017500000000401515071746523020634 0ustar00rgerrger#!/bin/bash # This test stresses the DA queue disk subsystem with multiple threads. # To do so, the in-memory queues are deliberately sized very small. # NOTE: depending on circumstances, this test frequently starts the # DAWorkerPool, which shuffles messages over from the main queue to # the DA queue. It terminates when we reach low water mark. This can # happen in our test. So the DA worker pool thread is, depending on # timing, started and shut down multiple times. This is not a problem # indication! # The pstats display is for manual review - it helps to see how many # messages actually went to the DA queue. # Copyright (C) 2019-10-28 by Rainer Gerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export ES_PORT=19200 export NUMMESSAGES=25000 export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check ensure_elasticsearch_ready generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME'.spool") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") main_queue(queue.size="2000") module(load="../plugins/impstats/.libs/impstats" log.syslog="off" log.file="'$RSYSLOG_DYNNAME'.pstats" interval="1") module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") :msg, contains, "msgnum:" { action(type="omelasticsearch" name="act-es" template="tpl" server="127.0.0.1" serverport="'$ES_PORT'" searchIndex="rsyslog_testbench" bulkmode="on" queue.lowwatermark="250" queue.highwatermark="1500" queue.type="linkedList" queue.size="2000" queue.dequeueBatchSize="64" queue.workerThreads="4" queue.fileName="actq" queue.workerThreadMinimumMessages="64") } ' startup tcpflood -m$NUMMESSAGES # use tcpflood to get better async processing than injectmsg! shutdown_when_empty wait_shutdown echo FOR MANUAL REVIEW: pstats tail $RSYSLOG_DYNNAME.pstats | grep maxqsize es_getdata $NUMMESSAGES $ES_PORT seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-endmsg.regex.crio.rulebase0000644000000000000000000000013215035412264022205 xustar0030 mtime=1752569012.391813284 30 atime=1764931165.943719097 30 ctime=1764935934.322747101 rsyslog-8.2512.0/tests/imfile-endmsg.regex.crio.rulebase0000664000175000017500000000116415035412264021653 0ustar00rgerrgerversion=2 rule=:%{"name":"multilinecrio", "type":"repeat", "parser":[ {"type":"word", "name":"time"}, {"type":"literal", "text":" "}, {"type":"word", "name":"stream"}, {"type":"literal", "text":" "}, {"type":"word", "name":"partial"}, {"type":"literal", "text":" "}, {"type":"char-sep", "name":"log", "extradata":"\n"} ], "while":[ {"type":"literal", "text":"\n"}, ] }% rsyslog-8.2512.0/tests/PaxHeaders/allowed-sender-tcp-hostname-ok.sh0000644000000000000000000000013215035412264022145 xustar0030 mtime=1752569012.384861924 30 atime=1764931162.841669366 30 ctime=1764935933.422733325 rsyslog-8.2512.0/tests/allowed-sender-tcp-hostname-ok.sh0000775000175000017500000000136115035412264021615 0ustar00rgerrger#!/bin/bash # check that we are able to receive messages from allowed sender # added 2019-08-15 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME export NUMMESSAGES=5 # it's just important that we get any messages at all generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $AllowedSender TCP,*'$RS_HOSTNAME'* template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/cfg4.testin0000644000000000000000000000013215035412264015750 xustar0030 mtime=1752569012.385854976 30 atime=1764931158.776604151 30 ctime=1764935932.284715905 rsyslog-8.2512.0/tests/cfg4.testin0000664000175000017500000000216015035412264015413 0ustar00rgerrger# This is more or less the sample config, but without imklog being # active. imklog must not always be present and as such may spoil # our testing result. The core point at this test is that a valid # config file should not lead to any error messages. # It may be a good idea to update this file from time to time, so that # it contains a reasonable complex config sample. # if you experience problems, check # https://www.rsyslog.com/troubleshoot for assistance # rsyslog v3: load input modules # If you do not load inputs, nothing happens! # You may need to set the module load path if modules are not found. # ######### Receiving Messages from Remote Hosts ########## # TCP Syslog Server: # provides TCP syslog reception and GSS-API (if compiled to support it) #$ModLoad imtcp.so # load module #$InputTCPServerRun 514 # start up TCP listener at port 514 # UDP Syslog Server: $ModLoad imudp.so # provides UDP syslog reception $ModLoad omoracle.so $UDPServerRun 514 # start a UDP syslog server at standard port 514 $IncludeConfig /home/munoz/logging/rsyslog/20*conf $IncludeConfig /home/munoz/logging/rsyslog/30*conf #*.* ~ rsyslog-8.2512.0/tests/PaxHeaders/imrelp-tls-cfgcmd.sh0000644000000000000000000000013215114522477017550 xustar0030 mtime=1764926783.043632054 30 atime=1764926784.240661436 30 ctime=1764935933.829739555 rsyslog-8.2512.0/tests/imrelp-tls-cfgcmd.sh0000775000175000017500000000406615114522477017225 0ustar00rgerrger#!/bin/bash # addd 2019-11-14 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init require_relpEngineSetTLSLibByName echo This test seems to have problems with a tcpflood segfault on some platforms, thus skipping echo see https://github.com/rsyslog/rsyslog/issues/6267 skip_test export NUMMESSAGES=1000 export RSYSLOG_DEBUG="debug nologfuncflow noprintmutexaction nostdout" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf add_conf ' module( load="../plugins/imrelp/.libs/imrelp" tls.tlslib="openssl") input(type="imrelp" port="'$TCPFLOOD_PORT'" tls="on" tls.cacert="'$srcdir'/tls-certs/ca.pem" tls.mycert="'$srcdir'/tls-certs/cert.pem" tls.myprivkey="'$srcdir'/tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog" tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2 CipherString=ECDHE-RSA-AES256-GCM-SHA384 Protocol=ALL,-SSLv2,-SSLv3,-TLSv1,-TLSv1.2,-TLSv1.3 MinProtocol=TLSv1.2 MaxProtocol=TLSv1.2") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup export TCPFLOOD_EXTRA_OPTS='-k "Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2 CipherString=DHE-RSA-AES256-SHA Protocol=ALL,-SSLv2,-SSLv3,-TLSv1.1,-TLSv1.2,-TLSv1.3 MinProtocol=TLSv1.1 MaxProtocol=TLSv1.1"' tcpflood --check-only -u "openssl" -Trelp-tls -acertvalid -p$TCPFLOOD_PORT -m$NUMMESSAGES -x "$srcdir/tls-certs/ca.pem" -z "$srcdir/tls-certs/key.pem" -Z "$srcdir/tls-certs/cert.pem" -Ersyslog 2> ${RSYSLOG_DYNNAME}.tcpflood shutdown_when_empty wait_shutdown content_check --check-only "relpTcpTLSSetPrio_gtls" ${RSYSLOG_DEBUGLOG} ret=$? if [ $ret == 0 ]; then echo "SKIP: LIBRELP was build without OPENSSL Support" skip_test fi content_check --check-only "OpenSSL Version too old" ${RSYSLOG_DEBUGLOG} ret=$? if [ $ret == 0 ]; then echo "SKIP: OpenSSL Version too old" skip_test else # Check for a failed session - possible ecodes are 10031 and 10040 content_check "librelp: generic error: ecode" $RSYSLOG_DEBUGLOG fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-json.sh0000644000000000000000000000013215035412264017013 xustar0030 mtime=1752569012.416639571 30 atime=1764931161.323645019 30 ctime=1764935932.996726804 rsyslog-8.2512.0/tests/template-json.sh0000775000175000017500000000153315035412264016464 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' set $!backslash = "a \\ \"b\" c / d"; # '/' must not be escaped! template(name="json" type="list" option.json="on") { constant(value="{") constant(value="\"backslash\":\"") property(name="$!backslash") constant(value="\"}\n") } :msg, contains, "msgnum:" action(type="omfile" template="json" file=`echo $RSYSLOG_OUT_LOG`) ' startup injectmsg 0 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! printf '{"backslash":"a \\\\ \\"b\\" c / d"}\n' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid JSON generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/3.rstest0000644000000000000000000000013215035412264015305 xustar0030 mtime=1752569012.383868873 30 atime=1764931158.359597458 30 ctime=1764935932.169714145 rsyslog-8.2512.0/tests/3.rstest0000664000175000017500000000071015035412264014747 0ustar00rgerrger# a simple RainerScript test result: 0 in: strlen($msg & strlen('abc')) > 20 +30 + -40 then $$$ out: 00000000: push_msgvar msg[cstr] 00000001: push_const abc[cstr] 00000002: push_const 1[nbr] 00000003: func_call strlen 00000004: strconcat 00000005: push_const 1[nbr] 00000006: func_call strlen 00000007: push_const 20[nbr] 00000008: push_const 30[nbr] 00000009: add 00000010: push_const 40[nbr] 00000011: unary_minus 00000012: add 00000013: cmp_> $$$ rsyslog-8.2512.0/tests/PaxHeaders/privdropabortonidfail.sh0000644000000000000000000000013115055602574020642 xustar0030 mtime=1756824956.037451554 29 atime=1764931161.29064449 30 ctime=1764935932.985726636 rsyslog-8.2512.0/tests/privdropabortonidfail.sh0000775000175000017500000000207715055602574020320 0ustar00rgerrger#!/bin/bash # add 2021-10-12 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.debuglog" skip_platform "SunOS" "This test currently does not work on Solaris." export TESTBENCH_TESTUSER1="USER_${RSYSLOG_DYNNAME}_1" export TESTBENCH_TESTUSER2="USER_${RSYSLOG_DYNNAME}_2" generate_conf add_conf ' global( security.abortOnIDResolutionFail="off" ) template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action( type="omfile" template="outfmt" file="'${RSYSLOG_OUT_LOG}'" ) action( type="omfile" template="outfmt" file="'${RSYSLOG_DYNNAME}'.dummy.log" FileOwner="'${TESTBENCH_TESTUSER1}'" FileGroup="'${TESTBENCH_TESTUSER1}'" DirOwner="'${TESTBENCH_TESTUSER2}'" DirGroup="'${TESTBENCH_TESTUSER2}'" ) ' startup shutdown_when_empty wait_shutdown content_check --regex "ID for user '${TESTBENCH_TESTUSER1}' could not be found" content_check --regex "ID for user '${TESTBENCH_TESTUSER2}' could not be found" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omkafka.sh0000644000000000000000000000013215071746523015652 xustar0030 mtime=1760021843.902421995 30 atime=1764931166.752732061 30 ctime=1764935934.567750852 rsyslog-8.2512.0/tests/omkafka.sh0000775000175000017500000000677315071746523015336 0ustar00rgerrger#!/bin/bash # added 2017-05-03 by alorbach # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init test_status unreliable 'https://github.com/rsyslog/rsyslog/issues/3197' check_command_available kcat export KEEP_KAFKA_RUNNING="YES" export TESTMESSAGES=100000 export TESTMESSAGESFULL=$TESTMESSAGES export RANDTOPIC="$(printf '%08x' "$(( (RANDOM<<16) ^ RANDOM ))")" # Set EXTRA_EXITCHECK to dump kafka/zookeeperlogfiles on failure only. export EXTRA_EXITCHECK=dumpkafkalogs export EXTRA_EXIT=kafka echo Check and Stop previous instances of kafka/zookeeper download_kafka stop_zookeeper stop_kafka echo Create kafka/zookeeper instance and $RANDTOPIC topic start_zookeeper start_kafka create_kafka_topic $RANDTOPIC '.dep_wrk' '22181' # --- Create/Start omkafka sender config export RSYSLOG_DEBUGLOG="log" generate_conf add_conf ' # impstats in order to gain insight into error cases module(load="../plugins/impstats/.libs/impstats" log.file="'$RSYSLOG_DYNNAME.pstats'" interval="1" log.syslog="off") main_queue(queue.timeoutactioncompletion="60000" queue.timeoutshutdown="60000") $imdiagInjectDelayMode full module(load="../plugins/omkafka/.libs/omkafka") template(name="outfmt" type="string" string="%msg:F,58:2%\n") local4.* { action( name="kafka-fwd" type="omkafka" topic="'$RANDTOPIC'" broker="127.0.0.1:29092" template="outfmt" confParam=[ "compression.codec=none", "socket.timeout.ms=10000", "socket.keepalive.enable=true", "reconnect.backoff.jitter.ms=1000", "queue.buffering.max.messages=10000", "enable.auto.commit=true", "message.send.max.retries=1"] topicConfParam=["message.timeout.ms=10000"] partitions.auto="on" errorFile="'$RSYSLOG_OUT_LOG'-kafka_errors.log" closeTimeout="60000" resubmitOnFailure="on" keepFailedMessages="on" failedMsgFile="'$RSYSLOG_OUT_LOG'-failed-'$RANDTOPIC'.data" action.resumeInterval="1" action.resumeRetryCount="2" queue.saveonshutdown="on" ) action( type="omfile" file="'$RSYSLOG_OUT_LOG'") stop } action( type="omfile" file="'$RSYSLOG_DYNNAME.othermsg'") ' echo Starting sender instance [omkafka] startup echo Inject messages into rsyslog sender instance injectmsg 1 $TESTMESSAGES wait_file_lines $RSYSLOG_OUT_LOG $TESTMESSAGESFULL 100 # experimental: wait until kcat receives everything timeoutend=100 timecounter=0 while [ $timecounter -lt $timeoutend ]; do (( timecounter++ )) kcat -b 127.0.0.1:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG count=$(wc -l < ${RSYSLOG_OUT_LOG}) if [ $count -eq $TESTMESSAGESFULL ]; then printf '**** wait-kafka-lines success, have %d lines ****\n\n' "$TESTMESSAGESFULL" break else if [ "x$timecounter" == "x$timeoutend" ]; then echo wait-kafka-lines failed, expected $TESTMESSAGESFULL got $count shutdown_when_empty wait_shutdown error_exit 1 else echo wait-file-lines not yet there, currently $count lines printf 'pstats data:\n' cat $RSYSLOG_DYNNAME.pstats printf '\n' $TESTTOOL_DIR/msleep 1000 fi fi done unset count #end experimental echo Stopping sender instance [omkafka] shutdown_when_empty wait_shutdown #kcat -b 127.0.0.1:29092 -e -C -o beginning -t $RANDTOPIC -f '%s' > $RSYSLOG_OUT_LOG #kcat -b 127.0.0.1:29092 -e -C -o beginning -t $RANDTOPIC -f '%p@%o:%k:%s' > $RSYSLOG_OUT_LOG.extra # Delete topic to remove old traces before delete_kafka_topic $RANDTOPIC '.dep_wrk' '22181' # Dump Kafka log | uncomment if needed # dump_kafka_serverlog kafka_check_broken_broker $RSYSLOG_DYNNAME.othermsg seq_check 1 $TESTMESSAGESFULL -d exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-ossl-basic-brokenhandshake-vg.sh0000644000000000000000000000013215055603742023746 xustar0030 mtime=1756825570.301069108 30 atime=1764931163.324677111 30 ctime=1764935933.565735514 rsyslog-8.2512.0/tests/imtcp-tls-ossl-basic-brokenhandshake-vg.sh0000775000175000017500000000270015055603742023414 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n' printf 'a valgrind-internal bug. So we need to skip it.\n' exit 77 fi . ${srcdir:=.}/diag.sh init export USE_VALGRIND="YES" export NUMMESSAGES=1 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action( type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' # Begin actual testcase | send one msg without TLS to force a handshake failure, send second msg with TLS to make the test PASS startup tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem wait_file_lines shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp_veryLargeOctateCountedMessages.sh0000644000000000000000000000013115035412264023716 xustar0029 mtime=1752569012.39578549 30 atime=1764931168.192755133 30 ctime=1764935934.973757066 rsyslog-8.2512.0/tests/imptcp_veryLargeOctateCountedMessages.sh0000775000175000017500000000157615035412264023377 0ustar00rgerrger#!/bin/bash # Test imptcp with poller not processing any messages # test imptcp with very large messages while poller driven processing is disabled # added 2015-10-17 by singh.janmejay # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=20000 generate_conf add_conf '$MaxMessageSize 10k template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") module(load="../plugins/imptcp/.libs/imptcp" threads="32" processOnPoller="off") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if (prifilt("local0.*")) then { action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") } ' export RS_REDIR="2>/dev/null" startup tcpflood -c1 -m$NUMMESSAGES -r -d100000 -P129 -O wait_file_lines shutdown_when_empty wait_shutdown seq_check 0 $((NUMMESSAGES - 1)) -E -T exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_backticks_empty_envvar.sh0000644000000000000000000000013115062756615022546 xustar0030 mtime=1758190989.238641644 30 atime=1764931159.798620552 29 ctime=1764935932.56272016 rsyslog-8.2512.0/tests/rscript_backticks_empty_envvar.sh0000775000175000017500000000057015062756615022220 0ustar00rgerrger#!/bin/bash # added 2018-11-02 by rgerhards # see also https://github.com/rsyslog/rsyslog/issues/3006 # released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' if `echo $DOES_NOT_EXIST` == "" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup shutdown_when_empty wait_shutdown check_exit content_check --regex "rsyslogd: .*start" exit_test rsyslog-8.2512.0/tests/PaxHeaders/proprepltest-nolimittag.sh0000644000000000000000000000013115035412264021140 xustar0030 mtime=1752569012.408695159 30 atime=1764931159.056608645 29 ctime=1764935932.36471713 rsyslog-8.2512.0/tests/proprepltest-nolimittag.sh0000775000175000017500000000211315035412264020605 0ustar00rgerrger#!/bin/bash # add 2018-06-27 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="+%syslogtag%+\n") :pri, contains, "167" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 TAG: Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 0 Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901 Rest of message...\"" tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 01234567890123456789012345678901-toolong Rest of message...\"" shutdown_when_empty wait_shutdown echo '+TAG:+ +0+ +01234567890123456789012345678901+ +01234567890123456789012345678901-toolong+' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdtls-sessionbreak.sh0000644000000000000000000000013215055603742020220 xustar0030 mtime=1756825570.301069108 30 atime=1764931164.409694508 30 ctime=1764935933.875740259 rsyslog-8.2512.0/tests/imdtls-sessionbreak.sh0000775000175000017500000000373315055603742017675 0ustar00rgerrger#!/bin/bash # added 2020-04-10 by alorbach, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 export USE_VALGRIND="yes" # TODO remote leak check skip and fix memory leaks caused by session break export RS_TESTBENCH_LEAK_CHECK=no export PORT_RCVR="$(get_free_port)" mkdir $RSYSLOG_DYNNAME.workdir generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir'/tls-certs/ca.pem" defaultNetstreamDriverCertFile="'$srcdir'/tls-certs/cert.pem" defaultNetstreamDriverKeyFile="'$srcdir'/tls-certs/key.pem" workDirectory="'$RSYSLOG_DYNNAME.workdir'" maxMessageSize="256k") main_queue(queue.type="Direct") $LocalHostName test $AbortOnUncleanConfig on $PreserveFQDN on module( load="../plugins/imdtls/.libs/imdtls" tls.AuthMode="x509/certvalid") input( type="imdtls" port="'$PORT_RCVR'" ruleset="spool" ) template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="spool" queue.type="direct") { if $msg contains "msgnum:" then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } } ' startup # How many tcpfloods we run at the same tiem for ((i=1;i<=10;i++)); do # How many times tcpflood runs in each threads ./tcpflood -Tdtls -p$PORT_RCVR -m$NUMMESSAGES -W1000 -d102400 -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem -s & tcpflood_pid=$! echo "started tcpflood instance $i (PID $tcpflood_pid)" # Give it time to actually connect ./msleep 1000; kill -9 $tcpflood_pid # >/dev/null 2>&1; echo "killed tcpflood instance $i (PID $tcpflood_pid)" done; wait_queueempty netstatresult=$(netstat --all --program 2>&1 | grep "ESTABLISHED" | grep $(cat $RSYSLOG_PIDBASE.pid) | grep $TCPFLOOD_PORT) openfd=$(ls -l "/proc/$(cat $RSYSLOG_PIDBASE$1.pid)/fd" | wc -l) shutdown_when_empty wait_shutdown if [[ "$netstatresult" == "" ]] then echo "OK!" else echo "STILL OPENED Connections: " echo $netstatresult echo "Open files at the end: " echo $openfd error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare-common.sh0000644000000000000000000000013215055602574020722 xustar0030 mtime=1756824956.037451554 30 atime=1764931159.640618017 30 ctime=1764935932.530719671 rsyslog-8.2512.0/tests/rscript_compare-common.sh0000775000175000017500000000300615055602574020370 0ustar00rgerrger#!/bin/bash # added by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!result") constant(value="\n") } set $!lower_nr = '$LOWER_VAL'; set $!higher_nr = '$HIGHER_VAL'; if $!lower_nr <= $!higher_nr then { set $!result = "<= RIGHT"; } else { set $!result = "<= WRONG"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") if $!lower_nr < $!higher_nr then { set $!result = "< RIGHT"; } else { set $!result = "< WRONG"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") if $!higher_nr >= $!lower_nr then { set $!result = ">= RIGHT"; } else { set $!result = ">= WRONG"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") if $!higher_nr > $!lower_nr then { set $!result = "> RIGHT"; } else { set $!result = "> WRONG"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") if $!higher_nr != $!lower_nr then { set $!result = "!= RIGHT"; } else { set $!result = "!= WRONG"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") if $!higher_nr == $!lower_nr then { set $!result = "== WRONG"; } else { set $!result = "== RIGHT"; } action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup shutdown_when_empty wait_shutdown content_check '<= RIGHT' content_check '>= RIGHT' content_check '!= RIGHT' content_check '== RIGHT' content_check '< RIGHT' content_check '> RIGHT' exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-batch-lokirest-retry.sh0000644000000000000000000000013215055602574021627 xustar0030 mtime=1756824956.035451526 30 atime=1764931164.888702187 30 ctime=1764935934.008742295 rsyslog-8.2512.0/tests/omhttp-batch-lokirest-retry.sh0000775000175000017500000000320015055602574021271 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Starting actual testbench . ${srcdir:=.}/diag.sh init export NUMMESSAGES=50000 omhttp_start_server 0 --fail-every 100 generate_conf add_conf ' module(load="../contrib/omhttp/.libs/omhttp") main_queue(queue.dequeueBatchSize="2048") template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") # Echo message as-is for retry template(name="tpl_echo" type="string" string="%msg%") ruleset(name="ruleset_omhttp_retry") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl_echo" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="lokirest" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } ruleset(name="ruleset_omhttp") { action( name="action_omhttp" type="omhttp" errorfile="'$RSYSLOG_DYNNAME/omhttp.error.log'" template="tpl" server="localhost" serverport="'$omhttp_server_lstnport'" restpath="my/endpoint" batch="on" batch.maxsize="100" batch.format="lokirest" retry="on" retry.ruleset="ruleset_omhttp_retry" # Auth usehttps="off" ) & stop } if $msg contains "msgnum:" then call ruleset_omhttp ' startup injectmsg shutdown_when_empty wait_shutdown omhttp_get_data $omhttp_server_lstnport my/endpoint lokirest omhttp_stop_server seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/imptcp_conndrop.sh0000644000000000000000000000013115055602574017435 xustar0029 mtime=1756824956.03145147 30 atime=1764931163.509680078 30 ctime=1764935933.619736341 rsyslog-8.2512.0/tests/imptcp_conndrop.sh0000775000175000017500000000165715055602574017116 0ustar00rgerrger#!/bin/bash # Test imptcp with many dropping connections # added 2010-08-10 by Rgerhards # # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=${NUMMESSAGES:-50000} # permit valgrind test to override value export TB_TEST_MAX_RUNTIME=${TB_TEST_MAX_RUNTIME:-700} # connection drops are very slow... generate_conf add_conf ' $MaxMessageSize 10k module(load="../plugins/imptcp/.libs/imptcp") input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'") $OMFileFlushInterval 2 $OMFileIOBufferSize 256k local0.* ?dynfile;outfmt ' startup # 100 byte messages to gain more practical data use tcpflood -c20 -m$NUMMESSAGES -r -d100 -P129 -D wait_file_lines shutdown_when_empty wait_shutdown export SEQ_CHECK_OPTIONS=-E seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/inputfilegen.c0000644000000000000000000000013215071746523016542 xustar0030 mtime=1760021843.891421822 30 atime=1764931157.456582963 30 ctime=1764935931.921710348 rsyslog-8.2512.0/tests/inputfilegen.c0000664000175000017500000001561415071746523016215 0ustar00rgerrger/* generate an input file suitable for use by the testbench * Copyright (C) 2018-2022 by Rainer Gerhards and Adiscon GmbH. * Copyright (C) 2016-2018 by Pascal Withopf and Adiscon GmbH. * * usage: ./inputfilegen num-lines > file * -m number of messages * -i start number of message * -d extra data to add (all 'X' after the msgnum) * -s size of file to generate * cannot be used together with -m * size may be slightly smaller in order to be able to write * the last complete line. * -M "message count file" - contains number of messages to be written * This is especially useful with -s, as the testbench otherwise does * not know how to do a seq_check. To keep things flexible, can also be * used with -m (this may aid testbench framework generalization). * -f outputfile * Permits to write data to file "outputfile" instead of stdout. Also * enables support for SIGHUP. * -S sleep time * ms to sleep between sending message bulks (bulks size given by -B) * -B number of messages in bulk * number of messages to send without sleeping as specified in -S. * IGNORED IF -S is not also given! * Part of rsyslog, licensed under ASL 2.0 */ #include "config.h" #include #include #include #include #include #include #if defined(_AIX) #include #else #include #endif #if defined(__FreeBSD__) #include #else #include #endif #if defined(HAVE_SYS_SELECT_H) #include #endif #define DEFMSGS 5 #define NOEXTRADATA -1 static volatile int bHadHUP = 0; static void hdlr_sighup(int sig) { fprintf(stderr, "inputfilegen: had hup, sig %d\n", sig); bHadHUP = 1; } static void sighup_enable(void) { struct sigaction sigAct; memset(&sigAct, 0, sizeof(sigAct)); sigemptyset(&sigAct.sa_mask); sigAct.sa_handler = hdlr_sighup; sigaction(SIGHUP, &sigAct, NULL); } void msleep(const int sleepTime) { struct timeval tvSelectTimeout; tvSelectTimeout.tv_sec = sleepTime / 1000; tvSelectTimeout.tv_usec = (sleepTime % 1000) * 1000; /* micro seconds */ if (select(0, NULL, NULL, NULL, &tvSelectTimeout) == -1) { if (errno != EINTR) { perror("select"); exit(1); } } } static FILE *open_output(const char *fn) { FILE *fh_output = fopen(fn, "w"); if (fh_output == NULL) { perror(fn); exit(1); } return fh_output; } int main(int argc, char *argv[]) { int c, i; long long nmsgs = DEFMSGS; long long nmsgstart = 0; int nfinishedidle = 0; int nchars = NOEXTRADATA; int errflg = 0; long long filesize = -1; char *extradata = NULL; const char *msgcntfile = NULL; const char *outputfile = "-"; FILE *fh_output; int sleep_ms = 0; /* How long to sleep between message writes */ int sleep_msgs = 0; /* messages to xmit between sleeps (if configured) */ int sleep_hubreopen_ms = 5; /* Wait until new file is being reopened, logrotate may need some time */ int ctr = 0; while ((c = getopt(argc, argv, "m:M:i:I:h:d:s:f:S:B:")) != -1) { switch (c) { case 'm': nmsgs = atoi(optarg); break; case 'M': msgcntfile = optarg; break; case 'i': nmsgstart = atoi(optarg); break; case 'I': nfinishedidle = atoi(optarg); break; case 'd': nchars = atoi(optarg); break; case 's': filesize = atoll(optarg); break; case 'S': sleep_ms = atoi(optarg); break; case 'B': sleep_msgs = atoi(optarg); break; case 'h': sleep_hubreopen_ms = atoi(optarg); break; case 'f': outputfile = optarg; sighup_enable(); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", optopt); errflg++; break; case '?': fprintf(stderr, "inputfilegen: Unrecognized option: -%c\n", optopt); errflg++; break; } } if (errflg) { fprintf(stderr, "invalid call\n"); exit(2); } if (filesize != -1) { const int linesize = (17 + nchars); /* 17 is std line size! */ nmsgs = filesize / linesize; fprintf(stderr, "inputfilegen: file size requested %lld, actual %lld with " "%lld lines, %lld bytes less\n", filesize, nmsgs * linesize, nmsgs, filesize - nmsgs * linesize); if (nmsgs > 100000000) { fprintf(stderr, "inputfilegen: number of lines exhaust 8-digit line numbers " "which are standard inside the testbench.\n" "Use -d switch to add extra data (e.g. -d111 for " "128 byte lines or -d47 for 64 byte lines)\n"); exit(1); } } if (msgcntfile != NULL) { FILE *const fh = fopen(msgcntfile, "w"); if (fh == NULL) { perror(msgcntfile); exit(1); } fprintf(fh, "%lld", nmsgs); fclose(fh); } if (strcmp(outputfile, "-")) { fh_output = open_output(outputfile); } else { fh_output = stdout; } if (nchars != NOEXTRADATA) { extradata = (char *)malloc(nchars + 1); memset(extradata, 'X', nchars); extradata[nchars] = '\0'; } for (i = nmsgstart; i < (nmsgs + nmsgstart); ++i) { if (sleep_ms > 0 && ctr++ >= sleep_msgs) { msleep(sleep_ms); ctr = 0; } if (bHadHUP) { fclose(fh_output); if (sleep_hubreopen_ms > 0) { /* Extra Sleep so logrotate or whatever can take place */ msleep(sleep_hubreopen_ms); } fh_output = open_output(outputfile); fprintf(stderr, "inputfilegen: %s reopened\n", outputfile); fprintf(stderr, "inputfilegen: current message number %d\n", i); bHadHUP = 0; } fprintf(fh_output, "msgnum:%8.8d:", i); if (nchars != NOEXTRADATA) { fprintf(fh_output, "%s", extradata); } fprintf(fh_output, "\n"); } if (nfinishedidle > 0) { /* Keep process open for nfinishedidle ms */ for (int x = 0; x < nfinishedidle; ++x) { if (bHadHUP) { /* Create empty file */ fh_output = open_output(outputfile); fclose(fh_output); fprintf(stderr, "inputfilegen: last message number was %d\n", i); bHadHUP = 0; } msleep(1); } } free(extradata); return 0; } rsyslog-8.2512.0/tests/PaxHeaders/include-obj-text-from-file-noexist.sh0000644000000000000000000000013215055602574022762 xustar0030 mtime=1756824956.032451484 30 atime=1764931159.205611036 30 ctime=1764935932.407717788 rsyslog-8.2512.0/tests/include-obj-text-from-file-noexist.sh0000775000175000017500000000063515055602574022435 0ustar00rgerrger#!/bin/bash # added 2018-01-22 by Rainer Gerhards; Released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' if $msg contains "msgnum:" then { include(text=`cat '${srcdir}'/testsuites/DOES-NOT-EXIST`) } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check --regex 'file could not be accessed for `cat .*/testsuites/DOES-NOT-EXIST' exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfwd-lb-1target-retry-test_skeleton-TargetFail.sh0000644000000000000000000000013115103346332025346 xustar0030 mtime=1762512090.634176013 29 atime=1764931160.50463188 30 ctime=1764935932.757723146 rsyslog-8.2512.0/tests/omfwd-lb-1target-retry-test_skeleton-TargetFail.sh0000775000175000017500000000265115103346332025022 0ustar00rgerrger#!/bin/bash # added 2024-02-19 by rgerhards. Released under ASL 2.0 # This test is not meant to be executed independetly. It just permits # to be called by different drivers with different io buffer sizes. # This in turn is needed to test some edge cases. . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test is currently not supported on solaris due to too-different timing" generate_conf export NUMMESSAGES=2000 # starting minitcpsrvr receivers so that we can obtain their port # numbers export MINITCPSRV_EXTRA_OPTS="-D900 -B2 -a -S5" start_minitcpsrvr $RSYSLOG_OUT_LOG 1 add_conf ' $MainMsgQueueTimeoutShutdown 10000 $MainMsgQueueDequeueBatchSize 100 global(allMessagesToStderr="on") template(name="outfmt" type="string" string="%msg:F,58:2%\n") module(load="builtin:omfwd" template="outfmt" iobuffer.maxSize="'$OMFWD_IOBUF_SIZE'") if $msg contains "msgnum:" then { action(type="omfwd" target=["127.0.0.1"] port="'$MINITCPSRVR_PORT1'" protocol="tcp" pool.resumeInterval="2" action.reportsuspensioncontinuation="on" action.resumeRetryCount="-1" action.resumeInterval="3") } ' echo Note: intentionally not started any local TCP receiver! # now do the usual run startup injectmsg shutdown_when_empty wait_shutdown # note: minitcpsrv shuts down automatically if the connection is closed! export SEQ_CHECK_OPTIONS=-d #permit 250 messages to be lost in this extreme test (-m 250) seq_check 0 $((NUMMESSAGES-1)) -m250 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_optimizer1.sh0000644000000000000000000000013215035412264020102 xustar0030 mtime=1752569012.411674314 30 atime=1764931161.995655798 30 ctime=1764935933.187729728 rsyslog-8.2512.0/tests/rscript_optimizer1.sh0000775000175000017500000000136515035412264017556 0ustar00rgerrger#!/bin/bash # added 2012-09-20 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_optimizer1.sh\]: testing rainerscript optimizer . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" field.delimiter="58" field.number="2") constant(value="\n") } /* tcpflood uses local4.=debug */ if prifilt("syslog.*") then stop # it actually does not matter what we do here else action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg 0 5000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmnormalize_processing_test3.sh0000644000000000000000000000013215035412264022141 xustar0030 mtime=1752569012.401743799 30 atime=1764931161.844653376 30 ctime=1764935933.145729085 rsyslog-8.2512.0/tests/mmnormalize_processing_test3.sh0000775000175000017500000000640615035412264021616 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init . $srcdir/faketime_common.sh export TZ=TEST+01:00 generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") module(load="../plugins/mmnormalize/.libs/mmnormalize") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="t_file_record" type="string" string="%timestamp:::date-rfc3339% %timestamp:::date-rfc3339% %hostname% %$!v_tag% %$!v_msg%\n") template(name="t_file_path" type="string" string="/sb/logs/incoming/%$year%/%$month%/%$day%/svc_%$!v_svc%/ret_%$!v_ret%/os_%$!v_os%/%fromhost-ip%/r_relay1/%$!v_file:::lowercase%.gz\n") template(name="t_fromhost-ip" type="string" string="%fromhost-ip%") template(name="t_analytics_msg_default" type="string" string="%$!v_analytics_prefix%%rawmsg-after-pri%") template(name="t_analytics_tag_prefix" type="string" string="%$!v_tag%: ") template(name="t_analytics_msg_normalized" type="string" string="%timereported% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%") template(name="t_analytics_msg_normalized_vc" type="string" string="%timereported:1:6% %$year% %timereported:8:$% %$!v_hostname% %$!v_analytics_prefix%%$!v_msg%") template(name="t_analytics" type="string" string="[][][%$!v_fromhost-ip%][%timestamp:::date-unixtimestamp%][] %$!v_analytics_msg%\n") ruleset(name="ruleset1") { action(type="mmnormalize" rulebase=`echo $srcdir/testsuites/mmnormalize_processing_tests.rulebase` useRawMsg="on") if ($!v_file == "") then { set $!v_file=$!v_tag; } action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_record") action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_file_path") set $!v_forward="PCI"; if ($!v_forward contains "PCI") then { if ($!v_fromhost-ip == "") then { set $!v_fromhost-ip=exec_template("t_fromhost-ip"); } if ($!v_msg == "" or $!v_tag == "") then { set $!v_analytics_msg=exec_template("t_analytics_msg_default"); } else { if ($!v_analytics_prefix == "") then { set $!v_analytics_prefix=exec_template("t_analytics_tag_prefix"); } if ($!v_hostname == "") then { # needed for vCenter logs with custom hostname set $!v_hostname=exec_template("t_fromhost-ip"); } if ($!v_exception == "VC") then { set $!v_analytics_msg=exec_template("t_analytics_msg_normalized_vc"); } else { set $!v_analytics_msg=exec_template("t_analytics_msg_normalized"); } } action(type="omfile" File=`echo $RSYSLOG_OUT_LOG` template="t_analytics") } } ' FAKETIME='2017-03-08 14:23:51' startup tcpflood -m1 -M "\"<182>Mar 8 14:23:51 host3 audispd: {SER3.local6 Y01 LNX [SRCH ALRT DASH REPT ANOM]} node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721):\"" shutdown_when_empty wait_shutdown echo '2017-03-08T14:23:51-01:00 2017-03-08T14:23:51-01:00 host3 audispd node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721): /sb/logs/incoming/2017/03/08/svc_SER3/ret_Y01/os_LNX/127.0.0.1/r_relay1/local6.gz [][][127.0.0.1][1488986631][] Mar 8 14:23:51 host3 audispd: node=host3.domain.com type=SYSCALL msg=audit(1488975831.267:230190721):' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/stop-msgvar.sh0000644000000000000000000000013015035412264016511 xustar0029 mtime=1752569012.41564652 29 atime=1764931160.46163119 30 ctime=1764935932.745722962 rsyslog-8.2512.0/tests/stop-msgvar.sh0000775000175000017500000000165015035412264016164 0ustar00rgerrger#!/bin/bash # Test for "stop" statement # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[stop-msgvar.sh\]: testing stop statement together with message variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$!nbr%\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if $msg contains "msgnum:" then { set $!nbr = field($msg, 58, 2); if cnum($!nbr) < 100 then stop /* check is intentionally more complex than needed! */ else if not (cnum($!nbr) > 999) then { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } } ' startup sleep 1 tcpflood -m2000 -i1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 100 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_le_var.sh0000644000000000000000000000013215035412264017247 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.378613813 30 ctime=1764935932.459718584 rsyslog-8.2512.0/tests/rscript_le_var.sh0000775000175000017500000000330715035412264016721 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_le.sh\]: testing rainerscript LE statement for two JSON variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } set $!var1 = "42"; set $!var2 = "42"; set $!var3 = "43"; if $!var1 <= $!var2 and $!var1 <= $!var3 then { if $!var3 <= $!var1 then { # Failure stop } else { unset $!var1; unset $!var2; unset $!var3; } } else { # Failure stop } set $.var1 = "42"; set $.var2 = "42"; set $.var3 = "43"; if $.var1 <= $.var2 and $.var1 <= $.var3 then { if $.var3 <= $.var1 then { # Failure stop } else { unset $.var1; unset $.var2; unset $.var3; } } else { # Failure stop } set $/var1 = "42"; set $/var2 = "42"; set $/var3 = "43"; if $/var1 <= $/var2 and $/var1 <= $/var3 then { if $/var3 <= $/var1 then { # Failure stop } else { unset $/var1; unset $/var2; unset $/var3; } } else { # Failure stop } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 1 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/asynwr_tinybuf.sh0000644000000000000000000000013215035412264017314 xustar0030 mtime=1752569012.384861924 30 atime=1764931165.482711708 30 ctime=1764935934.183744974 rsyslog-8.2512.0/tests/asynwr_tinybuf.sh0000775000175000017500000000260015035412264016761 0ustar00rgerrger#!/bin/bash # This tests async writing with a very small output buffer (1 byte!), # so it stresses output buffer handling. This also means operations will # be somewhat slow, so we send only a small amounts of data. # # added 2010-03-09 by Rgerhards # # This file is part of the rsyslog project, released under GPLv3 echo =============================================================================== echo TEST: \[asynwr_tinybuf.sh\]: test async file writing with 1-byte buffer . ${srcdir:=.}/diag.sh init export CI_SHUTDOWN_QUEUE_EMPTY_CHECKS=20 # this test is notoriously slow... generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp $MainMsgQueueTimeoutShutdown 10000 input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! $OMFileFlushOnTXEnd off $OMFileFlushInterval 2 $OMFileIOBufferSize 1 $OMFileAsyncWriting on :msg, contains, "msgnum:" ?dynfile;outfmt ' # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="log" startup # send 1000 messages, fairly enough to trigger problems tcpflood -m1000 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # shut down rsyslogd when done processing messages seq_check 0 999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/sparse_array_lookup_table-vg.sh0000644000000000000000000000013115035412264022075 xustar0029 mtime=1752569012.41564652 30 atime=1764931167.964751481 30 ctime=1764935934.908756071 rsyslog-8.2512.0/tests/sparse_array_lookup_table-vg.sh0000775000175000017500000000027715035412264021553 0ustar00rgerrger#!/bin/bash # added 2015-10-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/sparse_array_lookup_table.sh rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-basic-vg.sh0000644000000000000000000000013215035412264017636 xustar0030 mtime=1752569012.396778542 30 atime=1764931163.069673023 30 ctime=1764935933.490734366 rsyslog-8.2512.0/tests/imtcp-tls-basic-vg.sh0000775000175000017500000000011515035412264017302 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/imtcp-tls-basic.sh rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_tls_ossl_servercert_ossl_clientanon.sh0000644000000000000000000000013115035412264025167 xustar0029 mtime=1752569012.41564652 30 atime=1764931168.411758641 30 ctime=1764935935.035758015 rsyslog-8.2512.0/tests/sndrcv_tls_ossl_servercert_ossl_clientanon.sh0000775000175000017500000000353115035412264024641 0ustar00rgerrger#!/bin/bash # alorbach, 2019-01-16 # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1000 # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="ossl" StreamDriver.Mode="1" StreamDriver.AuthMode="anon" ) # then SENDER sends to this port (not tcpflood!) input( type="imtcp" port="'$PORT_RCVR'" ) $template outfmt,"%msg:F,58:2%\n" $template dynfile,"'$RSYSLOG_OUT_LOG'" # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" ) # Note: no TLS for the listener, this is for tcpflood! module( load="../plugins/imtcp/.libs/imtcp") input( type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) # set up the action action( type="omfwd" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" StreamDriver="ossl" StreamDriverMode="1" StreamDriverAuthMode="x509/certvalid" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. tcpflood -m$NUMMESSAGES -i1 wait_file_lines # shut down sender when everything is sent, receiver continues to run concurrently shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 $NUMMESSAGES exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-vg.sh0000644000000000000000000000013215055602574020571 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.636698147 30 ctime=1764935933.940741254 rsyslog-8.2512.0/tests/imhttp-post-payload-vg.sh0000775000175000017500000000023715055602574020242 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" #export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all" source ${srcdir:-.}/imhttp-post-payload.sh rsyslog-8.2512.0/tests/PaxHeaders/arrayqueue.sh0000644000000000000000000000013215055602574016423 xustar0030 mtime=1756824956.025451386 30 atime=1764931159.188610764 30 ctime=1764935932.402717711 rsyslog-8.2512.0/tests/arrayqueue.sh0000775000175000017500000000107015055602574016070 0ustar00rgerrger#!/bin/bash # Test for fixedArray queue mode # added 2009-05-20 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=40000 generate_conf add_conf ' # set spool locations and switch queue to disk-only mode $MainMsgQueueType FixedArray $template outfmt,"%msg:F,58:2%\n" template(name="dynfile" type="string" string=`echo $RSYSLOG_OUT_LOG`) # trick to use relative path names! :msg, contains, "msgnum:" ?dynfile;outfmt ' startup injectmsg shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/omod-if-array.sh0000644000000000000000000000013215035412264016677 xustar0030 mtime=1752569012.404722953 30 atime=1764931163.661682515 30 ctime=1764935933.663737014 rsyslog-8.2512.0/tests/omod-if-array.sh0000775000175000017500000000160015035412264016343 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="outfmt" type="string" string="%PRI%%timestamp%%hostname%%programname%%syslogtag%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -M "\"<167>Mar 6 16:57:54 172.20.245.8 %PIX-7-710005: UDP request discarded from SERVER1/2741 to test_app:255.255.255.255/61601\"" shutdown_when_empty wait_shutdown echo '167Mar 6 16:57:54172.20.245.8%PIX-7-710005%PIX-7-710005:' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_hash32-vg.sh0000644000000000000000000000013215035412264017501 xustar0030 mtime=1752569012.411674314 30 atime=1764931167.457743358 30 ctime=1764935934.760753806 rsyslog-8.2512.0/tests/rscript_hash32-vg.sh0000775000175000017500000000176715035412264017163 0ustar00rgerrger#!/bin/bash # added 2018-02-07 by Harshvardhan Shrivastava # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \rscript_hash32.sh\]: test for hash32 and hash64mod script-function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$.hash_no_1% - %$.hash_no_2%\n") module(load="../plugins/imtcp/.libs/imtcp") module(load="../contrib/fmhash/.libs/fmhash") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") set $.hash_no_1 = hash32("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e"); set $.hash_no_2 = hash32mod("0f9a1d07-a8c9-43a7-a6f7-198dca3d932e", 100); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup_vg tcpflood -m 20 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown_vg check_exit_vg . $srcdir/diag.sh content-pattern-check "^\(746581550 - 50\|3889673532 - 32\)$" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_compare_num-str-vg.sh0000644000000000000000000000013115055602574021532 xustar0030 mtime=1756824956.037451554 29 atime=1764931159.58661715 30 ctime=1764935932.516719456 rsyslog-8.2512.0/tests/rscript_compare_num-str-vg.sh0000775000175000017500000000020115055602574021173 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" export LOWER_VAL='1' export HIGHER_VAL='"b"' source ${srcdir:-.}/rscript_compare-common.sh rsyslog-8.2512.0/tests/PaxHeaders/omsendertrack-basic.sh0000644000000000000000000000013015062756615020162 xustar0029 mtime=1758190989.23764163 30 atime=1764931160.615633661 29 ctime=1764935932.78872362 rsyslog-8.2512.0/tests/omsendertrack-basic.sh0000775000175000017500000000225315062756615017635 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=10 # MUST be an even number! export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/omsendertrack/.libs/omsendertrack") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="hostname" type="string" string="%hostname%") action(type="omsendertrack" senderid="hostname" statefile="'$RSYSLOG_DYNNAME'.sendertrack") # The following is just to find a terminating condition for message injection template(name="outfmt" type="string" string="%msg:F,58:2%\n") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -h sender1.example.net -m $(( NUMMESSAGES / 2 - 1 )) tcpflood -h sender2.example.net -m 1 -i $(( NUMMESSAGES / 2 - 1 )) # this sender must have firstseen <> lastseen sleep 2 tcpflood -h sender2.example.net -m $(( NUMMESSAGES / 2 )) -i $(( NUMMESSAGES / 2 )) ./msleep 20 shutdown_when_empty sleep 1 echo cat ${RSYSLOG_DYNNAME}.sendertrack echo wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-basic-bulk-vg.sh0000644000000000000000000000013215035412264017264 xustar0030 mtime=1752569012.387841078 30 atime=1764931162.679666768 30 ctime=1764935933.375732605 rsyslog-8.2512.0/tests/es-basic-bulk-vg.sh0000775000175000017500000000011315035412264016726 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/es-basic-bulk.sh rsyslog-8.2512.0/tests/PaxHeaders/stats-json-es.sh0000644000000000000000000000013215055602574016752 xustar0030 mtime=1756824956.040451596 30 atime=1764931167.363741852 30 ctime=1764935934.734753408 rsyslog-8.2512.0/tests/stats-json-es.sh0000775000175000017500000000234415055602574016424 0ustar00rgerrger#!/bin/bash # added 2016-03-30 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[stats-json-es.sh\]: test for verifying stats are reported correctly json-elasticsearch format . ${srcdir:=.}/diag.sh init generate_conf add_conf ' ruleset(name="stats") { action(type="omfile" file="'${RSYSLOG_DYNNAME}'.out.stats.log") } module(load="../plugins/impstats/.libs/impstats" interval="1" severity="7" resetCounters="on" Ruleset="stats" bracketing="on" format="json-elasticsearch") if ($msg == "this condition will never match") then { action(name="an_action_that_is_never_called" type="omfile" file=`echo $RSYSLOG_OUT_LOG`) } ' startup injectmsg_file $srcdir/testsuites/dynstats_input_1 wait_queueempty wait_for_stats_flush ${RSYSLOG_DYNNAME}.out.stats.log echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown custom_content_check '{ "name": "an_action_that_is_never_called", "origin": "core.action", "processed": 0, "failed": 0, "suspended": 0, "suspended!duration": 0, "resumed": 0 }' "${RSYSLOG_DYNNAME}.out.stats.log" custom_assert_content_missing '@cee' "${RSYSLOG_DYNNAME}.out.stats.log" exit_test rsyslog-8.2512.0/tests/PaxHeaders/allowed-sender-tcp-hostname-fail.sh0000644000000000000000000000013215055602574022456 xustar0030 mtime=1756824956.025451386 30 atime=1764931162.847669462 30 ctime=1764935933.425733371 rsyslog-8.2512.0/tests/allowed-sender-tcp-hostname-fail.sh0000775000175000017500000000243315055602574022127 0ustar00rgerrger#!/bin/bash # check that we are able to receive messages from allowed sender # added 2019-08-19 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # Note: we need to know if CI supports DNS resolution. For this, we try to access # our rsyslog echo service. If that works, DNS obviously works. On the contrary # if we cannot access it, DNS might still work. But we prefer to skip the test in # that case (on rsyslog CI it will always work). rsyslog_testbench_test_url_access http://testbench.rsyslog.com/testbench/echo-get.php export NUMMESSAGES=5 # it's just important that we get any messages at all generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs") $AllowedSender TCP,www.rsyslog.com template(name="outfmt" type="string" string="%msg:F,58:2%\n") ruleset(name="rs") { action(type="omfile" template="outfmt" file="'$RSYSLOG_DYNNAME.must-not-be-created'") } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup assign_tcpflood_port $RSYSLOG_DYNNAME.tcpflood_port tcpflood -m$NUMMESSAGES shutdown_when_empty wait_shutdown content_check --regex "connection request from disallowed sender .* discarded" check_file_not_exists "$RSYSLOG_DYNNAME.must-not-be-created" exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_dtls_anon_ciphers.sh0000644000000000000000000000013215055603742021313 xustar0030 mtime=1756825570.303069141 30 atime=1764931164.439694989 30 ctime=1764935933.885740412 rsyslog-8.2512.0/tests/sndrcv_dtls_anon_ciphers.sh0000775000175000017500000000337715055603742020774 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init # start up the instances # uncomment for debugging support: #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.receiver.debuglog" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' global( debug.whitelist="on" debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imdtls/.libs/imdtls" tls.AuthMode="anon") input( type="imdtls" tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_256_GCM_SHA384" port="'$PORT_RCVR'") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup export RSYSLOG_DEBUGLOG="$RSYSLOG_DYNNAME.sender.debuglog" generate_conf 2 add_conf ' module( load="../plugins/omdtls/.libs/omdtls" ) action( name="omdtls" type="omdtls" target="127.0.0.1" port="'$PORT_RCVR'" tls.tlscfgcmd="CipherString=ECDHE-RSA-AES256-SHA384;Ciphersuites=TLS_AES_128_GCM_SHA256" ) ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg 0 1 shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown # IMPORTANT: this test will generate many error messages. This is exactly it's # intent. So do not think something is wrong. The content_check below checks # these error codes. content_check --check-only "TLS library does not support SSL_CONF_cmd" ret=$? if [ $ret == 0 ]; then echo "SKIP: TLS library does not support SSL_CONF_cmd" skip_test else # Kindly check for a failed session content_check "OpenSSL Error Stack" content_check "no shared cipher" fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_ccmiddle.sh0000644000000000000000000000013215055602574017726 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.582729337 30 ctime=1764935934.518750102 rsyslog-8.2512.0/tests/imuxsock_ccmiddle.sh0000775000175000017500000000151615055602574017400 0ustar00rgerrger#!/bin/bash # test trailing LF handling in imuxsock . ${srcdir:=.}/diag.sh init ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") local1.* action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup # send a message with trailing LF ./syslog_caller -fsyslog_inject-c -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" shutdown_when_empty wait_shutdown export EXPECTED=" test 1#0112" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/rulesetmultiqueue.sh0000644000000000000000000000013115055602574020042 xustar0030 mtime=1756824956.039451582 29 atime=1764931166.31272501 30 ctime=1764935934.437748862 rsyslog-8.2512.0/tests/rulesetmultiqueue.sh0000775000175000017500000000533215055602574017515 0ustar00rgerrger#!/bin/bash # Test for disk-only queue mode # This tests defines three rulesets, each one with its own queue. Then, it # sends data to them and checks the outcome. Note that we do need to # use some custom code as the test driver framework does not (yet?) # support multi-output-file operations. # added 2009-10-30 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test does not work on Solaris. The overall queue size check in imdiag requires atomics or mutexes on this platform, which we do not use for performance reasons." export NUMMESSAGES=60000 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' $ModLoad ../plugins/imtcp/.libs/imtcp # general definition $template outfmt,"%msg:F,58:2%\n" # create the individual rulesets $ruleset file1 $RulesetCreateMainQueue on $template dynfile1,"'$RSYSLOG_OUT_LOG'1.log" # trick to use relative path names! :msg, contains, "msgnum:" { ?dynfile1;outfmt ./'$RSYSLOG_OUT_LOG' } $ruleset file2 $RulesetCreateMainQueue on $template dynfile2,"'$RSYSLOG_OUT_LOG'2.log" # trick to use relative path names! :msg, contains, "msgnum:" { ?dynfile2;outfmt ./'$RSYSLOG_OUT_LOG' } $ruleset file3 $RulesetCreateMainQueue on $template dynfile3,"'$RSYSLOG_OUT_LOG'3.log" # trick to use relative path names! :msg, contains, "msgnum:" { ?dynfile3;outfmt ./'$RSYSLOG_OUT_LOG' } # start listeners and bind them to rulesets $InputTCPServerBindRuleset file1 $InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port $InputTCPServerRun 0 $InputTCPServerBindRuleset file2 $InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port2 $InputTCPServerRun 0 $InputTCPServerBindRuleset file3 $InputTCPServerListenPortFile '$RSYSLOG_DYNNAME'.tcpflood_port3 $InputTCPServerRun 0 ' startup assign_tcpflood_port2 "$RSYSLOG_DYNNAME.tcpflood_port2" assign_rs_port "$RSYSLOG_DYNNAME.tcpflood_port3" # now fill the three files (a bit sequentially, but they should # still get their share of concurrency - to increase the chance # we use three connections per set). tcpflood -c3 -p$TCPFLOOD_PORT -m20000 -i0 tcpflood -c3 -p$TCPFLOOD_PORT2 -m20000 -i20000 tcpflood -c3 -p$RS_PORT -m20000 -i40000 # in this version of the imdiag, we do not have the capability to poll # all queues for emptiness. So we do a sleep in the hopes that this will # sufficiently drain the queues. This is race, but the best we currently # can do... - rgerhards, 2009-11-05 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # now consolidate all logs into a single one so that we can use the # regular check logic cat ${RSYSLOG_OUT_LOG}1.log ${RSYSLOG_OUT_LOG}2.log ${RSYSLOG_OUT_LOG}3.log > $RSYSLOG_OUT_LOG seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_bare_var_root-empty.sh0000644000000000000000000000013215035412264021757 xustar0030 mtime=1752569012.409688211 30 atime=1764931159.287612352 30 ctime=1764935932.431718155 rsyslog-8.2512.0/tests/rscript_bare_var_root-empty.sh0000775000175000017500000000133115035412264021424 0ustar00rgerrger#!/bin/bash # addd 2018-01-01 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="empty-%$!%-\n") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="rs") ruleset(name="rs") { set $. = $!; set $! = $.; action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 shutdown_when_empty wait_shutdown export EXPECTED='empty--' echo "$EXPECTED" | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "FAIL: $RSYSLOG_OUT_LOG content invalid:" cat $RSYSLOG_OUT_LOG echo "Expected:" echo "$EXPECTED" error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-query-params-vg.sh0000644000000000000000000000013215055602574023215 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.671698708 30 ctime=1764935933.949741392 rsyslog-8.2512.0/tests/imhttp-post-payload-query-params-vg.sh0000775000175000017500000000025515055602574022666 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" #export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all" source ${srcdir:-.}/imhttp-post-payload-query-params.sh* rsyslog-8.2512.0/tests/PaxHeaders/imfile-growing-file-id.sh0000644000000000000000000000013215035412264020457 xustar0030 mtime=1752569012.391813284 30 atime=1764931166.211723392 30 ctime=1764935934.408748418 rsyslog-8.2512.0/tests/imfile-growing-file-id.sh0000775000175000017500000000505515035412264020133 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify-only generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile" mode="inotify" PollingInterval="1") /* Filter out busy debug output */ global( debug.whitelist="off" debug.files=["rainerscript.c", "ratelimit.c", "ruleset.c", "main Q", "msg.c", "../action.c"]) input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" Severity="error" Facility="local7" addMetadata="on") template(name="outfmt" type="string" string="%msg:F,58:2%\n") if $msg contains "msgnum:" then action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' # generate small input file - state file must be inode only ./inputfilegen -m 1 > $RSYSLOG_DYNNAME.input ls -li $RSYSLOG_DYNNAME.input echo "STEP 1 - small input" startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo "STEP 2 - still small input" # add a bit to input file, but state file must still be inode only ./inputfilegen -m 1 -i1 >> $RSYSLOG_DYNNAME.input ls -li $RSYSLOG_DYNNAME.input* if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then echo FAIL: more than one state file in work directory: ls -l ${RSYSLOG_DYNNAME}.spool error_exit 1 fi startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! echo "STEP 3 - larger input, hash shall be used" ./inputfilegen -m 998 -i 2 >> $RSYSLOG_DYNNAME.input ls -li $RSYSLOG_DYNNAME.input* echo ls ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then echo FAIL: more than one state file in work directory: ls -l ${RSYSLOG_DYNNAME}.spool error_exit 1 fi echo "STEP 4 - append to larger input, hash state file must now be found" ./inputfilegen -m 1000 -i 1000 >> $RSYSLOG_DYNNAME.input ls -li $RSYSLOG_DYNNAME.input* echo ls ${RSYSLOG_DYNNAME}.spool: ls -l ${RSYSLOG_DYNNAME}.spool startup shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! if [ $(ls ${RSYSLOG_DYNNAME}.spool/* | wc -l) -ne 1 ]; then echo FAIL: more than one state file in work directory: ls -l ${RSYSLOG_DYNNAME}.spool error_exit 1 fi seq_check 0 1999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/template-topos-neg.sh0000644000000000000000000000013115055602574017763 xustar0029 mtime=1756824956.04145161 30 atime=1764931161.398646222 30 ctime=1764935933.018727141 rsyslog-8.2512.0/tests/template-topos-neg.sh0000775000175000017500000000107215055602574017433 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="out" type="list") { property(name="STRUCTURED-DATA" position.from="2" position.to="-1") constant(value="\n") } local4.debug action(type="omfile" template="out" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] msgnum:irrelevant' shutdown_when_empty wait_shutdown export EXPECTED='tcpflood@32473 MSGNUM="0"' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile_hup.sh0000644000000000000000000000013215035412264016360 xustar0030 mtime=1752569012.403729902 30 atime=1764931160.775636228 30 ctime=1764935932.834724324 rsyslog-8.2512.0/tests/omfile_hup.sh0000775000175000017500000000156715035412264016040 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Written 2019-06-21 by Rainer Gerhards . ${srcdir:=.}/diag.sh init export NUMMESSAGES=${NUMMESSAGES:-1000000} export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n") template(name="dynfile" type="string" string="'$RSYSLOG_OUT_LOG'") :msg, contains, "msgnum:" action(type="omfile" template="outfmt" dynafile="dynfile") ' startup ./tcpflood -p$TCPFLOOD_PORT -m$NUMMESSAGES & # TCPFlood needs to run async! BGPROCESS=$! for i in $(seq 1 20); do printf '\nsending HUP %d\n' $i issue_HUP --sleep 100 done wait $BGPROCESS shutdown_when_empty wait_shutdown seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/config_enabled-off.sh0000644000000000000000000000013215035412264017720 xustar0030 mtime=1752569012.385854976 30 atime=1764931157.751587699 30 ctime=1764935931.999711542 rsyslog-8.2512.0/tests/config_enabled-off.sh0000775000175000017500000000111215035412264017362 0ustar00rgerrger#!/bin/bash # check disabling a config construct via config.enable. Most # importantly ensure that it does not emit any error messages # for object parameters. # addd 2019-05-09 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imfile/.libs/imfile") input(type="imfile" file="/tmp/notyet.txt" tag="testing-tag" config.enabled="off") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup shutdown_when_empty wait_shutdown content_check 'imfile: no files configured' check_not_present 'parameter .* not known' exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-wildcards.sh0000644000000000000000000000013115055602574017456 xustar0030 mtime=1756824956.029451442 29 atime=1764931166.05372086 30 ctime=1764935934.355747606 rsyslog-8.2512.0/tests/imfile-wildcards.sh0000775000175000017500000000664415055602574017140 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under GPLv3 . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify export IMFILEINPUTFILES="10" export IMFILELASTINPUTLINES="3" export IMFILECHECKTIMEOUT="60" mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' # comment out if you need more debug info: global( debug.whitelist="on" debug.files=["imfile.c"]) global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile" mode="inotify" normalizePath="off") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input.*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") input(type="imfile" File="/does/not/exist/*.log" Tag="file:" Severity="error" Facility="local7" addMetadata="on") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value=", filename: ") property(name="$!metadata!filename") constant(value=", fileoffset: ") property(name="$!metadata!fileoffset") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' # generate input files first. Note that rsyslog processes it as # soon as it start up (so the file should exist at that point). imfilebefore=$RSYSLOG_DYNNAME.input.01.log ./inputfilegen -m 1 > $imfilebefore # Start rsyslog now before adding more files startup for i in $(seq 2 $IMFILEINPUTFILES); do filnbr=$(printf "%2.2d" $i) cp $imfilebefore $RSYSLOG_DYNNAME.input.$filnbr.log imfilebefore=$RSYSLOG_DYNNAME.input.$filnbr.log done # Content check with timeout content_check_with_count "HEADER msgnum:00000000:" $IMFILEINPUTFILES $IMFILECHECKTIMEOUT # Add some extra lines to the last log ./inputfilegen -m $IMFILELASTINPUTLINES > $RSYSLOG_DYNNAME.input.$((IMFILEINPUTFILES + 1)).log ls -l $RSYSLOG_DYNNAME.input.* # Content check with timeout content_check_with_count "input.11.log" $IMFILELASTINPUTLINES $IMFILECHECKTIMEOUT shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! # Sort Output file now, and compare full file content presort printf 'HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.01.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.02.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.03.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.04.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.05.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.06.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.07.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.08.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.09.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.10.log, fileoffset: 0 HEADER msgnum:00000000:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 0 HEADER msgnum:00000001:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 17 HEADER msgnum:00000002:, filename: ./'$RSYSLOG_DYNNAME'.input.11.log, fileoffset: 34\n' | cmp - $RSYSLOG_DYNNAME.presort if [ ! $? -eq 0 ]; then echo "FAIL: invalid output generated, $RSYSLOG_DYNNAME.presort is:" echo "File contents:" cat -n $RSYSLOG_DYNNAME.presort error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-template-cnf6-vg.sh0000644000000000000000000000013215035412264020434 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.730763751 30 ctime=1764935935.124759378 rsyslog-8.2512.0/tests/pgsql-template-cnf6-vg.sh0000775000175000017500000000177715035412264020117 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' template(name="pgtemplate" type="list" option.sql="on") { constant(value="INSERT INTO SystemEvents (SysLogTag) values ('"'"'") property(name="msg") constant(value="'"'"')") } module(load="../plugins/ompgsql/.libs/ompgsql") if $msg contains "msgnum" then { action(type="ompgsql" server="127.0.0.1" db="syslogtest" user="postgres" pass="testbench" template="pgtemplate") }' startup_vg injectmsg 0 5000 shutdown_when_empty wait_shutdown_vg check_exit_vg # we actually put the message in the SysLogTag field, so we know it doesn't use the default # template, like in pgsql-basic psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/pmsnare-cccstyle-udp.sh0000644000000000000000000000013215035412264020273 xustar0030 mtime=1752569012.408695159 30 atime=1764931168.554760932 30 ctime=1764935935.076758643 rsyslog-8.2512.0/tests/pmsnare-cccstyle-udp.sh0000775000175000017500000001353715035412264017753 0ustar00rgerrger#!/bin/bash # add 2018-06-29 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init setvar_RS_HOSTNAME generate_conf add_conf ' module(load="../contrib/pmsnare/.libs/pmsnare") module(load="../plugins/imudp/.libs/imudp") input(type="imudp" port="'$TCPFLOOD_PORT'" ruleset="ruleset1") global(parser.escapeControlCharactersCStyle="on") $EscapeControlCharactersOnReceive on template(name="outfmt" type="string" string="%PRI%,%syslogfacility-text%,%syslogseverity-text%,%programname%,%syslogtag%,%msg%\n") ruleset(name="ruleset1" parser=["rsyslog.snare","rsyslog.rfc5424","rsyslog.rfc3164"]) { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup tcpflood -m1 -T "udp" -M "\"<14> 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite \\\"AES-256-CBC-SHA TLSv1 Non-Export 256-bit\\\" - Session Reuse The authenti\"" tcpflood -m1 -T "udp" -M "\"<14>123456789: HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................\"" tcpflood -m1 -T "udp" -M "\"<14>May 21 2017 00:00:00: %ASA-4-102030: Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group "local_in" [0x0, 0x0]\"" tcpflood -m1 -T "udp" -M "\"<14>2017-05-21T00:00:01.123Z hostname.domain Hostd: verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]};\"" tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname CROND[12393]: pam_unix(crond:session): session closed for user root................\"" tcpflood -m1 -T "udp" -M "\"<14>May 21 12:00:01 hostname.domain MSWinEventLog 1 Security 00000000 Sun May 21 12:00:01.123 4624 Microsoft-Windows-Security-Auditing N/A N/A Success Audit hostname.domain Logon An account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................\"" shutdown_when_empty wait_shutdown export EXPECTED='14,user,info,,, 05/21/2017:00:00:00 GMT HOSTNAME 1-ABC-2 : default SSLLOG SSL_HANDSHAKE_SUCCESS 39672436 0 : SPCBId 6377757 - ClientIP 192.168.0.11 - ClientPort 55073 - VserverServiceIP 192.168.0.11 - VserverServicePort 443 - ClientVersion TLSv1.0 - CipherSuite "AES-256-CBC-SHA TLSv1 Non-Export 256-bit" - Session Reuse The authenti 14,user,info,123456789,123456789:, HOSTNAME: May 21 12:00:01.123 gmt: %IOSXE-6-PLATFORM: F0: cpp_cp: QFP:0.0 Thread:105 TS:00000000000000 %NAT-6-LOG_TRANSLATION: Created Translation UDP 192.168.0.11:44593 192.168.0.11:21129 192.168.0.11:53 192.168.0.11:53 0................ 14,user,info,%ASA-4-102030,%ASA-4-102030:, Deny udp src vlan_12302:192.168.0.11/514 dst vlan_1233:192.168.0.11/514 by access-group local_in [0x0, 0x0] 14,user,info,Hostd,Hostd:, verbose hostd[81480B70] [Originator@6876 sub=Hostsvc.StorageSystem] SendStorageInfoEvent: Notify: StorageSystemMsg{HBAs=[vmhba0, vmhba1, vmhba2, vmhba3, vmhba32, vmhba4, ]}; 14,user,info,CROND,CROND[12393]:, pam_unix(crond:session): session closed for user root................ 14,user,info,MSWinEventLog,MSWinEventLog, 1\tSecurity\t00000000\tSun May 21 12:00:01.123\t4624\tMicrosoft-Windows-Security-Auditing\tN/A\tN/A\tSuccess Audit\thostname.domain\tLogon\t\tAn account was successfully logged on. Subject: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon Type: 3 New Logon: Security ID: 0x000000000 Account Name: first.last Account Domain: domain Logon ID: 0x000000000 Logon GUID: 0x000000000 Process Information: Process ID: 0x000000000 Process Name: first.last Network Information: Workstation Name: Source Network Address: 192.168.0.11 Source Port: 51542 Detailed Authentication Information: Logon Process: Kerberos Authentication Package: Kerberos Transited Services: - Package Name (NTLM only): - Key Length: 0 This event is generated when a logon session is created. It is generated on the computer that was accessed. The subject fields indicate the account on the local system which requested the logon. This is most commonly a service such as the Server service, or a local process such as Winlogon.exe or Services.exe. The logon type field indicates the kind of logon that occurred. The most common types are 2 (interactive) and 3 (network). The New Logon fields indicate the account for whom the new logon was created, i.e. the account that wa................' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table_rscript_reload_without_stub-vg.sh0000644000000000000000000000013015035412264025235 xustar0030 mtime=1752569012.399757696 29 atime=1764931167.83174935 29 ctime=1764935934.87075549 rsyslog-8.2512.0/tests/lookup_table_rscript_reload_without_stub-vg.sh0000775000175000017500000000031615035412264024706 0ustar00rgerrger#!/bin/bash # added 2015-12-18 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 export USE_VALGRIND="YES" source ${srcdir:-.}/lookup_table_rscript_reload_without_stub.sh rsyslog-8.2512.0/tests/PaxHeaders/imfile-endregex-timeout-none.sh0000644000000000000000000000013215055602574021725 xustar0030 mtime=1756824956.029451442 30 atime=1764931165.867717879 30 ctime=1764935934.300746765 rsyslog-8.2512.0/tests/imfile-endregex-timeout-none.sh0000775000175000017500000000317415055602574021401 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 echo ====================================================================== echo [imfile-endregex-timeout-none.sh] . ${srcdir:=.}/diag.sh init . $srcdir/diag.sh check-inotify mkdir "$RSYSLOG_DYNNAME.work" generate_conf add_conf ' global(workDirectory="./'"$RSYSLOG_DYNNAME"'.work") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" PersistStateInterval="1" startmsg.regex="^[^ ]") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # we need to sleep a bit between writes to give imfile a chance # to pick up the data (IN MULTIPLE ITERATIONS!) echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input ./msleep 5000 # wait 5 seconds - this shall cause a timeout echo ' msgnum:2 msgnum:3' >> $RSYSLOG_DYNNAME.input # the next line terminates our test. It is NOT written to the output file, # as imfile waits whether or not there is a follow-up line that it needs # to combine. echo 'END OF TEST' >> $RSYSLOG_DYNNAME.input ./msleep 200 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! printf 'HEADER msgnum:0\\\\n msgnum:1\\\\n msgnum:2\\\\n msgnum:3\n' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid multiline message generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_traillf.sh0000644000000000000000000000013215055602574017617 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.558728952 30 ctime=1764935934.511749994 rsyslog-8.2512.0/tests/imuxsock_traillf.sh0000775000175000017500000000137415055602574017273 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines ./syslog_caller -fsyslog_inject-l -m0 > /dev/null 2>&1 no_liblogging_stdlog=$? if [ $no_liblogging_stdlog -ne 0 ];then echo "liblogging-stdlog not available - skipping test" exit 77 fi generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") local1.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup ./syslog_caller -fsyslog_inject-l -m1 -C "uxsock:$RSYSLOG_DYNNAME-testbench_socket" shutdown_when_empty wait_shutdown export EXPECTED=" test" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/imrelp-maxDataSize-error.sh0000644000000000000000000000013115035412264021057 xustar0029 mtime=1752569012.39578549 30 atime=1764931164.052688784 30 ctime=1764935933.777738759 rsyslog-8.2512.0/tests/imrelp-maxDataSize-error.sh0000775000175000017500000000126415035412264020532 0ustar00rgerrger#!/bin/bash # add 2018-04-26 by Pascal Withopf, released under ASL 2.0 echo [imrelp-maxDataSize-error.sh] . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imrelp/.libs/imrelp") global( maxMessageSize="300" ) input(type="imrelp" port="'$TCPFLOOD_PORT'" maxDataSize="250") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup ./msleep 2000 shutdown_when_empty wait_shutdown grep "error: maxDataSize.*smaller than global parameter maxMessageSize" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imtcp-tls-gtls-x509fingerprint-invld.sh0000644000000000000000000000013215055603742023206 xustar0030 mtime=1756825570.301069108 30 atime=1764931162.954671178 30 ctime=1764935933.459733891 rsyslog-8.2512.0/tests/imtcp-tls-gtls-x509fingerprint-invld.sh0000775000175000017500000000217615055603742022663 0ustar00rgerrger#!/bin/bash # added 2018-12-22 by Rainer Gerhards # check for INVALID fingerprint! # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export NUMMESSAGES=1 generate_conf add_conf ' global( defaultNetstreamDriverCAFile="'$srcdir/tls-certs/ca.pem'" defaultNetstreamDriverCertFile="'$srcdir/tls-certs/cert.pem'" defaultNetstreamDriverKeyFile="'$srcdir/tls-certs/key.pem'" # debug.whitelist="on" # debug.files=["net_ossl.c", "nsd_ossl.c", "tcpsrv.c", "nsdsel_ossl.c", "nsdpoll_ptcp.c", "dnscache.c"] ) module( load="../plugins/imtcp/.libs/imtcp" StreamDriver.Name="gtls" StreamDriver.Mode="1" StreamDriver.AuthMode="x509/fingerprint" PermittedPeer=["SHA1:FF:C6:62:D5:9D:25:9F:BC:F3:CB:61:FA:D2:B3:8B:61:88:D7:06:C3"] # INVALID! ) input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ) action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup tcpflood -p'$TCPFLOOD_PORT' -m$NUMMESSAGES -Ttls -x$srcdir/tls-certs/ca.pem -Z$srcdir/tls-certs/cert.pem -z$srcdir/tls-certs/key.pem shutdown_when_empty wait_shutdown content_check --regex "peer fingerprint .* unknown" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_ne_var.sh0000644000000000000000000000013215035412264017251 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.446614904 30 ctime=1764935932.478718875 rsyslog-8.2512.0/tests/rscript_ne_var.sh0000775000175000017500000000260615035412264016724 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_ne.sh\]: testing rainerscript NE statement for two JSON variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } set $!var1 = "value1"; set $!var2 = "value2"; if $!var1 != $!var2 then { set $!var1 = "value"; set $!var2 = "value"; if $!var1 != $!var2 then { # Failure stop } else { unset $!var1; unset $!var2; } } else { # Failure stop } set $.var1 = "value1"; set $.var2 = "value2"; if $.var1 != $.var2 then { set $.var1 = "value"; set $.var2 = "value"; if $.var1 != $.var2 then { # Failure stop } else { unset $.var1; unset $.var2; } } else { # Failure stop } set $/var1 = "value1"; set $/var2 = "value2"; if $/var1 != $/var2 then { set $/var1 = "value"; set $/var2 = "value"; if $/var1 != $/var2 then { # Failure stop } else { unset $/var1; unset $/var2; } } else { # Failure stop } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 1 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rfc5424parser.sh0000644000000000000000000000013215035412264016537 xustar0030 mtime=1752569012.409688211 30 atime=1764931161.208643174 30 ctime=1764935932.961726268 rsyslog-8.2512.0/tests/rfc5424parser.sh0000775000175000017500000000133115035412264016204 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # rgerhards, 2013-11-22 echo =============================================================================== echo \[rfc5424parser.sh\]: testing mmpstrucdata . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") template(name="outfmt" type="string" string="%msg:F,58:2%\n") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") if $msg contains "msgnum" then action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) ' startup sleep 1 tcpflood -m100 -y shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown seq_check 0 99 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-defaults-vg.sh0000644000000000000000000000013215035412264017753 xustar0030 mtime=1752569012.405716005 30 atime=1764931165.110705745 30 ctime=1764935934.071743259 rsyslog-8.2512.0/tests/omprog-defaults-vg.sh0000775000175000017500000000131615035412264017423 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # Same test than 'omprog-defaults.sh', but checking for memory # problems using valgrind. Note it is not necessary to repeat the # rest of checks (this simplifies the maintenance of the tests). . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary=`echo $srcdir/testsuites/omprog-defaults-bin.sh p1 p2 p3` template="outfmt" name="omprog_action" ) } ' startup_vg injectmsg 0 10 shutdown_when_empty wait_shutdown_vg check_exit_vg exit_test rsyslog-8.2512.0/tests/PaxHeaders/glbl-internalmsg_severity-debug-not_shown.sh0000644000000000000000000000013215035412264024524 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.724587266 30 ctime=1764935931.992711435 rsyslog-8.2512.0/tests/glbl-internalmsg_severity-debug-not_shown.sh0000775000175000017500000000111215035412264024166 0ustar00rgerrger#!/bin/bash # check that info-severity messages are actually emitted; we use # lookup table as a simple sample to get such a message. # addd 2019-05-07 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl" reloadOnHUP="on") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup shutdown_when_empty wait_shutdown check_not_present "rsyslogd fully started up and initialized - begin actual processing" exit_test rsyslog-8.2512.0/tests/PaxHeaders/failover-double.sh0000644000000000000000000000013115035412264017307 xustar0029 mtime=1752569012.38883413 30 atime=1764931163.768684231 30 ctime=1764935933.692737458 rsyslog-8.2512.0/tests/failover-double.sh0000775000175000017500000000101415035412264016753 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export DEAD_PORT=4 # a port unassigned by IANA and very unlikely to be used generate_conf add_conf ' $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" @@127.0.0.1:'$DEAD_PORT' $ActionExecOnlyWhenPreviousIsSuspended on & @@127.0.0.1:1234 & ./'"${RSYSLOG_OUT_LOG}"';outfmt $ActionExecOnlyWhenPreviousIsSuspended off ' startup injectmsg 0 5000 shutdown_when_empty wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_ruleset_call.sh0000644000000000000000000000013215035412264020455 xustar0030 mtime=1752569012.412667365 30 atime=1764931162.003655927 30 ctime=1764935933.189729759 rsyslog-8.2512.0/tests/rscript_ruleset_call.sh0000775000175000017500000000170015035412264020122 0ustar00rgerrger#!/bin/bash # added 2012-10-29 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_ruleset_call.sh\]: testing rainerscript ruleset\(\) and call statement . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" field.delimiter="58" field.number="2") constant(value="\n") } # we deliberately include continue/stop to make sure we have more than # one statement. This catches grammar errors ruleset(name="rs2") { continue action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") stop } # this time we make sure a single statement is properly supported ruleset(name="rs1") { call rs2 } if $msg contains "msgnum" then call rs1 ' startup injectmsg 0 5000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/mmanon_random_cons_128_ipv6.sh0000644000000000000000000000013215035412264021436 xustar0030 mtime=1752569012.399757696 30 atime=1764931160.334629153 30 ctime=1764935932.712722457 rsyslog-8.2512.0/tests/mmanon_random_cons_128_ipv6.sh0000775000175000017500000000610015035412264021102 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%msg%\n") template(name="filename" type="string" string="'${RSYSLOG_DYNNAME}'.%syslogtag%.log") module(load="../plugins/mmanon/.libs/mmanon") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="testing") ruleset(name="testing") { action(type="mmanon" ipv6.anonmode="random-consistent" ipv6.bits="128") action(type="omfile" dynafile="filename" template="outfmt") }' echo 'Since this test tests randomization, there is a theoretical possibility of it failing even if rsyslog works correctly. Therefore, if the test unexpectedly fails try restarting it.' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 file1 33:45:DDD::4 <129>Mar 10 01:00:00 172.20.245.8 file2 :: <129>Mar 10 01:00:00 172.20.245.8 file6 :: <129>Mar 10 01:00:00 172.20.245.8 file3 72:8374:adc7:47FF::43:0:1AFE <129>Mar 10 01:00:00 172.20.245.8 file4 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF <129>Mar 10 01:00:00 172.20.245.8 file5 72:8374:adc7:47FF::43:0:1AFE\"" shutdown_when_empty wait_shutdown echo ' 33:45:DDD::4' | cmp - ${RSYSLOG_DYNNAME}.file1.log >/dev/null if [ ! $? -eq 1 ]; then echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file1.log is:" cat ${RSYSLOG_DYNNAME}.file1.log error_exit 1 fi; echo ' ::' | cmp - ${RSYSLOG_DYNNAME}.file2.log >/dev/null if [ ! $? -eq 1 ]; then echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file2.log is:" cat ${RSYSLOG_DYNNAME}.file2.log error_exit 1 fi; echo ' 72:8374:adc7:47FF::43:0:1AFE' | cmp - ${RSYSLOG_DYNNAME}.file3.log >/dev/null if [ ! $? -eq 1 ]; then echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file3.log is:" cat ${RSYSLOG_DYNNAME}.file3.log error_exit 1 fi; echo ' FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF' | cmp - ${RSYSLOG_DYNNAME}.file4.log >/dev/null if [ ! $? -eq 1 ]; then echo "invalidly equal ip-address generated, ${RSYSLOG_DYNNAME}.file4.log is:" cat ${RSYSLOG_DYNNAME}.file4.log error_exit 1 fi; cmp ${RSYSLOG_DYNNAME}.file3.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null if [ ! $? -eq 0 ]; then echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file3.log and ${RSYSLOG_DYNNAME}.file5.log are:" cat ${RSYSLOG_DYNNAME}.file3.log cat ${RSYSLOG_DYNNAME}.file5.log error_exit 1 fi; cmp ${RSYSLOG_DYNNAME}.file2.log ${RSYSLOG_DYNNAME}.file6.log >/dev/null if [ ! $? -eq 0 ]; then echo "invalidly unequal ip-addresses generated, ${RSYSLOG_DYNNAME}.file1.log and ${RSYSLOG_DYNNAME}.file6.log are:" cat ${RSYSLOG_DYNNAME}.file1.log cat ${RSYSLOG_DYNNAME}.file6.log error_exit 1 fi; cmp ${RSYSLOG_DYNNAME}.file4.log ${RSYSLOG_DYNNAME}.file5.log >/dev/null if [ ! $? -eq 1 ]; then echo "invalidly equal ip-addresses generated, ${RSYSLOG_DYNNAME}.file4.log and ${RSYSLOG_DYNNAME}.file5.log are:" cat ${RSYSLOG_DYNNAME}.file4.log cat ${RSYSLOG_DYNNAME}.file5.log error_exit 1 fi; rm -f ${RSYSLOG_DYNNAME}.*.log exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-bulk-errfile-popul-erronly.sh0000644000000000000000000000013215071746523022056 xustar0030 mtime=1760021843.886421743 30 atime=1764931162.636666079 30 ctime=1764935933.363732422 rsyslog-8.2512.0/tests/es-bulk-errfile-popul-erronly.sh0000775000175000017500000000256315071746523021533 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init ensure_elasticsearch_ready init_elasticsearch echo '{ "name" : "foo" } {"name": bar"} {"name": "baz"} {"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") # Note: we must mess up with the template, because we can not # instruct ES to put further constraints on the data type and # values. So we require integer and make sure it is none. template(name="tpl" type="list") { constant(value="{\"") property(name="$!key") constant(value="\":") property(name="$!obj") constant(value="}") } module(load="../plugins/omelasticsearch/.libs/omelasticsearch") module(load="../plugins/imfile/.libs/imfile") ruleset(name="foo") { set $!key = "my_obj"; set $!obj = $msg; action(type="omelasticsearch" template="tpl" searchIndex="rsyslog_testbench" serverport="19200" bulkmode="on" errorFile="'${RSYSLOG_DYNNAME}'.errorfile" erroronly="on") } input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile" Tag="foo" Severity="info" ruleset="foo") ' startup shutdown_when_empty wait_shutdown $PYTHON $srcdir/elasticsearch-error-format-check.py erroronly if [ $? -ne 0 ] then echo "error: Format for error file different! " $? error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-metrics.sh0000644000000000000000000000013115055605325017205 xustar0030 mtime=1756826325.656800789 29 atime=1764931164.78470052 30 ctime=1764935933.980741867 rsyslog-8.2512.0/tests/imhttp-metrics.sh0000775000175000017500000000073015055605325016655 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf IMHTTP_PORT="$(get_free_port)" add_conf ' template(name="outfmt" type="string" string="%msg%\n") module(load="../contrib/imhttp/.libs/imhttp" ports="'$IMHTTP_PORT'" metricsPath="/metrics" ) ' startup curl -s http://localhost:$IMHTTP_PORT/metrics > "$RSYSLOG_OUT_LOG" shutdown_when_empty wait_shutdown content_check "imhttp_up 1" exit_test rsyslog-8.2512.0/tests/PaxHeaders/func-substring-relative-endpos.sh0000644000000000000000000000013215055602574022310 xustar0030 mtime=1756824956.028451428 30 atime=1764931157.823588855 30 ctime=1764935932.017711818 rsyslog-8.2512.0/tests/func-substring-relative-endpos.sh0000775000175000017500000000103515055602574021756 0ustar00rgerrger#!/bin/bash # addd 2023-01-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%$!my_struc_data%\n") set $!my_struc_data = substring($STRUCTURED-DATA, 1, -2); local4.debug action(type="omfile" template="outfmt" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg_literal '<167>1 2003-03-01T01:00:00.000Z hostname1 sender - tag [tcpflood@32473 MSGNUM="0"] data' shutdown_when_empty wait_shutdown export EXPECTED='tcpflood@32473 MSGNUM="0"' cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/func-substring-invld-startpos-vg.sh0000644000000000000000000000013215055602574022612 xustar0030 mtime=1756824956.028451428 30 atime=1764931157.796588421 30 ctime=1764935932.010711711 rsyslog-8.2512.0/tests/func-substring-invld-startpos-vg.sh0000775000175000017500000000013315055602574022256 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/func-substring-invld-startpos.sh rsyslog-8.2512.0/tests/PaxHeaders/glbl-ruleset-queue-defaults.sh0000644000000000000000000000013215035412264021561 xustar0030 mtime=1752569012.389827181 30 atime=1764931157.697586832 30 ctime=1764935931.984711313 rsyslog-8.2512.0/tests/glbl-ruleset-queue-defaults.sh0000775000175000017500000000127015035412264021230 0ustar00rgerrger#!/bin/bash # check that global ruleset queue defaults can be specified. However, # we do not tests that they actually work - that's quite hard to # do reliably. # addd 2019-05-09 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global( default.ruleset.queue.timeoutshutdown="1000" default.ruleset.queue.timeoutactioncompletion="1000" default.ruleset.queue.timeoutenqueue="1000" default.ruleset.queue.timeoutworkerthreadshutdown="1000" ) action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup shutdown_when_empty wait_shutdown check_not_present 'parameter.*not known' exit_test rsyslog-8.2512.0/tests/PaxHeaders/sndrcv_relp_rebind.sh0000644000000000000000000000013215055602574020104 xustar0030 mtime=1756824956.039451582 30 atime=1764931164.152690387 30 ctime=1764935933.805739188 rsyslog-8.2512.0/tests/sndrcv_relp_rebind.sh0000775000175000017500000000305115055602574017552 0ustar00rgerrger#!/bin/bash # added 2017-09-29 by Rgerhards # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init echo testing sending and receiving via relp w/ rebind interval # uncomment for debugging support: # start up the instances #export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" export RSYSLOG_DEBUGLOG="log" generate_conf export PORT_RCVR="$(get_free_port)" add_conf ' module(load="../plugins/imrelp/.libs/imrelp") # then SENDER sends to this port (not tcpflood!) input(type="imrelp" port="'$PORT_RCVR'") $template outfmt,"%msg:F,58:2%\n" :msg, contains, "msgnum:" action(type="omfile" file="'$RSYSLOG_OUT_LOG'" template="outfmt") ' startup export RSYSLOG_DEBUGLOG="log2" #valgrind="valgrind" generate_conf 2 export TCPFLOOD_PORT="$(get_free_port)" # TODO: move to diag.sh add_conf ' module(load="../plugins/omrelp/.libs/omrelp") # We know that a rebind interval of 1 is NOT what you would normally expect in # production. However, this stresses the code the most and we have seen that # some problems do not reliably occur if we use higher rebind intervals. Thus # we consider it to be a good, actually required, setting. action(type="omrelp" protocol="tcp" target="127.0.0.1" port="'$PORT_RCVR'" rebindinterval="1") ' 2 startup 2 # now inject the messages into instance 2. It will connect to instance 1, # and that instance will record the data. injectmsg2 1 1000 # shut down sender shutdown_when_empty 2 wait_shutdown 2 # now it is time to stop the receiver as well shutdown_when_empty wait_shutdown seq_check 1 1000 exit_test rsyslog-8.2512.0/tests/PaxHeaders/privdropuserid.sh0000644000000000000000000000013215055602574017321 xustar0030 mtime=1756824956.037451554 30 atime=1764931161.266644105 30 ctime=1764935932.978726529 rsyslog-8.2512.0/tests/privdropuserid.sh0000775000175000017500000000111215055602574016763 0ustar00rgerrger#!/bin/bash # addd 2016-03-24 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris." . $srcdir/privdrop_common.sh rsyslog_testbench_setup_testuser generate_conf add_conf ' template(name="outfmt" type="list") { property(name="msg" compressSpace="on") constant(value="\n") } action(type="omfile" template="outfmt" file=`echo $RSYSLOG_OUT_LOG`) $PrivDropToUserID '${TESTBENCH_TESTUSER[uid]}' ' startup shutdown_when_empty wait_shutdown content_check --regex "userid.*${TESTBENCH_TESTUSER[uid]}" exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_field.sh0000644000000000000000000000013115035412264017061 xustar0030 mtime=1752569012.410681262 29 atime=1764931159.32861301 30 ctime=1764935932.444718354 rsyslog-8.2512.0/tests/rscript_field.sh0000775000175000017500000000126015035412264016530 0ustar00rgerrger#!/bin/bash # added 2012-09-20 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_field.sh\]: testing rainerscript field\(\) function . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 5000 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 4999 exit_test rsyslog-8.2512.0/tests/PaxHeaders/timestamp-3164.sh0000644000000000000000000000013215055602574016636 xustar0030 mtime=1756824956.042451623 30 atime=1764931159.080609031 30 ctime=1764935932.371717237 rsyslog-8.2512.0/tests/timestamp-3164.sh0000775000175000017500000000313215055602574016304 0ustar00rgerrger#!/bin/bash # add 2018-06-25 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="string" string="%timestamp:::date-rfc3164%\n") :syslogtag, contains, "TAG" action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup injectmsg_literal "<167>Jan 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Feb 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Mar 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Apr 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>May 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Jun 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Jul 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Aug 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Sep 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Oct 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Nov 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Dec 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Jan 6 16:57:54 172.20.245.8 TAG: MSG" injectmsg_literal "<167>Jan 16 16:57:54 172.20.245.8 TAG: MSG" shutdown_when_empty wait_shutdown echo 'Jan 6 16:57:54 Feb 6 16:57:54 Mar 6 16:57:54 Apr 6 16:57:54 May 6 16:57:54 Jun 6 16:57:54 Jul 6 16:57:54 Aug 6 16:57:54 Sep 6 16:57:54 Oct 6 16:57:54 Nov 6 16:57:54 Dec 6 16:57:54 Jan 6 16:57:54 Jan 16 16:57:54' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imuxsock_logger.sh0000644000000000000000000000013215055602574017441 xustar0030 mtime=1756824956.032451484 30 atime=1764931166.501728039 30 ctime=1764935934.494749734 rsyslog-8.2512.0/tests/imuxsock_logger.sh0000775000175000017500000000107715055602574017115 0ustar00rgerrger#!/bin/bash . ${srcdir:=.}/diag.sh init check_logger_has_option_d export NUMMESSAGES=1 export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/imuxsock/.libs/imuxsock" sysSock.use="off") input(type="imuxsock" Socket="'$RSYSLOG_DYNNAME'-testbench_socket") template(name="outfmt" type="string" string="%msg:%\n") *.=notice action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup logger -d -u $RSYSLOG_DYNNAME-testbench_socket test shutdown_when_empty wait_shutdown export EXPECTED=" test" cmp_exact exit_test rsyslog-8.2512.0/tests/PaxHeaders/lookup_table_rscript_reload_without_stub.sh0000644000000000000000000000013215035412264024625 xustar0030 mtime=1752569012.399757696 30 atime=1764931167.815749094 30 ctime=1764935934.865755413 rsyslog-8.2512.0/tests/lookup_table_rscript_reload_without_stub.sh0000775000175000017500000000323015035412264024272 0ustar00rgerrger#!/bin/bash # test for lookup-table reload by rscript-stmt without stub # added 2015-12-18 by singh.janmejay # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init skip_platform "FreeBSD" "This test currently does not work on FreeBSD" generate_conf add_conf ' lookup_table(name="xlate" file="'$RSYSLOG_DYNNAME'.xlate.lkp_tbl") template(name="outfmt" type="string" string="- %msg% %$.lkp%\n") set $.lkp = lookup("xlate", $msg); if ($msg == " msgnum:00000002:") then { reload_lookup_table("xlate") } action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' cp -f $srcdir/testsuites/xlate.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl startup # the last message ..002 should cause successful lookup-table reload cp -f $srcdir/testsuites/xlate_more.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl injectmsg 0 3 await_lookup_table_reload wait_queueempty content_check "msgnum:00000000: foo_old" content_check "msgnum:00000001: bar_old" assert_content_missing "baz" cp -f $srcdir/testsuites/xlate_more_with_duplicates_and_nomatch.lkp_tbl $RSYSLOG_DYNNAME.xlate.lkp_tbl injectmsg 0 3 await_lookup_table_reload wait_queueempty content_check "msgnum:00000000: foo_new" content_check "msgnum:00000001: bar_new" content_check "msgnum:00000002: baz" rm -f $RSYSLOG_DYNNAME.xlate.lkp_tbl # this should lead to unsuccessful reload injectmsg 0 3 await_lookup_table_reload wait_queueempty injectmsg 0 2 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown content_check_with_count "msgnum:00000000: foo_latest" 2 content_check_with_count "msgnum:00000001: quux" 2 content_check_with_count "msgnum:00000002: baz_latest" 1 exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_ipv42num.sh0000644000000000000000000000013215035412264017463 xustar0030 mtime=1752569012.411674314 30 atime=1764931159.320612882 30 ctime=1764935932.442718324 rsyslog-8.2512.0/tests/rscript_ipv42num.sh0000775000175000017500000000343415035412264017136 0ustar00rgerrger#!/bin/bash # add 2017-02-09 by Jan Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") # in pre 8.1907.0 versions of rsyslog the code was misspelled as # "ip42num" (missing "v"). We check this is still supported as alias set $!ip!v0 = ip42num("0.0.0.0"); # use correct function name set $!ip!v1 = ipv42num("0.0.0.0"); set $!ip!v2 = ipv42num("0.0.0.1"); set $!ip!v3 = ipv42num("0.0.1.0"); set $!ip!v4 = ipv42num("0.1.0.0"); set $!ip!v5 = ipv42num("1.0.0.0"); set $!ip!v6 = ipv42num("0.0.0.135"); set $!ip!v7 = ipv42num("1.1.1.1"); set $!ip!v8 = ipv42num("225.33.1.10"); set $!ip!v9 = ipv42num("172.0.0.1"); set $!ip!v10 = ipv42num("255.255.255.255"); set $!ip!v11 = ipv42num("1.0.3.45 "); set $!ip!v12 = ipv42num(" 0.0.0.1"); set $!ip!v13 = ipv42num(" 0.0.0.1 "); set $!ip!e1 = ipv42num("a"); set $!ip!e2 = ipv42num(""); set $!ip!e3 = ipv42num("123.4.6.*"); set $!ip!e4 = ipv42num("172.0.0.1."); set $!ip!e5 = ipv42num("172.0.0..1"); set $!ip!e6 = ipv42num(".172.0.0.1"); set $!ip!e7 = ipv42num(".17 2.0.0.1"); template(name="outfmt" type="string" string="%!ip%\n") local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") ' startup tcpflood -m1 -y shutdown_when_empty wait_shutdown echo '{ "v0": 0, "v1": 0, "v2": 1, "v3": 256, "v4": 65536, "v5": 16777216, "v6": 135, "v7": 16843009, "v8": 3777036554, "v9": 2885681153, "v10": 4294967295, "v11": 16778029, "v12": 1, "v13": 1, "e1": -1, "e2": -1, "e3": -1, "e4": -1, "e5": -1, "e6": -1, "e7": -1 }' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid function output detected, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/internal-errmsg-memleak-vg.sh0000644000000000000000000000013215035412264021365 xustar0030 mtime=1752569012.398764645 30 atime=1764931157.689586704 30 ctime=1764935931.982711282 rsyslog-8.2512.0/tests/internal-errmsg-memleak-vg.sh0000775000175000017500000000245415035412264021041 0ustar00rgerrger#!/bin/bash # This tests a memory leak we have seen when processing internal error # message with the settings used in this test. We use imfile as it is # easist to reproduce this way. Note that we are only interested in # whether or not we have a leak, not any other functionality. Most # importantly, we do not care if the error message appears or not. This # is because it is not so easy to pick it up from the system log and other # tests already cover this scenario. # add 2017-05-10 by Rainer Gerhards, released under ASL 2.0 uname if [ $(uname) = "FreeBSD" ] ; then echo "This test currently does not work on FreeBSD." exit 77 fi . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(processInternalMessages="off") $RepeatedMsgReduction on # keep this on because many distros have set it module(load="../plugins/imfile/.libs/imfile") # mode="polling" pollingInterval="1") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="tag1" ruleset="ruleset1") template(name="tmpl1" type="string" string="%msg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="tmpl1") } action(type="omfile" file=`echo $RSYSLOG2_OUT_LOG`) ' startup_vg_waitpid_only ./msleep 500 # wait a bit so that the error message can be emitted shutdown_immediate wait_shutdown_vg exit_test rsyslog-8.2512.0/tests/PaxHeaders/imdtls-sessionbreak-vg.sh0000644000000000000000000000013215055603742020632 xustar0030 mtime=1756825570.301069108 30 atime=1764931164.424694748 30 ctime=1764935933.880740336 rsyslog-8.2512.0/tests/imdtls-sessionbreak-vg.sh0000775000175000017500000000054015055603742020300 0ustar00rgerrger#!/bin/bash if [ "$(valgrind --version)" == "valgrind-3.11.0" ]; then printf 'This test does NOT work with valgrind-3.11.0 - valgrind always reports\n' printf 'a valgrind-internal bug. So we need to skip it.\n' exit 77 fi export USE_VALGRIND="YES" export RS_TEST_VALGRIND_EXTRA_OPTS="--keep-debuginfo=yes" source ${srcdir:-.}/imdtls-sessionbreak.sh rsyslog-8.2512.0/tests/PaxHeaders/omudpspoof_errmsg_no_params.sh0000644000000000000000000000013215035412264022042 xustar0030 mtime=1752569012.406709056 30 atime=1764931164.334693305 30 ctime=1764935933.854739938 rsyslog-8.2512.0/tests/omudpspoof_errmsg_no_params.sh0000775000175000017500000000056315035412264021515 0ustar00rgerrger#!/bin/bash # add 2019-04-15 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/omudpspoof/.libs/omudpspoof") action(type="omfile" file="'$RSYSLOG_OUT_LOG'") action(type="omudpspoof") ' startup shutdown_when_empty wait_shutdown content_check "parameter 'target' required but not specified" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile-whitespace-filename.sh0000644000000000000000000000013115035412264021413 xustar0030 mtime=1752569012.402736851 30 atime=1764931160.725635426 29 ctime=1764935932.82072411 rsyslog-8.2512.0/tests/omfile-whitespace-filename.sh0000775000175000017500000000070315035412264021063 0ustar00rgerrger#!/bin/bash # addd 2018-04-03 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' action(type="omfile" file=" ") action(type="omfile" file=`echo $RSYSLOG_OUT_LOG`) ' startup shutdown_when_empty wait_shutdown grep "only of whitespace" $RSYSLOG_OUT_LOG > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-start.sh0000644000000000000000000000013015035412264017513 xustar0030 mtime=1752569012.385854976 28 atime=1764931162.3636617 30 ctime=1764935933.290731304 rsyslog-8.2512.0/tests/clickhouse-start.sh0000775000175000017500000000166715035412264017176 0ustar00rgerrger#!/bin/bash # This is not a real test, but a script to start clickhouse. It is # implemented as test so that we can start clickhouse at the time we need # it (do so via Makefile.am). # Copyright (C) 2018 Pascal Withopf and Adiscon GmbH # Released under ASL 2.0 . ${srcdir:=.}/diag.sh init set -x if [ "$CLICKHOUSE_START_CMD" == "" ]; then exit_test # no start needed fi test_error_exit_handler() { printf 'clickhouse startup failed, log is:\n' $SUDO cat /var/log/clickhouse-server/clickhouse-server.err.log } printf 'starting clickhouse...\n' $CLICKHOUSE_START_CMD & sleep 10 #wait_startup_pid /var/run/clickhouse-server/clickhouse-server.pid printf 'preparing clickhouse for testbench use...\n' $SUDO ${srcdir}/../devtools/prepare_clickhouse.sh clickhouse-client --query="select 1" rc=$? if [ $rc -ne 0 ]; then printf 'clickhouse failed to start, exit code %d\n' $rc error_exit 100 fi printf 'done, clickhouse ready for testbench\n' exit_test rsyslog-8.2512.0/tests/PaxHeaders/imbatchreport_rename_success.sh0000644000000000000000000000013215035412264022153 xustar0030 mtime=1752569012.390820233 30 atime=1764931158.153594152 30 ctime=1764935932.110713242 rsyslog-8.2512.0/tests/imbatchreport_rename_success.sh0000775000175000017500000000572515035412264021633 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' # 804/805 fail/sent with space dedup global(maxmessagesize="820") module(load="../contrib/imbatchreport/.libs/imbatchreport" pollinginterval="1") global(localhostname="server") input(type="imbatchreport" ruleset="ruleset" tag="batch" severity="info" facility="local0" reports="./'$RSYSLOG_DYNNAME'*.done" deduplicatespace="on" programkey="KSH" timestampkey="START" rename=".done$ .sent .rejected" ) ruleset(name="ruleset") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="RSYSLOG_SyslogProtocol23Format") } ' { echo '164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)' echo '164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree' echo '164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)' echo '164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree' echo '164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)' echo '164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1' } > $RSYSLOG_DYNNAME.rsu.done case $(uname) in FreeBSD) datelog=$(date -ur $(stat -f %m $RSYSLOG_DYNNAME.rsu.done) "+%Y-%m-%dT%H:%M:%S") ;; *) datelog=$(date "+%Y-%m-%dT%H:%M:%S" -ud @$(stat -c "%Y" $RSYSLOG_DYNNAME.rsu.done)) ;; esac echo "Batch report to consume ${RSYSLOG_DYNNAME}.rsu.done for ${datelog}" startup shutdown_when_empty wait_shutdown export EXPECTED='<134>1 '${datelog}'.000000+00:00 server batch - - - 164313.149.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.150.tst-tmsm1!ARTIMPP_UDB.40042721.1.0: gtrid x0 x5624ee75 x1c88a0f: TRACE:at: } tpfree\n164313.151.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02B003UF^>: TRACE:at: { tpcommit(0x0)\n164313.152.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: gtrid x0 x5624ee75 x1c88a0f: ECID <000001833E1D4i^5pVl3iY00f02M003UF^>: TRACE:at: } tpfree\n164313.153.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003VF^>: TRACE:at: { tpacall("ARTIGW_SVC_REPLY_00700_02101", 0x110405698, 0, 0xc)\n164313.154.tst-tmsm1!ARTIMPP_UDB.40042722.1.0: ECID <000001833E1D4i^5pVl3iY00f02M003SF^>: TRACE:at: } tpcommit = 1' cmp_exact if [ -e $RSYSLOG_DYNNAME.rsu.done ] || [ -e $RSYSLOG_DYNNAME.rsu.rejected ] || [ ! -e $RSYSLOG_DYNNAME.rsu.sent ]; then echo "The batch report could not be renamed" ls $RSYSLOG_DYNNAME* error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/imhttp-post-payload-compress-vg.sh0000644000000000000000000000013115055602574022421 xustar0030 mtime=1756824956.030451456 30 atime=1764931164.767700247 29 ctime=1764935933.97574179 rsyslog-8.2512.0/tests/imhttp-post-payload-compress-vg.sh0000775000175000017500000000025015055602574022066 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" #export RS_TEST_VALGRIND_EXTRA_OPTS="--leak-check=full --show-leak-kinds=all" source ${srcdir:-.}/imhttp-post-payload-compress.sh rsyslog-8.2512.0/tests/PaxHeaders/omrabbitmq_error_server3.sh0000644000000000000000000000013215071746523021260 xustar0030 mtime=1760021843.903422011 30 atime=1764931160.901638249 30 ctime=1764935932.871724891 rsyslog-8.2512.0/tests/omrabbitmq_error_server3.sh0000775000175000017500000000312615071746523020731 0ustar00rgerrger#!/bin/bash # add 2019-09-03 by Philippe Duveau, released under ASL 2.0 . ${srcdir:=.}/diag.sh init cmd="./miniamqpsrvr -b 2 -f $RSYSLOG_DYNNAME.amqp.log -w 500 -d" echo $cmd eval $cmd > $RSYSLOG_DYNNAME.source if [ ! $? -eq 0 ]; then exit 77 fi . $RSYSLOG_DYNNAME.source export OMRABBITMQ_TEST=2000 generate_conf add_conf ' global(localhostname="server") module(load="../contrib/omrabbitmq/.libs/omrabbitmq") template(name="rkTpl" type="string" string="%syslogtag%.%syslogfacility-text%.%syslogpriority-text%") # rfc5424 without Timestamp : unable to manage template(name="bodyTpl" type="string" string="<%PRI%>1 %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg:2:$%\n") ruleset(name="rmq") { action(type="omrabbitmq" host="localhost:'$PORT_AMQP1' localhost:'$PORT_AMQP2'" port="5672" user="mtr" password="mtr" exchange="in" expiration="5000" body_template="" content_type="rfc5424" virtual_host="/metrologie" routing_key_template="rkTpl" populate_properties="on" delivery_mode="transient" ) } if $msg contains "msgrmq" then { call rmq } action(type="omfile" file="'$RSYSLOG_OUT_LOG'") ' startup injectmsg literal "<167>Mar 1 01:00:00 192.0.2.8 tag msgrmq" shutdown_when_empty wait_shutdown export EXPECTED='Exchange:in, routing-key:tag.local4.debug, content-type:plain/text, facility:local4, severity:debug, hostname:192.0.2.8, fromhost:127.0.0.1, delivery-mode:transient, expiration:5000, timestamp:OK, app-id:tag, msg:<167>Mar 1 01:00:00 192.0.2.8 tag msgrmq' cmp_exact $RSYSLOG_DYNNAME.amqp.log content_check "Connection closed : reconnect" exit_test rsyslog-8.2512.0/tests/PaxHeaders/omfile_both_files_set.sh0000644000000000000000000000013215035412264020555 xustar0030 mtime=1752569012.402736851 30 atime=1764931160.767636099 30 ctime=1764935932.832724293 rsyslog-8.2512.0/tests/omfile_both_files_set.sh0000775000175000017500000000232115035412264020222 0ustar00rgerrger#!/bin/bash # add 2016-11-22 by Pascal Withopf, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="dynafile" type="string" string=`echo $RSYSLOG_OUT_LOG`) template(name="outfmt" type="string" string="-%msg%-\n") :msg, contains, "msgnum:" { action(type="omfile" template="outfmt" file=`echo $RSYSLOG2_OUT_LOG` dynafile="dynafile") } action(type="omfile" file="'${RSYSLOG_DYNNAME}'.errorfile") ' startup tcpflood -m1 -M "\"<129>Mar 10 01:00:00 172.20.245.8 tag: msgnum:1\"" shutdown_when_empty wait_shutdown grep "will use dynafile" ${RSYSLOG_DYNNAME}.errorfile > /dev/null if [ $? -ne 0 ]; then echo echo "FAIL: expected error message not found. ${RSYSLOG_DYNNAME}.errorfile is:" cat ${RSYSLOG_DYNNAME}.errorfile error_exit 1 fi echo '- msgnum:1-' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "unexpected content in $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; if [ -f ${RSYSLOG2_OUT_LOG} ]; then echo "file exists, but should not: ${RSYSLOG2_OUT_LOG}; content:" cat ${RSYSLOG2_OUT_LOG} error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_parse_json-vg.sh0000644000000000000000000000013115035412264020553 xustar0030 mtime=1752569012.411674314 29 atime=1764931159.78162028 30 ctime=1764935932.558720099 rsyslog-8.2512.0/tests/rscript_parse_json-vg.sh0000775000175000017500000000115315035412264020223 0ustar00rgerrger#!/bin/bash # Added 2017-12-09 by Rainer Gerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port") template(name="outfmt" type="string" string="%$!%\n") local4.* { set $.ret = parse_json("{ \"c1\":\"data\" }", "\$!parsed"); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup_vg tcpflood -m1 shutdown_when_empty wait_shutdown_vg check_exit_vg export EXPECTED='{ "parsed": { "c1": "data" } }' cmp_exact $RSYSLOG_OUT_LOG exit_test rsyslog-8.2512.0/tests/PaxHeaders/omhttp-validate-response.py0000644000000000000000000000013215055603742021212 xustar0030 mtime=1756825570.302069124 30 atime=1764931165.094705489 30 ctime=1764935934.066743183 rsyslog-8.2512.0/tests/omhttp-validate-response.py0000664000175000017500000001310115055603742020652 0ustar00rgerrgerimport json import argparse import sys from collections import defaultdict def parse_json_lines_to_memory(file, filename): """Read a file and reconstruct complete JSON objects into a list.""" buffer = "" line_number = 0 parsed_objects = [] for line in file: line_number += 1 buffer += line.strip() try: # Attempt to parse the JSON object parsed_objects.append(json.loads(buffer)) buffer = "" # Clear the buffer after successful parsing except json.JSONDecodeError: # If parsing fails, keep buffering lines continue if buffer: # If there's leftover data in the buffer, raise an error raise ValueError( f"Incomplete JSON object found at the end of the file '{filename}'. " f"Last buffered content: {buffer}" ) return parsed_objects if __name__ == '__main__': parser = argparse.ArgumentParser(description='Validate and process log files for errors and responses.') parser.add_argument('--error', action='store', type=str, required=True, help='Path to the error file.') parser.add_argument('--response', action='store', type=str, required=True, help='Path to the response file.') parser.add_argument('--max-errors', action='store', type=int, default=10, help='Maximum number of errors to display.') args = parser.parse_args() messages = defaultdict(dict) errors = [] # Collect errors for reporting at the end # Load the error file into memory try: with open(args.error, "r") as error_f: error_data = parse_json_lines_to_memory(error_f, args.error) for json_obj in error_data: try: records = json.loads(json_obj['request']['postdata']) if records: for i, val in enumerate(records['records']): msgnum = val['value']['msgnum'] messages[msgnum]['response'] = json_obj['response'] messages[msgnum]['index'] = i except KeyError as e: errors.append( f"Missing key {e} in error file '{args.error}'. " f"Problematic JSON object: {json_obj}" ) except json.JSONDecodeError as e: errors.append( f"Error decoding 'postdata' in error file '{args.error}'. " f"Content: {json_obj['request']['postdata']}. Error: {e}" ) except FileNotFoundError as e: errors.append(f"File not found: {args.error}. Please check the file path.") except ValueError as e: errors.append(str(e)) # Load the response file into memory try: with open(args.response, "r") as response_f: response_data = parse_json_lines_to_memory(response_f, args.response) for json_obj in response_data: try: msgnum = json_obj['message']['msgnum'] code = json_obj['response']['code'] body = json_obj['response']['body'] batch_index = json_obj['response']['batch_index'] if msgnum not in messages: errors.append( f"Message {msgnum} in response file '{args.response}' " f"does not exist in the error file '{args.error}'." ) continue if messages[msgnum]['response']['status'] != code: errors.append( f"Status code mismatch for message {msgnum}:\n" f" Expected: {messages[msgnum]['response']['status']}\n" f" Found: {code}\n" f" Context: {json_obj}" ) if messages[msgnum]['response']['message'] != body: errors.append( f"Message body mismatch for message {msgnum}:\n" f" Expected: {messages[msgnum]['response']['message']}\n" f" Found: {body}\n" f" Context: {json_obj}" ) if messages[msgnum]['index'] != batch_index: errors.append( f"Batch index mismatch for message {msgnum}:\n" f" Expected: {messages[msgnum]['index']}\n" f" Found: {batch_index}\n" f" Context: {json_obj}" ) except KeyError as e: errors.append( f"Missing key {e} in response file '{args.response}'. " f"Problematic JSON object: {json_obj}" ) except FileNotFoundError as e: errors.append(f"File not found: {args.response}. Please check the file path.") except ValueError as e: errors.append(str(e)) # Report errors, limited by --max-errors if errors: print(f"Validation completed with {len(errors)} errors. Showing the first {min(len(errors), args.max_errors)} errors:\n") for error in errors[:args.max_errors]: print(f"- {error}") # Exit with non-zero code to indicate errors sys.exit(1) else: print("Validation completed successfully. No errors found.") # Exit with zero code to indicate success sys.exit(0) rsyslog-8.2512.0/tests/PaxHeaders/imtcp-msg-truncation-on-number2.sh0000644000000000000000000000013215035412264022277 xustar0030 mtime=1752569012.396778542 30 atime=1764931162.928670761 30 ctime=1764935933.451733769 rsyslog-8.2512.0/tests/imtcp-msg-truncation-on-number2.sh0000775000175000017500000000320715035412264021750 0ustar00rgerrger#!/bin/bash # addd 2016-05-13 by RGerhards, released under ASL 2.0 . ${srcdir:=.}/diag.sh init generate_conf add_conf ' $MaxMessageSize 128 global(processInternalMessages="on") module(load="../plugins/imtcp/.libs/imtcp") input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port" ruleset="ruleset1") template(name="templ1" type="string" string="%rawmsg%\n") ruleset(name="ruleset1") { action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="templ1") } ' startup tcpflood -m2 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"214000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"41 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"2000000010 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"4000000000 <120> 2011-03-01T11:22:12Z host msgnum:1\"" tcpflood -m1 -M "\"0 <120> 2011-03-01T11:22:12Z host msgnum:1\"" shutdown_when_empty wait_shutdown echo '<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 214000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 214000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1 2000000010<120> 2011-03-01T11:22:12Z host msgnum:1 4000000000<120> 2011-03-01T11:22:12Z host msgnum:1 <120> 2011-03-01T11:22:12Z host msgnum:1' | cmp - $RSYSLOG_OUT_LOG if [ ! $? -eq 0 ]; then echo "invalid response generated, $RSYSLOG_OUT_LOG is:" cat $RSYSLOG_OUT_LOG error_exit 1 fi; exit_test rsyslog-8.2512.0/tests/PaxHeaders/es-bulk-errfile-popul-def-interleaved.sh0000644000000000000000000000013215103346332023410 xustar0030 mtime=1762512090.633176003 30 atime=1764931162.654666367 30 ctime=1764935933.368732499 rsyslog-8.2512.0/tests/es-bulk-errfile-popul-def-interleaved.sh0000775000175000017500000000261115103346332023057 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init require_plugin imfile ensure_elasticsearch_ready init_elasticsearch echo '{ "name" : "foo" } {"name": bar"} {"name": "baz"} {"name": foz"}' > $RSYSLOG_DYNNAME.inESData.inputfile generate_conf add_conf ' global(workDirectory="'$RSYSLOG_DYNNAME.spool'") # Note: we must mess up with the template, because we can not # instruct ES to put further constraints on the data type and # values. So we require integer and make sure it is none. template(name="tpl" type="list") { constant(value="{\"") property(name="$!key") constant(value="\":") property(name="$!obj") constant(value="}") } module(load="../plugins/omelasticsearch/.libs/omelasticsearch") module(load="../plugins/imfile/.libs/imfile") ruleset(name="foo") { set $!key = "my_obj"; set $!obj = $msg; action(type="omelasticsearch" template="tpl" searchIndex="rsyslog_testbench" serverport="19200" bulkmode="on" errorFile="./'${RSYSLOG_DYNNAME}'.errorfile" interleaved="on") } input(type="imfile" File="'$RSYSLOG_DYNNAME.'inESData.inputfile" Tag="foo" Severity="info" ruleset="foo") ' startup shutdown_when_empty wait_shutdown $PYTHON $srcdir/elasticsearch-error-format-check.py interleaved if [ $? -ne 0 ] then echo "error: Format for error file different! " $? exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/imfile-readmode2-with-persists-data-during-stop.sh0000644000000000000000000000013115035412264025340 xustar0030 mtime=1752569012.392806336 29 atime=1764931165.71371541 30 ctime=1764935934.251746015 rsyslog-8.2512.0/tests/imfile-readmode2-with-persists-data-during-stop.sh0000775000175000017500000000474215035412264025017 0ustar00rgerrger#!/bin/bash # This is part of the rsyslog testbench, licensed under ASL 2.0 . $srcdir/diag.sh check-inotify . ${srcdir:=.}/diag.sh init generate_conf add_conf ' global(workDirectory="'${RSYSLOG_DYNNAME}'.spool") module(load="../plugins/imfile/.libs/imfile") input(type="imfile" File="./'$RSYSLOG_DYNNAME'.input" Tag="file:" ReadMode="2") template(name="outfmt" type="list") { constant(value="HEADER ") property(name="msg" format="json") constant(value="\n") } if $msg contains "msgnum:" then action( type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt" ) ' startup # write the beginning of the file echo 'msgnum:0 msgnum:1' > $RSYSLOG_DYNNAME.input echo 'msgnum:2' >> $RSYSLOG_DYNNAME.input # sleep a little to give rsyslog a chance to begin processing sleep 1 # now stop and restart rsyslog so that the file info must be # persisted and read again on startup. Results should still be # correct ;) echo stopping rsyslog shutdown_when_empty wait_shutdown # write some more lines - we want to check here if the initial # polling loop properly picks up that data. Note that even in # inotify case we do have one polling loop at startup, as this # is required to find data written while we were stopped. ls -l ${RSYSLOG_DYNNAME}.spool echo 'msgnum:3 msgnum:4' >> $RSYSLOG_DYNNAME.input echo restarting rsyslog startup echo restarted rsyslog, continuing with test echo ' msgnum:5' >> $RSYSLOG_DYNNAME.input echo 'msgnum:6 msgnum:7 msgnum:8' >> $RSYSLOG_DYNNAME.input #msgnum:8 must NOT be written as it is unfinished # give it time to finish sleep 1 shutdown_when_empty # shut down rsyslogd when done processing messages wait_shutdown # we need to wait until rsyslogd is finished! # give it time to write the output file sleep 1 ## check if we have the correct number of messages NUMLINES=$(grep -c HEADER $RSYSLOG_OUT_LOG 2>/dev/null) if [ -z $NUMLINES ]; then echo "ERROR: expecting at least a match for HEADER, maybe $RSYSLOG_OUT_LOG wasn't even written?" cat $RSYSLOG_OUT_LOG error_exit 1 else if [ ! $NUMLINES -eq 4 ]; then echo "ERROR: expecting 4 headers, got $NUMLINES" cat $RSYSLOG_OUT_LOG error_exit 1 fi fi ## check if all the data we expect to get in the file is there for i in {1..7}; do grep msgnum:$i $RSYSLOG_OUT_LOG > /dev/null 2>&1 if [ ! $? -eq 0 ]; then echo "ERROR: expecting the string 'msgnum:$i', it's not there" cat $RSYSLOG_OUT_LOG error_exit 1 fi done ## if we got here, all is good :) exit_test rsyslog-8.2512.0/tests/PaxHeaders/rscript_ge_var.sh0000644000000000000000000000013215035412264017242 xustar0030 mtime=1752569012.410681262 30 atime=1764931159.396614101 30 ctime=1764935932.463718645 rsyslog-8.2512.0/tests/rscript_ge_var.sh0000775000175000017500000000330715035412264016714 0ustar00rgerrger#!/bin/bash # added 2014-01-17 by rgerhards # This file is part of the rsyslog project, released under ASL 2.0 echo =============================================================================== echo \[rscript_ge.sh\]: testing rainerscript GE statement for two JSON variables . ${srcdir:=.}/diag.sh init generate_conf add_conf ' template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } set $!var1 = "42"; set $!var2 = "42"; set $!var3 = "41"; if $!var1 >= $!var2 and $!var1 >= $!var3 then { if $!var3 >= $!var1 then { # Failure stop } else { unset $!var1; unset $!var2; unset $!var3; } } else { # Failure stop } set $.var1 = "42"; set $.var2 = "42"; set $.var3 = "41"; if $.var1 >= $.var2 and $.var1 >= $.var3 then { if $.var3 >= $.var1 then { # Failure stop } else { unset $.var1; unset $.var2; unset $.var3; } } else { # Failure stop } set $/var1 = "42"; set $/var2 = "42"; set $/var3 = "41"; if $/var1 >= $/var2 and $/var1 >= $/var3 then { if $/var3 >= $/var1 then { # Failure stop } else { unset $/var1; unset $/var2; unset $/var3; } } else { # Failure stop } if $msg contains "msgnum" then { set $!usr!msgnum = field($msg, 58, 2); action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt") } ' startup injectmsg 0 1 echo doing shutdown shutdown_when_empty echo wait on shutdown wait_shutdown seq_check 0 0 exit_test rsyslog-8.2512.0/tests/PaxHeaders/omprog-single-instance.sh0000644000000000000000000000013115055602574020623 xustar0029 mtime=1756824956.03645154 30 atime=1764931165.228707636 30 ctime=1764935934.107743811 rsyslog-8.2512.0/tests/omprog-single-instance.sh0000775000175000017500000000364015055602574020276 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 # This test tests the omprog 'forceSingleInstance' flag by checking # that only one instance of the program is started when multiple # workers are in effect. . ${srcdir:=.}/diag.sh init skip_platform "SunOS" "This test currently does not work on Solaris " export NUMMESSAGES=10000 # number of logs to send export QUEUE_EMPTY_CHECK_FUNC=wait_file_lines generate_conf add_conf ' module(load="../plugins/omprog/.libs/omprog") template(name="outfmt" type="string" string="%msg%\n") :msg, contains, "msgnum:" { action( type="omprog" binary="'$srcdir'/testsuites/omprog-single-instance-bin.sh" template="outfmt" name="omprog_action" confirmMessages="on" forceSingleInstance="on" queue.type="LinkedList" # use a dedicated queue queue.workerThreads="10" # ...with multiple workers queue.size="5000" # ...high capacity (default is 1000) queue.timeoutShutdown="30000" # ...and a long shutdown timeout ) } ' startup injectmsg shutdown_when_empty wait_shutdown EXPECTED_LINE_LENGTH=25 # example line: 'Received msgnum:00009880:' line_num=0 while IFS= read -r line; do ((line_num++)) if (( line_num == 1 )); then if [[ "$line" != "Starting" ]]; then echo "unexpected first line in output: $line" error_exit 1 fi elif (( line_num == NUMMESSAGES + 2 )); then if [[ "$line" != "Terminating" ]]; then echo "unexpected last line in output: $line" error_exit 1 fi elif [[ ${#line} != $EXPECTED_LINE_LENGTH ]]; then echo "unexpected line in output (line $line_num): $line" error_exit 1 fi done < $RSYSLOG_OUT_LOG if (( line_num != NUMMESSAGES + 2 )); then echo "unexpected line count in output: $line_num (expected: $((NUMMESSAGES + 2)))" error_exit 1 fi exit_test rsyslog-8.2512.0/tests/PaxHeaders/pgsql-template-vg.sh0000644000000000000000000000013215035412264017602 xustar0030 mtime=1752569012.407702108 30 atime=1764931168.712763463 30 ctime=1764935935.118759286 rsyslog-8.2512.0/tests/pgsql-template-vg.sh0000775000175000017500000000151215035412264017250 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under GPLv3 . ${srcdir:=.}/diag.sh init psql -h localhost -U postgres -f testsuites/pgsql-basic.sql generate_conf add_conf ' # putting the message in the SyslogTag field, so we know the template is actually used $template mytemplate,"insert into SystemEvents (SysLogTag) values ' add_conf "('%msg%')" add_conf '",STDSQL $ModLoad ../plugins/ompgsql/.libs/ompgsql :msg, contains, "msgnum:" :ompgsql:127.0.0.1,syslogtest,postgres,testbench;mytemplate ' startup_vg injectmsg 0 5000 shutdown_when_empty wait_shutdown_vg check_exit_vg psql -h localhost -U postgres -d syslogtest -f testsuites/pgsql-select-syslogtag.sql -t -A > $RSYSLOG_OUT_LOG seq_check 0 4999 echo cleaning up test database psql -h localhost -U postgres -c 'DROP DATABASE IF EXISTS syslogtest;' exit_test rsyslog-8.2512.0/tests/PaxHeaders/clickhouse-load-vg.sh0000644000000000000000000000013115035412264017710 xustar0030 mtime=1752569012.385854976 29 atime=1764931162.47466348 30 ctime=1764935933.319731748 rsyslog-8.2512.0/tests/clickhouse-load-vg.sh0000775000175000017500000000011515035412264017355 0ustar00rgerrger#!/bin/bash export USE_VALGRIND="YES" source ${srcdir:-.}/clickhouse-load.sh rsyslog-8.2512.0/tests/PaxHeaders/es-basic-vgthread.sh0000644000000000000000000000013115071746523017530 xustar0030 mtime=1760021843.884421711 30 atime=1764931162.552664731 29 ctime=1764935933.34073207 rsyslog-8.2512.0/tests/es-basic-vgthread.sh0000775000175000017500000000144315071746523017202 0ustar00rgerrger#!/bin/bash # This file is part of the rsyslog project, released under ASL 2.0 . ${srcdir:=.}/diag.sh init export ES_PORT=19200 export NUMMESSAGES=5000 # test is pretty slow, so use a low number export QUEUE_EMPTY_CHECK_FUNC=es_shutdown_empty_check ensure_elasticsearch_ready init_elasticsearch generate_conf add_conf ' template(name="tpl" type="string" string="{\"msgnum\":\"%msg:F,58:2%\"}") module(load="../plugins/omelasticsearch/.libs/omelasticsearch") if $msg contains "msgnum:" then { action(type="omelasticsearch" server="127.0.0.1" serverport=`echo $ES_PORT` template="tpl" searchIndex="rsyslog_testbench") } ' startup_vgthread injectmsg shutdown_when_empty wait_shutdown_vg check_exit_vg es_getdata seq_check exit_test rsyslog-8.2512.0/tests/PaxHeaders/elasticsearch-error-format-check.py0000644000000000000000000000013215035412264022551 xustar0030 mtime=1752569012.387841078 30 atime=1764931162.510664058 30 ctime=1764935933.329731901 rsyslog-8.2512.0/tests/elasticsearch-error-format-check.py0000664000175000017500000001064415035412264022222 0ustar00rgerrgerimport json import sys import os def checkDefaultErrorFile(): with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file: json_data = json.load(json_file) indexCount =0 replyCount=0 for item in json_data: if item == "request": for reqItem in json_data[item]: if reqItem == "url": print("url found") print(reqItem) elif reqItem == "postdata": print("postdata found") indexCount = str(json_data[item]).count('\"_index\":') print(reqItem) else: print(reqItem) print("Unknown item found") sys.exit(1) elif item == "reply": for replyItem in json_data[item]: if replyItem == "items": print(json_data[item][replyItem]) replyCount = str(json_data[item][replyItem]).count('_index') elif replyItem == "errors": print("error node found") elif replyItem == "took": print("took node found") else: print(replyItem) print("Unknown item found") sys.exit(3) else: print(item) print("Unknown item found") print("error") sys.exit(4) if replyCount == indexCount : return 0 else: sys.exit(7) return 0 def checkErrorOnlyFile(): with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file: json_data = json.load(json_file) indexCount =0 replyCount=0 for item in json_data: if item == "request": print(json_data[item]) indexCount = str(json_data[item]).count('\"_index\":') elif item == "url": print("url found") elif item == "reply": print(json_data[item]) replyCount = str(json_data[item]).count('\"_index\":') else: print(item) print("Unknown item found") print("error") sys.exit(4) if replyCount == indexCount : return 0 else: sys.exit(7) return 0 def checkErrorInterleaved(): with open(os.environ['RSYSLOG_DYNNAME'] + ".errorfile") as json_file: json_data = json.load(json_file) indexCount =0 replyCount=0 for item in json_data: print(item) if item == "response": for responseItem in json_data[item]: print(responseItem) for res in responseItem: print(res) if res == "request": print(responseItem[res]) indexCount = str(responseItem[res]).count('\"_index\":') print("request count ", indexCount) elif res == "reply": print(responseItem[res]) replyCount = str(responseItem[res]).count('\"_index\":') print("reply count ", replyCount) else: print(res) print("Unknown item found") sys.exit(9) if replyCount != indexCount : sys.exit(8) elif item == "url": print("url found") else: print(item) print("Unknown item found") sys.exit(4) return 0 def checkInterleaved(): return checkErrorInterleaved() if __name__ == "__main__": option = sys.argv[1] if option == "default": checkDefaultErrorFile() elif option == "erroronly": checkErrorOnlyFile() elif option == "errorinterleaved": checkErrorInterleaved() elif option == "interleaved": checkErrorInterleaved() else: print("Usage: )', r'\1\n ' ) ] fixed_count = 0 for html_file in html_files: try: with open(html_file, 'r', encoding='utf-8') as f: content = f.read() original_content = content # Apply fixes for pattern, replacement in fixes: content = re.sub(pattern, replacement, content) # Only write if content changed if content != original_content: with open(html_file, 'w', encoding='utf-8') as f: f.write(content) fixed_count += 1 print(f"Fixed: {html_file.relative_to(html_path)}") except Exception as e: print(f"Error processing {html_file}: {e}") print(f"\nFixed {fixed_count} HTML files for offline Mermaid viewing") print("Note: ELK layout functionality is not available in offline mode") return True def main(): if len(sys.argv) != 2: print("Usage: python3 doc/tools/fix-mermaid-offline.py ") print("Example: python3 doc/tools/fix-mermaid-offline.py doc/build/html") sys.exit(1) html_dir = sys.argv[1] if fix_mermaid_offline(html_dir): print("\n✅ Mermaid offline fix completed successfully!") print("You can now open HTML files directly in your browser without CORS issues.") else: print("\n⌠Mermaid offline fix failed!") sys.exit(1) if __name__ == "__main__": main() rsyslog-8.2512.0/doc/tools/PaxHeaders/README.md0000644000000000000000000000013115055603742015723 xustar0029 mtime=1756825570.26606854 30 atime=1764865110.869065362 30 ctime=1764935922.873571834 rsyslog-8.2512.0/doc/tools/README.md0000664000175000017500000000016415055603742015371 0ustar00rgerrgerThis directory contains tools primarily of use for maintainers or people who want to build the doc (on a schedule). rsyslog-8.2512.0/doc/tools/PaxHeaders/buildenv0000644000000000000000000000013215114544362016176 xustar0030 mtime=1764935922.887572049 30 atime=1764935930.264684983 30 ctime=1764935922.887572049 rsyslog-8.2512.0/doc/tools/buildenv/0000775000175000017500000000000015114544362015717 5ustar00rgerrgerrsyslog-8.2512.0/doc/tools/buildenv/PaxHeaders/tools0000644000000000000000000000013215114544362017336 xustar0030 mtime=1764935922.899572233 30 atime=1764935930.378686728 30 ctime=1764935922.899572233 rsyslog-8.2512.0/doc/tools/buildenv/tools/0000775000175000017500000000000015114544362017057 5ustar00rgerrgerrsyslog-8.2512.0/doc/tools/buildenv/tools/PaxHeaders/git-clone0000644000000000000000000000013115055603742021220 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.366130737 30 ctime=1764935922.894572156 rsyslog-8.2512.0/doc/tools/buildenv/tools/git-clone0000664000175000017500000000061115055603742020663 0ustar00rgerrgerif [ ! -e /rsyslog-doc ]; then echo "ERROR: /rsyslog-doc is either not mounted or does not point to correct path" source tools/help exit 1 fi if [ -e /rsyslog-doc/source ]; then echo "ERROR: /rsyslog-doc contains a source directory, so we cannot clone into it" source tools/help exit 1 fi cd / git clone https://github.com/rsyslog/rsyslog-doc.git (cd /rsyslog-doc; git checkout $BRANCH) rsyslog-8.2512.0/doc/tools/buildenv/tools/PaxHeaders/help0000644000000000000000000000013115055603742020267 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.374130866 30 ctime=1764935922.897572202 rsyslog-8.2512.0/doc/tools/buildenv/tools/help0000664000175000017500000000312615055603742017736 0ustar00rgerrgerecho 'docker run -v /your/local/path:/rsyslog-doc command where command is one of: build-doc - generate documentation (currently HTML only) help - display this help message bash - start an interactive shell (-d terminates) version-info - outputs some information of component used in container git-clone - clone the official rsyslog-doc project into /rsyslog mount this is a quick way to populate /rsyslog, which must be empty before Environment variables (set with -eVAR=val on docker run): FORMAT - html (default) or another builder format STRICT - options to cause strict sphinx mode (default "-n -W") DEBUG - set to "on" to turn on some minimal container debugging SPHINX_EXTRA_OPTS - provides any option to sphinx the user wishes, e.g. -q for quiet builds bind mounts (mount with -v/local/path:/container on docker run): /output - output files will be placed here. If not mounted, output will be under /rsyslog-doc/output /rsyslog-doc - checked-out rsyslog doc project; if not mounted but /output is, an automatic git clone is done to a temporary volume An alternate way to specify extra options is by adding them, one per line, to the SPHINX_EXTRA_OPTS file. The name must be exactly as given, and it must be stored in the doc project home directory. This method is especially useful for complex options which otherwise might be hard to escape so that the shell does not misinterpret them. If both the file SPHINX_EXTRA_OPTS and the environment variable SPHINX_EXTRA_OPTS are given, both are used. ' rsyslog-8.2512.0/doc/tools/buildenv/tools/PaxHeaders/build-doc0000644000000000000000000000013115055603742021201 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.357130592 30 ctime=1764935922.892572125 rsyslog-8.2512.0/doc/tools/buildenv/tools/build-doc0000664000175000017500000000142615055603742020651 0ustar00rgerrgerif [ ! -e /rsyslog-doc/source ]; then if [ -e /output ]; then source tools/git-clone else echo "ERROR: /rsyslog-doc is either not mounted or does not point to correct path" echo " and /output is also not present, so we do not know what to do" source tools/help exit 1 fi fi if [ -e /output ]; then export OUTPUT=/output else export OUTPUT=build fi cd /rsyslog-doc if [ -e SPHINX_EXTRA_OPTS ]; then export SPHINX_EXTRA_OPTS="$SPHINX_EXTRA_OPTS `cat SPHINX_EXTRA_OPTS`" fi eval sphinx-build $STRICT -b $FORMAT $SPHINX_EXTRA_OPTS source $OUTPUT RESULT=$? # we need to do the chown as we currently cannot select the right user # inside the Dockerfile. Once this is solved, this can go away. # chown -R rsyslog:rsyslog $OUTPUT - need to do this differently... exit $RESULT rsyslog-8.2512.0/doc/tools/buildenv/tools/PaxHeaders/version-info0000644000000000000000000000013115055603742021755 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.383131012 30 ctime=1764935922.899572233 rsyslog-8.2512.0/doc/tools/buildenv/tools/version-info0000664000175000017500000000011015055603742021412 0ustar00rgerrgerecho "Versions used inside this container app:" sphinx-build --version rsyslog-8.2512.0/doc/tools/buildenv/tools/PaxHeaders/bash0000644000000000000000000000013115055603742020254 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.349130463 30 ctime=1764935922.890572095 rsyslog-8.2512.0/doc/tools/buildenv/tools/bash0000664000175000017500000000005415055603742017720 0ustar00rgerrgerecho "You are now in Alpine's ash" /bin/ash rsyslog-8.2512.0/doc/tools/buildenv/PaxHeaders/.dockerignore0000644000000000000000000000013115055603742020730 xustar0029 mtime=1756825570.26606854 30 atime=1764931129.318129963 30 ctime=1764935922.880571942 rsyslog-8.2512.0/doc/tools/buildenv/.dockerignore0000664000175000017500000000002415055603742020371 0ustar00rgerrgertmp* *.tmp README.* rsyslog-8.2512.0/doc/tools/buildenv/PaxHeaders/README.md0000644000000000000000000000013115055603742017533 xustar0029 mtime=1756825570.26606854 30 atime=1764865110.870065378 30 ctime=1764935922.885572018 rsyslog-8.2512.0/doc/tools/buildenv/README.md0000664000175000017500000000042315055603742017177 0ustar00rgerrgerbuild: docker build -t rsyslog/rsyslog_doc_gen . where rsyslog/rsyslog_doc_gen is the tag and the location on dockerhub. Obviously, you need to use something else if you are not a maintainer of that repository. ENV VARS DEBUG - turn on some (minimal) container debugging rsyslog-8.2512.0/doc/tools/buildenv/PaxHeaders/Dockerfile0000644000000000000000000000013215071746523020252 xustar0030 mtime=1760021843.843421065 30 atime=1764931129.325130076 30 ctime=1764935922.882571972 rsyslog-8.2512.0/doc/tools/buildenv/Dockerfile0000664000175000017500000000066415071746523017724 0ustar00rgerrgerFROM alpine LABEL maintainer rgerhards@adiscon.com RUN apk add --no-cache py-pip git RUN pip install sphinx RUN adduser -s /bin/ash -D rsyslog rsyslog \ && echo "rsyslog ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers WORKDIR /home/appliance CMD ["build-doc"] ENTRYPOINT ["/home/appliance/starter.sh"] VOLUME /rsyslog-doc RUN chmod a+w /rsyslog-doc ENV BRANCH="main" \ FORMAT="html" \ STRICT="-n -W" COPY starter.sh ./ COPY tools/* ./tools/ rsyslog-8.2512.0/doc/tools/buildenv/PaxHeaders/starter.sh0000644000000000000000000000013015055603742020273 xustar0029 mtime=1756825570.26606854 29 atime=1764931129.34213035 30 ctime=1764935922.887572049 rsyslog-8.2512.0/doc/tools/buildenv/starter.sh0000775000175000017500000000034315055603742017744 0ustar00rgerrger#!/bin/ash if [ "$DEBUG" == "on" ]; then echo "container in debug mode, environment is: " env set -x fi if [ -f tools/$1 ]; then source tools/$1 else echo "ERROR: command not known: $*" echo source tools/help exit 1 fi rsyslog-8.2512.0/doc/PaxHeaders/requirements.txt0000644000000000000000000000013115114522477016571 xustar0029 mtime=1764926783.00763117 30 atime=1764926784.225661069 30 ctime=1764935920.513535703 rsyslog-8.2512.0/doc/requirements.txt0000664000175000017500000000014715114522477016240 0ustar00rgerrger # Align with conf.py needs_sphinx requirement sphinx>=4.5.0 furo sphinxcontrib.mermaid sphinx-sitemap rsyslog-8.2512.0/doc/PaxHeaders/Makefile0000644000000000000000000000013115114522477014745 xustar0029 mtime=1764926783.00763117 30 atime=1764926784.225661069 30 ctime=1764935920.474535106 rsyslog-8.2512.0/doc/Makefile0000664000175000017500000000323415114522477014414 0ustar00rgerrger# Makefile for rsyslog-doc # # You can set these variables from the command line. SPHINXOPTS := $(SPHINXOPTS) SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build # Function to add parallel jobs from MAKEFLAGS to SPHINXOPTS define add_parallel_jobs $(eval SPHINXOPTS += $(if $(filter -j%,$(SPHINXOPTS)),,$(filter -j%,$(MAKEFLAGS)))) endef .PHONY: help clean html html-with-sitemap singlehtml json alljson help: @$(call add_parallel_jobs) @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) clean: rm -rf "$(BUILDDIR)" html: @$(call add_parallel_jobs) @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @echo "Applying Mermaid offline fix..." @python3 ./tools/fix-mermaid-offline.py "$(BUILDDIR)/html" # Build HTML with sitemap enabled (opt-in) html-with-sitemap: @$(call add_parallel_jobs) @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" -t with_sitemap $(SPHINXOPTS) $(O) @echo "Applying Mermaid offline fix..." @python3 ./tools/fix-mermaid-offline.py "$(BUILDDIR)/html" singlehtml: # -t minimal_build triggers stripped-down config in conf.py @$(call add_parallel_jobs) @$(SPHINXBUILD) -M singlehtml "$(SOURCEDIR)" "$(BUILDDIR)" -t minimal_build $(SPHINXOPTS) -D rst_epilog='' $(O) @echo @echo "Build finished. The minimal single page HTML is in $(BUILDDIR)/singlehtml." json: @$(call add_parallel_jobs) @$(SPHINXBUILD) -b json "$(SOURCEDIR)" "$(BUILDDIR)/json" $(SPHINXOPTS) $(O) alljson: json @$(call add_parallel_jobs) @$(SPHINXBUILD) -b json "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) %: @$(call add_parallel_jobs) @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) rsyslog-8.2512.0/doc/PaxHeaders/source0000644000000000000000000000013215114544362014526 xustar0030 mtime=1764935922.766570196 30 atime=1764935930.174683605 30 ctime=1764935922.766570196 rsyslog-8.2512.0/doc/source/0000775000175000017500000000000015114544362014247 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/PaxHeaders/licensing.rst0000644000000000000000000000013215055603742017312 xustar0030 mtime=1756825570.257068393 30 atime=1764928607.076888303 30 ctime=1764935921.173545808 rsyslog-8.2512.0/doc/source/licensing.rst0000664000175000017500000000603615055603742016763 0ustar00rgerrgerLicensing ========= If you intend to use rsyslog inside a GPLv3 compatible project, you are free to do so. You don't even need to continue reading. If you intend to use rsyslog inside a non-GPLv3 compatible project, rsyslog offers you some liberties to do that, too. However, you then need to study the licensing details in depth. The project hopes this is a good compromise, which also gives a boost to fellow free software developers who release under GPLv3. And now on to the dirty and boring license details, still on a executive summary level. For the real details, check source files and the files COPYING and COPYING.LESSER inside the distribution. The rsyslog package contains several components: - the rsyslog core programs (like rsyslogd) - plugins (like imklog, omrelp, ...) - the rsyslog runtime library Each of these components can be thought of as individual projects. In fact, some of the plugins have different main authors than the rest of the rsyslog package. All of these components are currently put together into a single "rsyslog" package (tarball) for convenience: this makes it easier to distribute a consistent version where everything is included (and in the right versions) to build a full system. Platform package maintainers in general take the overall package and split off the individual components, so that users can install only what they need. In source installations, this can be done via the proper ./configure switches. However, while it is convenient to package all parts in a single tarball, it does not imply all of them are necessarily covered by the same license. Traditionally, GPL licenses are used for rsyslog, because the project would like to provide free software. GPLv3 has been used since around 2008 to help fight for our freedom. All rsyslog core programs are released under GPLv3. But, from the beginning on, plugins were separate projects and we did not impose and license restrictions on them. So even though all plugins that currently ship with the rsyslog package are also placed under GPLv3, this can not taken for granted. You need to check each plugins license terms if in question - this is especially important for plugins that do NOT ship as part of the rsyslog tarball. In order to make rsyslog technology available to a broader range of applications, the rsyslog runtime is, at least partly, licensed under LGPL. If in doubt, check the source file licensing comments. As of now, the following files are licensed under LGPL: - queue.c/.h - wti.c/.h - wtp.c/.h - vm.c/.h - vmop.c/.h - vmprg.c/.h - vmstk.c/.h - expr.c/.h - sysvar.c/.h - ctok.c/.h - ctok\_token.c/.h - regexp.c/.h - sync.c/.h - stream.c/.h - var.c/.h This list will change as time of the runtime modularization. At some point in the future, there will be a well-designed set of files inside a runtime library branch and all of these will be LGPL. Some select extras will probably still be covered by GPL. We are following a similar licensing model in GnuTLS, which makes effort to reserve some functionality exclusively to open source projects. rsyslog-8.2512.0/doc/source/PaxHeaders/getting_started0000644000000000000000000000013015114544361017712 xustar0029 mtime=1764935921.11754495 30 atime=1764935930.262684952 29 ctime=1764935921.11754495 rsyslog-8.2512.0/doc/source/getting_started/0000775000175000017500000000000015114544361017435 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/installation.rst0000644000000000000000000000013215055605325023226 xustar0030 mtime=1756826325.620800245 30 atime=1764928606.067857662 30 ctime=1764935921.112544874 rsyslog-8.2512.0/doc/source/getting_started/installation.rst0000664000175000017500000000140715055605325022674 0ustar00rgerrgerInstalling rsyslog ================== rsyslog is included by default in many Linux distributions. If it is not installed, you can add it with the following commands. On Debian/Ubuntu ---------------- .. code-block:: bash sudo apt update sudo apt install rsyslog rsyslog-doc On RHEL/CentOS -------------- .. code-block:: bash sudo dnf install rsyslog rsyslog-doc Enable and Start the Service ---------------------------- After installation, enable and start rsyslog: .. code-block:: bash sudo systemctl enable rsyslog sudo systemctl start rsyslog Validating the Setup -------------------- To verify your installation and configuration, run: .. code-block:: bash rsyslogd -N1 This checks the configuration syntax without starting the daemon. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/ai-assistants.rst0000644000000000000000000000013115071746523023313 xustar0030 mtime=1760021843.791420244 29 atime=1764928605.68484602 30 ctime=1764935921.087544491 rsyslog-8.2512.0/doc/source/getting_started/ai-assistants.rst0000664000175000017500000000447615071746523022773 0ustar00rgerrger.. _ai-assistants: AI Assistants ============= .. meta:: :audience: beginner :tier: entry :keywords: rsyslog AI assistant, chatgpt, configuration help, troubleshooting, documentation, development .. summary-start Specialized AI helpers for rsyslog tasks: configuration, troubleshooting, documentation, and development. .. summary-end As part of rsyslog’s :doc:`../about/ai_first` strategy, we provide several AI assistants to make setup, configuration, and contribution easier. They are currently implemented as **OpenAI ChatGPT custom GPTs**, which means you need a free OpenAI account to use them. Most users will find the free tier sufficient, but availability may depend on your subscription. The platform may change in the future. General-purpose assistant ------------------------- - **Rsyslog Assistant** – the first stop for all usage, configuration, and troubleshooting questions. 🌠https://rsyslog.ai It can generate working config snippets, explain errors, and guide you through common tasks. While accuracy is usually high, always **verify the results**. Like any AI tool, it can occasionally produce mistakes. Other assistants ---------------- These are more specialized, and mainly interesting for contributors: - **Rsyslog Doc Assistant** Helps documentation writers maintain consistent style and structure. 🌠https://www.rsyslog.com/tool_rsyslog-doc-assistant - **Rsyslog Dev Assistant** For developers, focused on onboarding and codebase exploration. Still experimental (as of Sept 2025). 🌠https://www.rsyslog.com/tool_rsyslog-dev-assistant - **Rsyslog Commit Assistant** Guides developers in crafting commit messages that follow rsyslog’s conventions. 🌠https://www.rsyslog.com/tool_rsyslog-commit-assistant Community feedback ------------------ We are continuously improving these assistants. Suggestions and feedback are very welcome in the `GitHub Discussions `_. If you would like to see a new assistant for a specific use case, please let us know there. Video tips ---------- Some tutorials reference short “🎬 video tipsâ€. These will be added over time. If you would like to contribute tutorial videos to the project, please contact **rgerhards@adiscon.com** or post in the GitHub discussions. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/forwarding_logs.rst0000644000000000000000000000013215055605325023713 xustar0030 mtime=1756826325.620800245 30 atime=1764928606.011855961 30 ctime=1764935921.108544812 rsyslog-8.2512.0/doc/source/getting_started/forwarding_logs.rst0000664000175000017500000000433515055605325023364 0ustar00rgerrgerForwarding Logs =============== rsyslog can forward log messages to remote servers. This is often done to centralize logs, improve analysis, or send data to SIEM or monitoring systems. Minimal Forwarding Example (TCP) -------------------------------- Add the following snippet to your `/etc/rsyslog.conf` or to a file inside `/etc/rsyslog.d/`: .. code-block:: rsyslog # Forward all messages to a remote server using TCP. # The linked-list queue prevents blocking if the server is temporarily unreachable. action( type="omfwd" # Output module for forwarding messages protocol="tcp" # Use TCP (reliable transport) target="logs.example.com" # Destination server (replace with your host) port="514" # TCP port on the remote syslog server queue.type="linkedList" # Best practice for network forwarding ) Why use `queue.type="linkedList"`? ---------------------------------- When a remote server goes offline, a direct TCP forwarding action can block and delay local logging. Using a queue ensures that messages are stored temporarily and sent once the connection recovers. This is a recommended default for TCP-based forwarding. Forwarding via UDP ------------------ UDP is a connectionless protocol and does not block, so queues are not required in this case. To forward messages via UDP, modify the protocol: .. code-block:: rsyslog # Forward all messages to a remote server using UDP. action( type="omfwd" protocol="udp" # UDP (unreliable, but lower overhead) target="logs.example.com" port="514" ) Testing the Connection ---------------------- To verify that logs are reaching the remote server: 1. Send a test message locally: .. code-block:: bash logger "test message from $(hostname)" 2. Check the remote server's logs for the test message. Advanced Queue Tuning --------------------- The default queue parameters work for most cases. For high performance or large bursts of logs, you can adjust settings such as: - `queue.size` – Number of messages stored in the queue. - `queue.dequeueBatchSize` – Number of messages processed per batch. See :doc:`../rainerscript/queue_parameters` for details. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/basic_configuration.rst0000644000000000000000000000013215055605325024535 xustar0030 mtime=1756826325.620800245 30 atime=1764928605.715846963 30 ctime=1764935921.090544537 rsyslog-8.2512.0/doc/source/getting_started/basic_configuration.rst0000664000175000017500000000144515055605325024205 0ustar00rgerrgerBasic Configuration =================== rsyslog reads its main configuration from: ``/etc/rsyslog.conf`` Additional configuration snippets can be placed in: ``/etc/rsyslog.d/*.conf`` Minimal Example --------------- The following configuration logs all messages to `/var/log/syslog`: .. code-block:: rsyslog # Load the input modules for system and kernel logging. module(load="imuxsock") # Local system logs (e.g., from journald) module(load="imklog") # Kernel log capture # Traditionally, a *.* selector ("all logs") is added here. # This is unnecessary, as it is the default behavior. # Therefore, no filter is explicitly shown. action(type="omfile" file="/var/log/syslog") Apply changes by restarting rsyslog: .. code-block:: bash sudo systemctl restart rsyslog rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/beginner_tutorials0000644000000000000000000000013215114544361023613 xustar0030 mtime=1764935921.106544782 30 atime=1764935930.368686575 30 ctime=1764935921.106544782 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/0000775000175000017500000000000015114544361023334 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/05-order-matters.rst0000644000000000000000000000013115071746523027441 xustar0029 mtime=1760021843.79242026 30 atime=1764928605.898852526 30 ctime=1764935921.101544705 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/05-order-matters.rst0000664000175000017500000000570215071746523027112 0ustar00rgerrger.. _tut-05-order-matters: Order Matters: Config and Include Files ####################################### .. meta:: :audience: beginner :tier: entry :keywords: rsyslog order, config sequence, rsyslog.d, stop, discard .. summary-start Learn how rsyslog processes configuration **in order**, why file ordering in ``/etc/rsyslog.d/`` matters, and how earlier rules affect later ones. .. summary-end Goal ==== Understand that rsyslog executes rules **sequentially**. The order of actions and included files can change results. Key principle ============= - Rules in the same file run **top to bottom**. - Files in ``/etc/rsyslog.d/`` are processed in **lexical order** (e.g., ``10-first.conf`` runs before ``50-extra.conf``). - An earlier rule can **discard or modify messages**, so later rules may never see them. Hands-on example ================ 1) Create ``/etc/rsyslog.d/10-drop.conf``: .. code-block:: rsyslog if ($programname == "tut05") then { stop # discard these messages, no further actions } 2) Create ``/etc/rsyslog.d/20-log.conf``: .. code-block:: rsyslog if ($programname == "tut05") then { action(type="omfile" file="/var/log/tut05.log") } 3) Restart rsyslog: .. code-block:: bash sudo systemctl restart rsyslog 4) Send a test message: .. code-block:: bash logger -t tut05 "hello from tutorial 05" Expected result --------------- No file ``/var/log/tut05.log`` is created. The first snippet (`10-drop.conf`) discards the message before the logging rule runs. Switch the order ================ Rename the files to reverse order: .. code-block:: bash sudo mv /etc/rsyslog.d/10-drop.conf /etc/rsyslog.d/50-drop.conf sudo systemctl restart rsyslog logger -t tut05 "hello after reorder" Now ``/var/log/tut05.log`` will contain the message, because the logging rule ran first. If it’s not working… ===================== 1. **Still no log file** - Check snippet order with: ``ls -1 /etc/rsyslog.d/`` - Ensure ``20-log.conf`` comes **before** ``50-drop.conf``. 2. **File exists but is empty** - Confirm you used the correct tag: ``logger -t tut05 "…"`` 3. **Syntax errors** - Validate your config: ``sudo rsyslogd -N1`` Verification checkpoint ======================= By the end of this tutorial you should be able to: - Explain that rsyslog rules run **top to bottom, file by file**. - Use file naming (``10-…``, ``50-…``) to control execution order. - Predict why a later action might never see a message. See also / Next steps ===================== - :doc:`04-message-pipeline` – how messages flow through inputs, rulesets, and actions. - :doc:`../basic_configuration` – reference example of a simple config. - :doc:`../forwarding_logs` – adding network forwarding. ---- .. tip:: 🎬 *Video idea (3 min):* show two snippet files, run ``logger -t tut05 …``, then swap the file order and rerun. Visualize how rsyslog processes files in lexical order. rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/02-first-config.rst0000644000000000000000000000013115071746523027240 xustar0029 mtime=1760021843.79242026 30 atime=1764928605.778848878 30 ctime=1764935921.094544598 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/02-first-config.rst0000664000175000017500000000734115071746523026712 0ustar00rgerrger.. _tut-02-first-config: Your First Configuration ######################## .. meta:: :audience: beginner :tier: entry :keywords: rsyslog first config, logger, omfile, rsyslog.d .. summary-start Write a minimal RainerScript configuration that logs a specific test message to its own file, test it with ``logger``, and verify with ``tail -f`` — without changing distro-provided inputs. .. summary-end Goal ==== Create your first custom rsyslog configuration in modern **RainerScript** syntax. You will add a tiny rule that writes **only your test message** into a new file, so you don’t duplicate all system logs. .. important:: Most distributions already configure inputs (on Ubuntu this is often ``imjournal``, sometimes ``imuxsock``). **Do not load input modules here.** We’ll just add a safe, small rule in ``/etc/rsyslog.d/``. For background, see :doc:`03-default-config`. Steps ===== 1) Create a new config snippet ------------------------------ Create ``/etc/rsyslog.d/10-first.conf`` with this content: .. code-block:: rsyslog # Write only messages tagged "tut02" to a custom file if ($programname == "tut02") then { action(type="omfile" file="/var/log/myfirst.log") # no 'stop' here: allow normal distro handling to continue } Why this approach? ------------------ - We **don’t** touch inputs (distro already set them up). - We **filter by tag** so only your test message goes to the new file, keeping it clean. - We **don’t** use ``stop`` so normal logging continues unchanged. 2) Restart rsyslog ------------------ .. code-block:: bash sudo systemctl restart rsyslog systemctl status rsyslog --no-pager 3) Send a test message ---------------------- Use the ``logger`` command to generate a message with the tag ``tut02``: .. code-block:: bash logger -t tut02 "hello from rsyslog tutorial 02" 4) Verify the result -------------------- Check the new file: .. code-block:: bash sudo tail -f /var/log/myfirst.log You should see your message. The system’s regular logs (e.g., ``/var/log/syslog`` on Ubuntu or ``/var/log/messages`` on RHEL-like distros) continue to work as before. If it’s not working… ===================== 1. **No file created** - Service status: ``systemctl status rsyslog`` - Syntax check: ``sudo rsyslogd -N1`` - Ensure the snippet path is correct: ``/etc/rsyslog.d/10-first.conf`` 2. **File exists but no message inside** - Confirm you used the **exact tag**: ``logger -t tut02 "..."`` - Verify the filter matches: it checks ``$programname == "tut02"`` 3. **Permission denied** - Ensure rsyslog can write to ``/var/log/`` (default root-owned is fine). For custom paths, adjust ownership/permissions (``sudo chown`` / ``chmod``) as needed. 4. **Ubuntu-specific note** - Ubuntu typically uses ``imjournal`` by default. That’s fine — this rule still works. If you previously tried to load inputs manually, remove those lines and restart. Verification checkpoint ======================= By the end of this tutorial you should be able to: - Restart rsyslog without syntax errors. - Send a tagged test message with ``logger``. - See the message in your custom file without duplicating all system logs. See also / Next steps ===================== - :doc:`03-default-config` – why your distribution’s default config uses different syntax, and how to add modern snippets safely alongside it. - :doc:`04-message-pipeline` – understand the flow: input → ruleset → action. - Existing page: :doc:`../basic_configuration` – neutral reference example. ---- .. tip:: 🎬 *Video idea (3 min):* create ``10-first.conf``, restart rsyslog, run ``logger -t tut02 "…"`` and watch ``/var/log/myfirst.log`` update live with ``tail -f``. rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/03-default-config.rst0000644000000000000000000000013115071746523027536 xustar0029 mtime=1760021843.79242026 30 atime=1764928605.818850095 30 ctime=1764935921.096544629 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/03-default-config.rst0000664000175000017500000000712115071746523027204 0ustar00rgerrger.. _tut-03-default-config: Understanding the Default Configuration ####################################### .. meta:: :audience: beginner :tier: entry :keywords: rsyslog default config, imjournal, imuxsock, legacy syntax .. summary-start Why your distro’s default rsyslog config looks “oldâ€, what those lines mean, and how to safely add modern snippets alongside it. .. summary-end Goal ==== Understand why the configuration you see in ``/etc/rsyslog.conf`` may look different from these tutorials, and learn the safe way to extend it without breaking your distribution’s setup. Why it looks different ====================== When you open ``/etc/rsyslog.conf`` on a freshly installed system, you might see directives like: .. code-block:: none *.* /var/log/syslog $FileCreateMode 0640 These come from how Linux distributions ship rsyslog. It is a **compatibility choice** to preserve behavior from older syslog systems. At the same time, the distro config often loads modern modules such as: .. code-block:: rsyslog module(load="imuxsock") module(load="imjournal") This mix of legacy and modern syntax can look confusing. The key point: **both styles work.** For new configs, always use **RainerScript**. Want to know what a legacy line like ``$FileCreateMode`` actually does? You don’t need to learn all of these right now, but if you’re curious, try the `AI rsyslog assistant `_. It can explain individual directives in detail and suggest the modern equivalent. How inputs are handled ====================== - **Ubuntu/Debian** usually load ``imjournal`` (reads from systemd’s journal). - **RHEL/CentOS/Rocky/Alma** often use ``imuxsock`` (reads from the traditional syslog socket). - Some distros load both for maximum compatibility. That is why you should **not reload those same inputs again** in your snippets — the distro already set them up. But if you need to use a **new kind of input**, such as monitoring a text file with ``imfile`` or receiving logs over TCP with ``imtcp``, then you *do* load that module yourself. Adding new inputs is normal; reloading the already configured system inputs is unnecessary. Safe way to add your rules ========================== - **Leave ``/etc/rsyslog.conf`` as it is.** Do not try to “modernize†the legacy lines — rsyslog understands them. - **Add your own rules under ``/etc/rsyslog.d/*.conf``** in RainerScript syntax. Example: .. code-block:: rsyslog # Log all messages from facility 'local3' to a custom log file if ($syslogfacility-text == "local3") then { action(type="omfile" file="/var/log/myapp.log") } Should you convert legacy lines? ================================ No — there is no need. Over time you may choose to migrate, but rsyslog will happily run mixed syntax. Verification checkpoint ======================= By the end of this tutorial you should: - Recognize legacy lines like ``*.* /var/log/syslog``. - Understand why they exist in distro configs. - Know that you should not remove or convert them. - Be confident adding new modern rules in ``/etc/rsyslog.d/``. See also / Next steps ===================== - :doc:`02-first-config` – your first modern snippet. - :doc:`04-message-pipeline` – learn how inputs, rulesets, and actions fit together. - Existing page: :doc:`../understanding_default_config` – neutral reference version. ---- .. tip:: 🎬 *Video idea (2–3 min):* open ``/etc/rsyslog.conf``, highlight the mix of old and new lines, explain why it’s safe, then add a small snippet under ``/etc/rsyslog.d/`` to show the correct workflow. rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/04-message-pipeline.rst0000644000000000000000000000013215103346332030066 xustar0030 mtime=1762512090.626175929 30 atime=1764928605.859851341 30 ctime=1764935921.099544675 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/04-message-pipeline.rst0000664000175000017500000001026715103346332027540 0ustar00rgerrger.. _tut-04-log-pipeline: The Log Pipeline: Inputs → Rulesets → Actions ############################################# .. meta:: :audience: beginner :tier: entry :keywords: rsyslog log pipeline, message pipeline, input, ruleset, action, kafka, output .. summary-start Understand rsyslog’s core architecture: logs enter through **inputs**, are processed by **rulesets**, and end up in one or more **actions** (outputs). This flow is called the **log pipeline** — historically known as the *message pipeline*. .. summary-end Goal ==== Build a correct mental model of rsyslog’s architecture using the **log pipeline**. This helps you predict where to add filters, which actions will run, and why your snippets behave as they do. The three core components ========================= 1. **Inputs** – how logs arrive. Examples: ``imuxsock`` (syslog socket), ``imjournal`` (systemd journal), ``imfile`` (text files). 2. **Rulesets** – the logic in between. They hold filters and actions and decide what happens to each message. 3. **Actions** – where logs go. Examples: files (``omfile``), remote syslog (``omfwd``), or modern targets like Kafka (``omkafka``). Visual model ============ .. mermaid:: flowchart LR A["Inputs"]:::input --> B["Ruleset"]:::ruleset B --> C1["Action 1"]:::action B --> C2["Action 2"]:::action classDef input fill:#d5e8d4,stroke:#82b366; classDef ruleset fill:#dae8fc,stroke:#6c8ebf; classDef action fill:#ffe6cc,stroke:#d79b00; Explanation =========== - **Inputs** feed messages into rsyslog. - Each message enters a **ruleset**, which decides what to do with it. - **Actions** are destinations that execute **in order by default** (serial). Concurrency is possible through per-action queues or worker threads, but that’s an advanced topic. Example: add a second destination ================================= Write messages tagged ``tut04`` to a file *and* forward them: .. code-block:: rsyslog if ($programname == "tut04") then { action(type="omfile" file="/var/log/mypipeline.log") action(type="omfwd" target="logs.example.com" port="514" protocol="udp") } Restart and test: .. code-block:: bash sudo systemctl restart rsyslog logger -t tut04 "hello from rsyslog tutorial 04" sudo tail -n 20 /var/log/mypipeline.log .. note:: Forwarding requires a **second machine** or another rsyslog instance listening on a port. Without a reachable target and without an action queue, rsyslog will retry and may appear “stuck†for a short time before the next attempt. For a proper walkthrough, see :doc:`../forwarding_logs`. Action order and config sequence ================================ - Actions execute **serially in the order they appear**. - Earlier actions can **modify or discard** messages before later ones run. - Include snippets in ``/etc/rsyslog.d/`` are processed in **lexical order** (e.g., ``10-first.conf`` runs before ``50-extra.conf``). - Concurrency can be introduced by giving an action its **own queue** (``action.queue.*``) or by using separate rulesets/workers. See :doc:`05-order-matters` for a hands-on demo of ordering effects. Verification checkpoint ======================= You should now be able to: - Sketch **Input → Ruleset → Actions** from memory. - Recognize where your distro-provided **inputs** attach to the flow. - Understand that **actions** are sequential by default. - Name at least one modern output (e.g., **Kafka**). See also / Next steps ===================== You now understand the basic architecture — the **log pipeline**. To explore more advanced pipeline concepts (branching, staging, queues), see: - :doc:`../../concepts/log_pipeline/stages` - :doc:`../../concepts/log_pipeline/design_patterns` - :doc:`../forwarding_logs` - how forwarding and queues interact. - :doc:`05-order-matters` - ordering and include file sequence. - :doc:`../../concepts/log_pipeline/index` - conceptual overview ---- .. tip:: 🎬 *Video idea (2–3 min):* show the diagram, then run ``logger -t tut04 "…"`` and watch the message hit both the file and the forwarder; highlight that actions execute sequentially by default. rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/index.rst0000644000000000000000000000013215071746523025537 xustar0030 mtime=1760021843.793420276 30 atime=1764928605.977854928 30 ctime=1764935921.106544782 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/index.rst0000664000175000017500000000402015071746523025177 0ustar00rgerrger.. _beginner_tutorials: Beginner Tutorials ################## .. meta:: :audience: beginner :tier: entry :keywords: rsyslog, tutorial, getting started, learning path, message pipeline .. summary-start A guided series of step-by-step tutorials for rsyslog beginners, built around the message pipeline (input → ruleset → action). .. summary-end Welcome to the **Beginner Tutorials**, a curated learning path designed to help you get from zero to a working rsyslog setup quickly and confidently. Each tutorial is: - **Goal-oriented** – solves a single, practical problem. - **Runnable** – includes commented configuration examples. - **Verifiable** – always shows how to test results (e.g., with ``logger``). - **Resilient** – ends with an *If it's not working…* section. We use the **message pipeline metaphor** throughout: rsyslog receives messages through an *input*, processes them in a *ruleset* (filters, parsers, queues), and delivers them to an *action* (e.g., write to file, forward, or database). .. mermaid:: flowchart LR A[Input] --> B[Ruleset] B --> C[Action] This pipeline is the foundation of every tutorial in this series. Some tutorials will also include: - **Optional Docker shortcuts** – useful if Docker is already on your system and you want a quick sandbox environment. - **Companion videos** – short screen-capture demos for steps that are easier to show than to describe (installation, first config, troubleshooting). Upcoming, not yet available. .. note:: The *video tips* included in tutorials exist because we plan to provide these short videos over time. We also highly appreciate community contributions — if you would like to record a companion video, please contact **rgerhards@adiscon.com** or post in the `GitHub discussions `_. ---- .. toctree:: :maxdepth: 1 :numbered: 01-installation 02-first-config 03-default-config 04-message-pipeline 05-order-matters 06-remote-server rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/06-remote-server.rst0000644000000000000000000000013215071746523027452 xustar0030 mtime=1760021843.793420276 30 atime=1764928605.937853712 30 ctime=1764935921.103544736 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/06-remote-server.rst0000664000175000017500000001031415071746523027115 0ustar00rgerrger.. _tut-06-remote-server: Your First Remote Log Server ############################ .. meta:: :audience: beginner :tier: entry :keywords: rsyslog remote server, imudp, log receiver, central logging .. summary-start Set up rsyslog to **receive logs from another machine** over UDP. Use a **dedicated ruleset** so only remote messages go into ``/var/log/remote.log``. .. summary-end Goal ==== Create a basic **remote log receiver**. You will configure rsyslog to listen on UDP/514 and process incoming messages with a separate ruleset, ensuring local logs remain unaffected. .. important:: This tutorial requires **two systems** (or two containers/VMs). One acts as the **server** (receiver), the other as the **client** (sender). Without a second machine, forwarding may appear “stuck†because rsyslog retries. Steps ===== 1) Configure the server (receiver) ---------------------------------- On the receiving system, create ``/etc/rsyslog.d/10-receiver.conf``: .. code-block:: rsyslog # Load UDP input module(load="imudp") # A ruleset just for messages received via this UDP listener ruleset(name="rs-from-udp") { action(type="omfile" file="/var/log/remote.log") # This ruleset is used only for the UDP input below. # Local system logs continue to use the default distro config. } # Assign the UDP input to the ruleset above input(type="imudp" port="514" ruleset="rs-from-udp") Restart rsyslog: .. code-block:: bash sudo systemctl restart rsyslog systemctl status rsyslog --no-pager 2) Configure the client (sender) -------------------------------- On the sending system, create ``/etc/rsyslog.d/10-forward.conf``: .. code-block:: rsyslog # Forward all messages via UDP to the server action( type="omfwd" target="server.example.com" # replace with server hostname or IP port="514" protocol="udp" ) Restart rsyslog on the client: .. code-block:: bash sudo systemctl restart rsyslog 3) Test the setup ----------------- From the **client**, send a test message: .. code-block:: bash logger -t tut06 "hello from the client" On the **server**, check the remote log file: .. code-block:: bash sudo tail -n 20 /var/log/remote.log You should see the test message. Only messages from the client appear here, because the UDP input uses its own ruleset. If it’s not working… ===================== 1. **No messages arrive** - Verify the server is listening on UDP/514: .. code-block:: bash sudo ss -ulpn | grep ':514' - Check firewall rules (``ufw`` or ``firewalld``) to allow UDP/514. - Ensure the client’s ``target=`` hostname/IP is correct (try an IP to rule out DNS). 2. **Messages appear only on the client** - Test network reachability: .. code-block:: bash ping server.example.com - If ICMP/ping is blocked, check with traceroute or review firewall/NAT. 3. **Permission denied on /var/log/remote.log** - Ensure rsyslog has permission to write under ``/var/log/``. - For testing, root-owned files in ``/var/log/`` are fine. 4. **Service won’t start** - Validate configuration on both systems: .. code-block:: bash sudo rsyslogd -N1 Verification checkpoint ======================= By the end of this tutorial you should be able to: - Restart rsyslog cleanly on both client and server. - Send a message with ``logger`` on the client. - See the message arrive in ``/var/log/remote.log`` on the server, without local logs mixed in. See also / Next steps ===================== - :doc:`04-message-pipeline` – how inputs, rulesets, and actions fit together. - :doc:`../forwarding_logs` – more on forwarding (UDP vs TCP) and queues. - Reference: :doc:`../../configuration/modules/imudp` - Reference: :doc:`../../configuration/modules/omfwd` ---- .. note:: Forwarding requires a **reachable** server. Without a valid target (and without an action queue), rsyslog may retry and appear “stuck†for a while. .. tip:: 🎬 *Video idea (3–4 min):* show two terminals (client/server), run ``logger`` on the client, and tail ``/var/log/remote.log`` on the server. Then point out the dedicated ruleset in the config that keeps local logs separate. rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/PaxHeaders/01-installation.rst0000644000000000000000000000013215071746523027347 xustar0030 mtime=1760021843.791420244 30 atime=1764928605.741847753 30 ctime=1764935921.092544567 rsyslog-8.2512.0/doc/source/getting_started/beginner_tutorials/01-installation.rst0000664000175000017500000000740315071746523027017 0ustar00rgerrger.. _tut-01-installation: Installing rsyslog ################## .. meta:: :audience: beginner :tier: entry :keywords: rsyslog install, rsyslog service, rsyslogd -N1, docker .. summary-start Install rsyslog via packages, verify the service, and (optionally) try a Docker sandbox. .. summary-end Goal ==== Get rsyslog installed and confirm it runs correctly on your system. If you prefer a zero-risk sandbox, try the optional Docker approach at the end. .. important:: **About default distro configs:** Many distributions ship legacy-style config lines in ``/etc/rsyslog.conf`` (e.g., ``*.* /var/log/syslog`` or ``$FileCreateMode``). That is **normal** and supported. In these tutorials we use **modern RainerScript**. **Do not rewrite the distro file.** Add your own rules under ``/etc/rsyslog.d/*.conf``. For a guided explanation, see :doc:`03-default-config`. Steps ===== 1) Install the packages ----------------------- On **Ubuntu/Debian**: .. code-block:: bash sudo apt update sudo apt install rsyslog On **RHEL / CentOS / Rocky / Alma**: .. code-block:: bash sudo dnf install rsyslog 2) Enable and start the service ------------------------------- .. code-block:: bash sudo systemctl enable --now rsyslog systemctl status rsyslog --no-pager 3) Validate configuration syntax -------------------------------- Run a dry-run parse to check syntax without launching a second daemon: .. code-block:: bash sudo rsyslogd -N1 You should see **“rsyslogd: End of config validation run.â€** with no errors. Verification ============ Send a test message and ensure rsyslog is processing logs locally: .. code-block:: bash logger -t tut01 "hello from rsyslog tutorial 01" sudo tail -n 50 /var/log/syslog 2>/dev/null || sudo tail -n 50 /var/log/messages You should see a line containing ``tut01`` and your message. If it’s not working… ===================== 1. **Service not active** - Check: ``systemctl status rsyslog`` - Fix: ``sudo systemctl restart rsyslog`` 2. **Syntax errors** - Run: ``sudo rsyslogd -N1`` - Read the first error carefully; it points to the file/line. Remove the offending change or fix the typo, then re-run. 3. **Logs not visible** - Different distros write to different files. Try both: ``/var/log/syslog`` and ``/var/log/messages``. - Ensure your terminal command used ``logger`` (see above). 4. **Permission issues** - If you created custom log paths, ensure directory write permissions for the rsyslog service user. Use ``sudo chown`` / ``chmod`` appropriately. Optional: Try rsyslog in Docker (sandbox) ========================================= Use this if you want to **experiment without touching your host’s system logger**. .. code-block:: bash docker run --name rsyslog-sandbox -it --rm rsyslog/rsyslog In another terminal, exec a shell into the container to test: .. code-block:: bash docker exec -it rsyslog-sandbox bash logger -t tut01 "hello from inside container" tail -n 50 /var/log/syslog 2>/dev/null || tail -n 50 /var/log/messages .. note:: This container **does not replace** your host’s system logger. To receive host logs, you’d need volume mounts and socket plumbing; that is outside this beginner tutorial and covered later in best-practice guidance. See also / Next steps ===================== - :doc:`02-first-config` – write a message to a custom file using modern RainerScript. - :doc:`03-default-config` – why distro configs look “oldâ€, and how to add your own rules safely. - Existing page: :doc:`../installation` – neutral installation reference. ---- .. tip:: 🎬 *Video idea:* a 2–3 min screen capture showing package install, service check, ``rsyslogd -N1``, a ``logger`` test, and the Docker sandbox run. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/understanding_default_config.rst0000644000000000000000000000013115055605325026422 xustar0030 mtime=1756826325.620800245 30 atime=1764928606.125859424 29 ctime=1764935921.11754495 rsyslog-8.2512.0/doc/source/getting_started/understanding_default_config.rst0000664000175000017500000000545015055605325026073 0ustar00rgerrgerUnderstanding the Default Configuration ======================================= When you open ``/etc/rsyslog.conf`` on a freshly installed Linux system, you might see a configuration that looks very different from the examples in this guide. Lines such as ``$FileOwner`` or ``*.* /var/log/syslog`` can look unusual or even cryptic to new users. This layout comes from how many Linux distributions package rsyslog. It’s not the default style of rsyslog itself, but a compatibility choice made by the distribution to keep older tools and setups working smoothly. Why It Looks Different ---------------------- Distributions like Ubuntu, Debian, or RHEL ship rsyslog with a **mixed configuration style**: - **Legacy lines** such as ``$FileCreateMode`` or ``*.*`` are left over from older syslog systems. - **Modern modules** (e.g., ``module(load="imuxsock")``) are included to add newer rsyslog features. rsyslog supports both styles, so the system works out of the box. For new configurations, we recommend **modern RainerScript syntax**, as shown throughout this guide. Why We Don’t Show ``*.*`` in Examples ------------------------------------- In older configurations, you will often see a line like: .. code-block:: none *.* /var/log/syslog This means: *“Send all messages, regardless of facility or priority, to /var/log/syslog.â€* Modern RainerScript configurations **do not need this line** because logging everything to ``/var/log/syslog`` is already the default behavior. You can add explicit filters if needed, but a ``*.*`` filter is no longer necessary. For example: .. code-block:: rsyslog action(type="omfile" file="/var/log/syslog") is enough to log all messages to ``/var/log/syslog``. How to Work with the Default Config ----------------------------------- - **Keep the distribution’s default files as they are.** They ensure that standard system logging works correctly. - **Add your own rules in separate files** under ``/etc/rsyslog.d/``. This avoids conflicts with distro updates. For example, create ``/etc/rsyslog.d/10-myapp.conf``: .. code-block:: rsyslog # Log all messages from facility 'local3' to a custom log file. if ($syslogfacility-text == "local3") then { action( type="omfile" file="/var/log/myapp.log" ) } Should You Convert the Old Lines? --------------------------------- No, you don’t need to convert them. rsyslog understands both styles. Over time, you might choose to migrate to RainerScript for clarity, but it is not required. Key Takeaways ------------- - The default configuration is shaped by **distribution choices**, not by rsyslog itself. - Modern RainerScript is easier to read and is used in all new examples. - You can safely add your own rules in modern style without touching the existing legacy lines. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/index.rst0000644000000000000000000000013115114522477021635 xustar0030 mtime=1764926783.025631612 29 atime=1764926784.23266124 30 ctime=1764935921.110544843 rsyslog-8.2512.0/doc/source/getting_started/index.rst0000664000175000017500000000327415114522477021310 0ustar00rgerrger.. _getting_started: Getting Started with rsyslog ############################ rsyslog is a modern, high-performance logging service and the default system logger on many Linux distributions. It extends traditional syslog with advanced features like structured logging, reliable TCP/TLS delivery, and integration with modern pipelines (e.g., Elasticsearch, Kafka, or cloud services). This guide helps you get up and running quickly. It includes: .. toctree:: :maxdepth: 1 beginner_tutorials/index ai-assistants installation basic_configuration understanding_default_config forwarding_logs next_steps ---- **Quick Start (for experienced users):** .. code-block:: bash sudo apt install rsyslog sudo systemctl enable --now rsyslog The following pages explain these steps in more detail. .. _getting-started-versioning: Understanding rsyslog version numbers ===================================== Every regular rsyslog release is tagged ``8.yymm.0``. The constant ``8`` marks the current major series, ``yymm`` tells you the year and month of the build, and the trailing digit starts at ``0`` and only increments when a quick follow-up fix ships. Seeing a version such as ``8.2404.0`` instantly reveals it was published in April 2024 and is part of the same feature level as any other ``8.2404.x`` package. Stable builds arrive roughly every second month in even numbered months, typically on a Tuesday around mid-month, with an earlier December drop to avoid holiday downtime. If your installation shows a much older ``yymm`` value, plan an upgrade to keep up with supported features and fixes. Newcomers can read the full background and rationale in :ref:`about-release-versioning`. rsyslog-8.2512.0/doc/source/getting_started/PaxHeaders/next_steps.rst0000644000000000000000000000013215055605325022721 xustar0030 mtime=1756826325.620800245 30 atime=1764928606.095858513 30 ctime=1764935921.115544919 rsyslog-8.2512.0/doc/source/getting_started/next_steps.rst0000664000175000017500000000203115055605325022361 0ustar00rgerrgerNext Steps ========== You have installed rsyslog, configured local logging, and optionally set up log forwarding. Here are some recommended next steps. Explore Modules --------------- rsyslog's modular design allows integrations such as: - `omelasticsearch` for Elasticsearch and OpenSearch - `omkafka` for Kafka - `imfile` for monitoring text log files Filtering and Templates ----------------------- Learn how to filter messages and format log output using templates. See: :doc:`../configuration/index` Debugging and Troubleshooting ----------------------------- Use `rsyslogd -N1` to check configuration syntax and discover issues with included snippets. Advanced Tutorials ------------------ For more examples and step-by-step guides, visit: :doc:`../tutorials/index` Community and AI Assistant -------------------------- - Join the `GitHub Discussions `_ to ask questions and share knowledge. - Try the `AI rsyslog assistant `_ for quick configuration help. rsyslog-8.2512.0/doc/source/PaxHeaders/how2help.rst0000644000000000000000000000013215055603742017067 xustar0030 mtime=1756825570.257068393 30 atime=1764928606.846881321 30 ctime=1764935921.148545425 rsyslog-8.2512.0/doc/source/how2help.rst0000664000175000017500000000431315055603742016534 0ustar00rgerrgerHow you can Help ---------------- **You like rsyslog and would like to lend us a helping hand?** This page tells you how easy it is to help a little bit. You can contribute to the project even with a single mouse click! If you could pick a single item from the wish list, that would be awfully helpful! This is our wish list: - let others know how great rsyslog is - spread word about rsyslog in forums and newsgroups - place a link to `www.rsyslog.com `_ from your home page - let us know about rsyslog - we are eager for feedback - tell us what you like and what you not like - so that we can include that into development - tell us what you use rsyslog for - especially if you have high traffic volume or an otherwise "uncommon" deployment. We are looking for case studies and experience how rsyslog performs in unusual scenarios. - allow us to post your thoughts and experiences as a "user story" on the web site (so far, none are there ;)) - if you know how to create packages (rpm, deb, ...) - we would very much appreciate your help with package creation. We know that it is important to have good binary packages for a product to spread widely. Yet, we do not have the knowledge to do it all ourselves. `Drop Rainer a note `_\ if you could help us out. - if you have configured a device for sending syslog data, and that device is not in our `syslog configuration database `_, you might want to tell us how to configure it. - if you are a corporate user - you might consider `Adiscon `_'s commercial `MonitorWare products `_ for Windows, e.g. to deliver Windows Event Log data to rsyslogd (sales of the commercial products funds the open source development - and they also work very well). - you might be interested in `purchasing professional support or add-on development `_ for rsyslog **We appreciate your help very much.** A big thank you for anything you might do! rsyslog-8.2512.0/doc/source/PaxHeaders/tls_cert_100.jpg0000644000000000000000000000013215055603742017506 xustar0030 mtime=1756825570.263068491 30 atime=1764931128.858122536 30 ctime=1764935922.764570166 rsyslog-8.2512.0/doc/source/tls_cert_100.jpg0000664000175000017500000000072515055603742017156 0ustar00rgerrger--2014-01-22 12:50:33-- http://www.rsyslog.com/doc/tls_cert_100.jpg Resolving www.rsyslog.com (www.rsyslog.com)... 176.9.39.152 Connecting to www.rsyslog.com (www.rsyslog.com)|176.9.39.152|:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [image/jpg] Saving to: ‘tls_cert_100.jpg’ 0K .......... ...... 70.2K=0.2s 2014-01-22 12:50:34 (70.2 KB/s) - ‘tls_cert_100.jpg’ saved [16607] rsyslog-8.2512.0/doc/source/PaxHeaders/direct_queue_rsyslog.png0000644000000000000000000000013215055603742021553 xustar0030 mtime=1756825570.256068377 30 atime=1764931123.361033725 30 ctime=1764935921.058544047 rsyslog-8.2512.0/doc/source/direct_queue_rsyslog.png0000664000175000017500000002434115055603742021223 0ustar00rgerrger‰PNG  IHDR¬‘ŒÃåsBITÛáOà pHYsêe¤ IDATxœíytÅÚ‡Ÿ„l„û ‘EÙ¾Hà‚ ¢‚"•íƒ^P<^‘EE#² "²) *"—‚¢—v D ’uêû£½¹aI2Cfº«gê99œ¡§ç­_×[Ý¿®îêj7!@ +„(ø`ë¿wýC“–«d»B¹J¶+”k"Ù5:zô(·áݾ}{»«T(†ãææfë¿wñ~nëÊf”íˆrkÖ¬yÇ–ãáïïÿ裚tó”lW(WɾëŸ+w‡›:ÁWè‰ËW|Õ~¾ø­E¡PÜw£(\ –µ¬mLãïøN¹‚B!3F P8?,ëX7i'8áŽû6­H¡P‡2…±`ù†o¦2õ8ǵ%ÏðL#«J¡PºÇ p± S™z”£î¸[°n¸EݘÆF«“ˆ‚·üÝqyéWV\3BOz†VLkT=…ˆoùvÓsØw@s µÞäMŒÞ+䌠wž&Ä 7íß[þ¬_¨-oHÃâ RÆ °Ž¼<Ž#&† HM%#ƒë×ÉÈ lY>ú¨ðŠ—¹¼‰MG9J!KÐH&y{JÙ¦ïb¡;Pz æ`:ÁNÁ^{s‰¨KIŠ"¸~ˆ¶oçÔ)NŸæüù;¯Ö°!'Nܾ8–Øwyw«òÈÓ–¸áæƒÏ9ÎU£šãT+ŠÒ£ŒAQ!øê+"#Ù³‡Ã‡ÑÚF­Z4lHp0 L:T¨@¹røùáï_|¼3œy÷>ã³{x…Wf1ËÑÛ¡P(Jƒ2'NðÙg¬ZõwÏ 8˜Îÿþ«U«”±Ïqî=Þ[ÉÊ\rµNCuªÛA³B¡p Ê\!ظ‘U«øö[€à`FŽdà@í^Tqïóþr–‡6‡9v¯P(ì…2æûï™2…¨(4ˆ!ChÕÊÑe&0y“˜@€£ËR(w‡2—ä×_4ˆØXÊ—güxƧB£5) YPÆàbdg3u*³fáãÃK/1q"•+­I¡PÈ…zŽÁ•8x!CˆŽ¦kW–/§n]£) Q³«º ‹Ѫ±±ÌŸÏÎÊ EQ8­1„††¶iÓxï½÷/_¾¼gÏž   mÛ¶eff6nÜ8<<xî¹ç |øá‡íÛ·ÏÈÈØ»wo·nÝ"##SSS{÷î½bÅ `ܸq“&M–-[öüóÏçååEFF>üøñã)))aaaßÿ=0}úôÅ‹ëׯŸ:u*pðàÁéÓ§'&&¦¤¤Ìš5ë·ß~Ó‚|÷ÝwÀ®]»>ÿüsàäÉ“kÖ¬¹zõjjjêúõëcbbìY ¯¾JXÍšqö,cÇâ¦Þâ¢P@nn®"///999338wîÜùó瘘˜¨¨(mIDD„ö­Q8­14oÞ¼E‹@57nìåååããS§N___!„¿¿¿——`±XrssŒŒŒË—/ׯ_‰‰ÉÌÌÌÍÍŠŠJLL"##ýõWàÀ_ý5púôéeË–%%%¥¥¥-Z´H;â/]ºtݺuÀæÍ›ß{ï=à?þ˜ËìÙôêÅÞ½TSO››ŒŒŒï¾ûîìÙ³ÀÁƒãââ€+W®\»v °X,%ü^a ‡š2eʹsç’““_~ùåmÛ¶&LÐN+ç̙ӯ_?`Ó¦M:t8vìXlll³fÍ´³ÉæÍ›:4höÍ9sæxyy9räСCU«VÕVkܸñ+¯¼Œ;ö±ÇÖ®]z¾¨¹ôA(î–üü|‹Åb±X222²³³…©©©×®]B¤¤¤$$$!ÒÒÒbbbnܸ‘}ôèÑK—. !¢££O:%„8yòä¾}û„ ;wîLKKKMMݺuë™3gì#1'G´o/@ .rsíSa(ÇŽf̘!„¨ZµjïÞ½…ýû÷÷÷÷BÌŸ?8tèPtttíÚµW¬X!„ ™4i’bêÔ©{÷î5R½ÙÐ:ô?üðùsç€iÓ¦ !êÖ­Û³gO!ĨQ£…k×® >xðàÙ³g[µjµjÕ*!Ä“O>9eÊ!Ä|ðâ‹/ !vìØ1räÈøøøÄÄĉ'þòË/Bˆ3f|ûí·BˆÍ›7k?6œœLÓ¦X,=J•*z”¨0”<ò y—‹Â‰qc¸ÈÅ5¬™À„·xë-Þ:ƱbˆiC›2”1Z¾<õß|Ö-ôéc´…ø‹¿Nr2–Xí/‘Ä4Ò2ÈÈ #“̲”µ`I&¹`ýÛ_ûU•ª‰$¸ æå0‡ãˆ;Å©‚?<®sÝq%Ndâë¼î¸øVbzcH!%€€yq%+c‰-G9?ü|ñ5Z—A|þ9C†0bK–-Eq÷œæôöh¸P°Ü ·†4,G¹‚¿jTóÆ;ô;¾kZûóÃo1‹ Üsq’“?ñ“öO|Áò@ÒÐO/¼Wú<ÇsŽ‹o%æ6†¬x‰—NqJ HhK[£Jj*õëS±"ÑÑ”+g´…ÍÄ÷ Ÿ¬fu €;îmhÓžöÁ7 AAª‹Eâ'V³z kÎq(C™V´êHÇxà!jBWšYΔ›šGÞT¦NcZ0Á=èaÁR‡:ØÿÝ2&#<œ”V®T®`.b=ë²ð'~ˆ&4yžç;Ó¹#}ð1Z““Kî§|ºŒe80‘‰ÝéÞ‰NÚpv×Ä”=†Õ¬Ìà…,ãµHÃùóÓ¢?ÿl´…µÄW|5‰Ig8Sžò8ŒaÚÐ8…£I%u æ2÷*WkPc 1¨W•)0S!ŸüÌhF³A J&y4£V$Ó¦qã3f­Ca-?óó˼|€,gù ¼àr% "Ÿüy̛” 2îçþ¬èK_£EÉÅ­=†#GެY³ÆÍêÙ7+V¬øÚk¯ÙTdxxøõë6ÜÖñÄ 4°~ýýû÷ÿòË/Ö¯_¿~ýþýû[¿~VVÖÂ… ‹YáöŠzñÅ+V¬XBÜ[¦ÈX¿~½õš€{î¹ÇÖY8ªW¯nS›7o¾*®¾$^ÊùgÅY‹°ÿí·ß¶)¾6–õ$''—ôfbccm*bÀ€6ÅßÓ²¥qø°•ñúé'›âûøøØ¤_Ñ´iS›ŠX¶l™Mñµéi­§E‹¶nB™2¶¿ï߿ߚ°±"¶µh Z\5jÚðàÁ6é?qâ„MúÔÔT›ŠèÖ­›MñÃÃÃmŠÿÍ7ߨ¿N:ÅDË™Äwáî/üWˆÚBmÞSëѦŸ²žwÞyǦø¡¡¡6Å¿råŠMñ˜˜˜ÃÞÚcÈÊÊÒæïµww÷j6Îä|ñâÅâ'¾ER¥J•føÌx‹·~å×Ö´.1~zzzzzúCݟʶ¼ÞÒb±\¸p¡äõ Q£F ®Ú]¹rÅšÙØµ­sËÎlÓÆ-(ˆß~³2~vvváÓyJª(77·{î¹ÇÊà.\Èɱáaï*UªøùùY¿~zzºõ-„ðöö¶òt¾€3gÎÜ1TQë×®]Ûǧ„{Å;ØÑ—¾ùä¿Ë»C“‡¦^Kµ^¿¿¿M'U9996ÎAAAî¶<*Ÿ˜˜XTC½cEU­ZµR¥JÖÇOOO·iöi¢Nç/p¡=Žr´=>åÓ{ø»=Ÿ>}://Ïú"ýýý­_?99ùÒ¥KŬpKEùùùÕµå%ZùùùÚ€5Ç:ûî»O{é@1È~óùçüð«D¥ììA£åHÉêÕ ÌÒ¥ f´Eq|ÇwOñTe*og{š-Ç…8ÌáÞô¾À…yÌ{‰—Œ–c¤6¨G½k\K&ÙO£åÈJ‡DGsþ¼¥*3[ÙÚŸþÕ¨¶›ÝA-Ç…ø‘ã1ø’/{ÓÛh9æ@ÞQIùä—¡Ìf6ã˜r…"‰åçŸ S® 3?òãã<^“šÊt&’È^ôª@…-lQCQ­G^cx’'äÁ·yûA4Z‹ÄhÞyÆhŠ"I ¡?ý«Påw~¯Žm#/¥!–ؾôõÆ{{ÒÐh9fBRcH'=‘D×òÈz¾ÿž€BBŒÖ¡¸3¹ädà5®íd§r=¹Â•ÞôN%u;Û•+ØŠŒ“õŸå¬'žQD}ÆgFk‘›´4öî¥Glò¤Ð“ILÚǾiLëLg£µ¸xŠSËXfÇšÏÌdölly ˬHg ÑŸþ5©™GžCg1tvì '‡Þê~š¤üÁ³˜Õîoð†ÑZ\‹Ïøl';_â¥çyÞŽa}}IH n]Þ}—´4;–G%íf÷QŽªQe%3bË—sé¶<‡¡ÐhG»C:Á‰‚Qó H"©18ÌárØyPFR÷ÞKV+ò꫌Kùòö-A äê1¤Nx':)W°Šßçþû•+ÈÉ×|½Ÿý˜ \AgÆ0æ×–²Ôî®Ô¬É¨Q×®ñæ›Ô­ËôéNØ{«Ç0‘‰³˜õ´¤¥ÑZ¤'+‹òå0€U«Œ–¢¸•,²Ñ(‹¬Sœòdže¥dûÚÑn8Ã?åS‘”Dýúdg¸¹!+òÊ+Œç<½‡’aÕ*øûó×µãBK™Ü“Þhÿ°¢D9ZÀ],4JÀ½W~ŸöýÃ_´šóŸFãUµÈ¦*!tiô¸M|RgÛHyTI+ÀŽªŽÏ MoþãCOŸöºXÇqª(<Ï…óÙCÉ£Y¶mcíZ”Àô7Yÿó‡ý KirÇ 4‹šU³¨•GX˶øéÍaK¹PϲLªêÊŒEîWª^š9ärŽDªœ^@Vóý©G|9úÆ©:7©êŽ“½Y,äåÝù+ÓQr!3“ÜÜ›「¦»¥Õö 7hiÎçŽ.ËðækFâÓOII¡B‡•¡¸ö³?„×y=œp£µ¸½èµ›Ý§9]‡:Ž+åâEêÕ#;!þî+”/Ïøñüë_”8›µY(¹Çà«ËCfå(ŸAF²G²¯‘o%ÇS·®r YÄ¢2”Å(£…¸qÄE1„!u`æL²²þþìçÇøñŒï<– !Ũ¤l²3øÔ{›m 1‘:ŽÝwA&™ëX÷þQzFkq-V³Ú‚e(CZÊÅ‹,ZàïÏ”)ÄÅñÖ[Îæ Hb ûØ·šÕ?aÛÛc\!¸p@å£Ò±•­ÙdÀ¶W-)JÏç|^ŸúèàÐRfÎÄËë–`ˋ̈́nºÐ%•T5…ª \¾Lv66¾yF¡ßñ]Êô¤§ÑB\‹H"Oqj2“ÝpÜm=nÜ reââœÿ ®ñ=†D§3=ô²”5Z‹yHLTA6,X¶±­-m+£ž:Ô• l1È¡¥”-Ë¿ÿíü®€ Æðþ3™ÉG8b´S¡½ïPƒdüʯ—¹Ü‡>F q9~à‡zÔS³¨Ú ãaÃ~çw5÷¤mho¯ZÕhŠ›ØÍn@]GÒ™«\=ÈÁnt3Zˆó`°1ä’Nø½Üë·±JL†6\®¤WÏ+t&Š(_|Õûœuf7»-XºÒÕh!΃Áưƒ“˜´žõÆÊ0š1x+7•‹(¢äÁ2”1Zˆkñ?¸á¦ŒÁŽ<*éQÝÊVõ.V›Q=ù¸Â•8âã1£…¸QDTƒF q î1ìgWºV£š±2̇2ùˆ" hA £…¸,G9ª.ßÙ#A çñ'yÒ@ fE›óWƒLD <ÄCF q-Îqî:×›ÒÔh!N…‘—’òÉŸÍìœôÙA‡’—¨W=KE<ñ@}ê-ĵÐFº«ƒ}1òÈ’AÆ?ù§LLÙ²™™êõmòO|yÊWÄéæÍ‘­£¦ŒÁ¾i 3™NøyΛÅbÉw$Ï<óLÙ²Å>®Íy›™ù¿%99xz:ršïÿqñâÅÙ³gëPÌtìØ±OŸ›dK ÁÑóz*n' ˆ ÊŠˆˆøðÃ4hàåå%îpÇåÖ|ëèŸß²Â«¯¾úä“E^Æ÷жvæÌ™ö­Á´´´²eËnÙ²Åß¿È÷>ȃ}é[êö-º„-Z´ÈÉÉ©R¥J1Çå¼¼¼â¿u´ÎG}ôVc8tˆûïÿßM…råà¿Æ`±°d »wóÕWަ±cÇ»7ÓqìØ±[Œ!žxÇ×effþë_ÿ hÕª•#+zþ¼J•*‹/nÙ²å·ß~[↧⋯>BýòË/Û¶m+}·BÜòßÛ)å E}›­Ý§,àÚµk'Nœ(ýÖ&------99¹cxš§Ÿæiû–["‡òóóËÎÎ.s3^^^eƒ‡‡‡MëüñÇß~ûí˜1cnÒ]«AA„†2z4­[ÿÝcÈÈ 2’°0`½~Ï‚\¿~ؾ}{‹.:ç‰'žˆŽŽ.¼$‹¬d’ïá£$åää|ú©£Þr¬3÷Ýw_NNŽ•g`W¹Z‰J%®¶xñâ“'OÎ;·ÔêøóÏ?Ksà.½Gã<óÌ3Ï<óŒ}ãNŸ>}òäÉ¢Ø×Ãu¡K!ïònñ¡Îž=[¶lÙ5ìp¹IKÉSO=µbÅŠÒGsO<ñ„âVc¨V×_gÜ8V¬ eKZ¶˜>ˆ„ F úöÕM¡»»;P¾|ù*UªèV¨Txyyݲä*W¢ 6TH»víÜÝÝ÷îÝkIZÛîׯߨQ£J:iìÏË”)dí¥¡«\µfKDDÄîÝ»íb •*•lE¦ÆQ÷´¬o Yd]ær‰¡š7oÞ­[·o¾ùÆ^ŠWe8E*=š¥K9|˜¨(¢¢¶oÿû«‘#ñÔoÒrk’ëÜÜž£tÒ?ü¬’‘‘¡Y¬½$õêÕëÕ«—½bš‚R ì¨9+Ž}Ž¡øcÇ~ö/a‰CÜŽ‰ÁÃ>ºÃíå2e1¢¨hK–,™7ož]*c¸CŽ®sÁ¾¸lR¬¼”¤° GC‰Íô,g_æåp€¢0±1:0hÐ-kÓ·o1óo¯\¹rñâÅvèºÇ ”1HByi¤)c°;†ÃyÎÏgþA:H@Q˜Û€>ÀÏïý!=Za¸æ1¨0Ê$!…PÉÚÃŒ¡-mSHqô—nÇôÆP³&o½…¶‚»;AAtï®›6 ×<æöe”£œAŠ\4))¤ªÇ`w 3†‹\ÜÞTR$ (Lo Àر4j`±0z´>µÆ5A…¹=GÚTÛ,)rѤ\å*Ê€aưŸýOðÄüá Eá ÆàéÉÂ…ÞÞ ª‹¨›pÍcPanÏ‘/¾@&™EüÂá¸fR4cP—’ìŽaÃUCÙÄ&ýŸucºtaÀ|| ™+É5A…¹=Ge)‹2ݹÁ ½‚ç¬f ¨Ðžöú߬scæÏ'!Áñrî€kƒ £z ’ Í„‘E–ÑBœ Ã.%}Íו©I¤ƒ…óCµj?ÿ¬;®y *Œ2IÐ:jZ¿AaG 3†¦4}•WkQËAŠÂyŒÁ8\óT˜¢ŒÁÀ#”k&E3Õc°;†]JjIË–Üt»‘=èáèË…¦8ìʯ×;Fõ$ÁTÁè×cˆ'~Ó’HÒþETco`p’“¡„~Â':ÜD2ÅaW~…¸Þ1¨0êæ³$¨ƒƒÐÏîážxâïáž'y2‚O<ýðË'ÿu^oJÓ"þÿs˜[„I¾ó˜B!®w *Œ5=†,²Žs\OI¸^RÔ=¡ë=†÷yßßl %´;ÝûÑo$#g0#—ÜÚÔîCŸ"‚ÙY˜ä;)âzǠ¸¹¹‰2b7»W‚'žžxÃZÖ6¢QUªê) ×KŠõ—’ºuë6xð`Ç+rt½ÇPjÓ™>ŽqÀe.Ob’?µ;ŠQº¼gÔ‡]ùâzǠ¸¹¹‰\± #9œáCZê¾øÞàÆ)NaÌ.v d`ñ¯gX²d‰›]ŸZ—¿åØ;^J:ÏùÚÔ¾eͰ°0ýd™½G%ftSšºÿ·\í„Ëá /*ÔÙ³g?ûì3; “|ç1…B”11é×¹þ:¯×¦öSùßðÍU®Æ›K.DPº¢JçBuÆQŒêA lÈ#ÏowܳÈJ'ý5^kF37ÜÐÀh™¦Ç€áªè0ˆA«Y­ýW F£ßÄÑòï<öU8cÆ {…*@CAŽžåÙ¥,-|³Ac$# .“ê¯Ê¹™Å¬F4ÚÁŽšÔÅ(|Nr²! µúŒaqzŒyÀí>ðÃÏ 77Üîã>=Ï­äßyL¡e ÿÝüE,òij° xà1„!ƪrbêPç Þ’HšÆ´L2#‰ü‹¿Ýư8=ÆCMj¾Å[¡uô<·’ç1…B”1üwóÒð5^+è1h—F«SÝXUÎÍ+¼D{¡Ã—Vÿºaqz ›c,cಔÕùÜJþÇ QÆPhóßàúÔ׎SQâmg}T91Þx/`Á-o¿(~ ‹Â& 3O<°àYžÕy.uùwS(DC¡Í/KÙ…,ÔŽSu©Û½ß©wGUÎM/zõ£_Áņǰ(lÂ0cºÒu³$ (äßyL¡e 7o~/zõ§?0‚îÛ­lUåÜÌe®^š7è<†Åé1Ò0âÕKòï<¦Pˆ2†Û6ÿC> àŸüÓI˜¡åØ—úÔƒ7´» :aqz 6ý‘ç1…B¤L®nÜ1GF¡ÿLòÈßrìÎk¼Vz€ÎcXœe Òa …H™\Ý(*Gú¿ª¶0ò·»ãƒÏ|æûâkÈø`'Fƒt˜B!R&W7äÌ‘œªÍc<¶…ú_”vn”1H‡)"eruCÎÉ©J†2Ôh Ά2é0…B¤L®nÈ™#9U)̈2é0…B¤L®nÈYò·‰‹‹;zô¨Ñ*Lƒ2é0…B¤L®nØ¥æÏŸ¿`Á;)3´?~|ûöíVaL` ýû÷çwJGCþÇ QÆPêX¾|ùŠ+ì¤ÌÐrfÁ€i·me×®]¥R€ü;}&''[,–jÕªÙ+ Êd­ùÛ¶Â,˜Àì‹ü;}öíÛ7%%åøq{¾•^Úäꆜ5 ÛV˜\J²/òï<¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݳäo9 ³ ŒAF$W(mruCÎ0EÛV˜e Òa …H™\ݳäo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAM¢'¦Pˆ”ÉÕ »Ô@·nÝÜÝíyf&Ë1¯¾úÊb±­Â4˜À&MšT¿~ýÒÇXkâuxIDATÑpss“¼}È¿{+c°K Ìž=ÛNrþFþ–c žžžFK0&0†‰'–>Hòï<¦Pˆ2ùj@þ–£0 &0û"ÿÎc_…›6m²{IÚäꆜ5 ÛV˜e Òa_…U«VµW¨¤M®nÈYò·m…YP£’¤Ã ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݳäo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݰK üõ×_ýõ—ZŽLš4éÿø‡Ñ*Lƒ &ÑÛ¶m[•*UZ·n]úP˜aç1…B”1”ºzöìéîî~àÀ;‰2Á»F äøñãû÷ï7Z…i0AáÙgŸ}ÿý÷KGÇ]ù¢ŒA¾¿å(Ì‚ ŒÁ¾È¿óØWá¿ÿýï±cÇÚ+š†´ÉÕ 9k@þ¶­0 &¸”d_äßyì«ðÇLII±W4 i“«rÖ€üm[aTA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ÝÐj@6äo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡ü 5L!ÒAÈÙ¼ÍÒròãŠÆ`´„÷–6¹º!g ÈßrfAÍ•$¦Pˆ”ÉÕ 9k@þ–c C‡íÖ­›Ñ*Lƒ£Œ¡råÊcÆŒy衇Jªzõꥣ1bĈ޽{Û+š#÷._¾ü‚ Z¶li´ÃhÖ¬Ù˜1cªT©Rš ;wî´oÿuìØ±ééév èLôíÛ×h fBöc ²gÏžØØØaÆÙ%ZHHHJJÊñãÇíM¡Ð‡ÿüç?+VlÓ¦ÑBnbêÔ©o¿ýv|||:uŒÖâXÕcPÜ5;wîܹ³½¢½ð 7nܰW4…Bzöìi´—Fõ …Â*.]ºtéÒ¥† zzz­Å±(cP( ÅM8j¸ªB¡P(LŠ2…B¡PÜ„2…B¡PÜ„2…B¡PÜ„1Æ0}úôªU«æääµÂœ9s´O?ýôÝ1{ölÿ»û­B¡P¸2ÆÃÆŸ{î¹Í›7µB1¬[·î.â_½zuïÞ½*T¸K}ãPOýá‡Ú¶mÛ©S§-ZlÙ²åîUº$MÍáÇCBB:vìØºuë;wÞ½J…„îìÝ»wĈ§OŸîÓ§âäÉ“:u éܹsRR’bÁ‚^^^:uzýõ×k×®-„ˆŽŽnÛ¶mÛ¶mCBBŽ=ªÅ©U«VXXØ<0wîÜ[Š˜0aÂþýûµß:-Z´7nܺuëŠZ¡4[­}HJJªW¯Þ]ÇqMšš‹/¦§§ !âãヂ‚î:ŽðÎ;ïT©R¥ ­ÞÎìÙ³µO=õÔ]ÄŸ;wnpp°¿¿ÿ]ês 0†aÆEFF !ºwïž””Ô¹sç;vh_åççk v!íCûöíüñG!Ä/¿üÒ¡Cí«Š+ž9s&55µAƒ…ãÇÆÆ8P”n?”÷Üs'NœÎh ŽöT!DDDD›6mªW¯åø rtHªoß¾kÖ¬qðÖÈ‹nì|G›ÐÛV­Z5mÚ4íóõë×[¶lÙ¹sç]»viKŠÚ…Úµk·wï^qó.T°Î-ÆðÈ#hÆãííÝ¿‡nŽžèà©—+W®råÊC† ™6mÚäÉ“½½½¿øâ‹5jýúõ íÒ¥‹¶æÂ… Gåîî,Y²¤ø""##µëׯwÔ–èΆ FŽ9uêT ##£S§N÷ßÿîÝ»»ví X,­~n!((èçŸnß¾ý¾}ûî½÷^maQ³=ggg{{{+VLMMuÔ–8:¤F1räȺuë¾úê«ÛÙÉÌÌܶm[bb"péÒ¥Õ«WŸ8q¢à- w¬d &&¦cÇŽ@HHÈ™3g´…¾¾¾õë×rssõn:Œv&…µtëÖí·ß~+øo=Ö¬YÓ¡C‡.]ºhýh!Ę1czôè®ò:tè‘GѺÒÑÑÑÚ:Eu¶>þøãN:µoß¾uëÖÛ·o×a£œR³qãFí I§NºvíªÃFIˆ× pñƒšDO¡P˜ƒîÝ»‡‡‡·nÝZûohhè!C/^œŸŸ_øzCXXXLLL—.]>úè£ÄÄÄ?ÿü³ðõ†&MšZÏ£^½zçÎ+\Ê—_~¹téR­37|øðê¼™2 ŒA¡P(7¡¦ÄP( ÅM(cP( ÅM(cP( ÅM(cP( ÅM(cP( ÅM(cP( ÅMü?Ùå^yV4IEND®B`‚rsyslog-8.2512.0/doc/source/PaxHeaders/queue_analogy_tv.png0000644000000000000000000000013215055603742020662 xustar0030 mtime=1756825570.260068442 30 atime=1764931123.771040353 30 ctime=1764935921.180545915 rsyslog-8.2512.0/doc/source/queue_analogy_tv.png0000664000175000017500000004445215055603742020337 0ustar00rgerrger‰PNG  IHDRë8ô;LwsBITÛáOà pHYsÐй‹çŸ IDATxœíÝw\S×ßðOKöRQdƒ7ÕZ«­J­uÕ]·uàh뮥\m©¨ÕÚV­£¿ÖV[[«m]åqTqáAPAd„™óüq1 ! ; |ß/ÿ8Üœ{ï ćs﹇Ç!ºC$Â’%HLĹsÚn !ºŽG NtKa!‘›‹‡áâ¢íÖ¢Ó ´ÝBÊ25EPÃÏ?k»)„è:Jp¢{F@ NÈKÑ( Ñ=4BHÕPœèH!¤j(Á‰N¢Bª€FQˆN¢Bª€úàD'Ñ@ !U@ Nt ¤ò24ŠBt ¤ò2Ô'ºŠRyJp¢Ã†h … Ñ( ÑaÝ»#2< ¤¢õÁ‰ @)„T„œè°ž=K ”à„hB£(D‡=x4BˆFÔ':ÌÝ ¤¢%8Ñm4BHÅ(Á‰nëÑ£´p´ÚBt%8Ñm\ÜÛ¹¹01ÑvkÑ-t%“è¶¼8ÑmqqÊøp÷®öšBˆÎ¡'ºMíæ;Zj!ºˆœè6µ ˜ 7WKM!DçP‚ݦ–àr9®^ÕRSÑ9”àD‡åä &F}#ÝVHÈ ”àD‡EF¢¤D}#%8!/P‚¦1¬/_ÝKJp¢Ó4Τ‹ßàM!DQ‚]ÅX…ÏB¡BP‚݇ÌLÍ/ÑS®@ NtW%1M}pBP‚ÝUILß½Kóz%8Ñ]•$xI Íë!”àDG©Îåáñ4T B(Á‰ŽRË£qcJpBA‚ @ÛM õ@5 ÍÍ5T y=„èo‚3°£8êWà·kµÝRToDQMp ‹ÒÍë!D¼4»süFlqgÁð›ábˆµÝ(R§Ôæò¨&x‡Ê2 ¤&OŸ\™ÝŸ¸ûÅ]ó‰æþ_ùçý÷9>×vÓHRËck[fÜ×WY¦y=¤ÉÓWËn§±N;Cvf8e|mø5ÏGÝðÆF5š¹…êTœúà¤ÉÓõטÝÎÆlc àͱoR7¼±Qfµo×/>´4¯‡4yº›à•g·¢ZˆauÃÕ/,,sÏIf&,-KË4¯‡4y<¦{·d1°_ñë'9ŸÜÝ}8ÍpZå´j*¦ª·ª!²!'–ŸX¾ey(B¸©¤îåäÀƦÌÂÍš¡àÅ=£|~™—Ö­ÃÊ• Ú3ÓZ‚ëHv+„P7\ï¨Íå±±ÁÙ³èØ –y”Uj*Þ{¢¤††ÉJ·ÿ÷%8©={û‚àà[ ÞÏ?÷Ìj°cmÇÁµ5Þ]9 ×?jsyâã1gärlÙ‚›7•ÕFÂ÷ßÃÐ àƒ”Ûi^i’jžàrÈu0»Bè¦ý¢6—ÇÆ;v 2={¢¸Xù’L†I“‹/¿Ä€Êít1“4I5Ea`31óÏœ?Ÿí~¦ c&•ކ¢‹—D$j»9äe4ÎåéÜ/ÂË ¥[ÄØ±¥en^\¼˜×Sùí+„TGPÐÐú>ůåjÒ_„EßF}ûlÖ³VSZéT¿[ÕZ¬='=‡,<ŽyLÝp=PÑ\¯Ì})ª×zh^iòªàÛ±=ü`8l7,°] ›Ù-”W‡¯.X_SæšÕèi8ÕšË£Šæõ¦­z ¾ÛƒÃÇ£6>ؘ‡¼zjY (²;ocžuõ¶uÛà C6C3m7TªZsyTѼÒ´U#Áñ½óÝGqÔ|йxx'v¾|Ïú§šÝöAö_¬û"Ù5y*¦j»]¤jªø8”òÊÏë!¤)©j‚«Æ÷,̰\°\ºáå³;É5iQ¿[‹®]»V½ÔÖå©:Z¯‡4mUJðòñ `9–k·NÙ­³RRRz÷î}êÔ©*ծʺ<¡õzHÓöò×ßmuÃ)»u\PPPaaáÀ«”ãªsyŒ!•VãL±±xüXù%Íë!MÌK¼’ø†6ºá”ÝzÇã}òÉ'.]ºôòWÝâbtìˆ1cý’s$%aêTtèP¦&õÁISY‚Wßœë†Svë—   Î;så—ä¸ÚeLcc> ?¿ s<= ÂÛ{÷‚ÏÇŒ´^©Äÿý·aÆÜFúÁ¨0Á«ßhn8e·>RtÃ*ÌqÕ_» 8¸LŽçç++|ý5Üݱu+d2LœˆØXìÞMózH%zôèñ믿º¸¸¬[·.;;[ÛÍ©k¬œóìü86ŽwÇûoÛU¾‚šPŠm°M°•0ÉK+W˶F+ÀV`%ìÚÁ¾ÈgùUß=åá8L™Ü¾}›1&“É¢¢¢îܹ£(ß½{—1&•JÕÊÑÑÑŒ±ââbE¹¨¨(***&&FQ¾wïc¬°°P­Ë+((P”óóó£¢¢âââåû÷ï3ÆòòòÔÊñññŒ1‰D¢(çææFEE%$$(Ê<`Œåä䨕>|ÈËÎÎV”³²²¢¢¢=z¤('&&2Æž?®VNJJbŒeff*Êb±8**êñãÇŠò“'Ocjå§OŸ2ÆD"‘¢œžž•œœ,—Ëýüü4~êzõêõÏ?ÿ0ÆXv6ãóÀÆç³œœÒ^r2 f¦¦¥/©þãñØÛo³»w•?é™3•¯®[WOiþüóOîƒgmmòüùsÕnÞdnnY¼Pþ£Wçÿçê×ïéÁƒ5yk|:›Ž?§ðfÞ…¬°*G1—˜c¶°-5i‚&µÌnNËÃQ …Œ1îׯ¥¥%c,33€­­-cL$ppp`Œ={ö @‹-cOŸ>ЪU+ÆXRRÆØÃ‡¸»»3Æîß¿ÀËË‹1vïÞ=íÚµcŒÝ½{€¯¯/cìÖ­[:uêÄ»~ý:€.]º0Æ"##tïÞ1ößÿq¹Æ;þ<€ÀÀ@ÆØ¿ÿþ  _¿~Œ±3gÎ0`cìŸþ0hÐ ÆØ‰' <˜1öÇ bŒýöÛo†Î;r䀑#G2Æ~úé'cÆŒaŒýðÃÆÏ;pà€I“&1ÆöíÛ`Ê”)Œ±o¿ýÀôéÓc_ý5€Ù³g3ƾúê+sçÎeŒ…‡‡fŒ………X´hclòäÉ•ô:vìxë믕g??õ!—ãÊ:ìòeõj{ö(+ RÝÏ i z¨ÜãdiiùñÇ‹Åbµ:ú˜àFQ,`KÀAÄ}'LNÁ”|ä—¯¦ªGÃëxÌ„/®'ÈçóýýýU˾¾¾ ýýý;tèÀÈÈHcÙØØØßß¿]»vjeÿ¶mÛ055õ÷÷÷ññÑXööö`ff¦VöòòR”===…Bessswwwµ²………¢liiéïïïææ¦(»ººª•­­­ýýý]\\å6mÚ¨•mllüýýØÚÚª•[µjÀÎÎNQ¶··W+;99¨dðÑÅÅeîܹ>))ÊMåïoÙ[·¢kWå–íÛËÜ>X~Gš×C4 Q”³³³×®]ëêêºråÊŒŒ í5ª.”õ#ì>AÖÁ1ÓOaøÔð=ö^Ë«äWAí»áuÒïV•Çòð'šE6«ÍAHeeeY[[—ÿȹ¸¸ìÞ½»¨¨ˆ1ÆVvHöíÓ| ^½”u®\ÑPA.g66Ê:qqõø®ˆÞêÕ«WùO£P(\ºtizz:k4}pŽ|R¬S~\ú£Ï|ÙAÙ¾5û,“-+éצN×*¥­[·>þ\u —Ýqqq3fÌ066®Õ\U5š×#—ËKJJ0ÆŠŠŠŠŠŠ¸yyyyyy\9++‹|“Éd"‘H,J¥)))éé銋‹“’’RRR%$$ýå—_._¾ ))éÿûߥK—<|øpÿþý.\¿gÏn€.66öë¯¿Žˆˆ½}ûösçθ}ûvXXØÙ³gܸqcóæÍÜÀ]dddhhèéÓ§ü÷ߟ~ú)w-úüùó«V­âôÎ;·téÒ¿ÿþÀ©S§/^ü×_8qâÄüùó¹òï¿ÿþþûïså£GNŸ>ýäÉ“~úé§É“'s僎7Ž+ïÝ»wÔ¨Q\y÷îÝo¿ý6WÞ±cÇСC¹ã|ùå—ƒ âÊ[¶léß¿?׆õë×rm éÑ£Ç?ÿüóé§Ÿ–ÿH$’M›6¹ºº~ôÑGb±ÖW«­ò¡ÎõÁG²‘Ü—%¬äGö£O¦ÏKûã5è†×y¿[õÁµH­^¦ß­pïž²7bkËärÍÇziœ1¶f¢NÆ{ï™››s-RSSMMMÛ´iÃ{úô)ŸÏwvvfe/lpÙZõ QQQ¨Ý…W_}•UçÂÆ[o½ÅöÂÆ¶mÛ éÂÆgŸ}à£>bŒmÚ´ À²eËcëׯ°råJÆØš5k¬^½š1ÆÝ´fÍÆØªU«¬_¿ž1¶lÙ27ndŒ}ôÑG¶lÙÂ[¼x1€°°0ÆØ‚ „‡‡3ÆæÎ `ÇŽŒ±Ù³gصkclÆŒ¾ýö[ÆØÔ©SìÝ»—16iÒ$û÷ïgŒ?À¡C‡222x/‡íêêºmÛŸz×ù 0ƒ1£¬Gý¼ôçç!±»c÷í;8íà§ ;°CõÁ­ËËW´X±ñÁÆ÷Ýß@Pùa×bí&ɦ¼=yH‡ý4ûå®Ëgc6uº EÜÅÅeÅŠ“'O66.÷bµxm›W ¿v-77×ÔÔ”ûª°°ë_óx¼’’®ßÍãñø|>ŸÏÀçóMMM¹ú|>ßÜÜ\(044´±±±´´äÊŽŽŽ¶¶¶Œ[µjåèèÀÄÄÄÅÅ…ô755õôôlݺ533³víÚq„BaÇŽ=<<XXXtíÚ•»øaiiÙ³gOµµu`` waÆÎήÿþ;vààà0hÐ Í›7:th×®]´lÙrøðáݺuкuëQ£FõìÙ“ûn7Ž.pss›+·mÛöý÷ßçÊ:tæÊ;v\¼xqŸ>}tîÜyéÒ¥ÜöîÝ»¯ZµŠ+÷êÕëÓO?åŽÿÊ+¯„††rçíß¿ÿ–-[¸«…477çʃ¶··ïÞ½;€·Þz«uëÖFŒáå厗wß}×ÏÏ›=0a„nݺqïwÊ”):u0sæÌr±æÎûÖ[oq¨.\8zôhî{øÑGMš4‰»È´råÊY³fq>ýôÓàà`ww÷ÐÐP¦é‰‡‡ÇÇ<~üø;wøaaúv»aùPW냫zi¼*Ýðzíw«¢>¸¶ppÍýnUªw®YSaµªôÁ³³·¬Èù|Ijj~~>cL.—I¥R®–¼¢n>iìÒÒÒÌÌÔ× pssÛ³gâãѨÆÁ5âúãÑÖÑW>NãÝMıcÇ6mÚ¤ﮈê€õ®]ؽEE59ßÍ›˜>½t¹5€WR"ˆŽnÖ¬glllhXú·f%D“Æí³Ï>ËW™æââòÍ7ßÄÆÆN™2EññÐG5Ye­’_€§hRv7)“&MzIv£ìº<RR0kÜÝñå—e&aVîÒ% ‚.]ðóÏàó•Ûé)DEFFÆÎ¥‰äìì¼k×®¸¸¸éÓ§i·aµWóµê5æ¸E²EA8)»á”ÝD3Õuy|}qø0:uBr2-‚‹ BCQùèÓ§ñê«èÝ'N@ À‡â³Ï”¯R‚Ÿþ¹D"iÕªÕŽ;îß¿?kÖ¬—t/ôGmÿ|(ónÑ]L‡ø²x„ûˆIDážBºVI4P Ù^½0jFŽÄ‰ Å¥KX¹›7cÞ<,XPf/ÆpìBC ÖÖFp0ll‹E‹J«qózhÌ„b±ø×_ Ÿ1c†âúvUÔ~!ùP7@ê9þu,†ãïð¿ñ ö3µ“ÝrÈ·ad yNRå×åáñ0d† Á¿ÿbýzœ>õëñå—°´TÖœ0 àèˆÅ‹ñþûÊE5¹õz¸Gsëõxy5Ð{!:,++ëîÝ»z=Ø]‰š¢h:–ÁŒ‰±ŽùqÙ<9B|°áƒ§®Ox̤%‡pÈ[ì½lÝ2܆k[×;5©ªÊçòôë‡S§på Þz ùùPyŸgglÛ†G°dI™5‘i½¢‰»»{coÔm‚sxàÁS,Æbc4Üx—Ý>bŸ ¡v&¸ÍrÛ·jß-á­k©*Õuylm5w–»uñc¸u vvÊ«V!!óæ¡™¦>ÚRiìɯ¦”üˆCÄ! _'@·Yn«íWÇxÃÆò›ªÏåñõ…— B%÷¨&8õÁIõ=zdùÎ;ƒU·””ÔüjŠ¡!“É4ïn`ÀT?õ%%¼éÓktŠ5L‡Pvë%Õx­ñãPÊëÖ ¥7†sëõ¨³R©ŽQPÕ‘‰ ØíÛ‰'Þ«Ùß{ïõ?Žôöî +ë”PXºì¿ÿ:%'·?t¨LFÕìÎF=Ž9Ên=¦¶²Z]±°@ûö¸sx±^OÿþuvpÒØñx01)³¥_?Þ¯¿ÚÉk|̜㘘›#/ϬmÛÒ½ÅÇÛ b¨v®š©ûqð >Þ=Ãmߪ}qöq“1™â[¨ÎåáóÑ­[]œRHÝéÖ ‚ââZådBbcËl‰µéÝ»V Sг¼£~wc :—§mÛ:èèÑ»w—–)ÁI혙ÁÛ[~î\«V­$+$%™3¦y¤»U+ cÈÍ5nÞü*©Ô :Ú†+dd˜øúÖM õ&ø(»Õ`}ø;wbúôŽª‘HJ‡P84¯‡ÔÚ„ ¿üÒöúuͯFFº¸ä–ÿˆ%&šûú–…¼óçÛ•Ÿþ9iS}DmèAüQv76ª7¢äçcÎ|ñ֮Ř15OÛÂBì܉‘ž®ÜHózH­-^l°xq…£(¦¦lË– åÊçÌyýçŸMÜÝÔQTW@§ÇÁi¼»R›Ë³};ÚµCBÆŽE×®øûïj°¸»vÁË#=½{—X§R§¤R´i#oݺ„ûW\¬¹ÏÁëÓ§´Ž³³<:º¾ÚSa>ÁdÚ Jêw7ZjsyæÌÁìÙØ¿!!¸qo¼W_ņ –3.O&ÃÁƒX³@—.X»o¾‰µkKŸšàòeLž\?ï„4EŒáÙ3Þ®]ç[ 5Ü©²nÝÅä¡¡½Š‹ëkRº†@4‚zãÊÂ+Ž —º.‹¹/]p§Qv7råçòðù˜2cÇ⫯Šsçг'†ÇúõðñÑ|¹‡#$qqСÖ¬ÁÛo—ÂÐí(¤>Éå¼S§œ«^?+«³‹Ç4-;t§W¬þoïx ›©6K=ªãüX¾ü†ž?§y=¤®””`Æjï5}:š7¯‡Ö@Ó*k §Ø©žù=±X›x›Ml“„IªºöÏ=B2K®Je“d=2<°X ·t·}lŸ”I«x.¢O|}•kL>­¹Î³glî\flÌÖ¬kÙR¹K»v¥¶g“Vð!Q=Ë™3õ÷nѮʜS³¯b‚Sv7-ÙÙŒÏ/ V>ŸåäTV9!§XýRùÏɉíØÁ*Y~“•]sݺº}„莗'8§º9þÒ§ìnŠNR«Ÿ_•v¹y“Y[+÷Z°€åWa]ì={”» RËV“¦F nedÁ ¯¿þúæÍ›U«­X±bøðájû^¿~=00ÐÌÌL(úúú;vLã)âããAí›ZÕçT=Ç+IpÊî¦kÍe°ÎšUÕ½ª²V½š{÷”»ØÚ2Z¢žTŸZÈ~ÿý÷:uR|)—Ë]\\Ž9¢º‹T*mÞ¼ù×_]\\,“É®\¹òÿ÷U9xU/Á9UÉq NÙÝÔ ¬ Ö}ûªºW \.g66ʽââjÜdÒd©…lnn®™™Ytt4÷å… ¬¬¬ UwIJJ244”Édj‡ÊËË›9s¦­­­••ÕÔ©S \]]üää*]/Ô¨&3z`À¥f—NÍ9Õóãž™ÿd.]±Ô9Áy36sKkDssÈKÖå©[<”_Ò=…¤Ö„Bá°aÃ:Ä}yèСQ£F™”}À “““““Ó»ï¾ûûï¿§¥¥)¶Ï›7/???11ñÉ“'b±8$$äŸþ‰D"‘´lYÕö4¨qös*ê+úàÔï&¥TG66|8»v­J;V·ž“Ã6ndr¯Ù³kÙvÒ•èøóÏ?]]]cR©ÔÎÎ.""¢ü^‰‰‰³gÏöððàñx½{÷ŽÏÏÏ766‰D\…ÈÈHwwwmŽ¢”§šã–ñ–›Ø&.Á¿b_µÉhCÙMclï^e¤rw¤ðxlð`véÒKv¬z‚gf²2ã'Ü¿Žëð}&¢|ÈJ¥R‡‹/?~¼M›6òJ¯¯¤¥¥?¾OŸ>‰‰‰,_°°°°³³Ó­ç¨æ8îá ì&Jªwø-[Æ–.eææ¥_¾ö;{¶Â«’àéélùrfaQZ­_?öûïÊ;_zç"!åh ÙùóçÏ™3gìØ±Ë—/énݺecc#‘HLLLòËÞC• s Î9ÅNõ,ì‰`)ÚˆÛPv“RåçòˆÅlõjåÍ‚½{³“'5ìXy‚§¤°Å‹•c&o¼ÁΟ×pFš×CªIc‚_¹rÅÖÖVõ’¦*‘H´~ýúG1Ʋ²²fÏžýúë¯3Æ&Nœ8kÖ¬¬¬,ÆXrrò™3gÄb±AZZZ-Y÷ ÎéÈ:z2Ï$–TOÇ'z¦’¹<ÙÙlýzfo_új×®ì·ßÊÜÿWQ‚'%±9s˜©ié€Ì°a,2²ÌIi^©…Š:¼¼¼üýý5î’““3vìX''§fÍšY[[1âéÓ§Œ±¼¼¼yóæ988…B//¯mÛ¶1ÆæÍ›gaaaiiY›{Qê+ÁåLÎ+a%õt|¢g^:—G"aŸÎZ´PÖùé'VR˜¦gÓ¦•N»70`£G³[·4“æõÆ®¾žÎ€n?œ4œ—.m,`ñb<|ˆíÛáìŒÛ·1f Ú·ÇþýP}øZb"&NDÛ¶øî;Èå˜8ÑÑøé'øùi8¦ê‰¸õzi\4?›:6dNœ(-ïÛ÷’gvcÿ~l܈ÀÔ……¥/@.‡±1&OƲeps«ì8ŒÁÎNù8ò¸8Z¯‡42ÔG&õ¯ºsyŒ1}:bc±?Ú¶UÆ7##Ì›‡„ìÞý’øÀã•Y)‚æõF‡œÔ?µuyªØ64Äĉ¸{ÞÞÊ¿ý†mÛкuUO­6BHãB Nê_ùuyªÎÀ¶¶Ê/mlªwjZ¯‡4j”à¤þ©F§©)¤Ò†;µP¨ü…q÷.rsîÔ„Ô?JpRÿTüÈxzbûvÔïI¯\ÁÛo£W/å-(%%¸zµ~OJHâ'õ,'11¥e´k‡¤$ÌŸlØ€ììº?ãéÓxí5ôècÇЬ:tP¾D)¤q¡'õ,2%%¥åp÷.~û°nÑ IDAT Ý»#=+V M¬Xôô:8‘\^zä×_ÇÙ³°²ÂÊ•HLÄâÅÊ:”à¤q¡'õLm.‡aÃpù2ΜÁ€ÈÎÆ† puEp0?®á)d28__ ŽÈH4oŽ‘”„uë`oOózH#F Nê™ê(ªaÚ¿?NBd$†Ga!¶mƒ‡¦LAll5^P€¯¾‚§'&MBL \\°c>ÄÒ¥°°(­ãí­¼ƒE,F||-ß!ºƒœÔ§—Îå ÀÑ£¸s“&1ìÛ‡öí1r$®_É‘sr°iÜÜ0w.Ñ®öïG|<æÌA³fejÒ¼ÒxQ‚“úTŹ<íÚáûïKó×ÄGŽ kW „ˆ •E"|ü1Ú´Á²eHMUþ˜8†¬ØGózH#E NêSµæòpc •ŽüóúõCïÞxþ\Y', ..X·YYeÆa *ý$Ó¼ÒHQ‚“ú¤—U\򯄱ÌuÈK—pïžòÕDAA™k¡UÑ­›2âi^iDj˜àB¡P( '|aàÀ[¶lQ­¶råÊwÞyGmß7n¼òÊ+ÀÜÜÜÏÏï÷ßOHH …Õj·ËÇ›7o^³·@ÂK*[++Œ4tÛ[·ÆøñèÖ­G³°@ûö¥eš×C‘&¸D"‘H$·nÝ’&L˜ðÃ?(ê0Æ~øá‡ &¨î(“Ɇ 2a„¬¬¬¬¬¬o¿ýÖÚںƭwssKMM­ñî¤~©Îåáó«‘¹b1/†þ÷? 7ÿ=~ŒÑ£Ñ£ΫFch …4JµYBm¢ÜÜ\Õåã.\¸`eeUXX¨ºKRR’¡¡¡L&SÝèêê @ ‚äädÕê–322†*¼¼¼vîÜ)Ô‘‘1bÄ [[Û… J¥´>§V©®ËchÈÂÃYQÑKvÉËc¡¡ÌÒR}±ùŠþ½ù¦æÕyÔ\»ÆÚ·§õzHãS—ãàB¡pذa‡â¾Õ^ P–Õî69yþþ˜<IIšÛ1c€èhåFš×CÚÄù•@ÿüóOWWWƘT*µ³³‹ˆˆ(¿WbbâìÙ³=<Ÿ¯XûùäÉ“ÞÞÞµyw¤¶Vv{-b~~Ê50/SóèQæã£¡‹íêÊd={*·9ÂÆŒa<žzM¶x1ËÈP39™ÍšÅŒŒÀÌÌØ²eÌÚZY?.®¿„Ô‡:Np©TêààpñâÅãÇ·iÓF®ºâx9iiiãÇïÓ§OUüÑ£G¦¦¦Š:÷îÝSKðò¬¬¬jóîH­ÈåÌÆF™˜±±¬¤„íßÏ\]K·² Øùóe2Vü³³c_~Y:êR~¥ã«WÙk¯iØËÊŠ…†²”¶l33+½™5‹qk¿ù¦²æ¾}ÚüæRGêønBCCÃ1cÆ:tèСCãÆãUzÿ¯ƒƒÃ’%KbbbÔª1Ƥ¿x摽½½T*U|™Tî¯f;;»ââbÕ ŽŽŽuò¦HM”ŸËc`€‰‹­[áà€óçѧqéR™¬Z…°`Œ5¼kWœ>¿þB§Ne¶geaÅ ´j…QP€Ñ£]»À ÍѼÒèÔýýà&Løé§ŸŽ;¦v '###44411@vvöÎ;»tébmm]PP _'''@ðÛo¿…‡‡sAPPÐ’%K D"ѺuëÔŽ, ‡ ¢¨2vìØ:w¤ª*šËclŒwÞÁ AæàbÖ,ÄÇcíZåSM*1h®_ÇÁƒpu-³gwqÁرefÒí(¤Ñ©ûïÖ­›­­­··w»víÊ¿jbbr÷îÝ>}ú˜™™¹ººŠD¢½{÷ÚØØÌ™3ÇÓÓÓÊÊ*%%…Ï燇‡O›6ÍËË«W¯^Š}wïÞ-‰ìííÇ_þàß}÷]NNŽ£££O@@ÀŠ+êüÝ‘ªÒ8—çùs,] //8 ~=ÓÀãÇcíZ´hQ³`Ü8¬_õ—=ÂðáèÝ.”n¡y=¤ñÑö0i¤|}•ƒÎ§O³‚¶eK™‘qÅ¿îÝÙ›o2>ŸÌÜœ}ú)ËÉ)s¨òãà §O³€€Ò—<=Ù;ï0@Ã)Þz‹q7¹ª¶êÌ™†ûnR?hV=©jsyâãáí>RŽŒs|}qü8._ƉˆŠBPrsñÉ'ððÀ¶m(.®ìׯcà@ €«Wáä„Ý»ƒ#G™3Õo:üýwøùaútøù)7Ò@ i´ý+„4FªsyLM5tŠÙÞ½¬ìÄ.Æ»p*o%ù©¿dhˆiÓ°z5*ž¾[ÆñãX¾wïjx).®ÂG–¢hœÔ5µuyðxèß±±Ø´©Jñ ”¹yÜÈH¹}À€2·xWÅСˆŠÂ¦M(ÿüK 'zŽœÔµÇÕ¯X2†³gñÆ8p2Y5elŒà`té¢Ü²~}µ{Í11˜2+WB"Qé¥k¹¢Û(ÁI]kÓ—/#(H}ˆùÞ=Lš//ìÚ…¢¢j°òõw*qãFŽ„¯¯†ß­[#<›6ÕðÈ„èJpRºwÇï¿#* ï¾ >¿ÌKáý÷áæ†/¾@^^}5à Œ®]qäˆúÔ!OO|û-0¾úšÈ„èJpRoüüð¿ÿ!&S§–Ë’‚>P®xY‡þù}û"0'Oª?BÖ×?ü€{÷0mZ…O\!D¯P‚“zæå…ï¾CBæÍSïófdàãáâ‚+ðâ©85$—ã·ß€Aƒ4Ü>Ø­Ží[;VýoBô%8iÎÎØ¶ aɘ›—y);6ÀÕ âéÓjY&áCðóÃðá¸vMýÕ~ýpê®\Á[oѭߤñ¡' ÈÑ›6!) !!°±)óR~>¶n…»;fÌ@BB•ŽV\Œo¾&L(³C†àâEœ;WÕõì ÑC”à¤ÁY[ã“O”„-[мy™—Š‹ñí·ðñÁøñšçàpq?s&<(ó’FÂ8~*¶$¤Q¢9™D« ±g6oÖ°Ð%‡aðb.T®qæ ®\AXD"õúFF7Ë–ÁǧޛMˆn ':@*Å¡Cظqq^µ²RÞ¯bn®á¹Þ¦¦˜2K–ÀÅ¥^›Iˆ®¡':C.Ç/¿`ÃDEUu¡³fც·.!%8Ñ1ŒáÏ?ú’‡–X[cþ|ÃÖ¶¡ZFˆÎ¡'ºêÜ9¬_3gÔ·;:bÑ"¼ÿ~•ÖÒ$¤Q£'ºíʬ_ãÇÁZ·ÆGaútš O‡œèƒÔTüø#æÏ§•„¨¢'„}E3z!D_Q‚Bˆ¾¢'„}E N!úŠœÔJBBÇ …fff]»v½yófµö …>l®ö|« …B¡P(¸3rjÚpBJpR[@"‘H$’¡C‡Îš5«º»»¹¹¥¦¦V¥&w–[·n)Î()¿xqí×í ©W”à¤nŒ1âʳ^ÃÃÃAïÞ½¹b±8((H(z{{Ÿ>}/z⊽ÄbñÈ‘#---íìì-Z$«tm{•¿ùæ›qãÆJ¥`Íš5îß¿ïää ??Ö¬YvvvÖÖÖÓ¦M+,,äîääTƒß@„h%8©2™ìðáÃ:uRlñööŽŠŠÊÊÊòòòZ´h·qæÌ™ÖÖÖ"‘èÂ… (œiÓ¦™™™¥¦¦ÆÄÄ\ºtiÆ •œTcåÀÀÀóçϸqㆣ£ã… œ?>00À¼yóòóóŸ}úœ?þüùó}ûöõóó»yó&×OOO/..öðð°²²²²²0`@vv6333KKË:ùnÒ(ÁIÝ077ß²eKXX—‰YYY³gÏÞ·o_vvvDDc €½½½T*M±,}R¹uyìì슋‹U+(â¾¼J*FDDܼy³K—.‡‹Å¾¾¾vvv&&&Ïž=ËÊÊÊÊÊÊÎΕ_ë‡ýA NêLÇŽ;vìÈuË‹‹KJJlllŠ‹‹·nÝÊUAAAK–,)((‰DëÖ­S;‚P(2dˆ¢BHHÈØ±c+:]%•þùg##£W^ye×®]½zõ200£G^´h÷k&%%åìÙ³õò½ ¤AP‚“º4wîÜ;vÈår‡¥K—véÒÅÇÇÇ××WQa÷îÝ"‘ÈÞÞ>00püøñåðÝwßåää8::úøø¬X±¢’ÓUTÙßߟ1Ö§OR©”+صk—‘‘‘———¹¹ù«¯¾SgožGÏ&$„}E}pBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+Cm7€—))Az:22 A$*-äçÃÑöö°·‡]iA Ðv[ iP”àD'=x€Ó§ˆ¤¤Tu/¡Ý»£o_ €=ÀãÕg Ñ>cLÛm ä…çÏñãØ»W¯*7òùppPv´¹‚™ÒÒÊôÊE"äå)÷jÞ&`Ê´k×ðA NtC^BC†‚°¶Æo o_ôí oïªö¦³²pî""ð÷߈-ÝøúëØ¾^^õÕrB´‡œh›\Žýû±reéhÉk¯aÆ ¼ý6LLjuØ«W±w/~øÙÙ04ÄìÙ ­m4™Á fÁÚnƒvÌÆì¶h«íV4y/báB\»½z!, ݺÕåñÅb„„`×.Èd°±Á'Ÿàý÷adT—§ Zuò$nÝÒv#´ÁÛÇ`MôßIv’-JNfcÆ0ÌÙ™ýð“Ëëë\ÑÑlРҟ¼³3;w®¾NDÜôéÚŽ-ý1‚1Æ ðÀ G¸¶£4œØƒm·¢iûë/LœˆŒ X²~3³z<]»vøë/üù'>øqqèß~ˆÐPÒ½XÄàÁèØQÛh(÷ïãÈÅW Ì@Û¿GÔ`6˜úàZ#•²+˜ØàÁL"iг—”°-[ŸÏÖ»7{ò¤AÏNê×ÿö[m·£=ªìƒÓœLÒ€RR0`BCa`€qüxCÏÁ10À‡âüy8;ãâEøû㯿´„Ô)JpÒPNŸ†¿?""à䄳g±t©ÖfÜôì‰70d220dV®„L¦–R;”à¤þ•” $ƒ!=ƒáæMj¹I¶¶øãlÜ„†bÀ€jÌü$DgP‚“ú÷Ö[øôSðxX»'NÀÞ^Û ðxXºgÏ¢eKDDÀÇh»M„T%8©.€‰ <=a c¹–-á๹HHÐvk©ûïD%>òóñ;EEÚnÐ GŽ KDEÑC ‰ž¢'õ»bSS|õz÷ÖþxEq1,À¨QÈÎÆ¨QèÕKËí!¤F(ÁICyï=ü÷<=qý:ºtQ“ÐЈðpcûv>LS{ˆž¢' ¨S'\»VÚó9k×¢¤¤¡ÛðóÏðóCd$ÜÜpáæÎmèRw(ÁIò°ÀáÃØ¾&&X½nnøßÿÐ0ÈŒ‰Áo`ôhäæbøp\¿Ž®]⼄ÔJp¢ sçâÒ%´iƒÇ1núôAdd=žN,ÆüùèØÿ Û¶áèQXYÕã i”àDK:wÆÃ‡Ø»-ZàÒ%ôèÉ“‘œ\Çg‘J//lßóæ!) óæÕñYÑJp¢=xï=Ü¿+`b‚ýûѦ ¦NÅupð¬,„…¡}{,X€ÌL „[·°m-ò@Jp¢mB!֯ǽ{5 r9öîE—.èÔ Ÿ|‚³gQ\\C1†»w±cƃ­-/F|<¼½qü8þú‹Ì$ÝDEtƒ‹ Ft4¾ûàÖ­Ò•Wx¾ªGppÀ A4£FÁظ>ÛJˆöQ‚ÝÃã!(AA ‘àÉ“2m®ŸGÇ2½r“¶[OHá'ºM(DÛ¶hKkR¢]É$„}E NÑ9r¹\ÛMДà¤&ÒÓÓ/^üôéSm7„4NsæÌ ËÏÏ×vCt]µÿüó¼¼¼Ú0""bذaÓ§OOKKËÉÉ ;}út]µ¶ÎU=Íj>ŠÂçóÇŒ‹}êððp''§Y³f‰Åâ‘#GZZZÚÙÙ-Z´H&“‹ÅAAAB¡ÐÛÛ[ñ½S팫–³³³'Mšdmmmee5qâDnc~~þ¬Y³ìì쬭­§M›VXX¨vÞ¿RÎÎÎï½÷€ÂÂÂððpww÷E‹¥¦¦j»]¤‘øä“Ox<€´´´?üÐÍÍmË–-5Îñ%K–lÞ¼yôèÑÆÆÆ}úôùþûï”+EªØÙÙµiÓæ¿ÿþSd×®]ÎÎÎfffÍ›7 Ó_\aëÖ­®®®W¯^ýüóÏœ/_¾ÌU.e(—¢U|_5Op™Löã?úøø(Ú””””””´sçÎiÓ¦™™™¥¦¦ÆÄÄ\ºtiÆ fΜimm-‰.\¸ðÒ¿_fΜ)•J?~œ‘‘1÷ÅœçÍ›—ŸŸŸ˜˜øäɱX¢vÞ¿R3Ë—/722âÊ_~ù¥»»û|––¦Ý†‘FÀßßÿí·ßV|™žž¾dÉWW×Í›7K$’j*77÷êÕ«#GŽ,ÿ’ư*((ÈÎÎNKK›2eÊÒ¥K¹šb±xþüù¿þúk~~~llì€*:]AAANNNjjêôéÓßyç¼¼¼ÔÔÔ3f,[¶Œ« 1ÊPÃ4c0`¬ÊâããXZZZZZöîÝûÎ;ÜF—••ÅËÍÍåóùiii\ý“'Oz{{K$>ŸŸššªØ(¸¹‚jY"‘**sòóóE"÷edd¤»»»êy«n0 †Ÿ3NMM-**bŒeee‰D¢ââbÆXNNNff¦T*åZ’-“ɸH$’’’ÆXaaaAAW......–ËåŒ1™LÆUn:¦OŸ^þ3efföá‡*>ÌÆ†ìùs­¶´Ro¾Éö×_Ún)#**Šë†«±··ß¸qcnn.clút°o¿­ì8‰‰‰&&&å·k +.UòòòcwïÞµ¶¶æ^ÍÉÉ155=xð D"á¶hŒ/ÕÝ£££UeccÃ*ˆ2V6E+wô(؈Œ1VÃq𬬬¬¬¬ .tèÐAñŸÖÒÒ@FF†‘‘‘·þ7àââ’––&‰ŒŒŒ+9¾H$244TT椧§{xxXYYYYY 0 ;;[õ¼Õµiü¦æÍ›Ÿ;wÀèÑ£ííí#"" >ÜÆÆæüùó† biiyñâE …ÜßA¯¾új³fÍ®^½  wïÞÆÆÆ×¯_Э[7CCÛ7oèÔ©Çã®ôvìØÑÐÐðÞ½{üüüLLLîß¿À×××ÌÌìáÇ\ÙÜÜ<)) @‡¬¬¬’““´oßÞÖÖ–hß¾½ƒƒƒH$âÊ-Z´xþü9WnÕªUNN€víÚµiÓ†ûc³]»vnnnÜßhíÚµóôô”J¥\ÙÇLJ»a«]»víÛ· —Ë}}}ýýýÈd²N:uëÖ @QQQ—.]úôé    àÕW_ ‘Hzôè§è†+äççöÙgnnnK—.åZ«VìÝ;hР7nX²dÉ믿`ñâÅýû÷¿}û6€ààà~ýúݽ{Àœ9s^y啘˜3gÎìÓ§7¨8uêÔ^½zq?âI“&õèÑ#!!Àرc»uëÆý¸GÕµkWîÇ=|øðÎ;?yòÀСC;vìÈýèßxã ___îGÿÚk¯µoß>==À+¯¼Ò¶m[±X  W¯^ÞÞÞÜÇ ÀÓÓ“ûtêÔÉÝÝû´oßÞÕÕµ  €———³³37ÌêêêÚªU«’’­ZµjÙ²%ÆX‹-œœœH¥R‡V­Z(,,´³³kݺ5€¼¼<ggg999VVVmÚ´ðüùs îwFF†P(tuuššjffæææ 99ÙÔÔÔÃÃÀãÇ===<|øÏç{yy¸ÿ>Çóññ騱£Æ®®H$Z¶l™‹‹Ë† ¤Ò—÷ÇmllŠ‹‹sssÕ¶k +ffffffLLLCÒæææGýþûúöí{åÊ•ŠN§ØÝØØXõPEEE¨8ÊP£4«û9™vvvÅÅÅéééÜ÷%))ÉÑÑÑÞÞ^*•ªnä*s½`Ç}:ØÛÛËd2EeÅaMLLž={Ö¬Y3ÅFî?Fۘ͘·hÑÂÄÄ€•••ƒƒƒ±±1 [[[.•„B¡••W633377çóùLMMÍÌ̸²±±±‰‰‰CCCCCC®Ì{@IIIÉ‹åĤR©â3Áõåcòòò¸ßírss³³³¹rvvvff&W‹Åܯnééé\ùÙ³gÏŸ?çÊÉÉÉ999\9)))??Ÿ+?|ø°èÅ"ññññÜÅ \èຠ†††ärù­[·LMM¹ò7™LvíÚ5 ®|åÊkkkÃ&yyyÛ¶m344\ÿ²ŸÅ¿ÿþ»zõꨨ(CCþ}ûnÙ²…ûÞÀn$$üsýú‡~àÆgΜÉÌÌpóæÍÿý—Kɨ¨¨óçÏsÿånݺuéÒ%.1oݺÉeÄíÛ·¯_¿Î¥ç;w¢¢¢¸»)¢££ïܹÃ%ittô½{÷¸rLLÌýû÷¹ŸNll샸OH\\\bb"W¾ÿþÓ§O¹_À Ïž=ã~‚]>ÌÌÌäʉ‰‰ÙÙÙ\ùñãÇŠÖÓ§O¹äädîoMÏž=SÜ‚ššÊ}¶y<žH$2~ñx±X¬øß÷üùsÅG(;;[ÑSÎÍÍåê3Æòòò¸ €‚‚Åǯ¨¨ˆ{SŒ1©Tª8Ž\.çÚ ú‡U¼~S³fÍ,-- Ô;å™››üòË/S¦LQÝ®1¬*9Λo¾ùæ›oJ¥Ò­[·Ž?þìÙ³åãë¥4FY-T%Ó§ZµIDATEñ‡CEƒ‚‚&OžœŸŸŸžžÞ£GÆØÛo¿­ØØ§O®¾L&³´´­—ŸDEÞ|“×·o?uê”X,fŒ)œ1vóæÍsçÎq¿#£¢¢"""¸ß¯\šs¿/¹4çþ®¿}ûöåË—¹Ð¼sçNdd¤âïèk×®q¿S£££oܸÁ…é½{÷¢¢¢ c±±±·oßær!..îîÝ»ÜàÞýû÷cbb¸ÀMHHˆ‹‹ãÊ<à~³?bî#‘˜˜øèÑ#®üøñ㤤$îGÿäÉÅÇ#99999™û<{öìÙ³g\9---==+‹D"®£ —ËÅb1÷MËåÏŸ?ç¾ r¹<;;›{ãr¹\"‘poV.—çççsoP.—roJ.—sgŒÉd2Å ®Uª*EqrrÚ¾};÷«Ê( cìßÿµ³³;|øpQQQIIÉùóç'NœÈ4…•ƱÆXJJʉ'¸ÿ°»wïöððÐ_í®Z.e¬‚hÕHu¥^<==}øðáæææ666óçÏç>‚éééƒÞÞÞ;wîTÔÿþûï­­­·nÝªØøüùó±cÇr£í“&Mâ6æååÍ›7ÏÁÁA(zyymÛ¶M_¼±***âþ|Veaa±råJî¿}©J< à›o¾QÝ2gΜ÷ß¿¢O^^ÞÌ™3mmm­¬¬¦NÊeDµ*k@ãà:éwÞQûtµlÙ2<<\õçXÅgŒ]¼xqÀ€––– k×®dšÂª¢ÏÒ“'OzõêennnffÖ¥K—‹/2MñU•/e¬Á¼ ¯+»víRýßeiiùñÇs}Ø2*Npîp®7§áééYѧÊ”)&LÈÍÍÍÍÍ6lØÒ¥KYÅÿU4VÖ€\÷ܺuKµÞ²eË­[·–ÿ\õo4TœžMHj¨¨¨(44”+[YY-X°`Á‚ÖÖÖÕ:Hff¦‰‰ 7°® ¸Z[^AAÁ¡C‡’““¹{oW®\9vìØ7Ö¾2Ñ5kÖ¬aŒhÑ¢ÅÒ¥KgΜYGÇ %8©¡={ö<~üØÚÚzáÂ…ÁÁÁV5Zú»I ''G5ÄÓÓÓ+úM ¸ŽÏ}É3®x‡jU&:åÎ;¿þúkóæÍ—,Y2{ölÊîŠP‚“š(**Úµkך5k‚ƒƒkv7'ÇÂÂ" àðáê÷•ÿôÓOýû÷×xŸRE×ñ«U™è¾Ý»woÙ²eöìÙÜ­x¤"ôlBRb±øêÕ«üqm⛳iÓ¦eË–=z´¤¤¤  `ëÖ­?üðòeËœœœÁo¿ýVTTÎU£G^´hw?_JJÊÙ³gT«2Ñ}[·n]¼x1Å÷KQ‚“šhÙ²e]HôíÛ÷èÑ£[·nå·qãÆÿý×ÃÃÏ燇‡O›6ÍËË«W¯^Šú»ví222òòò277õÕW¹ 5ÕªLt7©‚TÝ‹Bê[•gÕß¹sÇÚÚzÿþý Ш2è^½ÕÄïE¡_tD‡tèÐáäÉ“OŸ>UÌß#„T‚®dÝÒ½{÷îÝ»k»„èêƒBˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœ4”?Dq±¶¡ÉÉ“¸xQÛ ¤&(ÁIýûì3˜˜à»ïл7=ÒvkTcÑ" ‚œ  •‹¢(ÁIý›2—.ÁÝ×®¡sgüú«¶HJÂ+¯àË/ad„ðpüñÌ͵Ý&Bª‡œ4ˆÎqý:FŒ@VFŒÀ¢EZQùãtîŒ+WàêŠ 0¾6CHMQ‚“†bi‰_~ÁÖ­02—_â•W”¤…fH¥X²Æ!3Æáúuh¡„ÔCrÈ=á©í–4œ¤h» MXp0zöĘ1¸r;#43f ÁEŒÅ„ ¸~FFظ‹Çk S“ú´y3öï×v#JF†²\ºFO´ÓÒàæMŒ?ÿÄìÙøê+„…¡ÿú=ir2V¬À` ­[ãèQtíZ¿g$ èþ}Ü¿¯íFhï{ í6hGs47ƒ™¶[Ñ´=Š%Kðà¼ý6¶l‡GÝŸ¥ ŸŽ‘—SS,^ŒåË!Öý‰ˆ6$$ 5UÛÐ;;øø€ÇÓvKHVT„/¿Dh(rr`d„… ñÑG°·¯›ƒ3†_~Ap0RSÁãaäHlÞ —º98!:€œè€´4¬\‰½{!—ÃÈAA˜9Ö|úöm8€ï¿‡H]º , uØdBt%8ÑOŸâã±?är06FŸ>èÛ^^pr‚ìíak«ë¹¹‰‘‘))8{ý…¬¬ÒWmm±d >úˆ®X’F‰œè±{÷âÈ\¾¬áU¯4Ê…B¤¤ %¥4îÕ´háÃñÞ{t§ iÜ(Á‰®ÊËéS8s))Ê^¶X µO¬¹9ìíKc½yst놾}áí­¥FÒ (Á‰^a¬4Ê%´l‰–-î^rBtÏÿª«Sÿ#VæIEND®B`‚rsyslog-8.2512.0/doc/source/PaxHeaders/rsyslog_confgraph_complex.png0000644000000000000000000000013015055603742022571 xustar0030 mtime=1756825570.263068491 28 atime=1764931128.8311221 30 ctime=1764935922.757570058 rsyslog-8.2512.0/doc/source/rsyslog_confgraph_complex.png0000664000175000017500000042754415055603742022257 0ustar00rgerrger‰PNG  IHDRP—ómûbKGDÿÿÿ ½§“ pHYsHHFÉk> vpAgP XU°€IDATxÚìýw\÷þÿ?v—¥#UŠ(6°cÁ†½w±aÁ‚%±ÆÞMLb4‰-cbŒGÆbï½WPQ¬  "* ½·Ý¹þøó½rò9ç$ꪼîÿxËì2ïç¼goáÉÌìŒJù'„BQb¨ @!„ož‘¡!Ä3¿g~Ïü`¿Ñ~£ýFjjj ª‘ª‘ª‘€‚ÂÛ|œÒ[lA™­ÌVfƒEŠEŠE t×u\×qPubÕ‰U'‚ê¹ê¹ê¹¡Ã ñÿQÉ)!Ä›–=9{röd8ÔýP÷CÝá°ýaûÃöàvÀí€Û¨u¥Ö•ZW@å®rW¹™d’ièÔÿ‡F4¢èëëCL‡˜1 bJÄ”ˆ)Ðâ‹_´ø|³}³}³Áî˜Ý1»c†-J:)Bˆ×Ng¢3Ñ™ÀÕaW‡]Aß}ô=hÖjÖjÖ Aƒ ^#¼FxÍÍÍC§þ\pÁîëîëîë °]`»Àv0#aF è;¯ï¼¾ó µ}kûÖö`²Éd“É&C‡%!Ä«W—ºÔ…˜f1ÍbšA`ëÀÖ­áÉ“&ÐóÇž?öü:÷ïÜ¿s0ûÐìC³!eqÊâ”Åp1ùbòÅdȘ•1+c¨WªWªWòÖ P:(”`z×ô®é]hfÖ̬™”©]¦v™ÚPÔ½¨{Qw¸Pp¡àBlÓnÓnÓ‚Ý&»Mv›`È€!† €_ÕøªÆW úLõ™ê3Co•xßIB¼2YͲše5ƒ}“÷MÞ7N,>±øÄb¨;§îœºsÀïŠß¿+à²Üe¹Ër(š^4½h:œß~ÿùý°½þöúÛëƒæææ¸å¸å¸å¼üoå²rY¹lè­ü#UUUxžö<íy¤ú§ú§úC‡= ³®³®³Ìš/4_iåÒÊ¥•ƒ=c÷ŒÝ3Ο)>S Þ›¼7yo‚þ¾ý}ûûBéoJSúCox_IBüeEnEnEn21dbÈDØÚck­=À"À"À";vì unÔ¹Q稂TAª ¸×è^£{ Ð%Ð%Ð’þ‘ô¤@ß«}¯ö½ ­ú·êߪ?˜¤˜¤˜¤z+ÿ{Å{Š÷ïÐJ¡•B+ÁÖÎ[;oí êáêáêá0H=H=H ^ã¼Æyµ³ÚYí ¶<Úòh > |øž9=szæ½§÷žÞ{:´Éh“Ñ&ÌUæ*s•¡·R¼/¤!þkÊfe³²¢—F/^ åÊ”ƒ§6OmžÚ@oÓÞ¦½M¡½¦½¦½L×™®3]ÉaÉaÉa°Ój§ÕN+¸”{)÷R.´œÔrRËIàëçëçëvãìÆÙƒÜ/r¿Èý”yPæAÈ3Ê3Ê3Õ(Õ(Õ(CÏÂïæc—²KÙÆ?ÿhü#Tʪ”U) l.Û\¶¹ 9Ãs†ç ‡Ce•=T?tþÐy¨Y®f¹šå``ß}ö…r½Ëõ.׊sŠsŠsà’ú’ú’¶®Þºzëj°p·p·pÿŠþý+‚ç Ïž3@}\}\}Üг ÞUR„ÿQzÿôþéýaOõ=Õ÷T‡ÓV§­N[AãøÆñã¡ß'ý>é÷ 898989@¡}¡}¡=œúâÔ§¾€ÝwvßÙ\×»®w]C̆˜ 1ƒ*ÙU²«dƒrU¹ª\…°åaËÖÖá[†o)­SZ§´ë@ë@ë@P"”%Âг¨P¡ÕBÕBÕBÈZµ:k5×7®o\–Xj`)hººéꦫA»V»V»bbb hTШ Qp÷—»¿ÜýºÌè2£Ë èþA÷º–Û,·YnƒÌ#™G2À>Í>Í> œ¨|¢ò‰ÊàuÖë¬×YÐd@“MÀ¥†K —†žñ®‘ „øƒÂ…= {ÀE“‹&M`{æöÌí™`jj ƒž z2è ÔxPãAÀÎpÂï‡ß¿½{ö‚ŒmÛ2¶Aûþöýí¡ydóÈæ‘ =¬=¬= qÇ}÷1l­¼µòÖÊpÇìŽÙ3èäÜɹ“3ttêèÔÑ JÍ,5³ÔLP)‹”E†ž^€‘È;“w&ï \ìp±ÃŰ»öîÚ»kƒë×®#`pÚà´ÁiP¥s•ÎU:ƒî¶î¶î6ÜH¼‘x#¶tÙÒeK(6.6.6¿»~wýîB£'ž4zFmŒÚµÇ¾}ûBе kA×à¡î¡î¡zÔìQ³GMèЧCŸ}ÀbŒÅ‹1†ž$ñ¶“ „@Ñ):EQË¢–E-ƒ€À€À€@xÞýy÷çݡƒú‚¶ß´ý¦í7`¼Éx“ñ&Hì“Ø'±l7Þn¼Ý®Ö¿Zÿj}hÿCûÚÿ½2zeôÊë ë ë Èi’Ó$§ n{¸íá¶ppæÁ™gBõÀêÕaðóÁÏ?‡r_•ûªÜW†ž•¿.¹Mr›ä6°Ã{‡÷o111‡–m[¶mÙúô èv?Ùýd÷äõÏëŸ×Ž… 9ûÌö™í3÷8÷8÷8œ;8wp.T¨R¡J…* ;®;®;WG]uula [£›F7nÂà&ƒ› nõÆÖ,hºhºhºzVÄÛF €%XÊÜ”¹)sa×Ï»~Þõ3\8zá腣ТA‹-€ïVß­¾[Á¾¯}_û¾““'¾>ñõ‰¯ao½uöÖ ]*t©Ð6l •ÊT*S© èÑ£®/½¾ôúRèÐ%  ¨\T.*|lð±ÁÇ þ¶úÛêoÍ!Í!Í!CÏÊ«£ªª ÷ï;Þw„€Þ½z˵/Ö¾X ýû;öw„Ö¶þ°õ‡  ÐhàyìóØç±°íãmoûÂú†õ ë tttÐ3¹grÏd(5ºÔèR£!35353Ž4>ÒøHc8\|¸øp1xÖð¬áYÞxkà-puu5ô¬ˆ·…!JŸŸ8Wç\su`çí·wÞ§>N}œúÀàCƒ >ÕÎU;Wí(éJº’7»Ýìv³v ìØòªæUÍ« Æ ‡ÆFvœvœvµvר]cw (W»\írµaÈÕ!W‡\÷Ûî·Ýoƒþ{ý÷úï!¬eX˰–°:`uÀêðJðJðJ€ ùò'äËXÆ2CφxÓ4_ü“¡ƒ!^¿“åO–?Y*׬\³rMÔgPŸA} h\Ѹ¢q°¿óþÎû;ÃjV³°g;ÏvLº1鯤ÐB×B×BFéFéFéâââ ßýîèwG!±|bùÄò0:`tÀèè9µçÔžSÁº·uoëÞ†Þú·™ÖLk¦¯k^×¼®gˆgˆg_ ¾|v{ïöÞí ZµV­UC¥ó•ÎW:Õ÷TßS}4ñlâÙÄb2b2b2 °|`ùÀòá”á”áîÝ/º_„ŠC+­84·4·4· *-*-* ZÎj9«å,P›«ÍÕæ†ž ñ¦ÉÓ…(A4Õ5Õ5ÕÁx¡ñBã…À&0.^¼xñâEØztëÑ­GaÚøi㧇†ÕVoX4& <ªø¨â£Š49hrÐdxìöØí±ô íÚ3Úïh¿£ý0555ôÖ¾CV±ŠUàÀ§e?-ûiY¸ôüÒóKÏa[Ýmu·Õ…ó{Îï9¿4bШ•V+­VŒë<®ó¸ÎÐÚ¥µKkX~où½å÷@ÓAÓAÓ†2”¡€ö¦ö¦ö&m5Új´ÃÆð¯S ¢d‘ DI’DI ü ü üðrqVLVLV Ôq«ãVÇ ¼ã¼ã¼ã À¬À¬À ¶ßz|ëq86áØ„c Á„L€…çž[xœf9ÍršÌb³ ½‘ï¾ßÎå·¦5­zëë­¯·ö=Ø÷`ßø¦÷7½¿é mÚ6´…á©ÃS‡§BÍû5ï׼͌š53‚”A)ƒRýnÅ1ÄJœ§Ä/xÁ Co­0µ¡! ï·Çîªïªïªï¾\~gÖYwfÁÞ{îÓwMß5}L¨1¡Æ„à´Ëi—Ó.C§ÿY´i=üCýCýCáónŸwû¼œÙxf㙪 U…þþÁÎ8ã ªMªM*yÊ øR„ªà»‚ï ¾ÇŽ@au†Õêöêöêö¯~¼a/Â^„Atqtqt1(þŠ¿âoèYx{¨¨¨€{k÷Öî­¡^ûzí뵇Â*…U «:x×HBü¹V´¢ÿz¾= ¯ñ;CÁŸü)l´yÐæAPÔ·¨oQ_COèëêëêëB¾{¾{¾;/op`(7¸Á Pò•|%ßг#ÞUR„†WH!…Ðv[Ûmm·ÁDωž=ÁèÑ£ ë«ë«ë :‹ÎŠÚµ)jú²ú²ú²ÀyÎst_é¾Ò}ÅaÅaÅaPä\ä\ä ÅÅÅÅÅÅ/‡Ó××ÝGºtÞxã ú†ú†ú† ›¥›¥ûݵ —\zpélûzÛ×Û¾]œ.NÜæ6·A×C×C× ,<ú•ú•ú•†žT!þor Âàô+ô+ô+àtÆéŒÓpÚî´Ýi;Wi\¥q•`õðÕÃW<€‘…‘…‘ÄV‹­[ &L ˜î¸sà\Kº–t- ll°±ÁFˆÛ·)nøîöÝí»ŠÔEê"5üôóO?ÿô3Ì<2óÈÌ#1.c\Æ8X7jݨu£`ôíÑ·G߆ )R6¤@êG©¥~îÏÝŸ»?ënÖݬ»Ážö|´ç#0›f6Íl”ïT¾SùNÐ;§wNy…x›È!„Á©g«g«gƒÛI·“n'án™»eî–Rß—ú¾Ô÷R1¥bJE°µµµµµ???ˆ<y:ò4Üȼ‘y#¬o[ß¶¾ ™¥3Kg–†!‡<òÜκu; ÿ¸÷{ÿ¸.]:»t†Ç<þàñ}=ûzöupoáÞ½DOž=´ÿÐþCû(ëVÖ­¬Ô©]§vÚÐlJ³)ͦÀ¾zûêí«ñ·ãoÇ߆aµ‡ÕV<}<}<}€{Üãž¡gWˆO €â­¡IÔ$jA½L½L½ Ô±êXu,¨²TYª,0úÊè+£¯ÀRo©·Ôƒq3ãfÆÍ wYî²Üe ŽPG¨#Àh…Ñ £`êjêjê fffð¤Ã“O:@q|q|q<¨SÕ©êTP%©’TI >¤>¤>ª`U°*Ô¥Õ¥Õ¥AÝOÝOÝŒ-0Zð2o=Ïzžõ­Ú´jÓª ü°í‡m?lëëë˜å?Ë–?$x&x&xzR…ø÷¤!ÞÙÛ²·eoƒ‚ô‚ô‚tHë–Ö-­ä·Ëo—ßr»ävÉíEŠ:u‚‚Ç CîªÜU¹«@Y¦,S–A~ùüòùå!¾l|Ùø²ömØ·aßBƒ”) RÀÒÌÒÌÒ ´Í´Í´ÍàYýgõŸÕ‡ · · 7(šV4­hä×ɯ“_LT&*Äí‹Û·RN¦œL9 'žœxrâ YYYA{Óö¦íMÁøcã?†â§ÅO‹ŸzV…ø÷ä"@!„Á´-h[ÐÒ§N; ÍmšÛ4·È#Œüjͨ5£Ö °,oYÞ²<ÄùÆùÆùB u6ÔÙV&V&V&‘‘ ªU‚ ŽŒ;2îÈ8°«jWÕ®*t«Ú­j·ª`ínínícŠÇ)†èºÑu£ë‚&H¤ ‚6 Û,l³”1Êe tÏêžÕ= v5ÝÕtWS¸¼òòÊË+Áv¾í|Ûùp±èbÑÅ"Py©¼T^0½ÙôfÓ›A™‚2e =»Bü{R„grÚä´ÉièF7ºݶtÛÒmËË×{Ñ‹^¿ÿ–´¤%|>úóÑŸ~¹xÛm7¶Ý€ §*œªp †Ž:nè8ÐZk­µÖ·G·ÝztûÝW\q…nm»µíÖöï¯Mmjÿ›ü¿Ý.sÌ1ç__Kâm&§„î·sâ¯ù@;æ\Ý\Ý\x¶éÙ¦g› ëJÖ•¬+ðäô“ÓON:Ýkàƒ>r«_ñ÷È!ÄŸRg¨3Ôz2õdêIH¼˜x1ñâËkäÞ¿}[`ÄÚkG¬…ÁUW\l;Ûv¶í ô¦7ïÑãˆ3g,ÎX n=ºõè4 oÞ0ÜЩĻFŽ!PN+§•Ó@#Ñèåòê‹«/®¾<{6öl s§Î:w*J:”t( ò~Èû!<ì+óÛ_ÂöííÛÛ·7770000tº¿¯h|Ñø¢ñpÑõ¢ëEWøÄùçOœÁ®µ]k»ÖPײ®e]Ë—ïW7Q7Q7%T Uä±ÌâOHB`tÎèœÑ9¸oußê¾<òlȳ!`Óܦ¹Ms˜•0+aVøÿâÿ‹ÿ/pÀâ€Å‹—O¥»}÷öÝÛwA¿H¿H¿ÈÐ[óîS6(” ðèÞ£{îÁ"Õ"Õ"l8ºá膣Ð% K@—€—Ë]r]r]r!uNêœÔ9pÇåŽË0±1±1±ùýŠßîS9âÍ’ D ¢_¢_¢_úúú/—7û¼ÙçÍ>ÏIž“<'Á§‹?]üébØn·Ýn»ä7Ìo˜ßZ¶*lUKÛ.m»´-xnõÜê¹–]]vuÙUø!⇈" alÂØ„±†ÞÚwOzZzZzl²Ùd³É¾þ"ø‹`°Í´Í´Í„ESM]4|’}’}’AÝJÝJÝ Ž 8³ÊÎ*;«,X&Y&Y&OªOªOêËõ+U”*JP¦(S”)@6Ùdz«…¡¨”2t!Äë·ÎbÅ: 8Þáx‡ã`Ⴥ>£G=Ž‚îÝ7ºo ¬_X¿°~°¥ý–ö[Úƒî¡î¡î! j;¨í ¶Ð0½azÃtммм€èMÑ›¢7AБ #AGàQ³GÍ5ƒž7{ÞìyÚOi?¥ý°ð´ð´ãüKa\a\a\jq©Å¥°í̶3Û΀mÛ&¶M`PÄ ˆAP3§fNÍ „B "6"6"mmm!-#-#-úŸí¶ÿYh>¨ù æƒÀ¸¯q_ã¾ðÜë¹×s/XÑxEãÁ¦”M)›RðqÃ~ÜT}U}UoÁSÅ›%@ˆ$õJê•Ô+°µxkñÖb¸Üër¯Ë½ 5­i ôZÞky¯å`7Ôn¨ÝPÈ«–W-¯™wdÞ‘y°¿Ïþ>ûû€‡‘‡‘‡ é6¤ÛnP¾zùê嫃n‚n‚n\i|¥ñ•ư¥ü–ò[ʃö²ö²ö2 >døáPwXÝau‡¦£¦£¦£¡gå jG;ÚAT¥¨JQ• À<À<ÀâæÄ͉›}ö=Ú÷(´mÚ¶iÛ¦`RÕ¤ªIUHê’Ô%© lwÜî¸Ý®L¹2åÊh»»íî¶»¡wtïèÞÑ`hh9ù9ù9ùp$äHÈ‘8Øë`¯ƒ½ ZnµÜj¹àç箎®Ž®Ž†ža(R„(ôAú }Ü+u¯Ô½Rp*àTÀ)Hš24e(ôwéïÒßZílµ³ÕNЎ׎׎‡ç}ž÷yÞ¶žÛznë9¸©½©½©…Ï:<ëð z÷4îi VŠ•b¥@fÿÌþ™ýápåÕW†#;ì<²jש]§vðã7Æo ¸vpíàÚáïo×Û*µjjÕÔª°K½K½K çÇž{~,4_Ù|eó•àââNNN_%¿J~8ñʼn/N|{Gíµw¸ítÛ鶆,²pÈB¨S9¦r è;ë;ë;Ãõ×7^ßÓ¦Lîr—»0hì ±ƒÆBýŠõ+Ö¯FµŒjÕ2ô¬C“ „  IA“‚&pnƹçfÀÎ;;ììŽ+W8®€Á&ƒM›@µnÕºUë,g9Ëá–Å-‹[˜˜˜¹r7än¿ñ~ãýƃ÷ïÞ@{L{L{ žV{Zíi5Z´6h-Ükt¯Ñ½FÐíÃnvûºôíÒ·K_°ìmÙÛòþÚ^~~~~~>œßq~Çù°kÍ®5»Ö@饔ƒsçÎ…j«u¬Ö˜Ç<æÁ­ž·zÞê «W®‚\u®:W ~Q~Q~Qàíëíëí ÚMÚMÚMð´áÓ†OBÐÞ ½A{á^Á½‚{Ðmx·á݆C—y]æu™–í,ÛY¶3ô¬ˆ·!ĤÖI­“ZvUÚUiW%8owÞî¼4?Úühó£Ð×¶¯m_[°¿k×þ.ä×ͯ›_N|zâӟž&{šìiåï–¿[þ. 5dÔQP9¡rBåÐ{é½ô^p½úõê׫C@ã€ÆAùPùPùÏÓ|<ãÏ ½u¤4R)@ó¡æC͇Ðq]Çu×A½õõÖ×[êPu¨:¦?L˜ÁÁÁ÷CÜq?@ï*½«ô®mú´éÓ¦˜Í5›k6×Ð[%ÞwR„¯]VpVpV0ìß·ßþ}p<÷xîñ\¨S­Nµ:ÕÀ¯¾_}¿úPÆ»ŒwoC§}uRƒRƒRƒ`Ï{~ØóœÕœÕœÕ@“êMª7©ýõ?Ôÿ8Ä9Ä9¼Åßrï')Bˆ7çŸÏ±ý$úI4 <x ¢2¢2¢2 í…¶Ú^€·jܪq ˜Ît¦9äó7Æ- €P·W·W·šÑŒf Ÿ£Ÿ£ŸØ`ƒÍßXuªS”^J/¥<«û¬î³ºpÌì˜Ù13°oc߯¾ ‰?$ª_®~¹úeP}«úVõ­¡wŠ(©¤! F7V7V7BcBcBc`‡²CÙ¡@þÃü‡ùA® W…ÅSü×ÇQmVmVm†§fOÍžšAÑ‚¢E À½·{o÷Þ Ÿ¯Ÿ¯ÿß.PUPUPUÝÝÝ0jjÔÔ¨)tŸÚ}j÷©Ðʾ•}+{0™l2Ùd²¡g]ˆÿ!Ä[C÷L÷L÷ t: PDE€ ª¿¾^µƒÚAí>ØðÁ† uTê¨ÔQ0Ûj¶Õl+(r.r.rþÁõèѦ˜b šAšAšA ™®™®™Î¿ž ÄÛÄÈЄâ7šršršr Aƒæ5¬ßÈËÈËÈ Œ† 1ªÇªÇªÇ`Œ1Ưr Ãæðš4!þ"µ¡!Ä£  Ç;…¤!„%’!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!D‰¡š©š©š ”¢¥ FÃ’ „xïê u…:H\Ÿ¸>q=¼°xañÂÒï¥ßK¿YyYyYy²1ecÊFH“8&q äµËk—×ÎÐé…x3TÊ?:ˆB¼*wMïšÞ5¿î~ÝýºCF¥ŒJ• §QN£œF OÓ§éÓÀj–Õ,«Y`ee+mWÚ®´…FŒ:z+„x½ä#.„x︪\U®*(g^μœ9„þMø7|_dµ}kûÖö…Zk5®Õø†oøæUˆw‹œB¼wlólóló “k'×N®`ôØè±Ñã?û¾íû¶ï N*'•“ÊÐé…x3ä€â½Õ–¶´\º4tiÏxƳ߽nkk ²:duÈu5u5u5C§âÍ#Bˆ÷–Ç_x|555|½öîÚ»kúºúºzC§âÍ’ „xo™™˜™˜™@ë.Ö]¬A½Z½Z½T¦*S•)´ú±Õ­~çÎ5œk:­o–!Ä{¯‰{÷&îà1Éc’Ç$°ÚhµÑj#t=ÓõL×3†N'„aÈ5Bˆ7¦0®0®0n=½õôÖSH³N³N³Uš*M•¨Pñ /ÂSõUõUõ…Âã…Ç C©U¥V•ZŵŠkׂ¸Œ¸Œ¸ 8UæT™Se@¿S¿S¿ó5løINrLZ›´6i š7hÞ 9˜«ÍÕæòg˜0)Bˆ7&ø@ðà°tçÒKwBÍ{5ïÕ¼ššš@"‰$¾Ââ'~µ§ÚSí îÝ/º_„ì¢ì¢ì"¸5áÖ„[@ÿ‹þý/¼ü^à«b‹-¶ Ú¨Ú¨Úaéaéaé0ìÖ°[ÃnÁ ‰ƒ&šø&÷€/É€„¯]ÖŠ¬Y+`Nòœä9ÉÐIÕIÕI>·|nùܽJ¯Ò«€\rÉ}õã«n«n«nCš>MŸ¦‡LÿLÿL(ï^Þ½¼;({”=Êž×°áZ´hAõ™ê3ÕgÚ<´yhsøéÀO~:_úzÔ×£À5Þ5Þ5þuï!þ_R„¯Ý¶úÛêo«¡ñ¡ñ¡ñðåÚ/×~¹Ì|Ì|Ì| îÍÑÏÔÏÔÏ„¥ÉK“—&ƒiGÓŽ¦aJÄ”ˆ)À—|É—†N)J 9û$„xm⿈ÿ"þ 8b}Äúˆ5 ðà=À»äýâÿúõ7êo`€f€f€nøÝð»áwÝïºßu7t:QÒHB¼6»ï:¼ë0xÄzÄzÄ‚×~¯ý^û Êð*®¯¸¾âzhÕ¡U‡V ¨{P÷ îP¸±pcáFC§%…!Ä+1&bLĸ}=úz4ø­ñ[ã·4:N£3tº·G9=æô˜‰J¢’¨@0Á:”(1¤!^™â-Å[Š·ÀÖò[Ëo-ÍM››67…Êm+·­ÜÖÐéÞ>íÚ;´‡Þ {7ìÝvì(ØQ™Ó3§gN7t:ñ¾“ „xeBrBrBr ^¯×B =.ô¸`èTo¿¶ËÚ.k» Lê™Ô3©ÇN;u씡S‰÷!Äß–µ0kaÖBØæ¸Íq›#ôXßc}õàXѱ¢cEC§{û™ùšùšù³fÌàÈ¥#—Ž\‚„2 eÊ:x_IBümǦ›~l:Í5šk4Újw¨Ý!C§z÷4´mhÛÐ*i*i*i`ÇÒKw,Ô¨åÿÖâU“”â/Kx‘ð"áiq¤Å‘0à耣Ž‚…»…»…|­í¦.§.§.~^~^~^úIè'¡ŸÀ½û÷îß»oètâ}#@ñ¿{Ä#ÁžN{:íéå生S~4®Ý¸vãÚ†÷îsuu…æ™Í3›gÂÖè­Ñ[£¡¸iqÓ⦆N'ÞR„ÿ³ÈŸ"Šü .Ç\޹¿øÅÀ/@ªNU§:Ý{À , ÷²ÞËz/ƒØò±åcËÃå)—§\žbèpâ}!@ñ_+._\¾¸üË¿H½ïzßõ¾ ·=n{Ü6tº÷Oé‘¥G– >w|îøÜƒw Þ1rkçÖΕ#-âo’ „ø¯]=põÀÕðÄø‰ñcèãÛÇ·¯¡S½ÿ:tëЭC7PÍTÍTÍ„£7ŽÞ8zÃЩĻN €â?Êyó çl»}ìö±Ð=¢{D÷p q q 1tºW§(ª(ª( 2¿Ìü2óKPZ)­”V†NÐÿJÿ+ý¯À¢EŠ É+É+ÉËÐéÄ»J €â?:yñäÅ“Aï¬wÖ;C§…vZhèT¯Þ~wúÝé_ø|áó…¤·Jo•þ€ß4œÕpVÃYP~PùAåÁî‘»GîièTâ]%@ñ§^¤¾H}‘ çœp>ô›Ûon¿¹`ÑÝ¢»EwC§{õܸ/p_cöÙ7fXeYeYe:ÕKÚNÚNÚN0°ÖÀZkAHnHnH.D}õMÔ7†N'Þ5F† „x{íé»§ïž¾PƸŒqchr¾Éù&çúÔ§þëW—®Kץá‡:Z>hù %TN­œZ9¢NFŒ: n*7•› LãMãMãáÑ7¾yô t\ÐqAÇà9ßs¾ç|x¸àႇ àä‘“GN}”>Jå”oP¾tÊî”Ý)ï{¼ïñ>8yòäÉ“'¡‡S§Np¾êùªç«‚2X¬ k¬±âcâcâc ¿_¿þ~àÒÑ¥£KÇ׿_ªzWõ®ê ¯4¾Òø lËÞ–½-涘Ûbn P_P_PË-˜Å G„ððÙÃgŸÁÅЋ¡CÁ¯À¯À¯Œ¦M5šúúÇרhl46~$ýHú‰ ‰ ‰ƒÆWh\ŠW¯.^ G¶Ùrd xû{û{ûCQó¢æEÍaCƆŒ /×—u"ëDÖ ¨v Új Qq£âFŰfÑšEkÁc£ÇF ô†ÒJo€ƒ.]º@ö¦ìMÙ›àÁƒ<€‡þýúC‹ -.´¸·gÞžy{&ì»»ïî¾»opu¥+]¡÷„ÞzO€Ç¾}ûBhHhHè{tM†x½¤!þEo£·ÑÛÀ¶Äm‰Û¡á ?høT^ýyõço>i5Ój¦ÕÀt¿é~Óýàbëbëb îöîöîö ›¤›¤›Îõœë9×ƒŠ³+ή8^Œx1âÅ(ÞS¼§xTJ«”V) >søÌá3(Ø\°¹`3dÎÉœ“9²‡gÏ3-fZÌ###0l4Øh0˜L4™h2Ì{š÷4ï Î'œO8ŸçcÎÇœAÒá¤ÃI‡ßüü¸”v)íRº:uuêêAÓƒ¦M‡\×\×\×7ŸG¼[¤!þåÚ¶kÛ®mƒ‡ÕVXúzöõìë RH¡)((@4ÑDÿn¹ *Àlþ¸\µTµTµ 6l,Ø+-WZ®´„í·:Ü žn|ºñéF(jTÔ¨¨¨>U}ªúУGÿorSL1K,±¿[þÏöЂ´0ÀüüS§ÅwZ ÅÅÅp2ðdàÉ@Ãåï)BòÏåŸË?ÛömÛ·mtV:+pé2ÒÅ€W™ëÓôiú4Ð5Ö5Ö5ý3ý3ý3ÐÇéãôq k¢k¢kŠ•b¥Xýnùºu?BÎÚœµ9ká|íóµÏ×ï™Þ3½gB—Ó]Nw9 f­ÍZ›µ†âàâàâ`ЫÿVÿ-èÓõéút(ÖkŠ5 ?¯?¯?:{½Îþwù¬ôVz+Ðyè‚Ù}f÷™Ý†,²xÈbh}²õÉÖ' l3˜EcŠÆjPƒ ¾®¾®¾ú|}¾>ŸzW_S_S_}–>KŸ bƒÀ(Ù(Ù(¨Le*CaÂ:…u@µLµLµ TZ•V¥uOuOuOPf(3” ¯«¯«¯ 8á„I$‘ º©º©º š'š'š' ;§;§;Le*SÁ¨•Q+£V ²TYª, 7}‡#G†%O–/óy™ÏË@åž•{VîiÀý*Þ*R„(Á6žÚxjã)xð݃ï|óÍ[4o˜Ô2©eRËÐéÄ_N8áðýåï/²_d¿È~³Sf§ÌNÍ7šo4r߀ONQEoŒÞ½Î8àütwÐÝAwåÿ{£&5© ¾¾¾ðpÉÃ%—@Øa„}`èpâm!@ˆè\ÿsýÏõ‡ *@õîÕ»WïìWÒ¹ötíéÚ* ©4¤ÒØÛdo“½M J¼-¤Qyžó<çy’û$÷Iî   †N%^µÌ&™M2›@l™Ø2±eÀ[ñV¼å„¯ø')B”@^6^6^6PÕ¹ªsUgرvÇÚkAùXùXùØÐéÄ«rD}D}D ó,æỸöMÛ7mßÔЩÄÛBž D ¤nªnªn æ ˜3`|¾ùóÍŸo†ð‚ð‚ð¨E-äR€wW|™ø2ñeà襣—Ž^‚L>2ùÈÌʘ•1+cètâm!G„(Á*.®¸¸âbhMkZ[£¶Fm‚¢ÉE“‹& Ð<æ1ŠcŠcŠc H)RŠзззå‘òHyúŠúŠúŠ ôWú+ýø€@§Óét:P|_ÅÈ"‹ß=ÍOwCwCwŠë×-® t§;ݺԥ.è u…ºBPî(w”; ¤)iJè’uɺdP®*W•«¿Ë{‚œ€âüâüâ|(Ž(Ž(Žnr“›˜¿žô¤'ì꾫û®îà±Ðc¡ÇB¨]?º~ôß_½x¿h¾ø'CBNùg埕ûÝÿëþ_Áæ[›om¾… ,*X¼þñõëôëôëàXü±øcñ°'aOžˆ54j(ü:ñ׉¿NãAƃŒÁÉïN~wò;8Þõx×ã]¡žªžªž Ö®/\_§ZŸj}ª54ÖlX³apÏúžõ=kؼoó¾Íû $3$3$žL|2ñÉDpNtNtN„Åî‹Ý»ÃócÏ=?å*”«P®|­úZõµ Æ%ŒKµ‡×^{8œ{rîɹ'°«Ç®»z@ð÷Áß¹Cs‡æ…J[*m©´TMUMUoàÐ{Dˆ=`Ç£v<‚¦~4õ£©`_þ†}×?¾x·È!ö-í[Ú·„ž'zžèyví0ÚaÙ£²Gezýãßó¾ç}ÏÖkÖkÖk û³îϺ?ÿfþÍü›AâñÄã‰Ç!õTê©ÔS`û¥í—¶_Bx¿ð~áýÀòSËO-?»™v3ífB¸Y¸Y¸äŽÈ‘;~´þÑúGkp›ë6×m. »:ìê°«°çÙžg{žAܽ¸{q÷@ÕNÕNÕyxäá°s·s·sÅ]qWÜ!ºOtŸè>8!qBâø©×O½~êí~n÷s»Ÿ¡ýÎö;Ûï„TþGåT†¤˜¤˜¤˜×?…ممÙÔ5¨kPWhîÑÜ£¹¸;»;»;¿þñÅ»I €â_Úµ5jk&ÓL¦™Lƒ#wŽÜ9òn%ûÀãÇ0*kTÖ¨,¸ÏvŸí>L²M²M²AóLóLó ÔÔÔ@ÓJÓJÓ T«U«U«RHÍÍÍPG©£ÔQ?1bþDˆØ±/b$,MXš°®}{íÛkßBÖY_d}i™i™i™`ÔΨQ;PPPx™Oc­±ÖXƒæœæœæ¼øâÅ/¾€ÇæÍ›Ãá‡> ‘Ý#»Gv‡Ô¥©KS—BN™œ29oàœû•ÙWf_™ ñÃã‡Ç‡^ù½ò{å¿þqÅ»M.Bü‹Y®Y®Y. x2àÉ€'°fÞšykæAsçæÎÍÁ%Á%Á%áÕ«úDõ‰êPÊ)å”rÀe.s™—OýûÃüs¹^xý›å®¸â ô =À¨³Qg£Î`3ÄfˆÍpÕ¸j\5°`Ò‚I &A–5ZÖh §5§5§5`dmdmdý»õjÑ¢¬°Â TTT@ûLûLû lîÚܵ¹ ŽŽްlÁ²Ë@™Ae•ôúöWööìíÙÛaGÁŽ‚ÐsQÏE=Aé¨ÒQ¥£^߸âý G„Pߨ¾Q}#¨4­Ò´JÓ`×®]»víz}ãyTõ¨êQŠ»w-î a…a…a…ªMÕ¦j¡hTѨ¢QÀö°,V[¬¶X Yg²Îd¤¯“¾Núò&æMÌ›…³ gÎíTíTíT¨ST§¨NäææBy¥¼R^š¹5skæ‚e+ËV–­ÀÒßÒßÒ^l}±õÅVȶ˶˶ƒüGùòA^¿¼~yý t¯Ò½J÷‚Šùó+惮‡®‡®TÞTySåMPcTQ5Fé*ÓU¦«^ß¼;xìృ Ù®Ù®Ù¦v˜ÚaêëO¼_ä"@!ĨK©K©Kk× ® È1È1ȪW® -Z:´|uã9ôrèåÐ àúæë›¯o~ù8Û””ð:àuÀë´ØÞb{‹í1(cPÆ H0N0N0ÅB±P,ÀêœÕ9«sPG©£ÔQÀ«‰W¯&9,rXä0¸ïrßå¾ËËŸw)v)v)×T×T×Tˆû>îû¸ï!½gzÏôž@ºÐ*:Tt¨ œ87p†jí«µ¯ÖÂòÂòÂòà±Õc«ÇVPh]h]h .V.V.V ñÖxk¼_Ý|%^I¼’x~òýÉ÷'_útèÓ¡O¡â¢Š‹*.zÃñÎ’‡ !þ£µ³ÖÎZ; â·Åo‹ßŸ%|–ðYh 4š‚×8°3Î8ÃàòƒË.>Ù>Ù>ÙàîînèY1€¬`¬îµº×ê^¼1ycòF˜»h‹@S¤)Ò:¤xWÈ)!ÄÔ«C¯½:@¬M¬M¬ \¶½l{Ùöõû¤å“–OZBVBVBV¼¨÷¢Þ‹z 7Ó›éÍ =+o^äØÈ±‘c!$"$"$ü¢ü¢ü¢ä¿øk¤!þ#ÇŽ;@÷;Ýït¿[c·Æn…ìMÙ›²7½Æq×9®s\?Õú©ÖOµ`ðÕÁW_Õ:Õ:Õ:CÏÊ›£KÔ%êaÛØmc·…&štjÒ ª¸Vq­âjètâ]%§„ÿµì Ù²/À'µ?©ýImhÝ:»u6ôqíãÚG~½6!Æ!Æ!ư>|}øúpXÔkQ¯E½À1Ü1ܱ$ž ¯„Bü×,[X¶°l~'üNø€CŸúôЧØ/±_b?C§{ÿäæææææÂ¶ÆÛok ÝÚtkÓ­ü⯆!Äÿ¬ñ׿nü5¸Å¸Å¸ÅÀÞø½ñ{ã êýsâ鉧'ž‚n…n…ntØÜas‡Í†N%ÞR„ÿ3Í Í Í ð‹ô‹ô‹„à Á‚'ÀƒVZ=heètᄂI’Àþãûï?ýK÷/Ý¿4Xµ±jcÕÆÐéÄûB €â/«_5¾j<4þ¼ñç?‡ Û Û [(X<°x ¡Ó½»ö}³ï›}߀k€k€kx¯ò^åýo($J&)Bˆ¿­O~Ÿü>ùð¸ÁãÀµö×Ú_koèTïžGíµ{Ô.ú]ô»è~_ú}é÷%h¿Ñ~£ýÆÐéÄûF €âos~æüÌùt íÚ-¶ÏÝ>wû\Èž;Ê„È_"‰ü"ÊD”‰(EÖEÖEÖ/.cþÆü¹>r}äz¸w;ïvÄëãõñzPr•\%÷ÏÇÍõÎõÎõ†¨Q;¢v@⇉&~9s&æLÛ{¶÷lïAóÇÍ7 Fß}gôX.´\h¹´çµçµç¡èdÑÉ¢“àààë=Ö{¬÷€ûû{PÒ•t%ú%ôKè·ëÜ®s»D'F'F'‚îKÝ—º/!öYì³ØgÙ ²AdxRæI™'e Þ*Þ*Þ XÊR–zo‰×ÍÈЄâMь֌֌†ufëÌÖ™½,GvÙq$lŠÞ½)†Z µj,:Yt²€7vÞØò¯ç_Ï¿ÎcœÇ8kß^ûöÚ·0tÇÐCw@‹u.Ö¹øÇq³ïdßɾ¹¹¹€1ÆCÂü„ù ó¡8ª8ª8 fŽ™9fæøáÑ~x妗›^n:I$‘PT©¨RQ%¸q9âr–),SX’¿Kþ.ù;È8˜q0ã ¬;¸î຃P«C­µ:ÀÍR7KÝ,}–÷YÞg9¤þšúk꯰|éò¥Ë— ƒF V'¬NX€×^x 4hÐz§‰×F €¢ÄPõVõVõ«ÎUç ¥}Jû”ö.Å]Š»Ã…M6]Ø7_Ü|qóT?TýPõCpäÊ‘+G®ÀÊ++¯¬¼uuuðäö“ÛOnÃŽQ;Fíu¨C3®cŽcŽcT¸\ár…Ë`>Î|œù8¨W¿^ýzõ!¥FJ” 5ÖkA¿H¿H¿pÄG  hÖ_Ziý%”=[ölÙ³`V`V`Vµ>«õY­Ïà»§ß=ýî)P‹ZÔ‚áû‡ï¾–™,3Yf‡*ªp¨ô?ÓÿLÿ3`œkœkœ =Œzõ0ëkÖ׬¯z¨z¨z¨¡÷–xÝ䀢äУGd‘E@/_V¿P¿P¿}}}}}}Èþ<ûóìÏ¡ ¤ ¤ ̃̓̓_¾ß^m¯¶WC"‰$þ7ãGM4(m•¶JÛóúorÿÙŸÞ*T¨€§<å)(þŠ¿âÿòåDûDûD{ˆ58j0l¨º¡ê†ªðb‹ /&€KKK0‹YÌ#Œ0Lõ¦zS=XN°œ`9T¥T¥T¥ ½³Äë&@QrhÑ¢ÊQŽrÀv°ãw¯»ãŽ;PƒÔ‹\‹\‹\ÐŽÐŽÐŽ€ü&ùMò›¼|{z—ô.é]ÀAå rPýãW¤"AuBuBuâwË ( ˜Ît¦ƒj„j„j/‹Ê$&1 Æ0†;ÙÉNP†(C”!/WcçoçoçUW\e0ø÷?î>]øtáS˜â5ÅkŠè§é§é§jªjªj*à†Þ9âM“ „(1”ÊFe#p—»Ü…¤ ¤ ¤ Hœ>8}0$vJì”Ø ’>Jú(é#°ÿÚþkû¯¡íçm?oû9ì²oȾ!°÷—½¿ìýbÆ>Œ}}êô©Ó§ÎŸ›5.k\Ö8x>äùçCàéæ§›Ÿn†¤åIË“–Ãã”Ç)S c]ƺŒuð°æÃškÂÃ*«<¬þþþðä“'Ÿ<ùœÎ:u: 7«Ý¬v³„……AûYígµŸ9Ýrºåtƒ]UwUÝU‚›7 nI{’ö$í8ã8ã8cH›’6%m ÄæÆæÆæþws(Þ*åŸ D!^·‹6.Ú¸®$]Iº’ãW_=~5¸9¹9¹9Áƒ´iÒ@3P3P3jzÖô¬é E¾E¾E¾µ.j]Ô:(ø¨à£‚À)Õ)Õ)*̯0¿Â|PmQmQmùã¸Ù‹³g/†ðkáׯñ¯¯#z8{8{8C¶]¶]¶ÄŒ3œ>púÀé066†§žvzÚ Êx•ñ*ã6ŸÚ|jó)D4‰hÑ ê媗«^†§öOíŸÚÃóºÏë>¯ æ£ÍG›†r?—û¹ÜÏžžžžž±»cwÇî÷_ÝuÿÊ|Sæ›2ßz/‰7E €¢ÄذzÃê «!uYê²Ôe0#zFôŒhC§Â0䀢ä(¢ˆ"@AAþì%œ!„¢’ „B”@R„BˆH €BQIB!J )B!D $@Qr´ -L01t! K €â½£©© Ù+³Wf¯„ÜÄÜÄÜD(˜]0»`6|UðUÁWPð¤àIÁÈÊËÊËʃ¢iEÓŠ¦:½o†<XñÞyxãá‡7`æ™Cf]Œ.F±mcÛÆ¶…¢E‹ÂeÍeÍe ¨««ÃÌF3ÍlÍiNsCo„¯™!Ä{ÇZ±V¬H^¼:y5„ìÙ²ãï»W|¯ø^1¸åþ•ûWà\ŹŠsÀ?ü ½B¼^r @ñÞqssƒNQ¢:Eg9ËÙ? m m -T0©`RA® %„!Ä{«Ý¶vÛÚmÇ\Ç\Çó¸[ãŸ6þº´èÒ¢K 0Zn´Üh¹¡S ñfÈ)!Ä{«NÝ:uëÔ…Úŵ‹kÃINròw¯W«W=¤5Hkfè´B¼Yr@ñ޲ʳʳʃ®C»í:ô¯7ù¤É'M> öì+Ø:­o–B¼÷Zjq¨Å!(»¹ìæ²›!uqêâÔÅàcâcâcªbU±ªØÐ)…x³¤!^»¤RI¥’JÁóÎÏ;?ï Üä&7l°yï`; ¨TQ©¢RàòƒË.?€º¬º¬º,¨Ôê¸ýøöãÛA  P¼Æh¯k¯k¯ƒå$ËI–“@­ŒVF¿Æ…RêuŽ:,_X¾°|êêêppÅÁW8ÀPâ”8%îõÅQ­V­V­†œ97rn@ŽkŽkŽ+Ly8åᔇÐ4¤iHÓ  MhòçE@¥ü“¡ƒ!Þ·¯Þ¾zû*|ÛÿÛþßö‡vOÚ=i÷|.ú\ô¹F£ŒFe·²[Ùýúó¨ÜTn*7xÞôyÓçM!Õ.Õ.Õj®5ºÖhÐ×Ó×Ó×^ãÿ U5T5T5@ÿµþký×p)øRð¥`¸p)àŒl7²ÝÈvÐfG›mvüýñ„ø¿HBü}ç8Ç9¸v÷ÚÝkwáûŠßWü¾"ôÜÜssÏÍЧEŸ}Z€ê#ÕGª ˜ó)Oy <ä!¶´¥­ó¨P¡‚óåÏ—?_Ö–Z[jm)ð7õ7õ7…NW;]ítÕ€ùÄ{M €âo îÜ7¸/ühú£é¦àgægæg>Û}¶ûl2È ÃÐ)ß~—c/Ç^Ž…nÿpû‡Û0Àq€ãGðiãÓÆ§ ¨²TYª,C§ï ¹@ñ—‰?&~ø9àçš24eh tÜÙqgÇÀ:Ö±ÎÐ)ßÞe½Ëz—­…ÖBk+.¯¸¼â2~QøEáÐǺukPg¨3ÔR¨Äß$G„ÿ5ÅD1QLàXè±Ðc¡˜˜˜®ûp݇ë õúÖë[¯7tÊ÷LJwÞyË;,ï°¼t¸×á^‡{àçàçàçšlM¶&ÛÐ)Å»J €â?RF(#”°Ÿýìv$íHÚ‘ã“Æ'O‚&¡MB›„:åû+²Md›È6°$cIÆ’ h~´ùÑæGÁ–ÿ,ÿY ýEû‹öC§ï¹ âO)s•¹Ê\ØytçÑGa·õnëÝÖ0µÞÔzSëA“ÝMv7yWñ—tUÏT=Sõ |2ç“9ŸÌU!«BVÁÏ·¾ýóm(˜X0±`¢¡SŠwBüAñòâåÅË!(*(*( ÎdŸÉ>“ SO=<õ0x¦y¦yʽó æIä“È'‘°$rIä’H¨ª®ª®ª†ÑcG=ÌbÍbÍb R¼í¤!þ¥èQÑ£¢G°)gSΦÞ¼'xÌšï{ø±ò•¬ á«ÂW…¯‚¹óçΟ;ÿ¯ÿâ/W<®x<Ýýt÷ÓÝpcÍ57Ö@ø’ð%áK b]ĺˆupwÔÝQwGÁ‹/^¼xaèÙxV±ŠU®Mצk!<,<,< Ò'¥OJŸô×Wë¬rV9«àã~÷û¸ä̘?–¦-M[šisÓæ¦Í5ôÆ‹·!J \Ç\Ç\Gø¾ô÷¥¿/ Ñ£G?†¹“çNž;ܼݼݼÿúúõçõçõçáªùUó«æ0:xtðè`U…ªBUðhÊ£)¦À‰èÑ'¢á”ë)×S®†ž•7`›ØiÓ.¦]„Ù³gÂÙÃgŸ=ü÷WoŸoŸoŸ³gÍž5{hnhnhnÀ o,¼ÉÍ’›%Ë)ñOR„(A²Ü²Ü²ÜàÛ*ßVù¶ $5Ij’Ô>ùùÈÏGB™Æe—iü÷Ç177‡*õ«Ô¯RljÛÔ¶© ëw®ß¹>øäøäøä€_Ž_Ž_T¶¬lYÙòåÏ+ã”qÊ8(Î(Î(Î}/}/}/ <ò@IQR”P|ŨG=ê>Z­}¨>T ú}Œ>”Ê@e ¼#¡:PV(+” _¦_¦_Æ¿nÑ«D+ÑJ4GGG‚~Œ~Œ~ÌïrNR&)“@9¡œPN€rE¹¢\¥¦RS© P@°žõ¬Ý*Ý*Ý*(w³ÜÍr7Ár…å ËP<¤xHñW·ŸKå”Ê)•ÓÇN;},Ø.µ]j»¾Îû:ïëÏ|ÅÝ‹»w‡Äs‰çÏÁ”ƒSN9Q_E}õ˜¿0aþJ,=²ôHpâ2Äe”ëV®[¹n0¶ÁØc€³£³£³#üªÿUÿ«œsssáÖœ[snÍ›"›"›"hü}ãï÷•ûÊ}Öu\×q]Gè–Þ-½[: 1xÄàà¼ÁyƒóÐ7Ó7Ó¿ÆCóæÌ7˜o€ k&¬™°ª¬¬²²ÊJø2åË”/S zwôîh¹ŸC‰#@ˆ÷QCÒ~Iþ%ù—dx|éñ¥Ç—`ZËi-§µëÅÖ‹­¿s™Ë\(uºÔéR§¡©OSŸ¦>ÐxQãEŧŸZ|úòí7moÚÞ´…JC* ©4LÏšž5= Õ/T¿Pý$I8’pÒ¾Iû&í0¹drÉä”ý®ìwe¿ƒšík¶¯ÙjN¬9±æDð®ç]Ï»\˜taÒ…IðÐë¡×C/ÈHÉHÉHS™§2OeÂcïÇÞ½¡®¦®¦®4Ã4Ã4ÃÀNg§³ÓÁeíeíe-<;ÿìü³óýUöWÙ_ú;õwêïÀl¶Ùl³ÙP±cÅŽ;BÍñ5Ç×Ï:=ëô¬hii‡ƒ‡ƒ‡˜55kjÖ4 5 5 ÛÜæöëß&[M¶šl…Ñv£íFÛ®¢®¢®",½`ô‚Ñ/¿ "J)B¼B %Ú›µ7kofÍ*šU„£ŽN8:t5t5t5^ å´rZ9 &çLΙœssshP®A¹å _¿6~/߯٥٥ÙzK½¥þw×èƒôAú `³˜ªªª/·S9¬VþÍEt­Û´nÓº Ü©}§öÚììì c§Œ2v \hv¡Ù…fðÐæ¡ÍC¨~¥ú•êWàòÎË;/ï„o3ø›Á`ô£ýÌ1ÇÀ /¼+¬°%X V‚A S”°ßèK_ú‚ªªªàŽ;‚Xb‰%à„Noàs±›Ý솋K/.½¸²wdïÈÞ~‡üùmUmUmÕ7C¼ä!Þcõ¶×Û^o;̰a;Ö&-MZšù=ò{ä÷€!K†,²ŒfÍ6šýêÇÏ Ë Ë ƒUª@™+3Wf®§ÙN³fƒÝ5»kv×^¾ß;Ð;Ð;¢,£,£,!9 9 9®ï¼¾óúN¨T®R¹JåÀ6Ö6Ö6 ®\+¸¹þ¹þ¹þ¿ÖÚZkk­£ÆQãd‘EtîÖ¹[çn°±ÛÆn»Å]‹»wÁt·énÓݨJT%ª sjæÔÌ©à9Às€çxPöAÙe!Ü#Ü#Ürä,ÈYE­ŠZµ‚5úÔè£ÜG¹rÓV¦­L[:¥ø«tÞ:o7ì|ºóéΧphÌ¡1‡ÆÀ´ÃÓO; u¯Ô½R÷Š¡S C“k„(*<ªð¨Â#˜ûáÜç~÷?½ÿéýOaUýUõWÕ‡¼áyÃó†:¥ø_·/n_ÜŸ> |G;ít´ÌIž“<'Y~ñ‹ÿ—BèŸèŸè‹#G.ŽǾŽ}ûÂDÕDÕDXδœi9ÓÐ)ÅŸ)ì[Ø·°/üÒè—F¿4‚ÐÌÐÌÐL˜1rÆÈ#¡j…ªªV0tJñ¶‘ „ø—äŒäŒä Xú`郥Àâ‹O,>Én“Ý&»Íz›õ6ë Rü&¿S~§üN°®ñºÆëCDZDZDÌt˜é0Ó*Í«4¯Òí<|SüMñ7Å úQõ£êG˜n3Ýfº Øýl÷³ÝφNYråÆäÆäÆÀç<ÿãyx¶èÙ¢g‹`vöììÙÙàúÌõ™ë3C§o;)Bˆ?•96slæXø.÷»Üïr!;";";f|<ãャ¯£¯£¯¡S–ÙÙÙ°rÖÊY+gAJLJLJ ÌL™:3\œ\œ\ÞÄýÄ{A €â?ÊNÎNÎN†UšUšUHXš°4a)Ì\2sÉÌ%àªwÕ»ê òý•q1ãbÆEø6üÛðoáàFÁ‚0éLJ¯)½¦ôC§ïù€â?²t°t°t€É¡“C'‡Bùúåë—¯_g~ùu&<­ð´ÂÓ †NùþI=Ÿz>õ<,*»¨ì¢² ·ÕÛêmaŽóç9Îò‹_ü=r@ñ?+h_о =lðÜà¹ÁnÞ¼yóæM˜í:Ûu¶+T ¨P)ÀÐ)ß]Iw’î$Ý%éKÒ—¤ƒÍ¯6¿Úü “GN9y$”j\ªq©WðØfQ²IBüe… €%@ Pàb…‹.V€™a3Ãf†AõáÕ‡Wnè”ïŽç#Ÿ|>–œ^rzÉipqwqwq‡ ê ê j°8jqÔ⨡SŠ÷…!ÄßV|ªøTñ)ØvnÛ¹mçàø•ãWŽ_^3¼fxç"ÏEž‹ òíõÛUü‹ª.ªº¨*xœö8íqÆùŒóç¦L;™v2tJñ¾‘ „xeôõõaw·ÝÝvwƒýßîÿvÿ·0¥þ”úSêƒ×N¯^; òíñhÍ£5ÖÀ’fKš-iu‚ë× †‘åF–YLºšt5éjè”â}%@ñÊ)M”&J8èrÐå  lÌߘ¿1êÇÔ©VŸX}bõ (­•ÖJë7(—\rA¬V¾øâ ú(}”>Š7ö8^ÕϪŸU?CNÙœ²9eáöšÛkn¯ö~íýÚûÁPŸ¡>C}@[E[E[å Ì‹(Ѥ!^¥…ÒBi!î!î!îóòÆBhРyý9ÔžjOµ'\¾|9rŸä>É}íRÛ¥¶K]K]K]Ë70!e)KYÐ7Ñ7Ñ7ò!åCʇ@Ûkm¯µ½F­ŒZÉC˜Ä"@Qbl,ÚX´±Rz§ôNé 3Î88ã ¡S ar!D‰¡¬VV+«p 7t! K €BQIB!J )B!D $@!„(¤!„%!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!„xCô}õ}õ}áæ²›Ën.ƒK+/­¼´tYº,]0–±Œ‚ &”J¥(ÁJ° Üâ· ½â}!@!ÞÜÜ\صx×â]‹!ºvtíèÚpóÓ›ŸÞü–|°äƒ%@Zë´Öi­!øjðÕà«0©Â¤ “*Àã!‡<bè­ï )Bˆ’Cƒ  B…êÍ¡ö…ÚjƒéBÓ…¦ aàÔSNç;Îwœï@žuzÖé æµÌk™×‚Ê÷*ß«|Â3Â3Â3 Ó6Ó6ÓSSS!¬IX“°&†žTñ®22t!„xSÔ3Ô3Ô3àVï[½oõ† iÒ.¤;ÙÉNÈË˃f­šµjÖ ,ÛX¶±léÆéÆéÆpËö–í-[ȋɋɋ×®\@Íû5ï×¼ê(u”:ê㦤¦¤¦¤BÄâˆÅ‹A=Q=Q=Ø>°}` &eLʘ”UgUgUgÈwÉwÉw­³ÖYë šGšGšGë–ë–ëÿ8ñÿ8ÏÛ>oû¼-L91åÄ”à‘à‘à‘÷ŠîÝ+‚§ÇŸzl>°ùÀ樿³þÎú;!rjäÔÈ©x<ñxâq°ùÞæ{›ïÁä¡ÉC“‡àéêéêé ÄO¼¡÷šx]䀢ÄÐh 4°ãÆŽ;nÀ¾ü}ùûòÁ|´ùhóÑðk̯1¿ÆÀÁõ×\ù;ówæï„•+#VFÀ#»GvìÀtŒéÓ1°6hmÐÚ 8wëÜ­sÿǹyíííÐj µ…`ÜÀ¸q0ícÚÇ´äyåyåyÁ×s¿žûõ\ˆ111M5M5M5à Oxš¾š¾š¾ð|ÁóÏ€ÞIï¤wó æÌ/Àõ%×—\_«¬n°ºhr5¹š\خڮڮ‚ÓO><â–Å-‹[s3æfÌÍ€ˆ9s"æÀï~õð+ÐM×M×M7ôÞ¯›!DÉQ‰JTqÄì~°ûÁÔWê+P±uÅÖ[Ãá‡> Ïæ?›ÿl>\±¿bÅ:.ãbhýkë_[ÿ •kU®U¹¼zðêÁ«>l©Ã¥—: N¡N¡N¡àö¥Û—n_Bʼn'VœÎë×;¯“Ú&µMjÖXc ä“O>0•©L‹‹‹°o?Þ~<¸e»e»eC¹å”[§Êž*{ª,GGGBó:Íë4¯NþNþNþp6ôlèÙP(=ªô¨Ò£ÀúºõuëëÐåA—]€Ï8Ÿq>ã@“¬IÖ$zg‰×M €¢äУGd‘EpˆCúÝë™d’ xàä·ÏoŸßt³t³t³@k£µÑÚ¼|»Å0‹aà 볬ϲ>û/Æÿç_òJO¥§Òó/äÿíÚ…tÒI $ðwñã3ã3ãáq…ÇW€§vœÚq hE+ZAãqÇ5ô¡}@5Z5Z5Ô+Ô+Ô+ÀÈÁÈÁÈXÄ"zg‰×M®B”¿]h‚ &@YÊRöw¯›bŠ)ЈF4kkk0»mvÛì6¤?Nœþœp xîûÜ÷¹/¸9¸9¸9üã›a†PzÔûÝòߊ‰ .¸¥)Mi@‡ÿ:bñ¯?çs>‡¢šE5‹j¾\M™ü2ùeò!ß4ß4ßü¯ú_õ¿ ê`u°:øåûB¯†^ ½ú»<æ˜cnè#Þ4)BˆCi®4Wšƒ©ÞToª‡äíÉÛ“·C¢*Q•¨‚ó^Ì{1ÌrÌrÌrÀz¾õ|ëùЯ _A¿ØóÉžOö|öÉöÉöÉPQQÃO ?1üÄŸ›œœ Ï[=oõ¼hëkëkëÃSç§ÎOáI§'žt‚|×|×|W¿~?ü>dÌ̘™1 îÜ-¸ QÞQÞQÞP%³Jf•LØûpïýáH#5ŽÔ€®Í»6ïÚÖ\[smÍ5ø±Öµ~¬åΖ;[î,xÅyÅyÅÁ“ÙOf?™ y³òfåÍ‚G6lÙ€=öØz'‰7F¥ü“¡ƒ!Äë¶Ñr£åFKˆÚµ7j/L­4µÒÔJ`¥¶R[©!%%%%%ÔwÕwÕwÁé§_œ~ÅWñU|!isÒæ¤ÍPäUäUäÖݬ»Yw›t›t›t`Cø7ßÓ/ˆ,ˆ,ˆ„¤II“’&ñ¯Sö-í[Ú·„‚eË –AÆŒŒ3Àâ°Åa‹Ã`dndndßf|›ñ-Xݱºcű͋͋!qGâŽÄ`æiæiæ N7œn8Ý€ô-é[Ò·@ú­ô[é·Àx¤ñHã‘`Óʦ•M+ÈÛ“·'od É’5ìžÙ=³{¥ÂJ…• 3ô^oŠ!D‰±aÕ†UVAêòÔå©ËaÆãg<6t*! C.B”¿SBHB!J")B!D $@!„(¤!„%!„¢’ „B”@R„ïŸ/ø‚/@y¦¤û°égÓϦP›ÚÔ6ôFˆ·•!ô§?ýáÚ—×¾¼ö%l>¾ùøæã «« ýªö«Ú¯*4ˆlÙ ̵æZs­¡C—\IIIp7ànÀÝØ1wÇÜs!5=5=56Øh`#h™ß2¿e>h"5‘šHC§o)B”`¹º\]®¶>ßú|ës8÷sÿ8÷ð)çSΧtvïìÞÙ,ÛZ¶µlkè´âÏŒ)S0ÎežË<— [7lݰuxîõÜë¹F”Q~Dy°ijÓÔ¦©¡ÓŠ·…!J Ì[™·2oÁªŽ«:®ê óæ'̇‰™3'f‚Ç,Y³ RüUñcãÇÆ…Ÿ–ÿ´ü§å÷uÞ×y_ÃŒ¼y3òÀy…ó ç†N) Mž D ’W>¯|^yXU¸ªpU!ä¯Ë_—¿æo˜¿aþ†ÿâ9ä€r^9¯œœp ˆ!†˜W°B l`p{ÜÜpà ”o•o•o½ìeïÿ±ž (~æg~æ_w |]2~Ìø1ãG8×ì\³sÍ z^ô¼èy¿{ÃyÎsøˆø”qÊ8e°‚¬tèнºKŸ¥‡éÕ¦W›^ l¯Ú^µ½ú_¬ÇlàfÊÍ”›)0Ùw²ïd_x°ãÁŽ;þ~ÌüÞù½ó{Ãwß~÷íwß•òWÊ_)‰&„{ì]°[¶ lõçëÉËÍËÍË…Ê e…WG]uuÔ«ŸÖâKÅ—Š/Á¯Û~Ýöë¶—WíÇLŽ™3¶tÚÒiK'Øo´ßh¿d–É,“YV»®v]í Ë—;/w½£ÞQïøêóY”¶(mQÆ 7xÜ`pZè´Ði!üìý³÷ÏÞ óÑùè|^ý¸âÝ @ˆàþÊû+﯄0ÿ0ÿ0øhÞGó>šÖU¬«XWùVTDEà¶Øm±Ûbˆø5â׈_!mTÚ¨´Wð V3P3P3jÖ(¬Q¥ƒJ•§%NKœ–@Áˆ‚# òzäõÈëP¬/ÖëárÒå¤ËIåŸåŸåÚµj?„ujÔ©QJ?-ý´ôÓW?¯ÙU³«fW…³gÏž={Z o5¼ÕphYز°e!T¨W¡^…zP®a¹†åB©OK}ZêS°L±L±L›ov¼Ùô[õ[õ[_}¾ßï3Þg¼FÞygäHÚœ´9i3\ît¹ÓåN¯o\ñv“ D pdù‘åG–Cƒ6 Ú4h厖;Zîè__ŸQ£>F}@ç¡óÐy@x™ð2áeàäù“çOž‡° aÂ6@Ö¦¬MY›àÔ¾SûNíƒðRá¥ÂKAöÅì‹Ùá䘓cNŽð&áM›@á£ÂG…À8Æ8Æ8òoçßοý»quF:#¨W«W«WÃå–—[^n __ÿúú××á\™seΕ”­)[S¶‚I˜I˜Iä×ʯ•_ ¢’¢’¢’à°Ýa»Ãv:4thèP8Üæp›Ãm º}tûèöÿyûõóôóôó Ê-Ê-Ê bbbàö¸ÛãnƒÑ/¢_Dƒ¦¹¦¹¦9¿üyíJíJíJPPPÕÕÕÈÙ™³3g'\H¿~!ަM=š у¢EúûŸ›96slæ@§tZ‡Zjy¨%œ-8[pö5}øÄ[K €ï±Ô›©7SoÂýv÷ÛÝoMG7Ýtô+Xq.¹ä?ð?€q¸q¸q8h“´IÚ$Xc½Æz5œÛynç¹°/l_ؾ0Øž½={{6˜|lò±ÉǰÇhÑ#ØÞt{ÓíMÁ¸ºquãê°cÔŽQ;FÁ6ý6ý6ýïÆýç¹r•›ÊMåy½ózçõ†„„„0_a¾Â|˜39fr ¶·ÙÞf{ØYgýõ!Î&Î&Ξ_x~áy(=ó)”êXªc©Ž ¬UÖ*kA{A{A{œœœA™¤LR&¶¿¶¿¶?8¬uXë°H „ß›J*© Þ Þ ÞÎ:Û¶m7BÍ5oÔ¼6>6>6>`Àþ€ýP}§úNõØ/±_b¿̽ͽͽ¡Ú¢j‹ª-‚v9írÚå@LXLXLäŒË—3²ªfUͪ IÛ“¶'m‡•_T~Qtãuãuã¡ü½ò÷Êß›Ã6‡mCMš5=À¶—m/Û^àô©Ó§NŸ‚ê”ê”êÔ§Q5]5]5²¼³¼³¼áØÞc{í¯ ^¼&@³f!ÍBàYì³Øg±iiiÿ÷wŸÍ-›[6·Àô±écÓÇÔ4©i’|=°Ä‘gñS¶)Û”m úEõ‹ê`Cò VüÛÍïr”£€^xãÏx(5¾ÔøRã!ëqÖã¬Ç`ÚÏ´Ÿi?à1yü 7Ð#Œ@ÙªlU¶þný5©IÍó~ 4 œTN*'cãPžò”%P T?üðƒm¶Ûl·Ù­C·Ý:¿ÆÆ´ÓnL;piäÒÈ¥(Ί³â J=¥žRïÈ_Žr”]˜.Li‡Ò¥‚à˜à˜àˆý8öãØ¡n«º­ê¶—-.[\¶½éMï¿>m¿rPuTuTuýAýAýÁW¸_Ä;A €ï1{c{c{cPn+·•Ûv4íhÚQ°ZgµÎjÝ+ Ÿ|ò T ÂËÅ7=ÜôpTëY­gµžÕ<«yVsÈWò•üßßuä·"Q–²”ýÝrSL1Ѐÿfy jPÈ@B±}±}±=èÝônz·ß½ß ,xy|=zô¼¼EîU®r•—§š¨š¨šð¯;#ú‡û‡û‡Ã€Š*¨t¡ ]À¼‚yó á—á—áÇ¿¾Þ‡;î¸ÿn|*Tÿf;~[þÏq7o6Þ e‹Ê•-‚fšuhÖ:Ìï0¿ÃüßýÜ&0áïï¶ ¯ ¯ /È«˜W1¯"8¶qlãØæ|Ä;E €ï±Òö¥íKÛCÅ[Tl—+]®t¹Ò¿¾Vÿ—i‡k‡k‡ƒ»µ»µ»5\\|qñÅÅpgÄwF@‘o‘o‘/ôû¼ßçý>‡Û+n¯¸½‚6mÚ ‡¶Úrh ¤,LY˜²Œsss!¦8¦8¦ž'>O|žœä$'!"5"5"’ÔIê$5¨[¨[¨[€þ¬þ¬þ,ØŽµk;öå×ñº¶éÚ¦kHÜž¸=q;¨»©»©»ÁÕ®W»^í M š4…§ƒŸ~:žœrþÉyȯ’_%¿ <Ÿ÷|Þóyàhåhåh&˜`ò»íWâ”8%¿êþ*È-Ÿ[>·<ÜýÇÝÜý¸Íq›ã6?.~\ éÒ;¥w‚[Kn-¹µbnÅÜŠ¹éáéáéáv-íZÚ5ÔuP×A]áø‘ãGŽ„* Uª@ÙÑeG— &4šÐhX˜Z˜Z˜þõý©ŠTEªÀz…õ ëàlælælfèO«xÓäN€B”7Rn¤ÜHMúMúMz˜;mî´¹Ó ôæÒ›Koþ +lK[ÚBê©ÔS©§ §nNÝœº Û©Û©Û ¶ lØ.ëÍÖ›­7CÑ÷Eß} ³f'Ìõ]õ]õ]`0ƒ êºêºêº`ÕÕª«UWH[œ¶8m1EQPÊ£”G)È Ê Ê â_‡úKw)Ý¥tHßœ¾9}3ävËíöÿcï>㢸úþfwéM¥ƒ‚ˆ *XP,(Vì½÷D51‰Fb,1jŒ±w½ÄØ{ÃÞ°‚ A"Ò{]Ø6ÿwüß¹r_IŒÙ¨ó~¢/v÷Ì÷œÝSÎ)íU~ªòS•Ÿ èvÑí¢Û n7ˆ@±@±@±Êë•×+¯616161 j®j®j… /^Û^¶½l{y#óFæÿiu½YÌbä?ΜÿrÝrÝrÝÀ¬–Y-³Z`•n•n•¹B®+€ªªªTšSiN¥9 LQ¦(S@¥R©T*°mcÛÆ¶ YYYBÆŒ7@å£òQù€i’i’iX?³~fý äáòpyøŸØ_?+••ÊJeðí¬og}; Z5kÕ¬U3èØ­c·ŽÝô}”JþiR ‘¼t}t}t}`Ó O6<üYù³ògÁ”Ð)¡SBÁd­ÉZ“µúN)y]tN:'l¾µùÖæ[1,cXÆ0ø¢Ã¾è†s çÎyõíHÞ,ÒSÉ;@vDvDv†}7ì»aßAa»Âv…íàûÜïs¿ÏeUeUeÕWߎäßEýHýHývÛí¶Ûm}ú<ô&|0რÒÿ»N: ‘¼ƒ2ëeÖˬ˯,¿²ü µ0jaÔ&ö˜Øcbp\â¸Äq‰¾SJþªü%ùKò—À¶Ûnl»1ícÚÇ´‡ A3‚f€{‰{‰{‰¾SJôM*$’wX~ïüÞù½aóªÍ«6¯‚èÈèÈèHþlø³áÏÀ_ç¯ó×ᧆŸ~ªï´’ߣ  P±FÃ6ÇmŽÛ¡J@•€*ðá­o}x V8¬pX¡ï´’ ©H$h«k«k«Ã¥”K)—R`cöާmNÛœ¶Á ¥ƒ–Z µ…ÚBmä“ä“äÃãh’¿F÷ƒîÝØ ±Ab8°ôÀÒK!29292z¬é±¦Çèù^Ï÷z¾FOž=ÕwjÉ¿TH$’ßÈ2È2È2€cŽÇ9¾7úÞè Õƒ«W†.^]¼ºxA=ÿzþõüÁxšñ4ãi¯¾]ÉöË<QžQžQžü øAðˆ9$rÔÿ¡þõ€þ7ûßìª:Tu¨ê‚—à%xé;½äßJ*$Éï;ÃÎ@JAJAJ\ØqaÇ…pÓø¦ñMc0~füÌø4Ó|Ló1Ðäh“£MŽ‚s¡s¡s!………ê»oMGMGMGH]˜º0u!<þ B\C\C\!oqÞâ¼Åà«öUûª¡ÓÌN3;Í„{kì­±„ÍÂfáoX+@òn ‰DòÇ}Á|E{Šöí°Ü°Ü°\¸6áÚ„k ¹mrÛä¶P© RA¥¨Y/²^$Ô¿RÿJý+P]Y]Y] fçÌΙ…•ÂJaEÅŒ€o9 t”hK´%ZxaûÂö…-„«ÃÕájx4ìѰGÃ Ó Ó ÓìzÛõ¶ë -†¶Úb(4§9Í*æUÌ«˜qħï^IÞTR ‘H^™¶½¶½¶=dÍËš—5"kEÖŠ¬÷¿¾ÿõý¯áùÎç;ŸïÎGç–ý-û[öO;O;O;psssss§Ï>wúì­í­í­ÁRc©±Ô€l¸l¸l8¿Nýû¯qŒcqŽ8Gœřřř1-cZÆ4H”þ(ý$öMì›Øâ¢â¢â¢ «RV¥¬J k¨k¨kÕÚVk[­-ÔŸUVýYPÿ^ý{õï}sûæöÍÁ`ªÁTƒ©úî¬äm#‰äµ+kXÖ°¬!ü`ôƒÑFpjý©õ§ÖCàØÀ±c!'5'5'ò¶åmËÛb˜&†Å·ßZ| U|ªøTñË`Ë`Ë`°ö¶ö¶ö[o[o[ïŠ)mM6˜l0ÙË –,E?E?E?V «…Õ ß,ß,ß Ìf6³AW_W_WtëuëuëA;O;O;ÔuÕuÕu¡LY¦,SB¡_¡_¡ä®È]‘»2÷eîËÜ 6l€Ü©¹Ss§BáâÂÅ…‹A(‚Õz«õVëÁÑÞÑÞÑ<7ynòÜ®Ç\¹ƒê;ªï¨¾,÷Yî³Üǯ‹I$ÿéP“H$¯]t@t@tÜï¿ÿýþ0Ãü ó7@Ó°¦aMÃ@}Z}Z}ÊÇ—/™Á™Á™Áb”b”bT±@®e®e®eÅ= U#ªFT…âjÅÕŠ«vŸvŸvˆ/Äâ ;‰ÄNÀr–³ØÈF6‚ØWì+öaˆ0Dæ0‡A¨.Tªßò-ß‚b©b©b)èÎêÎêÎBè†Ð ¡ _P¿ ~AàèèÖqÖqÖqà¼Ùy³ófphíÐÚ¡5dü‘ñG`8ÕpªáT@Däå_·zÒ“žúÞ;’w•t@"‘¼6Iý“ú'õ‡yÙó²çeC·€nÝ ï ¾ƒú¼ñÆû¯·¯MÓ¦iÓ@m¤6RÆUãªq­XŒHÛ@Û@Û bù_]Œ.Fâ2q™¸ äååA¨,T*ƒ\!WÈ )d YÅ©÷ŸíãëC_úú41ibÒÄúíî·»ßn}²Dò×H€D"ùÛN(œP8¾nòu“¯›@õ‹Õ/V¿ZNh9¡%(&*&*&ê;åŸw§ÝvwÚÁ§8ýÃiXä¶Èm‘إ٥٥é;DòçHkH$’¿V­UkÕ°uæÖ™[g‚Aƒ&M`t³ÑÍF7{s¿øÑx_ã}÷AµøjñÕâá¨ßQ¿£~úN%‘ü5R ‘Hþ6§—^vzD¼ñ^Ä{ðц6|´L?6ýØôc}§{ur[¹­Ü¶Øj`+yò0ä!$¶Jl•ØJßé$’?Gº ‘H^Ù#ûGöìaiý¥õ—Ö‡O¯zýÓëà§ôSú)õîï'v»‰Ý`yŸå}–÷ªQj0ÕyªóTg¼oáîmHþ Ò‰Dò—e»d»d»Àúo×»þ[èÒ;¤wø-ð[à·@ßé^á”pJ8ýú;õw‚pppx²éɦ'›ôN"ùc¤@"‘üiº.º.º.°m×¶]Ûvs?ç~Îý W^uzÕ>ã3>ÓwÊׯz×ê]«w…–ñ-ã[ÆÃ¸qâ@×Q×Q×Qßé$’ÿ›TH$’?í¢ ‹.,‚˜b>ˆùÆŽ aaaúN÷Ïë5¿×ü^ó!ùAòƒäú,ôYè3}§’HþoR ‘Hþ°ô¾é}ÓûÂÞa{‡íÃZ k1¬8„9„9¼ƒ_ü¿°¿fÍþtÜqpÇÁ°¿ÕþVû[A™¬LV&ý/+ù—’M‰Dò_‰wÄ;âØýÞî÷v¿Ë<–y,ƒ–n-ÝZºé;Ý¿G§N!B Ø´Ø´ØB¾ ù2äK}§’Hþ3©H$ÿÕÃ+¯<¼)))0<{xöðlPÌUÌUÌÕwºJw+Ý­tzuèÕ¡W8zíèµ£× hGÑŽ¢úN'‘üÿ¤@"‘ü.õ}õ}õ}Ø_yåý•¡ýŽö;Úï€jë ¯6\ßéþ½ÚÎn;»íl¥ÉÒdipåÄ•WNè;•Dòÿ“ ‰Dò»î¯¼¿òþJÈžœ=9{2tžÞyzçéúNõïgnn=½W€IDAT½}zûôöS½Nõ:Õ ( @ßá$’ŸI€D"ù õfõfõf8Þåx—ã] µGkÖ`Óצ¯M_}§{s´xÚâi‹§`>Î|œù88·æÜšskôJ"ùR ‘H~#ºGtèðbÏ‹=/ö@à¤ÀI“ôêÍcôØè±ÑcèÔ'¨OÇÇÇ@Îòœå9ËõNò®“ ‰DòÁ«ƒW¯??????pë0ÖaìßÐpI$)¤òÇ?ölð³ÁÏÕFW]i%‘%‘%‘/½¡ˆ"Š@ÌsÄ u¨ä‘Gž¾G·iܦq°}jûÔö)œI>“|&Yß©þ€rÊ)žð„'@e”ý÷•½_ö~Ùûp+öVì­Xxñ8âqÄKoH&™dà(G9 âââÀ1Žq P¡B¥ïοý¤@"‘üêùÎç;Ÿï„¨&QM¢š@× ]7tÝð74ìˆ#Žð“åO–?Y‘¢#EGŠþ@÷çîÏÝaKŸ-}¶ôèuÑë¢×AüÊø•ñ+añ²ÅË/ƒDm¢6Q ±Q±Q±Qäää!½Bz…ôÒ÷¨‚Q{£öFí¡ÿþ7ú߀K/=¼ôÒ¦=L{¨ït¿/ý›ôoÒ¿…XxRìSìSìÿûçŽÎ::ëè,¸øüâó‹Ï!>*>*> Î=wôÜQØâ¼Åy‹3ûûûÃÁSO<³²feÍÊ‚¢‚¢‚"éf‰×N*$ɯBlClClÁµŸk?×~P½EõÕ[ü d$#¡zIõ’ê%àâãâãâóß?ö8úqôãhHOOOOO‡áý‡÷Þ\šº4ui µ§ÖžZ{*XÔ¶¨mQjÌ©1§ÆH6J6J6‚Ÿ¾øôŧ tT:*áΔ;SîLÍ<Í<ͼ~|ú4ôièÕüªùUóƒÓ§Nüó9þ(“““¨k_×¾®=˜7nú<ý¡Û«Û«Û »\ìr± ÔÙZgk­Ð#¸Gp`p r r ‚šv5íjÚ¹¹¹8&:&:&Bظ°qaã@½Z½Z½bÅŠ=qKâ–Ä-Ñ÷h¼}ú ‘HôOYYYYYnu¹ÕåV¸vàÚk!Û;Û;Û»þîz°Xo±Þb=”û•û•ûGW®]ÁÑÞÑÞÑn׿]ÿv}0›c6ÇlhGhGhG€³»³»³;60l`Ø´×µ×µ×A´-D Š„"á¥3eëËÖ—­‡È'‘O"ŸÀóGÏ=OÒŸ¤?I‡ªêªêªj0-3-3-åUåUåU°ö´ö´öùUùUùUg‰³ÄYpLvLvL‡—^vxµ jÔ |/û^ö½ iKÓ–¦-…èëÑ×£¯ƒ¡ƒ¡ƒ¡4šÛhn£¹o‘o‘oQª(U” l/Û^¶½ +•Æ <šy4óh?xüÁãÀkׯ=`sÝæºÍõŠ~ÉïÈïÈï@ߤ¾I}“`åâ•‹W.†Îý:÷ëÜœ9r>ô×÷£n¡n¡n!„½{ör.ä\ȹ&ãMÆ›Œ¡«ÐUè ~Ûý¶ûm‡ìÙ-²[ÀÓ£O>= ¶ŸØ~bû h7i7i7Co‡Þ½Á4Í4Í4 ÊŽ—/;|Çw|÷Ò†ÛІ6x$ñHâˆ;w$î<ûdì“±ÐØ¦±Mc’„$! „-Âa è~Ôý¨û >6øØàc}*ûTö)dÎ<œy–w_Þ}yw¨q¯Æ½÷`”Ã(‡Q`½Ñz£õFxØæa›‡m wNîœÜ9PuxÕáU‡ƒ§è)zŠVVVô¦7½AÞRÞRÞâââA£‹ÑÅ@æ¥ÌK™— Qt£èFÑ Ÿ(Ÿ(Ÿ¨ï•¯Ÿt@"‘ðhÓ£M6ÖEë¢ußTßTßT(ý±ôÇÒaáü…ó·¤ÑI£“FCn|n|n<,깨碞‘‘G><òá‘a퉵'Öž€øöñíãÛCúÚôµékáÎì;³ï̆UŠUŠU Ðøh|4ÿáL€ì„ì„ì(ÊeŠ2m‘m‘mƒíÛ ¶ƒì¾ì¾ì>¬^¹zåê•pÃ÷†ï ß—øù²ÌCæ!󀜌œŒœ (˜[0·`.˜$™$™$AÊ•”+)W`Ye=–õ€Â‹… /¦7šÞh ›ý6ûmöƒâÅ‹Âì.³»Ìî×b®Å\‹§wžÞyzR>Jù(å#ØÕ~Wû]íá™Ç3g¿?ÞõÞ¯÷~½÷Á³‘g#ÏFptæÑ™GgÙd“ý×÷£l†l†lÜè}£÷Þ°ÁiƒÓ'0p1p1pS·OÝ>uv·ÞÝzwk(T2¨d|©úRõ¥ B"B"B" úTô©èS tV:+aÅÝwWÜ…;†w ïþ‡ Ûb‹-("ŠÕ“Õ“ÕKKK0úÐèC£!>4>4>¾éõM¯ozAñûÅï¿Bª*¤™d’ Âmá¶pA±A±A±MMMáÄû'Þ?ñ>~pøÁá ‹ÓÅéâ`Í©5§Öœ‚'=ùèÉG V/X½`5Ä;w¾âž’PÿPÿP8˜{0÷`.¨ž«ž«žëû_ã?G: ‘H™23d&4 lØ0Ì¿7ÿÞü{Ðiƒ´A`>Å|ŠùðêäÕÉ«ÔßTSýMppÔÁQGÁ³KÏ.=»¶!¶!¶!`.7—›Ëa¨0T*€à"¸.œœ Âcá±ð°Ã»ßæ1ðÙï³ßg?œîºÿéþ|+ùVò-hkÞÖ¼­9ºººÃ¦:›êlªýÝû»÷wóÏÌ?3ÿ Z|×â»ßAÃ9 ç4œâq‡¸–.-\Zf'ÍNšüýñ. —…ËÐwpßÁ}Â; î,¸]kw­Ýµ6¸áƫ̰lÓÔ¦©MS¨Ò¯J¿*ý Eÿý[ô‡ÂF… ÁöšÛkn¯ ]>èòA—À¼­y[ó¶Ð²VËZ-kA½%õ–Ô[ººº`þÌü™ù3ˆÄÿaƒ8ÀpŽuŽuŽ…*ªtªÒ ¼¾ñúÆë°¿nÝþ:8ìpØá°d¶2[™-0éLçׂM)ŽGB展ÇV •ÛUnW¹ÔÚQkG­`Óæ‡M8±üÄòËÁ_ë¯õ×Bë•­W¶^ û½÷{ï÷†EŠÃF‡ÁÞÛÞÛÞŽ8~àx«ˆUÄ* ë¡ë¡ë]’º$uI///}ÿküçHg$’wXÖá¬ÃY‡!Ê>Ê>ÊZ´mѶEÛ—Þ`€@0Á‡8Ä!-‘-‘-y€<@¥—J/•^!LÂ@æ"s‘¹T|ñÿêw¸ó'jР±ƒØAìdA ü‰v´hÑ‚¸^\/®šÓœæPâZâZâ é­Ó[§·†Ã>‡}û@|@|@|´ÜØrcË ÿJþ•ü+ …B¡dé²tY:È2…LòMòMòM`9Ùr²ådgÊ3å™ÿ=V-ÏZžµ<¡Þƒzê=€£ Ž68Úˆ!†˜Wر?KYÊÒŠ·1ncÜ”ÔÔÃ@—¥ËÒe`/Ø ö {!{!{²²² »$»$»¤‘FÚØî/ÇË/w÷O'‰åñQ9rä@8ᄇ9ÌኗóòòòòòàÑüGó͇ý-÷·ÜßªŽ«:®ê8¨y¼æñšÇA7H7H7¨b?ýÒ/ƒO >5øŒ¦M7š^Qàþr¯Ê»B*$’wX„C„C„˜×5¯k^j̨1£ÆŒ—ÞðËãX}èCö û„}PÜ ¸AqP¯T¯T¯û‰öí'‚¸X\,.¡¹Ð\hþ6(C† hK[ÚÆcüüåý=éIOÀSL:tüútMhB“—>÷Ë™o¼ñjS›Ú ™£™£™â|q¾8ª,ª²¨Ê"¨z©ê¥ª—`€ÏŸ>0ùÔäS“OÁ´zÓêM«F#ŒF ¢ðø_¿¢«ÜTn*7ˆ<y8ò0-6(lPØvîݹwç^¨íWÛ¯¶Ô«W¯^½z°¾ßú~ëûÁÁ ƒAƒàɆ'žl€Än‰Ý»òŠòŠò ĚŚŚUäÍ Î Î †EÇ_t"GEŽŠõÇ÷COj|Rãh´¤Ñ’FKàèÄ£N1SÌÿÀ™„ÿM8 @âáÄɇa×Õ]Ww]…>øðÁ‡0üÆðÃo@ÚÙ´³igA§ŒSÆAlÕØª±UOù”O!6)6)6 •…ÊB%Äõ‰ë×Êæ•Í+ûOQ$ìHØ‘° >*ø¨à#ˆ>}>úQlÔ>¨}(?qüÄñ¢˜\-¹Zr5Q,É.É.ÉEõ5õ5õ5QLª”T)©’(&&$&$&ˆbù˜ò1åcDQ]_]_]__ä¾È}‘+ŠÏ|žù<óÅ¢oо)úæ·ÛÕtÑtÑtÅ_\|qQã{Æ÷Œï)Šùòä?Å   Q|6ôÙÐgCEñŇ/>|ñ¡(æuÎëœ×YŸ•=+{V&Š)7Sn¦ÜEålålålQ|ø<ðy (&~™øeâ—¢¨Ù¤Ù¤Ù$ŠÅ“‹'OÅgžuxÖAŸW^ýyuQÌ_‘¿"…(|PðAÁ¢———!Š™]3»fvÅÿ¹¤ йF®‘‹bê™Ô3©gDQ9]9]9ýÏï—Äî‰Ý»‹âû3ߟùþLQŒ¬Y#²ÆŸog—÷.ï]Þ¢8àà€ƒŠb|ÿøþñýE1­FZ´¢¨ ׆kÃE± }Aû‚ö¢&Š™‰™‰™‰¢(Öë‹õE±Ð¥Ð¥ÐEã ã ã E1eBÊ„” ¢¨ Ôj»Ý¢IE“Š&‰b|·ønñÝD19;9;9[KÕ¥êRµ(¦OOŸž>]ãíãíãíE1{vöììÙ¢˜žž.Šñ£ãGÇÅü#ùGòˆbþ½ü{ù÷D1æÓ˜Oc>Åœ¤œ¤œ$QÔÍÐÍÐÍÅôVé­Ò[‰büþøýñûE1Õ=Õ=Õ]KÅR±TÅ”í)ÛS¶‹â³¼gyÏòD±Ô«Ô«Ô«"o¡m¡m¡­(f|™ñeÆ—¢¨Û®Û®Ûþºÿõý{H€Dò ) ) )ÅeË>–‰¢²®²®²îoß—Ô>©}R{Ql‘Ü"¹E²(÷ îÜSßéß~ëCׇ®Åy·æÝšwK5ÆcñÿüÚqkÇ­'Š}Ÿö}Ú÷©(æÊ?”Hß½’üÛH—$’wУ:ê<ªµKj—Ô.ãããˆß¾¯ìnÙݲ»0xÍà5ƒ×€Ñh£ÑF£Aw[w[w[ß½x{õìÒ³KÏ.=þzüuxœ÷8ïñ˜ÒX¨T‚ëû®ï»¾’:%uJ‚¢»Ew‹îê»W’á—J@ßA$Éë÷˵Û/²¾Èú" m´iÐ&ð/÷/÷/×w:Éÿ¶åΖ;[îÀóÄç‰Ïá«V_µúª(Ž G}§“¼é¤3É;$åqÊã”Ç ¼¦¼¦¼ž2O™§þÈMÌMÌM„¸Uq«âV*[•­z… pÞV=:÷èÜ£3üϽðàûß?ø^ß©$o ©HÞ!á«ÂW…¯‡µkÖ‚Í›;6æ¹üW”Ý%»KvØôÓ¦Ÿ6ýû|÷ùîó…¬mYÛ²¶ý÷Ï]-ºZtM<4ñÐDØ¿zÿêý«A×F×F×F_£úúØåÙåÙåA»Äv‰íáp³ÃÍ7ÍQÍQÍQ}§“¼é¤@"y‡DŸ‰>}¼Â½Â½ÂzÔ£Þ?·ý‡‘#FB\Õ¸ªqUáƒÃþà0ØÖ°­a[ã¿Þ"Ñ"Ñ"òîçÝÏ»GGqth{j{j{êkT_¿Î :'@–{–{–;ܹs÷U& ú«†0„!ð¢Á‹/@Á½‚{÷ô=:’¿J*$’w@A½‚zõ ùËä/“¿ssónûºÎºÎºÎW=®z\uȘ“1'c”,=Xzäµäµäµ ýdúÉô“ðDóDóD1{böÄì²Ùe³Ëfïó>ïƒÅ‹;w@vKvKv „mÂ6a}[ômÑ·}-úZô5ˆ‘ÇÈcäPÚ¿´iÿŠz;4ßt|Óñbbòò¢A?OMûËT³ekËÖ–­…ës®Ï¹>¬»Yw³î#Œh0¢Ôµ¨kQ×’,’,’,àtãÓO7†f̘Aß}oô½çzœëq®üÏ„5úÞk¿U9¤rHåèêÐÕ¡«ó?æÌ”®JW¥ë«·ÿßT_^}yõåË!·ÞÑzGëФZ“jMª¬³¬³¬3´nÜ"Æ=÷xÜcðºäuÉë”y—y—yƒI_“¾&}Áõë!×C JV%«’¡àË‚/ ¾„ý;öïØ¿cccá½[ïÝzï=ÄbÒ„4! ¾(ø¢à ¸6äÚkC`ƒnƒnƒ®F^¼ Ú³Ú³Ú³/µóóâââ`nnnnnã§Ÿ>~:œ¬y²æÉš0¥ï”¾SúBĦˆM› ä@É’r(åPÊ!8zêè©£§àÌ…3Î\‡R‡R‡R{È=ä¹—¯]`ïÀÞ½¡ì~Ùý²û2+dVȬ׿]ÁH0Œ€U¬b°}ìžò”§ 7•›ÊMÁ¤‘I#“F`ô™ÑgFŸü‚ü‚üPB %/7øóÚ ƒÄ PTT„”“)'SNÂÅŽ;^ì{ý÷úïõ‡JG+­tŒÂŒÂŒÂô½Þ|Ò%‰ä-¦Û¥Û¥ÛIý’ú%õƒ®»6îÚ˜_¯µþã(P€pA¸ \E¨"T 747474pÄìˆÙ3Øn·Ýn»˜÷4ïiÞ‚7 nôR;?¯'l6 Ag«³ÕÙBÀå€Ë—¡k“®Mº6/ÏyþËó°UÜ*na²ÁdƒÉ`·Ón§ÝNè6¸Ûànƒ¡Æ75¾©ñ ˆ^¢—è¹—¯E„E„EôpîáÜÃŽçÏ?ž- Z´(ÓÏM?7ýüul ,@l(6‚ØDl"6á×ņèF7ºà/ø þT¬jXJ)¥ «¢«¢«òR{†bÂ(a”0 Æ c…1Ø4·inÓÚÚ·µok-,[X¶°„QÇGu Ò Ò Òõ½Þ|R ‘¼Å²§gOÏž¹¹¹à1Ìc˜Ç°>‡vžvžv$oMÞš¼2?Îü8ócH2K2K2‹­[-¶VÌ0xÏýžû=wH]º uAÅ"1é©é©é©¢JQ¥¨ g|Îøœñèšèšè ß;øÞÁ÷ ©wSï¦Þ`<Úx´ñhðøÂã / ÚgÕ>«ö4+lVجŽß=~÷ø]hr¨É¡&‡ÀÁÝÁÝÁjzÕôªéòKòKòKúÞ‹¿¯õÈÖ#[„3–g,ÏX•ãWŽ_9]?ïúy××Pæææ€Y™Y™Yümð·P/½^z½t(t,t,t„¤[I·’nU,ÆXíDµÕN@^Q^Q^„4 iÒR R R  P, E»È]ä.ÐIÖIÖI*_¨|¡2hiiÍ{6ïÙ¼µšÔjR« a„‘¾wÂLš P"y‹…Í ›6vœÜqrÇIX¼mñ¶ÅÛÀÔÇÔÇÔçŸË¡Z«Z«Z C‡>…ü¸ü¸ü8ð:ïuÞë<Øô²éeÓ ÂÛ†· o šÝšÝšÝ`4Ùh²Ñd(Qþ¢ü¸wuïêÞR¤ HæææàuÁë‚×Ho—Þ.½Ü,¸YpŒ§O1žÞVÞVÞV`¶Öl­ÙZÈwÏwÏw‡È!‘C"‡€PY¨,T»©vSí¦‚Ûf·Ín›A>F>F>Fß{ñ¿;w>î|ö9ìsØÛ/¶_l–‰–‰–‰ßvÄÅÅáÉ´'ÓžLƒ´–i-ÓZB•mU¶UٹŹŹÅP͸šq5c¨e]˺–5”e”e”eÀÃúë?¬²(Y”, ä“å“å“¡üaùÃò‡Ð`Iƒ% –½éMox\ü¸øq1¨OªOªO‚u±u±u1¸+Üî 0\b¸Äp‰¾GÿÍ%É[ìðõÃ×_‡ÈN‘";Á—Æ_i B®+äê;äïR:¨tPé ˜á7Ão†´=Øö`ÛƒÐûvïÛ½¥5$¿Cº P"y‹%|ðuÂ×woK_üo'Ó}¦ûL÷Amm-œñ9ãsÆò†å ËÓÃ%É›A*$’·*^¯Š‡ M†&CUÛTmSµ¾SI^7ÿ•þ+ýW‚ÅgŸY|çÇŸ~¼¾SIþ­¤@"y •••AAÍ‚š5Á>Õ>Õ>Uß©$¯›aºaºa:ô½Ù÷fß›pîĹçN@NNNNN޾ÓIþm¤@"y e̘=tF§‡F½z»’7ƒß¿!~CÀ6Ý6Ý6ΤI;“¦ïT’©HÞB   `9×r®å\¨Ü¬r³ÊÍôJòO105050…¾}úÀÅŒ‹3 㓌O2>Ñw:É¿…TH$o¡” )R6€C{‡öíAˆ¢…h}§’üÓ j0¨Á pövövö†SCO =5Tß©$ÿR ‘¼…2b2b2bÀ®¿]»þ¯ÞžäÍd`e`e`ýû÷ïß¿?\ï½ÿõþ2)eRÊ$}§“è›TH$oM¶&[“ ™O3Ÿf>­˜Mònó™ç3ÏgÔð«áWÃN|}âë_W¼žR˜R˜RW¿¹úÍÕo@ÛSÛSÛSß©%¯›4°Dò)¹Ur«äÞ,¼Yx´Z­¾SIôMÞNÞNÞú9÷sîç ‹Æ-·hˆ)bŠ˜»/ì¾°û”Ý-»[v.̽0÷Â\¨D%*é;¼äµ‘ ‰ä-RÒ¿¤IÐåêru¹`þØü±ùc}§’蛺±º±ºqÅZ OO?=ýô4ìß¼óþÍPn^n^nn§ÜN¹‚”)#RF@¥ÈJ‘•"õ^òºH—$’·HQxQxQ8~‚ŸàævævævúN%Ñ—¢ïо+úf¹Îrå C†„ ƒ»SïN½;Ê”(?PñþüjùÕò«A¢u¢u¢µ¾ÓK^7é €Dòɉ͉͉“N&L:™ƒ™ƒ™ƒ¾SIôÅ8È8È8\º>t}b7±›Ø xÈCþöýyóæ „DãDãDc}§—¼nÒ‰ä-’ö4íiÚS¨<¤òÊCÀÈÔÈÔÈTß©$úb 4P(aBà„À °vÊÚ)k§€ÛçnŸ»ý§å‚£‰&CCC@·M·M·Mß½¼.Ò‰ä-’SSSUVYXe!p„#Ñw*‰¾É“åÉòdÔtPÓAM¡ÒJ7*Ý€iÉÓ’§%Cxð:áu€¯øŠ¯ ¡GB„PRZRZR £,FYŒÒw/$7é €Dò)xTð¨àTž]yvåÙúN#ù×¹Ãî@§ÌN™2aÓÁM7„€7nT¼-æF̘Pܯ¸_q?}‡–¼.Ò‰äm Fò=ò=ò= n׺]ëvÒI']ßá$ÿ:N8áMÔMÔMÔ°1zcôÆh4,hܪ~«ú­ê}=ûzöup<áxÂñ”Þ.½]z”Ó”Ó”Ó@}]}]}tž:O'¨WªWªWFaU ªTá™ðLxL¾6ùÚäk0v1v1v™ÌGæB²,$™ÈD}ÒÛO*$’·€6U›ªM…ÂÎ… ;Cå+\ùc}§’è^xAI‡’% ß+ß+ß ò ò ò+îI]–º,uÔºXëb­‹u%êJÔ˜›07an8¦8¦8¦€ÚEí¢vmmmmmmŠŃ ¶[Š-Al$6ÖXc ÂûÂûÂû 8 ΂3 ……ÂB••…‘ÂHaÆŸnü9X„X„X„€•ÖJk¥…J5+Õ¬Tª®z¸êapzâôÄé X5±jbÕ*=¬ô°ÒC0O7O7Ožð„'úô7‡ þLßA$É_W´¯h_Ñ>ºt%è |fõ™ÕgVPkQ­Eµé;äuÑÞÖÞÖÞ†âóÅç‹ÏCƒ„  Ú9Ú9Ún'ÜN¸ )•S*§TÕIÕIÕI××׋Ç-ƒ]¨]¨](ØxÙxÙxEC‹† A¢Q„€c%ÇJŽ•À¢¹Es‹æ`öÜì¹Ùs0jjÔÔ¨)Èd²0Tª U@5ªQ ÔÓÔÓÔÓ@ûö;íwPþ~ùûåïCɃ’% 8±8±8J®•\+¹ï¼WðäÉ“7rÇåŽË™f™f™fP`Z`Z` ºÕºÕºÕ P)T 8Îpœá8Üänr79x÷ï5Ü]Ý]Ý]Á<Ä<Ä<f 3…™¾÷Ú¿‡TH$ot÷t÷tw˜¹kæ®™»`ᜅsÎûóöçíÏë;äUiŸjŸjŸBRpRpR0<ÿhü£ñ>.|\ø8H¿—~/ýÈ’eɲdpâ<Äy¸yºyºyB­/k}YëK°)²)²)‹“'-N‚¹Ò\i®E?E?E?ÀC õÝÛÿÐW­«ÖŠ÷ï-Þ Å-‹[·„ìžÙ=³{BLPLPL9õÉ©OàAñƒâÅ`gg-7¶ÜØr#4ÍmšÛ4l l l @^]^]^¨Nuªë»7ÿÆ{Œ÷ïO<ñ¤âÏ®­º¶êÚ r/ç^ν a7Ân„Ý€kæ×̯™ÃñÇ޶޶޶УA=€ûF÷îAÞDÞDÞDß½ûûHg$’7HÁ–‚-[àƒÍlþ`3\»síε; ë­ë­ë JC¥¡Ò,’,’,’€Câ,hµ Õ‚VðAì±Äê»’E/Š^Á<à‘Û#·GnPw`ÝuB· nAÝ‚ æÐšCkÃ]†» wé;õÛKU¨*TBâƒÄ‰àLÀ™€3ð`ôƒÑFƒ×÷^ß{}cÆ Œ j4¨Ñ@ß©_TH$o 9ò9ò9r˜_w~ÝùuA|,>ÿâ?N]œº8u#qGâŽÄA“˜&1MbôþÝS–R–R–§N%œJ€–',OXByuæÕ™ý ûö7·Jn•Ü*°^X/¬×wêwXšÐ’’“’“’áˆçÏ#žpßò¾å}Kèt¿ÓýN÷¡Wí^µ{Õ³ fÌ.è;ôŸ'ÉèÖù[ço‡n‰Ý»%BÞ¸¼qyã~û¾îNݺ;Á¾žûzîë ¦ëM×›J_,ÿ˜Ì~™ý2ûÁ÷¿ŸøýDȘ’1%c Œöí9ÚMj4©Ñ$µ•µ•µÕwZÉïLjcÄ1aaa›¼6ymòÓ»¦wMïÂ$&1 ¨º¥ê–ª[ôö“f”HÞ@µÜj¹Õrƒ¦›^lzñ·¯+–*–*–BLJv|(}ñÿÓž‡={ .x¸à!˜M1›b6¾]ýíêoWƒß!¿C~‡¤/þ7…°YØ,lŸ•>+}VÂü„ù ó êðªÃ«‡oL¿1ýÆâêÅÕ‹«§ï´œTH$o *5«Ô¬RÚMo7½ÝtM“M“M«xÝa³Ãf‡ÍÐnp»Áíë;í»#Ó&Ó&ÓVŬŠY>W|®ø\OÆ~2ö“±P¹]åv•Ûé;å›§(´(´(â­â­â­@i«´UÚê/Õ"«EV‹`‚áà †ÐÊ·•o+_X6pÙÀe!¹crÇäŽúµÿN*$’7X{ÿöþíýÁé¶Óm§Û?˜0;`6T_P}AõúNùöÓÞÑÞÑÞ]vtÙѪ׬^³zMx_ù¾ò}%}bô‰Ñ' Ÿ´?i‚kó¯Í¿6¶¬Ú²jË*(­SZ§´Î«çÌóËóËóƒ=½÷ôÞÓ²f5Ìjñ3ãgÆÏ„ï‡?üû᥉ÒDi~¿Ü¹7roÀß=¾{|!{eöÊì•ÿ¸–Ü-¹[r¶oÚ¾iû&غ;tw(D>Š|ùï>¼ûðnˆß¿1~#¤‡¦‡¦‡Âæ™›gnž !º]ˆîïÏõ E E E tvÐÙAgÁÏÂÏÂ϶šn5Ýj e§ÊN•z}ÛUR ‘¼Áj÷­Ý·v_ð}äûÈ÷~kø­á·Ð>¼}xûp0kfÖ̬™¾S¾ýîÄ߉¿YYY0òۑߎü < < <ÿx;ò¡ò¡ò¡ ýRû¥öKØ“µ'kO”L(™P2áÕsª»¨»¨»@zŸô>é}@]S]S]l²ýÉö'<*xDEDEDE€ÖNk§µƒ„‚„‚„KÄ±Ô Õ Õ !}Dúˆô >¯>¯~ N%”'”'”ÃÍS7OÝ<Ã<ü1¸ tè6ÒìÒìÒì@ù©òSå§`íiíií a3Ãf†Í„ot¼ñü&.ß+ß+ß ƒG 1x¨‡ª‡ª‡Âõˆë×#^ÿöÿ*©HÞ`&óMæ›Ì‡¦QM£šFMW›®6]¡‘w#ïFÞúN÷öÓi‚4ApnܹqçÆAë¸Öq­ãÀê¨ÕQ«£½]ËË–—-/ƒÆCã¡ñ€¤â¤â¤bˆy/潘÷ ÿ£üò?‚’g%ÏJžAÌõ˜ë1ס¨rQå¢Ê«øÅ¬ˆY³ŠêÕ-ª ¦ï™¾gút¯Ü½r÷Ê`QdQdQæ×̯™_ã{Æ÷Œï2dÈà‹ /.¼€•WW^]yž‡>} ƳŒgÏ‚îuÿ¨ûG`ºÝt»évx‘ö"íEÄËãåñrxð<ày<ÝûtïÓ½PÖ¾¬}YûÿÞ1QL!qGâŽÄò(åQÊ#(Š-Š-ŠÃM†› 7Aç{ïu¾ùùù``e`e`f§ÌN™ÁSð^*À”}”}”} ®E\‹¸«ŒUÆ*A9J9Jù7,wlVŬŠYè0¬Ã°Ãà‚ .,ÕAÕAÕÁ×z(þ%R ‘¼Án½wë½[ïÁ¡ƒ‡:YYYðCì±?ÄB¾s¾s¾³¾S¾½òGæÌ )ÝSº§t‡º=êö¨ÛãÕÛz =…žÆöˆíÛÎ9s:çóGÏ=4DÙFÙFÙÂÔ½S÷NÝ W¼¯x_ñ†‚»w îÂùù9\ùþÊ÷W¾‡‚¢‚¢‚"˜l4Ùh²\™zeê•© s‘¹È\€zÔ£èšëšëšChС= Ü4Ü4ܽ½½!óÓÌO3?…Éq“ã&ÇÁõÃ×_? û¿Üÿåþ/aföÌì™Ù K:/鼤3ì­½·öÞÚÿ½ÿª0U˜* R›¥6KmÊebZÇ´Ži yòõ7êoÔêyÔó¨çNININIо^ûzíë‹§‹§‹'ØlµÙj³Ê{•÷*ïõÛq”u“u“uƒgÕŸUV.¾pøÂaz~èù¡ç¡ÇÚk{¬…Sѧ¢OECvnvnvî«ï?s¹Î\¦ûM÷›î‡Œ3>Ìøð:(ÿ©HþÍ $ §N)œ¿~üõã¯aKÏ-=·ô„{Æ÷Œïƒ0[˜-¼4g¹I¢I¢I"˜~gúéwúîÄÛK~@~@~tÃtÃtÃ@÷©îSݧGÃÈ‘ƒxH<$qÄŒ-6Z Öµ­k[׆ÔüÔüÔ|À[l©˜óög‚¹`.˜vØa÷Rûf˜aö~þ¿©P¡Þã=Þ ( ÿC;Z´h;ÜáÎKÝ9#?#?ÚvÚvÚvPüAñÅÀÂì…Ù ³!(-(-( æ¹Ìs™çEK‹–-ÁEp\€÷yŸ÷‡<äáKù 0Àp §ßÆò„æã—ÚïD':ð‘ð‘ð°‘läׂS˜+Ìæ£Íh3Ä 1H!…@ƒ …ÎBg ƒ„AÀ|ÁÀAòò5oSL1aª0U˜ &¶&¶&¶0¼Êð*뀺“º“º(Ú(Ú(Ú€Å`‹Áƒ©(hB %ð ¯—ÚuÇwv »„]ÀG|ÄG@ jP0Çs033‡ .@÷Ðî¡ÝC¡êüªó«ÎúÑ~`ØÖ°­aÛ—úùe-ÍZšµÊ\Ë\Ë\¡ê”ªSªN6° ¯õüS¤@"ù'e‘EäûåûåûAø©ðSá§àVÜ­¸[qWWW†w ïÞ:fuÌê˜Á˜ªcªŽ© î;Üw¸ï€J•+Vü†c·Ün¹Ýr¨ìPÙ¡²Œž5zÖèY`ll¬ïN¿½,'XN°œ³=f{̆ûŽ÷ï;‚—ÖKë¥ýëí·7noÜŒîÝ7ºwÞix§!yyyy{óöæí!pfàÌÀ™Ù.²]d;u u u÷±îcÝÇBQFQFQäÔÉ©“S’/$_H¾yÃò†å ƒ$Ç$Ç$GH´N´N´†¼°¼°¼0Hþ.ù»äïÀ©®S]§ºR+¥VJ-¸`tÁ肸«ÜUî*È={:÷4ÄŒ? &L,˜¹Gsæ­x\0½<½<½r{äöÈí¥ËK——.×£®G]¾Ôñ"ˆ1WÌsáyæóÌç™{8÷pîax¾íù¶çÛ€e,cdœÌ8™q4W4W4W %(%(%²/g_ξ̯SúZo±Þb½¤5Hk'Fœqbøºøºøº€Ã ‡3Àý®û]÷»¯~&àÎÖ;[ïl—z.õ\ꃙƒ™ƒ™¾Öß’¦–H^‡‘Œd$Ü(¸Qp¢;GwŽî !'BN„œ€èþŒ6 ¾};úv„Æ¡C‡BMûšö5íÁä®É]“»ÿ}s¡kBׄ®]·wÝÞu_]|uñU0I1I1y…ßd$ÌS³§fOÍà»”ïR¾K A‚€ËX—±.cÿ|{åõËë—ׇ'»Ÿì~²”””@wLwLw > > P-¡ZB5(î^ܽ¸;ø6òmäÛ,Ì-Ì-þéqí·Úoµß“€'O u@ê€Ôà‘ç‘ç‘–û-÷[î‡H×H×HWP„*B¡à²ße¿Ë~HÔ&jµ Ÿ!Ÿ!Ÿ F5Õ`(++Ó:Oê<©òRy©¼¼¼¼ zÝêu«×ÙVÙVÙÖ?¿ßÒóÒóÒó`‰Ã‡%0¼öðÚÃkƒïC߇¾õ}”þ–TH$¯â Oxª¶ª¶ª¶÷4îiÜS¸ºøêâ«‹áaÌØ‡1 |%|%| "D4ˆÿ*þUü«€çHÏ‘ž#Áxñã5À 1èÏÇ:.tì\µsÕÎU°Äu‰ëW0É2É2ÉÒ÷ ½;vÖÚYkg-ˆ‹‹ƒ™Wg^y*u¯Ô½Rw}§“¼.ÅÏ‹Ÿ?‡åõ–×[^ì§ÙO³Ÿ㯌¿2þ ç…óÂk˜'áUI—$’?AÜ-îwCòµäkÉ×àŽÓ§;NpËé–Ó-'(ìWد°x™x™x™À˜ucÖY^½z ‹»w-^þ>ƒ 2ôÝ+Éße@ÝuÔ…´¡iCӆ²´eiËÒ`ʇS>œò!X'Y'Y'é;¥äïR0´`hÁPX·pÝÂu Ak¡µÐZÀÐAC Â,a–0Kß)Ÿô€DòŸSL1úúúà ù ù 9Ìš4?æ›;lî0þ<ü9tºØéb§‹°°Å [@ÐÉ “A'Á¯º_u¿êÿá‹ÿïöóMc¿þ) è{ß=&‡M›†½>ôúÐ ¬,­,­,aîÁ¹ç„'ÓŸL2ÄŸÄŸÄŸôVò§-a K .7.7.¾¶ÿÚþk{кiÝ´n0yâ䉓'‚eMËš–5õö¿“.H$€v«v«v+$''ÕW^\ywºßé~§;áB¸Í7;Üì0´ÞÝzwëÝPµ jAÕ‘‘Ñ_þСC7®ջVïZ ‹Ó§-N“\“\“¿á¹fÉ_S>¥|Jù”Š g‚KƒKƒK¡Kv—ì.ÙÐò‡eK°œi9Ór¦¾ÓJ~OéÞÒ½¥{á´æ´æ´Ž Ç„c´.h]к†.ºdè0M4M4MÔwÚ?Nº y'ççç½¼{y÷òàòùËç/Ÿ‡$¯$¯$/p3s3s3ƒ÷V½·ê½Uà]Ï»žw=°xdñÈâP›ÚüÍþ)ò~ò~ò~ /——ËËAì(v߀ÕÈÞvF+V­„¡%CK†–€O3Ÿf>Í`Wý]õwÕ‡;oì¼±zG÷Žî -¾hñE‹/Àì˜Ù1³cúNÿîR–+Ë•åpG{G{G G+>+¼&zMôš-ÂZ„µïÝÞ»½wƒÅp‹áÃAÖKÖKÖëÕ㼭įůů¡hfÑÌ¢™mmm 7ÜpcDŒŠ1 ¬[5¶j K—.©øÅÀÂÊÂÊŠ_çx[H€äVšUšUš¡×B¯…^ƒóÎ_8RW§®N] õ×o\¿1tl×±]ÇvPó`̓5‚Á ƒ/ôþïóÐì¡ÙC3ر1bc,½¶ôÚÒk`ö¾Ùûfïë;äÏ*¿R~¥ü $.K\–¸ BœBœBœ üiøÓð§P~§üNùp=âzÄõÔQoD½PóyÍç5ŸƒËr—å.ËÁdŠÉ“)€X¼jª±ŸoÚ-·.·.·†dËdËdKˆk×(®V>VBüÙø³ñgÁÀÞÀÞÀê¨{ îhÐ8 1¸7qoâÞŒãŒãŒãôÝ©×O*$o”_V_»ñùÏo|gãÏÆŸF£Ñh uTë¨ÖQÐêX«c­ŽãMÇ›Ž7Š·ùŽ—‡æÍšÃ&å&å&%,Ùµd×’]`6Ôl¨Ù[pªRò?ÊN–,; ñ³ãgÇφÈÊ‘•#+Cd‡È‘ £ZFµŒj ''µj9Ô×Ö®­][ƒ{ˆ{ˆ{ØùÚùÚù‚eˆeˆe˜]6»lvL L L @î)÷”{¾zÞ¿J7O7O7”¾J_¥/w,îXÜŠ-(ZYƒ³g †x³x³x3x¾ûùîç»!í»´ïÒ¾õõõ°[h·Ðn!ÔîS»Oí>à½Á{ƒ÷¨ùSÍŸjþ¦¦¦úÞ«ú#’§ `äœÈ9‘s.´½ÐöB[¸tùÒåK—Á8Ö8Ö8ºt)èR-´<Ðò˜Ï3Ÿg>OßáÿyRðnÓŽÒŽÒŽ‚bM±¦X‰7$n€ø±ñcãÇBBqBqB1¼Xÿbý‹õPZPZPZbM±¦XäkåkåkÁj±Õb«ÅP¹såΕ;ƒU«V ÀÌÛÌÛÌÌvší4Û &·Ln™ÜC¡ÆP²ë²ë²ë`0Ë`–Á,ÇÉãäq ê ê êšMŒ&TkTkTk@iª4UšBé´Òi¥Ó D[¢-ÑBGGäÏ;Ÿw ´Ú-h/k/k/W¹ÊU0™`2Ád8…9…9…[°[°[0Ôì[³o;PýVõ[Õoe?Ë~–ý@þBþBþñû»¼Å¿IÞ(%”P/¾øb œË?—.n,»±ìÆ2°›b7Ån ¼÷Ù{Ÿ½÷44hhÐÐL½M½M½o¼ñÖw'ôG,‹ÅbKÅR±8ÊQŽê;•äŸ"ß&ß&ßVXaÔ§>õú?Õÿ©þOÀMnrʋˋˋ¡xTñ¨âQPÔº¨uQk(”Ê åQ'£NFȨŸQ?£>*÷}ÓÿûG…£ÂQÔ‚ZPókA%‘à?þ`„F€Ñ£;FwÀk¬ÿ¯ÏMe*Sÿ×ÓH# È$“LÀgœaÑÕEW]×f®Í\›Áà!ÁC^^”*Ž8þÌ5öŸWýc8îïÁ|{H€äŸñóÝõ)Y)Y)YpìÖ±[ÇnÁJw*Ý©µ'ÕžT{|üEðÁàYìYìY ²²²úÿ律©˜©˜ +…•ŠŠeTÇ2–¿°Dò‡8âˆãK®`+ÀØÙØÙعb"$zЃú+ùߤ@òZ¥ú§ú§úÃÉè“Ñ'£áæ‡7?¼ù!xzzÂôƒÓN?žåžåžå ÷‘ûÈ¥ßðÿ¼}ìcN:éÀZÖ²Vß¡$ï*Ãñ†ã ǃR§Ô)u¯Þžäõ ÉßcÓ˜iiipzØéa§‡AÈŠ!+À½£{G÷޵ïÖ¾[û.ÈåÆrc}‡ ¤’J*¨W¨W¨W€ØFl#¶Ñw(É»ÊÄËÄËÄ òîäÝÉ»£ï4’ß#’¿æ—¸¹µrkåÖ‚“‡N:y.¸tâÒ pmîÚܵ9L¾7ùÞä{àÓÞ§½O{í•í•íÕwø·Pe”v§v§v'ЉNtf0ƒú'y×Xܶ¸mqR¦¤LI™¢ï4’ß#’?¥8¢8¢8.TºPéB%8p*àTØæÚæÚæÂ§?=øéAðžî=Ý{:Ô4¨iP8ÂŽè;ýÛOð<O µ¨¥ï4’w•¹Ü\n.åYåYåYÐÐÐÙYÙYÙY}§“üB*$ÿ§òíåÛË·Ã-Ý-Ý-xhà¡ [ [ [#"GDŽˆ„f×›]ov ;v4”¡ù版ˆ/ý)‘è‘yºyºy:(/*/*/‚æ´æ´æ4bˆ¡¾ÃI~%’ÿh&š‰f•••»“v'íN‚Œ°Œ°Œ0è5²×È^#¡½{ÿöþ`jbjbjt¤#Ò¿þü2Õë/wc ú%yWçç為™º™ºhghghgÛØÆ6}§“üB*$¤þ”úSêOpðãƒüîͽ7÷Þ\° ° °…Ï ?+ü¬¬eÖ2kÒc=ÿ2ò™ò™ò™ < A,ËÄ2}§’¼« 40hºÛºÛºÛ i¤i¤i¤ïT’ÿM*ÞQ¥ãJÇ•ŽƒsCÎ 97Žõ?ÖÿXð¸îqÝã:|¥ùJó•ܹ/r_ÄŸD¢W²š²š²š MÐ&h|ðT¨Pé;ä]cð™ÁgŸî¹î¹î9hnininé;•ä“ €w„ØDl"6G)R¥À®â]ŻС¬~Yý²ú0ÎiœÓ8'hr¤É‘&G@ž.O—§ë;µäª Õ„j@;ÚÑÄ=âq¾SIÞU†] »vZЂ =¬=¬= |ÄG|¤ït’_Èô@òze©²TY*X×v]Ûumae핵WÖßk¾×|¯Á· ß&|›Ík5¯Õ¼–ôÅÿ¦’»ËÝåî .Š Al+¶Ûê;•ä]¥(V+ŠA×B×B×´*­J+‰úבμeÔÛÔÛÔÛàºêºêº ö$ìIؓՖV[Zm)Ì›77ÜÝÝe,c™¾SK^•pD8"m=m=m=*»”¿”èb•b•bˆ·Ä[â-Ð\×\×\×w*Éÿ&oºŸ'€yqòÅÉ'aÇ¥—v\‚øVñ­â[ÁCn ¹múµéצÔ0¨aP¨A jè;¼äï"/È @/Œƃ¨¢ô¯[¢' #…‘ÂDÑF´ÎGç”RJ©¾ÓI~!ýñ†R7V7V7† Á‚/þFûík>¶>¶>¶°°ÓÂN ;}ª}ª}*P…*TÑwjÉë"L& “Aã¦qÓ¸2dÈøíò¨’¿&’H"AtÝD7DADÀ 3ÌôîßGá¯ðWøƒ8H$M²&Y“¬ïTÿbPP1‡/ä ù€+®¸¾¾ÍJ÷¼)®r•«Z%µJjX¼cñŽÅ;àˆ÷ï#Þ0fܘqcÆÁä“wNÞ öeöeöeH_üïY¬@V2™ƒÌÄiâ4qš¾S½ùÄâ q\zýéõ§°¢óŠÎ+:Ó3OÎ<9S±öRñáâÃŇA9C9C9âÓãÓãÓ!«0«0«Pß½øç8àÚµk?Öwªß§j¡j¡jÏ­ž[=·‚ÔC©‡R{ØÃßp3mɘ’1%c %$%$%tótótó*^8îḇã`•Ë*—U.pÛê¶Õm«×ßo©ø—Ӟממ‡óUÏW=_fžyxæa0ŒcÌZ0kÁ,hy¾åù–çA¾E¾E¾Eß©%ÿ4ù ù ù LÁ444ô꟣٨٨Ùb$ý}í¦nNÝœº~üàÇ~üêß«¯þ=GÈ#ä°"kEÖŠ,M M Me±²XY ‹Ú/j¿¨=lk½­õ¶Ö/å\¬Y¬Y â2q™øß{£h¬h¬h еее tV:+õê÷©ÜTn*7Ø:b눭#`aû…í¶q¢8QœøêíßßpÃý °üÈò#Ë@éÒÒ¥¥K¡xHñâ!°Åw‹ï_p‹u‹u‹››67mn¾þ~KÀ¿Tî¹Üs¹ç`ÍÍ57×Ü„½óöÎÛ;Þ¯ñ~÷kÀ”€)SÀöcÛmÿÅ•µäŸ!dBˆ‡ÄCâ!ÐZh-´¯‹¾¢¯è t£ݨ¸4Кִ²È" XÊR–[ØÂË…äArÄ®bW±+ˆ;Ä⎗>÷ó*>á>>æc>~i»½éMïÿ¼B A<%žO8Gœ#Ί)¦˜Ë\æR±¼q $T|¼À§À§À¶ÚnµÝj ™ù™ù™ù/µM4ÑÀ—|É—ÀINr˜À&ƒÌàß׬#YG²Ž@òÆäÉÁûï¼?Ù³=fÔSLYMn5¹ÕäTY[em•µ`W`W`WªpU¸* ;v,ì[Ÿm}¶õdÍ›5ö¥ ýÜ_ñ xP<â"q‘¸ˆ_ïñùuQ§ld#C 1Àp†3\ßGßo)T •B†‹ .e]e]eÝ¿qa„âdq²8¹âO 'H$‘D`"™œãç@üLüLü ıD,©hÎüGóÍ—h—h—h(³(³(³ÑD4M€›Üä&ÇÑÏíDAT,¾¥D‰ò·q}ý|ý|ýàs«Ï­>·³‹fÍ.Báܹ…s!Ö1Ö1Ö<'zNôœ5»ÖìZ³ë?°Ÿ^ÿ&$„ø¹ø¹ø9<²~dýÈ6>Øø`ã°ûÊî+»¯`þ²ùËæ/''' ‡rôZòo¡°TX*,Aå¥òRyÁ⹋ç.ž 111à|Þù¼óy(]Yº²t% m0´ÁÐðXóXóXçÖŸ[n=ÔÛ_o½ý`|Êø”ñ)èÙ%²K$œ?|þðùÃr#åFÊ P?V?V?††‰ &Bã³Ï6> k­=¶ö”*K•¥Jpöröröe2HC͆š 5»»»íÚ-´„ 9rtWtWtWÀÏÚÏÚÏjd×È®‘ ßµú®Õw­ fÝšukÖÝÝÝ(1*1*1‚]Mv5ÙÕtgugugAQ¨(TÂýÈû‘÷#a‚÷ï Þ`gegeg;Gî¹s$´Ö´Ö´Ö@SšÒô¥ñ,;Pv ìÜ^}{õíÕP?¡~B}8}"úD4´Ñ¶Ñ¶ÑÂþo÷»ÿ[ð|æùÌó `<ðÀtOuOuO!¸,¸,¸ 6´ßÐ~C{€þ7úßèž.xºàé¸iqÓâ¦EÅ:MO6=Ùô$¸p=àzÖE®‹\ µ¢kE׊]¨.T íÆ·ßn<WWWƒO7Ÿn>Ý }¿öýÚ÷ÓÃñè¥ðRxÁƒ%K ô‡ÒJxõvµ×´×´×àbÝ‹u/Ö…˜Ø˜Ø˜XÐÓÓh³ýÍö7awûÝíw·‡¤o“¾Mú¼“½“½“áa¯‡½ö‚¾ñ}ãûÆC£ÑF7 Ô¡u€œà\)»Rv¥ öÞÝ{wï]î7Üo¸ÔŸ[ný¹°«Î®:»ê€G”G”Gt2édÒɤ"¯øX|,>†‡=zÀ±-ǶÛúðЇ‡à‘æ‘æ‘G'ŽN]QŸV]it¥Ñà´Õi«ÓÖ×·Ÿ¤3z¦j«j«j {Oí=µ÷,k´¬Ñ²FÐvwÛÝmwÃŒof|3ãpÚæ´ÍIšC[ò{F1ŠQ`nenen¹.¹.¹.PæSæSæC[m9´%dª2U™*Ø›½7{o6ØØØÀµ×V\[Î}û:÷RRR¸réÊ¥+— 8"8"8ú'öOìŸí¶Øn ¬ÿtý§ë?…4¿4¿4?(½Vz­ô”÷/ï_Þ†Œ2fÈHÛ”¶)mìÕíÕíÕAŽyŽyŽ9¬>µúÔêSÐdz“éM¦C@Ç€ŽaݲuËÖ-ã×3ñ#âGÄ€œs9çrÎA“ M&4™žÏ=Ÿ{>‡J#*¨4º„w ïÍ5oÔ¼DäDäDä€.@  aŠ0E˜S ¦L…µjÔªñVM4`<Àx4¨Û nƒºà˜í˜í˜ Äb< = = ¡Ð±Ð±Ð"="="=^jà/xŠjŠjŠjàVÓ­¦[M¨´µÒÖJ[¡ÓG>êô(W)W)WÁšëk®¯¹þ{ý÷úï…æ½š÷jÞ ÖM\7qÝDûÈ}ä>»0vaìBÈ÷È÷È÷€F¥J•‚áxÃñ†ãÁæ‰Í›'`þØü±ùcýŽò=ò=ò=`nnʡʡʡ¯ÞnxëðÖá­a÷ÒÝKw/…n3»Íì6zì=²÷HØscÏ=7 <*<*< D;ÑN´ƒçKŸ/}¾ºî뺯ë>0»fvÍììÙ²gËž—Ïtý|æ@è&tº—»—»—;$&'&'&Cɺ’u%ëÀÀ×À×À4Aš Mx–y–yþ‡©·ÁG𪚪šª¸{ôîÑ»GA¹V¹V¹Z6´lh öþöþöþN»v;í~ýûI*ô$#:#:#–”-)[R7Žß8~ã8|øEà0`Ñ€EÑ£=FÒŒn’ÿB¾C¾C¾ä)òy ȳåÙòl0¼kx×ð.XDYDYDA­ãµŽ×:‘}#ûFöyGyGyG0?c~Æü xyyAýÚõkׯ >„*ŽU«8‚}eûÊö•Á³À³À³t™ºL]&¿øü"T›VmZµi`kkkkkûûãjǪ̂™Q3PÜWÜWÜÓOL?1ý¤âuÅrÅrÅr­”­”­|éƒ4høõRˆÁ"ƒE‹@¥ˆRDÙ³ f ûtöéìÓðldzÏv@†o†o†/¤þúCên–n–n¥{J÷”Fsæ‚ëc×Ç®¡arÃä†ÉPÕ£ªGU~{øíá·¡éܦs›ÎÕ÷Q † ¥Z©Vª_½½'gŸœ}rOOOÁ%Õ%Õ%ªÇV­ VÍ­š[5‡u„:B F+ŒV­ƒï ¾3øÌ›56k öí;Ûw†‚Ž ^^ÄL50†1ŒÇ8Ç8Ç8èØ!°C \޽{9’Ì’Ì’ÌÀ*À*À*܌܌܌~?·ÁçŸ|òEòEòE ;,;,; FFF X¬X¬X ¦íLÛ™¶Ê)§üõï©ø‡=r}äúÈæ„Í › B£ÐÀ¼çóžÏ{>‚à#Pq­I"ùdr™\&äÈ‘ƒÚMí¦vÁOðü*Þ§¤¤2s™¹Ìœ_OUÿzîñ9Ïy^ñ~!GÈr@œ+Îç¾´Á<࿞*e?ûÙOÅsÞ`Pñv]]]9ÊeŽ Æ‰qb‡„CÂ!M–M–M»Oí>µû¾îõu¯¯{3Î8º*º*º*À)Nqê¥&˜`¯ÿaÿr×¾¼ª¼ª¼*tìÞ±{Çîpkõ­Õ·VCÈœ9!sÀ¯¯__¿¾b€×߬²øËÏ+Q‰J/ïŸô +@‹mÅ< xâ‰'pžóœÙMÙMÙMüÁo:Þt¼ _¯ýzí×kÁ±¾c}Çú ö{Š=`‚ ~i{¿¬ù/cxÅðŠáPå¨rTÃ%Ká¾p_¸ç8Ç©8^¾Eœ%Îg*„ ¡@ %”ðÛÇ5(P]èB——7ðóþ ‚ˆŠÇñÚ´7ho±«bWÅ®‚ã-·<Þ|úô=$“ÌyÌñ—ÆcLÅs¿G¿7ÿ©xÍ455áøãCŽe¥ËJ—•B‡>útèSã¦ÆMëöÖí­Ûë;­äM%L¦ Ó@HR…ÔŠÇË¿/ÿ¾ü{ÈŸŸ??><-|Zø´=iô¤ÑÐ\Ò\Ò\uœ:Nå-Ë[–·¬h×w¿ï~ßýšš iSÓ¦¦M…¨…Q £‚¼º¼º¼:xxx€vŽvŽv”RþIù'ß)¿S~'xzüéñ§ÇÁ_|»FvìAõ°êaÕÃÀ,Û,Û,72nd -:µèÔ¢SÅõlõlõl(S”)Ê^ºsI>K>K> ”Ê@e dŒÏŸ1´Úmø÷?îÊÍÊÍÊÍ ³[f·ÌnP5 j@Õ€ÿ>®åVåVåV š š šeš2M™¦âuÕPÕPÕP(__¾¾|=ˆ¡b¨ ª«ª«ª«P¾µ|kùV~½¶\]] éõÒë¥×ƒJ³*ͪ4 \» v ÐhT£QFÿuÿëþ×Áà ƒ/ ¾ÕNÕNÕN(ËÄ2±"GYRYRYlÿxûÇÛ?†[é·Òoý ¦ô6ênÔݨ;”'”'”'¼z{urêäÔÉõ9õ9õ9Hü<ñóÄÏ!þTü©øSPغ°uakðñ÷ñ÷ñ‡²Œ²Œ² PY¨,T N'ˆ@=Z=Z=Ô=Ô=Ô=@×U×U×Tö*{•=”ï,ßY¾TóTóTóÀ'À'À'¬s­s­s!jEÔŠ¨P£¨FQ¢?pe–g–g‚º¥º¥º%”=*{TöÊ–,?êTuª:”­”­”­þ¹ý#Ÿû³n“ˆ’ˆ’زj˪-«àêÌ«3¯Î„O">‰ø$Ú·nߺ}k/–/–/ÖwZÉ›N£Óè4:¸xìⱋǠئئØÒz¥õJëª*ª*ª*`Ó̦™M3è¿·ÿÞþ{!>->-> ² ² ²  Æ®»jìª8E^-¨ZPµ ²„,! nO¿=ýötH,H,H,€=z@Ó¦ LárË=.÷€ÇÓO<T6*• ؅؅؅@¿õýÖ÷[Ö3¬gXÏ€j[ªm©¶n»Ýv»í±Ç~û1(((]éJWˆ½{-öXåXåXå€ÏG>ù|fß™}göä ¹B®Ï<ðlxL÷˜î1lfÛ̶™ Ùk³×f¯_C_C_CðÜê¹Õóÿ¸¹J³W³W³×â^ È/É/É/çSΧœOì¾ì¾ì>D­‹Zµ®âRåTË©–S!) ) )Œ¡^ïz½ëõ†òŽåË;³Üg¹Ïr¡¡sCç†ÎP›ÚÔn)o)o)!Î-Î-Πʋʋʋ@¼/ÞïClnlnl.Tº[én¥»P×½®{]w`! Y!!!!!!`ýÜú¹õspëîÖÝ­»þŽËÐèÐèÐhP„*B¡à;Ìw˜ï°¿ÞžÝ»v#Àò¶åmËÛp+þVü­xˆ™3#f´QµQµQA“†M6iÔÔÔ ,–KÀcÇ Aû0öaìCN §…ÓPíLµ3ÕÎ@üœø9ñs@|$>W W W Tq¨âPÅJÊKÊKÊ¡ª®ª®ªšŽm:¶éØßϫ֪µj-<Úøhã£õ ëAÖ°_l¿Ø~1,:Xt2r2r2rÀ6Æ6Æ6Ü» v C…¡Âð5î Qò·J–>,}˜(Îrå:ËU§)¦)¦)D1iaÒ¤…úN'y[•þXúcé¢8)uRê¤TQì?¯ÿ¼þóDñËõ_®ÿrýKo<'žω¢¨Õ¢Zÿç±;QŸ‰ÏÄg¢ø?ϧ‹¢¨µ¢ö¥Ï%ˆ b‚(ê”:¥N)Šbg±³Øù·9æ,›³lÎ2QœÝuv×Ù]_zá‚xA¼ðt`¤8R)ŠºKºKºK¢(¶[Š-EQü^ü^ü^Åóâyñ¼(Š[Å­âVQŸŠOŧ/}>ULSEQ·N·N·Nó{æ÷Ìï)Š9ßå|—ó(îè¿£ÿŽþ¢˜µ,kYÖ²?0 ™b¦˜)Šâ8qœ8Nÿç’…(þÏãf/Ó:q¸NÅ`1X Eq€8@ Šâfq³¸ù¥Ü¿¼þKÎR]©®TÅ‹âEñâKÛ"‡ˆ¢î²î²î²(þÏ¢N/mç’xI¼$Šâ&q“¸é¥\ÿRë²Öe­ËÅõ ëÖ'ü çˆ9bŽ(ж¢­h+Šbu±ºX]¬8®“Åd1YÅÅâbq±(бb¬ûÒ¸-—ˆKDQLÅDQüŸK\¢(Îç‹ó+6SàPàPà ŠE׋®]Å“Lþ1Y[$¶Hlñrf‹Ùb¶(Š£ÄQâ(QcÄ1FÿçR…øëþ£Ä(1JÅ)âqÊK¹^3á—¿¼Æã+'®œ¸r"Ôú¾Ö÷µ¾‡± Æ.»,šY4³h¦ï”’·•ÆKã¥ñ‚W~¸òÕî¥î¥î¥°äÓ%Ÿ.ù¬+YW²®ô÷o¿´yióÒæðY¿Ïú}ÖÔÕÕaiêÒÔ¥©P¥s•ÎU:ÿa=ö°|ÙòeË—AùöòíåÛÁÿÿü€65ÛÔlSóÈ!`ã6U†*C•“&Mš4i’¾Sýq[?ÜúáÖ!ùjòÕä««¨v?×ý\÷s †Côò¯“ €WtëÀ­·À¦I›&mšÊ:”u(ƒþ»úïê¿ zô4è©ï”’·x\<.‡eÊ>”A»¹íæ¶› ~þ~þ~þàø“ãOŽ?Q¶Q¶Qöß¿}õQõQõQHù,å³”Ï@w@w@wœ—:/u^ F{öíýçÆ#y_ò¾ä} z¤z¤z®m\Û¸¶EGEGEÇWn^òmóÛæ·Í â â âarîäÜɹúNõÇe8e8e8AA³‚fÍÀÕßÕßÕŒ‚Œ‚ŒþÆ'õE*þ$]ª.U— Á;ƒwï„ýyûóöçÁ°ãÃŽ;~ø“„IÂTéJÞp}éK_˜ü|òóÉÏ¡ß÷ý¾ï÷=4 hÐôÕ›—HþŠ]»"vE@zrzrz2|Þåó.Ÿwyõv%i&À?H3T3T3ö¥îKÝ— çýÎû÷ƒI'užÔ/n¼¸±t3ŸD_ZÒ’– ˆWÄ+âA]K]K]ëÕ›•H^…ÁrƒåËAc¢1јðÛÇî$z%=ø_¨òTyª<ض|ÛòmËáºÑu£ëF0k÷¬Ý³vCãöÛ7–ß“è[sšÓqŠ8Eh>Ó|¦ùLß¡$ï:Å"Å"Å"ÐÖÖÖwýSQQGmx´ntºÑéF'PG©£ÔQ½]1RŒ#!eRʤ”IpqèÅ¡‡Bæ€Ì™~ÿsRð;”˔˔Ë`ãÌ37΄ðKá—Â/Á¬u³ÖÍZ©©©úN)‘üì—ÀZa­°õgêÏÔop ^¡^¡^« V¬æ×õÒ%oƒÍ› 6ƒúõê¿a-€7<@ €è:Ñu¢ëÀ7Ý¿éþMw(Ñ•èJt¯ÐðÏ˾k{i{i{Áâ‹O,>÷Ýï»ßwÿýIÀÿRêQêQêß¹|çò Ä÷ïßfÎ œÕ<ªyTóxõíH$¯ƒÂEá¢pÍ6Í6Í›¸vD!„ÀÅ7^Ü»fïš½k6”~PúAéPÒ§¤OI(¯Q^£¼”®+]WºJ_”¾(}%MKš–4ŸÎOçªÆªÆªÆPbRbRbºÑºÑºÑ›S/S/S/ƒ‚ü‚ü‚|P.T.T.³é’Þ+355…²Ø²Ø²X(®W\¯¸*:Tt´Ú m”U*«TV Jw”î(Ýb (‚rµrµr5”n-ÝZºðÁÍD3Ñ Š2Š2Š2 ð‹Â/ ¿ÍÍÍP+Ô µŠeŲb%%%@aRaRah§k§k§ÿ6¯*S•©Ê„‚'O ž@Y½²zeõ€Ílf3”Û”Û”Û@qJqJq ”l.Ù\² C C C@k¯µ×Úÿ¶ÝòåË7B¹¶\[®…*¦UL«˜‚l‘l‘lPjT«xYµ²jeÕ  ¬ ¬ T·T·T·~Û®®µ®µ®5/_<,FYŒ²ÆcŒÇ.r‘‹¿¿¤{~V*+••Ê`Ýüuó×͇ܒܒܘi2Ód¦ ØÚÛÚÛÚ¿úv$’×IñXñXñÔÕÕõæÏ+Ú\´¹h3ìY°gÁž×9¯s^gp?æ~Ìýœ~þùùç`8Ìp˜á0pŠuŠuŠƒÓ§ Nõ1ׯ\³—Ì^2{ ”Ô+©WR–å-Ë[–sWÏ]=wuÅâ>[3·fnͱ¦XS¬ …í Û¶ƒÁ™ƒ3gBí/jQû }ʛ˸̸̸ ®_¾ k¾\óåš/A8#œÎ@„ = òRä¥ÈKpîÇs?žû–*—*—*!x{ðöàíp±ëÅ®»ÂÊ¢•E+‹à’Å%‹KpÏþžý={0³7³7³‡æC›m>Ìæ™Í3›_ŸøúÄ×' CË-;´„üÜüÜü\pÒ8iœ4ðþñ÷¿rçäÎÉ;vìØ±cȼeÞ2o(ú¢è‹¢/`„ÿÿþ~7ünø]Ø×g_Ÿ}} ß¤~“úM‚;wïBuÖ£ÊG•*‡ÄQ‰£GÁnÃ݆» Áº—u/ë^\š\š\ º…º…º… //Ñ÷¢ïE߃6lØ€Ée“Ë&—AW_W_WÆN;iì$0{nöÜì9ìž´{ÒîI^7½nz]°¹osßæ>d—e—e—ÐJh%ü3 ¾ógJG•Ž*ßýý×ß ùyùyùy0­Ù´fÓšmÛ¶=ôR"ùcäéòty:h¾Ð|¡y¿¸,¶[l·Ø® ® ® ÐàLƒ3 Î@—¡]†v fáfáfáP¶°laÙBè¥ÿ•þW mö Û6„œ;9wrî€ò¡ò¡ò!Ô «V+ rkçÖέ å¥å¥å¥pÆåŒËH8p áLž3yÎä9`qÚâ´ÅiøIñ“â'é×£WfXÓ°¦aMÈMËMËMƒÞ ¼xè’Q%£J ZZµ´jiP½kõ®Õ»Â‹e/–½XŠDE¢"Üû¸÷qï)gSΦœ•N¥Sé`o½=ööÛ5¶kl×À>˜ðÁ¨¥©¥©¥ª%UKª–@qIqIq ´ÛÔnS»Mð~»÷۽ߎE‹8±§bOÅž‚ŸžøôħÑ8£qFc˜ÒkJ¯)½@öPöPöm=´õÐVpã8Æq øøøB§ÜN¹r¡ãÔŽS;N…ã#Ž8> ³ ³ ³`‹Ù³-f`°Ú`µÁj˜ØgbŸ‰} k·®ÝºvÙ²d?Tœºß:j먭£ÀîžÝ=»{ðé„O'|:¢ò¢ò¢òàú{×ß»þ„Î :N+N+N+àƒ ø`Œ 42¨bÙkq˜8Lü?f^|g €²€²€²øa÷»Ø =3zfô„©6Sm¦Ú@•ÚUjW©­ï”ÉŸc`e`e`ê/Ô_¨ßÀà a†0„}Â>aßK?o+´ÚB%ËJ–•,Áé¬ÓY§³`Öþ¬ýY –XbAø^ø^ø˜Ît¦ƒ&„ a ‹•ÅÊb!Î3Î3ÎRV¦¬LY GÝŽºuƒ”å)ËS–CqŸâ>Å}ô= o>í†[ ·‚B©P*”°êÇU?®ú6uÝÔuSW(P: t΂³à B±P,#ÁV+„‹òÈmå¶r[è4¬Ó°NÃàX±„c °Èe‘Ë"È”3(gABB¡ŠP+ÁJ°F #…‘}9ûröeˆk×8®1¤K9–r Ž <2:et‚bm±¶X L`@¨*Tª‚ì‘ì‘ì˜6l>T'U'U'AÝ_Ý_ÝbÖĬ‰Y^ݽº{½<%ó/‹Zbˆ!hkhkhkÀÓNO;=íñÆñÆñÆpl䱑ÇFBÉä’É%“+–Ž·ˆ·ˆ·€Jç*«tl"l"l"€‰Ld"ÐntT¨Pýþþyç U *P›7%nJ„”ð”ð”pøÜþsûÏíÁzºõtë鯼‰D/äåòry9hvivivé;Í+0Çs~ûØØ/Ëì¦BÊK?ÿeµ_Veûåõ_V[k@T¼ndidid ‰‰‰Ð¸Zãj«Á'Û>ÙöÉ6˜<#xFðÌ*ù}7¹ÉMð_å¿Ê,ÈZµ ‡‡?ìýaï{A˜)ÌfOx ˆ"ЍØè@‡ŠÕ{ïソ÷~øáô§8 º‘º‘º‘ðíøoÇ;Ôaê0uÝ„nB7z ½„^ ½«½«½ ÚõÚõÚõ`tÏèžÑ=0r7r7rÇcŽÇAã76ÞAãƒÆ‡)_MùjÊW ‹×ÅëâÁ f0àˆ#ŽüºŒ°°_Ø/ì¯è·bbb ¨}Õ¾jß—ÆE‡ЛÞô®è¿é2Óe¦Ë FíµkÔ†¦«›®nº—,.Y\=?êùQÏ@øHøHø4-4-4-€žô¤'«NÖj µ6´¡Íïïžw¦ÐžÒžÒž‚]ówÍß5bZÆ´Œi Ÿ›}nö¹ØÙÛÙÛI×ø%o8sssPTTÔwš¿Î¼y;óvp%áJÂxfýÌú™5–––@þÒü¥ùKA}V}V}  4¦Q¦Q¦QÝ#ºGtH“§ÉÓäPæQæQæQqÓX³ðfáÍ¡|iùÒò¥ý(ûQö#P|¯ø^ñ=˜Í0›a6Cߣðæ“Ëä2¹ ÊN–,; f7Ìn˜ÝÏ®ž]=»‚±¹±¹±9˜u7ënÖ´-´-´-àé¹§çžžƒìÙ³BÙó²çeÏ¡xgñÎâ°ÞþyûçA¹u¹u¹5x}çõ×w`QÉ¢’E%` jGµ£Ú’…d!Y€«^W½®zÓh§ÑN£Á}‹û÷-ÐlH³!͆@‘Q‘Q‘äzçþ?öî3.Šsÿûøg KïÒTŠX°#Fƒ{ï=ökb/±%±ÄKìF=±E,X£ÆŠ‚Tªˆ´¥Ãî^÷ƒCîsþ9'‰e™÷“äå3ß¹fa;s•ê™ÕÁ Ð Ð LË™–3-ê½ê½ê½PðEÁ_@n@n@n¨W©W©WAþ©üSù§ ärÉå’ËÐ( Q@£€²ccïÅÞ‹½iîiîiîPx¾ð|áy(ñ+ñ+ñƒ——HP$(Px´ðháQ0Œ3Œ3ŒÕ^Õ^Õ^¨y¼æñšÇ¡È¿È¿È.n»¸íâ6H8–p,áäßÌ¿™ríríríþËõyïWôÇ82ôÈÐ#CáböÅì‹Ù03jfÔÌ(pä2Èe¾CJ$¯Ç­·vÞÚ Zc­±Öü>ôûÐïÃWßïÛæXѱ¢cŲ?ùwòïäßë¬?°þ?rüÈñ#¨t¥Ò•JWÀ2Ð2Ð2\æ¹Ìs™Ï;>ïø¼#ÈkÊkÊk‚“¥“¥“%x¬òXå± êµ¬×²^K°¶²¶²¶‚˜ó1çcÎCŽOŽOŽXl¶Øl±,{[ö¶ì­ïÖøûʸ”q)ã:t̆˜ 1å]Ë»–w…n³ºÍê6 œ69mrÚVQVQVQ®MצkÁèK£/¾×X×X×XðZäµÈkˆZ¢–¨1³cfÇÌÕ÷ªïUßC_u_u_5÷5îkÜv?Øý`÷p¸ãpÇᤤ¤B‡= üòwÊßwCwCwC0ÿÖü[óoá‘í#ÛG¶{"÷Dî 044„<§<§<'°Þe½ËzT¬[±nźPèYèYè 666à½Î{÷:ø`ÉK>XŇŠ‚¤ÝI»“vƒj j j ¸7roäÞ< = = ¡Aå•T.{Dý$ïIÞ“<( * * ‚r.å\ʹ€{5÷jîÕÀµ·ko×Þe«.\8\ \ \ ÊúV¸-u[ê¶d­e­e­sÞüzCúuúÀé§1¨dPÉ !î=½÷ôÞS}§’HÞŒÍY›³6g ±ºduÉê}§‘üÓÝ1»cvÇLˆ1ÆcŒÇ ‘¿+Wþ®7ÜT×T×TW!šWm^µyU!¢vFíŒÚ©ïÖx÷¼·Â… {£öFí‚ÑõG×]ªºUu«ê¦ïtÉ›aàmàmà š)š)š÷`±Éß›ÜQî(w„-{ B#4Bóæw#îFÜ 0ªnTݨ:Ä,‹Y³ xÈCê»UÞï]°3agÂNøfú7Ó¿™= ÉûB»K»K» bRcRcR¡ÀºÀºÀ^tyÑåEx1鍓à¶ÏmŸÛ>`]ǺŽu°TX*,à¡ñÐxh@v[v[&Özkd/'Ðwÿåâõ‹×/^‡]wuÞÕ6\ØpaCp9ìrØå°¾ÓI$oWܸ!qC ÷ÀÞ{„yŠ Éû¢xañÂâ…0ÅŠÿøÞú{ëï­ùµÓŸZ£Ö¨5`ñÂâ…Å )ÿRþ% 04>ßôù¦Ï7éû,þyÞù;é½Ó{§÷†Ý‹v/Ú½zMî5¹×dp™î2Ýåo¼Ú™Dò*»8vqì^ /…—›†7 oúŸÛ½\SÅþKû/í¿„ê?Wÿ¹úÏúN/yß~fø™ágP3©fRÍ$øÆüóoÌAg¥³ÒY•mWH!…€é Ó¦7À¹ÿr©O€Þ¼³uÏtÏtÏ`Oñžâ=ÅPÞ·¼oy_h6¡Ù„fôN"Ñ/ÓΦM;CËî-»·ìF³fÍþýí[_o}½õu°km×Ú®õ?ŽDòg4Êi”Ó(<£<£<£~»*Ϫ<«ò üúûõ÷ëÿÇ÷/y½ÞÙàú¡ë‡®‚ˆM›"6Áàùƒçž*c•±ÊXßé$’wC¯&^M¼ üò7ÊßøÏ×-²-²-²¡…e Ë– ?(?(—žýKÞ/ / / ð{â÷ÄïÉïo×rRËI-'ý9ûsöçôúŸë+òÖç­Ï[{•{•{•Ðåj—«]®‚ÛL·™nÒòœÉÿÇm±Ûb·ÅÿŸ¯×ø©ÆO5~‚ÚvµíjÛýùýK$†²¼²¼²Ï}POQOQO¡ïpÉ[vƒÜ€Ò€Ò€Ò(xPð àw)îRÜJJJ ¤SI§’N Ù£Ù£Ù¥.¥.¥.àìì ÚkÚkÚkPâZâZâ "D>ˆö°‡= ðWø+üÁ šA5ƒj Z­Z­Z ªUŽ*Œºu5ê Æ:c±”^J/¥P›ÚÔÖw#IÞ6ííí(U8ªp-.Z\´J®”\)¹%ÝKº—t‡RãRãRc-EKÑÜ"Ü"Ü"Àº¶umëÚ`?Ý~ºýtxhôÐè¡èt º„²5[”½”½”½@µFµFµTÇTÇTÇÀpšá4Ãi`l`l`l†+ W®.q‰Kún¿/½qÇ}÷1ÜŒ»w3æ.œ»pîBP4R4R4Òw:‰äՈꢺ¨źb]±rúäôÉé‰!‰!‰!Ü6¹mr[H K K ƒôaéÃÒ‡Af~f~f>‚˜'æ‰y€:ÀSLêT§:ÈêÈêÈê€Á×_| ö‹ìÙ/‚}>û|öù€¸%n‰[@8á„S¶hP6Ùd5©IMà)Oy ²Ú²Ú²Ú`~Þü¼ùy°imÓÚ¦5Ø÷µïkßœœœÀ5Ü5Ü5\“\“\“ÀôŽéÓ;```ð›ýKÞ ýèG?(X2°d \/¸^p½l‰Äá‰Ã‡CêÊÔ•©+!mvÚì´ÙÙ*³Uf+P‡©ÃÔa 3Ôê >ô¡O<ñüú~Ä_|¡0¡0¡0ªR•ªÀµ”k)×R ¬NX°:ÀArÈ#<às>çs 2•© d ;ì°###°q·q·q‡rËu.×{9örì.w]îºÜ7™›ÌMVC¬†X £UF«ŒV|£|£|£¾/»Cïm¾aø†á vW»«ÝaZä´Èi‘¿™ÒT"y—QDäeæeæeÂcícíc-<ªþ¨ú£êicÒÆ¤ü‡ùó‚aeÃʆ•Áv¡íBÛ…àpÔá¨ÃQ°k`×À®888€Í|›ù6óÁ¨“Q'£N º§º§ºª`U°*”S•S•SA9W9W9 'N(œEW‹®]…r Ë5,×´‘ÚHm$ˆ‹â¢¸ÚXm¬6JÓJÓJÓ ä“’OJ>’j%ÕJªAáˆÂ…# ½$½$½žõ}Ö÷Y_xîñÜã¹6}lúXHï‘Þ#½˜˜˜I?“~&ýÀ®Ð®Ð®¼R¼R¼RÀ;Ù;Ù;<x4ðh–-[>pÀAßWïíÑ[ð"óEæ‹L˜^<½xz1L œ81jÜ«q¯Æ=}7ËûKý¹úsõ瑟‘Ÿ‘Î :/CCC}§{w 7á&Ü }Wú®ô]ðð»‡ß=ü®_¼~ñúExüôñÓÇOA6C6C6œ›87qn•ÛTnS¹MÙ7—/\¾pùì?·ÿÜþs0P¨ þŽË£žãç ¨oQߢ¾šœšœš Éw’ï$ß'yOòžäAÌ¥˜K1—àùÞç{ŸïU7U7U7¨Ü½r÷ÊÝÁÿ¾ÿ}ÿûàêê V¶V¶V¶ü:µ±äwL0ä^ͽš{+++àÆÝwoÜ…ûù÷óïçC~J~J~ ذ`;¼¶xmñÚ•2+eVÊ—ñ.ã]ƃÓ§#NGÀÔÏÔÏÔØÌf6ëû$ÿ<ÍÍÍxQú¢ôE)¤ÌN™2–$,IXÑÍ¢›E7ƒ¤EI‹’A©g©g©'”/-_Z¾üÎû÷;Õ'WŸ\}28Lq˜â0——ï᣽§ÖZwjœ+ôûÐï!lYز°e i i i•å•å•åP÷“ºŸÔýª6¨Ú j°ò³ò³òå.å.å.þ±}9DUQUT…Â>…} û@b½Äz‰õàÖŠ[+n­€ÛgnŸ¹}2b3b3b¡ÂÔ S+L…f÷šÝkvjo«½­ö60mjÚÔ´©¾ÏæÕ½õ@[W[W[Ì[0oÁ<¨9¿æüšó¡û­î·ºßÒwsèæKÍ—š/!ùVò­ä[àrßå¾Ë}PÞWÞWÞõý_S]S]SÁ†ÝvoØ _|üÅÇ_| Ê8eœ2ö}¼ïã}C‡vtØ®³\g¹Î‚áAÆA“NM:5é#ŒF0‚„ 7n€K'—N.@9J9J9Jß­ø×å-Ê[”·®˜_1¿b§'Ÿž|z2,/X^°êÞ©{§îh¼¸ñâÆ‹Á}¥ûJ÷•`¼Âx…ñ }§ÿú”Oùr›ä6Émî=º÷è\8uáÔ…Sp¯å½–÷Z‚Ë— . ýÚökÛ¯…:ñuâëăjªjªjª¾OâÍÑkµÆ5?j~Ô|8¹íä¶“Ûà‘É#“G&PiM¥5•Ö@ó-Í·4ßUݪºUu«@«@«@ Íh¦ï³øû)µ.µ.µ†Ä–‰-[ÂÃ+†W áZ»kí®µÙ Ù Ù h±¾Åúë¡IA“‚&`3Ñf¢ÍD}§ÿóÞzðòâ¬#³ŽÌ:3ëά;³.x”z”z”–mWª(U”* quâêÄÕ@A®µ®µ®5˜/4_h¾ì­í­í­!­BZ…´ Pú´ôiéSP ¦FL˜`ö™ÙgfŸë×®;þs»¢ÇE‹ÃÜÊs+Ï­ v[í¶Úm…Z½jõªÕ Â,Ã,Ã,aܘqcÆë®o¸¾öºîuÝë ®tºÒé Ø}c÷Ý7PkZ­iµ¦ÁwAß}ž <x.€äÉÉ““'C¹Är‰å¡{•îUºWÙ[go½œ|||¡5¨„-[¶Æ?düpŸà>Á}lHܸ!ðÃ?Èû  |dùÈò‘ðaƒ|Ø>Ö|¬ùXÍ›77CCCȨšQ5£*„U«Vb®Å\‹¹1ŸÇ|ó9GGGÖá[†oÚvÚvÚv°áîÂH›‘6#mÀ|~ÓŽ…õ ëÖ‡ä>É}’û@fÌ:™uàA¯½ôåYåYåY˜á:Ãu†+´Ý~tûÑ0hï ½ƒöòkï[±El[ übøÅð‹6'lN؈]»,vØ.³]f» ¾úíÐo‡‚¢®¢®¢.äÈrd92ðâ1ÄcÔ/W¿\ýr0.l\ظ0\¸&p ˜>2}dúš?lþ°ùCXÑaE‡ ßž~{úíÀnÝ_Còaʇ)¶çÛžo{;=v‚®©]S»¦B‹-6¶Ø&…&…&…oû·Còò΀#Ž8ý3úgôÏ€¶uÚÖi[~ þ1øÇ`Xî¾Ü}¹;|àþûî0`Ø€a†ù6ómæ£Î…Ï ž<‡c×]?vNN<9ñäDðwöwöw†ÅsÏY<[:¶tl DEÔ+Vò'™œ79oršÓœæ@#ÑH4píɵ'מÀþVû[ío+_¬|±2Œ0a8Â<z>ô|T¤"õ}ÿñ–mˆÙ³!FˆµK×.]»ôo?váØ…c ±&xMðšà²Ÿ1vÆØc…Xyyåå•—…ݺ?t¿mú´éÓ¦©#RG¤ŽB-SËÔ2!o\¼qñF!Ä,ˆYS¶Ÿøñ#âGÑÁ¡ƒC!b^ļˆy!ÄÇ]>îòq!Ö»¯w_ï^¶ý´±ÓÆN+ĪäUÉ«’…ˆ"BÑéD§N‘––&ĵA×]T¶ßäëÉד¯ Ñnv»Ùíf 4?h~Ð|! ­ ­ ­…8Þéx§ã„èúi×O»~*DáG…~$Dœkœkœ«í·_Ü~±wÞxw w†Þzg¨{òöäíÉB¥ÒFý~;ž :t*Hˆn»5îÖXˆüýùûó÷—½>|èð¡Ã‡ ±iƦ›füæßM†› 7â[×o]¿u"xIð’à%Bt¯Ù½f÷šB«‹ÕÅj!n˜ß0¿a.D—¡]†v*Dfvfvf¶—Ž_:~é¸útêÓ©)þ)þ)þB´>ÕúTëSBœÖÖÖ ¡nªnªn*Dþøüñùã…ˆvvv"»]v»ìv¯ð†.†‹áBÜȾ‘}#[ˆa®Ã\‡¹ ±Â|…ù s!ÒRÓRÓR…i"M¤½ßÉ+¹+BÄ®Ž]»Zˆ™>3}fú1É}’û$w!þõ Zß!ÿ·´/Ó¾LûRˆ9½çôžÓ[ˆñÕÇW_]ˆ;ï ¼3PíIíIíI}§”üQYNYNYNBlŽÚµ9Jˆü?òÿÈ_ˆ3çÏœ?s^ˆ ãÕwÊÿôöîÌe.s!Á.Á.ÁŒŒþÈ¢>/LJîg?ûV´¢X?²~dýžñü‹ç_ÛÙÎvPíRíRí³ŸÍ~6ûÌtf:3$·Jn•Ü ¼M½M½M/¼ðKKKÐ*µJ­²µÙÚl-È!Ä~±_ì/‹cµÌj™Õ2Hßœ¾9}3äDäDäD@RpRpR0¼uðÖÁ[?"Dþ(7§Üœrs@¶L¶L¶ ä#ä#ä#Àä²Ée“Ë`”i”i”Y6ŒFDŠH º]º]º]PÉ©’S%'¨º¡ê†ª èVЭ [P¹_å~•ûAåÈÊ‘•#AÞ@Þ@þßfÖúå„Ä`1X æ×ñÞ¿2à 3À<þ@á8FŒc@î"w‘»@VaVaV!$VH¬XŒ<0òÀHÈÙ•³+gØõ²ëe× XÇ:ÖâKÅ—Š/Átœé8Óq`kk[¶ï5Þk¼_Ãá¡GC†…íý¶÷ÛÞúŒì3²ÏHhÕ:«u(Ž Ç×ðþ–¼¿Œ/÷ðõðõð…¹6smæÚÀž{îK —.5„‰ê‰ê‰j¨fXͰš¡¾C—Iü"ñ‹Ä/`Y«e­–µ‚Š™3+f”îSºOé–=-{Zö|õãHÞ.«««¾aø†á šc5Çjް¥Ê–*[ª@·9æ|ÝÖt[Óm È'È'ÈßUmßÚTÀÙå³Ëg—‡Ï_<ñ<¯x^ñ¼ò~ð—_øŸ@=J=J= ¬7Xo°Þœà'øufÁ—·®_²žh=Ñz"äW˯–_­ìߋ֭+Z4¢Àt¥éJÓ• >Ÿ‰Ï@¶_¶_ö› wCî†Ü `-¬…µ#w#w#wpœï8ßq>tÚÙig§0~ÖøYãgÁÆ{lìVu¬êXÕ†2”¡@ ZÐâ7çùòÚGøkıH!…hÛ¬m³¶Í 4"4"4„?Õ2«eVËüí(ý(ûQö#¿>ëþÕ/½‚eßȾ‘}ó›¯E-j+YÉJ~í%/¼…·ðQCÔ5ÊfŒsjáÔ©tëÖ9 &ÚM´›hëG¯½~4X·8nqÄV±UlšÒ”¦¿‰9KÌ³Ê ±ÒV¥­J[ýù÷[øóðçáÏá»3ßùî ŒVVVA»Þíz·ë ЕЕЕÿ¥¹¢E´ˆ†ÂÝ…» wCQ—¢.E]€lä5L$¢ûD÷‰î(Š)Š)Š1JŒ£ ¤aIÃ’†;ÿvþmеӵӵû/û®®EQEQEQ žŠ§âéÏñ‡5  |Iø’ð%°·poáÞBÈ<‘y"ó'''î´î´î4”ƕƕÆAþ‚üù @³_³_³ÿÕcü»—S…Ý?tÿÐýЪY«f­šÁºªëª®« ‰×¯'^íñ'e=Ëz–õ Vy­òZå¾½}{ûö†qûhÜGüƒ_WWWWWò‹ó‹ó‹¡$³$³äüþÿA/G”Ô-©[RÄD1QL„Bu¡ºP … 6 0à¿ ÖTÑTÑT’ê%ÕKªW¸Âù{ÿ'‡‡‡ÂÙîg»ŸíÇçŸ|>”¨KÔ%j(ö*ö*ö±T,K¡xJñ”â)PàVàV຺º¯/ÏË>d 6<Úð(L}0õÁÔpúðéçÃù3çÏœ‡F³¼½ ;;;;›_;ÍY…X…XýÎ+b’˜$&A\j\j\*¯ ^¼2Úe´Ëh-í[Ú·´/›É*ëRÖ¥¬KV”V”VT¶ŸöÛ7nßÒ|Ò|Ò|àLè™Ð3¡p$ôHè‘P¨ß²~Ëú-¡Ri¥ÒJ¥ Qj”%Ä}÷QÜGp:ïtÞé<Èj›Õ6«-´ÜÛro˽àìì Þ—½/{_† þAýƒúí鷦ߚ©mRÛ¤¶ô¾é}ÓûBv³ìfÙÍ é|Òù¤óeù¬|­|­|!»OvŸì>p6õlêÙT(t.t.t†ºßÕý®îw`‘d‘d‘nSܦ¸M£vFíŒþË„h&š‰f41ibÒDx±èÅ¢‹ ñEâ‹Ä^-½Zz5ȘŸ1?c>$?J~”ü’û&÷Mî[ÖY2Ù/Ù/ÙT-U-U-!«vVí¬ÚpzËé-§·€›‘›‘›x¬ñX㱂<ƒ<ƒ<á–ú–ú–ž9|øÀ¼‰ó&Λé¡é¡é¡pûèí£·Âð¥Ã—_ ÷.Ý»tᅩ?¾ßá~‡û`Þ¤y“æM‚ÌÄÌÄÌÄWÏ÷ï¢ûD÷‰î{›ím¶·ì3Øg°’Ö$­IZŸy}æõ™ÄZÆZÆZÂÓVO[=mçœÿq>œÝqvÇÙ¯?×Kò>ò>ò>Ð-²[d·Hðëî×ݯ;ì²Ýe»ËŠ ‹ ‹õѧ㗂ÿÀŠ+¬—±.c]ÆÂ`»Ávƒí@å«òUùþñÝeÎ=æLœ3qÎDØ‘»#wÇk\,-H¤RÃÚfk›­mùC󇿅#Ž4:ÒÆM7mÜ4Ⱦ’}%û¿| />^|¼ÖnY»eíÐÔÔÔÔÔ|ýÍ{vÛÙmg·Áe×Ë®—]A¾L¾L¾ n6¿ÙüfsX¸eá–…[ kZÖ´¬iðóÏ?ÿüóÏ0lÀ°Ã”ÍŸð¦Tm^µyÕæ0ÆxŒñc8zñèÅ£á©ùSó§æoî¸Ô[{ ž§ž§žªïUß«¾Ã†= {ü´Æk %-i &æ&æ&æ0Ñ|¢ùDsðêëÕ׫/())Á¬àYÁ³‚Á(Ò(Ò(²l7õ[×o]¿5X·µnkÝ’‡'OµzÔêQ«T›Wm^µy`4Üh¸Ñp¹"Wäòko$SSS˜”1)cRxòä=dŸÈ>‘}3ªÏ¨>£:ܯ¿þýú ë¯ë¯ë¢›è&ºj»j»j;ÌVÍVÍVãeÇËŽ—AWCWCWj©q¤ÆX([([(mKmKmK ˜bŠÁ°ža=Ãz¨Tª¡á' ?iøÉÿn>Í*Í*Í*¨=²öÈÚ#Á¹šs5çj`xÜð¸áqÐÕÔÕÔÕ„±qcãÆÆqœqœqhNhNhNÀØÇc} ¦L˜oGoGoGXðdÁ“O@ç§óÓùƒÒAé „g4žÑî—»_î~9ÐÝÑÝÑÝñ¡øP|†¹†¹†¹0g朙sf‚s˜s˜s/á%¼ÀBg¡³ÐÁÐ>Cû í†W^a8P Tøßçûcê©?¦‚{#÷Fî Ð7Ð7ðOü}É Û Û œ®;]wº!“B&…LÝ÷ºïuß¿úïƒë<×y®ó wýÞõ{׫VV­¬ZA•§UžVy ™¶™¶™¶P0¤`HÁHl—Ø.±DýAô87pnà\pµuµuµ…Þ^½½z{ùróåæËù_=çK1þ1þ1þ±*cUÆ*è0§Ãœs€³œå,ô:Üëp¯Ãàt×é®Ó]0¯f^ͼ”š•š•šAæžÌ=™{^_žß#O–'Ë“¡×Ù^g{…Eb‘X$àêý«÷¯Þ‡¦u›ÖmZ÷Íçx)jpÔà¨Áð0ñaâÃD˜uiÖ¥Y—@UEUEUåÏïÏf„Í›`¨4T*áùØçcŸ¥ìè+ªëPס®x{z{z{‚YM³šf5Á³ŽgÏ:°óãïü´K´K´Kàæ…›n^ƒŸ ~2ø j¨u¢Ö ¨R7¤nT6«lVÙ ö´§ýëkßÇn»q Ì/™_2¿í[µoÕ¾¼Hz‘ô" L˜40i–“-'[N†*±Ub«ÄBÚ–´-i[ (º(º(š_ïp½)u;×í\·3ÜKº—t/ 7:Üèp#˜”2)eR ÈœeÎ2ç7wüßóÖ €‚ùó æƒ²²²²²2<6xlðø¿üÀ.v± 455Ás”ç(ÏQp-àZÀµÿÜÜ÷¨ïQߣ¿>1ø²Ÿe?Ë~.ûøëÁ¿5õË£í<í<í<(?»üìò³!`VÀ¬€Y¿×!Ê!Ê!ê¿Ì$ùË~ÛІ6ÿÇËF-ŒZµ€Æ4¦1 ‰×Äkâ!bhÄЈ¡PúséÏ¥?ƒUºUºU:ThZ¡i…¦”Í™ý; jÔ2¨uoÔ½Q÷Æo^˜ÉLfþ&ÿ¿çîD':;î¸Ld"¿çú2ç¯6° e½·_þ÷÷ÚÁ 'œšÐ„&À#ñT¨PþøãÏ—U>«|Vy¸t#èFŒí7¶ßØ~ ·—ÛËíÿÄŽþ¼³¼³¼3¤ÏJŸ•> NL91åÄÈËËËË˃:ª:ª:*0ò5ò5ò…ó¾ç}ÏûB»vì ÿ«ü¯ò¿‚ ¾|/øBÇÕWw\ Õ ªT‡[Q·¢nE㇎:~ …d+d+d+ ¿~ÿüþ°áð†ÃClilil)X(, 0;kvÖì,Üš{kî­¹`•a•a•áׯ…_ƒÒ’Ò’Ò0¿e~ËüVÙ0ÔŽöí;Úƒ½»½»½ûïŸ^H^H^„{†{†{£óÎ?:÷]Üwqxß÷¾ï}î<¾óøÎc0Þn¼Ýx;T «V5 dÍdÍdÍ@ÖFÖFÖ°Å[ˆôôô‡ˆ*U"ª€ò åÊ/ Yf=šõÇ«ŽW¯þõëfÖÒ¬¥YKh\¡q…Æ ¤RH¥JÐøÓÆŸ6þäíåíå¯ñƒè÷„L ™2j^ªy©æ%°7´7´}~m·õ}ê ÝÜ»¹ws‡'¾O|ŸøÂÓÊO+?­ ^Î^Î^Î ûJö•ì+Ÿ”Ÿ”Ÿ„¤¥IK“–ÂÒ K',Ï<žy<“Ù&³MfóÙÏf?› I½’z%õ³D³D³D^¼>x=8w8îp &L.˜ ÊéÊéÊéÐñnÇ»ï‚a[ö†mÿô“Û'·OnQùQùQù`ÜÁ¸ƒq/^>¼<(ý”~J?¸p+àV¸}êö©Û§ ›#›#›²ë²ë²ë ‹“ÅÉâ@‹` ¯]¼vñ<ÝñtÇÓ`Óɦ“M'h1¾ÅøãÁd€É“ý²fffÀÂ¥ —.\ É^É^É^àšïšïšÿæßÿî­=(6,6,6åååPÎTÎTÎüýíÓ;¦wLïå¾+÷]¹ïʾçç翹œé é é `÷Ýwv߯Cã¡ñõõõŽ·ÕZ Ü…»p‡ÐâÐâÐb6(l4qjâÔÄ •••_ý8ï‹Ô ©R+€ÖJk¥µ‚òËo,ÿžÕ¿ì«`æeæeæ5ª×¨^£:؅څڅ²šËj.« é Ó¦7„ïµßk¿×BB„: uÀr†å ËpðöÁÛoC°„a ÃÀüˆùó#°×j¯Õ^«²©Jåqò8y°–µ¬ã>Æ}ŒûS™ÊT°mgÛζT\UqUÅUeì{ëí­··¤N?œ~îL½3õÎT¸ñãoü¾Ç|ùƒ«?_ýùêÏpèÆ¡‡nüïó7íiÚÓ´'8Ç;Ç;ǃM›þ6ý¡rÏÊ=+÷„rË=,÷N(O(O(á¶ÿmÿÛÿGå&·‘ÛÈm álÂÙ„³ðuÎ×9_ç@ÅÛoW¼ Y¡Y¡Y¡°®ûºî뺃¶²¶²ö5¼¿k/¯½¼örH©–R-¥<Ïžÿü-ü¡-¨\P¹ 2Äuë×|?õýÔ÷Ó×·YMYMYM(·­Ü¶rÛ ®¬®¬® ²²²`uÉê’Õ%Ý<»yvsغ;uw*”4/i^Ò´»´»´»à» ßUø®”¶)mSÚJ®–\-¹ ;»ïì¾³;äÏÈŸ‘?d!²Yˆqbœ#-FZŒ„¢ÁEƒ‹CE³ŠfÍÀuë×5Pt¿è~Ñ}Ø‘º#uG*L2Ép|Éñ%Ç—@æÎÌ™;ÁÇßÇßÇvíܵs×NoÞ:¼õÿ>›i6Ól¦­ÖVk«-›¬ÂŽ ;*ì#c#c#cعcçŽ; íQÚ£´G ß*ß*ßZ¶Ÿ—wŒB:†t éß÷ý¾ï÷}¡ö‚Ú j/€Ð¸Ð¸Ð88bÄþÈ+|‘xÉq‰ãÇ%`»Èv‘í"¸wøÞá{‡_ë[ïOyk€ÖNk§µ¥Ò@ ò¶ò¶òÿRáÙ±;bw¾¬úeÕ/«ÂTÏ©žS=Áò¼åyËóü¸–ÝgvŸÙ}‹k-®µ¸LI˜’0%,--Þboq…Â@SÚOi?¥=Œ?~üøñàxÉñ’ã{8'õ«Jߘ¾1}#˜Æ›Æ›Æƒ‰»‰»‰û«ï÷å-î—•¿n¸ƒ<ñÄbbbÀHf$3’L.“Ëä`Ù˲—e/PuVuVuY®,W– j µ…Tþ*•?pŠSœ2É$8ÎqŽƒÊIå¤róJæ•Ì+ÒFi£» vì&€¥°– nÜ2¸2™¬l)ÓOM?5ý*\¨p¡ÂpKqKqKäÛÉ·“o—Í…~/ã^ƽ ¸«»«»«ƒGµÕzT d² YØö²íeÛ ÌW˜¯0_._»|íò5X\²¸dq Œ…±0 {${${ôŸÍ¨U„*Báþ¤û“îO‚gâ™x&À±Ø±Ø±lkÙÖ²­·ÜZpk¹¹½†ëgZ×´®i]P,Q,Q,»»»WßïÿRr¨äPÉ!(j]Ôº¨5XtµèjÑõ5à—éVÝ­º[u÷ZîµÜkAÏžµú×ê_«?¨Uª@xñÙ‹Ï^|¹›r7ån‚HûHûH{¸»íî¶»Û i{Òö¤í`Üĸ‰q°¬gYϲ”Ë.—].l½m½m½Á²ƒeË`gg÷›ÎÜ9äSÖŒ²Á²Á²ÁpiÄ¥—F€Aƒ ÀvŸí>Û}`tÍèšÑ5¸Yp³àfÁ«_6y y y °x`ñÀâd6ÏlžÙüÍ¿Ï[{ðò߯½¨ÿW¯Ð—½åß¶Œ`ī捻°¤°¤4­5­5­Á$Á$Á$xžü‰½þ(ù¯LMMËzý–î-Ý[º”(_íMþËè qFœg€ñŒg<(3•™ÊL-ÿZþ5h:h:h:€,\. Ù:Ù:Ù:~5ñÊäÈ‘å(G¹?°ý/}G¸Ë]îRöÌÅC AV_V_Vr,s,s,áPíCµՆ… ‚ãxÇñŽãaBð„à Á” ýåέiÍø¦ö’l¼l¼l<”4(iPÒr:ætÌé7ß<~ó8hzizizAÿaý‡õªªª¯ÞlZs­¹Ö´½µ½µ½ÁÐÕÐÕЕ7>U®¢¢¢(‚AŠ (ù¸äã’ùÏÑ?U.¹äþæ}ù ÕmÕmÕm·Åmq´3µ3µ3v´£e ]ã×þâ±ËcŒ)ë«õ{^Ž«~Á ^±Äò›a¿Øc}Ù#»ÇvíÛÁ¾ƒûî;b›Ø&¶Ÿ±Ÿ±Ÿ1¸uê:H#´²Oÿ,YYY(ü¡ð‡ÂàyÁó‚çpõÜÕsWÏAÅ›oV¼ îGܸºÐ….½¹D±(ÅPÜ¡¸Cq0 1 1 áOÿ>½.o¯x.{.{¥~¥~¥~ »§»§» ¼ÁN˜o]Öò¬åYËañþâýÅð¯ n`ŒÇ1`ÿåçsãsãsã!r^ä¼Èy`ÑÍ¢›E7¨Þµz×ê¯óÄ{ÆQã¨qÔ@IQIQId,ËX–± \wºîtÝù ;þåƒ÷×?´¿tNx\ø¸ðq!×)®S\ª-¬¶°ÚB8¼åð–Ã[ È£È£È„¹0æ œ…³p¡j¡æ×W´-EK‡ÅaqÄ'âñ ˆKâ’¸â”8%Nì¼ì¼ì<¼(xQðtž:O'ˆ©bª˜ Â^Ø û²áN/ÿ Šeb™XƯ`ÄP1T mž6O›å:”ëP®ÌN:;•_ïÈÊÊ–5ƒh#Úˆ6e£Å^ÎÃ@2Än±[ìÝeÝeÝeÉ"Y$ƒˆñ"tN:'TjT©Q¥FPº­t[é6èÒ­K·.Ý@Y ,P}éKßW¿lEEEîŸîŸî½*zUôzóïÇßóÖ UmUmUmÐÆiã´q } } }nnnúk€×-4?4?4âuñºxŒté<Ò +V4üSA*§(§(§À±ùÇæ›%á%á%á°ŠU¬Ò÷ɽÜ>wúÜéspûÈí#·àÆÐCo W\q}…ýV¸^áz…ëàâëâëâ » wî*„LU¦*S½ì{Ù÷²‡zÕû¨ÞGX?°~`}8p&àLd÷Íî›Ý,W[®¶\ éÑéÑéцM ›6…‡Ë.¸´Úm•7*oTbbb Æ±ÇjƒÝ#vØ=öÛ?nÿ8p©ìRÙ¥2­4Zi´Â&„M›Ï}Ÿû>÷e¾2_™É#’G$€\Ó\Ó\S tÒ!W“«ÉÕ€ùóæþóü‹lŠlŠlʆ-½5 j@Ô0¾k|×ø.ˆF¢‘h‰Y‰Y‰YpkÈ­!·†_ð_@bnbnb.N œ8 Z}Öê³VŸÁ&—M.›\À}©ûR÷¥P#»Fvl¨Õ½V÷ZÝAVOVOö ñ…øB|\\pqÔû¹ÞÏõ~“Z&µLj½ù÷£²·²·²74Ûhl£±pÅëŠ×/ܸ'p¨ú«ú«úÿõý×I¯“^'nÙÞ²½e [ý·úoõ‡´®i]Ӻ¨®£ºŽê •ÆV[i,T¯T½RõJ°oð¾ÁûƒyŒyŒy X=±zbõžœxrâÉ xxöáÙ‡gÁ0Ü0Ü0ÂcÂcÂcàÙžg{ží£<£<£<ˆ_¿"~|¨ùPó¡B†‡ ¶¶¶ò]Êw)ßá|Ãù†óá” S.Lá×ÎÄ/†¾úb(Ä.]»d‰²DY"dTɨ’Q´´´@q[q[qû?ÏÿYè³Ðg¡›—›—›º*º*º*ðäÚ“kO®AìúØõ±ëÁx·ñnãÝp/ô^è½P°±±“Y&³LfAL˘–1-¡£OGŸŽ>ðbý‹õ/ÖÃê뫯¯¾å{–ïY¾'øòä?*t¨Ð¡B‡¿~Ý„Ƈ33³7ÿ~ü]okÊÁð»áwÃï 1~ÄøãG‘;+wVî,}O„øú}uù«Ë_]bì¼±óÆÎ¢àQÁ£‚GBˆþ¢¿è/DáñÂã…Ç…Èž3˜ôÁ¤Êþ½ô|éùÒóB¨k¨k¨k‘W/¯^^=!t:CÙvÚ0m˜6LˆÜª¹Us« ‘7 o@Þ!tStStSôÝJoNÔ¬¨YQ³„ï6Þm¼› ½z'ôþëûӭЭЭ¢àXÁ±‚cBäÜ̹™sSˆÜ‘¹#sG ¡½ª½ª½Z¶}é¦ÒM¥›„ȹ”s)ç’ù5òkä×"73737Sˆ¢EE‹Š Q4¬hXÑ0!ÔWÔWÔW„ÈÍÍ¢HV$+’ ¡ÎRg©³„(¸Up«à–Z/­—ÖKõõõ!rÏæžÍ=û›ícÔ1ê!òÖå­Ë['Dî”Ü)¹S„ÈÛ“·'o¥;Jw”î({ä]λœwYm¶6[›ý_΀n€n€ùæùæùæB¨×©×©× Qܰ¸aqC!JìKìKì…ÈuËuËu+Ûï¿&Ø"wTî¨ÜQBä×ϯŸ__]{]{]{!41šMŒ9wsîæÜBÝPÝPÝPˆ¢Œ¢Œ¢ !þ5#æ_¿n×÷\ßs}Ä1A‘ŸŸÿ–ߌBˆ¼ayÃò† 1cÜŒq3Æ qjÅ©§V¼ú~5©šTMªy1y1y1Bä É’3Dˆü”ü”ü!D;ÑNüf í¢öEí‹Ú ‘“™“™“)DþôüéùӅȳʳʳ¢Ä¸Ä¸ÄXˆ‚îÝ º ¡>§>§>'DáÌ™…3…øWo}!Ô±êXu¬ÅTü‘¥—~\ú±ÙÁÙÁÙÁe?_У GA!ÔÕՅȋʋʋB­ÎVg Q^^.DÉý’û%÷…È5Ë5Ë5¢PU¨*T !ºŠ®¢ë9ÿÖšÖšÖBävÊí”ÛIˆÜɹ“s' QêQêQê!Da\a\aœêÃêÃêÃB +V0LˆÂÕ…« W ¡ŽPG¨#„(œW8¯pžb»Ø.¶ Qü øAñ!²ó²ó²ó„Èý(÷£Ü„(V:¬tØ_¿^s2ædÌâÓíŸnÿt»¡³Bg…¾Ÿo­ˆ&šh„U8ªpT¡Ó2¦eLÓ÷é¿>i¶i¶i¶B ¹7äÞ{Bü«Ž§/Ÿ¾|ú²ÆÆÆB¬µrÔÊQB¬¶jتaBL2yÈä!B\éx¥ã•ŽeûûµÈ™”3)Gˆ‚ ±ºùêæ«› ±8pqàâ@!oZ¼iñ&!âìãìãì…Ðøj|5¾BìÙºgëž­B,öZìµØKˆù‡æšHˆÓÕOW?]]qPõÝjoÀ1D âÛ-ßnùv‹Ó¢§EO‹"c@Æ€Œú'yÓb£c£c£…]ytåÑ•…8åü•óWôJˆˆví"Ú 1lÁ°Ãîîî£ïT’7­ \A¹‚rB|!ûBö…LˆÝVt[ÑMˆ’oK¾-ùVßéÞb:$uHê!†UVeX!’ÔIê$µ¾Oÿõ[eºÊt•©jL¨1¡†º(]”.JˆÒy¥óJç V¶ýâé‹§/ž.Äô^Ó{MïUöï/ €O|>ñùÄGˆ§§'!>ðÁ€ñSÂO ?%‘ôCÒI?¡¶P[¨-„ˆÜ¹!rƒÝ ºt7"¥0¥0¥PˆÐ¡C ÑË«—W//!Ô=Ô=Ô=ôÝZoN¡A¡A¡_•ÿªüWå…˜VeZ•iU„HŠLŠLz…o–’wÌqq\â^À½€{BŒh=¢õˆÖBìÞ¼;XÑEt]ôRQ*JE©§ãNÇŽbÐ…A]âç.?wùù]È'y­²¿Îþ:ûk!- Z$Ĭ泚Ïj.DV\V\Vœ¾Ó•ykí’­’­’ÁÈÖÈÖÈÒÓÓÞÇEX^ö®ýe”ƒ¬š¬š¬”jKµ¥ZÈLÉLÉLïC¾ù>î}¸÷á^(^_¼¾xýîî_8ÀFa£°Q@Ã1 Ç4_îürç—;aÿäý“÷OÍ"Í"Í"H»‘v#í$^H¼xBN„œ9·nÝ6‚By¡¼Pš4?h~Ðwc½9F%F%F%0Öf¬ÍXpvqvqvµÔ^PÂv‡íÛ b­X+Öê;­äÏÒ<Õ<Õ<…“óOÎ?9,XË—.ƒ>gûœís8ÂŽè;-¿Giýeë/[ “& L‚oF3ú›Ñ°/|_ø¾pø×-w}‡•üi;ØÁxèõÐë¡ÌýxîÇs?Ý:Ý:Ý:˜:5tj(XU²ªdUéUöú¼µN€FÁFÁFÁà`à`à`ñAñAñA¿v:}ü2,F6\6\6œ_{¹žH:‘t" ‚F  s.Ϲ<ç2ÜYygå•ÿSþOù?ÝèF7À#Œ@ì{Å^0J2J2J‚iݦu›Ö ž4~ÒøIcX0dÁCÀ`‰Áƒ%PGWGWGVÑVÑVÑPí†[ 70»gvÏìt+ìVØ­,?°üÀò}7Ö›gaacŒy0æœr:åtÊ Öú¯õ_ëþ]ý»úw…nÚnÚnZpT8*ß§a)ï‹_¦j¯_7¾.ìMØ›°7‚‚‚`Læ˜Ì1™Ð ²AdƒH%ÿJþ•¾Cÿ¶²•­e£íSíSíSaóÍÍ77ß„ˆ&M"šÀ€v ؾC}‡útèÐé;¼äßeOÏžž=އ= g‡žzv(´8Úâh‹£ÐKÙKÙK ÆZc­±VßiÿÓÛ[øå”?Pþ$œJ8•p ½|Ý^{QQQì´ì´ì´²‰@ò&çMΛ ÿêlS6Á„â™â™â$$$CQ\Q\QäžÎ={òä5ÈkO—>]út)œ9pæÀ™ÐêT«S­N§‰§‰§ (z*z*zB¥é•¦WšNQNQNQ HP$(À·À·À·,®X\±¸òhy´>øø Ü5¹kr×âžÄ=‰{Å{‹÷ï…Š… +‚ß¿3~g ¶Sm§ÚN`]ɺ’õ;ÔYê]“×"¯E^ ¸;é“àºúºúºbT1ª(Ž)Ž)ŽAÅJ+U¬¾æ¾æ¾æàyÕóªçU°Yk³Öf-X|eñ•ÅW _-_-_­ï³z.r‘‹P´£hGÑȪ—U/«¤Z¤Z¤Z@dxdxd8D_Œ¾}Ò»¤wIïR6scÝ)u§Ô~ƒüù ···…ÊBe¡ú>¹×ç­/íܲsËÎ-’’“÷MÞ7yŸ¾›C"ùc^αžÕ4«iVS87ôÜÐsCae½•õVÖ׎®];‚}¤}¤}$´5hkÐ\]]]]]ÁÕÊÕÊÕ œk;×v® ®«]W»®»-v[ì¶€ê–ê–ê(›+›+›ƒb–b–b(F(F(Fw¸Ã×p"¿L±*¢E´ˆÝ0Ý0Ý0Ð4Ö4Ö4MŠ&E“E]‹ºu…gGžyv’Ï%ŸK>)Q)Q)QØ1±cbGH]™º2ueÙÜû– K…¥¼;zwôîÕ½ª{U÷Ÿ(Ÿ(Ÿ(°øÔâS‹OAî+÷•û¾úéüS‰(%¢ Ï$Ï$Ïä×Õµ‰4‰4‰4‡AƒAæðÌá™ÃAž*O•§‚ýXû±öcÁí¼Ûy·óà4ßi¾Ó|péçÒÏ¥8×s®ç\Œ2>J;¥Ò”ϔϔÏ@¢Q„€lšlšleëy¿ªÉLf2èÎèÎè΀f·f·f7h²4Y𬲵>2/f^̼I“'=†”Î)S:CòÕä«ÉW!áQ£„GPpºàtÁi0Üf¸ÍpTÔUÔUÔAµgÕžU{¾|ø>{/{/{/PF)£”Qú¾ªožÞ €;#3¶¶ÚÚjk+XâºÄu‰+˜60m`Ú@ßÍ"‘ü1ÖÖÖ°)|Sø¦p¨ä\ɹ’3 \>pùÀå ]¯]¯]©­R[¥¶‚h]´.Zəəəð|ÛómÏ·zŒzŒz h?Ö~¬ýŒ<Œ<Œ<ÀÄÀÄÀÄŒ4:†} ûösss0«lVÙ¬2ùùù‚ÂEá¢pÃ}†û ÷n•n•n”X–X–X‚ÆNc§±ƒâÖÅ­‹[ÿfJ+ûFY²®d]É:(\8¸ppYçÔ’ %J&€Aƒ>}ÀÊÇÊÇÊì¯Ø_±¿î'ÝOºŸ¯Æ^½ƒÝ@»vÁv·ínÛÝ Z¡Z¡Z¡ï«õÏ¥1Õ˜jL!smæÚ̵ðâð‹Ã/Cì´Øi±ÓàI«'­ž´‚´eiËÒ–Af‡Ì™ ¤sIç’Î`ðÁ7߀ÉI““&'Á¸Ä¸Ä¸ 7n0ܦN¦N¦N`žjžjž F±F±F±`0Ò`¤ÁHPE¨"T HS¤)Ò ¸mqÛâ¶e‹@[[[@þóüçùÏ!÷aîÃ܇PdXdXdE_}QôÎ)œS8 s s sA–)Ë”e‚Ù:³ufëÀ~¤ýHû‘àlàlàlÞxã 8pà<lÛ>¶} f×Í®›]ç×á{ÿTz+Š,‹,‹,aFÇgt„þû?ìÿüÂüÂüÂôÝ,Éÿ­dVɬ’YÔ5¨kPW8,‹ÃºÎï:¿ë|èÕ)ªS$$$üïý‰ùb¾˜ÿšÚ2µ™ÚL-äTÉ©’SrLrLrL ïEÞ‹¼Pж mA[È]—».wäÉ;“wŠÌŠÌŠÌ@g¯³×ÙC±w±w±7Ⱦ–}-ûT ªU(Rþ¤ü ŒÎ1:æÎæÎæÎ`¶Ûl·Ùn0Ùa²Ãd˜™™å Ë–7ÀÒÆÒÆÒloÚÞ´½ &-MZš´6±‰Mú¾*’׿ 9E?ýXô#d,ÊX”±rå Ê9n9n9n ^¬^¬^ ŽŽŽW’W’Wy#óFæ„«…W ¯‚ö¡ö¡ö!D÷îÝböÅì‹Ù­´>Ðú¨t*J†™†™†™`šgšgšæýÌû™÷Óê¦ÕM«ƒé.Ó]¦»Àršå4ËieØ­G[¶ –-[>ù ù ù }7âß‡Þ €—¶šm5ÛjÅŠ?‚>vúØIßÍ"‘üÿ2§gNÏœ›¯m¾¶ùÄ;Ä;Ä;ÀØø±ñcã¡VX­°ZïBáúË*qÔ¦6µ&4¡ e«üý²°Dò6]´¼hyÑÎŒ?3þÌxX´ hA(#”Ê}§ûçzk3þžTlP:?t~è Ù‡²eÒw*‰ä_î÷¼ßó~Oø,골Ϣ 8¬8¬8 4^ÐxAãwèƒÿ¥—ãà‹)¦8ÃÎ }ðKôë—å~™Â¦ ïP½Þ¼+xWããÆÇÃí;·ïÜ~›$’¿@ë®u׺ÃIï“Þ'½aIÌ’˜%1Ðàhƒ£ ŽÂŒ~3úÍèNãœÆ9ÓwZ‰äo¢”RJ<òÈÓwÉKz/TÇUÇUÇáà nøpœ¯q¾Æù i¦i¦i¦ït’ µ½Ú^mk£×F¯†ïݾwûÞ Æ&M›ýÕýÕýÕ`¸Åp‹á}§•H$’W§÷ॆ .l¸2Š ›}6(¡„}§“¼/^ŽO?ûüíó·aþ£ùæ?‚jŽÕ«9ÂÜNs;Íí®>®>®>úN+‘H$oÎ;S¼¸5pkàVˆéÓ9¦3$}šôiÒ§úN%ù»+Ø[°·`/li¹¥å––°+{Wö®l¦¦¦†!û†ì²LBLBLBôV"‘HÞ¼w®pïçÞϽx^ð¼ày‚·o ÞªïT’¿«DÏDÏDOX˜¿0a><²{d÷Èæ­˜·bÞ hêÜÔ¹©3ÈUr•üuÌ`&‘H$ï\Ànv³ÚŸi¦ý¸VñZÅk!éIÒ“¤'ú'yçýÒÛøFíµoÔ†ùæw˜ßœ¼œ¼œ¼`þÄùçO„JA•‚*é;¬D"‘èRß~ÏTŸ©>SÁûCï½?„ã1ÇcŽÇÀ˜ c*Œ© ït’wMÉ ’A%ƒàhç£v†cãŽ;6úú÷õïëmk·­Ý¶6(J¥ŠR}§•H$ý{÷îüB¦”)eJèâ×ů‹„>žÜ}r÷É]}§“¼+2K2K2K`eÎÊœ•9pþÅùç_Àt£éFÓ CõÕ;T—>ø%‰äß½³w^òÌòÌòÌ_µ¯ÚW Ç–[vlL,?±üÄòÀb³Xß)%oÍT¦2¢££aÝ…uÖ]€rŸ—û¼Üç°Ðj¡ÕB+p¨éPÓ¡¦¾ÃJ$É»ë½ð’ÌIæ$s‚.á]»„ÃÅwßY ‘ޑޑŽúN'y[t×u×u×á¬ËY—³.°è“EŸ,úê=¬÷°ÞC˜qwÆÝw¥~‰D"ù£Þùà%wwwhѸEãaoøÞð½áPœ\œ\œ¬ït’7¥À§À§À¶5ÙÖd[Øc³Çf Œœ?rþÈù0°ÅÀ[€áxÃñ†ãõV"‘Hþ>ÞùGÿ®Cz‡ôépµùÕæW›Ã…µÖ^X m–´YÒf‰¾ÓI^—de²2Y ëo®¿¹þ&:::¼¦óšÎk £+FWŒÖwJ‰D"ùûúÛÜxÉ2Ï2Ï2zžìy²çI8Üýp÷ÃÝáÅ®»^ìÒw:É« O O Oƒ¹‘s#çFB9ûröåìaþ—ó¿œÿ¥ôÁ/‘H$¯Ëß®x©¡CC‡†àzÔõ¨ëQØŸ»?w.°mlÓw:ÉUš\š\š ?DÿýC4¬Þ¾zûêíÐ9²sdçH˜à1Ác‚X®µ\k¹Vßi%‰äýñ·- Ö¬5X ƒüÓàŸà–Ë-—[.p½ñõÆ×ë;äÉÊÉÊÉÊÕíV·[ÝÎ,<³ðÌBø¤î'u?© {uîÕ¹(‹”EÊ"}§•H$’÷Ïß¶xÉí’Û%·KÐùçÎ?wþv}»ëÛ]ßBN…œ 9ôNòïâ¢â¢â¢`~üüøùñ öP{¨=`Q›EmµÚ­j·ªÝJß)%‰äý÷·/^jÝ­u·ÖÝÀfÍ:›u°ßf¿Í~cÄ1Fßéþ¹Äz±^¬‡K-.µ¸ÔF/Œ^ ¾¾¾0Ë~–ý,{pè0Ða ¾ÓJ$’7¢)Mi ²%²%²%€è;”D&~¡ï ¯KÜå¸Ëq—aᣅ>‚1SÇL3¼hð¢Á }§ûç(:Rt¤èÚ}h÷¡Ýpzïé½§÷ ”A)ƒR ™M3›f6 °TX*,õV"‘¼¥Á¥Á¥ÁQ-£ZF5?‘?‘?Ë·/ß¾|.6½ØôbS˜¢›¢›¢ÅÅÅ0[h¶Ðl!XD[D[DÎ8ã¬ï³yÿ½wÀK'U'U'UptÀÑG”ÝbvèåÐË¡—¾Ó½¿2ÎfœÍ8 ߸}ãö¤vIí’Ú&¤NH >Ù>Ù>ÙúN)‘HÞ„´Ùi³ÓfÃxÿñþãý!®J\•¸*PP¯ ^A=Èù"狜/À%Û%Û%tëuëuëajÈÔ©!ЧJŸ*}ªèû,þ9Þ›Gÿ®Õ­~lõ#xÔõ¨ëQ¶¯Þ¾zûjÐLÑLÑLÑwº÷OôêèÕÑ«a^§yæu æÎœ(}ðK$ÿå²Êe•Ëc c c ¸å}Ëû–7R|¤øH†{ ÷îÕwZ‰D¢ukÕ­U·Tö­ì[Ù÷?_WnRnRn‚æÍ#šG€y¢y¢y¢¾Sÿó¼÷ÀK~Ÿû}î÷9tèÕ¡W‡^°¡â†Š*Búžô=é{ôîÝ—î‘î‘îKK—–.-…Û[no¹½>ûÙØÏÆBÓòMË7-²ÏdŸÉ>ÓwZ‰D¢OnÕܪ¹UƒÆ3Ïh<ã?_·7±7±7À'Oè;í?×?¦ ˆ ‚ [t·ènÑP~Xùaå‡Á¦]›vmÚÅŠ?ÒwÈwϽ½÷öÞÛ sMæšÌ5U¶*[• j-¨µ xUòªäU 0ÄC}§•H$ïùSùSùShÕµU×V]Á²£eGËŽe¯øôç>…Šöí+Úë;í?×{; àÉeÈ2d0÷ë¹_Ïý–4,iXý‹û÷/ÙlÙlÙl}§|ût§t§t§àÜgç>;÷ì<¼óðÎÃÐ>±}bûDè1¶ÇØcA¡ŠPEè;­D"y—¥ßN¿~ÚýÔî§v?A„g„g„'lœ·qÞÆy0,lXذ0}§üçúÛ­øºØ [a+`üüñóÇχÅO?Yüœ9r>Íg7ŸÝüTì)ØS°vOß=}÷t¸|5øj0Œ0vÀØÐÈ©‘S#' ‚"ôV"ùg*\^¸¼p9dµËj—ÕDÑF´¬±ÆZßé~£ÝèÚGÚGÚGPç§:?Õù R?Hý õ¨8±âÄŠ!¥0¥0¥„¿ðþ€ 2}‡4hÐÏyÎs0J5J5J•ÊF2L'{úýcïü»ŸFý4ê§Q°­â¶ŠÛ*´ÚÓjO« ÕZWk]­µ¾Ó½9©•R+¥V‚o ¿1üÆòŒóŒóŒaüˆñ#Æ€Jc*©$ͤ(‘¼‚ƒƒa›Ë6—m.`¥±ÒXi@4ÍD3}§û_>Èå#å#å#!qâþÄýÔ;©wRoðké×Ò¯%ÈËËù䓯ïпQ—ºÔ…’>%}Jú€}Š}Š} Ì_7Ýüu`5ÈjÕ }‡|uRðoöUÝWu_UÍ Í Í„ùËæ/›¿ œ>rúÈé#}§{ H î~p÷ƒ»À:Ÿu>ë|Àk„ׯ0²ÁÈ#€eË –ôV"‘üÖæ”Í)›S ý|úùôó0áᄇBiõÒê¥Õõî?ÉÎÉÎÉÎAîéÜÓ¹§Aí©öT{‚Ó*§UN«@öHöHöСãúF-«#«#«)ûRö¥ìƒÅ7ZÜVXy`å°ßj¿Õ~«¾S¾ºì#€ßÓ}T÷QÝGAÊÉ”“)'a•r•r•æÌ ˜—,.Y\ÒwÊ?O©‰ÔDBp·ànÁÝ`諒—ö^‚.¹]r»äBçÐΡCAUAUAUAßi%ÉÿEÖGÖGÖLƘŒ1æ_˜aþ…¾Sý}éKßÿò„¢u¨£ï¿¯p_á¾Â} ˆTD*"V´â=Z¬ìŸ3 àRMTMTM„Ñ¡£CG‡‚¡·¡·¡7¬ËZ—µ. ŠjÕ(ª¡ï”\^h^h^(l:¹é䦓pÈïß!?˜Øhb£‰ ‡cÇŽeç-‘H$’©ø¦Å¦Å¦Å0éÇI?Núžïy¾çùؾ}ûöíÛAÛPÛPÛð?N³_³_³tßé¾Ó}§¿üÉñÉñÉñ°°ÉÂ& ›À“ÛOn?¹ ó;Ïï<¿3ÔO­ŸZ?d2™ƒþrJ$‰D?¤à°]h»Ðv!LÖNÖNÖBÄöˆíÛa¿|¿|¿„³pÎ:+uVê,˜g:Ïtž)DUˆªUáõåÈËÌËÌ˄؎±c;òëòšÿ.\®WÀ¼ó^Ì{.U]ªºT…¹s æ€[o·Þn½õݪ‰D"Ñ7©øƒÜë¸×q¯“U“U“Up^}^}^ ;Âv„íƒY³ fÀ’3KÎ,9ûŠ÷ï+qDG^áÀg9ËYر'bO 4,<xºªºªºªp$äHÈ‘X½sõÎÕ;¡Ã½÷:܃qÝÇu×,¾³øÎBw$$‰Dòn‘:þIUVWY]e5ôë߯¿þ0bÀˆ#@‚U‚U‚èŽèŽèŽÀÑíG·ÝE}õQT¡ e•Ë;?Üùáΰjܪq«ÆA4ÑD ’$/H†ºñuãëÆÃƒrÊ=(“£&GMŽ‚:]ët­Ó†è»Õ$‰Dò®‘ €?)µVj­ÔZ°O»O»O ɺd]²tttʶ‹þ1úÇèáPÌ¡˜C10»ÕìV³[ýfØËÿ»9wsîfX¾~ùúåë!Ú Ú Ú ìõC¡‡B…‹¹/澘 [3·fnÍ„ *L¨0Aß­$‘H$’wôàÒ”Ó”Ó”ƒ­.[]¶ºÀžÏ÷|¾çs(½_z¿ôþn/E „ý“÷OÞ?â«ÅW‹¯ö¿#6‰Mbì•í•í•Áᇇ~øäy¬y¬y F>ù`$ܯx¿âýŠún%‰D"‘ü]HÀ¤<¥<¥<ý¦õ›Öo,˜²`Ê‚)Pëv­Ûµnƒ²Ÿ²Ÿ²à„Ne?]7ºnt]øÁùçœÿ÷q"®G\¸«ìWÙ¯²‡ßßßßß>¥CJ‡”°Äm‰Û7HZœ´8i±¾[K"‘¼Ë´•´•´•à6·¹ l-ØZ°µ^x¿ð~á ‰mÛ$¶£ŽG:B‘c‘c‘£¾Sÿqâ¬8+ÎBìϱ?Çþ [“·&oM†Ø5±kb×è;Ý»C*þ(?üð&M<šÀ´øiñÓâáÈ´#ÓŽLƒ¯ž|õä«'àŸæŸæŸ……… Ù­Ù­Ù J”(…'ñOâŸÄÿçîsäÈ9_5ýªéWM!ºKt—è.¿ÙÀwÜÁæšÍ5›kÐHÛHÛH SÛLm3µ Ìm6·ÙÜf`ó±ÍÇ6ë»±$É»LÑUÑUÑÌ›6 ße}—õ]¤L˜:ò£ó£ó£á±ö±ö±4Ã5Ã5Ãõú“%Êe‰`ooG§~t:Üw¿ï~ß]ßéÞR€¿H¦•ieZ¨@*“MZ4iô ìØ3‚rƒrƒraWæ®Ì]™p·ÜÝrwËÁžÇ{ïy 'œ8p"ÈzÊzÊzÂÁàƒÁƒáÇøãŒÇ*ŽU«€ÏŸ->[ e£–Z6‚¶°ýƒíà›ê›ê› å”[Pn¾[C"‘ü¨W«W«WCFqFqF1¨}Ô>jeɲdY „ƒp—d—d—dèÚ²kË®-A©ŠTE‚ÎFg£³”€”€”(ú²èË¢/Á¦­M[›¶`³Éf“Í&~]D'3(3(3²ÏeŸË>º5º5º5à0×a®Ã\0bþÄü 9ùääðî3Üg8X˜X˜X˜@Ï>ž}<áA¥•T‚}“öMÚ7 ¼"¼"¼" åVÊ­”[PÙ¢²Ee èNwº»÷íÞ·{˜_7¿n~î4¿ÓüNsÈÈȆJ¢’¨$`Ú·Ó¾ö-tJì”Ø) à à áKR—¤.I°Ûd·ÉnÙÉìdvP¾¤|IùPWWÙzÙzÙz}_w‡T¼)¿,'i=ö@çt߸~ãú+Ä/_¿8Æ1Ž£«£«£+Œrå:ʬ¿³þÎú;`Ó˜¦ï“‘H$gǯ¿rü d]̺˜u´YÐfAÈÚ™µ3k'쫳¯Î¾: ³YÈ,À£šG5j "D„ˆ]w]w]w¸¾ùúæë›!{öþìýйSçN;Q=£zFõ@+‹•ÅÂÎØ±;c¡ü€òÊ€ÁîƒÝ»ÃóóÏÏ??C3†f -Ë×9»svçlð8çqÎãl Ú´%.X_°¾` W4^Ñxˆú¢¾¨~lôc£¡êªwªÞËc.¹<nn¼¹ñæFØ:ëü­óÁ¬§YO³žð½ï÷¾ßû‚N¡Sèú¾ï©À[¢ì¦ì¦ì&L&˜üÃôL{˜ö0íÊpe¸2\ßi%ÉûäéÇO?~ú18¤9¤9¤â”â”âˆÕbµXýüÀËÕù<ðÀt‘ºH]$t{ÔíQ·G {¬{¬{ ãÖŒ[3n =zôJ»–v-í ‰‰‰àúƒë®?”íÖ~¨ýPû¡PeR•IU&ANßœ¾9}áZܵ¸kq°åô–Ó[NÃÏ?{üìºiºiºi f‰Yb(((€iwÓî¦ÝÁl€Ù³¶3mgÚN0ogÞμ˜'˜'˜'Ÿó9Ÿë»õß]Rð–”ëV®[¹nЫ_¯~½úgÏžÀû’÷%ïK8.p\à80/1/1/ÑwZ‰Dò>1ílÚÙ´3äËòeù²ß¼ @d#d#d#@ÖUÖUÖÈ%—\`"™ô¤'=Ái¡ÓB§…ðMÖ7YßdAmm-|sè›Cß‚´‚´‚´°j5Ôj(dÅeÅeÅý~®óKÏ/=¿´¬ïSÏôžé=Ó¡þÝúwëß®r•«€9æ˜øâËoFG™ššB±g±g±'h‡i‡i‡†b4§9Í)Laо¯Æ»C*Þ2]]]ø´ç§=?í k»¯í¾¶;Ä-[·2údôÉè£ï”‰ä}Ø+°W`/x^ëy­çµ È È È"U‘ªHäÝÌ»™wž{=÷zî S¦$Lµ¿Ú_í)ÚmŠŽ/:¾èø"8õìÔ³SÏ pzáôÂéPÅ¿Š0w7w7w‡®Çºëz Â’Â’Â’àT‹S-Nµ€›#nޏ9^ô}Ñ÷E_0ýÐôCÓ¡ôQé£ÒGðàÒƒK.AÆÍŒ›7!7?7?7ž< xêGêGêG\>¹|rù²óó›â7Åo ëŒuÆ:8xèࡃ‡ |Iø’ð% .R©‹ ccÆÆŒú¾ï©À[R2¤dHÉHˆIˆIˆ^›zmêµ ~Óð›†ßÀO«~ZõÓ*8zðèÁ£aæïЉä½àWÓ¯¦_M0b2Äd¤vJí”Ú L›.6] óÒç¥ÏK‡òOË?-ÿD(0wÀÜs€Ë*—U.« ÒµJ×*]ƒÇ9sç€ÌWæ+ó…ù…ó ç‚u¢u¢u"^ ¼x\|]|]|!ezÊô”éPšSšSš¥GJ”ƪƪÆ*0.5.5.…Ò“¥'KOB`ÏÀž=¡ñµÆ×_‹‹‹øÌé3§ÏœÀõë×À.p*l®°¹Âf˜õÁ¬f}±þ±þ±þ 3Õ™êLaꆩ¦n§H§H§HЭҭҭùdùdùd}_=’·"1'1'1Gˆ¡ ý`èB¤I’:¤ìõÈÐÈÐÈP!®¸vàZ!âââôZ"‘¼K6lØ Äʽ+÷®Ü«ï4ï¿dïdïdo!>êöQ·º ‘¶1mcÚF}§z}¤GoIL¯˜^1½ÀJi¥´R‚……EÙëÕÛVo[½-Ôɨ“Q'öwÜßqGІiôaúN/‘H$’÷T¼%?üp0TJ©”R)«««³A@Ï[=oõ¼Ñ·£oG߆ÛA·ƒné;½D"‘HÞ7Rð†­/Z_´ýôè§G?ïPß¡¾C{—c.Ç\ŽAëÂÖ…­ aàþÀýP¬,VK=6$‰DòšHÀ–Ù7³of_P—ªKÕ¥à¾Ñ}£ûè…Ú¾iû¦í›BATATA„œ9rBßg#‘H$’÷…ôò ‹Û·9n3˜1c6k8Öp¬ñ¿Îb½Åz‹õн {A÷8píÀµ× mÛ¶`aa-Íe-‘H$’¿Hºð†EÞ¼y<Ò<Ò<ÒÀp¼áxÃñüç?”}(ûP¶m;Úv„c-޵8ÖBßg%‘H$’¿;©xC´>Z­ĉ8' Úºj몭ûóû146464†¾ô¥/²3dgÈNxòõ“¯Ÿ|­ï³”H$Éß•T¼!©±©±©±Ý"»Ev ¨ò´ÊÓ*Oÿúþ|‹}‹}‹¡æƒšj>€ƒŠƒŠƒ ŸˆOÄ'ú>[‰D"‘üÝH}Þ„ 3f€iÓ¦Àú[ëo­¿ýëû“id™zm赡ט;sî̹3!"$"$"jS›Úú>i‰Dòfý²HObbbbb"Ü^{{ííµ IÕ¤jRõîÿM ˆ’ – E–|¼|<”¬×~¤ý¸Å3ž²W<Îk&3È mpÚà´ÁP¬.V«RHÑwº×G*Þû÷îß»<*{Tö¨ Æ9Æ9Æ9¯¾ßòcÊ)?ƒƒƒ`ŸÓ>§}NPµ¨jQÕ"042424Ò÷ÙK$’7¡¢SE§ŠNp¹Åå—[ÀÕÕ0“™ÌÔwºÿ$ÎÉÜeîà0&=1=›¥¤@dÊ]*w±M>A>Pþkùôw†^xAéîÒÝ¥»ÁÛÍÛÍÛ ŒÜŒÜŒÜôîõ‘½œPßAÞ­F«Ñ¬Ÿfý4ë'háÒÂ¥… ´öníÝÚûõ'K—¥ËÒÁÌë3¯Ï¼]Óº¦uMƒÖ]ZwiÝEß­ ‘HÞ$'âDÜË©ÜSL1ÕwªÿC‘ÜIî²U×ò¯åƒlÝ•W^€.k‚çO @ñBñø×Thï-Z´ «'«'«²ƒ²ƒ²ƒ@cÓXßá^éÀk–3/g^Î<ȼ˜y1ó"xUôªèUØÅ.v½¾ãXË­åÖrèÞ¶{ÛîmáÙ²dP?³~fýL°j=Ôzè«G"‘¼{d2™ȽkwÏÿokþµkj]­uä–Xb ¿üß»çÙ/(ÞSR'À×,&8&8&ŒŒŒÀÕÅÕÅÕåÍ/à|Àù€ó`bbA©A©Aïâ³@‰Dò¦ˆUÄÙÙКÖúÎ$‘î¼f·>Üúp+¸á† ª©ª©ªùæŽgTר®Q]è÷E¿/ú}«3Vg¬Î€&FMŒš[‘[‘[‘¾[E"‘H$ïéÀk¢©¯©¯©Ñ3£gFÏßM¾›|7½½ã× ªT+ª-©¶¤Ú8u0ê`ˆf¢™h¦ïÖ‘H$É»F*^“¬¯²¾Êú ^¬|±òÅJ¨4ªÒ¨J£Þb€«\å*ôÌè™Ñ3¢ªEU‹ªw»Þíz·«¾[G"‘ü³e$f$<Ì{˜ vˆúÎ$‘ €×$).).) ‚þչũԩԩôíç¨àTÁ©‚4—7—7—ÃÞV{[ímEQEQEQún%‰DòÏt?å~ Àþ°ýaÚ"­ôhRï¤à5‰ŒŒŒ·Qn£ÜFy=ózæõô—§ãŽŽ;:î€LËLËLK¸¼éò¦Ëoñ‘„D"‘”ñ¾ã} sÃÎ ÁŠ`}g’HÀ«zÈC£•V>Z >—}.û\Öw(°îmÝÛº7t¿ÐýB÷ pxßá}‡÷AÎМ¡9Òð@‰DòV9Œt P[U[ ;";¢ïL©xEõ2êeÔƒÔìÔìÔl¨Þ¸zãêïÐDÍŒ›733S3S3S8|"ø„TyK$É?žT¼¢D—D—D0˜c0Ç`8:;:;:ë;Uî†] »Bï½ô~Á‚/_€¤“I'“Nê;D"‘HôE*^QLó˜æ1ÍÁå;—ï\¾³efËÌ–é;Õª}²öÉÚ'¡ŠeË*–p°üÁò˃è%z‰^úN'‘HÞo¥ÊR%@Þ´¼i¬a¾3I¤à/*¡*¸v?ì~T­YµfÕš %%{›Ãÿþ yyyèãÒÇ¥ Dˆ! raäÂÈ…úN'‘HÞo‘7"o|7ø»ÁÚ;Ú;úÎ$‘ €¿¨`iÁÒ‚¥z8õpêaðí9Ús´¾Sýo444Ðì`³ƒÍÂþšûkî¯ ¥¥¥úN'‘HÞO†‘†‘–,;ðŸé;“D*þ¢§¹OsŸæ‚X%V‰UP1¼bxÅp}§úãºìí²·Ë^Ȱΰΰ†Ÿ–ý´ì§wðÑÅ{C À!qÈ%—\}‡’HÞŸ^>½z,è±@‘ªÖ,Ñ;©ø‹bæÆÌ™ jµƒÌlÍlÍlõ곎·Ž·Ž‡.‰]»$Â?xüàj™Z¦þ[,/ö'ýòœµ,kYÖ2Èú$듬O€<òÈ{ó‡555…õ Ö/X¿B¢C¢C¢!gÎþœý-Ë–eË@ÓGÓGÓRî¦ÜM¹ ©—R/¥^‘%²D–¾Q"ù«Æ cÕ@Õ@Ð@ß™$RðÅ;<<<<<<@ö‰ìÙ'úNõç5MošÞ4LƒMƒMƒ!È$È$ÈDߩހ4ÒHƒýÁûƒ÷þÚûjï« |Ï÷|ÿ'ö³–µ¬ííí tÒóÒ¥=J{À¶Ôm©ÛRÁòk˯-¿»svçìÎÁž–{Zîi >:ðÑ ô\é¹Òs°?räþH˜?;~v<”Î/_:„¿ðþ »§»§»§ïF•H$gRð'å‡ä‡ä‡ÀÓ½O÷>Ý UVXe ¾SýuÆÎÆÎÆÎÐ÷iß§}ŸBð§ÁŸ ‰÷ï%¾Í˜Ãæ0°„%,ù/Û½\Ÿ{8ì`+øõžÜàÆÿñs…R=Œ{÷0†^“zMê5 ðÆoÊnÉË·|ËïQS£¦FM…C·Ý:t pÆg@ƒÍn_|¤øHñ¸ïwßï¾x|îñ¹Ççà;Ãw†ï è!ï!ï!‡îÝ=º{€ñ ãÆ/ b¿Šý*öƒ‚K— .¦¹¦¹¦9üpþ‡ó?œ‡û“ïO¾?ùÿ8Ï$’HÖ±Žu@>ùäÿ¦ÝÂ#ì-^W‰DòÎ’–þ“²eÊTö‡Ù9Þ9Þ9pÅW}§ûëjM¯5½Öt¨ººêꪫá‡Þ?ôþ¡7LΘœ19H%•7ðÌ.jKÔ–¨-<8xpð`È äPDZŽcGhò¬É³&ÏàŘc^ŒOO<=ñ à à à Ç8Ç8ÇŠŠŠ!üVø­ð[ÀzÖ³ÌsÍsÍs¡jXÕ°ªa»:vuìjHß’¾%} Î œ8 ¶ïÛ¾oû>ðœä9ÉsG¶G¶G64Ðd@“°1mcÚÆ4x2ëɬ'³ÀaˆÃ‡!Ð4 i@S_–_–_í!í!í!¸9ðæÀ›!þLü™ø3pjë©­§¶‚õbëÅÖ‹!Ì+Ì+Ì 2FeŒÊ™ÈD@ÖJÖJÖ d¥²RY)Üm|·ñÝÆ°êÒªK«.AËo[~Ûò[°üÁòË€Œ`ÙÙÙAqûâöÅí¡bŠ=*ö€ÆAƒÁ·U¾­òm0¬iXÓ°&˜ô7éoÒêÖ®[»nmˆsˆsˆs€¼ªyUóªÂíí-È d²}¿K%_OƒžÄŸ? ФK“.òfriµR½‘îüIýû?ö³;fwÌî€Ã‡ôêÕ)  è­ì­ì­„ïïoˆôŒôŒô|sÇݺqëÆ­¡`fÁÌ‚™Ðõ^×{]ïõë)ÖS@»X»X»6Þ4zÓhH+L+L+„~súÍé7üÛú·õo Ê…Ê…Ê…»=w{îv;v.ìT_W}]õuPηœo9_0ô1ô1ôK/]¼tlNÙœ²9w«Ý­v·x®ð\á¹ÚVl[±mEø®ùwÍ¿k òy‚;,vX ž½<{yö‚úíë·¯ßä]ä]ä]~Óž– K…%T?RýHõ#à sÐ9è ±wcïÆÞà3Óg¦ÏL0ð0ð0ð€+í¯´¿ÒtÁº`]0`‹-¶ މc┿PþBù `2ÍdšÉ4h¼¾ñúÆëÁÁÄÁÄÁÖëÖëÖë@µMµMµ ºEt‹èû£÷GvOížÚAήœ]9»àV—[]nuߎ¾};‚±»±»±;ZZZÑ7Fß}8à€ƒ¾ß’¿¿Ä+‰W.…^ Ð%ë’õI"Ýø“îgÜϸŸ'UœTq¨òUùª|}§z}*L®0¹ÂdhæÞ̽™;ìÍÙ›³7Ú,´Yh™™™¯ïx•¾­ôm¥oáè•£WŽ^ëÖ¬@—»üØåG(iVÒ¬¤Üì}³÷ÍÞ0!{Bö„l°¸`qÁâ4ªÙ¨f£š ìªìªì ö\Øsa8Vq¬âXê9×s®ç œà'àÞÇ÷>¾÷1ȵr­\ ÎÎΠܠܠܦM›>ïÞ+¼W€Aƒ:uàiå§•ŸV£F+ŒV€Q®Q®Q.w6îlÜùÿ8±@ £Ï>7ú”6J¥ ˜M2›d6©l3Æ €OŸú>ú>ú> f‹Ùb6hJ4%šˆ÷÷÷S7S7S7¨<­ò´ÊÓ@Ö_Ö_ÖrBrBrB ¨{Q÷¢î€/¾¼¤ Ô‹zQ/‚á¡á¡á!hNhNh~¶“~·~·~7èóõùú|Ð × × }Ž>GŸzk½µÞŒ®FW£+•F¥Q ™3f>F0‚PMYMYM 6Ø|`ó4^ÛxmãµÐÆØÆØÆ®½\{¹ö—ÎKçº"]‘®pÁà‡8§RN¥œJƒ>:øÄ01L 3÷Ñ(‘Hþ Rð+¥†¦†¦†‚E„E„E¸ qâ6ÄÜ©þ|-η8ßâ<(w(w(wÀ‘ýGöÙÿêÚ×xj<5ž°µÞÖz[ëÁ½Ýû×½Áè°Ña£ÃÀYtEøðø‡Ç?<ÊÆÊÆÊÆ°©Æ¦›jÀ·nÜ ªOTŸ¨> ¨¨vìØ€¬‡Y³B‰K‰K‰ änÈÝ»*l«°­Â6H—8.qhkkÙ¹gæž™ ‡px :?èü ót2èdÐIhÕ"ªEXí·ÚoµަM;š†å†å†å¥ý5¢FÔ@lýØú±õÁwŽïß9\˜\˜\NNN×"¯E^ ðªêUÕ«*Ü]~wùÝåPP£ FA ¨p¸Âá ‡!gzÎôœéУe–=Z•¡W†^ ±§bOÅž‚Q¦Q¦Q¦ÒþmHÙ²!N49ÑäDH«–V-­X´i5¬}¬}¬} kjÖÔ¬©@':Ñ rå4Êi™µ3kgÖq±¸X\lî£P"‘ü)Dɯ²?þþ|Qœž5=kz–(›››™;Õ_çö“ÛOn?Åwn¼s㢘d™d™dù Þ n7ˆ¢ñ}ãûÆ÷EѨ5jZQ¢Q4¾dû1D Ec;c;c;Q4n7n7nÅ7ω¢Éd2™L¢hÒ˜4&(ŠƒÅÁâ`QW‹«ÅÕ¢h:n:n:.ŠâXq¬8V Ož(™›%d YÐ{xï὇Ãý”û)÷S ªCT‡¨¿Á| ž1ž1ž1P>´|hùPhÚ´iÓ¦M¡}›ömÚ·µÚFmò»ò»ò»Ðãh£=ŽB½óõÎ×;‰Q‰Q‰Q ºŠ®¢+nܸ’ܓܓÜA®ׇÃöÛlƒÁ`0ÀØÈ±‘c#!ýlúÙô³p¸âኇ+š{oH$¯ZÍìšÙƒ|ùțɛ™;“D*~ÁÓÞO{?í ®V¸Zá*ØL±™bó7œèæ¯æ»Òw¥ïJh]к uì(¿£üŽò ë©ë©ëiîtÿ›ðXx,<a°GØSúsE%E%E%pëèÖÑ­#x›¼MÞ&p™ê2Õe* GŽø’/ù„`!XÁOðüøiµ½è~Ñý¢ûAÊÑ”£)GápÜá¸ÃqïžïžïùùùÒò»’«æVÍk:¾øæ?—¹æÎ$‘.ü‚d‡d‡dðÞê½Õ{«¹ÓüýtÝet—Ñp-àZÀµ¸°öÂÚ káMÞäMs‡ûo*R‘Š ôz=€cãˆbXœâ§øÏÅJ(¡УG˜0aЀ@yÊS¬*ZU´ª^ ^ ^ Pkz­éµ¦CpApAp¸îsÝçºï7§–H$’ßLø à à à cBÆ„Œ àwÉï’ß%s§úûqºïtßé>t¿Ýýv÷Û°çæž›{nB²@Y 4wº_f½Âz…õ ˆñŒñŒñ„äJÉ•’+ºžºžºL+˜V0­t{›6;mv‚°SØ)ì„g¹ÏrŸåBŽ,G–#m’6I›F£Ñ@SUSUSäTÍ©šS   Ài™Ó2§eàpÏážÃ=sï‰DRHÀÿ“ãžãžãEˆ ¿¹~sý¤¡ªß­ù¶æÛšo‡3fÀÁo~sðs§úeﺽëö®8éü¥ó—pëØ­c·ŽAÓˆ¦M# Ü¼róÊÍõxõxõx¨Ð¢B‹ -à£-mùh ÄÆÄÆÄÆ@ARARAô¸ÓãN;`J0%˜ ‡U«VÐrCË -7Àå›—o^¾ ·çÜžs{ä+ó•ù¯q$‘ü>Ùõ³ë<ýp4€8KœeîLi5Àÿ'꣨¢>ÅÔ¨?P‹bþ§ùŸæjîTwÞYxg¡(òä?È_§$NIœbîT‰ä¯q©Â¥ ¢(Š3GÍ%Š¢¨ß¨ßhîLiàÿÉø:ã댯Áþ¡ýCû‡`›o›o›oîT!÷Cî‡Ü‡î5Ük¸CøúðõáëA¼ ^/˜;D"ùsååt[Úm)€ü¶ü¶¹3I¤Å€þŸuOÖ=Y÷´ñÚxm<Œj?ªý¨öæNõÏ‘XœXœX 3¾ŸñýŒïaÜúqëÇ­‡ë!×C®›;D"‘”ÒÀL·L·L· Õ*Õ*Õ |ßñ}Ç÷s§úçñUú*}•ÐzPëA­ÁŽG;íxº¡º¡º2¸Ì²D"‘˜‹Tü@¿W¿W¿²]²]²]Àk¹×r¯åæNõÏÕ©o§¾úB~×ü®ù]áüÜósÏK7[J$É_F*~›”›”›š0M˜& *4©Ð¤Bs§úçrÞí¼Ûy7tìÙ=öøïñßãùŠ|E¾4;…DòcúÒô%€>N@QæÎ$‘þÔþ iPÒ ¤A`ãdãdãnsÜæ¸ÍÖ±ŽuæN÷ÏÕ¼Mó6ÍÛÀiñ´xZ„C^‡¼yÁ@2ÐÜá$É+r§òÊ×][0"jD€ü²ü²¹³•]ÒÀÒê¤ÕI«î­Ü[¹·EEEs§úç³^j½Ôz)ôóèçÑÏÎÎÎ ñlâÙijæN'‘H^ ›6\º4`3›ÍI"?xþéóOŸ î5Ýkº×!TBͪ쨽¾öúÚ롆¼†¼†vÕÙUgW0L“âtqº8l½³õÎÖ; ^¯^¯^oîÔ‰äß©¨<Ž| p¿ÒýJú#ú#Á™Á™‡=pß÷¾/@úgéŸp©ðÿË”ùK¦K¦K¦Kê”ê”ê>hôA£̪ Š#Ž8x[ö¶ìmÌHž‘<#æºÏuŸë{Ûîm»·-)S<ZšZšZšÀg˜Ï0Ÿaæ/‘H^(nVÜ `Ò²IË"s"säå(¢€B „îBw€ "Þžõ¶4Cà_¦Ì¨ƒ€Û·þË¡êêê7#nFÜ s§—H$/WK]K ’’ð²ß[ݳºж^ÛzÖ“¬'™;sÙSæïÈØ’±%c ععع€ýöoØ¿aîTe‡ì;Ùw²ï =íi¸½­ÞVo «V9¬‚)G§rôwôwôwà ÷AïƒÞµ0jaÔB° ¶ ¶ ý—ú/õ_‚éˆéˆéˆÓÄiâ4@5˜,M–&K“Åd1°ÄK••á°pX8 ä“O>„GÂ#5’5’5Y¾,_–r'¹“Ü ^ /…Èmä6r+åJ¹òÅüfòË`!·[ÈÁ"Ã"Ã",>°øÀân 7…›€ ™T†K^¦^¦^â^q/€´ú”••Á.Ü.Ü.”ß)¿S~à˜ã˜ã˜ŽÏŸ;>'£“ÑÉ.^.^.^àô™ÓgNŸ¥µ¥µ¥5(J%ŠPLTLTLrƒæ>J$¯±‘Œ0 0 }/û@¶TöÒÇjó?Ïÿà›sßœð\á¹ WÝ^uäEò¢{ÁÏùŸJ?•••r(ä@û í+xVóü·»þSv§ìX&,ºEt‹}?ô¥€æKÍ—çúŸë LT&4y»ÉÛòy‚¹wõë¯Ì*µJ­RƒÊ 2¨ à¶Ëm—Û.s§2ƒYÌb”$•$•$A¶W¶W¶d·Ìn™Ý²Ä,1K„TMª&UÏeÏeÏePø´ðiáS(©SR§¤¨j£ÚB€ €……… (]”.J°³³åyåyåyPWW‡rËÊ-+· Á1Ø1Ø1ìFÚ´ qqq`QÛ¢¶EmP¤+Òé¼ø36t¶:[-8r:åt dMdMdM@^S^S^³ôüOßôd²õ’õ’õzÑ‹^`’™d&˜››å(G9+‹•ÅÊ`ÔµF-˜œLN&'0\1\1\c#c#c#0ô5ô5ôC¬!Ö †­†­†­ ½¡½¡½%‡K—†‚'O ž@Á€‚ XY¬,VBöÑì£ÙG!¾y|óøæP\\\ºõuôuôu%J”`÷/»Ùý ”¢RTŠàÐÍ¡›C7ðœè9Ñs"x½åõ–×[à†n€›£›£›#¸Íu›ë6¬—Y/³^T¤"Í}Jþ:OÖ?Y°óà΃×w\Pz/Ý޲в a§†Ê¯-¿@ö­ìÛ—¾ÀG€®]»vèP©C%ù7òoBo…Þ°heÑ €K\¨è^Ñ`ªvªÀ~“ý&6°á¥ï³œå} úä?Ì`ªoª GþÒ—ÅŨ>U} ô(è€åBË…æþlþz‚øsù«eÍ<šy&§LN™œ³Sf§ÌNïÙÞ³½g›;ݧÓét:Ì)˜S0r;ævÌíq¾q¾q¾ççç©…©…©…{<÷xîq0 `›b›b›öÍì›Ù7ƒòKÊ/)¿Êo(¿¡üp q q çsÎçœÏs[ç¶ÎmÁÙÊÙÊÙ ”ÙÊle6țɛɛà(8 ŽÀ¦0ÅÜ{ç5¤C‡Îp†—ŽLè·è·è·@QvQvQ6äåæåæåBÞ„¼ y ¯^^½¼z»5wkîVH‹I‹I‹,§,§,'(®]\»¸6¨ë¨ë¨ë€eË&–MÀí¶Ûm·Ûà£òQù¨ `wÀî€ÝàëãëãëÎöÎöÎöàøØñ±ãcË‹åÅæÞI’ÿ¤R¨™V™VîÝ;Ø}o÷ý˶O_‘¾àq½Çõj6¬ÙÀ]î.ÿ5ï÷ÚùqfÁÛ¼x|¸9Í~éÒÚ¡7½ pó½›ïŒx6â€ç4ÏiæîÊ_¯ÌñOãŸÆ?…yÌû`Þ0ÿÊü+󯀛ÆMã¦1wºÿ⇙óô¹ú\}.äœÎ9sbâbâbâ æTÌ©˜Sð´ÒÓJO+AþäüÉù“ùé­ë)×S®§ âÁŠ+„Š[+n­¸|×ø®ñ]<:xt›t›t›t°jnÕܪ9(ÒiŠ4Ào¼Í½$¿h›Øúæúæúæ }¦}¦}ªªªf“f“fIg’Î$ÄÆ‰C²²²?ä7ÍošßäÃåÃåÃÁõ#×\?‚ÀyóçAÐ¥ KA— ðaàÃÀ‡à´Êi•Ó*???0wçË¢ÓOO?8¼ùðf€1ãÇŒ¨äRÉå4ûeìiì  m¯m`}Þú<¼x ùeÛ? yP¸¢p@íwj¿/Æ&ÍÝ—?®ÌÒ¤?H‡U™«2WeÂüÕóWÏ_ Žk×8®1wºRùÝó»çw‡g Ÿ-|¶ôyÐçAx4ùÑäG“!Lþ˜ü1`?ß~¾ý|ðËñËñËê7«ß¬~*~Vñ³ŠŸëb×Å®‹ÁñãÇ ».».»nîÞI^†-†-†-••9á9á9ágggË=.÷¸$®O\Ÿ¸4Aš M¸·poáުϭ>·ú\¨î\ݹº3øò?ä”ã•ã•ãÍÝ»¿¥-lJWÍû…Er —.ÐÆhcÜÂÝ„L!ÓÜ]ø'¸¼üòr€#ïyà›l|EßÀY³Ì7ÎÞ8{ã,ìè´£ÓŽN0ïü¼óó΃mÛ¶ þ ‰$’ý úô‡è6Ñm¢ÛÀ•5WÖ\YOÝžº=uÅÅÅð/ð/ð/€¸¸8ºt+è”Ï,ŸY>ä£ä£ä£p0÷^–ücüðT„~Œ~Œ~ ¤,OYž²žÄ=‰{÷zßë}¯7$ÖL¬™X„^B/¡Ô8^ãxãÐtWÓ]Mwÿ}ÿûþ÷AYEYEYÅÜzeîÈܰ§ÞžzÍC›‡TO©žbîleÒO…i“µÉББò(y”¹£ýqe¶8£;£;£ƒ N,8±æŽ;vîX°PZ(-”Þûšô&½I‰S§$N3ò3ò3r¸UÿVý[õA$’A-«ZVµ¬ ©eS˦–àßÕ¿«W°™b3Åf ½…ÞBosïE‰äÓMÓMÓM(™Q2£d»4wiîRpÚä´ÉiXT¶¨lQèK_ú¾º÷1í4í4í„ÇÅ‹Ã~ÇýŽû!6*6*6 ãããa¨õPë¡ÖÜ;¸wpoPÞWÞWÞªP…*À]îr×Ü{M"y9YCYCYC°?nÜþ8Ô§>õúsëÏ­?ò*çUΫ QU¢ªDUS§NÀ©¾§úžê !C:†t„ÎÓ:Oë< *eWÊ®” t§;ÝÍÝ»¿RuêÕÕÕÕ|ŽtâÿùÈ|ÒÆ¥ˆNŠNøÐãCùsùssgüOev`eñÊâ•Å ¨¯¨¯¨ïG¿ý~ô«k?ùJò•ä+°³æÎš;kƒº>º> «« Ø`ƒ¹ÃýŒ'žx‚f‘f‘f”¼[ònÉ» mªmªm „Nø¾L^]^]^‚݃݃Ýa쌱3ÆÎ€É™“3'gBbdbdb$L1}ÄôpG¼#Þù[Mɽœ{`éÂ¥ âóãó{+?.­9®9®9†u†u†u¯.¥q¡q¡q!Ü n7/‹—ÅË “éd:h“´IÚ$ Œ0ÂþK;3Œ3Œ3Àà`p08xÄ£W¿Wu™ºL]&œ»îþ¹ûpìÆ±Çn€ÁÖ`k°}7}7}7SÄ1ôžzO½'heZ™Vâ q†øJW•]•]PvUv^ÓÿOÄ2Æ8Æ8Æ8FgXͰša%ЇòåÊÿýí½8EqKì–Ø-±¢øNÊ;)龜â9å9å9¥(êô ús÷ºÔ¹£çŽž;*ŠŸ7ú¼ÑçDQí®vW»›;•äÿÓŽÓŽÓŽŽå÷–ß[^‡ì²sÈNQÌœ9!s‚¹Ó•ŠËŠËŠËÅù æ7˜ß@W8­pZá$Šs®Î¹:çª(^¯ˆW~G»êXu¬:V÷<ÚóhÏ#Q(Š¢x¼õñÖÇ[‹¢é]Ó»¦wÍÝûßâÉì'³EQ74ÝÐTE±È£Èã··’Ó!§CNQ:>t|¨(n¸´áÒ†K¯.å~q¿¸_ť喖[ZN‹N(:!ŠÛ4Û4Û4¢8¼hxÑð"QÌÿWþ¿òÿõËíì3î3î3ŠâÒw—¾»ô]Q4Øì v¯~¯õ9êsÔG§ë¦ë¦ëDqÿÐýC÷Å+=¯ô¼ÒS§_~uúUQÌmšÛ4·©(žíq¶ÇÙ¢8àÒ€K.‰blNlNlΫÏõËÔŸª?EQT¥ªRÿÊ÷}¹27` 5…šBA³Z³Z³ìªÚUµ«úûÛ;æ}Ìû˜7\­zµêÕª0}êô©Ó§BË¢–E-‹@á«ðUøš»×¥ªÜ©r§ÊxkÌ[cÞ–³,gY΂‡3fÀ ý ý಺b¦˜)f•®Wº^é Ïv?Ûýl·¹Sý2Ë/-¿´ü÷î Ü 5j&ÔÝÝÝ€W¸_œEgÑJn•Ü*¹¦ë¦ë¦ßðx¨æºæºæú‹ÙWšå}”÷QT_R}Iõ%°²áʆ+‚æ ̶͚߰µ¿µ¿µ?t¯Ú½j÷ª0:ptàè@Ø%ß%ß%‡ë®¸þ ÷߯Š];€÷z¿×@™¡Ìøí­¸v9ìr)ŠE ¤N>úÕ¥ ù äƒ ´Wh¯Ð^ l«l«l gΜ…xM¼&^†w ïÞ…;º;º;:¸¿äþ’ûK~ÖŽ"†ˆ:4thèP͓͓Í{õ{õÚÅk¯]ûÛö·íoC—ð.á]¡r§Ê*w‚NC; í4ì·Ùo³ßÁ¾Á¾Á¾z'õNêP_U_U_}õ¹þKâã׎,ê·¨€!Úð /=ÿVeî&@SgSgSgЖӖӖ›Ý6»m~lj ¹yróäæp¢ß‰~'úÁÈé#§œþþþ¿?ßC÷‡îÝáü§ç?=ÿ)4¬Û°núPYýeõ—v±v±v1XºZºZºBü¤øIñ“àVŸ[}nõýýý°:guÎê8=szæô œª8UqªòŠòŠòŠóȧ1‚˧.Ÿº| K{-íµ´X °`5k;Öv¬ +V¬„ËŸ_þüòç^+½Vz-(—P.¡\´¨Ó¢N‹:`‘`‘`‘ðëûùTþTþT·Êß*«<ð Ÿð 4nÛ¸mã¶q%ãJƸ»õîÖ»[_Ìú>x´ôhéÑÎÌ=3÷Ì\Ì Ì Ì„r­Ëµ.×.Ö¿Xÿb}ÐËô2½ j=«õ¬Ö3°zßê}«÷aÞ¦y›æm‚æš_h~ÞúÎÐw†‚ÝWv_Ù}çûŸï¾?ª Õ…jjÔ.¨Ô¨R£J*p¢Ï‰>'ú€fšfšfØ{Ù{Ù{Az`z`z TЍQ)T§T§T§ ×"×"×Úßh£ý (׸\ãrý~’} û@ö‘B¤YºX‘q•q•q\µ¾j}ÕÒ†¥ K–-;[v†¦ò¦ò¦r(÷´ÜÓrOAã¢qѸÀÅ‚‹ '3'3'òæ7Ìo>×|®ù\ƒv}Úõi×çׯQ40h`Ð@~šhêGî)î)î)P (P(Ààdp28ýþÿ.ê?­ÿ´þS4{ÐìA³!Ü&Ü&ܪž©z¦êpjíÔÚ©õïoÿ/0Žq¯°µÖ|ˆ‹‹‹…ƒ£Ž:8 4O4O4Oà_£ÿ5ú_£!arÂä„Éžž>éôI§O ò@äÈêêê¿éøMÇo mLÚ˜´1Ú<µyjs¨Ú«j¯ª½@–(K”%‚¼‡¼‡¼¤Nœ:ô[ÐoA?ðïâßÅ¿ Ø6·mnÛ2keÖʬiiiàÜȹ‘s#8»í춳۠ܦr›Êm‚’%-JZ€¥‡¥‡¥´÷oïßÞ,ß´|Óò¿¬ò™¶-m[Ú6xxÿáý‡÷Áv·ínÛÝ9'rNäP4S4S4ƒè®Ñ]£»Be¿Ê~•ý@v^v^v„d!YHáð@xœä$'áòÒËK//…¤öIí“Úƒ‹ÜEî"‡–1-cZÆ€uœuœõš¨Ò¹Jçžå<Ë0ºÝf9—¹±³ØYì švšvšv`;ÝvºíôßÞÎù›çož¿ B€ @uÿêþÕÿÀ‰ÿG¶cmÇÚŽ…2d@š2M™¦„ŸŸøüöç·?¿ 1bă 0( Ⴤ>ÕBÕBÕBX1gÅœs@õ‘ê#ÕGPdQdQdÆùÆùÆù°ÆuëWЌՌՌµÚNmç<Îyœƒò5Ê×(_ŽN::éè$8p0à`@é¼ûZíkµ¯œìw²ßÉ~¿¾º÷tïéÞƒùMç7ßÔÅêbu1¸+Ý•îJ(Ì-Ì-ÌÅÅÅø¦ø›âoŠ!ÿPþ¡üC ˆb<ÞñxÇã`Ùβe;XsyÍå5—áшG#? ? ? È»›w7ï.Ø~iû¥í—Püañ‡Å‚ïtßé¾ÓK×$Ø8j㨣àQñ£âGÅP)¼Rx¥pX±jŪ« naܸ…p»ÓíN·;ÁÅöÛ_lU«8Vq„ËC.¹<N«O«O«!x@ð€àp¹á冗Bx¥ðJá•þøñ!ë!ë!ëGÆ ‡CÓM?4ª»Vw­î y{óöæí…Å9‹s瀺¶º¶º6VVVÁjª¨U—W]^u9ÜØuc×]{#÷Fî °p·p·ø ËbËòdy²<=‘=‘ýìf¶T§T§T'¨ÒµJ×*]Áº­u[ë¶¼ÿM¾nòu“¯Ázõë5p{Üíq·_å‰õï"ðÅ*|.=]zºô„ê ª7¨ÞÒ–§-O[Ë–, €¬ŠY³*¦›lZÚÖÚÖÚÖ ¤¤lx°áh»k»k»CÉÜ’¹%sa]þºüuùPò¤äIÉ“ÒÕ+ÅÏÅÏÅÏA™¬LV&Cñ½â{Å÷À{©÷Rï¥à±Óc§ÇN(üªð«Â¯`ÝŽu;ÖíÓÓÓØ3lϰ=à ý«ô¯Ò¿¿[~·ünÁ†FmhwòîäÝÉûßÝwúÊé+§¯À9Á9Á9< x/÷^î½777aý¼õóÖσôyéóÒçìˆìˆìHi;²g²g²gp¾õùÖç[ÃŽ¯w|½ãkÊ Ê Ê‚“O^t9€U±•§Ø.s€~‚~‚~èCõ¡úP°­i[Ó¶æoh Õ¨q»âvÅí‚···W—¯Ò”JS*M6Û4nÓ¢¦EM‹šI““&'M†Ó‡O>}ΩΩΩ {böÄì‰Plý±õÇB¥}•öUÚ.3]fºÌ„6OÛ3}fŸ§>O}žÂ§ã?ÿéxر)bSXæ[æ[æCë¹­ç¶ž —¶^Úzi+\m~µùÕæPË£–G-ÒvGî¹gähSЦ M,µlÔ²Q0¯É¼&óš€ÎZg­³¡³ÐYèÌ‹ÅÂä .—‹Ë¡duÉê’ÕÝ2ºetK¸ºùêæ«›!”PBàÁ ‚€é3Óg¦Ï€‹\äç'Ì÷ß(d@¼‚ã;¾ã;PÇ©ãÔq`YͲšåÏ–UU„(B! n·‹ÛA_S_S_ÚÎk;¯í<ȱϱϱ‡oR¿Iý&µô’B«Þ­z·úKØØØÂž•{VîY ¡ÏBŸ…>ƒzMê5©×äôûGïò.ïBq§âNÅÀ¾};ûv¯°ýWFÕIÕ `Iì’X€§¶Om_aóPâ>qŸø³‰f¬fZÍ´š ¦tSº)½tÙn¶³í€?þøSz¼þQ&L˜ø¿ÿáÇ嵟óœçüçSN8á²Éþ%û<»úì곫°)|Sø¦pذkî »àÒ—Þ¸ôó{I~\æ{®8WœûÛã ¡B¨ ªzªzªz¶1mcÚF8ïrÞå¼ x=ôzèõÚ^m{µí+¹WàÅßgØÓvO[€;^w¼^E»¿O™+УУУøé´3Ù™ìL¿½Fë­o´¢â£â£â¡øtñéâÓ¯.gí:µë郞 c1¢§GOž½“{'÷N†Ì™2@VRVRV”ë]®w¹Þ öûŠ}A¬&V«7¸ÁŸ5\ôÃêYéLgà'8¼É›¼ êêêêê꥛W:Pé@¥PqDÅG@ï½Oô>ÍÿhþGó¡•±•±•ñ×÷K÷H÷H÷²dÈÓ†L2mtVuVuVÁÕÉW'_ \æ2—¡ùèæ£›†âuÅëŠ×AÄ•ˆ+W xQð¢àE¥íÆ×¯_†›†›†›`ä[#ßùD$E$E$:O§Î+]¾WS_S_Sä:¹N®ƒJ•*@µäjÉÕ’¡Oã>û4†1-Æ´Ó*+++++ÁØÀØÀØÄJb%ñgCúâcñ±ø¸tùàŸ<æ1öyüV?~cùáó® ×…ë¨ Tª íLÚ™´3¥›§uNëœÖìÚ/´_Î={:÷SkSkSk¨™S3§fÔ\QsEÍð¡ï‡¾úBÝNu;ÕíôÛãô}±ëw ß%|—>®>®>®Ðp}Ãõ ׃zŠzŠz 0šÑ¼‚›ÕÒ«¤WI¯)Å)Å)ÅPgf™ufþñv_=‹zõª7«Þ Àf–ͬWØüSžò¨E-j•þ8ªZTµ¨jà1Ãc†Ç ðŠðŠðŠ]º.]—Æ)Æ)Æ)@9䀨Xl,6qˆC”þ}hLcƒ.†‹áü´ÙOÛÿpB757575/} ô'Z´hAl$6»ÙÍn`#ÙbG±£ØñgÛÿðsãXãXãXÙ²!dÌí<·óÜÎ0?|~øüpè>¼ûðîÃK_öâ1 2•ùùw?öã=Þ㽟=î÷C® IÓÓÓð[æ·ÌoTH¯^!z ê1¨Ç øpÿ‡û?ÜaýÃú‡½’y(„ï„ïÚ?jÿ öíÚ·_áqñ•¹›K:”t(éòuòuòu`ý±õÇÖÿövîm¸·á^8·åÜ–s[`›Ï6Ÿm>ðžë{®ï¹‚"G‘£Èùý9m»Ûv·í;v ÛY¶³lgA…7+¼YáMèb×Å®‹øMò›ä7‰Ÿ¾$WL®˜\L‡M‡M‡!®{\÷¸î|%øJðx0÷ÁÜsAqFqFq¢+GWŽ® 6Ø` œïü{ç߃Ó×O_?}úTëS­O5øÆæ›ol`yÇå—wŸ!>C|†ÀçÞ8÷Æ9ðJðJðJøßýµ¢VÔÂù¦ç›žo wÂï„ß ‡çCžy>Þ^øö·òÓ7׆® ]B³øfñÍâÁ¥·Ko—Þ`·ßn¿ÝþÒvï¿wüÞq¸:æê˜«c ¤wIï’ÞÐob¿‰ý&‚k×&®M Á”SL½ù{ó÷æ—.f3¬`XÁ°Ø?hÿ ýƒ Ï.Ï.Ï|³|³|³ ¶}mûÚöggg ªªªïï﹇sç­­ÖVk ñAñAñA””úýúýúýP0³`fÁLpLpLpü/ûK?T?T?¢/G_޾ ý,úYôƒ˜ƒ1cBŸV}Zõi;ê쨳£¬j¸ªáª†3*gTÎ(–6,mXxŒðá1îõ½×÷^_8_ó|Íó5!ncÜÆ¸ k¡k¡k~çýÎû‡÷ƒß~?”J¥ÿST»¨vQíàÈ£#Ž<‚Ê«*¯ª¼ N §„SxuõêêÕÆÕW{\íÒ¡Þߪ¤MI›’6°©å¦–›ZBõ°êaÕà heÐÊ •ÀR–ò[.Eýé,Ã,Ãú–ô- u^]ë!³Cf‡Ì†;µïÔ¾S6^ØxaãH»v!í =tôÐѸ:puàjN N Nm¶=Øö”••ÁÞÏÞÏÞâ¯Ç_¿Ñë£×G¯ÙSÙSÙS¸ÓáN‡; ý\ú¹ôs Ï•çÊs!îhÜѸ£Ð8¦qLã8õñ©O} åœÊ9•s‚TÿTÿTPÌVÌV̆³ûÎî;» 5 5 5 sræäÌÉ›››¦`S°)2¯f^ͼ &k“µÉ,4‹—¬Îú¼ñóÆÏCþ¢üEù‹À0Â0Â0&LO§?þt:(†+†+†CT—¨.Q]ÀuªëTש`1Àb€ÅˆéÓ'¦tŠéÓ)6žØxbã X^ny¹ååÀg£ÏFŸÐhQ£Eo´o´ï»kÿÅH µ©ý…ÿK™› ðÚ…k®]€ù;òwäÃ’°%aKÂ@a¡°PXüööRû¥öKíó´ó´ó´¼5xkðV¼cðŽÁ;Àþ=û÷ìßûýy >2|âDq¢8,ü,ü,ü@Ÿ¨OÔ'‚p_¸/ÜE±¢XQ %ãKÆ—Œ½“ÞIï¶É¶É¶É`©²TYª $£$£$tqº8]X7±nbݤô¦™¢õEë‹ÖƒÕU««VWÁî„Ý » Þ©Þ©ÞY:ô¬ÈVd+²AV]V]V®G]º :tADágG•è%z‰^PîT¹SåNAõ‘ÕGV ÄC Èäò°¯h_ѾbéÍF?Î1¿û»Ýßíþ´nкAk¨|§òÊwJÛ×ÌÔÌÔÌ•µÊZe ²õ²õ²õ`/Ú‹ö"Èãäqò8ÐVÑVÑVâÁŃ‹ƒrrrX}`õÕP¼¯x_ñ>ÐÓÓ‹ví,ÚuEëŠÖA=F=F=¦tÈÑf¾Í|›ù ¹¬¹¬¹ â)ñ”xêÅ÷=›Y )ÖkŠÁxÂxÂx¢öGíÚYÓ²¦eM¡›ÐMèö³ýôÃ7&ûnöÝì»AHnHnH.X]³ºfu ¬tV:+Ø8Ø8Ø8€f®f®f.¨º«º«ºƒ"@ ûûûª Õ„j°6}múÚt000€·Þx î~¸ûán?cüŒñ3à³ ŸMøl¨ê¨ê¨ê”N<ó“,²ÈY‰¬DVÁí‚Û·÷î;Üw€±¯±¯±/°šÕ¬…ÂGáΓœ'9OÁ^°ìýñŸ5(kPÖ X5tÕÐUCA§Óét:ø$ü“ðOÂÁa­ÃZ‡µ¯ìÏÃ߆a§a§a'¨BT!ª0¶3¶3¶‹Š-*‚ò†ò†òDI ŠWÅ«âA›ªMÕ¦‚â ÅŠ7ÀtÚtÚt¬åÖrk9è;ë;ë;ƒÞAï w«YV³¬f¸R\)®½‹ÞEïÖßYgýÈÒdi²4(ªYT³¨&X‡Y‡Y‡x]¼.^CSCSCS»È]ä.`t6:Á¢‚E‹ `ñ¦Å›o‚ê‚ê‚êX´²heÑ ìfØÍ°›Üç>÷_ÒÿO Ÿ>âÅ#ŠG”åÛæÚæÚæÂ‹ùW@«ÕjµZ°¬bYŲ ó„yÂ<ÐÍÐÍÐÍË>–},û€­ÂVa«M?M?M?PTT¹£ÜQî¶wmïÚÞ‹mÛ,¶™ûÓuÊ\pfÑ™EgÁÉïO~ò{˜¯Ÿ¯Ÿ¯Ù=Ù=Ù½ßßnò…ä É`徕ûVîí¿´ÿÒþ Þëô^§÷:Aõ¼êyÕó@ð<„_ñÍêïÂØÄØÄØ’|’|’|@›¢MѦәÎÏŸ®øášÝ9»svçÀë[¯o½¾y_y_ùKÖ^ØÞd{“íM@ÛWÛWÛ”¹Ê\e.ô°éaÓÃd“d“d“ÌÝû_OüJüJü RW¤®H]EQEQEQ œÎ ç~¶ár–³¼ô„_áD…N”Þ;ñ{ÍÚ=k÷¬Ý k¥k¥k]žuyÖå<øâÁ¾€‡ýö{ØFÍ5kÔ,Ðn×n×n1MLÓ~ÖP %”€pA¸ \“‡ÉÃN+œV8­øãûéÇâÆä“oL†o;øÛÁPéJ¥+•®ÀûÞŸðþp^å¼Êy•™>L‰äW3)MJ“£É@‘ªx…7ƒþQe®8rñÈÅ#áF„ 0k³æ‚ðDx"¼‚9¹U_©¾R}{Çì³w œÜ~rûÉíP§Cu:@wßî¾Ý}¡¢[E·Šn <ž OͽW^?×]t}ä~šûiî§ÐÌÐÌÐÌ5j:ü–§6$äìÌÙ™³îV¸[án0­3­3­Ë©–S-§BÍG5Õ|.Ý]º»ü…‹ï‡‡‡@LŘŠ1!üãðÃ?†¸Ëq—ã.CO‡ž= ÝúvëÛ­‹ï,¾³øÎÜ{ó0¤RöïÚ¿ ÀgªÏT€FªF*sg“¼:ª-ª-åå!ï…¼Ð\Ó\óGÚ}µÊ\°/x_ð¾`ˆºu?ê>LO™ž2=Á_xÏñÿH\ .@üÖø­ñ[awÝ5v×€‡Š‡Š‡ чèCôжQÛFmAP“ &AMÀ¢±Ec‹ß0QŒDòw¢}Sû¦öM¸»ïî¾»ûà¤ËI—“.ð,ìYس0hÞ8¼q8tóîæÝÍÊ·.ߺ|kJïbÿûû¡'§ŸœW9®2À°”a)ò‡ò‡æŽ(ùã22ŽZµ«V ÜùrçÍ­T™+v^Úyiç%Hl›Ø6±-|²ù“ÍŸlÞæmÞþóÞ×xÁxÁxž5zÖèY#8µåÔ–S[àîÔ»SïN×q®ã\ÇAÓ M/4½µ»×î^»;xÇ{Ç{ǃl¾l¾l¾¹÷žDòëzzzAüàøÁñƒávÞí¼ÛypÝæºÍuÐL×L×L‡Æo4~£ñz?ô~è}ðiàÓÀ§«„UÂ?zˆ_œ NÐE뢬ܭ^LÀ$-ÎõÏ âňNº°‡=8à`îh¥Ê\°¥ú–ê[ªCÖ̬™Y3a|¯ñ½Æ÷2Cn~Ëú$듬OàFñâÅp=ázÂõÈpÍpÍpÏÙž³=gC½.õºÔë57ÕÜTs”ïV¾[ùn`gmgmgmî½*)s6³™ÍP´´hiÑRHÍNÍN͆»–w-ïZBäìÈÙ‘³!§^N½œzàìì M*4©Ð¤ÔßUWý]àø/Ç9þËÜyeMÌš ^ ^à•ï• pQ¸˜;[YT¸¿p?À“ož|PuQÕEÊ*Ê*æÎöÛ•¹`ý¦õ›ÖoM”&J£–ŽZ:ê5z|Èl6CF—Œ.] âVÄ­ˆ[p÷‹»_ÜýÒ+¤WH¯¶ŸÚ~jû)lذ‚š5 jAõ‚êÕƒòËo,¿,ß±|Çò²ðJò*™všvšv‚öíÚ %<%<%ž|ýäë'_ÓOj<© ‰ ‰ ‰`ØdØdؾn¾n¾nP{DíµG@]»ºvuíÀu¨ëPס ÷’{ÉÍ8ñÉßÏÕçWŸìX´cÀ(×Q®U>­ò©¹³•EG3f\x÷»’'$¸ßsÿ7‘›K™+VèVèVèÀâ‹O,>÷—¾¿ôýרø%¦ý¦ý¦ý]=»zvuHHH€ûïW¼_b'ÅNŠ9×r®å\›$›$›$(ߤ|“òM à«€¯¾‚Š+N¬8Êo(¿¡üðððððð›{6÷lþ†°ä7ºÃî@ñÔâ©ÅS!ãbÆÅŒ‹Q7£nF]HpKpKpƒ¸¸¸x>àù€çÀkÈ5ä‚Ç2eË ð|àùÀóPsWÍ]5wïw¾ßù~΂³à,ðÓc€’?ÊxÙx Ã.ÃÀ¹ƒsÛ4Û´—m¯©®y1‘×<æXw±îbî>¼Î^L9×s®8õrê`áoñÒ{Š+W²…l;•ÝßøæÍ2W,þtñ§‹?‡ÆC—\:ðoPü¢Ëû‹ýÅþóQÎG9Aü—ñ_Æ Ž Ž Ž[+¶Vl-x^çyçu dTɨ’Q h¤h¤hT:QŽÇuë×Ák¿×~¯ýà'÷“ûÉÁµ®k]׺`sÆæŒÍ°l;Ùvriá ß+ß+ß Øa‡¹wÊ?XD€>H¤µ\-WËA=G=G=T‡T‡T‡àyäóÈç‘x6ñlâYHMM…ço?ûùÛ÷}Þ÷y߃8Oœ'Îûö=ì{€g¬g¬g,Ô¨PüÞö{Ûïm¨Ô©R§JÀÑÊÑÊÑ ˆ%–Xsï É:›~6à芣+F,±À_í¯þ#íþS <p¸ÑáFò'äøö9lîl¾2WÌ­2·ÊÜ*´(hQÐ"èÙ¥g—že BˆÄ Qj”%¨>T}¨úR¥4JiIÑIÑIÑœœ éƒÓ§†¬>Y}²ú€îMÝ›º7Af-³–Y—.*bßÚ¾µ}kp÷s÷s÷×O\?qý>wøÜáspôwôwô§IN“œ&ó]ç»ÎwÁÉÑÉÑɬ.X]°º2­L+Ó‚ÌOæ'ó+H¦”)eJ† Ã…á  ABЉNüŽ©kÿ4KXŠŇ`úØô±éc0å™òLy`J5¥šRÁoŠ7Ńé–é–é¨>V}¬úòšå5Ëkùóòçåσ‚zõ êAÁÞ‚½{¡À©À©À rss!ëDÖ‰¬PÒ¹¤sIg0:Ž Îg‰³Àú´õiëÓàñ±Çǃ§§§§§'xúxúxú€oC߆¾ Ás›ç6Ïm¥¨XeYeYeQ:E´äo¦äƒ’¢ý£ýáÅ$×.=\z¼lûçªç*€‹½/ö¨s¬Î1€ÊÆÊ/Ÿâ;žxñ²x@ø^ø€Ã¼Úæmnˆ«Å#I/Ö0@˜"Lyéöá„\lr± @f§ÌN,:XØÜ°¹ñ²—¥%§%èëx·ðn Ÿ!ŸñJûóZ*3S›f›f›fƒz±z±zqéjRtùé.Í4¡‹ÐEè6Ø`ØÄØÄØÄ€+®¸!„òóD¨³ÕÙêl(lPØ °Ÿ)>S|ŠfÍ*šY1Y1Y1Z/µ^j=Èž7P®T®T®/w/w/whP®A¹åÀm©ÛR·¥ ¼§¼§¼ÊÏ”Ÿ)?‡.]º€Õ`«ÁVƒ¡ eèKŒF4âL0$yݼXÝêQïWmoL4&¤·Ooà³Ëgðÿ¦Ö/¥uѺ@é= òyòyýmúÛÈÔ²—Ž4$%<| P'³N&€«Ÿ«ß˶ÏÊÏÊØQ´£ x~ð|€7‡¼9@ð<ÿíŸó9@Î…œ ú} €PK¨ÅáåãåÀÎPæ”™CKCKCKø´ý§í?mNv8Ùá$´<Ûòl˳æN÷¢G˜À&”.’c¬i¬i¬ %·Jn•Ü‚¢”¢”¢(9Yr²ä$¨««ƒzƒzƒz¨Ž«Ž«ŽƒÚBm¡¶Ý1Ý1Ý1ÐÓÓmymymyPŸPŸPŸÍZÍZÍZ0l3l3l½^¯×ë!kFÖŒ¬pÁpÁpÁ-Z8´pÛ¶;mw‚X]¬.Vù—ò/å_‚E‰E‰E J*© è¦è¦è-&ZL   °ncÝÆº ØÌ´™i3,çZεœ –C-‡Z«T«T«T°icÓÆ¦ ؄ڄڄ‚mÛ6¶mÀ¦³Mg›Î`;ÅvŠípXæ°ÌaØZÛZÛZ—Ž´ÁB° Œ`¯`9a‰äÜáÅÔÚ:^¬îÙ˜—ÎGbØkØ pµÓÕNbU±*À¿Âÿ «#{éš;²vd¬m¼¶1À†¤ I•õ•õ/Û¾ðXá1€ë箟ðîìÝ ÚÇÕ>à·þí?®nøããw¶¼X}ñÅ*„’—*3€®‡®‡®L´˜h1ÑzÓû›Þß@S›¦6MmÌNòÊü¸,© ˆôŽôŽô†uÖXw.Z¸há"PUU-]œHØ%ìv%d Y?k¯?ýéÿ³%Éïð°ÕÃV‘]#»ô]Õw€ü‰üÌÀ*ù}ÊÌ%1YL“Ax,<ƒ|‰|‰| 0•©L5w:É+óÉÿGñµãkÇ×PPP°/°/°/(ýýË”Ót0wx‰äŸ*xrðd€À?o”o4w&‰ÌÜþ*¦1¦1¦1`¼a¼a¼²²2é&§¼··7ðòôòôòüãíI$’ßCÞNÞÀò±åcšÑÌÜ™$e¦OŠ'Å“ ,– Ë@¶D¶D¶ÄÜ©$¶Œqã2ÆW]¯º^uÍF"‘H^e§Ø#î÷€i­i­i-ÈöËöËö›;•äÏ¢ª¨ª¨ª¹Ñ¹Ñ¹ÑP±uÅÖ[›;•D"‘¼>ÊL`šhšhšÌb³@6G6G6ÇÜ©$–ÌØÌØÌXÐêõà¥öR{I¡H$f’´*iÀ…öÚ˜"M‘æÎ$)3€øT|*>å§ELdÏdÏdÏÌJògÉ=:{4Øî¶Ým»lFØŒ°‘£“HÌ$黤ïÎ;? ÀtÏ$M=nveæ)ÓÓÓ0µ0µ0µy]y]y] B ÍNòªeÞμyŽ GXhý¡õ‡ÀZÖ²ÖÜé$’²¦ö°ÚÃÞ x@¡T(Ì`sg+»ÊL Æ‹ñb<‡„CÂ!õ—õ—IÏuÿc%´Lh™Ð¼ßò~Ëû-·’·’·2w*‰¤¬RQùù¿’×AÙ¹0[œ-Σ§ÑÓè B+¡• þqŒÑÆhc4¤_L¿˜~¼y7ò–¦º•H$’ÿPv €t1]L/]ýŒ (øÃÍJ^3úÙúÙúÙß5¿k~Wð˜è1Ñc¢¹SI$Éë§Ì‚L 2À ,ÌFòg)ÙP²¡d¨¬UÖ*k('/'/'7w*‰¤¬ÓtÔtȽœ{®ý¿ÊL€øÃb8àXcµ¹CI^µôö/V5S8(àÞ˽—{/s§’HʺÛooXýñê ïÞ1w&I™)Ä(1JŒE_E_E_È dÒ%€œÔoS¿Mýœ:;uvê 6J¥ÒÜ©$’²Î³™g3€ºWê^“3w&I™)xÆ3žüˆüˆüȾ’}%ûÊÜ¡þ:†C¡ÒW¤¯H_ùkó׿ÿ‡Ë¨•Q+£¸ãŽ; Ôêuþp³‰äñêÿà-«·¬d³e³ÍIRv €©Q£¦tÝú¿Ø­Ž·:ÞêW¢¯D_‰B %ôÏßsžç<ÏyÂÖ°8ÝòtËÓ-áöíÛ·o߆k“®Mº6 TóUóUóáÔ¤S“NM‚ýWö_Ù à à Ãÿúýõ[¥L™><çxÎñ”fz”H$’_Tö 3Kn›Ü6¹-$$'$'$ƒ¸Z\-®þõ¯×¨4* Òj¥ÕJ«´¢ÿåqFÝÝÝ_¾(|4šÑhF£ÐzZëi­§Aâ–Ä-‰[ ¡mBÛ„¶`3Ëf–Í,Èl“Ù&³ |»üÛåß.Ý{º÷tïANýœú9õ!_ÌóEsïÍRÚ.Ú.Ú. ~?ƒŸÁÜ©$‰äõUf&úõ¨G=oŠ7Å›Þ%½KzÐ××—î.Ý]ºƒC¬C¬C,0ỹÜ~¹ýrûAÑÇE} âNq§¸\÷¸îqÝ%”|PòÈÈÈ€©©©ض·moÛšÞjz«é-0›ŠMÅ JV%«’!§CN‡œ //ÆcŽ1\Žºu9 Ê}Ê}Ê}püäñ“ÇO­ž·zÞê c¢ÇD‰·ûn÷ÝîƒPK¨%ÔÚІ6³4giÎRˆ;w.ªªªª‚õiëÓÖ§¡™¾™¾™Lz“Þ¤A#h ¸Ä¸Ä¸Ä€¬ž¬ž¬Á*ù*ù*9ÔíU·WÝ^V-¬ZX5°Üj¹Õr+d®Í\›¹Ô>jµ¸œq9ãrì‚í‚í‚áùÏßxþXܶ¸mqLßš¾5} ö5íkÚ׃ڠ6¨Áeˆ2D‹¯‹¯‹/0ŸùÌÿ峨±Ø±ØTsTsTsÀ-×-×-×Ü™D"yÁ„éÅ¿wMwv ; 4w¶²«ì?Üý/;/;/;‡ìÙ²ƒ [.l¹°|‹}‹}‹Ák¦×L¯™Ð³jϪ=«BäÕÈ«‘WaOážÂ=…P9¾r|åxH´M´M´…:ß×ù¾Î÷‘‘‘ Éß$“ü Ô^ox½á¼"xEð Hذ;a7\¼|ñòÅËðÉŒOf|2Æí·oÜ>hóe›/Û| •,*YT‚Üþ¹ýsûÈ3#ÎŒ8g£ÏFŸ†˜1-bZÀ“EO=Y.^.^.^ _,_,_ ¦¶¦¶¦¶è’è’è9-rZä´€¨žQ=£zBíÚ!µCàÔÑSGO…k+¯­¼¶6MÙ4eÓ…D!„]Â.a¤^M½šzŽß;~ïø=PÔWÔWÔ‡úƒêª?ââââââàDË-O´„òÃË/?²S³S³SaxÎðœá9ðUׯº~Õr–ç,ÏY!Y!Y!YP{oí½µ÷Âãk¯=¾ÉÆdc²fœ9pæ@P ø¯k±¶X[¬±™ØLlŽFG££H%•TstIY÷´ÞÓzF<Ðmn·¹²8Yœ¹³•]e§°ÄK—‰ËÄe€-¶ØÂ…E]XÚ/µ_j¿„> û4ìÓ …B¡ÃdÃdÃdØ8uãÔS¡î³ºÏê>ƒÁ÷ß|RÆ¥ŒKúúú OÐ'è!sbæÄ̉0ðÐÀCE‹€E,bq=âzÄÊ)?¤ü°i5Òj$4ŒiÓ0Ñø‹Æ_À`§ÁNƒàñ'?yü T¾RùJå+ h¥h¥hÍŠš5+úÏîÊ&É&É&AH¯^!½Àk‡×¯•³*gU΂gÍž5{Ö N}pêƒS€h#Úˆ6@ $€8H$¿H¿H¿H(÷¼ÜórÏ!´ehËЖPa~…ùæÃg ?[øÙBèà×Á¯ƒtÜypçÁ0(zPô hx|âñ‰Ç' üíò·Ë߆¯¯/xgí;kßY âuñºx*¨t ÒÐxj<5ž o(o(oø¿?Þì³?Ìþ,¶[l·Ø¡¡Á½‰ä×(²*²H½Ÿz@tÍIRv €BÃÃÃ0F#ŒÐË£—G/X¼rñÊÅ+aäᑇG†¾î}ÝûºCûík´¯)>)>)>Ð¥S—N]:•6ë½Ä{‰÷’Òÿozjzjz 6mÛ4§·œÞrz‹#`&~º=]Ø$l6ËYÎr~™/‰—ÄK`]Ùº²ue°‰·‰·‰‡,ë,ë,kµ“µ“µqš8Mœö+úýãÄGÇ9Îqà׸Ìe.s)!Œ0€ÛÜæöÿnG<$±‘±‘±$^L¼˜xnl¼±ñÆF(Ì,Ì,Ì!LÂ@þ©üSù§ 4š ÍÀömÛ·mßÇ›Ž7o–¾S7§nNÝ~ûÇ›à™à™à åüËù—óÛDÛDÛD³q‰ä'5ËÕ,Pybå‰r¹\š ËìÊL \® WAØ*l¶‚ñ{ã÷Æï!0(0(06 Ù4dÓ¿~+ü,‹^½,ÞØüÆæ76ƒò]å»Êw¡PW¨+Ôý—7úa¤v´£ÝK~ÿã w%+YIéój=éIO&„ `êdêdêÚ m†6ìOÙŸ²?™2d³˜Å@ozÓû¿äÑ¡CÂa€0ˆ'žø—ìŸÕÂja5Ѓô ´`YÆ2–Dìb»€L2Éa†0C˜ÎíÛ;·‡†£Žj8 Âv†í Û ={&öLûÇöíÃ-ñ–xKs˜Ãÿ™C¢ ц€©’©’©Øl·Ùn³ŸFl~IúÝô»éw¡¼oyßò¾f9Ä$É/²ÚoµÀ «?XÂ’?Мä•(3OÈ>•}*û„ B¡ˆÞ¢·è ûî컳ï\œqqÆÅ «)«)« UrªäTÉå)å)å)èZܵ¸k1\H¹r!ÎÆŸ?‘±‘±‘±ù óAæÈ>™}2û$dŸÊ>•} c c cÀÔÞÔÞÔR3R3R3 Cþ†ü Y1³bfEÐûëýõþÝ1ºctG88÷à܃sÁù ç/œ¿€zwëÝ­wœ>rúÈé#ˆ½{7ö.Ü(¾Q|£ŒmŒmŒm~ÖáCâS}J¥ƒÒ&.˜¸`âðxÓãM7!ìNذ;à8Òq¤ãHÐkô½xÎsžÿ¬¿yÌclÁÆåË—ž.ž.ž. Þ©Þ©Þ U×V][u-Œ >*Œ;;;¡ÚØjc«…Q_ŽúrÔ—`3Ãf†Í ˜æ>Í}š;ÄLˆ™3 û û û` ï@ß¾q-âZÄ5(*)*)*«3Vg¬Î€ÖVk«µ…ö¾í}Ûû‚&\® Ãdž —Ænº§éž¦{ ¤CI‡’ ?*?*?úË«f™f™fä¨sÔ9jð™ã3ÇGzþ_"‘Hþ'Aü¹ƒüÙ ?)ü¤ð˜ºcꎩ;`¸ípÛá¶P3ºftÍhóå*©WR¯¤ô|»çÛ=߆ñúñúñzh3µÍÔ6Sͽ×^)}Sú¦ô…ëg¬Ÿ±æ?šÿhþ#ðhèÑÐãWÜ<(‘Hþ 9696™þ™þÁ‡ ›;[ÙUf.k…µÂZ0ùš|M¾`R˜¦×`ü#Ù6Ù6Ù*XU°ª`i Ò¤5ÃJÃJÃJs§{ýe É’5lŽØ±9vvvÒÉkæqÓÇMv­ÞµÀèl”ž0»²SÌæs@^,/–ƒé¤é¤é¤¹SAÐÌ ™A3aý±õÇÖƒ]vØ!ŠEˆ¹Ó½þ²’³’³’Á¾»}wûî`=Ýzºõts§’H$ÿ®Jd•H€. º4—7w&Ékðø¯ñã„6¦|S¾)L‘¦HS$à…^fÌÕZh-´ZÓšÖæÞK?I±I±I±àõÔë©×SP\W\W\7w*‰DòïÊå”Ë(G¹?ØÁsg’”`¼0^ò•ò•ò• ˆâë0T<žñŒ‡øòñåãËCž6O›§…ZGj©u×××ÌòõcJ6%›’!õZêµÔkr7änÈ]à(G9úG[—H$’¾²s X‚Á´ß´ß´ŒaÆ0c˜¹SAôèèÑÑ£á›YßÌúf\­}µöÕÚ B…êW¼>{xöðìáðU÷¯ºÕ¶lØ`î^ýùô³õ³õ³!÷«Ü¯r¿bbbs§’H$’¿2SȲdY²,EÉ¢dQ`zßô¾é}s§‚kS®M¹6Ô½Ô½Ô½`°Ã`‡Á ¡¡ñ¿_ï¶ÎmÛ:(¹Sr§äÜly³åÍ–æîÕŸïÇÇ.K• *Ï=ž{<ÿãíJ$’?ƒ©ÈT/æb †sg’”@&“Éd¥7×éºéºé~Ç”³¯Šj¹j¹j9<^ðxÁã\\\i)i)i) †‹áb8<òäÿÈ.'\N¸œÃ"†E u#u#u£Òö¬|¬|¬|@vEvEv¥ôç)ÇSާ‡++®¬¸²"zEôŠè%'JN”œ(Ý.Gž#Ï‘ÃõÐë¡×Cá¦ú¦ú¦ŠÅŠâ×ðBQZ½´ziõ@¶V¶V¶Êm)·¥Üs§’H$/ùYägkÚ¯i`üØø±¹3IÊN K%€¥`)X  ]£]£]c¾<†Q†Q†Q ËÔeê2AwCwCwÔ#Ô#Ô#@»N»N»Ž·:Þêx+È;!wl<·ñÜÆsÞ&¼Mx›ÿlWh%´ZA®³ùÌb®Å\‹¹‘§#OGž†ô+éWÒ¯@Á„‚ `±j±j± †> } gcÎÆœµóÖÎ[;ŒþF£¿ùö×ÿ—23efÊLp~Ëù-ç·À.Ó.Ó.ÓÜ©$ÉËY¾kù.€Ã ‡ALd¢¹3IÊN/‹—Ń¥h)ZŠ Ù¦Ù¦Ùf¾<2™ƒ |}}Áw†ï ß’’’ÖyÖyÖyÐçAŸ}@Ç®»vì •ÄJb%îº;èî —4¼”¥,ÕÕÕxØôaÓ‡M\p®[»níºìììáa«‡­¶‚{ìy°º ì2°Ë@hÚ,´Y(œªwªÞ©zP¸¡pCáóí¯ÿ/mSÚ¦´Mà~Ãý†û : „N¼]‰Dòg¨>½út€¾}-äNr'sg’¼†ƒ»aª0U˜ ––– ½®½®½Néâ7æ’K.¹ Öë‹õKœ¼5ykòVØ•¾+}W:8Ìt˜é0noº½éö&ð™à3Ág?Íùÿ#qŽ8Gœž=7zn„ ·&Üšp v÷ÛÝow?84þh>ûø,¼ÿìýgï?ƒF_4ú¢Ñ &‰IbÒÏÚ±Ç{n7„ m¨m¨mu—Ô]Rw l~¸ùáæ‡àpÉá’Ã%8øÖÁ·¾N{ö:í… ©R+¤B¯£½Žö: ãúë?®?|‘ôEÒI ŒTF*_ƒ¿ÚEí¢vô–é-Ó[‚ŒŒ¿t3‘D"‘üfefàG?®Ö«}¤}¤}Ô¤&5ÿú%gKΖœ…¤Ô¤Ô¤TH•§ÊSå””¾u|ëøÖóÏÏ??ÿŽÜÍÁ&Î&Î&âóâóâó€ŠT¤"ÈkÉkÉk_ó5_ƒ»µ»µ»5¸wvïìÞ… ÌX6FM4°Ä‰ÿX¸ pA 8Ÿp>á|â7/‘Hþ)ò9@B«„VM¶7Ù +'+gîleW™+6ÜÙpgÃPŪbU±0º×è^£{™;•ä×:~,üX8\8záè…£0ï£yÍûdõeõeõÿxû‰äÏpuÉÕ%çMçM“ZLj h h`îleWÙ»cc…Ó §NzÑ ©øÛH(J(J(o…·Â[!ø%’¿‡;jìð¾í}@ž#Ï1w&IÙ» ðŒÕ«3 ›®›®›¬f5«ÍJòk¥mNÛœ¶¼W{¯ö–>7‰äoÂ!Â! ¢©¢ @p¤å€Í®ìvVvVv  Ó†iÃ@ôýD?s§’ü/Å·Šo߂̭™[3·B@ý€úÒ7‰D"ùÝÊ\`}Ðú õA0  Ök‰µÌJò¿d,ÎXœ±ŒÇÇǡ¢ ‹*˜áæM‰D"ù§(s€åW–_Y~º]‰®¨K]êš;•äI·K·K·û¡öC퇂]»vÒcÉßDÉÆ’Ï«<1ÿJ-¤/^fWæ «`«`«`ÐöÒöÒöÑWô}ÍJò¿Ä5Œk×¼›x7ñnV:+•ÎÜ©$ɯsÐýA›‡n `8f8fîL’2WX°`=ô½F¯±®XW”FÌï‡üM-M-M-/¼ðÓÓӈ߿+~T^QyEåæ+‘H~›òóËϨV' @vPvÐÜ™$eî1@«»Vw­î‚Þ]ï®wSSSs§’ŸŸŸÂ¦üMù›ò!õpêáÔÔ””1-bZÄ´€FµÕnTŒAÞYÞYÞÙÜé%É %ÕKªDΊœ Z¨Z +’Èä gΟ9 :ˆ>>•*àƒ¹ûòÏWæ ëëÖ×­¯ƒÉßäoò­ÖGëS:E°ÄOŸ§ÏÓUÓUÓUà!y¶ù¶ù¶ù ¼¦¼¦¼®]ºßS¾§|OçUÏ«žW¡ü½ò÷ÊßÏ‘ž#=G‚ínÛݶ»†4¤¡¹? ‰äÏ"îwX~gù€ÍE›‹/Û>'>'`e••Uü ~€þ–ý-äZ¹öß^PH!À¡§‡žÄôéP;°v Àã 7|øö‡oÈÏËÏÄëãõkŽ®9 öiا-µxé½>ªîªî»–îZ `ÿ™ýg].w¹  x¦xfî}ýú+s÷-„B °Üe¹Ër¨+©+©+™;ÕŸOÌsÅ\(®Z\µ¸*dÔȨ‘Q¢NFŒ: Ñ!Ñ!Ñ!Ú.µ]j;ЯүүåUåUåUp™á2Ãeø¤ù¤ù¤Aµ¡Õ†V N›œ69m'''pNvNvNå`å`å`°ªmUÛª6]„.Bv »…Ý@?úѨHE*‚ÐUè*tñxH<yyy`gogogò&ò&ò& n7ŠAWOWOWŠ7(nyyyPм yAsÈ7 o<{ö< b¾ù6æ[¸Ztµèj”Ü,¹YräoÊß”¿ ž O…§ªÖ¬Z³jM¨q¹Æå—Á3Ë3Ë3 î:Üu¸ BO¡§ÐÓÜŸ¦Dò{E‰°¡Ó†N}?èûÀ¼ñÒííÙ/x;àíÇZ޵ä'ä'^ú:µíÔ@|(>0T0ThTÔèÅŒ€½ä½~þ²JC* ˜Ÿ9?@øHøè¿õC1Q1 ’g%OC-ËŅÒIÿo¯»r3  £  Ù¡f‡lÚ”Á¿Ìüh¥×J¯•^`1Ñb¢ÅD>vøØáÿ„çPW°‚PìPìPìj=¨õ D" xòÍ“ož|†C„!<¿õüÖó[¨Ú¢j‹ª- JA•‚*àý¹÷çÞŸƒrrrX9X9X9€pG¸#Ü1w';qž8OœÚrÚrÚrPbWbWb©bª˜*BÌØ˜±1c!ºFtè‘‘2™‹Ì[¶ l R¤6H…šÖü°æ‡àpÃá†Ã ` X`î^JÊžœé9Ó­|´ ú‚ê \†¹ {ÙöyEyE¹ýrûTØTa€µ»µ»¹ûòW¸PéB%€ˆüˆ|€m´(^>ÜÜÙþze¶ø®ïw}¿ë ÏO>?ùü$ŒÏŸ3>ÇÜ©~;S?S?S?ˆõõõ‡‹\üàâpË÷–ï-_Pø)ü~P}EõÕW@á ‡6 ¾ù~äû¸|ïò½Ë÷ Üî ÷ÌÝó‰ÇÄcÿMþ7ùß@âèÄщ£!"'"'"¢ÞŒz3êMÐ^Ó^Ó^ƒº·êÞª{ š5jUTYPeȯɯɯ™»7’¾ÓgNŸ¸øùÅÏÞ|? BA…sg{‰ßŠßï ï`Äø²ínö¸Ù ýNú€Öï·~@9Y9ÙÜ}øãÊlpÄûˆ÷o¸1âÆˆ#`f§™fvYMYMYMs§ûe†Ñ†Ñ†Ñð¨Õ£VZÁÁ÷¾ð}ˆ;?v>TVuXÕaвzËê-«CÍ5Ô\6ímÚÛ´dÈÊÞ­Ÿ¯Žæ‡{œF?Œ~ Æ_a<c=ìuÛë¶× ®·¼ÞòzKèÛ!¶C,t íÚ%¬ ­ ­ ÍVòúˆ_¿àéŧÞøäOìkÚ¿Æ#“ƒ£Á`·çnO¿¿€Fg ¯áM†e¶¸wõÞÕ{Waì ³6Ì‚yOç=÷ìãìãì͸*UþìüÙù³a]Áº‚u»(vQì"viØ¥a— žXO¬'‚ÐRh)´4÷^”üOKX¸¿éþ¦û›`nn< = = áà Nøp¸Mp›à&ÍG!‘üM//œxr @æ´ÌiÏ< Û&ÛfîŒÿ©Ì^ ¶­Ek — — —Á`c°1ؘ/OþðüáùÃañòÅË/‡âÅ‹7œªsªÎ© õ[ÔoQ¿…tâÿ­L L L @;A;A;Ä‹âEñâo÷WÇ8ÆA­µÔz³·ÏÞ>{;ȪʪʪÂÛ¶ l!Û!Û!ÛÁÜ{KòçË¿‘@÷¦îMsgù0a†þ†þ†þ ‹ÐEè"€Hø+ƒÈ›Ë›´¿Üþ2@ÿ¯û ¯ë‰ÿGe¶° ³ ³ CCCóº9º9º9°®ýºöëÚƒm;Ûv¶í`⬉³&Î÷'îOÜŸüïvŒ###!:(:(:îÕºWë^-0ùš|M¯àÚa±g±g±'DµŠjÕ 455!MŸ¦OÓõÍ×6_Û ù±ù±ù±¿ÜNÑÝ¢»Ew!ªNT¨: }¤}¤ýõÑ~¬ýXû1쪼«ò®Ê°ø»Åß-þâ†Ç »<ìò° Õ.ª]Tr«æVÍ­ ×ß½þîõw!}Wú®ô]¯>—K}—ú.õaìÙ±gÇž/¥—ÒK «¬Z°j¨k¨k¨k¼ú÷•˜[Êê”ÕŸWû¼@ÜŒ¸¿½UgUgUgˆÐDh"4Ð2¡eBËW—2mHÚ´!ðÔö©íS[Ðí×í×í‡'›Ÿl~²n¸=âöÐ_Ô_Ôÿ—B:Í6Í6ÍžZ>µ|jùâʸø'Ü4—1>c|ÆxX³wÍÞ5{aýùõçן‡Ìa™Ã2‡ÁÃj«=¬Z£Ö¨5BâÑÄ£‰Gáúþëû¯ï‡’+%WJ®¼ÊD‚à ¸¯¸ÿêûûªý_{÷Eµ÷qü3»Én’MϦJB º€éU^A¥ ˆ‘"ˆå"E¥H“* Ò!ô"Uz/¡†$„@éÙlʶìîó‡záQ¹Š{¹9ïx½6“9¿sfÂ~wgæœRbbbÀüŠùó+`}|úøô@C !ЎÇ9Ö²–µpÆýŒûwX¼2xe0’ I†$]º(tL¸?áþ„ûàââ&“ƒÉŒ?4~ú$}’>éçÈ ›Žt¤ã_ÔüÔüÔ|ÈÛ·;o7× ®\‚ׯ ^ã_ÿúø×!âZĵˆkà³Âg…Ï poäÞȽX:X:X:<ÜŸ5Ök}]}]}]0¬1¬1¬bˆ!æïŸÎ;ìü1¼ñào<€Ã£:< |pðÁÁçp" ÏI`¯À^­Þoõ>€½ÙÞüä{qºítÛé6¨•j¥Z Æ·oßccc0l4l4l^åU^ÓVÓVÓV0Õ7Õ7ÕkµÀZ¦ö¦ö¦ö`zÅôŠé å(-Ç·ßr< ,;°ìÀ²àÐÛ¡·Coñ ñ ñÉ_ò—üÁ¼Ë¼Ë¼ ÖE¬‹X¿=øíÁoÁºÎºÎºZi5¦Õ˜Ÿg%x$GÉQrc}c}c}0Ž7Ž7޽J¯Ò«ÀTh*4>ùxĈ?#Œ0oÞ,¼ÔªZ«j­ª0¦`LÁ˜pè6Ðm '''ýDû‰öùùýGîÒ7¯4¯4¯|¸Jl‰ªDU¢J(¡äiœ§sOçL•O•”|QòÅS<ÍžP©› øWNr'¹“':Ntœ9Ós¦çL~íŸ3œ3œ3€ª¢ª¢ª"DÞˆ¼yã)ìxÛØY5³jfÕ„­Ã·ß:¿úþj(Û¶lÛ²m¡ZrµäjÉ0Û~¶ýl{Ñ}D÷ÝÁþ{ûïí¿‡/{ÙûËÞ0j¨ £&€}Sû¦öMáË_ŽørŒœ6rÚÈiPij¥©•¦‚”)eJ™P8¡pBáصo×¾]û þõø×ã_‡ R©‚5ðö·AsSsSs¢VF­ŒZ 'Ê(w¢ômÞ·yßæP‡:ÔùÝ/h]к 5\]]ARó¤æIÍaOù=å÷”‡¨³Qg£ÎÂìe³—Í^¯¾Zøj!´£íÙ4@ k¸5Üvlرa$WJ®”\ Œ¹Æ\c.¼2õ•©¯L…F4¢Ñ?8l“#&GLßßß8ÕàTƒS  èô|NIábee·Žß:~ë8¬ö\í¹Ún¿~ûõÛ¯CÓð¦áMÃ!ghÎМ¡°ÑþEûÁ¿öükÏ¿öÀùù9Ú|hó¡Í0¹ýäö“ÛÃóÎ8‡:ê|¨3|üeð—Á ¹In’ÛÃS¥4JiKG,±tD6‰lÙ###àÆ¿nüëÆ¿àH¥#•ŽT‚¡aCƆÁŒÈ‘3"!*"*"*¨Le*CjßÔ¾©}a´ÇhÑà½Ä{‰÷’Ç÷?ùXò±äcÿjü«ñ¯‚b¥b¥b%¿|üòñË`-¶[‹aÙÌe3—Í„OZÒú“ÖàÔØ©±Sc ‘DA:#‘΀f¯f¯f/¬¼¾òúÊë`lglglÆÎÆÎÆÎðF·7º½Ñ ‚cƒcƒcÿÉ‘«1»ÆlS¦)À2Ë2ËvçQ©ý@~J~J~ T%ªU ä•É+“WæùµMsMsMÓ"¦EL»•v+íV>…7§9ÍÁÇÕÇÕǺé»é»é¡÷ë½_ïý:lß¼}óöÍýSöOÙ?AvAvAvhWiWiWAÄ•ˆ+W ó­Ì·2ß‚üåùËó—C¹oÊ}SîÈè™Ñ3£'hÛhÛhÛ<ü²¶µ¶µ¶·¦nMÝšB°1Øl„Èj‘Õ"«AÓM{4íå_.ÿrù—!Ý;Ý;ÝÌÞfo³7Øo±ßb¿J®—\/¹½Jz•ô*<Àí펿ð¸œË—=.{ æÑšGk…°„°„°xuÁ« ^]ëT¬S±èÒtiº4Ȩ‘Q#£ÆœGäGäGàÚ›×Þ¼ö&l Û¶1 úå÷Ëï—u^©óJW`ñ«‹_]ü*ýy}#s”9Ê¡Â>¨ð\7\7\7üýý ÿÛ¤áÒpi8TŒ®]1úéw¤ßh°ªÁª«`‰y‰y‰8 p·­·­·­': „¤±Ic“Æ‚,[–-ˆ…! CB¢O¢O¢˜f˜f˜fmiK[°¦XS¬)Þxã 4Éh’Ñ$ªÖ¬Z³jMrrr€„c ÇŽçÏ9žs@§‰ÓÄsÿæþÍ¡ŸK?—~.psí͵7×Â…‚  þ¼ÿ¡ C†6„ò£Ë.?ê(ê(ê( zbôÄ艱0baÄB¸~7ün8kŠ5Å6H¤G¦ü•©d*™ ¶þkë¿¶þ îÔ¼SóNM9e䔑SÀxÁxÁxÖÝYwgݧqä¼ý½ýÚUoW@á¯ð·ÝyTjÀ¯\2]2]2¡à‚7 žã„ ; vì×®\üóýýÛ/SÕIAR²BY¡¬‚{÷ î îÉîÉîÉŸŸ²YŒ,¤[Ò-éH“¤IÒ$õ“õ“õéªtUº ²Ñ²Ñ²Ñ {Sö¦ìM~¾ru‰Ÿ×þÒ @Z!­V€4Eš"MY†,C–ÒYé¬tdkdkdk.ª#k(k(kR ©…Ôd!²YH“¥ÉÒdpþÒùKç/Þ§«« K..¹¸ä"Ìí4·ÓÜNðCÇ:þЬQÖ(kȇɇɇ4L& yyy 3é ÒHi¤4$wÉ]rÿý0JIR’”i÷Òî¥Ýƒ´OÓ>MûŽ•9VæX¸9ÿæü›óAÓAÓAÓJz—ô.ù—n~Ë-Û-Û- Ë–-, ¼Ë»¼ûlÏEáY0757¸5ëÖ,€â¦ÅMŸâî]^tG– K%<|¹ú¬ê³ªÏ‚¼áyÃó†CVë¬ÖY­A~F~F~¤•ÒJi%ÈNÈNÈN€Ô^j/µ–°„% í“öIû@ê u:<¼´ˆ#F B .ª&U’*I•@~@~@~àa²]²]²] 5‘šHM@j.5—š?ü»—w’w’wçƒÎ‚Ýq»ãvÇÁ8Ì8Ì8 §&NMœ s?œûáÜaN¯9½æô‚éÒ¤?ÒÎ"Ù"Ù"555xøº´MÚ&m{ØÞ¯ý¦ˆ" êR–”%eÁn|pãÈLÎLÎL†½.{]öº@vvvvv6dÏÏžŸ=ÿ©¹C8S÷L]€øyñóžâyñ„DøÑåG—AÛBÛBûËqÚì´Ùi3Î)œS8ç4@À8Æ1ŒõŒõŒõ ävÉí’ÛàÒÒ¥¥KKà~à@ÿžy@ äß×1aÂÄÏŽF€TEª"UyøºTN*'•ãß_éဠ‘†HC–eµX-V Pžò”ªP…*€=öØMiÊ£ÿQºãŽûÃÕíœíœíœÁ?Ø?Ø?Êö(Û£lðK÷K÷KdMƒl²É©µÔZj 8ãŒó#ûýõ£KðȨQ£~8räÈ—•.+]VBX·°naÝ Uv«ìVÙ0#jFÔŒ(p6:ÿü°î*ÜU¸ œÞszÏé=`‹Xô ÎáÓÑXrhÉ!€Ä’ħr ùvØaÇÿó_Ž,Y8ñŠxE<8h4à3>ã3NnÅŠ¨Nuªn¸áÆ¿Ï{©¡ÔPjxá…ÿ~ÜŽú¿,øëö¿þýv¡ ]©ï×í£‰&ðÀ ,e) Ô¦6µÙ¾1i Üà7Ài Ó@§PöÕ²¯–}Ê.(» ìðœä9ÉsÒ#¿÷KRK©¥Ôò‘×ý,Š(¢ø÷=ÿþì׺ùÀdßо¡}CðªáUëD„E„E„Áàƒ #rFäŒx*kÅXMVÀá‡$¼ðöSäùÂÓ¦¼©¼ Ю^»z>}žâMö}íûÚ÷…¢ÊE•‹*ÃÀaÿàýƒ÷†¨ÝQ»£vCùºåë–¯ Fo£·Ñî̽3÷Î\Ðh4`|Ëø–ñ-(ªVT­¨hkhkhk€®’®’®h 5…šBÐŽÓŽÓŽÝ@Ý@Ý@(’É‹ä`_ξœ}9Hž04îw;äœÿqþÇ`¨n¨n¨ùÕò«åWƒº?Ôý¡î +£+£+lb›À'Ù'Ù'Ônj7µÛÓ8rÒOÒOݼ»yÔßZëóN© øWG_;úÚÑ× Ö7Ö7Ö¦wšÞiz'°kcׯ®Í³o㢋6.‚«®vºÚ b,1– ¨|U¾*_[Žð¬éêꬹ³æÎš þeýËú—…>3úÌè3¨D%*ÙºJAþ•úK^#½Fz„¢¢¢ÐéŠtÿànî'Õ¶¤mIÛàc>æcø®Üwå¾+†&†&†&¶áY1éL:“~8÷ùÎæ¶æ¶æ6tÐq@Lj7þÿ]Ó™`TU–æ–æ¶.IxvŠºu(*SôŸ2û«J}pŽwŽwŽóióióiЩt*êùµï4ÄiˆÓTkP­Aµ qKâ–Ä-0gᜅsBÁ·ß|këQž–â ÅŠ'À¢r‹Ê-*/]¼tñ 9·¤[Ò- ø†oøÆÖ£&<©Ûñ·ãoÇÃg²ÏdŸÉàέ;·îÜ‚1•ÇTS¿ ü*ð+[W)<{r“ÜP5¦j €®†®€y‘Y<íñ?Dî'÷ˆ¾} öKµ_²uM¿'€›ÂMávj;µt7t7tOcF¾¿Éo‘ß"¿E0.|\ø¸p¨âUÅ«ŠüËù_Îÿr†3VÌX1r·æn͵áݣ¦‰ÕÄjbaÍŽ5;Öì€O?ýôÓO?…‡‡˜¸i⦉› pEàŠÀ¶®Vxþj_¨} ûáî‡äSäSl]“ðô¸Ut«Тf‹šðóe¶®é÷D0)L ÈÎËÎË΃î–î–î–­«UwUwUw跢ߊ~+ Æ!Æ!Æ®Ÿ¼~òúI›46ill*ÞT¼©òÆçÏÏ¿§ž“8âˆmOmOmOغ=t{(ŒÝ0vÃØ pnƹçfÀ{9ïå¼—ï^}÷ê»WÁµ¯k_Wqwiöó¼°‚ŸàÏÏÉÿNò¸äqgÎ$ÀÏëóÙºôÒìÛ7€MÇ7Ș7ÐÖ5ý}¥v-€_)’IŠ$PtStStƒ¢~EýŠúÙºª‡$¤‘4P•ªT>U}ªúTg<Îxœñ€í—·_Þ~önÜ»qïF¨ëQ×£®DŒ>}ÊÍ,7³ÜL°Ûn·Ýn»­{óâ3eþÊü$7HnÜŽ÷:Þëx/8"þD<8p:átºevËì–ùpÞ§žN=zÚºzáÅ“?'ÀÆÓO¸Öw­P±cÅŽ¶®­4ºÒçJ€ÛSoOh6¶ÙX[×ô÷•úðë"7¿>÷ž«ÊUå>Ç›Ÿ”C‘C‘CÑÃÅgê­w¶ÞYˆsŠsŠs‚Cñ‡âÅÃôÄé‰ÓAí¡öP{@­:µêÔªµSk§ÖN?o?o?opòsòsò~äG~´uïþ |Îç|º£º£º£á•á•á營~~8œ¿qþÆù^7½nz]ˆèÑ=¢;ô[ßo}¿õP£{î5ºƒƒƒƒƒƒƒ­;#¼øªß¯~ ‚K»ÆvÿÓöù­ò[è4: €ºšº€Ýb»ç¸Úé‹ãç§¿ mTÚ(€ÀÄÀDÇ9Žÿ†ÖB š½×ì=€=Zô^–^¶uþ¾R?À¯f}6ë³YŸë@×®¡¿oßþ/àsø–8Kœ%²œ³œ³œáÂÌ 3/Ì„³ûÏî?»R‡¥KŽï:¾ëø.”K)—R.*¹Vr­ä ោþ øÕñ«ãW”¾J_¥/È^‘½"{P¡â¿8 =Ö/SƒZb-±–X0~jüÔø)d4Ìh˜Ñ§$NIœ7Þ\xs!$êõ‰z(º\t¹è2”ñ,ãYÆj{Õöªíµ«Õ®V»ø.õ]ê»deebù^ÁæŸ:| `Ó‚M †·Þ  üëå_ÿÃ_˜Ílk k ©²TÙÖ}øG~yÌÒÒÐÒ@–,KøÿËþ>´ûÌî3{ûïíc±\ ¸fë®<{"ü⻽ßíýn/h&j&j&¨3£ÎŒ:c몞Ë`Ë`Ë`ÈZŸµ>k=¤ÌO™Ÿ2®œ¹ræÊHèÐ!¡äÎÏŸ;yŠÁ}À§•O+ŸV o)o)oùO;!ÏŠáÃ;™Ç3xMðšàôºÓ€{Ÿßû`?/’ר»±7@ÍA5ýaƒ `:h: ÿXþ1€ì ÙÓ]Lm8ÃŒ½?/²õË…JñóPBÿßö£ °)hS@º}º=@¿%ý–¨.¨þð1Km[m[€’µ%k˜|M¾&_°Ýþuû×AY ,P€Ë&—M.›.&RsÍý5÷CàÔÀ©S!haР…à1ÇcŽÇU’U’U²È"ËÖGMž”r±r1ðËZ^N•¬J6@iVšÿÓöúú ®,¸ —‡ ýhèGòÉòÉô{—ú\êpüÊñ+¯9½æPöxÙã´ýƒw¼° Â‚ Q‰Q‰·wÞ ½'½÷ÿ~!‰$?³Ÿ@ÝHÝÀ~Ÿý¾ÿÔ×]®»þÿ ¸>åCò_L€_¸×r¯å^ V¬(X–.–.–.WƒûŸõë²¢&™If‚‹ã/Ž¿8âNÆŒ; Ÿ…~úY(¼Tþ¥ò/•óÛæ·Íoƒ!ÇcÈckckck0Š EÛ/·_n?È Ê Ê ‚ÂÖ…­ [Cq¿â~Åý@¿@¿@¿Jn•Ü*¹æíæíæí`þÑü£ùGÛËíåö Ÿ!Ÿ!ŸvûìöÙíe%e%e%pÊuÊuÊç=Î{œ÷€Ç;ïx¼žöžöžö ,¯,¯,Š E"èa‘'Êå‰<\Åì>÷¹ÿÈ8´§=ím}0áyó\æ¹  #ÿÒöУУm7·Ý `J0%ÈîÈîü§ß³7Ù›8Á éséóÿ´½ûP÷¡Ý¢ºEx;{;ÃÏ ÿá/la À˼À—äŸ;q à—{_î}¹7,¨¹ æ‚šðÍžoö|³?*~T”‚›ãŽn=ºõèVX¹ rA$ n?¸ýàö}#úF´ çEAžR?À¯¼ü¼ü¼ü äZɵ’k =¯=¯=o몞½SêSêSjøvË·[¾Ýoû¿íÿ¶?D‰>}ÄÖÕ ‚ ÏŠ¿poíÞÚ½5C 1'Ï“çý÷~Ïù=ç÷ÀœŸæü4ç'ès®Ï¹>ç éõ¦×›^¼ñÆÛÖU ‚ ÏŠ¿PlSlSlG‹£ÅÑš*š*š*¶®êé»Üår—Ë]`ÖüYóg͇ž=#zF@«f­šµjÔ¦6µm]¥ ‚ð¬‰ð ùUùUùUpÎrÎrÎMš&M“f몞žGn¹qf¤ÎH‘ :têЩ´Kk—Ö. ˜Å,fÙºJAáyà¿Näâlv6;›Aó“æ'ÍO¶®êŸ»»ã;`Æç3>Ÿñ9´¼ÙòfË›ÐiI§%–€,T*+Ï» ‚ ÿŸ¿÷Ñî£ÝGCÞñ¼ãyÇÿñnm&Ý%Ý%ݦ{ún¨µ¦ÖšZk û©î§ºŸé”tJ:eë*A[à7|—û.÷]™3g6zÓ›Þ¶®ê¯Ë+ŸW>¯<̰›a7š5 jýÜû¹÷sûJö•ì+ÙºJAÁÖDø õõõÈ?’$ÿ˜N™N™^€OÊEó‹æ͇Y/ÏzyÖËà¸Êq•ã*zf虡gÀÁÎÁÎALû$‚ üB€ßp‰u‰u‰C5C5C50ƒŒOcûgÄf3„Á¼éó¦Ï›:‹Î¢³À¨ £.Œºª©ª©ª©¶®RAøo#Ào8ëü­ó·`eeÆ{Æ{Æ{¶®ê÷LMMañžÅ{ïyx³ß>ø|àîÝ'ºO´u•‚ Â+ñ¥ðo¸^s½æz LɦdS2è.é.é.xغ8Àz×z×zV½úëÕ_C\J\J\ Ll7±ÝÄvà³Øg±X÷[Aø"ü†Û}·ûn÷A™®LW¦C–>KŸ¥•¿Ê_e»º¬C¬C¬C 6!6!6~ þ)ø§`»}ìö±Û!P¨TÛzôA„…¿á4Ûi¶Ólpí2Úe4<0<0<0@QDÙ°®}íöµÛ×bÝbÝbÝà}ãûÆ÷P^]^]^¼ñ ‚ OHÜðžË=—{.‡ì·³ßÎ~Ûvuœ¬~²úÉê°2ceÆÊ ˜20e` ÔhZ£i¦¶%AáE%¾x õRõRõRÈVd+²Ï¿ý+þWü¯øÃ‚á †/½›ônÒ» 4 lØ0ÐÖ£#‚ ¼èDx ïºÞu½ëÂóóóók7aÂþ„ýðµõkë×Vèð~‡÷;¼­•­•­•¶Aá…¸ðe>,óa™!onÞܼ¹ Oÿžþ½g×ÞÝ#wÜ=Ó¦M›6m4oÞ8:]ît¹Óe[† ‚ð¿F€Çð>â}ÄûèƒôAú ((SP¦ ÌÓoçþ¼ûóîσ©û§îŸºj­=´öPx#öØ7bA^W^W^×Ö£!‚ ü¯à1œv9írÚòòòPðrÁË/?½ýg¼ñvÆÛ0¥Æ”Sj@Å£V< ý×ö_Û-Ø«íÕöâî~Aᑬ¿°u!ÿm4r\#‡±²±²±2h©n©n©åååÈÑçèsôÐá«_uø Ü/¹_r¿E9E9E9À4¦1 TÓUÓUÓî7·anÃ܆0Y?Y?Y¾|7øn€á>Ã}†û€£ÊQåhÃùA„ÒA€_ܺ~ëú­ë°gž {&À%÷Kî—Üa_¥}•öUK-K-K-(t-t-t…J©•R+¥Â¦ðMá›Â! J@•€*°jϪ=«öÀŽ“;Nî8 Ó‹¦M/7½›ÞMS›Om>µ9¨^V½¬zFùŽòå *‹Ê¢²ØzA„ÒB<ð‹ÔC©‡RÁ”ÎS:Oé éo¦¿™þæã·X° `xtòèäÑ Š,>;‡í¶s¬KZ—´. ´ µ µ ¡úçÕ?¯þ98¼éð¦Ã›ðžã{Žï9Š7~AÁ6Ä=¿xEþŠü9¼±èEo,úóí}Ûù¶ómNV'«“®~ýóëŸÃ¡)‡¦šòp»ÝºÝºÝ:Xzýéõ§¡~›úmê·WgWgWg[÷ZA(­Dø…|||¼ÓéNït‚jöÕì«ÙÿÁ†§8Å)ðÏðÏðÏxøòõõ5dÆgÆgÆ?²ýHF2’’’`䀑F€­Ÿlýdë'`ɵäZrmÝ{A¡´à7*Œª0ªÂ(8fà˜cÀAí vxän|•·Ê[å a«ÃV‡­†ûƒîº?~<òã‘€u¢u¢õ–áíE/zAÞŠ¼y+ Ñ-Ñ-Ñ ,Í-Í-ÍmÝkA¡´à1zDöˆì M¶4ÙÒdËÃ׎9s8%%%plî±¹ÇæÂå¶—Û^nûÈÜpà \ǸŽqo´{£Ýí`ãW¿Úø¼÷ò{/¿÷2Ø]°»`wÁÖ½AJqàcxõôêéÕF„g÷ŸÝv?(++ƒç<Ïyžó`ÎÔ9SçLãwÆïŒß£³£³£3¼¼úåÕ/¯†a]‡uÖš7-nZ .¸àbëÎ ‚ ¥ž¢ÉŠ&+š¬€v[Ûmm·Ž=rôÈQ¸´ôÒÒKKád¥“•NV‚jUªU©V¥J”݆uÖm¨‹ÕÅêb[÷BAþ?1ÀŸ¸YöfÙ›ea𗃿ü%œò;åwÊB7‡nÝ MÓš¦5Mƒ÷»¾ßõý®Ö7¬oX_À„ “­«A„?&îxœªT¥*¬²~Èú!pøõï~ôMõMõMávÉí’Û%ÐîT»SíNAØëa¯‡½ŽxãA^"<Îæ0ìííÿc;/;/;/GË£åѶ.VAžŒ¸àqÓ˜ÆÐã\s=ÎÁ¥J—*]ªÇ Ç Ç Ð§_Ÿ~}úÁKá/…¿nëbAáɈ{þ¢sŽçÏ9¢7½¹èMø‚/øP/R/Rÿ…™AΈøà/rôsôsôUeUeUePtUtUtµuU‚ ‚ð÷ˆðYÏYÏYÏÕ`5X @9äe)KY[W'‚ OFÜ(‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ð¢ËXÆBÊî”Ý)»á²ù²ù²Jv”ì(ÙaëâA„…/˜[Ën-¨¥p÷.KIDAT»µ –6_Ú|is8’}$ûH6ÄoŽß¿ôXÐcAÈNÈNÈN€8Ç8Ç8Gø´þ§õ?­·æßšk¾­{!‚ ØšOJŽ9 !!=ÿæ·8Þâx Ð×Ô×Ôׄ·Ö¾µö­µàæêæêæ N“œ&9M;;; ‚•OT>Qîº?èþ (Ž,Ž,Ž„ëæëæëfÀGm=¸‚ Âó"À_$5‘šHMÀ¼Ä¼Ä¼®æ^ͽš w]Üuq\u¼êxÕδ9ÓæL(2™ŠL_Ÿ¢OѧÀ•”+)WRàtáéÂÓ…¸>q}âz°¼fyÍòÚãÛ×uÑuÑu›UoV½YR‡¦M K2–d,û(û(û(ˆÔFj#µ “ÎIçÀÑßÑßÑì7Ùo²ßæææ°î•u¯¬{æ š7hÞ Hú*髤¯Àêmõ¶zÃý1÷Çܧ矞z>\Ñ\Ñ\Ñ€±ØXl,†{Y÷²îeÁ§ Nœ áÄ>„ĉ€5Äb ±õQAÇÎÖ¼0üðÃdQ²(Y¬ë°®Ãºÿnþ»ùïB»þvýí`Ùée§—†&G›mrÞÔ¾©}S +]Vº¬tívívív(ÿVù·Ê¿ë—­_¶~¼zêÕS¯ž‚&4¡É4oüÔø©ñSÐ-Ô-Ô-ÝÝÝÈ?:ÿ4”l)ÙR²>lðaƒÀ' ?YøÉB¨·¾ÞúzëV´¢XZZÂõ¸ëq×ãà¾Ó}§ûNPì[ì[ì ·¿¿ýýíïa^y=æõ€Zµ2jeÀ%å%å%%ÔïX¿cýŽ n¦n¦n1>1>1>зRßJ}+Ê_å¯ò‡À€%J[;AáwÄ7‘uuu (¿S~§üÔáêpu8¸Ww¯î^4*hTQŸF}õ)ĵ‹k×2ó2ó2ó`ÇÑGw…V Z5hÕ:Duˆê‘ŠHE¤Öç­Ï[ŸÖýÖýÖý¿oß­Š[·*20d`È@ ƒšN5j:APvPvP68f8f8f€u¶u¶u6ÿþjßú™õ3ëgà´Êi•Ó*È È È‚°ýaûÃöCÕŒªU3à¨óQç£ÎPP¥ JAèáÐá‡Tz§Ò;•ÞÑ;£wFƒ_ ¿~-ÀñÇwß–A-ƒZA©‡ÔCEEE[5AáqDxRf̘=zôÀ*V±êá¥FR#©XNZNZN‚>SŸ©Ï„bm±¶X Nݺ;u¸½ûf÷Íî›!¯R^¥¼J`mkmkmûÚÏ!‡°Ö²Ö²ÖúýÈ'Ÿ| ?ýéÿðå¼y-òZ@rTrTr,[·<î¿7þÞx¨P! BA ''ö~ö~ö~àPÑ¡¢CEVJ+¥•¶>X‚ ÂãˆKOJ† àŠ+®Àְ摟{àH ¥†RCp<ïxÞñ<8rä< îÜ/¸øã?dk³µÙZðŽõŽõŽY5Y5YµÿÐþ¯û_*-•–½èE/À€H½¤^R/`£RH!H]¥®RW"¥H)èNwºƒ¹›¹›¹ÛÃÝ{FyFyFAØõ°ëaסO`ŸÀ> ¸¡¸¡¸ñ°½Dy¢Á}‚û€©©© ¤*R© p›ï6ßm>¨T*x`|`|`÷D÷D÷DP;©ÔNT1©bREpüÆñÇo "!"!"²eÊ÷Çß<(UJ•R¾|;ùvÃ%Ã%Ã%¸¿âþŠû+Àÿÿ!ÿCPFWFWFgë£%‚ üþ¢«9Ws®æÀÓÓ|–õYÖgYàZÕµªkU[W'‚ OF\xR,Xl]„ ‚ ü3"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"üER{©½Ô$³d–Ì@ÊPÆÖU ‚ Âß#ÖøUª@óZÏk=¯5ÄÿQüGŸ–Ÿ–ŸñÚxm¼²·foÍÞ vkìÖØ­–mZ¶iÙzlë±­Ç6‘‘±uoAá‰ðNŸ9}æô$:$:$:ÀòZËk-tÕ½*T¡ \ç:×y[y[y[hx¶áÙ†gÅ¿ ‚ðb—~C>Z>Z>:èp Ãp~ßù}ç÷¿}ùäòÉå“¡QÝFuÕµuõ‚ ‚ð׈µãéé Ú»¶wmï çõçõçõ¿ß®ßõ~×û]‡¥­—¶^Úd)²YŠ­«A„ÿL|𾡾¡¾¡Ð|UóUÍWýþ犗/)^‚ví"ÚEˆ7~AáÅ"ÀcÈRe©²ThòZ“ך¼^2/™×#£UqzÅé§Cí-µ·ÔÞbëjAáɈð'êΩ;§î¨Ð¥B— ]¾Þhr£É&CзAß}kë*AáɈ§~µ‘lëyëyëy°ÚYí¬và¶ÇmÛhÖºYëf­áZĵˆkЬQ³FÍì#ÙG²À²Ï²Ï²$wÉ]rI-©%5J(¡¶îœ ‚ üÿ3Àl ¶ƒ6H¤ ‚¼¢¼¢¼"Ð&i“´IP[[ š“š“š“œœ ùó+æW‹ÎEçFÉ(%(YR²¤d ð Ÿð Ül}³õÍÖ`Îþœý9Ø_e•ýUàÂù ç/œÙW²¯d_}Š}Š} (f+f+fƒj¸j¸j8¸[Ü-îP‡«ÃÕáà–ê–ê– ÎùÎùÎùàVÝ­º[uð\ã¹Æs 8}äô‘ÓGÀP†2ÔÖ£+‚ ü¯ù¯ À°Ì°Ì° òßÏ?ÿ}xÐâA‹- áX±„cŸŸAAA ™©™©™ $“L2(¿S~§üì?·ÿÜþsPUTUTUÏž <€K´K´K48UqªâTÊ;”w(Š]Š]Š] /‘—ÈKÀàcð1ø@VxVxV8 0XÌbƒ¹•¹•¹C¡ÆPÐètPt£èFÑ ÐžÑžÑžÜ͹›s7ƒ~´~´~4kkk€a²a²a2(ª*ª*ª‚G:uÀÿ´ÿiÿÓá–pK¸¼»zwõîú0HȳåÙòl[-AáEaó`íkíkí š›š›š›pÝåºËu¸žw=ïzÜê«ÿ­þ ¦¦vövövöà÷™ßg~ŸAЦ MA›  s@ç€Îäää ÑÑÑ ôQú(}@aQXP¬T¬T¬Ù@Ù@Ù@À<þB¡é¤“œá g€–´¤%à€á÷äG~óóó0Œ`TUFèVéVéVAæ¥ÌK™—àÞü{óï͇Ôz©õRëÁ]Ã]Ã]dgegegì{Ù÷²ïÁ;Ø;Ø;*&TL¨˜‘ªHU¤ "ÖD¬‰XNóæ;ÍV³šÕ¶:Ê‚ ›ç\pÁ2»evËì—¢.E]Š‚3µÏÔ>Sî¼7òÞHpã4Æi „>ªfWÍ®š AÊ e¼Çzõûð«udÈJíŒÖ¥Ö¥Ö¥¿6mþZÈX”±(c$•K*—T®.¹ºäêH™–2-eHU¥ªRU_¾4|)ÔÛToS½MÙ6²md[pñsñsñ³u¯A[yfÀXÝXÝXnn»¹íæ6ø1óÇÌ3áfß›}oö­‡ÖC u:ÖéX§#TWUWUWAèêÐÕ¡«Á~‹ýû-@MjRÓÖÃô˜ÊT¦BQrQrQ2Ül{³íͶpAvAvA—†^zi(XG[G[GC­ µ*ÔªÍï7¿ßü>Nœ8dI²$Y’­;#‚ #ûŒì3^Þóòž—÷€ìCÙ‡²m]´ ‚ðwýå é¨é¨ésÍ4wdÈ8qÞÕ¿«WUõUõUõüû±8áÅV2¢dDÉØ×{_ï}½aÍ»kÞ]ó.´Ò·Ò·ÒC÷sÝÏu?ö*{•½ÊÖÕ ‚ OêO@þ[ùoå¿ÓÚLk3­ 8ìuØë°†í¶gØðLóLóL³u7^<æ¹æ¹æ¹äšäšä ÖvÖvÖvPa]…uÖCÂ[W QDÜŠ¾}+fš9hæ ¨=¸öàÚƒ¡_r¿ä~É ’Ƀl]¬ ‚ðW=öºk‰µÄ ‹‡/¾x8¨T*•JD}õAÔ“¿ñgÎÉœ“9¾¼þåõ/¯ÃÁï~ðû§×‘ý1ûcöÇÀ–k[®m¹E‹:u†»6îÚ¸ ¾™üÍäo&ƒ¡¦¡¦á?‚ ³õØpdú‘éG¦CæñÌã™Çah­¡µ†Ö§÷œÞszïÉR_Q_Q_„š 5j•cWŽ]9öô:b?Å~ŠýPvRvRvÕfÕfÕfp˜î0Ýa:ìÛ°oþ `ºmºmº wÛÞm{·-<¨õ ÖƒZ÷£˜¯˜¯˜Š­Š­Š­<³Ç÷®Ù»fïð›à7ÁoôêÑ«G¯ Ë”eÊ2Ÿ^;ª}ª}ª} tR:)`ßÔ}S÷M…’Å%‹KþÆ¥š² eÊ&ÀÐC; í{çì³w¤´Ki—Òîé“ ‚ðlü.EEEÁΑ;Gî ¯^3¼fw?w?÷0qŒl‘l‘lØÏµŸk?2×f®Í\ —k\®q¹Ä9Æ9Æ9‚ÞSï©÷„c‚1ÁW†_~e8WWWÀ­š·jÞª Wf_™}e6ïïï@À[o¼A#‚FxØ®Óm§ÛN·A¶X¶X¶²ò³ò³òazÎôœé9°}ÝöuÛ×Aβœe9Ë  f@Í€š|0ø`ðAÈKÍKÍK…³ýÏö?Ûnt¸ÑáF8·îܺsëàÖ«·^½õ*àƒ>>¹“s'çN†[n ¸5RÝRÝRÝ ½Wz¯ô^pîö¹ÛçnÃåj—«]®úKúKúKì`ÛØ†E†E†Ep-æZ̵¸ãvÇ페n˜n˜n@Âü„ù óáR—K].uÔZ©µRkìììЋ^ôúûÇ3r\ä¸ÈqP½yõæÕ›Ãö˜í1ÛcžîÉ)‚ <;¿ ñoÆ¿ÿ&˜BM¡¦PˆêÕ#ªÇSlñ{¾ç{(Š+Š+Šƒ¬È¬È¬HX•°*aU¬l¿²ýÊöpLwLwL‚'Oý!ý!ý!8QåD•U`‚Ç  wÐ;èàXçcu†ñ•ÇW_ô)ú} °œå,jQ‹ZÎEÅEÅEhFjFjF‚Áßàoð‡£ÙG³fÃGE|Ù²d€± Æ6ÛŽ}wì»cßÁ­n}p똰yÂæ ›ávÈíÛ!Þ}ÝÝÝÐÿ ÿAÿHRù³ógçφVTXQæ†Í ›–K‰¥Ž.;ºìè2ØSeO•=UÀzÕzÕz6ÝÜtsÓMHšŸ4?i>üXþÇò?–‡tXÐîW¼_ñ~EÈß¿;7C9€+Oaú§Æ>}ûÀµ©×¦^› y²«™*˜*˜*€] »v5žA‹w¹Ë]`6³™ýðeŸ²>e}ÊBQbQbQ"èVèVèV€tN:'œp‰þÉUX7[7[73™ÉÌÿ°½9rà*W¹ lg;ÛAê#õ‘ú7¹ÉMý ûAö?üüñóðáâ¸b¤)F‚1;bv<ò¹õ¤õ¤õ$X[Z[Z[>|½jZÕ´ªi@_úÒv¶ÙÙfgú:èë ¯¡xUñªâU°Ç´Ç´ÇÞ ¼x7•§ÊSå ¹s'æNïsÞç¼Ï=Ò_îæÚ¤0)L Yª,U– ¦Ž¦Ž¦ŽO¿Aáéú]ðOóOóOƒœWr^Éy̳ͳͳÿήà /¼x¸šÞ/’“““““ÁËÎËÎËÜîFw#”L+™V2 ¬/Y_²¾(Q¢ééé @3fÌÀ V°ˆ ‚ˆG^_ÈBõ¨G=°î¶î¶îK}K}KýGêû%`H+¥•ÒÊGößntÆ0†1<œ"w0ƒ £Åh1B{uîÕ¹ÍúhÖG³`‚ÿÿ þмGó͹”"Õ–jKµAZ/­—Ö?|ÝãsÏ=>‡º“êNª; ÖÎ_;í|¨Õ³VÏZ=¡f»šíj¶ƒXßXßX_®\/¸(†*†*†‚K+—V.­ ¯A^ƒ¼ôë—U ¥yÒ$}”$—$—$ƒóç1Îc ´FhÐÀ|Á4(iPÒ Ð[ô½||| 8¦8¦8›6 l¹³sgçΆüåùËó—C™ì2Ùe²A§Ð)t ÐLÑLÑLà’à’à0Þ4Þ4Þ„Ô¥©KS—B™OÊ|Ræ0X ƒòÝòÝòÝÀ5È5È5´=µ=µ=A½T½T½\’\’\’ yJò”ä)à=Ù{²÷d”¥@ ¤ R©Âïû_P¡ BAH I I »ùvóíæCXrXrX2¨š«š«šƒ©±©±©1d~ùuæ×°4`iÀRÐËô2½ òìóìóì¡Ìƒ2Ê<Ö²–µ`Z`Z`ZIõ“ê'Õãaãaãa°¯j_Õ¾*KŒ%ÆKKK—a.Ã\†=ùqÌ=Ÿ{>÷š|4.^¼xñâEÊ e…ðŠêÕ+*hZ¡i…¦@=P=P=ÐÖAžµ§~Ë:É:É: rëäÖÉ­çcÎÇœ£n<ºÒÇ¥Kµ†0„!¶îœ ‚ð¼<óð8æqæqæq~:ýtúi¸™q3ãf\¨s¡Î…:Ò)¥SJ'(ÙT²©døûûCðÜà¹Ás!bqÄâˆÅà7ÅoŠßðlíÙÚ³õÙôìÚ´;hëá}yä‘úïôß鿃¼Nyò:Aκœu9ë Mž&O“CÂO ?%ü÷‚ïß †¼Ì¼Ì¼Lpvvvvv†ð¯Ã¿ÿjׯ]¿v}(7´ÜÐrCÁ³¶gmÏÚ 5H þy¹‚ ‹Ífà±:әΠWéUz¤ø¤ø¤ø@âáÄɇ!iBÒ„¤ po꽩÷¦BÁÉ‚“'¡d{Éö’íà|Öù¬óYPWWWWW¯ê^Õ½ªƒÇhÑ£ÁsˆçÏ! ÎRg©³Àm„Û· ,T* A¾\¾\¾äÊ?”R#©‘Ôd'e'e'A:/—΃eŒeŒe X/[/[/ƒ¥¡¥¡¥!˜˜˜@‰¥ÄRbÝÝÝÐ8iœ4N}*ûTö)ÈUä*r ±j¬+dÇdÇdÇ@NpNpN0è_Ó¿¦ ”””À½Ž{÷:º#tGès s sƒˆmÛ"¶A™žez–é vƒìÙ ºÐ….¶>˜‚ «ÿ¾ðg>á>C+C+C+(ò*ò*ò‚‚áà †Cª*U•ª‚´Vi­ÒZAöÛÙog¿ o·Æ4w5w5w¡èZѵ¢k`hlhlh ÖUÖUÖU ##’BRH &I“¤I`èaèaèÚ•Ú•Ú•àµÉk“×&]‘]‘]Ë6Ë6Ë6°.³.³.ËËË““Ç•Ž+W‚sŒsŒs ¸¹¹Ç1cÇÀ»wï>h 4ÁÏËÏËÏ œ—9/s^ª»ª»ª»`7Þn¼ÝxÀgœm}0A„Õ‹þ!k'k'k'Ð÷Õ÷Õ÷ÃÃÃ0L4L4LS9S9S9022i·´[Ú ×¢®E]‹‚u××]_wÞ_òþ’÷—€ëb×Å®‹AVAVAVìß°Ãþ PtPtPtåååPÎVÎVÎåDåDåD –Xbm=‚ BiUêÀßu­úµêתÒo–|³äø´Â§>­®¾®¾®¾¶®NAžŒ˜¼÷/²°°«Áj°€L2É|ñEAá#ûç»AáE#€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$Àoe“M6Fi_–¤0) ¤÷¤÷¤÷*Tü^ $zôèmÝ AAøÏ$ë/l]È‹b»b»b;Øí»Ûw·/dh3´Z¸ï~ßý¾;œH=‘z"ÚMh7¡ÝPöQöQöª?Tý¡ê-EKÑÈ&É&É&Ùº7‚ ‚ðÇDø c?c?c?è?¨ÿ þƒà‡ú?Ôÿ¡>°—½ì¶³íÀ+¼Â+ ;&;&;³[În9»% k;¬í°¶¶î… ‚ ügâÀo(–+–+–CK]K]K8;;­hE+`.s™ t£Ý ¨jPÕ ªÐplñ ÇÚºzAAøkDxŒhÏhÏhOjÔ,¨Ùã·«q§Æw rbåÄʉ¶®ZAþ#`nÀÜ€¹ÐüBó Í/üþçvÕìªÙUƒW­¯Z_µ‚¢XQ¬(¶uÕ‚ ‚ð׈ðŠÅŠÅŠÅÐħ‰OPQQyøó ø ø xh0£ÁŒ3l]­ ‚ <þDƒ 4hC#†F }øzÃà 7< ¡ýBû…ö³u•‚ ‚ðdìl]À»2õËÔ/Sš:6ulê   Ð*¿U~«|PÎWÎWηu•‚ ‚ðdž{¸k¼k¼k„ý¡ûC÷‡‚1ŘbL©—ÔKêeëáx„„„²Ã²Ã²Ã ¹¤¹¤¹v'ìNØ€[Ëo-¿µ-^´xÑb°JVÉ*Ùºèß³¬´¬´¬¯W½^õzÚèÚèÚèÀå„Ë —¶®NA°•ç>Àކ;îhßzëý­7´­Þ¶zÛê`ýÎúõ;[Çø‰Ÿø Š¿(þ¢ø HIIàQÁ£‚GÜ,7ËÍÀu®sÝÖÅ>ÂwÜA_[_[_t8Ðá@ø¦Á7 ¾iáêpu¸ÚÖE ‚ ¶òÜ¿°¼ayÃòTÝUuWÕ]0dÒIC&“˜ÄñÌy–w-ïZÞS¡©ÐTJ‹Ò¢´»ØÅ.[W÷xEYEYEYpåê•«W®‚5ÝšnMÔ¨@¡Ô÷üE²Z²Z²Z D‰`';ÙiëªAáïO‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B/l°¦ZS­©¹8sqæb¸àuÁë‚äÏÈŸ‘?t t t àfÓ›Mo6ÃjÃjÃj[Wýä4ÿÒüKó/¸}1úb4¤I?’~ÄÖU ‚ /º60ŠQŒQcÔáÃ}îûp\èp¡Ã…>+}Vú,˜7vÞØyc!gLΘœ1¶.úÉŽŽŽÁK¿XúÅRØþýöï·oëªA„Ý ¬·¬·¬·À´Î´Î´bbbÀQã¨qÔ€ù˜ù˜ùM š4 >vøØácðYí³Úç‘o̘?0AgÐù{ó÷æï=zô´WÆZÆZŒcccÁènt7ºƒåˆåˆå‘Oâ–ÖÖÃ`ô3úýÀ4Õ4Õ4˜Â¦€e‡e‡e˜CÍ¡æP°ô±ô±ôK‰¥Ä¬`+€ù˜Á4×4×4ÔoªßT¿ î¹î¹î¹`~Ãü†ù [AáE÷ÂÌhz×ô®é]زyËæ-›!¹qrãäÆàºÔu©ëRÈÞœ½9{3H_J_J_BbNbNb|=çë9_ÏÁ!ƒC‡€z”z”z¬,\Y¸²”½”½”½@}B}B}zÕéU§W0Ž3Ž3Žƒu6ÖÙX´•´•´• xLñ˜â1öZØka¯A¼y=ò`}ùõå×—‡Ô¦©MS›BþæüÍù›áå/·x¹„î ݺ¾nøuïBÍ÷k¾_ó}°¬¶¬¶¬†n»Mì6âfÄ͈›gLgLgLàÝØ»±wc¸q;ãvÔñ¬ãYÇÓÖGCAxѽ0ßœ>qúÄé°±pcáÆBè5¥×”^S wãÞ{7õ~õ~õ~°N·N·N‡PïPïPo¸Ÿr?å~ ä‡ç‡ç‡ÃâÅŠ!nGÜŽ¸Ðç‹>_ôùêm­·µÞVo—o—o‡Í 67ØÜ.Lº0éÂ$èÿzÿ×û¿}ä}ä}äà¶Ìm™Û²‡õï Þ¼_|eð¨1²ÆÈ#aÅÇ+>^ñ1¨·ª·ª·BÊK)/¥¼Î&g“³ Z,m±´ÅRH›š65m*Ì›7?Z·*nU ýÇõׄº†º†º‚¥ÐRh)´õÑA^t/L¸ÞçzŸë}À#Ä#Ä#Êf—Í.› öÉöÉöÉ µ”ZJ-<àÈ_’¿$ dñ²xYÌ6wÚÜiP©C¥•:Àøã;Œï cÆ&Œå<å<å<(©]R»¤ö#uô–zK½Áî»wìÞk×®ÀäÚ“kO® ªxU¼*¼'zOôž,e)KÖñïeƒÏr–³ì7NŠ“â€A b°ˆE,zdœqƨD%*Ùúh‚ /º&T-ªZTµ4:N£ƒKÕ.U»T ²‹²‹²‹ÀpËpËp Š»w+î…µ kÖý6ý6ý6(îZܵ¸+¹väÚ‘k¹ sAæh’Ý$»I6¸^s½æz LËMËMˡѵF×]ƒëšëšë¸1ãÆŒ3 Ë1Ë1Ëô3õ3õ3!ÿëü¯ó¿†¼!yCò†@ðõàëÁ×A}X}X}Œ)Æc ô)èSÐ 2ƒÌ ƒÂe…Ë ¹„Ò$¤IHpÀàÔW§¾:õä\ιœstMuMuMAwNwNwÎÖGCAxѽ07Ö)©SR§ú¥ôKé—Ç'Ÿp|” .\&Ýjt«Ñ-P,V,V,†äÓɧ“OC½µõÖÖ[ ¦–¦–¦–à<Ðy ó@8×õ\×s]A'‹“ÅÁЃC=Ök„Âß 'üí’í’í‚ïxçÀ;àeõ²zY¡rDåˆÊPe]•uUÖA×Ϻ~Öõ38xþàùƒçÁéªÓU§«Ð4¦iLÓHé•Ò+¥Ô­[?JÚ”´)if…YaV@Ⱥu!ë`”ý(ûQöpöÒÙKg/¦¢¦¢¦"T{©ÚKÕ^¿Ù~³ýfƒ¡º¡º¡:(£”QÊ([AáE#Yñ¼ܶ`Û‚m à䮓»Nî‚)Û§lŸ²ÝÖÃð¿«(«(«( †^zuèUøÈû#ï¼!¢JD•ˆ*¶®NA°•æ€ ‚ O‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P =ÿGq@EÙºû¥€ 2 4Ò€d’I¶uQ‚ ‚­=÷©€´Z-\Œ¹s1Æ{xìa Íhfëáø¢B… ' ' ' oTÞ¨¼Q`ï`ï`ï´§=ím]¤ ‚`+Ï}*àœ-9[r¶Àå —'\žú]ú]ú] u•ºJ]m=ÿC¬X±‚µ³µ³µ3xä{ä{äC5vÔØW®:\µu‘‚ ‚­<÷ ‚ ‚퉛A¡ú?aî #˰.zTXtcreate-datexÚ320°Ô50Õ54 14·2°´26Ò60²20Aë4¼yð.zTXtmodify-datexÚ320°Ô50Õ54 14·2°´26Ò60²20AëV„ŽIEND®B`‚rsyslog-8.2512.0/doc/source/PaxHeaders/containers0000644000000000000000000000013215114544361016672 xustar0030 mtime=1764935921.003543205 30 atime=1764935930.262684952 30 ctime=1764935921.003543205 rsyslog-8.2512.0/doc/source/containers/0000775000175000017500000000000015114544361016413 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/containers/PaxHeaders/collector.rst0000644000000000000000000000013215071746523021475 xustar0030 mtime=1760021843.790420229 30 atime=1764928604.308804164 30 ctime=1764935920.990543006 rsyslog-8.2512.0/doc/source/containers/collector.rst0000664000175000017500000000750415071746523021147 0ustar00rgerrger.. _containers-user-collector: .. _container.image.rsyslog-collector: rsyslog/rsyslog-collector ========================= .. index:: pair: containers; rsyslog/rsyslog-collector pair: Docker images; rsyslog/rsyslog-collector Overview -------- The ``rsyslog-collector`` container image extends the standard :doc:`standard` base with modules for **centralised log aggregation**. It is preconfigured to receive logs via UDP, TCP, and optionally RELP, and can forward them to storage backends or files. This image is the recommended starting point for building a log collector or relay service. .. note:: - **UDP (514/udp)** and **TCP (514/tcp)** are enabled by default. - **RELP (2514/tcp)** is available but **disabled by default**. - External deployments usually map RELP to **20514/tcp** to avoid conflicts with the standard syslog port. Environment Variables --------------------- Runtime behaviour can be tuned with the following variables: .. _containers-user-collector-enable_udp: .. envvar:: ENABLE_UDP Enable UDP syslog reception. Default ``on``. .. _containers-user-collector-enable_tcp: .. envvar:: ENABLE_TCP Enable TCP syslog reception. Default ``on``. .. _containers-user-collector-enable_relp: .. envvar:: ENABLE_RELP Enable RELP syslog reception (internal port ``2514/tcp``). Default ``off``. .. _containers-user-collector-write_all_file: .. envvar:: WRITE_ALL_FILE Write all messages to ``/var/log/all.log``. Default ``on``. .. _containers-user-collector-write_json_file: .. envvar:: WRITE_JSON_FILE Write JSON formatted messages to ``/var/log/all-json.log``. Default ``on``. .. _containers-user-collector-rsyslog_hostname: .. envvar:: RSYSLOG_HOSTNAME :noindex: Hostname used inside rsyslog. Defaults to the value of ``/etc/hostname`` when unset. .. _containers-user-collector-permit_unclean_start: .. envvar:: PERMIT_UNCLEAN_START :noindex: Skip configuration validation when set. By default ``rsyslogd -N1`` validates the configuration. .. _containers-user-collector-rsyslog_role: .. envvar:: RSYSLOG_ROLE :noindex: Role name consumed by the entrypoint. Defaults to ``collector``. Port Mapping Reference ---------------------- +-----------+----------------+------------------+-----------------+ | Protocol | Container Port | Example External | Controlled by | +===========+================+==================+=================+ | UDP Syslog | 514/udp | 514/udp | ``ENABLE_UDP`` | +-----------+----------------+------------------+-----------------+ | TCP Syslog | 514/tcp | 514/tcp | ``ENABLE_TCP`` | +-----------+----------------+------------------+-----------------+ | RELP | 2514/tcp | 20514/tcp | ``ENABLE_RELP`` | +-----------+----------------+------------------+-----------------+ Example Deployment (docker-compose) ----------------------------------- A minimal configuration using `docker compose`: .. code-block:: yaml version: "3.9" services: rsyslog-collector: image: rsyslog/rsyslog-collector:latest environment: ENABLE_UDP: "on" ENABLE_TCP: "on" ENABLE_RELP: "on" ports: - "514:514/udp" # Syslog UDP - "514:514/tcp" # Syslog TCP - "20514:2514/tcp" # RELP (external 20514 → internal 2514) volumes: - ./data:/var/log # Optional: collect logs on host Verifying the Container ----------------------- To confirm that the collector is listening on the expected ports: .. code-block:: bash docker compose exec rsyslog-collector ss -tuln This should show listeners on ``514/udp``, ``514/tcp``, and ``2514/tcp`` when RELP is enabled. .. seealso:: - `GitHub Discussions `_ for community support. - `rsyslog Assistant AI `_ for self-help and examples. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/standard.rst0000644000000000000000000000013115062756615021311 xustar0030 mtime=1758190989.179640808 29 atime=1764928604.46180882 30 ctime=1764935921.001543174 rsyslog-8.2512.0/doc/source/containers/standard.rst0000664000175000017500000000202515062756615020755 0ustar00rgerrger.. _containers-user-standard: .. _container.image.rsyslog-standard: rsyslog/rsyslog =============== .. index:: pair: containers; rsyslog/rsyslog pair: Docker images; rsyslog/rsyslog The general-purpose image builds on ``rsyslog-minimal`` and adds commonly used modules such as ``imhttp`` and ``omhttp``. Use it when you need a ready-to-run rsyslog with HTTP ingestion or forwarding capabilities. Environment Variables --------------------- The same entrypoint variables as the minimal image are available: .. _containers-user-standard-rsyslog_hostname: .. envvar:: RSYSLOG_HOSTNAME :noindex: Hostname used inside rsyslog. Defaults to the value of ``/etc/hostname`` when unset. .. _containers-user-standard-permit_unclean_start: .. envvar:: PERMIT_UNCLEAN_START :noindex: Skip configuration validation when set. By default ``rsyslogd -N1`` validates the configuration. .. _containers-user-standard-rsyslog_role: .. envvar:: RSYSLOG_ROLE :noindex: Role name consumed by the entrypoint. Defaults to ``standard``. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/user_images.rst0000644000000000000000000000013215062756615022015 xustar0030 mtime=1758190989.179640808 30 atime=1764928604.750817616 30 ctime=1764935921.003543205 rsyslog-8.2512.0/doc/source/containers/user_images.rst0000664000175000017500000000261515062756615021465 0ustar00rgerrger.. _containers-user-images: User-Focused Images ------------------- .. index:: pair: containers; user images pair: Docker; rsyslog images Official images are built on Ubuntu LTS releases and install the latest rsyslog packages from the Adiscon daily-stable PPA. Images are tagged ``rsyslog/rsyslog[-]:`` where ```` follows the ``YYYY-MM`` rsyslog release. Available variants include: * :doc:`rsyslog/rsyslog-minimal ` – rsyslog core only. * :doc:`rsyslog/rsyslog ` – standard image with common modules such as ``imhttp`` and ``omhttp``. * :doc:`rsyslog/rsyslog-collector ` – adds modules for centralized log collection (``elasticsearch``, ...). * :doc:`rsyslog/rsyslog-dockerlogs ` – includes ``imdocker`` to process logs from the Docker daemon. * ``rsyslog/rsyslog-debug`` – planned variant with troubleshooting tools. .. toctree:: :maxdepth: 1 minimal standard collector dockerlogs Images are built using the layered ``Makefile`` in ``packaging/docker/rsyslog``:: make all make standard make VERSION=2025-06 minimal Configuration snippets in each directory and environment variables allow enabling or disabling functionality at runtime. Consult the `packaging/docker README `_ for the latest details and feedback instructions. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/development_images.rst0000644000000000000000000000013215062756615023361 xustar0030 mtime=1758190989.178640794 30 atime=1764928604.351805472 30 ctime=1764935920.992543036 rsyslog-8.2512.0/doc/source/containers/development_images.rst0000664000175000017500000000162615062756615023032 0ustar00rgerrger.. _containers-development-images: Development and Historical Images --------------------------------- .. index:: pair: containers; development images pair: containers; historical images Large images used by rsyslog's Continuous Integration live under ``packaging/docker/dev_env``. They provide all build dependencies for multiple distributions (Alpine, CentOS, Debian, Fedora, SUSE and Ubuntu) and are intended for contributors who need to reproduce the CI environment. Due to the many tools they include, these images are several gigabytes in size and are not meant for production use. The repository also retains some historical material for reference: * ``packaging/docker/appliance`` – deprecated attempt at an all-in-one logging appliance. * ``packaging/docker/base`` – obsolete base images (Alpine and CentOS 7). These directories are kept to document past work but are no longer maintained. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/minimal.rst0000644000000000000000000000013215062756615021140 xustar0030 mtime=1758190989.179640808 30 atime=1764928604.433807968 30 ctime=1764935920.999543144 rsyslog-8.2512.0/doc/source/containers/minimal.rst0000664000175000017500000000211015062756615020576 0ustar00rgerrger.. _containers-user-minimal: .. _container.image.rsyslog-minimal: rsyslog/rsyslog-minimal ======================= .. index:: pair: containers; rsyslog/rsyslog-minimal pair: Docker images; rsyslog/rsyslog-minimal A lean Ubuntu-based image containing the rsyslog core and a tiny configuration that writes logs to standard output. It serves as the foundation for the other rsyslog images and is suitable when you want to add your own modules or configuration. Environment Variables --------------------- The entrypoint script recognizes the following variables: .. _containers-user-minimal-rsyslog_hostname: .. envvar:: RSYSLOG_HOSTNAME Hostname used inside rsyslog. Defaults to the value of ``/etc/hostname`` when unset. .. _containers-user-minimal-permit_unclean_start: .. envvar:: PERMIT_UNCLEAN_START Skip configuration validation when set. By default ``rsyslogd -N1`` validates the configuration. .. _containers-user-minimal-rsyslog_role: .. envvar:: RSYSLOG_ROLE Role name consumed by the entrypoint. Defaults to ``minimal`` and normally does not need to be changed. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/dockerlogs.rst0000644000000000000000000000013215062756615021646 xustar0030 mtime=1758190989.178640794 30 atime=1764928604.378806294 30 ctime=1764935920.994543067 rsyslog-8.2512.0/doc/source/containers/dockerlogs.rst0000664000175000017500000000233015062756615021310 0ustar00rgerrger.. _containers-user-dockerlogs: .. _container.image.rsyslog-dockerlogs: rsyslog/rsyslog-dockerlogs ========================== .. index:: pair: containers; rsyslog/rsyslog-dockerlogs pair: Docker images; rsyslog/rsyslog-dockerlogs This variant includes the ``imdocker`` module to read logs from the Docker daemon and forward them to a central rsyslog instance. Environment Variables --------------------- .. _containers-user-dockerlogs-remote_server_name: .. envvar:: REMOTE_SERVER_NAME Required hostname or IP of the collector to forward logs to. .. _containers-user-dockerlogs-remote_server_port: .. envvar:: REMOTE_SERVER_PORT TCP port on the collector. Defaults to ``514`` when unset. .. _containers-user-dockerlogs-rsyslog_hostname: .. envvar:: RSYSLOG_HOSTNAME :noindex: Hostname used inside rsyslog. Defaults to the value of ``/etc/hostname`` when unset. .. _containers-user-dockerlogs-permit_unclean_start: .. envvar:: PERMIT_UNCLEAN_START :noindex: Skip configuration validation when set. By default ``rsyslogd -N1`` validates the configuration. .. _containers-user-dockerlogs-rsyslog_role: .. envvar:: RSYSLOG_ROLE :noindex: Role name consumed by the entrypoint. Defaults to ``docker``. rsyslog-8.2512.0/doc/source/containers/PaxHeaders/index.rst0000644000000000000000000000013215062756615020621 xustar0030 mtime=1758190989.178640794 30 atime=1764928604.406807146 30 ctime=1764935920.996543098 rsyslog-8.2512.0/doc/source/containers/index.rst0000664000175000017500000000113115062756615020261 0ustar00rgerrger.. _containers-index: Rsyslog Containers ================== .. index:: single: containers single: Docker images Rsyslog runs well inside containers and the project provides official Docker images for common logging scenarios. Dockerfiles and build recipes live under `packaging/docker `_. Since version 8.32.0 rsyslog also adjusts a few defaults when it detects that it is running as PID 1 inside a container: ``Ctrl-C`` is handled and no pid file is written. .. toctree:: :maxdepth: 2 user_images development_images rsyslog-8.2512.0/doc/source/PaxHeaders/includes0000644000000000000000000000013215114544361016333 xustar0030 mtime=1764935921.157545563 30 atime=1764935930.262684952 30 ctime=1764935921.157545563 rsyslog-8.2512.0/doc/source/includes/0000775000175000017500000000000015114544361016054 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/includes/PaxHeaders/container_dev_env.inc.rst0000644000000000000000000000013215055603742023405 xustar0030 mtime=1756825570.257068393 30 atime=1764928606.944884297 30 ctime=1764935921.153545501 rsyslog-8.2512.0/doc/source/includes/container_dev_env.inc.rst0000664000175000017500000000105615055603742023053 0ustar00rgerrger.. note:: The rsyslog project maintains multiple `rsyslog docker development environment images `_. These images have been configured specifically for use with rsyslog and are recommended over your own build environment. Rsyslog docker development images are named with the ``rsyslog_dev_`` prefix, followed by the distro name. .. warning:: If you plan to copy the binary for use outside of the container you need to make sure to use an image of the same distro/version when building rsyslog. rsyslog-8.2512.0/doc/source/includes/PaxHeaders/substitution_definitions.inc.rst0000644000000000000000000000013215071746523025067 xustar0030 mtime=1760021843.793420276 30 atime=1764928347.387688223 30 ctime=1764935921.158545578 rsyslog-8.2512.0/doc/source/includes/substitution_definitions.inc.rst0000664000175000017500000000631415071746523024537 0ustar00rgerrger .. This file is included by the common header file, which is itself included by means of the rst_prolog Sphinx build configuration file (source/conf.py). Add substitutions here instead of directly to the rst_prolog configuration option. .. |PRODUCT| replace:: ``Rsyslog`` .. |FmtBasicName| replace:: ``basic`` .. |FmtAdvancedName| replace:: ``advanced`` .. |FmtObsoleteName| replace:: ``obsolete legacy`` .. |FmtObsoleteDescription| replace:: ``Obsolete Format Equivalents`` .. |RsyslogDockerHub| replace:: official rsyslog Docker Hub .. _RsyslogDockerHub: https://hub.docker.com/u/rsyslog/ .. |GitHubDockerProject| replace:: rsyslog docker definitions .. _GitHubDockerProject: https://github.com/rsyslog/rsyslog/packaging/docker .. |DockerApplianceAlpineDockerHubRepo| replace:: Alpine rsyslog appliance Docker Hub repo .. _DockerApplianceAlpineDockerHubRepo: https://hub.docker.com/r/rsyslog/syslog_appliance_alpine/ .. |DockerApplianceAlpineName| replace:: ``rsyslog/syslog_appliance_alpine`` .. |DockerApplianceAlpineRUN| replace:: ``docker run -ti rsyslog/syslog_appliance_alpine`` .. |RsyslogPackageDownloads| replace:: rsyslog package downloads .. _RsyslogPackageDownloads: http://www.rsyslog.com/downloads/download-other/ .. |GitHubDocProject| replace:: rsyslog source documentation .. _GitHubDocProject: https://github.com/rsyslog/rsyslog/tree/main/doc .. |GitHubDocProjectREADME| replace:: rsyslog doc/ README .. _GitHubDocProjectREADME: https://github.com/rsyslog/rsyslog/blob/main/doc/README.md .. |GitHubDocProjectDevREADME| replace:: rsyslog doc/ BUILDS README .. _GitHubDocProjectDevREADME: https://github.com/rsyslog/rsyslog/blob/main/doc/BUILDS_README.md .. |GitHubDocProjectGoodFirstIssueLabel| replace:: rsyslog doc issues marked with Good First Issue label .. _GitHubDocProjectGoodFirstIssueLabel: https://github.com/rsyslog/rsyslog/labels/good%20first%20issue .. |GitHubDocProjectHelpWantedLabel| replace:: rsyslog-doc issues marked with Help Wanted label .. _GitHubDocProjectHelpWantedLabel: https://github.com/rsyslog/rsyslog-doc/labels/help%20wanted .. |RsyslogOfficialForums| replace:: Forum .. _RsyslogOfficialForums: http://kb.monitorware.com/rsyslog-f40.html .. |RsyslogStackExchangeAsk| replace:: Ask .. _RsyslogStackExchangeAsk: https://serverfault.com/questions/ask?tags=rsyslog .. |RsyslogStackExchangeView| replace:: View .. _RsyslogStackExchangeView: https://stackexchange.com/filters/327462/rsyslog .. |RsyslogOfficialMailingList| replace:: Mailing list .. _RsyslogOfficialMailingList: http://lists.adiscon.net/mailman/listinfo/rsyslog .. |GitHubSourceProject| replace:: rsyslog source project .. _GitHubSourceProject: https://github.com/rsyslog/rsyslog/ .. |GitHubSourceProjectREADME| replace:: rsyslog project README .. _GitHubSourceProjectREADME: https://github.com/rsyslog/rsyslog/blob/main/README.md .. |GitHubSourceProjectGoodFirstIssueLabel| replace:: rsyslog issues marked with Good First Issue label .. _GitHubSourceProjectGoodFirstIssueLabel: https://github.com/rsyslog/rsyslog/labels/good%20first%20issue .. |GitHubSourceProjectHelpWantedLabel| replace:: rsyslog issues marked with Help Wanted label .. _GitHubSourceProjectHelpWantedLabel: https://github.com/rsyslog/rsyslog/labels/help%20wanted rsyslog-8.2512.0/doc/source/includes/PaxHeaders/footer.inc.rst0000644000000000000000000000013215055605325021212 xustar0030 mtime=1756826325.621800261 30 atime=1764928347.404688425 30 ctime=1764935921.155545532 rsyslog-8.2512.0/doc/source/includes/footer.inc.rst0000664000175000017500000000061715055605325020662 0ustar00rgerrger---- **Support:** `rsyslog Assistant `_ | `GitHub Discussions `_ | GitHub Issues: |GitHubSourceProject|_ **Contributing:** Source & docs: |GitHubSourceProject|_ © 2008–2025 `Rainer Gerhards `_ and others. Licensed under the `Apache License 2.0 `_. rsyslog-8.2512.0/doc/source/PaxHeaders/reference0000644000000000000000000000013215114544360016462 xustar0030 mtime=1764935920.365533437 30 atime=1764935930.263684968 30 ctime=1764935920.365533437 rsyslog-8.2512.0/doc/source/reference/0000775000175000017500000000000015114544360016203 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/reference/PaxHeaders/parameters0000644000000000000000000000013215114544362020627 xustar0030 mtime=1764935922.632568145 30 atime=1764935930.368686575 30 ctime=1764935922.632568145 rsyslog-8.2512.0/doc/source/reference/parameters/0000775000175000017500000000000015114544362020350 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-parsehostname.rst0000644000000000000000000000013115114522477025712 xustar0030 mtime=1764926783.027631661 29 atime=1764926783.45564217 30 ctime=1764935921.509550952 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-parsehostname.rst0000664000175000017500000000174415114522477025365 0ustar00rgerrger.. _param-imkafka-parsehostname: .. _imkafka.parameter.input.parsehostname: parseHostname ============= .. index:: single: imkafka; parseHostname single: parseHostname .. summary-start Controls whether imkafka parses the hostname from each received message. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: parseHostname :Scope: input :Type: boolean :Default: input=``off`` :Required?: no :Introduced: 8.38.0 Description ----------- If this parameter is set to on, imkafka will parse the hostname in log if it exists. The result can be retrieved from $hostname. If it's off, for compatibility reasons, the local hostname is used, same as the previous version. Input usage ----------- .. _imkafka.parameter.input.parsehostname-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="your-topic" parseHostname="on") See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-name.rst0000644000000000000000000000013115062756615026204 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.144554547 29 ctime=1764935921.77855507 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-name.rst0000664000175000017500000000242215062756615025651 0ustar00rgerrger.. _param-imtcp-streamdriver-name: .. _imtcp.parameter.module.streamdriver-name: .. _imtcp.parameter.input.streamdriver-name: StreamDriver.Name ================= .. index:: single: imtcp; StreamDriver.Name single: StreamDriver.Name .. summary-start Selects the network stream driver for all inputs using this module. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.Name :Scope: module, input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Selects :doc:`network stream driver <../../concepts/netstrm_drvr>` for all inputs using this module. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-name: .. _imtcp.parameter.module.streamdriver-name-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.name="mydriver") Input usage ----------- .. _param-imtcp-input-streamdriver-name: .. _imtcp.parameter.input.streamdriver-name-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.name="mydriver") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-addtlframedelimiter.rst0000644000000000000000000000013115062756615026741 xustar0030 mtime=1758190989.187640921 30 atime=1764928595.460533531 29 ctime=1764935921.56955187 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-addtlframedelimiter.rst0000664000175000017500000000516515062756615026415 0ustar00rgerrger.. _param-imptcp-addtlframedelimiter: .. _imptcp.parameter.input.addtlframedelimiter: AddtlFrameDelimiter =================== .. index:: single: imptcp; AddtlFrameDelimiter single: AddtlFrameDelimiter .. summary-start Defines an additional ASCII frame delimiter for non-standard senders. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: AddtlFrameDelimiter :Scope: input :Type: integer :Default: input=-1 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This directive permits to specify an additional frame delimiter for plain tcp syslog. The industry-standard specifies using the LF character as frame delimiter. Some vendors, notable Juniper in their NetScreen products, use an invalid frame delimiter, in Juniper's case the NUL character. This directive permits to specify the ASCII value of the delimiter in question. Please note that this does not guarantee that all wrong implementations can be cured with this directive. It is not even a sure fix with all versions of NetScreen, as I suggest the NUL character is the effect of a (common) coding error and thus will probably go away at some time in the future. But for the time being, the value 0 can probably be used to make rsyslog handle NetScreen's invalid syslog/tcp framing. For additional information, see this `forum thread `_. **If this doesn't work for you, please do not blame the rsyslog team. Instead file a bug report with Juniper!** Note that a similar, but worse, issue exists with Cisco's IOS implementation. They do not use any framing at all. This is confirmed from Cisco's side, but there seems to be very limited interest in fixing this issue. This directive **can not** fix the Cisco bug. That would require much more code changes, which I was unable to do so far. Full details can be found at the `Cisco tcp syslog anomaly `_ page. Input usage ----------- .. _param-imptcp-input-addtlframedelimiter: .. _imptcp.parameter.input.addtlframedelimiter-usage: .. code-block:: rsyslog input(type="imptcp" addtlFrameDelimiter="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserveraddtlframedelimiter: - $InputPTCPServerAddtlFrameDelimiter — maps to AddtlFrameDelimiter (status: legacy) .. index:: single: imptcp; $InputPTCPServerAddtlFrameDelimiter single: $InputPTCPServerAddtlFrameDelimiter See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmrfc5424addhmac-key.rst0000644000000000000000000000013215071746523025156 xustar0030 mtime=1760021843.821420718 30 atime=1764928598.502626867 30 ctime=1764935922.086559786 rsyslog-8.2512.0/doc/source/reference/parameters/mmrfc5424addhmac-key.rst0000664000175000017500000000150015071746523024616 0ustar00rgerrger.. _param-mmrfc5424addhmac-key: .. _mmrfc5424addhmac.parameter.action.key: key === .. index:: single: mmrfc5424addhmac; key single: key .. summary-start Specifies the key used to generate the HMAC. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmrfc5424addhmac`. :Name: key :Scope: action :Type: string :Default: none :Required?: yes :Introduced: 7.5.6 Description ----------- The key to be used to generate the HMAC. In production, this should be a cryptographically strong and secret key. Action usage ------------ .. _param-mmrfc5424addhmac-action-key: .. _mmrfc5424addhmac.parameter.action.key-usage: .. code-block:: rsyslog action(type="mmrfc5424addhmac" key="a-long-and-very-secret-key-phrase") See also -------- See also :doc:`../../configuration/modules/mmrfc5424addhmac`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-parsehostname.rst0000644000000000000000000000013215062756615027653 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.981580241 30 ctime=1764935921.872556509 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-parsehostname.rst0000664000175000017500000000220015062756615027311 0ustar00rgerrger.. _param-imuxsock-syssock-parsehostname: .. _imuxsock.parameter.module.syssock-parsehostname: SysSock.ParseHostname ===================== .. index:: single: imuxsock; SysSock.ParseHostname single: SysSock.ParseHostname .. summary-start Expects hostnames on the system log socket when special parsing is disabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.ParseHostname :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.9.0 Description ----------- .. note:: This option only has an effect if ``SysSock.UseSpecialParser`` is set to "off". Normally, the local log sockets do *not* contain hostnames. If set to on, parsers will expect hostnames just like in regular formats. If set to off (the default), the parser chain is instructed to not expect them. Module usage ------------ .. _param-imuxsock-module-syssock-parsehostname: .. _imuxsock.parameter.module.syssock-parsehostname-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.parseHostname="on") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-trimlineoverbytes.rst0000644000000000000000000000013215062756615026477 xustar0030 mtime=1758190989.185640893 30 atime=1764928594.088491337 30 ctime=1764935921.449550033 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-trimlineoverbytes.rst0000664000175000017500000000215415062756615026145 0ustar00rgerrger.. _param-imfile-trimlineoverbytes: .. _imfile.parameter.input.trimlineoverbytes: .. _imfile.parameter.trimlineoverbytes: trimLineOverBytes ================= .. index:: single: imfile; trimLineOverBytes single: trimLineOverBytes .. summary-start Truncates lines longer than the specified number of bytes. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: trimLineOverBytes :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Tells rsyslog to truncate lines whose length exceeds the configured number of bytes. A positive value trims the line at that byte count. The default ``0`` means lines are never truncated. This option can be used when ``readMode`` is ``0`` or ``2``. Input usage ----------- .. _param-imfile-input-trimlineoverbytes: .. _imfile.parameter.input.trimlineoverbytes-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" trimLineOverBytes="0") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-usehttps.rst0000644000000000000000000000013215114522477024631 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.482642833 30 ctime=1764935922.436565144 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-usehttps.rst0000664000175000017500000000137615114522477024304 0ustar00rgerrger.. _param-omhttp-usehttps: .. _omhttp.parameter.input.usehttps: useHttps ======== .. index:: single: omhttp; useHttps single: useHttps .. summary-start Switches omhttp to use HTTPS instead of HTTP when sending requests. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: useHttps :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- When switched to ``on`` you will use ``https`` instead of ``http``. Input usage ----------- .. _omhttp.parameter.input.usehttps-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-serverstreamdriverauthmode.rst0000644000000000000000000000013215114522477030356 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.453642121 30 ctime=1764935921.318548028 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-serverstreamdriverauthmode.rst0000664000175000017500000000377115114522477030032 0ustar00rgerrger.. _param-imdiag-serverstreamdriverauthmode: .. _imdiag.parameter.input.serverstreamdriverauthmode: ServerStreamDriverAuthMode ========================== .. index:: single: imdiag; ServerStreamDriverAuthMode single: ServerStreamDriverAuthMode .. summary-start Accepts a stream driver authentication mode string, but imdiag always uses the plain TCP driver so the value has no effect. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ServerStreamDriverAuthMode :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Selects the authentication mode for the active :doc:`network stream driver <../../concepts/netstrm_drvr>`. imdiag always uses the plain TCP driver (``ptcp``) and therefore lacks TLS or other authenticated stream implementations. The value is accepted for compatibility with the generic TCP listener framework but is ignored by the ``ptcp`` driver. Configure this parameter before :ref:`ServerRun ` if you need forward compatibility with a future build that supports alternate stream drivers. In current releases the setting does not change listener behavior. Input usage ----------- .. _param-imdiag-input-serverstreamdriverauthmode: .. _imdiag.parameter.input.serverstreamdriverauthmode-usage: .. code-block:: rsyslog module(load="imdiag") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverStreamDriverAuthMode="anon" serverRun="19998") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagserverstreamdriverauthmode: - $IMDiagServerStreamDriverAuthMode — maps to ServerStreamDriverAuthMode (status: legacy) .. index:: single: imdiag; $IMDiagServerStreamDriverAuthMode single: $IMDiagServerStreamDriverAuthMode See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-listenportfilename.rst0000644000000000000000000000013215062756615026464 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.267558322 30 ctime=1764935921.725554258 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-listenportfilename.rst0000664000175000017500000000226715062756615026137 0ustar00rgerrger.. _param-imtcp-listenportfilename: .. _imtcp.parameter.input.listenportfilename: ListenPortFileName ================== .. index:: single: imtcp; ListenPortFileName single: ListenPortFileName .. summary-start Writes the listener's port number into the given file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: ListenPortFileName :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: 8.38.0 Description ----------- Specifies a file name into which the port number this input listens on is written. It is primarily intended for cases when ``port`` is set to ``0`` to let the OS assign a free port number. This parameter was introduced for testbench scenarios that use dynamic ports. .. note:: If this parameter is set, ``port="0"`` is permitted. Otherwise, the port defaults to ``514``. Input usage ----------- .. _param-imtcp-input-listenportfilename: .. _imtcp.parameter.input.listenportfilename-usage: .. code-block:: rsyslog input(type="imtcp" port="0" listenPortFileName="/tmp/imtcp.port") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv6-enable.rst0000644000000000000000000000013215071746523025036 xustar0030 mtime=1760021843.804420449 30 atime=1764928597.335591097 30 ctime=1764935921.941557566 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv6-enable.rst0000664000175000017500000000177615071746523024515 0ustar00rgerrger.. _param-mmanon-ipv6-enable: .. _mmanon.parameter.input.ipv6-enable: ipv6.enable =========== .. index:: single: mmanon; ipv6.enable single: ipv6.enable .. summary-start Enables or disables IPv6 address anonymization for the mmanon action. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv6.enable :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 7.3.7 Description ----------- This parameter controls whether ``mmanon`` will attempt to find and anonymize IPv6 addresses. If set to ``off``, all other ``ipv6.*`` parameters for this action are ignored. Note that this does not affect IPv6 addresses with embedded IPv4 parts, which are controlled by :ref:`embeddedIpv4.enable `. Input usage ----------- .. _mmanon.parameter.input.ipv6-enable-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv6.enable="off") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-ruleset.rst0000644000000000000000000000013215062756615024245 xustar0030 mtime=1758190989.195641035 30 atime=1764928596.776573948 30 ctime=1764935921.819555698 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-ruleset.rst0000664000175000017500000000221215062756615023706 0ustar00rgerrger.. _param-imudp-ruleset: .. _imudp.parameter.input.ruleset: Ruleset ======= .. index:: single: imudp; Ruleset single: Ruleset .. summary-start Assigns incoming messages to a specified ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Ruleset :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=RSYSLOG_DefaultRuleset :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Binds the listener to a specific :doc:`ruleset <../../concepts/multi_ruleset>`. Input usage ----------- .. _param-imudp-input-ruleset: .. _imudp.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imudp" Ruleset="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.inputudpserverbindruleset: - $InputUDPServerBindRuleset — maps to Ruleset (status: legacy) .. index:: single: imudp; $InputUDPServerBindRuleset single: $InputUDPServerBindRuleset See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-filecreatemode.rst0000644000000000000000000000013215062756615026414 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.613507489 30 ctime=1764935921.472550385 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-filecreatemode.rst0000664000175000017500000000220115062756615026053 0ustar00rgerrger.. _param-imjournal-filecreatemode: .. _imjournal.parameter.module.filecreatemode: .. meta:: :tag: module:imjournal :tag: parameter:FileCreateMode FileCreateMode ============== .. index:: single: imjournal; FileCreateMode single: FileCreateMode .. summary-start Sets the octal permission mode for the state file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: FileCreateMode :Scope: module :Type: integer :Default: module=0644 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Defines access permissions for the state file using a four-digit octal value. Actual permissions also depend on the process ``umask``. If in doubt, use ``global(umask="0000")`` at the beginning of the configuration file to remove any restrictions. Module usage ------------ .. _param-imjournal-module-filecreatemode: .. _imjournal.parameter.module.filecreatemode-usage: .. code-block:: rsyslog module(load="imjournal" FileCreateMode="...") Notes ----- - Value is interpreted as an octal number. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-headerless-hostname.rst0000644000000000000000000000013115062756615027023 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.309773736 29 ctime=1764935922.61856793 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-headerless-hostname.rst0000664000175000017500000000211415062756615026466 0ustar00rgerrger.. _param-pmrfc3164-headerless-hostname: .. _pmrfc3164.parameter.module.headerless-hostname: .. _pmrfc3164.parameter.module.headerless.hostname: headerless.hostname =================== .. index:: single: pmrfc3164; headerless.hostname single: headerless.hostname .. summary-start Override the hostname assigned to headerless messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: headerless.hostname :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module= :Required?: no :Introduced: 8.2508.0 Description ----------- By default, rsyslog uses the sender's IP address as the hostname for headerless messages. Set this option to provide a different hostname. Module usage ------------ .. _param-pmrfc3164-module-headerless-hostname: .. _pmrfc3164.parameter.module.headerless-hostname-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" headerless.hostname="example.local") See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-server.rst0000644000000000000000000000013215114522477025432 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.469642513 30 ctime=1764935922.140560612 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-server.rst0000664000175000017500000000140115114522477025072 0ustar00rgerrger.. _param-omclickhouse-server: .. _omclickhouse.parameter.input.server: server ====== .. index:: single: omclickhouse; server single: server .. summary-start Specifies the address of the ClickHouse server that receives events from this action. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: server :Scope: input :Type: word :Default: localhost :Required?: no :Introduced: not specified Description ----------- The address of a ClickHouse server. Input usage ----------- .. _omclickhouse.parameter.input.server-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" server="clickhouse.example.com") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-myprivkey.rst0000644000000000000000000000013215103346332025562 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.814482901 30 ctime=1764935921.365548747 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-myprivkey.rst0000664000175000017500000000161115103346332025225 0ustar00rgerrger.. _param-imdtls-tls-myprivkey: .. _imdtls.parameter.input.tls-myprivkey: tls.myPrivKey ============= .. index:: single: imdtls; tls.myPrivKey single: tls.myPrivKey .. summary-start Points to the private key file paired with ``tls.myCert``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.myPrivKey :Scope: input :Type: string :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- The private key file corresponding to ``tls.myCert``. This key is used for the cryptographic operations in the DTLS handshake. Input usage ----------- .. _imdtls.parameter.input.tls-myprivkey-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.myCert="/etc/rsyslog/server.pem" tls.myPrivKey="/etc/rsyslog/server.key") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsontransform-mode.rst0000644000000000000000000000013115103346332025611 xustar0029 mtime=1762512090.62717594 30 atime=1764928598.076613817 30 ctime=1764935922.012558653 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsontransform-mode.rst0000664000175000017500000000245215103346332025261 0ustar00rgerrger.. _param-mmjsontransform-mode: .. _mmjsontransform.parameter.input.mode: mode ==== .. index:: single: mmjsontransform; mode single: mode .. summary-start Chooses whether dotted keys are expanded or flattened during processing. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsontransform`. :Name: mode :Scope: input :Type: string :Default: unflatten :Required?: no :Introduced: 8.2410.0 Description ----------- Controls the transformation direction used by ``mmjsontransform``: ``unflatten`` (default) Expands dotted keys into nested containers. See :ref:`mmjsontransform-mode-unflatten` for details. ``flatten`` Collapses nested containers back into dotted keys. See :ref:`mmjsontransform-mode-flatten` for the full description. The comparison is case-insensitive. Omitting the parameter or providing an empty string selects ``unflatten``. Any other value triggers a configuration error. Input usage ----------- .. _param-mmjsontransform-mode-usage: .. _mmjsontransform.parameter.input.mode-usage: .. code-block:: rsyslog action(type="mmjsontransform" mode="flatten" input="$!normalized" output="$!normalized_flat") See also -------- See also the :doc:`main mmjsontransform module documentation <../../configuration/modules/mmjsontransform>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-maxframesize.rst0000644000000000000000000000013215062756615025433 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.435532763 30 ctime=1764935921.611552513 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-maxframesize.rst0000664000175000017500000000216015062756615025076 0ustar00rgerrger.. _param-imptcp-maxframesize: .. _imptcp.parameter.input.maxframesize: MaxFrameSize ============ .. index:: single: imptcp; MaxFrameSize single: MaxFrameSize .. summary-start Sets the maximum frame size when using octet counted mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: MaxFrameSize :Scope: input :Type: integer :Default: input=200000 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- When in octet counted mode, the frame size is given at the beginning of the message. With this parameter the max size this frame can have is specified and when the frame gets too large the mode is switched to octet stuffing. The max value this parameter can have was specified because otherwise the integer could become negative and this would result in a Segmentation Fault. (Max Value: 200000000) Input usage ----------- .. _param-imptcp-input-maxframesize: .. _imptcp.parameter.input.maxframesize-usage: .. code-block:: rsyslog input(type="imptcp" maxFrameSize="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-retry-addmetadata.rst0000644000000000000000000000013215114522477026346 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.480642783 30 ctime=1764935922.409564731 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-retry-addmetadata.rst0000664000175000017500000000201615114522477026011 0ustar00rgerrger.. _param-omhttp-retry-addmetadata: .. _omhttp.parameter.input.retry-addmetadata: retry.addmetadata ================= .. index:: single: omhttp; retry.addmetadata single: retry.addmetadata .. summary-start Adds HTTP response metadata to ``$!omhttp!response`` for messages handled by the retry logic. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: retry.addmetadata :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- When this option is enabled, omhttp will add the response metadata to ``$!omhttp!response``. There are three response metadata fields added: ``code``, ``body``, ``batch_index``. Input usage ----------- .. _omhttp.parameter.input.retry-addmetadata-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" retry="on" retryRuleSet="rs_omhttp_retry" retryAddMetadata="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhdfs-omhdfsdefaulttemplate.rst0000644000000000000000000000013115114522477027277 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.474642636 30 ctime=1764935922.342563705 rsyslog-8.2512.0/doc/source/reference/parameters/omhdfs-omhdfsdefaulttemplate.rst0000664000175000017500000000273415114522477026752 0ustar00rgerrger.. _param-omhdfs-omhdfsdefaulttemplate: .. _omhdfs.parameter.module.omhdfsdefaulttemplate: omhdfsDefaultTemplate ===================== .. index:: single: omhdfs; omhdfsDefaultTemplate single: omhdfsDefaultTemplate .. summary-start Sets the template omhdfs applies when no template is specified for an action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhdfs`. :Name: omhdfsDefaultTemplate :Scope: module :Type: word :Default: RSYSLOG_FileFormat :Required?: no :Introduced: Not documented Description ----------- Default template to be used when none is specified. This saves the work of specifying the same template repeatedly. Of course, the default template can be overwritten by specifying a template directly on an action. Module usage ------------ .. _omhdfs.parameter.module.omhdfsdefaulttemplate-usage: .. code-block:: none $ModLoad omhdfs $omhdfsFileName /var/log/hdfs/system.log $omhdfsDefaultTemplate RSYSLOG_FileFormat # write all messages to HDFS using the custom default template *.* :omhdfs: Legacy names (for reference) ---------------------------- Historic names/directives for compatibility. Do not use in new configs. .. _omhdfs.parameter.legacy.omhdfsdefaulttemplate: - ``$OMHDFSDefaultTemplate`` — maps to ``omhdfsDefaultTemplate`` (status: legacy) .. index:: single: omhdfs; $OMHDFSDefaultTemplate single: $OMHDFSDefaultTemplate See also -------- See also :doc:`../../configuration/modules/omhdfs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-port.rst0000644000000000000000000000013215071746523023736 xustar0030 mtime=1760021843.827420812 30 atime=1764928602.721755811 30 ctime=1764935922.576567287 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-port.rst0000664000175000017500000000202615071746523023402 0ustar00rgerrger.. _param-omsnmp-port: .. _omsnmp.parameter.module.port: Port ==== .. index:: single: omsnmp; Port single: Port .. summary-start Specifies the port used for sending SNMP traps. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Port :Scope: module :Type: integer :Default: module=162 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- The port which will be used, common values are port 162 or 161. Module usage ------------ .. _param-omsnmp-module-port: .. _omsnmp.parameter.module.port-usage: .. code-block:: rsyslog action(type="omsnmp" port="162") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmptargetport: - $actionsnmptargetport — maps to Port (status: legacy) .. index:: single: omsnmp; $actionsnmptargetport single: $actionsnmptargetport See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ignoreownmessages.rst0000644000000000000000000000013215062756615027045 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.010581131 30 ctime=1764935921.840556019 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ignoreownmessages.rst0000664000175000017500000000213615062756615026513 0ustar00rgerrger.. _param-imuxsock-ignoreownmessages: .. _imuxsock.parameter.input.ignoreownmessages: IgnoreOwnMessages ================= .. index:: single: imuxsock; IgnoreOwnMessages single: IgnoreOwnMessages .. summary-start Suppresses messages that originated from the same rsyslog instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: IgnoreOwnMessages :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 7.3.7 Description ----------- Ignore messages that originated from the same instance of rsyslogd. There usually is no reason to receive messages from ourselves. This setting is vital when writing messages to the systemd journal. .. seealso:: See :doc:`omjournal <../../configuration/modules/omjournal>` module documentation for a more in-depth description. Input usage ----------- .. _param-imuxsock-input-ignoreownmessages: .. _imuxsock.parameter.input.ignoreownmessages-usage: .. code-block:: rsyslog input(type="imuxsock" ignoreOwnMessages="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-name.rst0000644000000000000000000000013215103346332023643 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.770481547 30 ctime=1764935921.349548502 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-name.rst0000664000175000017500000000140715103346332023311 0ustar00rgerrger.. _param-imdtls-name: .. _imdtls.parameter.input.name: Name ==== .. index:: single: imdtls; name single: name .. summary-start Assigns a unique identifier to the imdtls input instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: name :Scope: input :Type: word :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Provides a unique name to the input module instance. This is useful for identifying the source of messages when multiple input modules are used. Input usage ----------- .. _imdtls.parameter.input.name-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" name="dtlsListener01") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-compression-driver.rst0000644000000000000000000000013215062756615026551 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.967671711 30 ctime=1764935922.267562556 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-compression-driver.rst0000664000175000017500000000222215062756615026213 0ustar00rgerrger.. _param-omfile-compression-driver: .. _omfile.parameter.module.compression-driver: compression.driver ================== .. index:: single: omfile; compression.driver single: compression.driver .. summary-start For compressed operation ("zlib mode"), this permits to set the compression driver to be used. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: compression.driver :Scope: module :Type: word :Default: module=zlib :Required?: no :Introduced: 8.2208.0 Description ----------- For compressed operation ("zlib mode"), this permits to set the compression driver to be used. Originally, only zlib was supported and still is the default. Since 8.2208.0 zstd is also supported. It provides much better compression ratios and performance, especially with multiple zstd worker threads enabled. Possible values are: - zlib - zstd Module usage ------------ .. _param-omfile-module-compression-driver: .. _omfile.parameter.module.compression-driver-usage: .. code-block:: rsyslog module(load="builtin:omfile" compression.driver="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-keepalive-time.rst0000644000000000000000000000013215114522477025630 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.461642317 30 ctime=1764935921.657553218 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-keepalive-time.rst0000664000175000017500000000222315114522477025273 0ustar00rgerrger.. _param-imrelp-keepalive-time: .. _imrelp.parameter.input.keepalive-time: keepAlive.time ============== .. index:: single: imrelp; keepAlive.time single: keepAlive.time .. summary-start Controls how long a connection stays idle before the first keep-alive probe is sent. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: keepAlive.time :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: Not documented Description ----------- The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked with keep-alive, this counter is not used any further. The default, 0, means that the operating system defaults are used. This only has an effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imrelp-input-keepalive-time-usage: .. _imrelp.parameter.input.keepalive-time-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" keepAlive="on" keepAlive.time="600") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdblookup-fields.rst0000644000000000000000000000013215071746523025060 xustar0030 mtime=1760021843.807420497 30 atime=1764928597.778604682 30 ctime=1764935921.968557979 rsyslog-8.2512.0/doc/source/reference/parameters/mmdblookup-fields.rst0000664000175000017500000000322515071746523024526 0ustar00rgerrger.. _param-mmdblookup-fields: .. _mmdblookup.parameter.input.fields: fields ====== .. index:: single: mmdblookup; fields single: fields .. summary-start Defines the list of database fields whose values are appended to the message. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdblookup`. :Name: fields :Scope: input :Type: array (word) :Default: none :Required?: yes :Introduced: 8.24.0 Description ----------- This parameter specifies the fields that will be appended to processed messages. The fields will always be appended in the container used by mmdblookup (which may be overridden by the ``container`` parameter on module load). By default, the lookup path (without a leading exclamation mark (``!``), if present) is used as the name for the resulting JSON property. This can be overridden by specifying a custom name. Use the following syntax to control the resulting variable name and lookup path: * ``:customName:!path!to!field`` — specify the custom variable name enclosed in colons, followed by the MaxMind DB path. * Exclamation marks (``!``) denote path levels within the database record. For example, to extract ``!city!names!en`` but rename it to ``cityname``, use ``:cityname:!city!names!en`` as the field value. Input usage ----------- .. _mmdblookup.parameter.input.fields-usage: .. code-block:: rsyslog action(type="mmdblookup" key="!clientip" mmdbFile="/etc/rsyslog.d/GeoLite2-City.mmdb" fields=[":continent:!continent!code", "!country!iso_code", ":loc:!location"]) See also -------- See also :doc:`../../configuration/modules/mmdblookup`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-uid.rst0000644000000000000000000000013215114522477023533 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.482642833 30 ctime=1764935922.434565113 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-uid.rst0000664000175000017500000000126315114522477023201 0ustar00rgerrger.. _param-omhttp-uid: .. _omhttp.parameter.input.uid: uid === .. index:: single: omhttp; uid single: uid .. summary-start Provides the username for HTTP basic authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: uid :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The username for basic auth. Input usage ----------- .. _omhttp.parameter.input.uid-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" uid="api-user" pwd="secret" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-fields.rst0000644000000000000000000000013215071746523024525 xustar0030 mtime=1760021843.805420466 30 atime=1764928597.704602413 30 ctime=1764935921.952557734 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-fields.rst0000664000175000017500000000377715071746523024207 0ustar00rgerrger.. _param-mmdarwin-fields: .. _mmdarwin.parameter.input.fields: fields ====== .. index:: single: mmdarwin; fields single: fields .. summary-start Defines the array of values that mmdarwin forwards to Darwin as parameters. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: fields :Scope: input :Type: array :Default: input=none :Required?: yes :Introduced: at least 8.x, possibly earlier Description ----------- Array containing values to be sent to Darwin as parameters. Two types of values can be set: * if it starts with a bang (:json:`"!"`) or a dot (:json:`"."`), mmdarwin will search in the JSON-parsed log line (:json:`"!"`) or in rsyslog local variables (:json:`"."`) for the associated value. For nested properties, use additional bangs as separators (for example, :json:`"!data!status"` reads the :json:`"status"` property inside the :json:`"data"` object). * otherwise, the value is considered static, and will be forwarded directly to Darwin. For example, given the following log line: .. code-block:: json { "from": "192.168.1.42", "date": "2012-12-21 00:00:00", "status": "200", "data": { "status": true, "message": "Request processed correctly" } } and the :json:`"fields"` array: .. code-block:: none ["!from", "!data!status", "rsyslog"] The parameters sent to Darwin would be :json:`"192.168.1.42"`, :json:`true` and :json:`"rsyslog"`. .. note:: The order of the parameters is important and must match the order expected by the Darwin filter. Refer to `Darwin documentation`_ to see what each filter requires as parameters. .. _`Darwin documentation`: https://github.com/VultureProject/darwin/wiki Input usage ----------- .. _param-mmdarwin-input-fields-usage: .. _mmdarwin.parameter.input.fields-usage: .. code-block:: rsyslog action(type="mmdarwin" fields=["!from", "!data!status", "rsyslog"]) See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-framingfix-cisco-asa.rst0000644000000000000000000000013115062756615026731 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.598537772 30 ctime=1764935921.597552299 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-framingfix-cisco-asa.rst0000664000175000017500000000202415062756615026374 0ustar00rgerrger.. _param-imptcp-framingfix-cisco-asa: .. _imptcp.parameter.input.framingfix-cisco-asa: Framingfix.cisco.asa ==================== .. index:: single: imptcp; Framingfix.cisco.asa single: Framingfix.cisco.asa .. summary-start Ignores a leading space after a line feed to work around Cisco ASA framing issues. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Framingfix.cisco.asa :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Cisco very occasionally sends a space after a line feed, which thrashes framing if not taken special care of. When this parameter is set to "on", we permit space *in front of the next frame* and ignore it. Input usage ----------- .. _param-imptcp-input-framingfix-cisco-asa: .. _imptcp.parameter.input.framingfix-cisco-asa-usage: .. code-block:: rsyslog input(type="imptcp" framingfix.cisco.asa="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-usepidfromsystem.rst0000644000000000000000000000013215062756615026730 xustar0030 mtime=1758190989.197641063 30 atime=1764928597.050582357 30 ctime=1764935921.897556892 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-usepidfromsystem.rst0000664000175000017500000000266215062756615026402 0ustar00rgerrger.. _param-imuxsock-usepidfromsystem: .. _imuxsock.parameter.input.usepidfromsystem: UsePIDFromSystem ================ .. index:: single: imuxsock; UsePIDFromSystem single: UsePIDFromSystem .. summary-start Obtains the process ID from the log socket instead of the message. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: UsePIDFromSystem :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies if the pid being logged shall be obtained from the log socket itself. If so, the TAG part of the message is rewritten. It is recommended to turn this option on, but the default is "off" to keep compatible with earlier versions of rsyslog. Input usage ----------- .. _param-imuxsock-input-usepidfromsystem: .. _imuxsock.parameter.input.usepidfromsystem-usage: .. code-block:: rsyslog input(type="imuxsock" usePidFromSystem="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketusepidfromsystem: - $InputUnixListenSocketUsePIDFromSystem — maps to UsePIDFromSystem (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketUsePIDFromSystem single: $InputUnixListenSocketUsePIDFromSystem See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-name.rst0000644000000000000000000000013015062756615023656 xustar0030 mtime=1758190989.190640964 29 atime=1764928595.41753221 29 ctime=1764935921.61855262 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-name.rst0000664000175000017500000000245515062756615023332 0ustar00rgerrger.. _param-imptcp-name: .. _imptcp.parameter.input.name: Name ==== .. index:: single: imptcp; Name single: Name .. summary-start Sets the inputname property used for tagging messages and statistics. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Name :Scope: input :Type: string :Default: input=imptcp :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets a name for the inputname property. If no name is set "imptcp" is used by default. Setting a name is not strictly necessary, but can be useful to apply filtering based on which input the message was received from. Note that the name also shows up in :doc:`impstats <../../configuration/modules/impstats>` logs. Input usage ----------- .. _param-imptcp-input-name: .. _imptcp.parameter.input.name-usage: .. code-block:: rsyslog input(type="imptcp" name="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverinputname: - $InputPTCPServerInputName — maps to Name (status: legacy) .. index:: single: imptcp; $InputPTCPServerInputName single: $InputPTCPServerInputName See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-statefile.rst0000644000000000000000000000013115062756615024670 xustar0030 mtime=1758190989.185640893 29 atime=1764928594.14449306 30 ctime=1764935921.442549926 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-statefile.rst0000664000175000017500000000327115062756615024340 0ustar00rgerrger.. _param-imfile-statefile: .. _imfile.parameter.input.statefile: .. _imfile.parameter.statefile: stateFile ========= .. index:: single: imfile; stateFile single: stateFile .. summary-start Deprecated; sets a fixed state file name for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: stateFile :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the name of this file's state file. This parameter should usually **not** be used. When wildcards are present in the monitored file name, all matching files share the same state file, which typically causes confusion and is unlikely to work properly. Upon startup, rsyslog tries to detect such cases and emits warning messages, but complex wildcard patterns may go unnoticed. For details, see :ref:`State-Files` in the module documentation. Input usage ----------- .. _param-imfile-input-statefile: .. _imfile.parameter.input.statefile-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" stateFile="/path/to/state") Notes ----- - Deprecated; rely on automatically generated state file names instead. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilestatefile: - ``$InputFileStateFile`` — maps to stateFile (status: legacy) .. index:: single: imfile; $InputFileStateFile single: $InputFileStateFile See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-template.rst0000644000000000000000000000013215062756615026425 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.609660756 30 ctime=1764935922.242562174 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-template.rst0000664000175000017500000000157015062756615026074 0ustar00rgerrger.. _param-omelasticsearch-template: .. _omelasticsearch.parameter.module.template: template ======== .. index:: single: omelasticsearch; template single: template .. summary-start Template used to render the JSON document sent to Elasticsearch. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: template :Scope: action :Type: word :Default: action=StdJSONFmt :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Defines the rsyslog template that generates the JSON payload. The default `StdJSONFmt` includes common fields. Action usage ------------ .. _param-omelasticsearch-action-template: .. _omelasticsearch.parameter.action.template: .. code-block:: rsyslog action(type="omelasticsearch" template="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-persiststateaftersubmission.rst0000644000000000000000000000013215062756615030601 xustar0030 mtime=1758190989.185640893 30 atime=1764928594.127492537 30 ctime=1764935921.417549543 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-persiststateaftersubmission.rst0000664000175000017500000000252115062756615030245 0ustar00rgerrger.. _param-imfile-persiststateaftersubmission: .. _imfile.parameter.input.persiststateaftersubmission: .. _imfile.parameter.persiststateaftersubmission: persistStateAfterSubmission =========================== .. index:: single: imfile; persistStateAfterSubmission single: persistStateAfterSubmission .. summary-start Persists state file information after each batch submission for robustness. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: persistStateAfterSubmission :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: 8.2006.0 Description ----------- When switched ``on``, imfile persists state file information after a batch of messages has been submitted. This enhances robustness against unclean shutdowns, but may cause frequent state file writes and degrade performance, depending on overall rsyslog configuration. Input usage ----------- .. _param-imfile-input-persiststateaftersubmission: .. _imfile.parameter.input.persiststateaftersubmission-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" persistStateAfterSubmission="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-address.rst0000644000000000000000000000013215062756615024207 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.742572904 30 ctime=1764935921.792555284 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-address.rst0000664000175000017500000000220415062756615023651 0ustar00rgerrger.. _param-imudp-address: .. _imudp.parameter.input.address: Address ======= .. index:: single: imudp; Address single: Address .. summary-start Local address that UDP server binds to; ``*`` uses all interfaces. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Address :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Local IP address (or name) the UDP server should bind to. Use ``*`` to bind to all of the machine's addresses. Input usage ----------- .. _param-imudp-input-address: .. _imudp.parameter.input.address-usage: .. code-block:: rsyslog input(type="imudp" Address="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.udpserveraddress: - $UDPServerAddress — maps to Address (status: legacy) .. index:: single: imudp; $UDPServerAddress single: $UDPServerAddress See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-skipverifyhost.rst0000644000000000000000000000013215062756615027703 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.717664061 30 ctime=1764935922.239562128 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-skipverifyhost.rst0000664000175000017500000000161215062756615027347 0ustar00rgerrger.. _param-omelasticsearch-skipverifyhost: .. _omelasticsearch.parameter.module.skipverifyhost: skipverifyhost ============== .. index:: single: omelasticsearch; skipverifyhost single: skipverifyhost .. summary-start Disable TLS host name verification (insecure, for testing). .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: skipverifyhost :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Sets the curl `CURLOPT_SSL_VERIFYHOST` option to `0`. Use only for debugging. Action usage ------------ .. _param-omelasticsearch-action-skipverifyhost: .. _omelasticsearch.parameter.action.skipverifyhost: .. code-block:: rsyslog action(type="omelasticsearch" skipverifyhost="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-filtercode.rst0000644000000000000000000000013115071746523025376 xustar0030 mtime=1760021843.806420481 30 atime=1764928597.696602167 29 ctime=1764935921.95555778 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-filtercode.rst0000664000175000017500000000171015071746523025042 0ustar00rgerrger.. _param-mmdarwin-filtercode: .. _mmdarwin.parameter.input.filtercode: filtercode ========== .. index:: single: mmdarwin; filtercode single: filtercode .. summary-start Sets the legacy Darwin filter code expected by older Darwin filters. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: filtercode :Scope: input :Type: word :Default: input=0x00000000 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Each Darwin module has a unique filter code. For example, the code of the hostlookup filter is :json:`"0x66726570"`. This code was mandatory but is now obsolete. It can be omitted or left at its default value. Input usage ----------- .. _param-mmdarwin-input-filtercode-usage: .. _mmdarwin.parameter.input.filtercode-usage: .. code-block:: rsyslog action(type="mmdarwin" filterCode="0x72657075") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-ratelimit-interval.rst0000644000000000000000000000013015103061376030411 xustar0030 mtime=1762419454.852381127 28 atime=1764928599.7646655 30 ctime=1764935922.218561806 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-ratelimit-interval.rst0000664000175000017500000000176615103061376030071 0ustar00rgerrger.. _param-omelasticsearch-ratelimit-interval: .. _omelasticsearch.parameter.module.ratelimit-interval: .. _omelasticsearch.parameter.module.ratelimit.interval: ratelimit.interval ================== .. index:: single: omelasticsearch; ratelimit.interval single: ratelimit.interval .. summary-start Seconds over which retry rate limiting is calculated. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: ratelimit.interval :Scope: action :Type: integer :Default: action=600 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Defines the interval for rate limiting when `retryfailures` is enabled. Set to `0` to disable. Action usage ------------ .. _param-omelasticsearch-action-ratelimit-interval: .. _omelasticsearch.parameter.action.ratelimit-interval: .. code-block:: rsyslog action(type="omelasticsearch" ratelimit.interval="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-dhbits.rst0000644000000000000000000000013015114522477025002 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.464642391 28 ctime=1764935921.6825536 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-dhbits.rst0000664000175000017500000000245015114522477024451 0ustar00rgerrger.. _param-imrelp-tls-dhbits: .. _imrelp.parameter.input.tls-dhbits: tls.dhBits ========== .. index:: single: imrelp; tls.dhBits single: tls.dhBits .. summary-start Specifies the Diffie-Hellman key size, overriding the librelp default when set. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.dhBits :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: Not documented Description ----------- This setting controls how many bits are used for Diffie-Hellman key generation. If not set, the librelp default is used. For security reasons, at least 1024 bits should be used. Please note that the number of bits must be supported by GnuTLS. If an invalid number is given, rsyslog will report an error when the listener is started. We do this to be transparent to changes/upgrades in GnuTLS (to check at config processing time, we would need to hardcode the supported bits and keep them in sync with GnuTLS - this is even impossible when custom GnuTLS changes are made...). Input usage ----------- .. _param-imrelp-input-tls-dhbits-usage: .. _imrelp.parameter.input.tls-dhbits-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.dhBits="2048") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhdfs-omhdfsfilename.rst0000644000000000000000000000013115114522477025677 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.474642636 30 ctime=1764935922.345563751 rsyslog-8.2512.0/doc/source/reference/parameters/omhdfs-omhdfsfilename.rst0000664000175000017500000000220715114522477025345 0ustar00rgerrger.. _param-omhdfs-omhdfsfilename: .. _omhdfs.parameter.module.omhdfsfilename: omhdfsFileName ============== .. index:: single: omhdfs; omhdfsFileName single: omhdfsFileName .. summary-start Sets the HDFS path of the file that omhdfs writes log messages to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhdfs`. :Name: omhdfsFileName :Scope: module :Type: word :Required?: yes :Introduced: Not documented Description ----------- The name of the file to which the output data shall be written. Module usage ------------ .. _omhdfs.parameter.module.omhdfsfilename-usage: .. code-block:: none $ModLoad omhdfs $omhdfsFileName /var/log/hdfs/system.log # write all messages to the specified HDFS file *.* :omhdfs: Legacy names (for reference) ---------------------------- Historic names/directives for compatibility. Do not use in new configs. .. _omhdfs.parameter.legacy.omhdfsfilename: - ``$OMHDFSFileName`` — maps to ``omhdfsFileName`` (status: legacy) .. index:: single: omhdfs; $OMHDFSFileName single: $OMHDFSFileName See also -------- See also :doc:`../../configuration/modules/omhdfs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-parsehostname.rst0000644000000000000000000000013215062756615026157 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.124584627 30 ctime=1764935921.844556081 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-parsehostname.rst0000664000175000017500000000155515062756615025631 0ustar00rgerrger.. _param-imuxsock-parsehostname: .. _imuxsock.parameter.input.parsehostname: ParseHostname ============= .. index:: single: imuxsock; ParseHostname single: ParseHostname .. summary-start Expects hostnames in messages when the special parser is disabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: ParseHostname :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: 8.9.0 Description ----------- Equivalent to the ``SysSock.ParseHostname`` module parameter, but applies to the input that is being defined. .. versionadded:: 8.9.0 Input usage ----------- .. _param-imuxsock-input-parsehostname: .. _imuxsock.parameter.input.parsehostname-usage: .. code-block:: rsyslog input(type="imuxsock" parseHostname="on") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdblookup-reloadonhup.rst0000644000000000000000000000013215071746523026132 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.786604927 30 ctime=1764935921.976558102 rsyslog-8.2512.0/doc/source/reference/parameters/mmdblookup-reloadonhup.rst0000664000175000017500000000221215071746523025573 0ustar00rgerrger.. _param-mmdblookup-reloadonhup: .. _mmdblookup.parameter.input.reloadonhup: reloadonhup =========== .. index:: single: mmdblookup; reloadonhup single: reloadonhup .. summary-start Controls whether mmdblookup reopens the MaxMind database after a HUP signal. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdblookup`. :Name: reloadonhup :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: 8.24.0 Description ----------- When this setting is ``on``, the action closes and reopens the configured MaxMind DB file whenever rsyslog receives a HUP signal. This lets updated GeoIP data become effective without restarting the daemon. Set it to ``off`` if you prefer to keep the currently loaded database until the action is restarted manually. Input usage ----------- .. _mmdblookup.parameter.input.reloadonhup-usage: .. code-block:: rsyslog action(type="mmdblookup" key="!clientip" mmdbFile="/etc/rsyslog.d/GeoLite2-City.mmdb" fields=["!continent!code", "!location"] reloadOnHup="off") See also -------- See also :doc:`../../configuration/modules/mmdblookup`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-timeout.rst0000644000000000000000000000013115114522477025611 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.470642538 29 ctime=1764935922.14756072 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-timeout.rst0000664000175000017500000000146015114522477025257 0ustar00rgerrger.. _param-omclickhouse-timeout: .. _omclickhouse.parameter.input.timeout: timeout ======= .. index:: single: omclickhouse; timeout single: timeout .. summary-start Configures the send timeout, in milliseconds, for ClickHouse HTTP requests. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: timeout :Scope: input :Type: int (milliseconds) :Default: 0 :Required?: no :Introduced: not specified Description ----------- This parameter sets the timeout for sending data to ClickHouse. Value is given in milliseconds. Input usage ----------- .. _omclickhouse.parameter.input.timeout-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" timeout="4500") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgssservermaxsessions.rst0000644000000000000000000000013115114522477030652 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.454642145 29 ctime=1764935921.45655014 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgssservermaxsessions.rst0000664000175000017500000000260315114522477030320 0ustar00rgerrger.. _param-imgssapi-inputgssservermaxsessions: .. _imgssapi.parameter.input.inputgssservermaxsessions: InputGSSServerMaxSessions ========================= .. index:: single: imgssapi; InputGSSServerMaxSessions single: InputGSSServerMaxSessions .. summary-start Sets the maximum number of concurrent sessions supported by the server. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSServerMaxSessions :Scope: input :Type: integer :Default: 200 :Required?: no :Introduced: 3.11.5 Description ----------- Sets the maximum number of concurrent sessions supported by the listener. .. note:: Due to a long-standing bug, the configured limit is not forwarded to the underlying TCP listener. Regardless of the value set here, the listener currently enforces the built-in default of 200 sessions. Input usage ----------- .. _imgssapi.parameter.input.inputgssservermaxsessions-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssServerMaxSessions 200 Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgssservermaxsessions: - $inputGssServerMaxSessions — maps to InputGSSServerMaxSessions (status: legacy) .. index:: single: imgssapi; $inputGssServerMaxSessions single: $inputGssServerMaxSessions See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dynafile.rst0000644000000000000000000000013215062756615024512 xustar0030 mtime=1758190989.207641205 30 atime=1764928600.073674952 30 ctime=1764935922.290562909 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dynafile.rst0000664000175000017500000000347315062756615024165 0ustar00rgerrger.. _param-omfile-dynafile: .. _omfile.parameter.module.dynafile: dynaFile ======== .. index:: single: omfile; dynaFile single: dynaFile .. summary-start For each message, the file name is generated based on the given template. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dynaFile :Scope: action :Type: string :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- For each message, the file name is generated based on the given template. Then, this file is opened. As with the *file* property, data is appended if the file already exists. If the file does not exist, a new file is created. The template given in "templateName" is just a regular :doc:`rsyslog template <../../configuration/templates>`, so you have full control over how to format the file name. To avoid path traversal attacks, *you must make sure that the template used properly escapes file paths*. This is done by using the *securepath* parameter in the template's property statements, or the *secpath-drop* or *secpath-replace* property options with the property replacer. Either file or dynaFile can be used, but not both. If both are given, dynaFile will be used. A cache of recent files is kept. Note that this cache can consume quite some memory (especially if large buffer sizes are used). Files are kept open as long as they stay inside the cache. Files are removed from the cache when a HUP signal is sent, the *closeTimeout* occurs, or the cache runs out of space, in which case the least recently used entry is evicted. Action usage ------------ .. _param-omfile-action-dynafile: .. _omfile.parameter.action.dynafile: .. code-block:: rsyslog action(type="omfile" dynaFile="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-path.rst0000644000000000000000000000013215062756615023674 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.341529874 30 ctime=1764935921.625552728 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-path.rst0000664000175000017500000000136215062756615023342 0ustar00rgerrger.. _param-imptcp-path: .. _imptcp.parameter.input.path: Path ==== .. index:: single: imptcp; Path single: Path .. summary-start Specifies a Unix-domain socket path for the listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Path :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- A path on the filesystem for a unix domain socket. It is an error to specify both ``path`` and ``port``. Input usage ----------- .. _param-imptcp-input-path: .. _imptcp.parameter.input.path-usage: .. code-block:: rsyslog input(type="imptcp" path="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-detect-yearaftertimestamp.rst0000644000000000000000000000013115062756615030244 xustar0029 mtime=1758190989.21364129 30 atime=1764928603.290773157 30 ctime=1764935922.608567777 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-detect-yearaftertimestamp.rst0000664000175000017500000000240415062756615027711 0ustar00rgerrger.. _param-pmrfc3164-detect-yearaftertimestamp: .. _pmrfc3164.parameter.module.detect-yearaftertimestamp: .. _pmrfc3164.parameter.module.detect.YearAfterTimestamp: detect.YearAfterTimestamp ========================= .. index:: single: pmrfc3164; detect.YearAfterTimestamp single: detect.YearAfterTimestamp .. summary-start Treat a year following the timestamp as part of the timestamp instead of the hostname. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: detect.YearAfterTimestamp :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Some devices append the year directly after the timestamp, which would otherwise be parsed as the hostname. When enabled, years between 2000 and 2099 are treated as part of the timestamp. Module usage ------------ .. _param-pmrfc3164-module-detect-yearaftertimestamp: .. _pmrfc3164.parameter.module.detect-yearaftertimestamp-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" detect.YearAfterTimestamp="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-partitions-number.rst0000644000000000000000000000013215062756615026537 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.448716966 30 ctime=1764935922.470565664 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-partitions-number.rst0000664000175000017500000000162615062756615026210 0ustar00rgerrger.. _param-omkafka-partitions-number: .. _omkafka.parameter.module.partitions-number: Partitions.number ================= .. index:: single: omkafka; Partitions.number single: Partitions.number .. summary-start Number of partitions to load-balance across. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Partitions.number :Scope: action :Type: integer :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, specifies how many partitions exist and activates load-balancing among them. The number must match the topic's partition count. Action usage ------------ .. _param-omkafka-action-partitions-number: .. _omkafka.parameter.action.partitions-number: .. code-block:: rsyslog action(type="omkafka" Partitions.number="3") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsontransform-output.rst0000644000000000000000000000013115103346332026225 xustar0029 mtime=1762512090.62817595 30 atime=1764928598.074613756 30 ctime=1764935922.014558683 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsontransform-output.rst0000664000175000017500000000243015103346332025671 0ustar00rgerrger.. _param-mmjsontransform-output: .. _mmjsontransform.parameter.input.output: output ====== .. index:: single: mmjsontransform; output single: output .. summary-start Sets the destination property that receives the rewritten JSON tree. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsontransform`. :Name: output :Scope: input :Type: string :Default: none :Required?: yes :Introduced: 8.2410.0 Description ----------- Defines where the transformed JSON object is stored on the message. The property must use a JSON-capable prefix (``$!``, ``$.`` or ``$/``). When the configuration uses a leading ``$`` symbol, it is stripped automatically before validation. The module rejects other prefixes during configuration. At runtime ``mmjsontransform`` verifies that the destination property does not already exist. Attempting to overwrite an existing value raises an error and the action aborts without modifying the message. Input usage ----------- .. _param-mmjsontransform-output-usage: .. _mmjsontransform.parameter.input.output-usage: .. code-block:: rsyslog action(type="mmjsontransform" input="$!raw" output="$!normalized") See also -------- See also the :doc:`main mmjsontransform module documentation <../../configuration/modules/mmjsontransform>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-ignorenonvalidstatefile.rst0000644000000000000000000000013215062756615030363 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.657508843 30 ctime=1764935921.476550447 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-ignorenonvalidstatefile.rst0000664000175000017500000000243515062756615030033 0ustar00rgerrger.. _param-imjournal-ignorenonvalidstatefile: .. _imjournal.parameter.module.ignorenonvalidstatefile: .. meta:: :tag: module:imjournal :tag: parameter:IgnoreNonValidStatefile IgnoreNonValidStatefile ======================= .. index:: single: imjournal; IgnoreNonValidStatefile single: IgnoreNonValidStatefile .. summary-start Ignores corrupt state files and restarts reading from the beginning. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: IgnoreNonValidStatefile :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When a corrupted state file is encountered, the module discards it and continues reading from the start of the journal (or from the end if ``IgnorePreviousMessages`` is enabled). A new valid state file is written after the next state persistence or shutdown. Module usage ------------ .. _param-imjournal-module-ignorenonvalidstatefile: .. _imjournal.parameter.module.ignorenonvalidstatefile-usage: .. code-block:: rsyslog module(load="imjournal" IgnoreNonValidStatefile="...") Notes ----- - Historic documentation called this a ``binary`` option; it is boolean. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-template.rst0000644000000000000000000000013215114522477025033 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.484642882 30 ctime=1764935922.499566108 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-template.rst0000664000175000017500000000250015114522477024474 0ustar00rgerrger.. _param-omlibdbi-template: .. _omlibdbi.parameter.module.template: .. _omlibdbi.parameter.input.template: Template ======== .. index:: single: omlibdbi; Template single: Template .. summary-start Defines the template used to render records, either globally for the module or for a specific action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: Template :Scope: module, input :Type: word :Default: module=StdDBFmt; input=inherits module :Required?: no :Introduced: Not documented Description ----------- Set the default template that omlibdbi uses when writing to the database, then optionally override it per action. If no template is provided at the action or module level, omlibdbi uses the built-in ``StdDBFmt`` template. Module usage ------------ .. _param-omlibdbi-module-template-usage: .. _omlibdbi.parameter.module.template-usage: .. code-block:: rsyslog module(load="omlibdbi" template="dbTemplate") Input usage ----------- .. _param-omlibdbi-input-template-usage: .. _omlibdbi.parameter.input.template-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog" template="structuredDb") See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv4-mode.rst0000644000000000000000000000013215071746523024532 xustar0030 mtime=1760021843.803420434 30 atime=1764928597.311590361 30 ctime=1764935921.932557428 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv4-mode.rst0000664000175000017500000000425715071746523024206 0ustar00rgerrger.. _param-mmanon-ipv4-mode: .. _mmanon.parameter.input.ipv4-mode: ipv4.mode ========= .. index:: single: mmanon; ipv4.mode single: ipv4.mode .. summary-start Selects the IPv4 anonymization mode used by the mmanon action. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv4.mode :Scope: input :Type: string :Default: input=zero :Required?: no :Introduced: 7.3.7 Description ----------- The available modes are ``simple``, ``random``, ``random-consistent``, and ``zero``. In simple mode, only octets as a whole can be anonymized and the length of the message is never changed. This means that when the last three octets of the address 10.1.12.123 are anonymized, the result will be 10.x.xx.xxx. The replacement character is configurable via :ref:`ipv4.replaceChar `. This means that the length of the original octets is still visible and may be used to draw some privacy-evasive conclusions. This mode is slightly faster than the other modes, and this may matter in high throughput environments. The modes ``random`` and ``random-consistent`` are very similar, in that they both anonymize IP addresses by randomizing the last bits (any number) of a given address. However, while ``random`` mode assigns a new random IP address for every address in a message, ``random-consistent`` will assign the same randomized address to every instance of the same original address. The default ``zero`` mode will do full anonymization of any number of bits. It will also normalize the address, so that no information about the original IP address is available. For example, if 24 bits are anonymized, 10.1.12.123 would be anonymized to 10.0.0.0. Input usage ----------- .. _mmanon.parameter.input.ipv4-mode-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv4.mode="random-consistent") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmanon.parameter.legacy.mode: - mode — maps to ipv4.mode (status: legacy) .. index:: single: mmanon; mode single: mode See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-main.rst0000644000000000000000000000013215062756615024370 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.681509581 30 ctime=1764935921.481550523 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-main.rst0000664000175000017500000000202715062756615024035 0ustar00rgerrger.. _param-imjournal-main: .. _imjournal.parameter.input.main: .. meta:: :tag: module:imjournal :tag: parameter:Main Main ==== .. index:: single: imjournal; Main single: Main .. summary-start Runs the input's ruleset on the main thread and stops reading if outputs block. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: Main :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: 8.2312.0 Description ----------- When enabled, the input module executes its bound ruleset in the main thread and pauses ingestion if the output side cannot accept data. Only the first input with ``Main="on"`` is treated as such; others run in background threads. Input usage ----------- .. _param-imjournal-input-main: .. _imjournal.parameter.input.main-usage: .. code-block:: rsyslog input(type="imjournal" Main="...") Notes ----- - Earlier documentation misclassified this option; it is boolean. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-dstmetadatapath.rst0000644000000000000000000000013215071746523027312 xustar0030 mtime=1760021843.813420591 30 atime=1764928598.203617708 30 ctime=1764935922.038559051 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-dstmetadatapath.rst0000664000175000017500000000170115071746523026755 0ustar00rgerrger.. _param-mmkubernetes-dstmetadatapath: .. _mmkubernetes.parameter.action.dstmetadatapath: dstmetadatapath =============== .. index:: single: mmkubernetes; dstmetadatapath single: dstmetadatapath .. summary-start Defines where the ``kubernetes`` and ``docker`` properties are written. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: dstmetadatapath :Scope: action :Type: word :Default: $! :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This is the where the `kubernetes` and `docker` properties will be written. By default, the module will add `$!kubernetes` and `$!docker`. Action usage ------------ .. _param-mmkubernetes-action-dstmetadatapath: .. _mmkubernetes.parameter.action.dstmetadatapath-usage: .. code-block:: rsyslog action(type="mmkubernetes" dstMetadataPath="$!") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-failedmsgfile.rst0000644000000000000000000000013215062756615025650 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.540719775 30 ctime=1764935922.459565496 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-failedmsgfile.rst0000664000175000017500000000157415062756615025323 0ustar00rgerrger.. _param-omkafka-failedmsgfile: .. _omkafka.parameter.module.failedmsgfile: failedMsgFile ============= .. index:: single: omkafka; failedMsgFile single: failedMsgFile .. summary-start File that stores messages saved by `KeepFailedMessages`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: failedMsgFile :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: 8.28.0 Description ----------- .. versionadded:: 8.28.0 Filename where the failed messages should be stored. Must be set when ``KeepFailedMessages`` is enabled. Action usage ------------ .. _param-omkafka-action-failedmsgfile: .. _omkafka.parameter.action.failedmsgfile: .. code-block:: rsyslog action(type="omkafka" failedMsgFile="/var/spool/rsyslog/failed.kafkamsgs") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-ruleset.rst0000644000000000000000000000013215103346332024406 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.778481793 30 ctime=1764935921.353548563 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-ruleset.rst0000664000175000017500000000140415103346332024051 0ustar00rgerrger.. _param-imdtls-ruleset: .. _imdtls.parameter.input.ruleset: Ruleset ======= .. index:: single: imdtls; ruleset single: ruleset .. summary-start Binds received DTLS messages to the specified processing ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: ruleset :Scope: input :Type: word :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Determines the ruleset to which the imdtls input will be bound. This can be overridden at the instance level. Input usage ----------- .. _imdtls.parameter.input.ruleset-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" ruleset="secure-logs") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-template.rst0000644000000000000000000000013115114522477024527 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.486642931 29 ctime=1764935922.52056643 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-template.rst0000664000175000017500000000204115114522477024171 0ustar00rgerrger.. _param-ommail-template: .. _ommail.parameter.input.template: template ======== .. index:: single: ommail; template single: template .. summary-start Selects the template used for the mail body when body text is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: template :Scope: input :Type: word :Default: input=RSYSLOG_FileFormat :Required?: no :Introduced: 8.5.0 Description ----------- Specifies the name of the template for the mail body. This parameter is only effective if :ref:`param-ommail-body-enable` is "on" (which is the default). Input usage ------------ .. _ommail.parameter.input.template-usage: .. code-block:: rsyslog module(load="ommail") template(name="mailBody" type="string" string="Message: %msg%") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" template="mailBody" ) See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-errorfile.rst0000644000000000000000000000013215062756615025046 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.464717455 30 ctime=1764935922.457565465 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-errorfile.rst0000664000175000017500000000156515062756615024521 0ustar00rgerrger.. _param-omkafka-errorfile: .. _omkafka.parameter.module.errorfile: errorFile ========= .. index:: single: omkafka; errorFile single: errorFile .. summary-start Write failed messages to this JSON file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: errorFile :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, messages that could not be sent are written to the specified file. Each entry is JSON and contains the full message plus the Kafka error number and reason. Action usage ------------ .. _param-omkafka-action-errorfile: .. _omkafka.parameter.action.errorfile: .. code-block:: rsyslog action(type="omkafka" errorFile="/var/log/omkafka-error.json") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-parent.rst0000644000000000000000000000013115062756615026102 xustar0030 mtime=1758190989.203641148 29 atime=1764928599.63266146 30 ctime=1764935922.209561669 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-parent.rst0000664000175000017500000000146415062756615025554 0ustar00rgerrger.. _param-omelasticsearch-parent: .. _omelasticsearch.parameter.module.parent: parent ====== .. index:: single: omelasticsearch; parent single: parent .. summary-start Parent document ID assigned to indexed events. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: parent :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Adds a parent ID to each record. The mapping must define a corresponding parent field. Action usage ------------ .. _param-omelasticsearch-action-parent: .. _omelasticsearch.parameter.action.parent: .. code-block:: rsyslog action(type="omelasticsearch" parent="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmtaghostname-tag.rst0000644000000000000000000000013215071746523025060 xustar0030 mtime=1760021843.823420749 30 atime=1764928598.746634341 30 ctime=1764935922.098559969 rsyslog-8.2512.0/doc/source/reference/parameters/mmtaghostname-tag.rst0000664000175000017500000000205015071746523024521 0ustar00rgerrger.. _param-mmtaghostname-tag: .. _mmtaghostname.parameter.input.tag: tag === .. index:: single: mmtaghostname; tag single: tag .. summary-start Assigns a tag to messages. This is useful for inputs like ``imudp`` or ``imtcp`` that do not provide a tag. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmtaghostname`. :Name: tag :Scope: input :Type: string :Default: none :Required?: no :Introduced: at least 7.0, possibly earlier Description ----------- The tag to be assigned to messages processed by this module. This is often used to route messages to different rulesets or output actions based on the tag. If you would like to see the colon after the tag, you need to include it when you assign a tag value, like so: ``tag="myTagValue:"``. If this parameter is not set, message tags are not modified. Input usage ----------- .. _mmtaghostname.parameter.input.tag-usage: .. code-block:: rsyslog action(type="mmtaghostname" tag="front") See also -------- * :doc:`../../configuration/modules/mmtaghostname` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-escapelf.rst0000644000000000000000000000013215062756615025023 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.695479237 30 ctime=1764935921.334548272 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-escapelf.rst0000664000175000017500000000171715062756615024475 0ustar00rgerrger.. _param-imdocker-escapelf: .. _imdocker.parameter.module.escapelf: escapeLF ======== .. index:: single: imdocker; escapeLF single: escapeLF .. summary-start Escapes line feeds as ``#012`` in multi-line messages; default ``on``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: escapeLF :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.41.0 Description ----------- If enabled, line feed characters embedded in messages are escaped to the sequence ``#012``. This avoids issues with tools that do not expect embedded LF characters. Module usage ------------ .. _param-imdocker-module-escapelf: .. _imdocker.parameter.module.escapelf-usage: .. code-block:: rsyslog module(load="imdocker" escapeLF="...") Notes ----- - The original documentation described this as a binary option; it is a boolean parameter. See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-fileowner.rst0000644000000000000000000000013215062756615024732 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.359530427 30 ctime=1764935921.588552161 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-fileowner.rst0000664000175000017500000000161315062756615024377 0ustar00rgerrger.. _param-imptcp-fileowner: .. _imptcp.parameter.input.fileowner: FileOwner ========= .. index:: single: imptcp; FileOwner single: FileOwner .. summary-start Sets the owner of the Unix-domain socket by user name. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FileOwner :Scope: input :Type: UID :Default: input=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the file owner for the domain socket. The parameter is a user name, for which the userid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are *not* detected. Input usage ----------- .. _param-imptcp-input-fileowner: .. _imptcp.parameter.input.fileowner-usage: .. code-block:: rsyslog input(type="imptcp" fileOwner="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-apikey_file.rst0000644000000000000000000000013115071746523025340 xustar0030 mtime=1760021843.799420371 30 atime=1764928597.260588797 29 ctime=1764935921.90655703 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-apikey_file.rst0000664000175000017500000000165015071746523025007 0ustar00rgerrger.. _param-mmaitag-apikey_file: .. _mmaitag.parameter.action.apikey_file: apiKeyFile ========== .. index:: single: mmaitag; apiKeyFile single: apiKeyFile .. summary-start Specifies a file containing the API key for the provider. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: apiKeyFile :Scope: action :Type: string :Default: none :Required?: no (either :ref:`param-mmaitag-apikey` or ``apiKeyFile`` must be set) :Introduced: 9.0.0 Description ----------- File containing the API key for the provider. If :ref:`param-mmaitag-apikey` is not set, the module reads the first line of this file and uses it as the API key. Action usage ------------- .. _param-mmaitag-action-apikey_file: .. _mmaitag.parameter.action.apikey_file-usage: .. code-block:: rsyslog action(type="mmaitag" apiKeyFile="/path/to/keyfile") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-statefile-directory.rst0000644000000000000000000000013215062756615026673 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.931486505 30 ctime=1764935921.440549895 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-statefile-directory.rst0000664000175000017500000000243415062756615026342 0ustar00rgerrger.. _param-imfile-statefile-directory: .. _imfile.parameter.module.statefile-directory: .. _imfile.parameter.statefile-directory: statefile.directory =================== .. index:: single: imfile; statefile.directory single: statefile.directory .. summary-start Sets a dedicated directory for imfile state files. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: statefile.directory :Scope: module :Type: string :Default: module=global(workDirectory) value :Required?: no :Introduced: 8.1905.0 Description ----------- Permits specification of a dedicated directory for the storage of imfile state files. An absolute path name should be specified (e.g., ``/var/rsyslog/imfilestate``). If not specified the global ``workDirectory`` setting is used. **Important: The directory must exist before rsyslog is started.** rsyslog needs write permissions to work correctly. This may also require SELinux definitions or similar permissions in other security systems. Module usage ------------ .. _param-imfile-module-statefile-directory: .. _imfile.parameter.module.statefile-directory-usage: .. code-block:: rsyslog module(load="imfile" statefile.directory="/var/rsyslog/imfilestate") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmutf8fix-mode.rst0000644000000000000000000000012615071746523024317 xustar0030 mtime=1760021843.823420749 30 atime=1764928598.952640651 26 ctime=1764935922.10056 rsyslog-8.2512.0/doc/source/reference/parameters/mmutf8fix-mode.rst0000664000175000017500000000332115071746523023757 0ustar00rgerrger.. _param-mmutf8fix-mode: .. _mmutf8fix.parameter.input.mode: mode ==== .. index:: single: mmutf8fix; mode single: mode .. summary-start Selects how invalid byte sequences are detected and replaced. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmutf8fix`. :Name: mode :Scope: input :Type: string :Default: "utf-8" :Required?: no :Introduced: 7.5.4 Description ----------- Sets the basic detection mode for invalid byte sequences. ``"utf-8"`` (default) Checks for proper UTF-8 encoding. Bytes that form invalid UTF-8 sequences are replaced with the character defined by :ref:`param-mmutf8fix-replacementchar`. This applies to various invalid conditions, including: * Invalid start bytes or stray continuation bytes. * A multi-byte sequence that is incomplete. * A complete sequence that is invalid (e.g., overlong encoding, a disallowed codepoint like a UTF-16 surrogate, or a value > U+10FFFF). Control characters are not replaced because they are valid UTF-8. This mode is most useful with non-US-ASCII character sets, which validly include multibyte sequences. ``"controlcharacters"`` Replaces all bytes that do not represent a printable US-ASCII character (codes 32 to 126) with the character defined by :ref:`param-mmutf8fix-replacementchar`. This invalidates valid UTF-8 multi-byte sequences and should be used only when characters outside the US-ASCII range are not expected. Input usage ----------- .. _mmutf8fix.parameter.input.mode-usage: .. code-block:: rsyslog module(load="mmutf8fix") action(type="mmutf8fix" mode="controlcharacters") See also -------- See also :doc:`../../configuration/modules/mmutf8fix`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpheaders.rst0000644000000000000000000000013115114522477025264 xustar0030 mtime=1764926783.032631784 29 atime=1764926783.47764271 30 ctime=1764935922.381564302 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpheaders.rst0000664000175000017500000000217615114522477024737 0ustar00rgerrger.. _param-omhttp-httpheaders: .. _omhttp.parameter.input.httpheaders: httpheaders =========== .. index:: single: omhttp; httpheaders single: httpheaders .. summary-start Configures an array of additional HTTP headers that omhttp sends with each request. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpheaders :Scope: input :Type: array :Default: input=none :Required?: no :Introduced: Not specified Description ----------- An array of strings that defines a list of one or more HTTP headers to send with each message. Keep in mind that some HTTP headers are added using other parameters. ``Content-Type`` can be configured using :ref:`param-omhttp-httpcontenttype`, and ``Content-Encoding: gzip`` is added when using the :ref:`param-omhttp-compress` parameter. Input usage ----------- .. _omhttp.parameter.input.httpheaders-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpHeaders=[ "X-Insert-Key: key", "X-Event-Source: logs" ] ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-srcmetadatapath.rst0000644000000000000000000000013215071746523027307 xustar0030 mtime=1760021843.816420639 30 atime=1764928598.245618994 30 ctime=1764935922.049559219 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-srcmetadatapath.rst0000664000175000017500000000170615071746523026757 0ustar00rgerrger.. _param-mmkubernetes-srcmetadatapath: .. _mmkubernetes.parameter.action.srcmetadatapath: srcmetadatapath =============== .. index:: single: mmkubernetes; srcmetadatapath single: srcmetadatapath .. summary-start Specifies the message property containing the original filename. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: srcmetadatapath :Scope: action :Type: word :Default: $!metadata!filename :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When reading json-file logs, with `imfile` and `addmetadata="on"`, this is the property where the filename is stored. Action usage ------------ .. _param-mmkubernetes-action-srcmetadatapath: .. _mmkubernetes.parameter.action.srcmetadatapath-usage: .. code-block:: rsyslog action(type="mmkubernetes" srcMetadataPath="$!metadata!filename") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-annotate.rst0000644000000000000000000000013215062756615026613 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.953579381 30 ctime=1764935921.860556325 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-annotate.rst0000664000175000017500000000242015062756615026255 0ustar00rgerrger.. _param-imuxsock-syssock-annotate: .. _imuxsock.parameter.module.syssock-annotate: SysSock.Annotate ================ .. index:: single: imuxsock; SysSock.Annotate single: SysSock.Annotate .. summary-start Enables annotation or trusted properties on the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.Annotate :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Turn on annotation/trusted properties for the system log socket. See the :ref:`imuxsock-trusted-properties-label` section for more info. Module usage ------------ .. _param-imuxsock-module-syssock-annotate: .. _imuxsock.parameter.module.syssock-annotate-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.annotate="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogsockannotate: - $SystemLogSocketAnnotate — maps to SysSock.Annotate (status: legacy) .. index:: single: imuxsock; $SystemLogSocketAnnotate single: $SystemLogSocketAnnotate See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-tls-myprivkey.rst0000644000000000000000000000013215114522477025611 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.482642833 30 ctime=1764935922.432565083 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-tls-myprivkey.rst0000664000175000017500000000156315114522477025262 0ustar00rgerrger.. _param-omhttp-tls-myprivkey: .. _omhttp.parameter.input.tls-myprivkey: tls.myprivkey ============= .. index:: single: omhttp; tls.myprivkey single: tls.myprivkey .. summary-start Provides the private key file that pairs with :ref:`param-omhttp-tls-mycert`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: tls.myprivkey :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- This parameter sets the path to the SSL private key. Expects ``.pem`` format. Input usage ----------- .. _omhttp.parameter.input.tls-myprivkey-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" tlsMyPrivKey="/etc/rsyslog/certs/omhttp-client.key" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmrfc5424addhmac-hashfunction.rst0000644000000000000000000000013115071746523027056 xustar0030 mtime=1760021843.821420718 29 atime=1764928598.50762702 30 ctime=1764935922.084559755 rsyslog-8.2512.0/doc/source/reference/parameters/mmrfc5424addhmac-hashfunction.rst0000664000175000017500000000164615071746523026532 0ustar00rgerrger.. _param-mmrfc5424addhmac-hashfunction: .. _mmrfc5424addhmac.parameter.action.hashFunction: hashFunction ============ .. index:: single: mmrfc5424addhmac; hashFunction single: hashFunction .. summary-start Specifies the OpenSSL hash algorithm used for the HMAC. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmrfc5424addhmac`. :Name: hashFunction :Scope: action :Type: string :Default: none :Required?: yes :Introduced: 7.5.6 Description ----------- An OpenSSL hash function name for the function to be used. This is passed on to OpenSSL, so see the OpenSSL list of supported function names. Action usage ------------ .. _param-mmrfc5424addhmac-action-hashFunction: .. _mmrfc5424addhmac.parameter.action.hashFunction-usage: .. code-block:: rsyslog action(type="mmrfc5424addhmac" hashFunction="sha256") See also -------- See also :doc:`../../configuration/modules/mmrfc5424addhmac`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-dynbulkid.rst0000644000000000000000000000013215062756615026577 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.734664581 30 ctime=1764935922.186561317 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-dynbulkid.rst0000664000175000017500000000164115062756615026245 0ustar00rgerrger.. _param-omelasticsearch-dynbulkid: .. _omelasticsearch.parameter.module.dynbulkid: dynbulkid ========= .. index:: single: omelasticsearch; dynbulkid single: dynbulkid .. summary-start Treat `bulkid` as a template that generates per-record IDs. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: dynbulkid :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Enables interpreting `bulkid` as a template, producing a unique identifier for each record. Action usage ------------ .. _param-omelasticsearch-action-dynbulkid: .. _omelasticsearch.parameter.action.dynbulkid: .. code-block:: rsyslog action(type="omelasticsearch" dynbulkid="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-retryfailures.rst0000644000000000000000000000013115062756615027511 xustar0030 mtime=1758190989.204641162 29 atime=1764928599.74966504 30 ctime=1764935922.222561868 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-retryfailures.rst0000664000175000017500000000173615062756615027165 0ustar00rgerrger.. _param-omelasticsearch-retryfailures: .. _omelasticsearch.parameter.module.retryfailures: retryfailures ============= .. index:: single: omelasticsearch; retryfailures single: retryfailures .. summary-start Resubmit failed bulk items back into rsyslog for retry. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: retryfailures :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When enabled, bulk responses are scanned for errors and failed entries are resubmitted with metadata under `$.omes`. Action usage ------------ .. _param-omelasticsearch-action-retryfailures: .. _omelasticsearch.parameter.action.retryfailures: .. code-block:: rsyslog action(type="omelasticsearch" retryfailures="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-tls-cacert.rst0000644000000000000000000000013215071746523026203 xustar0030 mtime=1760021843.817420655 30 atime=1764928598.261619484 30 ctime=1764935922.054559295 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-tls-cacert.rst0000664000175000017500000000214515071746523025651 0ustar00rgerrger.. _param-mmkubernetes-tls-cacert: .. _mmkubernetes.parameter.action.tls-cacert: tls.cacert ========== .. index:: single: mmkubernetes; tls.cacert single: tls.cacert .. summary-start Specifies the CA certificate used to verify the Kubernetes API server. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: tls.cacert :Scope: action :Type: word :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Full path and file name of file containing the CA cert of the Kubernetes API server cert issuer. Example: `/etc/rsyslog.d/mmk8s-ca.crt`. This parameter is not mandatory if using an `http` scheme instead of `https` in :ref:`param-mmkubernetes-kubernetesurl`, or if :ref:`param-mmkubernetes-allowunsignedcerts` is set to `"on"`. Action usage ------------ .. _param-mmkubernetes-action-tls-cacert: .. _mmkubernetes.parameter.action.tls-cacert-usage: .. code-block:: rsyslog action(type="mmkubernetes" tls.caCert="/etc/rsyslog.d/mmk8s-ca.crt") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-batch-maxsize.rst0000644000000000000000000000013015114522477025507 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.475642661 29 ctime=1764935922.35856395 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-batch-maxsize.rst0000664000175000017500000000150015114522477025151 0ustar00rgerrger.. _param-omhttp-batch-maxsize: .. _omhttp.parameter.input.batch-maxsize: batch.maxsize ============= .. index:: single: omhttp; batch.maxsize single: batch.maxsize .. summary-start Limits how many messages omhttp includes in a batch. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: batch.maxsize :Scope: input :Type: Size :Default: input=100 :Required?: no :Introduced: Not specified Description ----------- This parameter specifies the maximum number of messages that will be sent in each batch. Input usage ----------- .. _omhttp.parameter.input.batch-maxsize-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" batch="on" batchMaxSize="200" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ratelimit-interval.rst0000644000000000000000000000013215103061376027107 xustar0030 mtime=1762419454.852381127 30 atime=1764928597.025581591 30 ctime=1764935921.851556188 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ratelimit-interval.rst0000664000175000017500000000274415103061376026562 0ustar00rgerrger.. _param-imuxsock-ratelimit-interval: .. _imuxsock.parameter.input.ratelimit-interval: RateLimit.Interval ================== .. index:: single: imuxsock; RateLimit.Interval single: RateLimit.Interval .. summary-start Sets the rate-limiting interval in seconds for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: RateLimit.Interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies the rate-limiting interval in seconds. Default value is 0, which turns off rate limiting. Set it to a number of seconds (5 recommended) to activate rate-limiting. The default of 0 has been chosen as people experienced problems with this feature activated by default. Now it needs an explicit opt-in by setting this parameter. Input usage ----------- .. _param-imuxsock-input-ratelimit-interval: .. _imuxsock.parameter.input.ratelimit-interval-usage: .. code-block:: rsyslog input(type="imuxsock" rateLimit.interval="5") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.imuxsockratelimitinterval: - $IMUXSockRateLimitInterval — maps to RateLimit.Interval (status: legacy) .. index:: single: imuxsock; $IMUXSockRateLimitInterval single: $IMUXSockRateLimitInterval See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsendertrack-interval.rst0000644000000000000000000000013215114522477026124 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.487642955 30 ctime=1764935922.560567042 rsyslog-8.2512.0/doc/source/reference/parameters/omsendertrack-interval.rst0000664000175000017500000000243315114522477025572 0ustar00rgerrger.. _param-omsendertrack-interval: .. _omsendertrack.parameter.input.interval: interval ======== .. index:: single: omsendertrack; interval single: interval .. summary-start Sets how many seconds elapse between each write of sender statistics to the state file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsendertrack`. :Name: interval :Scope: input :Type: integer :Default: input=60 :Required?: no :Introduced: 8.2506.0 (Proof-of-Concept) Description ----------- This parameter defines the **interval in seconds** after which the module writes the current sender statistics to the configured :ref:`statefile `. A smaller ``interval`` value results in more frequent updates to the state file, reducing potential data loss in case of an unexpected system crash, but it also increases disk I/O. A larger ``interval`` reduces I/O but means less up-to-date statistics on disk. Input usage ----------- .. _omsendertrack.parameter.input.interval-usage: .. code-block:: rsyslog module(load="omsendertrack") action(type="omsendertrack" senderId="%hostname%" interval="60" stateFile="/var/lib/rsyslog/senderstats.json") See also -------- See also :doc:`../../configuration/modules/omsendertrack`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-userawmsg.rst0000644000000000000000000000013215071746523026010 xustar0030 mtime=1760021843.820420702 30 atime=1764928598.415624202 30 ctime=1764935922.074559602 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-userawmsg.rst0000664000175000017500000000231315071746523025453 0ustar00rgerrger.. _param-mmnormalize-userawmsg: .. _mmnormalize.parameter.action.userawmsg: useRawMsg ========= .. index:: single: mmnormalize; useRawMsg single: useRawMsg .. summary-start Uses the raw message instead of just the MSG part during normalization. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: useRawMsg :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 6.1.2, possibly earlier Description ----------- Specifies if the raw message should be used for normalization (``on``) or just the MSG part of the message (``off``). Action usage ------------- .. _param-mmnormalize-action-userawmsg: .. _mmnormalize.parameter.action.userawmsg-usage: .. code-block:: rsyslog action(type="mmnormalize" useRawMsg="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmnormalize.parameter.legacy.mmnormalizeuserawmsg: - $mmnormalizeUseRawMsg — maps to useRawMsg (status: legacy) .. index:: single: mmnormalize; $mmnormalizeUseRawMsg single: $mmnormalizeUseRawMsg See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dynafilecachesize.rst0000644000000000000000000000013215062756615026371 xustar0030 mtime=1758190989.207641205 30 atime=1764928600.090675472 30 ctime=1764935922.292562939 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dynafilecachesize.rst0000664000175000017500000000405115062756615026035 0ustar00rgerrger.. _param-omfile-dynafilecachesize: .. _omfile.parameter.module.dynafilecachesize: dynaFileCacheSize ================= .. index:: single: omfile; dynaFileCacheSize single: dynaFileCacheSize .. summary-start This parameter specifies the maximum size of the cache for dynamically-generated file names (dynafile= parameter). .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dynaFileCacheSize :Scope: action :Type: integer :Default: action=10 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This parameter specifies the maximum size of the cache for dynamically-generated file names (dynafile= parameter). This setting specifies how many open file handles should be cached. If, for example, the file name is generated with the hostname in it and you have 100 different hosts, a cache size of 100 would ensure that files are opened once and then stay open. This can be a great way to increase performance. If the cache size is lower than the number of different files, the least recently used one is discarded (and the file closed). Note that this is a per-action value, so if you have multiple dynafile actions, each of them have their individual caches (which means the numbers sum up). Ideally, the cache size exactly matches the need. You can use :doc:`impstats <../../configuration/modules/impstats>` to tune this value. Note that a too-low cache size can be a very considerable performance bottleneck. Action usage ------------ .. _param-omfile-action-dynafilecachesize: .. _omfile.parameter.action.dynafilecachesize: .. code-block:: rsyslog action(type="omfile" dynaFileCacheSize="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dynafilecachesize: - $DynaFileCacheSize — maps to dynaFileCacheSize (status: legacy) .. index:: single: omfile; $DynaFileCacheSize single: $DynaFileCacheSize See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-keepalive-interval.rst0000644000000000000000000000013215062756615026347 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.115553656 30 ctime=1764935921.716554121 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-keepalive-interval.rst0000664000175000017500000000216615062756615026020 0ustar00rgerrger.. _param-imtcp-keepalive-interval: .. _imtcp.parameter.module.keepalive-interval: .. _imtcp.parameter.input.keepalive-interval: KeepAlive.Interval ================== .. index:: single: imtcp; KeepAlive.Interval single: KeepAlive.Interval .. summary-start Defines the interval for keep-alive packets. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: KeepAlive.Interval :Scope: module, input :Type: integer :Default: module=0, input=module parameter :Required?: no :Introduced: 8.2106.0 Description ----------- The interval for keep alive packets. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-keepalive-interval: .. _imtcp.parameter.module.keepalive-interval-usage: .. code-block:: rsyslog module(load="imtcp" keepAlive.interval="...") Input usage ----------- .. _param-imtcp-input-keepalive-interval: .. _imtcp.parameter.input.keepalive-interval-usage: .. code-block:: rsyslog input(type="imtcp" port="514" keepAlive.interval="...") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-flushinterval.rst0000644000000000000000000000013115062756615025604 xustar0030 mtime=1758190989.208641219 30 atime=1764928600.113676175 29 ctime=1764935922.31156323 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-flushinterval.rst0000664000175000017500000000221615062756615025252 0ustar00rgerrger.. _param-omfile-flushinterval: .. _omfile.parameter.module.flushinterval: flushInterval ============= .. index:: single: omfile; flushInterval single: flushInterval .. summary-start Defines, in seconds, the interval after which unwritten data is flushed. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: flushInterval :Scope: action :Type: integer :Default: action=1 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines, in seconds, the interval after which unwritten data is flushed. Action usage ------------ .. _param-omfile-action-flushinterval: .. _omfile.parameter.action.flushinterval: .. code-block:: rsyslog action(type="omfile" flushInterval="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.omfileflushinterval: - $OMFileFlushInterval — maps to flushInterval (status: legacy) .. index:: single: omfile; $OMFileFlushInterval single: $OMFileFlushInterval See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-threads.rst0000644000000000000000000000013215062756615024372 xustar0030 mtime=1758190989.191640978 30 atime=1764928595.304528737 30 ctime=1764935921.643553003 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-threads.rst0000664000175000017500000000273015062756615024040 0ustar00rgerrger.. _param-imptcp-threads: .. _imptcp.parameter.module.threads: Threads ======= .. index:: single: imptcp; Threads single: Threads .. summary-start Sets the number of helper threads that pull data off the network. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Threads :Scope: module :Type: integer :Default: module=2 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Number of helper worker threads to process incoming messages. These threads are utilized to pull data off the network. On a busy system, additional helper threads (but not more than there are CPUs/Cores) can help improving performance. The default value is two, which means there is a default thread count of three (the main input thread plus two helpers). No more than 16 threads can be set (if tried to, rsyslog always resorts to 16). Module usage ------------ .. _param-imptcp-module-threads: .. _imptcp.parameter.module.threads-usage: .. code-block:: rsyslog module(load="imptcp" threads="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverhelperthreads: - $InputPTCPServerHelperThreads — maps to Threads (status: legacy) .. index:: single: imptcp; $InputPTCPServerHelperThreads single: $InputPTCPServerHelperThreads See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-key.rst0000644000000000000000000000013115071746523024046 xustar0030 mtime=1760021843.806420481 30 atime=1764928597.673601462 29 ctime=1764935921.95755781 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-key.rst0000664000175000017500000000257015071746523023517 0ustar00rgerrger.. _param-mmdarwin-key: .. _mmdarwin.parameter.input.key: key === .. index:: single: mmdarwin; key single: key .. summary-start Stores the Darwin score in the specified JSON field. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: key :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: at least 8.x, possibly earlier Description ----------- The key name to use to store the returned data. For example, given the following log line: .. code-block:: json { "from": "192.168.1.42", "date": "2012-12-21 00:00:00", "status": "200", "data": { "status": true, "message": "Request processed correctly" } } and the :json:`"certitude"` key, the enriched log line would be: .. code-block:: json :emphasize-lines: 9 { "from": "192.168.1.42", "date": "2012-12-21 00:00:00", "status": "200", "data": { "status": true, "message": "Request processed correctly" }, "certitude": 0 } where :json:`"certitude"` represents the score returned by Darwin. Input usage ----------- .. _param-mmdarwin-input-key-usage: .. _mmdarwin.parameter.input.key-usage: .. code-block:: rsyslog action(type="mmdarwin" key="certitude") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-embeddedipv4-enable.rst0000644000000000000000000000013215071746523026506 xustar0030 mtime=1760021843.802420418 30 atime=1764928597.361591894 30 ctime=1764935921.925557321 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-embeddedipv4-enable.rst0000664000175000017500000000172015071746523026152 0ustar00rgerrger.. _param-mmanon-embeddedipv4-enable: .. _mmanon.parameter.input.embeddedipv4-enable: embeddedIpv4.enable =================== .. index:: single: mmanon; embeddedIpv4.enable single: embeddedIpv4.enable .. summary-start Enables or disables anonymization of IPv6 addresses with embedded IPv4 parts. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: embeddedIpv4.enable :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 7.3.7 Description ----------- This parameter controls whether ``mmanon`` will attempt to find and anonymize IPv6 addresses with embedded IPv4 parts. If set to ``off``, all other ``embeddedipv4.*`` parameters for this action are ignored. Input usage ----------- .. _mmanon.parameter.input.embeddedipv4-enable-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" embeddedIpv4.enable="off") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-healthchecktimeout.rst0000644000000000000000000000013215062756615030464 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.500657421 30 ctime=1764935922.202561561 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-healthchecktimeout.rst0000664000175000017500000000175115062756615030134 0ustar00rgerrger.. _param-omelasticsearch-healthchecktimeout: .. _omelasticsearch.parameter.module.healthchecktimeout: HealthCheckTimeout ================== .. index:: single: omelasticsearch; HealthCheckTimeout single: HealthCheckTimeout .. summary-start Milliseconds to wait for an HTTP health check before sending events. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: HealthCheckTimeout :Scope: action :Type: integer :Default: action=3500 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Before logging begins, rsyslog issues an HTTP HEAD to `/_cat/health` and waits up to this many milliseconds for `HTTP OK`. Action usage ------------ .. _param-omelasticsearch-action-healthchecktimeout: .. _omelasticsearch.parameter.action.healthchecktimeout: .. code-block:: rsyslog action(type="omelasticsearch" HealthCheckTimeout="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-template.rst0000644000000000000000000000013115062756615024531 xustar0030 mtime=1758190989.209641233 30 atime=1764928599.861668468 29 ctime=1764935922.32856349 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-template.rst0000664000175000017500000000253615062756615024204 0ustar00rgerrger.. _param-omfile-template: .. _omfile.parameter.module.template: Template ======== .. index:: single: omfile; Template single: Template .. summary-start Sets the template to be used for this action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: Template :Scope: module, action :Type: word :Default: module=RSYSLOG_FileFormat; action=inherits module :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the template to be used for this action. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-template: .. _omfile.parameter.module.template-usage: .. code-block:: rsyslog module(load="builtin:omfile" Template="...") Action usage ------------ .. _param-omfile-action-template: .. _omfile.parameter.action.template: .. code-block:: rsyslog action(type="omfile" Template="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.actionfiledefaulttemplate: - $ActionFileDefaultTemplate — maps to Template (status: legacy) .. index:: single: omfile; $ActionFileDefaultTemplate single: $ActionFileDefaultTemplate See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-keepkerneltimestamp.rst0000644000000000000000000000013115114522477026771 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.456642194 29 ctime=1764935921.52055112 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-keepkerneltimestamp.rst0000664000175000017500000000307015114522477026436 0ustar00rgerrger.. _param-imklog-keepkerneltimestamp: .. _imklog.parameter.module.keepkerneltimestamp: KeepKernelTimestamp =================== .. index:: single: imklog; KeepKernelTimestamp single: KeepKernelTimestamp .. summary-start Keeps the kernel-supplied timestamp prefix in each message when kernel timestamps are parsed. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: KeepKernelTimestamp :Scope: module :Type: boolean :Default: off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If enabled, this option keeps the [timestamp] provided by the kernel at the beginning of each message rather than to remove it, when it could be parsed and converted into local time for use as regular message time. Only used when ``ParseKernelTimestamp`` is on. Notes ----- - Legacy documentation referred to the type as "binary"; it behaves as a boolean value. Module usage ------------ .. _param-imklog-module-keepkerneltimestamp: .. _imklog.parameter.module.keepkerneltimestamp-usage: .. code-block:: rsyslog module(load="imklog" parseKernelTimestamp="on" keepKernelTimestamp="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.klogkeepkerneltimestamp: - $klogKeepKernelTimestamp — maps to KeepKernelTimestamp (status: legacy) .. index:: single: imklog; $klogKeepKernelTimestamp single: $klogKeepKernelTimestamp See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-dynparent.rst0000644000000000000000000000013215062756615026616 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.640661705 30 ctime=1764935922.188561347 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-dynparent.rst0000664000175000017500000000162615062756615026267 0ustar00rgerrger.. _param-omelasticsearch-dynparent: .. _omelasticsearch.parameter.module.dynparent: dynParent ========= .. index:: single: omelasticsearch; dynParent single: dynParent .. summary-start Treat `parent` as a template for per-record parent IDs. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: dynParent :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When enabled, `parent` names a template that produces the parent ID for each record. Action usage ------------ .. _param-omelasticsearch-action-dynparent: .. _omelasticsearch.parameter.action.dynparent: .. code-block:: rsyslog action(type="omelasticsearch" dynParent="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmrfc5424addhmac-sd-id.rst0000644000000000000000000000013215071746523025366 xustar0030 mtime=1760021843.822420733 30 atime=1764928598.513627204 30 ctime=1764935922.088559816 rsyslog-8.2512.0/doc/source/reference/parameters/mmrfc5424addhmac-sd-id.rst0000664000175000017500000000156315071746523025037 0ustar00rgerrger.. _param-mmrfc5424addhmac-sd-id: .. _mmrfc5424addhmac.parameter.action.sdId: sdId ==== .. index:: single: mmrfc5424addhmac; sdId single: sdId .. summary-start Sets the RFC5424 structured data ID added to the message. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmrfc5424addhmac`. :Name: sdId :Scope: action :Type: string :Default: none :Required?: yes :Introduced: 7.5.6 Description ----------- The RFC5424 structured data ID to be used by this module. This is the SD-ID that will be added. Note that nothing is added if this SD-ID is already present. Action usage ------------ .. _param-mmrfc5424addhmac-action-sdId: .. _mmrfc5424addhmac.parameter.action.sdId-usage: .. code-block:: rsyslog action(type="mmrfc5424addhmac" sdId="exampleSDID@32473") See also -------- See also :doc:`../../configuration/modules/mmrfc5424addhmac`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-parsekerneltimestamp.rst0000644000000000000000000000013215114522477027160 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.457642219 30 ctime=1764935921.525551197 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-parsekerneltimestamp.rst0000664000175000017500000000351715114522477026632 0ustar00rgerrger.. _param-imklog-parsekerneltimestamp: .. _imklog.parameter.module.parsekerneltimestamp: ParseKernelTimestamp ==================== .. index:: single: imklog; ParseKernelTimestamp single: ParseKernelTimestamp .. summary-start Parses kernel-provided timestamps and uses them as the message time instead of the receive time. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: ParseKernelTimestamp :Scope: module :Type: boolean :Default: off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If enabled and the kernel creates a timestamp for its log messages, this timestamp will be parsed and converted into regular message time instead of using the receive time of the kernel message (as in 5.8.x and before). Default is 'off' to prevent parsing the kernel timestamp, because the clock used by the kernel to create the timestamps is not supposed to be as accurate as the monotonic clock required to convert it. Depending on the hardware and kernel, it can result in message time differences between kernel and system messages which occurred at the same time. Notes ----- - Legacy documentation referred to the type as "binary"; it behaves as a boolean value. Module usage ------------ .. _param-imklog-module-parsekerneltimestamp: .. _imklog.parameter.module.parsekerneltimestamp-usage: .. code-block:: rsyslog module(load="imklog" parseKernelTimestamp="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.klogparsekerneltimestamp: - $klogParseKernelTimestamp — maps to ParseKernelTimestamp (status: legacy) .. index:: single: imklog; $klogParseKernelTimestamp single: $klogParseKernelTimestamp See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-usehttps.rst0000644000000000000000000000013215062756615026471 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.585660022 30 ctime=1764935922.255562373 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-usehttps.rst0000664000175000017500000000160515062756615026137 0ustar00rgerrger.. _param-omelasticsearch-usehttps: .. _omelasticsearch.parameter.module.usehttps: usehttps ======== .. index:: single: omelasticsearch; usehttps single: usehttps .. summary-start Default scheme for servers missing one. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: usehttps :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If enabled, URLs in `server` without an explicit scheme use HTTPS; otherwise HTTP is assumed. Action usage ------------ .. _param-omelasticsearch-action-usehttps: .. _omelasticsearch.parameter.action.usehttps: .. code-block:: rsyslog action(type="omelasticsearch" usehttps="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-confirmtimeout.rst0000644000000000000000000000013215062756615026013 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.069735925 30 ctime=1764935922.534566644 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-confirmtimeout.rst0000664000175000017500000000257615062756615025471 0ustar00rgerrger.. _param-omprog-confirmtimeout: .. _omprog.parameter.action.confirmtimeout: confirmTimeout ============== .. index:: single: omprog; confirmTimeout single: confirmTimeout .. summary-start Sets the maximum time in milliseconds to wait for message confirmations. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: confirmTimeout :Scope: action :Type: integer :Default: action=10000 :Required?: no :Introduced: 8.38.0 Description ----------- Specifies how long rsyslog must wait for the external program to confirm each message when :ref:`param-omprog-confirmmessages` is set to "on". If the program does not send a response within this timeout, it will be restarted (see :ref:`param-omprog-signalonclose`, :ref:`param-omprog-closetimeout` and :ref:`param-omprog-killunresponsive` for details on the cleanup sequence). The value must be expressed in milliseconds and must be greater than zero. .. seealso:: `Interface between rsyslog and external output plugins `_ Action usage ------------ .. _param-omprog-action-confirmtimeout: .. _omprog.parameter.action.confirmtimeout-usage: .. code-block:: rsyslog action(type="omprog" confirmMessages="on" confirmTimeout="20000") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-apikey.rst0000644000000000000000000000013115114522477026066 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.473642612 30 ctime=1764935922.177561179 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-apikey.rst0000664000175000017500000000214715114522477025537 0ustar00rgerrger.. _param-omelasticsearch-apikey: .. _omelasticsearch.parameter.module.apikey: apikey ====== .. index:: single: omelasticsearch; apikey single: apikey .. summary-start Supplies the value for the ``Authorization: ApiKey`` HTTP header. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: apikey :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: 8.2406.0 Description ----------- Accepts the API key material expected by Elasticsearch's ``ApiKey`` authentication scheme. The configured value is appended to the ``Authorization: ApiKey`` header without modification, so provide the base64-encoded ``:`` string exactly as documented by Elasticsearch. The API key setting cannot be combined with :ref:`param-omelasticsearch-uid` or :ref:`param-omelasticsearch-pwd`. Action usage ------------ .. _param-omelasticsearch-action-apikey: .. _omelasticsearch.parameter.action.apikey: .. code-block:: rsyslog action(type="omelasticsearch" apikey="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-ignoretimestamp.rst0000644000000000000000000000013215062756615030211 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.884577263 30 ctime=1764935921.867556433 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-ignoretimestamp.rst0000664000175000017500000000254315062756615027661 0ustar00rgerrger.. _param-imuxsock-syssock-ignoretimestamp: .. _imuxsock.parameter.module.syssock-ignoretimestamp: SysSock.IgnoreTimestamp ======================= .. index:: single: imuxsock; SysSock.IgnoreTimestamp single: SysSock.IgnoreTimestamp .. summary-start Ignores timestamps included in messages from the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.IgnoreTimestamp :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Ignore timestamps included in the messages, applies to messages received via the system log socket. Module usage ------------ .. _param-imuxsock-module-syssock-ignoretimestamp: .. _imuxsock.parameter.module.syssock-ignoretimestamp-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.ignoreTimestamp="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogsocketignoremsgtimestamp: - $SystemLogSocketIgnoreMsgTimestamp — maps to SysSock.IgnoreTimestamp (status: legacy) .. index:: single: imuxsock; $SystemLogSocketIgnoreMsgTimestamp single: $SystemLogSocketIgnoreMsgTimestamp See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-provider.rst0000644000000000000000000000013215071746523024712 xustar0030 mtime=1760021843.800420386 30 atime=1764928597.227587785 30 ctime=1764935921.916557183 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-provider.rst0000664000175000017500000000146315071746523024362 0ustar00rgerrger.. _param-mmaitag-provider: .. _mmaitag.parameter.action.provider: provider ======== .. index:: single: mmaitag; provider single: provider .. summary-start Selects which backend provider processes the classification (``gemini`` or ``gemini_mock``). .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: provider :Scope: action :Type: string :Default: gemini :Required?: no :Introduced: 9.0.0 Description ----------- Specifies which backend to use for classification. Supported values are ``gemini`` and ``gemini_mock``. Action usage ------------- .. _param-mmaitag-action-provider: .. _mmaitag.parameter.action.provider-usage: .. code-block:: rsyslog action(type="mmaitag" provider="gemini_mock") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgssserverpermitplaintcp.rs0000644000000000000000000000013215114522477031146 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.454642145 30 ctime=1764935921.458550171 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgssserverpermitplaintcp.rst0000664000175000017500000000265115114522477031002 0ustar00rgerrger.. _param-imgssapi-inputgssserverpermitplaintcp: .. _imgssapi.parameter.input.inputgssserverpermitplaintcp: InputGSSServerPermitPlainTcp ============================ .. index:: single: imgssapi; InputGSSServerPermitPlainTcp single: InputGSSServerPermitPlainTcp .. summary-start Allows accepting plain TCP syslog traffic on the GSS-protected port. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSServerPermitPlainTcp :Scope: input :Type: boolean :Default: 0 :Required?: no :Introduced: 3.11.6 Description ----------- Permits the server to receive plain TCP syslog (without GSS protection) on the same port that the GSS listener uses. Input usage ----------- .. _imgssapi.parameter.input.inputgssserverpermitplaintcp-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssServerPermitPlainTcp on Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgssserverpermitplaintcp: - $InputGSSServerPermitPlainTCP — maps to InputGSSServerPermitPlainTcp (status: legacy) - $inputGssServerPermitPlainTcp — maps to InputGSSServerPermitPlainTcp (status: legacy) .. index:: single: imgssapi; $InputGSSServerPermitPlainTCP single: $InputGSSServerPermitPlainTCP single: imgssapi; $inputGssServerPermitPlainTcp single: $inputGssServerPermitPlainTcp See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmpstrucdata-jsonroot.rst0000644000000000000000000000013215071746523026022 xustar0030 mtime=1760021843.821420718 30 atime=1764928598.462625641 30 ctime=1764935922.079559678 rsyslog-8.2512.0/doc/source/reference/parameters/mmpstrucdata-jsonroot.rst0000664000175000017500000000143515071746523025471 0ustar00rgerrger.. _param-mmpstrucdata-jsonroot: .. _mmpstrucdata.parameter.action.jsonroot: jsonRoot ======== .. index:: single: mmpstrucdata; jsonRoot single: jsonRoot .. summary-start Sets the JSON root container where parsed structured data is stored. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmpstrucdata`. :Name: jsonRoot :Scope: action :Type: string :Default: action="!" :Required?: no :Introduced: 7.5.4 Description ----------- Specifies into which json container the data shall be parsed to. Action usage ------------ .. _param-mmpstrucdata-action-jsonroot: .. _mmpstrucdata.parameter.action.jsonroot-usage: .. code-block:: rsyslog action(type="mmpstrucdata" jsonRoot="!") See also -------- See also :doc:`../../configuration/modules/mmpstrucdata`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-template.rst0000644000000000000000000000013215114522477024565 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.481642808 30 ctime=1764935922.425564975 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-template.rst0000664000175000017500000000250215114522477024230 0ustar00rgerrger.. _param-omhttp-template: .. _omhttp.parameter.input.template: template ======== .. index:: single: omhttp; template single: template .. summary-start Selects the rsyslog template used to render each message before omhttp submits it. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: template :Scope: input :Type: word :Default: input=StdJSONFmt :Required?: no :Introduced: Not specified Description ----------- The template to be used for the messages. Note that in batching mode, this describes the format of *each* individual message, *not* the format of the resulting batch. Some batch modes require that a template produces valid JSON. Input usage ----------- .. _omhttp.parameter.input.template-usage: .. code-block:: rsyslog template(name="tpl_omhttp_json" type="list") { constant(value="{") property(name="msg" outname="message" format="jsonfr") constant(value=",") property(name="hostname" outname="host" format="jsonfr") constant(value=",") property(name="timereported" outname="timestamp" format="jsonfr" dateFormat="rfc3339") constant(value="}") } module(load="omhttp") action( type="omhttp" template="tpl_omhttp_json" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-headerless-ruleset.rst0000644000000000000000000000013215062756615026671 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.325774223 30 ctime=1764935922.620567961 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-headerless-ruleset.rst0000664000175000017500000000206015062756615026333 0ustar00rgerrger.. _param-pmrfc3164-headerless-ruleset: .. _pmrfc3164.parameter.module.headerless-ruleset: .. _pmrfc3164.parameter.module.headerless.ruleset: headerless.ruleset ================== .. index:: single: pmrfc3164; headerless.ruleset single: headerless.ruleset .. summary-start Route headerless messages to a specific ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: headerless.ruleset :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none :Required?: no :Introduced: 8.2508.0 Description ----------- If set, detected headerless messages are sent to the given ruleset for further processing, such as writing to a dedicated error log or discarding. Module usage ------------ .. _param-pmrfc3164-module-headerless-ruleset: .. _pmrfc3164.parameter.module.headerless-ruleset-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" headerless.ruleset="errorhandler") See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmcount-value.rst0000644000000000000000000000013215071746523024237 xustar0030 mtime=1760021843.805420466 30 atime=1764928597.471595268 30 ctime=1764935921.948557673 rsyslog-8.2512.0/doc/source/reference/parameters/mmcount-value.rst0000664000175000017500000000251115071746523023702 0ustar00rgerrger.. _param-mmcount-value: .. _mmcount.parameter.input.value: value ===== .. index:: single: mmcount; value single: value .. summary-start Counts only messages where the selected key equals the specified value. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmcount`. :Name: value :Scope: input :Type: word :Default: none (count every observed key value) :Required?: no :Introduced: 7.5.0 Description ----------- Limits counting to a specific property value when combined with :ref:`param-mmcount-key`. After :ref:`param-mmcount-appname` matches and the requested key is present, mmcount compares the property's string representation with ``value``. If they are equal, a dedicated counter is incremented and stored in the message's ``mmcount`` property. Messages that do not match are left unchanged. When ``value`` is not provided, mmcount maintains separate counters for each property value instead. Specifying ``value`` without :ref:`param-mmcount-key` has no practical effect; in that case the module still counts messages per severity. Input usage ----------- .. _param-mmcount-value-usage: .. _mmcount.parameter.input.value-usage: .. code-block:: rsyslog action(type="mmcount" appName="glusterfsd" key="!gf_code" value="9999") See also -------- See also :doc:`../../configuration/modules/mmcount`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-port.rst0000644000000000000000000000013115062756615023545 xustar0030 mtime=1758190989.194641021 29 atime=1764928596.75157318 30 ctime=1764935921.808555529 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-port.rst0000664000175000017500000000257215062756615023220 0ustar00rgerrger.. _param-imudp-port: .. _imudp.parameter.input.port: Port ==== .. index:: single: imudp; Port single: Port .. summary-start Port or array of ports for the UDP listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Port :Scope: input :Type: array[string] :Default: input=514 :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the port the server shall listen to. Either a single port can be specified or an array of ports. If multiple ports are specified, a listener will be automatically started for each port. Thus, no additional inputs need to be configured. Examples: .. code-block:: rsyslog module(load="imudp") # needs to be done just once input(type="imudp" port="514") .. code-block:: rsyslog module(load="imudp") input(type="imudp" port=["514","515","10514"]) Input usage ----------- .. _param-imudp-input-port: .. _imudp.parameter.input.port-usage: .. code-block:: rsyslog input(type="imudp" Port="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.udpserverrun: - $UDPServerRun — maps to Port (status: legacy) .. index:: single: imudp; $UDPServerRun single: $UDPServerRun See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgssserverkeepalive.rst0000644000000000000000000000013115114522477030243 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.454642145 29 ctime=1764935921.45455011 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgssserverkeepalive.rst0000664000175000017500000000216115114522477027710 0ustar00rgerrger.. _param-imgssapi-inputgssserverkeepalive: .. _imgssapi.parameter.input.inputgssserverkeepalive: InputGSSServerKeepAlive ======================= .. index:: single: imgssapi; InputGSSServerKeepAlive single: InputGSSServerKeepAlive .. summary-start Enables TCP keep-alive handling for GSS-protected connections. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSServerKeepAlive :Scope: input :Type: boolean :Default: 0 :Required?: no :Introduced: 8.5.0 Description ----------- Enables or disables keep-alive packets at the TCP socket layer. Input usage ----------- .. _imgssapi.parameter.input.inputgssserverkeepalive-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssServerKeepAlive on Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgssserverkeepalive: - $inputGssServerKeepAlive — maps to InputGSSServerKeepAlive (status: legacy) .. index:: single: imgssapi; $inputGssServerKeepAlive single: $inputGssServerKeepAlive See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-socketbacklog.rst0000644000000000000000000000013115062756615025552 xustar0030 mtime=1758190989.191640978 29 atime=1764928595.58153725 30 ctime=1764935921.639552942 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-socketbacklog.rst0000664000175000017500000000343015062756615025217 0ustar00rgerrger.. _param-imptcp-socketbacklog: .. _imptcp.parameter.input.socketbacklog: SocketBacklog ============= .. index:: single: imptcp; SocketBacklog single: SocketBacklog .. summary-start Sets the listen() backlog for pending TCP connections. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: SocketBacklog :Scope: input :Type: integer :Default: input=64 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the backlog parameter passed to the ``listen()`` system call. This parameter defines the maximum length of the queue for pending connections, which includes partially established connections (those in the SYN-ACK handshake phase) and fully established connections waiting to be accepted by the application. For more details, refer to the ``listen(2)`` man page. By default, the value is set to 64 to accommodate modern workloads. It can be adjusted to suit specific requirements, such as: - **High rates of concurrent connection attempts**: Increasing this value helps handle bursts of incoming connections without dropping them. - **Test environments with connection flooding**: Larger values are recommended to prevent SYN queue overflow. - **Servers with low traffic**: Lower values may be used to reduce memory usage. The effective backlog size is influenced by system-wide kernel settings, particularly ``net.core.somaxconn`` and ``net.ipv4.tcp_max_syn_backlog``. The smaller value between this parameter and the kernel limits is used as the actual backlog. Input usage ----------- .. _param-imptcp-input-socketbacklog: .. _imptcp.parameter.input.socketbacklog-usage: .. code-block:: rsyslog input(type="imptcp" socketBacklog="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-hostname.rst0000644000000000000000000000013215062756615025124 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.082583339 30 ctime=1764935921.837555973 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-hostname.rst0000664000175000017500000000227015062756615024571 0ustar00rgerrger.. _param-imuxsock-hostname: .. _imuxsock.parameter.input.hostname: HostName ======== .. index:: single: imuxsock; HostName single: HostName .. summary-start Overrides the hostname used inside messages from this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: HostName :Scope: input :Type: string :Default: input=NULL :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Allows overriding the hostname that shall be used inside messages taken from the input that is being defined. Input usage ----------- .. _param-imuxsock-input-hostname: .. _imuxsock.parameter.input.hostname-usage: .. code-block:: rsyslog input(type="imuxsock" hostName="jail1.example.net") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensockethostname: - $InputUnixListenSocketHostName — maps to HostName (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketHostName single: $InputUnixListenSocketHostName See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-serverstreamdriverpermittedpeer.r0000644000000000000000000000013215114522477031052 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.453642121 30 ctime=1764935921.322548089 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-serverstreamdriverpermittedpeer.rst0000664000175000017500000000431415114522477031067 0ustar00rgerrger.. _param-imdiag-serverstreamdriverpermittedpeer: .. _imdiag.parameter.input.serverstreamdriverpermittedpeer: ServerStreamDriverPermittedPeer =============================== .. index:: single: imdiag; ServerStreamDriverPermittedPeer single: ServerStreamDriverPermittedPeer .. summary-start Accepts permitted peer identifiers for compatibility, but the plain TCP driver used by imdiag does not enforce them. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ServerStreamDriverPermittedPeer :Scope: input :Type: array :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines the set of remote peers that may connect when the chosen :doc:`network stream driver <../../concepts/netstrm_drvr>` supports authentication. imdiag always uses the plain TCP (``ptcp``) stream driver, which offers no peer verification. As a result, the configured identities are accepted but ignored. The parameter is kept for forward compatibility with the generic TCP listener framework should imdiag gain authenticated stream support in the future. Configure this parameter before :ref:`ServerRun ` if you need to preserve configuration compatibility. When multiple peers are listed, provide an array of identity strings even though the ``ptcp`` driver ignores them. Input usage ----------- .. _param-imdiag-input-serverstreamdriverpermittedpeer: .. _imdiag.parameter.input.serverstreamdriverpermittedpeer-usage: .. code-block:: rsyslog module(load="imdiag") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverStreamDriverPermittedPeer=["diag.example.com","127.0.0.1"] serverRun="19998") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagserverstreamdriverpermittedpeer: - $IMDiagServerStreamDriverPermittedPeer — maps to ServerStreamDriverPermittedPeer (status: legacy) .. index:: single: imdiag; $IMDiagServerStreamDriverPermittedPeer single: $IMDiagServerStreamDriverPermittedPeer See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-ratelimit-burst.rst0000644000000000000000000000013215103061376026054 xustar0030 mtime=1762419454.851381097 30 atime=1764928595.536535867 30 ctime=1764935921.632552835 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-ratelimit-burst.rst0000664000175000017500000000146515103061376025526 0ustar00rgerrger.. _param-imptcp-ratelimit-burst: .. _imptcp.parameter.input.ratelimit-burst: RateLimit.Burst =============== .. index:: single: imptcp; RateLimit.Burst single: RateLimit.Burst .. summary-start Sets the rate-limiting burst size in number of messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: RateLimit.Burst :Scope: input :Type: integer :Default: input=10000 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the rate-limiting burst in number of messages. Input usage ----------- .. _param-imptcp-input-ratelimit-burst: .. _imptcp.parameter.input.ratelimit-burst-usage: .. code-block:: rsyslog input(type="imptcp" rateLimit.burst="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-pollinginterval.rst0000644000000000000000000000013115062756615026121 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.923486258 29 ctime=1764935921.42254962 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-pollinginterval.rst0000664000175000017500000000301215062756615025562 0ustar00rgerrger.. _param-imfile-pollinginterval: .. _imfile.parameter.module.pollinginterval: .. _imfile.parameter.pollinginterval: PollingInterval =============== .. index:: single: imfile; PollingInterval single: PollingInterval .. summary-start Seconds between file scans in polling mode; default ``10``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: PollingInterval :Scope: module :Type: integer :Default: module=10 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Specifies how often files are polled for new data. It has effect only if imfile is running in polling mode. The time specified is in seconds. During each polling interval, all files are processed in a round-robin fashion. A short poll interval provides more rapid message forwarding, but requires more system resources. While it is possible, it is strongly recommended not to set the polling interval to 0 seconds. That will make rsyslogd become a CPU hog, taking up considerable resources. Even if quick response is needed, 1 second should be sufficient. imfile keeps reading files as long as there is any data in them, so a "polling sleep" will only happen when nothing is left to be processed. **We recommend to use inotify mode.** Module usage ------------ .. _param-imfile-module-pollinginterval: .. _imfile.parameter.module.pollinginterval-usage: .. code-block:: rsyslog module(load="imfile" PollingInterval="10") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ratelimit-burst.rst0000644000000000000000000000013215103061376026422 xustar0030 mtime=1762419454.851381097 30 atime=1764928597.033581836 30 ctime=1764935921.849556157 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ratelimit-burst.rst0000664000175000017500000000225115103061376026066 0ustar00rgerrger.. _param-imuxsock-ratelimit-burst: .. _imuxsock.parameter.input.ratelimit-burst: RateLimit.Burst =============== .. index:: single: imuxsock; RateLimit.Burst single: RateLimit.Burst .. summary-start Sets the rate-limiting burst size in messages for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: RateLimit.Burst :Scope: input :Type: integer :Default: input=200 :Required?: no :Introduced: 5.7.1 Description ----------- Specifies the rate-limiting burst in number of messages. The maximum is ``(2^31)-1``. Input usage ----------- .. _param-imuxsock-input-ratelimit-burst: .. _imuxsock.parameter.input.ratelimit-burst-usage: .. code-block:: rsyslog input(type="imuxsock" rateLimit.burst="500") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.imuxsockratelimitburst: - $IMUXSockRateLimitBurst — maps to RateLimit.Burst (status: legacy) .. index:: single: imuxsock; $IMUXSockRateLimitBurst single: $IMUXSockRateLimitBurst See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls.rst0000644000000000000000000000013215114522477023531 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.465642415 30 ctime=1764935921.698553845 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls.rst0000664000175000017500000000237715114522477023206 0ustar00rgerrger.. _param-imrelp-tls: .. _imrelp.parameter.input.tls: tls === .. index:: single: imrelp; tls single: tls (imrelp) .. summary-start Enables TLS encryption for RELP connections handled by this listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not documented Description ----------- If set to "on", the RELP connection will be encrypted by TLS, so that the data is protected against observers. Please note that both the client and the server must have set ``tls`` to either "on" or "off". Other combinations lead to unpredictable results. *Attention when using GnuTLS 2.10.x or older* Versions older than GnuTLS 2.10.x may cause a crash (Segfault) under certain circumstances. Most likely when an imrelp inputs and an omrelp output is configured. The crash may happen when you are receiving/sending messages at the same time. Upgrade to a newer version like GnuTLS 2.12.21 to solve the problem. Input usage ----------- .. _param-imrelp-input-tls-usage: .. _imrelp.parameter.input.tls-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-port.rst0000644000000000000000000000013215114522477023725 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.471642562 30 ctime=1764935922.154560826 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-port.rst0000664000175000017500000000147215114522477023375 0ustar00rgerrger.. _param-omdtls-port: .. _omdtls.parameter.input.port: port ==== .. index:: single: omdtls; port single: port .. summary-start Sets the UDP port on the remote host that receives DTLS messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: port :Scope: input :Type: word :Default: input=443 :Required?: no :Introduced: v8.2402.0 Description ----------- Defines the port number on the target host where log messages will be sent. The standard port for DTLS is 4433. This should be specified explicitly if required, as the module defaults to port 443. Input usage ----------- .. _omdtls.parameter.input.port-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-dynatopic.rst0000644000000000000000000000013115062756615025046 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.423716203 29 ctime=1764935922.45456542 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-dynatopic.rst0000664000175000017500000000163115062756615024514 0ustar00rgerrger.. _param-omkafka-dynatopic: .. _omkafka.parameter.module.dynatopic: DynaTopic ========= .. index:: single: omkafka; DynaTopic single: DynaTopic .. summary-start Treat `topic` as a template for dynamic topic names. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: DynaTopic :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, the topic parameter becomes a template for which topic to produce messages to. The cache is cleared on HUP. Action usage ------------ .. _param-omkafka-action-dynatopic: .. _omkafka.parameter.action.dynatopic: .. code-block:: rsyslog action(type="omkafka" DynaTopic="on" Topic="topic.template") Notes ----- - Originally documented as "binary"; uses boolean values. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-keepalive-time.rst0000644000000000000000000000013115062756615025640 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.520535375 30 ctime=1764935921.604552406 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-keepalive-time.rst0000664000175000017500000000273215062756615025311 0ustar00rgerrger.. _param-imptcp-keepalive-time: .. _imptcp.parameter.input.keepalive-time: KeepAlive.Time ============== .. index:: single: imptcp; KeepAlive.Time single: KeepAlive.Time .. summary-start Sets idle time before the first keepalive probe is sent. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: KeepAlive.Time :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further. The default, 0, means that the operating system defaults are used. This has only effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imptcp-input-keepalive-time: .. _imptcp.parameter.input.keepalive-time-usage: .. code-block:: rsyslog input(type="imptcp" keepAlive.time="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverkeepalive_time: - $InputPTCPServerKeepAlive_time — maps to KeepAlive.Time (status: legacy) .. index:: single: imptcp; $InputPTCPServerKeepAlive_time single: $InputPTCPServerKeepAlive_time See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-consumergroup.rst0000644000000000000000000000013115114522477025751 xustar0030 mtime=1764926783.027631661 29 atime=1764926783.45564217 30 ctime=1764935921.506550906 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-consumergroup.rst0000664000175000017500000000157615114522477025427 0ustar00rgerrger.. _param-imkafka-consumergroup: .. _imkafka.parameter.input.consumergroup: consumergroup ============= .. index:: single: imkafka; consumergroup single: consumergroup .. summary-start Sets the Kafka consumer group identifier (group.id) used by imkafka. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: consumergroup :Scope: input :Type: string :Default: input=``none`` :Required?: no :Introduced: 8.27.0 Description ----------- With this parameter the group.id for the consumer is set. All consumers sharing the same group.id belong to the same group. Input usage ----------- .. _imkafka.parameter.input.consumergroup-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="your-topic" consumerGroup="default") See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-statefile.rst0000644000000000000000000000013215062756615025424 xustar0030 mtime=1758190989.187640921 30 atime=1764928594.618507643 30 ctime=1764935921.493550707 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-statefile.rst0000664000175000017500000000231115062756615025065 0ustar00rgerrger.. _param-imjournal-statefile: .. _imjournal.parameter.module.statefile: .. meta:: :tag: module:imjournal :tag: parameter:StateFile StateFile ========= .. index:: single: imjournal; StateFile single: StateFile .. summary-start Specifies path to the state file holding the journal cursor. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: StateFile :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines where the module stores its persistent position in the journal. A relative path is created inside rsyslog's working directory; an absolute path is used as is. Module usage ------------ .. _param-imjournal-module-statefile: .. _imjournal.parameter.module.statefile-usage: .. code-block:: rsyslog module(load="imjournal" StateFile="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournalstatefile: - $imjournalStateFile — maps to StateFile (status: legacy) .. index:: single: imjournal; $imjournalStateFile single: $imjournalStateFile See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-cry-provider.rst0000644000000000000000000000013215062756615025344 xustar0030 mtime=1758190989.206641191 30 atime=1764928600.198678773 30 ctime=1764935922.274562664 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-cry-provider.rst0000664000175000017500000000173715062756615025020 0ustar00rgerrger.. _param-omfile-cry-provider: .. _omfile.parameter.module.cry-provider: cry.Provider ============ .. index:: single: omfile; cry.Provider single: cry.Provider .. summary-start Selects a crypto provider for log encryption. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: cry.Provider :Scope: action :Type: word :Default: action=no crypto provider :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Selects a crypto provider for log encryption. By selecting a provider, the encryption feature is turned on. Currently, there are two providers called ":doc:`gcry <../../configuration/cryprov_gcry>`" and ":doc:`ossl <../../configuration/cryprov_ossl>`". Action usage ------------ .. _param-omfile-action-cry-provider: .. _omfile.parameter.action.cry-provider: .. code-block:: rsyslog action(type="omfile" cry.Provider="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-mailto.rst0000644000000000000000000000013215114522477024202 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.485642906 30 ctime=1764935922.508566246 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-mailto.rst0000664000175000017500000000246315114522477023653 0ustar00rgerrger.. _param-ommail-mailto: .. _ommail.parameter.input.mailto: mailTo ====== .. index:: single: ommail; mailTo single: mailTo .. summary-start Provides one or more recipient email addresses for each mail sent by ommail. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: mailTo :Scope: input :Type: array :Default: input=none :Required?: yes :Introduced: 8.5.0 Description ----------- The recipient email address(es). This is an array parameter, so multiple recipients can be provided in a list. For a single recipient, a simple string value is also accepted (for example, ``mailTo="operator@example.net"``). Input usage ------------ .. _ommail.parameter.input.mailto-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo=["operator@example.net", "admin@example.net"] ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailto: - $ActionMailTo — maps to mailTo (status: legacy) .. index:: single: ommail; $ActionMailTo single: $ActionMailTo See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-ignorepreviousmessages.rst0000644000000000000000000000013215062756615030254 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.632508073 30 ctime=1764935921.479550492 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-ignorepreviousmessages.rst0000664000175000017500000000276515062756615027732 0ustar00rgerrger.. _param-imjournal-ignorepreviousmessages: .. _imjournal.parameter.module.ignorepreviousmessages: .. meta:: :tag: module:imjournal :tag: parameter:IgnorePreviousMessages IgnorePreviousMessages ====================== .. index:: single: imjournal; IgnorePreviousMessages single: IgnorePreviousMessages .. summary-start Starts reading only new journal entries when no state file exists. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: IgnorePreviousMessages :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If enabled and no state file is present, messages already stored in the journal are skipped and only new entries are processed, preventing reprocessing of old logs. Module usage ------------ .. _param-imjournal-module-ignorepreviousmessages: .. _imjournal.parameter.module.ignorepreviousmessages-usage: .. code-block:: rsyslog module(load="imjournal" IgnorePreviousMessages="...") Notes ----- - Historic documentation called this a ``binary`` option; it is boolean. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournalignorepreviousmessages: - $ImjournalIgnorePreviousMessages — maps to IgnorePreviousMessages (status: legacy) .. index:: single: imjournal; $ImjournalIgnorePreviousMessages single: $ImjournalIgnorePreviousMessages See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-template.rst0000644000000000000000000000013215062756615024670 xustar0030 mtime=1758190989.211641261 30 atime=1764928601.505718706 30 ctime=1764935922.481565833 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-template.rst0000664000175000017500000000137015062756615024335 0ustar00rgerrger.. _param-omkafka-template: .. _omkafka.parameter.module.template: Template ======== .. index:: single: omkafka; Template single: Template .. summary-start Template used to format messages for this action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Template :Scope: action :Type: word :Default: action=inherits module :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Sets the template to be used for this action. Action usage ------------ .. _param-omkafka-action-template: .. _omkafka.parameter.action.template: .. code-block:: rsyslog action(type="omkafka" Template="MyTemplate") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-enterpriseoid.rst0000644000000000000000000000013215071746523025626 xustar0030 mtime=1760021843.825420781 30 atime=1764928602.768757245 30 ctime=1764935922.571567211 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-enterpriseoid.rst0000664000175000017500000000254415071746523025277 0ustar00rgerrger.. _param-omsnmp-enterpriseoid: .. _omsnmp.parameter.module.enterpriseoid: EnterpriseOID ============= .. index:: single: omsnmp; EnterpriseOID single: EnterpriseOID .. summary-start Specifies the enterprise OID used in SNMPv1 traps. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: EnterpriseOID :Scope: module :Type: string :Default: module=1.3.6.1.4.1.3.1.1 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- The default value means "enterprises.cmu.1.1" Customize this value if needed. I recommend to use the default value unless you require to use a different OID. This configuration parameter is used for **SNMPv1** only. It has no effect if **SNMPv2** is used. Module usage ------------ .. _param-omsnmp-module-enterpriseoid: .. _omsnmp.parameter.module.enterpriseoid-usage: .. code-block:: rsyslog action(type="omsnmp" enterpriseOID="1.3.6.1.4.1.3.1.1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmpenterpriseoid: - $actionsnmpenterpriseoid — maps to EnterpriseOID (status: legacy) .. index:: single: omsnmp; $actionsnmpenterpriseoid single: $actionsnmpenterpriseoid See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-inputproperty.rst0000644000000000000000000000013215071746523026024 xustar0030 mtime=1760021843.800420386 30 atime=1764928597.248588429 30 ctime=1764935921.911557106 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-inputproperty.rst0000664000175000017500000000152315071746523025471 0ustar00rgerrger.. _param-mmaitag-inputproperty: .. _mmaitag.parameter.action.inputproperty: inputProperty ============= .. index:: single: mmaitag; inputProperty single: inputProperty .. summary-start Selects which message property is classified instead of the raw message. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: inputProperty :Scope: action :Type: string :Default: none (raw message is used) :Required?: no :Introduced: 9.0.0 Description ----------- Specifies which message property to classify. If unset, the module uses the raw message text. Action usage ------------- .. _param-mmaitag-action-inputproperty: .. _mmaitag.parameter.action.inputproperty-usage: .. code-block:: rsyslog action(type="mmaitag" inputProperty="msg") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-permitexpiredcerts.rs0000644000000000000000000000013215062756615031023 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.181555682 30 ctime=1764935921.781555116 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-permitexpiredcerts.rst0000664000175000017500000000327015062756615030655 0ustar00rgerrger.. _param-imtcp-streamdriver-permitexpiredcerts: .. _imtcp.parameter.module.streamdriver-permitexpiredcerts: .. _imtcp.parameter.input.streamdriver-permitexpiredcerts: StreamDriver.PermitExpiredCerts =============================== .. index:: single: imtcp; StreamDriver.PermitExpiredCerts single: StreamDriver.PermitExpiredCerts .. summary-start Controls how expired certificates are handled in TLS mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.PermitExpiredCerts :Scope: module, input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=warn, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Controls how expired certificates will be handled when stream driver is in TLS mode. It can have one of the following values: - on = Expired certificates are allowed - off = Expired certificates are not allowed (Default, changed from warn to off since Version 8.2012.0) - warn = Expired certificates are allowed but warning will be logged The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-permitexpiredcerts: .. _imtcp.parameter.module.streamdriver-permitexpiredcerts-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.permitExpiredCerts="off") Input usage ----------- .. _param-imtcp-input-streamdriver-permitexpiredcerts: .. _imtcp.parameter.input.streamdriver-permitexpiredcerts-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.permitExpiredCerts="off") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-socket.rst0000644000000000000000000000013215062756615024576 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.073583063 30 ctime=1764935921.858556295 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-socket.rst0000664000175000017500000000212115062756615024236 0ustar00rgerrger.. _param-imuxsock-socket: .. _imuxsock.parameter.input.socket: Socket ====== .. index:: single: imuxsock; Socket single: Socket .. summary-start Adds an additional UNIX socket for this input to listen on. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: Socket :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Adds additional unix socket. Formerly specified with the ``-a`` option. Input usage ----------- .. _param-imuxsock-input-socket: .. _imuxsock.parameter.input.socket-usage: .. code-block:: rsyslog input(type="imuxsock" socket="/path/to/socket") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.addunixlistensocket: - $AddUnixListenSocket — maps to Socket (status: legacy) .. index:: single: imuxsock; $AddUnixListenSocket single: $AddUnixListenSocket See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-embeddedipv4-bits.rst0000644000000000000000000000013215071746523026221 xustar0030 mtime=1760021843.801420402 30 atime=1764928597.379592446 30 ctime=1764935921.922557275 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-embeddedipv4-bits.rst0000664000175000017500000000233415071746523025667 0ustar00rgerrger.. _param-mmanon-embeddedipv4-bits: .. _mmanon.parameter.input.embeddedipv4-bits: embeddedIpv4.bits ================= .. index:: single: mmanon; embeddedIpv4.bits single: embeddedIpv4.bits .. summary-start Sets how many low-order bits of embedded IPv4 addresses within IPv6 are anonymized. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: embeddedIpv4.bits :Scope: input :Type: positive integer :Default: input=96 :Required?: no :Introduced: 7.3.7 Description ----------- This sets the number of bits that should be anonymized (bits are from the right, so lower bits are anonymized first). This setting permits to save network information while still anonymizing user-specific data. The more bits you discard, the better the anonymization obviously is. The default of 96 bits reflects what German data privacy rules consider as being sufficiently anonymized. We assume, this can also be used as a rough but conservative guideline for other countries. Input usage ----------- .. _mmanon.parameter.input.embeddedipv4-bits-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" embeddedIpv4.bits="80") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-retryruleset.rst0000644000000000000000000000013215062756615027363 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.757665285 30 ctime=1764935922.225561914 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-retryruleset.rst0000664000175000017500000000161015062756615027025 0ustar00rgerrger.. _param-omelasticsearch-retryruleset: .. _omelasticsearch.parameter.module.retryruleset: retryruleset ============ .. index:: single: omelasticsearch; retryruleset single: retryruleset .. summary-start Ruleset used when processing retried records. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: retryruleset :Scope: action :Type: word :Default: none (unset) :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Names a ruleset to handle records requeued by `retryfailures`. If unset, retries start at the default ruleset. Action usage ------------ .. _param-omelasticsearch-action-retryruleset: .. _omelasticsearch.parameter.action.retryruleset: .. code-block:: rsyslog action(type="omelasticsearch" retryruleset="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omjournal-template.rst0000644000000000000000000000013115114522477025257 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.483642857 29 ctime=1764935922.44156522 rsyslog-8.2512.0/doc/source/reference/parameters/omjournal-template.rst0000664000175000017500000000324315114522477024726 0ustar00rgerrger.. _param-omjournal-template: .. _omjournal.parameter.input.template: template ======== .. index:: single: omjournal; template single: template .. summary-start Selects the template that formats journal entries before they are written. .. summary-end This parameter applies to :doc:`../../configuration/modules/omjournal`. :Name: template :Scope: input :Type: word :Default: none :Required?: no :Introduced: 8.17.0 Description ----------- Template to use when submitting messages. By default, rsyslog will use the incoming ``$msg`` property as the ``MESSAGE`` field of the journald entry. It also includes ``SYSLOG_IDENTIFIER`` (from the tag), ``SYSLOG_FACILITY``, and ``PRIORITY`` (derived from facility and severity). You can override the default formatting of the message, and include custom fields with a template. .. warning:: Complex JSON objects or arrays from ``json`` or ``subtree`` templates are **not** supported. The omjournal action currently converts each field via ``json_object_get_string()``, which returns ``NULL`` for nested JSON structures and leads to a crash inside ``build_iovec()``. Emit only values that convert cleanly to strings (plain text, numbers, booleans) until this limitation is fixed. See `rsyslog issue #881 `_ for background on the crash. Journald requires that the template's output contains a field named ``MESSAGE``. Input usage ----------- .. _param-omjournal-input-template: .. _omjournal.parameter.input.template-usage: .. code-block:: shell action(type="omjournal" template="journal") See also -------- See also :doc:`../../configuration/modules/omjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-ratelimit-interval.rst0000644000000000000000000000013215114522477026566 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.479642759 30 ctime=1764935922.400564593 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-ratelimit-interval.rst0000664000175000017500000000242115114522477026231 0ustar00rgerrger.. _param-omhttp-ratelimit-interval: .. _omhttp.parameter.input.ratelimit-interval: ratelimit.interval ================== .. index:: single: omhttp; ratelimit.interval single: ratelimit.interval .. summary-start Controls the duration, in seconds, of the rate-limiting window for the retry ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: ratelimit.interval :Scope: input :Type: integer :Default: input=600 :Required?: no :Introduced: Not specified Description ----------- This parameter sets the rate limiting behavior for the :ref:`param-omhttp-retry-ruleset`. It specifies the interval in seconds onto which rate-limiting is to be applied. If more than :ref:`param-omhttp-ratelimit-burst` messages are read during that interval, further messages up to the end of the interval are discarded. The number of messages discarded is emitted at the end of the interval (if there were any discards). Setting this to value zero turns off ratelimiting. Input usage ----------- .. _omhttp.parameter.input.ratelimit-interval-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" retry="on" rateLimitInterval="300" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-defaulttz.rst0000644000000000000000000000013215062756615024742 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.589537496 30 ctime=1764935921.574551947 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-defaulttz.rst0000664000175000017500000000140415062756615024405 0ustar00rgerrger.. _param-imptcp-defaulttz: .. _imptcp.parameter.input.defaulttz: Defaulttz ========= .. index:: single: imptcp; Defaulttz single: Defaulttz .. summary-start Sets a default time zone string. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Defaulttz :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set default time zone. At most seven chars are set, as we would otherwise overrun our buffer. Input usage ----------- .. _param-imptcp-input-defaulttz: .. _imptcp.parameter.input.defaulttz-usage: .. code-block:: rsyslog input(type="imptcp" defaulttz="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-output.rst0000644000000000000000000000013215062756615024307 xustar0030 mtime=1758190989.212641276 30 atime=1764928602.111737206 30 ctime=1764935922.546566828 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-output.rst0000664000175000017500000000433315062756615023756 0ustar00rgerrger.. _param-omprog-output: .. _omprog.parameter.action.output: output ====== .. index:: single: omprog; output single: output .. summary-start Appends the program's output streams to the specified file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: output :Scope: action :Type: string :Default: action=none :Required?: no :Introduced: v8.1.6 Description ----------- Full path of a file where the output of the external program will be saved. If the file already exists, the output is appended to it. If the file does not exist, it is created with the permissions specified by :ref:`param-omprog-filecreatemode`. If :ref:`param-omprog-confirmmessages` is set to "off" (the default), both the stdout and stderr of the child process are written to the specified file. If :ref:`param-omprog-confirmmessages` is set to "on", only the stderr of the child is written to the specified file (since stdout is used for confirming the messages). Rsyslog will reopen the file whenever it receives a HUP signal. This allows the file to be externally rotated (using a tool like *logrotate*): after each rotation of the file, make sure a HUP signal is sent to rsyslogd. If the omprog action is configured to use multiple worker threads (:doc:`queue.workerThreads <../../rainerscript/queue_parameters>` is set to a value greater than 1), the lines written by the various program instances will not appear intermingled in the output file, as long as the lines do not exceed a certain length and the program writes them to stdout/stderr in line-buffered mode. For details, refer to `Interface between rsyslog and external output plugins `_. If this parameter is not specified, the output of the program will be redirected to ``/dev/null``. .. note:: Before version v8.38.0, this parameter was intended for debugging purposes only. Since v8.38.0, the parameter can be used for production. Action usage ------------ .. _param-omprog-action-output: .. _omprog.parameter.action.output-usage: .. code-block:: rsyslog action(type="omprog" output="/var/log/prog.log") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-snmpv1dynsource.rst0000644000000000000000000000013215071746523026132 xustar0030 mtime=1760021843.828420828 30 atime=1764928602.784757733 30 ctime=1764935922.580567349 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-snmpv1dynsource.rst0000664000175000017500000000235715071746523025605 0ustar00rgerrger.. _param-omsnmp-snmpv1dynsource: .. _omsnmp.parameter.module.snmpv1dynsource: Snmpv1DynSource =============== .. index:: single: omsnmp; Snmpv1DynSource single: Snmpv1DynSource .. summary-start Overrides the SNMPv1 trap source address via template. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Snmpv1DynSource :Scope: module :Type: string :Default: module="" :Required?: no :Introduced: 8.2001 Description ----------- .. versionadded:: 8.2001 If set, the source field of the SNMP trap can be overwritten with a template. valid IPv4 Address. Otherwise setting the source will fail. Below is a sample template called "dynsource" which you can use to set the source to a custom property: .. code-block:: none set $!custom_host = $fromhost; template(name="dynsource" type="list") { property(name="$!custom_host") } This configuration parameter is used for **SNMPv1** only. It has no effect if **SNMPv2** is used. Module usage ------------ .. _param-omsnmp-module-snmpv1dynsource: .. _omsnmp.parameter.module.snmpv1dynsource-usage: .. code-block:: rsyslog action(type="omsnmp" snmpv1DynSource="dynsource") See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-filecreatemode.rst0000644000000000000000000000013215062756615025667 xustar0030 mtime=1758190989.207641205 30 atime=1764928599.885669202 30 ctime=1764935922.300563062 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-filecreatemode.rst0000664000175000017500000000342615062756615025340 0ustar00rgerrger.. _param-omfile-filecreatemode: .. _omfile.parameter.module.filecreatemode: fileCreateMode ============== .. index:: single: omfile; fileCreateMode single: fileCreateMode .. summary-start Specifies the file system permissions for newly created log files. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: fileCreateMode :Scope: module, action :Type: string (octal) :Default: module=0644; action=inherits module :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the file system permissions for log files newly created by ``omfile``. The value must be a 4-digit octal number (e.g., ``0640``). When set at the module level, it defines the default mode for all ``omfile`` actions. When set at the action level, it overrides the module default for that specific action. Please note that the actual permissions depend on rsyslogd's process umask. If in doubt, use ``$umask 0000`` at the beginning of the configuration file to remove any restrictions. Module usage ------------ .. _param-omfile-module-filecreatemode: .. _omfile.parameter.module.filecreatemode-usage: .. code-block:: rsyslog module(load="builtin:omfile" fileCreateMode="0644") Action usage ------------ .. _param-omfile-action-filecreatemode: .. _omfile.parameter.action.filecreatemode: .. code-block:: rsyslog action(type="omfile" fileCreateMode="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.filecreatemode: - $FileCreateMode — maps to fileCreateMode (status: legacy) .. index:: single: omfile; $FileCreateMode single: $FileCreateMode See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-createpath.rst0000644000000000000000000000013215062756615025426 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.065582817 30 ctime=1764935921.833555912 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-createpath.rst0000664000175000017500000000333115062756615025072 0ustar00rgerrger.. _param-imuxsock-createpath: .. _imuxsock.parameter.input.createpath: CreatePath ========== .. index:: single: imuxsock; CreatePath single: CreatePath .. summary-start Creates missing directories for the specified socket path. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: CreatePath :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: 4.7.0 Description ----------- Create directories in the socket path if they do not already exist. They are created with 0755 permissions with the owner being the process under which rsyslogd runs. The default is not to create directories. Keep in mind, though, that rsyslogd always creates the socket itself if it does not exist (just not the directories by default). This option is primarily considered useful for defining additional sockets that reside on non-permanent file systems. As rsyslogd probably starts up before the daemons that create these sockets, it is a vehicle to enable rsyslogd to listen to those sockets even though their directories do not yet exist. .. versionadded:: 4.7.0 Input usage ----------- .. _param-imuxsock-input-createpath: .. _imuxsock.parameter.input.createpath-usage: .. code-block:: rsyslog input(type="imuxsock" createPath="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketcreatepath: - $InputUnixListenSocketCreatePath — maps to CreatePath (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketCreatePath single: $InputUnixListenSocketCreatePath See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-socketpath.rst0000644000000000000000000000013215071746523025424 xustar0030 mtime=1760021843.806420481 30 atime=1764928597.681601707 30 ctime=1764935921.964557918 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-socketpath.rst0000664000175000017500000000144515071746523025074 0ustar00rgerrger.. _param-mmdarwin-socketpath: .. _mmdarwin.parameter.input.socketpath: socketpath ========== .. index:: single: mmdarwin; socketpath single: socketpath .. summary-start Specifies the Darwin filter socket path that mmdarwin connects to. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: socketpath :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: at least 8.x, possibly earlier Description ----------- The Darwin filter socket path to use. Input usage ----------- .. _param-mmdarwin-input-socketpath-usage: .. _mmdarwin.parameter.input.socketpath-usage: .. code-block:: rsyslog action(type="mmdarwin" socketPath="/path/to/reputation_1.sock") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-committransactionmark.rst0000644000000000000000000000013215062756615027360 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.103736962 30 ctime=1764935922.529566568 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-committransactionmark.rst0000664000175000017500000000210015062756615027015 0ustar00rgerrger.. _param-omprog-committransactionmark: .. _omprog.parameter.action.committransactionmark: commitTransactionMark ====================== .. index:: single: omprog; commitTransactionMark single: commitTransactionMark .. summary-start Defines the marker sent to denote the end of a transaction. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: commitTransactionMark :Scope: action :Type: string :Default: action="COMMIT TRANSACTION" :Required?: no :Introduced: 8.31.0 Description ----------- Allows specifying the mark message that rsyslog will send to the external program to indicate the end of a transaction (batch). This parameter is ignored if :ref:`param-omprog-usetransactions` is disabled. Action usage ------------ .. _param-omprog-action-committransactionmark: .. _omprog.parameter.action.committransactionmark-usage: .. code-block:: rsyslog action(type="omprog" useTransactions="on" commitTransactionMark="COMMIT TRANSACTION") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-send_partial.rst0000644000000000000000000000013215071746523025724 xustar0030 mtime=1760021843.806420481 30 atime=1764928597.713602688 30 ctime=1764935921.961557872 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-send_partial.rst0000664000175000017500000000302515071746523025370 0ustar00rgerrger.. _param-mmdarwin-send_partial: .. _mmdarwin.parameter.input.send_partial: send_partial ============ .. index:: single: mmdarwin; send_partial single: send_partial .. summary-start Controls whether mmdarwin calls Darwin when some fields are missing from the message. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: send_partial :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Controls whether to send data to Darwin if not all :json:`"fields"` could be found in the message. Darwin filters typically require a strict set of parameters and may not process incomplete data, so leaving this setting at :json:`"off"` is recommended unless you have verified the filter accepts missing fields. For example, for the following log line: .. code-block:: json { "from": "192.168.1.42", "date": "2012-12-21 00:00:00", "status": "200", "data": { "status": true, "message": "Request processed correctly" } } and the :json:`"fields"` array: .. code-block:: none ["!from", "!data!status", "!this!field!is!not!in!message"] the third field won't be found, so the call to Darwin will be dropped. Input usage ----------- .. _param-mmdarwin-input-send_partial-usage: .. _mmdarwin.parameter.input.send_partial-usage: .. code-block:: rsyslog action(type="mmdarwin" sendPartial="on") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-tls-cacert.rst0000644000000000000000000000013215062756615026653 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.685663082 30 ctime=1764935922.246562235 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-tls-cacert.rst0000664000175000017500000000163115062756615026320 0ustar00rgerrger.. _param-omelasticsearch-tls-cacert: .. _omelasticsearch.parameter.module.tls-cacert: .. _omelasticsearch.parameter.module.tls.cacert: tls.cacert ========== .. index:: single: omelasticsearch; tls.cacert single: tls.cacert .. summary-start CA certificate file used to verify the Elasticsearch server. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: tls.cacert :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Path to a PEM file containing the CA certificate that issued the server certificate. Action usage ------------ .. _param-omelasticsearch-action-tls-cacert: .. _omelasticsearch.parameter.action.tls-cacert: .. code-block:: rsyslog action(type="omelasticsearch" tls.cacert="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-maxframesize.rst0000644000000000000000000000013215062756615025253 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.072552336 30 ctime=1764935921.728554304 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-maxframesize.rst0000664000175000017500000000272015062756615024720 0ustar00rgerrger.. _param-imtcp-maxframesize: .. _imtcp.parameter.module.maxframesize: .. _imtcp.parameter.input.maxframesize: MaxFrameSize ============ .. index:: single: imtcp; MaxFrameSize single: MaxFrameSize .. summary-start Sets the maximum frame size in octet-counted mode before switching to octet stuffing. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: MaxFrameSize :Scope: module, input :Type: integer :Default: module=200000, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- When in octet counted mode, the frame size is given at the beginning of the message. With this parameter the max size this frame can have is specified and when the frame gets to large the mode is switched to octet stuffing. The max value this parameter can have was specified because otherwise the integer could become negative and this would result in a Segmentation Fault. (Max Value = 200000000) The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-maxframesize: .. _imtcp.parameter.module.maxframesize-usage: .. code-block:: rsyslog module(load="imtcp" maxFrameSize="...") Input usage ----------- .. _param-imtcp-input-maxframesize: .. _imtcp.parameter.input.maxframesize-usage: .. code-block:: rsyslog input(type="imtcp" port="514" maxFrameSize="...") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-body-enable.rst0000644000000000000000000000013215114522477025076 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.485642906 30 ctime=1764935922.504566185 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-body-enable.rst0000664000175000017500000000270115114522477024542 0ustar00rgerrger.. _param-ommail-body-enable: .. _ommail.parameter.input.body-enable: bodyEnable ========== .. index:: single: ommail; bodyEnable single: bodyEnable .. summary-start Toggles inclusion of the mail body in messages sent by ommail. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: bodyEnable :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 8.5.0 Description ----------- Setting this to "off" permits the actual message body to be excluded. This may be useful for pager-like devices or cell phone SMS messages. The default is "on", which is appropriate for almost all cases. This option should only be disabled for specific use cases, as it deviates from standard email behavior. Input usage ------------ .. _ommail.parameter.input.body-enable-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" bodyEnable="off" ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailenablebody: - $ActionMailEnableBody — maps to bodyEnable (status: legacy) .. index:: single: ommail; $ActionMailEnableBody single: $ActionMailEnableBody See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-flowcontrol.rst0000644000000000000000000000013215062756615025130 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.122553871 30 ctime=1764935921.712554059 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-flowcontrol.rst0000664000175000017500000000356415062756615024604 0ustar00rgerrger.. _param-imtcp-flowcontrol: .. _imtcp.parameter.module.flowcontrol: .. _imtcp.parameter.input.flowcontrol: FlowControl =========== .. index:: single: imtcp; FlowControl single: FlowControl .. summary-start Applies light flow control to throttle senders when queues near full. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: FlowControl :Scope: module, input :Type: boolean :Default: module=on, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This setting specifies whether some message flow control shall be exercised on the related TCP input. If set to on, messages are handled as "light delayable", which means the sender is throttled a bit when the queue becomes near-full. This is done in order to preserve some queue space for inputs that can not throttle (like UDP), but it may have some undesired effect in some configurations. Still, we consider this as a useful setting and thus it is the default. To turn the handling off, simply configure that explicitly. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-flowcontrol: .. _imtcp.parameter.module.flowcontrol-usage: .. code-block:: rsyslog module(load="imtcp" flowControl="off") Input usage ----------- .. _param-imtcp-input-flowcontrol: .. _imtcp.parameter.input.flowcontrol-usage: .. code-block:: rsyslog input(type="imtcp" port="514" flowControl="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpflowcontrol: - $InputTCPFlowControl — maps to FlowControl (status: legacy) .. index:: single: imtcp; $InputTCPFlowControl single: $InputTCPFlowControl See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-prioritizesan.rst0000644000000000000000000000013215062756615030167 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.195556112 30 ctime=1764935921.783555147 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-prioritizesan.rst0000664000175000017500000000243715062756615027641 0ustar00rgerrger.. _param-imtcp-streamdriver-prioritizesan: .. _imtcp.parameter.module.streamdriver-prioritizesan: .. _imtcp.parameter.input.streamdriver-prioritizesan: StreamDriver.PrioritizeSAN ========================== .. index:: single: imtcp; StreamDriver.PrioritizeSAN single: StreamDriver.PrioritizeSAN .. summary-start Uses stricter SAN/CN matching for certificate validation. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.PrioritizeSAN :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Whether to use stricter SAN/CN matching. (driver-specific) The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-prioritizesan: .. _imtcp.parameter.module.streamdriver-prioritizesan-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.prioritizeSAN="on") Input usage ----------- .. _param-imtcp-input-streamdriver-prioritizesan: .. _imtcp.parameter.input.streamdriver-prioritizesan-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.prioritizeSAN="on") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-parsetrusted.rst0000644000000000000000000000013115062756615027526 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.960579596 29 ctime=1764935921.87455654 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-parsetrusted.rst0000664000175000017500000000276515062756615027205 0ustar00rgerrger.. _param-imuxsock-syssock-parsetrusted: .. _imuxsock.parameter.module.syssock-parsetrusted: SysSock.ParseTrusted ==================== .. index:: single: imuxsock; SysSock.ParseTrusted single: SysSock.ParseTrusted .. summary-start Turns trusted properties into JSON fields when annotation is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.ParseTrusted :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 6.5.0 Description ----------- If ``SysSock.Annotation`` is turned on, create JSON/lumberjack properties out of the trusted properties (which can be accessed via |FmtAdvancedName| JSON Variables, e.g. ``$!pid``) instead of adding them to the message. .. versionadded:: 6.5.0 As ``$SystemLogParseTrusted``. .. versionchanged:: 7.2.7 Support for the advanced format was added. Module usage ------------ .. _param-imuxsock-module-syssock-parsetrusted: .. _imuxsock.parameter.module.syssock-parsetrusted-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.parseTrusted="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogparsetrusted: - $SystemLogParseTrusted — maps to SysSock.ParseTrusted (status: legacy) .. index:: single: imuxsock; $SystemLogParseTrusted single: $SystemLogParseTrusted See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-veryrobustzip.rst0000644000000000000000000000013115062756615025665 xustar0030 mtime=1758190989.209641233 29 atime=1764928600.10567593 30 ctime=1764935922.330563521 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-veryrobustzip.rst0000664000175000017500000000367115062756615025341 0ustar00rgerrger.. _param-omfile-veryrobustzip: .. _omfile.parameter.module.veryrobustzip: veryRobustZip ============= .. index:: single: omfile; veryRobustZip single: veryRobustZip .. summary-start If *zipLevel* is greater than 0, then this setting controls if extra headers are written to make the resulting file extra hardened against malfunction. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: veryRobustZip :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 7.3.0 Description ----------- If *zipLevel* is greater than 0, then this setting controls if extra headers are written to make the resulting file extra hardened against malfunction. If set to off, data appended to previously unclean closed files may not be accessible without extra tools (like `gztool `_ with: ``gztool -p``). Note that this risk is usually expected to be bearable, and thus "off" is the default mode. The extra headers considerably degrade compression, files with this option set to "on" may be four to five times as large as files processed in "off" mode. **In order to avoid this degradation in compression** both *flushOnTXEnd* and *asyncWriting* parameters must be set to "off" and also *ioBufferSize* must be raised from default "4k" value to at least "32k". This way a reasonable compression factor is maintained, similar to a non-blocked gzip file: .. code-block:: none veryRobustZip="on" ioBufferSize="64k" flushOnTXEnd="off" asyncWriting="off" Do not forget to add your desired *zipLevel* to this configuration line. Action usage ------------ .. _param-omfile-action-veryrobustzip: .. _omfile.parameter.action.veryrobustzip: .. code-block:: rsyslog action(type="omfile" veryRobustZip="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-sslpartialchain.rst0000644000000000000000000000013115071746523027322 xustar0030 mtime=1760021843.816420639 30 atime=1764928598.253619239 29 ctime=1764935922.05155925 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-sslpartialchain.rst0000664000175000017500000000332315071746523026770 0ustar00rgerrger.. _param-mmkubernetes-sslpartialchain: .. _mmkubernetes.parameter.action.sslpartialchain: sslpartialchain =============== .. index:: single: mmkubernetes; sslpartialchain single: sslpartialchain .. summary-start Enables OpenSSL ``X509_V_FLAG_PARTIAL_CHAIN`` verification. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: sslpartialchain :Scope: action :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This option is only available if rsyslog was built with support for OpenSSL and only if the `X509_V_FLAG_PARTIAL_CHAIN` flag is available. If you attempt to set this parameter on other platforms, you will get an `INFO` level log message. This was done so that you could use the same configuration on different platforms. If `"on"`, this will set the OpenSSL certificate store flag `X509_V_FLAG_PARTIAL_CHAIN`. This will allow you to verify the Kubernetes API server cert with only an intermediate CA cert in your local trust store, rather than having to have the entire intermediate CA + root CA chain in your local trust store. See also `man s_client` - the `-partial_chain` flag. If you get errors like this, you probably need to set `sslpartialchain="on"`: .. code-block:: none rsyslogd: mmkubernetes: failed to connect to [https://...url...] - 60:Peer certificate cannot be authenticated with given CA certificates Action usage ------------ .. _param-mmkubernetes-action-sslpartialchain: .. _mmkubernetes.parameter.action.sslpartialchain-usage: .. code-block:: rsyslog action(type="mmkubernetes" sslPartialChain="on") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-dynatopic-cachesize.rst0000644000000000000000000000013215062756615027003 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.431716447 30 ctime=1764935922.452565389 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-dynatopic-cachesize.rst0000664000175000017500000000155415062756615026454 0ustar00rgerrger.. _param-omkafka-dynatopic-cachesize: .. _omkafka.parameter.module.dynatopic-cachesize: DynaTopic.Cachesize =================== .. index:: single: omkafka; DynaTopic.Cachesize single: DynaTopic.Cachesize .. summary-start Number of dynamic topics kept in cache. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: DynaTopic.Cachesize :Scope: action :Type: integer :Default: action=50 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, defines the number of topics that will be kept in the dynatopic cache. Action usage ------------ .. _param-omkafka-action-dynatopic-cachesize: .. _omkafka.parameter.action.dynatopic-cachesize: .. code-block:: rsyslog action(type="omkafka" DynaTopic.Cachesize="100") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-maxlinesatonce.rst0000644000000000000000000000013215062756615025723 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.008488876 30 ctime=1764935921.403549329 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-maxlinesatonce.rst0000664000175000017500000000326315062756615025373 0ustar00rgerrger.. _param-imfile-maxlinesatonce: .. _imfile.parameter.input.maxlinesatonce: .. _imfile.parameter.maxlinesatonce: MaxLinesAtOnce ============== .. index:: single: imfile; MaxLinesAtOnce single: MaxLinesAtOnce .. summary-start Legacy polling-mode limit on how many lines are read before switching files. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: MaxLinesAtOnce :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This legacy setting is only supported in polling mode. In inotify mode it is fixed at ``0`` and attempts to set a different value are ignored but generate an error message. Future versions may remove this parameter. In polling mode, a value of ``0`` processes each file completely before switching to the next. Any other value limits processing to the specified number of lines before moving to the next file, providing a form of load multiplexing. For polling mode, the default is ``10240``. Input usage ----------- .. _param-imfile-input-maxlinesatonce: .. _imfile.parameter.input.maxlinesatonce-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" MaxLinesAtOnce="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilemaxlinesatonce: - ``$InputFileMaxLinesAtOnce`` — maps to MaxLinesAtOnce (status: legacy) .. index:: single: imfile; $InputFileMaxLinesAtOnce single: $InputFileMaxLinesAtOnce See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-server.rst0000644000000000000000000000013215062756615026120 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.484656932 30 ctime=1764935922.231562005 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-server.rst0000664000175000017500000000164215062756615025567 0ustar00rgerrger.. _param-omelasticsearch-server: .. _omelasticsearch.parameter.module.server: Server ====== .. index:: single: omelasticsearch; Server single: Server .. summary-start List of Elasticsearch servers to send events to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: Server :Scope: action :Type: array[string] :Default: action=localhost :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Defines one or more Elasticsearch servers. If no scheme is given, it is chosen based on `usehttps`. Missing ports use `serverport`. Requests are load-balanced in round-robin order. Action usage ------------ .. _param-omelasticsearch-action-server: .. _omelasticsearch.parameter.action.server: .. code-block:: rsyslog action(type="omelasticsearch" Server="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-skippipelineifempty.rst0000644000000000000000000000013215062756615030704 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.568659502 30 ctime=1764935922.237562097 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-skippipelineifempty.rst0000664000175000017500000000206415062756615030352 0ustar00rgerrger.. _param-omelasticsearch-skippipelineifempty: .. _omelasticsearch.parameter.module.skippipelineifempty: skipPipelineIfEmpty =================== .. index:: single: omelasticsearch; skipPipelineIfEmpty single: skipPipelineIfEmpty .. summary-start Omit the pipeline parameter when `pipelineName` expands to an empty string. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: skipPipelineIfEmpty :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When enabled and the pipeline name resolves to an empty value, the parameter is not sent to Elasticsearch to avoid errors. Action usage ------------ .. _param-omelasticsearch-action-skippipelineifempty: .. _omelasticsearch.parameter.action.skippipelineifempty: .. code-block:: rsyslog action(type="omelasticsearch" skipPipelineIfEmpty="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-kafkaheader.rst0000644000000000000000000000013215071746523025300 xustar0030 mtime=1760021843.823420749 30 atime=1764928601.497718462 30 ctime=1764935922.461565526 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-kafkaheader.rst0000664000175000017500000000157115071746523024750 0ustar00rgerrger.. _param-omkafka-kafkaheader: .. _omkafka.parameter.module.kafkaheader: KafkaHeader =========== .. index:: single: omkafka; KafkaHeader single: KafkaHeader .. summary-start Defines Kafka message headers to attach to each produced message. Each entry is a `key=value` pair. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: KafkaHeader :Scope: action :Type: array[string] :Default: action=none :Required?: no :Introduced: 8.2405.0 Description ----------- Specifies static headers that are added to every message sent to Kafka. The parameter accepts an array of `key=value` strings. Action usage ------------ .. code-block:: rsyslog action(type="omkafka" topic="mytopic" broker="localhost:9092" kafkaHeader=["foo=bar","answer=42"]) See also -------- * :doc:`../../configuration/modules/omkafka` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-dynsearchtype.rst0000644000000000000000000000013215065245277027474 xustar0030 mtime=1758808767.291657809 30 atime=1764928599.540658645 30 ctime=1764935922.195561454 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-dynsearchtype.rst0000664000175000017500000000165315065245277027145 0ustar00rgerrger.. _param-omelasticsearch-dynsearchtype: .. _omelasticsearch.parameter.module.dynsearchtype: dynSearchType ============= .. index:: single: omelasticsearch; dynSearchType single: dynSearchType .. summary-start Treat `searchType` as a template name. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: dynSearchType :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When enabled, `searchType` references a template whose expansion becomes the type. Action usage ------------ .. _param-omelasticsearch-action-dynsearchtype: .. _omelasticsearch.parameter.action.dynsearchtype: .. code-block:: rsyslog action(type="omelasticsearch" dynSearchType="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-deletestateonfiledelete.rst0000644000000000000000000000013215062756615027574 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.023489338 30 ctime=1764935921.377548931 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-deletestateonfiledelete.rst0000664000175000017500000000335115062756615027242 0ustar00rgerrger.. _param-imfile-deletestateonfiledelete: .. _imfile.parameter.input.deletestateonfiledelete: .. _imfile.parameter.deletestateonfiledelete: deleteStateOnFileDelete ======================= .. index:: single: imfile; deleteStateOnFileDelete single: deleteStateOnFileDelete .. summary-start Removes the state file when the monitored file is deleted. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: deleteStateOnFileDelete :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Controls whether the state file is deleted if its associated main file is removed. This usually prevents problems when a new file with the same name is created. However, if a monitored file is modified with an editor that replaces the file, deleting the state file would cause the whole file to be reprocessed. Disable this setting only when the reason is fully understood. Input usage ----------- .. _param-imfile-input-deletestateonfiledelete: .. _imfile.parameter.input.deletestateonfiledelete-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" deleteStateOnFileDelete="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.removestateondelete: - ``removeStateOnDelete`` — maps to deleteStateOnFileDelete (status: legacy) .. index:: single: imfile; removeStateOnDelete single: removeStateOnDelete See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-facility.rst0000644000000000000000000000013215062756615024515 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.956487275 30 ctime=1764935921.391549145 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-facility.rst0000664000175000017500000000255315062756615024166 0ustar00rgerrger.. _param-imfile-facility: .. _imfile.parameter.input.facility: .. _imfile.parameter.facility: Facility ======== .. index:: single: imfile; Facility single: Facility .. summary-start Sets the syslog facility for messages read from this file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: Facility :Scope: input :Type: word :Default: local0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The syslog facility to be assigned to messages read from this file. It can be specified in textual form (for example ``local0``) or as a number (for example ``16``). Textual form is recommended. Input usage ----------- .. _param-imfile-input-facility: .. _imfile.parameter.input.facility-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" Facility="local0") Notes ----- - See https://en.wikipedia.org/wiki/Syslog for facility numbers. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilefacility: - ``$InputFileFacility`` — maps to Facility (status: legacy) .. index:: single: imfile; $InputFileFacility single: $InputFileFacility See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-file.rst0000644000000000000000000000013215062756615023630 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.940486782 30 ctime=1764935921.393549176 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-file.rst0000664000175000017500000000240715062756615023277 0ustar00rgerrger.. _param-imfile-file: .. _imfile.parameter.input.file: .. _imfile.parameter.file: File ==== .. index:: single: imfile; File single: File .. summary-start Specifies the absolute file path to monitor; wildcards are allowed. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: File :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- The file being monitored. It must be an absolute path without macros or templates. Wildcards are supported at the file name level. See :ref:`WildCards ` in the module documentation for details. Input usage ----------- .. _param-imfile-input-file: .. _imfile.parameter.input.file-usage: .. code-block:: rsyslog input(type="imfile" File="/path/to/logfile" Tag="example") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilename: - ``$InputFileName`` — maps to File (status: legacy) .. index:: single: imfile; $InputFileName single: $InputFileName See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-preservecase.rst0000644000000000000000000000013115062756615025250 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.731572567 29 ctime=1764935921.81055556 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-preservecase.rst0000664000175000017500000000171415062756615024720 0ustar00rgerrger.. _param-imudp-preservecase: .. _imudp.parameter.module.preservecase: PreserveCase ============ .. index:: single: imudp; PreserveCase single: PreserveCase .. summary-start Controls whether ``fromhost`` preserves original case. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: PreserveCase :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.37.0 Description ----------- This parameter is for controlling the case in ``fromhost``. If ``PreserveCase`` is set to "on", the case in ``fromhost`` is preserved, e.g., ``Host1.Example.Org`` when the message was received from ``Host1.Example.Org``. Default is "off" for backward compatibility. Module usage ------------ .. _param-imudp-module-preservecase: .. _imudp.parameter.module.preservecase-usage: .. code-block:: rsyslog module(load="imudp" PreserveCase="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonrewrite-output.rst0000644000000000000000000000013115103346332025673 xustar0029 mtime=1762512090.62717594 30 atime=1764928598.034612531 30 ctime=1764935922.008558591 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonrewrite-output.rst0000664000175000017500000000240315103346332025337 0ustar00rgerrger.. _param-mmjsonrewrite-output: .. _mmjsonrewrite.parameter.input.output: output ====== .. index:: single: mmjsonrewrite; output single: output .. summary-start Sets the destination property that receives the rewritten JSON tree. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonrewrite`. :Name: output :Scope: input :Type: string :Default: none :Required?: yes :Introduced: 8.2410.0 Description ----------- Defines where the normalized JSON object is stored on the message. The property must use a JSON-capable prefix (``$!``, ``$.`` or ``$/``). When the configuration includes a leading ``$`` symbol it is removed automatically before validation. Other prefixes are rejected during configuration. At runtime ``mmjsonrewrite`` verifies that the destination property does not already exist. Attempting to overwrite an existing value triggers an error and the action aborts without modifying the message. Output usage ------------ .. _param-mmjsonrewrite-output-usage: .. _mmjsonrewrite.parameter.input.output-usage: .. code-block:: rsyslog action(type="mmjsonrewrite" input="$!raw" output="$!structured") See also -------- See also the :doc:`main mmjsonrewrite module documentation <../../configuration/modules/mmjsonrewrite>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-keepalive.rst0000644000000000000000000000013115062756615024704 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.494534576 30 ctime=1764935921.607552452 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-keepalive.rst0000664000175000017500000000215515062756615024354 0ustar00rgerrger.. _param-imptcp-keepalive: .. _imptcp.parameter.input.keepalive: KeepAlive ========= .. index:: single: imptcp; KeepAlive single: KeepAlive .. summary-start Enables TCP keep-alive packets on the socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: KeepAlive :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Enable or disable keep-alive packets at the tcp socket layer. The default is to disable them. Input usage ----------- .. _param-imptcp-input-keepalive: .. _imptcp.parameter.input.keepalive-usage: .. code-block:: rsyslog input(type="imptcp" keepAlive="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverkeepalive: - $InputPTCPServerKeepAlive — maps to KeepAlive (status: legacy) .. index:: single: imptcp; $InputPTCPServerKeepAlive single: $InputPTCPServerKeepAlive See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-authmode.rst0000644000000000000000000000013215114522477025335 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.463642366 30 ctime=1764935921.675553493 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-authmode.rst0000664000175000017500000000332015114522477024777 0ustar00rgerrger.. _param-imrelp-tls-authmode: .. _imrelp.parameter.input.tls-authmode: tls.authMode ============ .. index:: single: imrelp; tls.authMode single: tls.authMode .. summary-start Selects the mutual authentication strategy for TLS-secured RELP sessions. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.authMode :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- Sets the mode used for mutual authentication. Supported values are ``fingerprint``, ``name``, or ``certvalid``. ``fingerprint`` mode basically is what SSH does. It does not require a full PKI to be present, instead self-signed certs can be used on all peers. Even if a CA certificate is given, the validity of the peer cert is NOT verified against it. Only the certificate fingerprint counts. In ``name`` mode, certificate validation happens. Here, the matching is done against the certificate's subjectAltName and, as a fallback, the subject common name. If the certificate contains multiple names, a match on any one of these names is considered good and permits the peer to talk to rsyslog. ``certvalid`` mode validates the remote peer's certificate chain but does not check the subject name, so any certificate trusted by the configured CAs is accepted. This mode is therefore weaker than ``name`` and typically used only when that reduced verification is acceptable. Input usage ----------- .. _param-imrelp-input-tls-authmode-usage: .. _imrelp.parameter.input.tls-authmode-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.authMode="fingerprint") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-allowregex.rst0000644000000000000000000000013215071746523026144 xustar0030 mtime=1760021843.819420686 30 atime=1764928598.399623712 30 ctime=1764935922.065559464 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-allowregex.rst0000664000175000017500000000203015071746523025603 0ustar00rgerrger.. _param-mmnormalize-allowregex: .. _mmnormalize.parameter.module.allowregex: allowRegex =========== .. index:: single: mmnormalize; allowRegex single: allowRegex .. summary-start Enables support for liblognorm regex field types despite higher overhead. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: allowRegex :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 6.1.2, possibly earlier Description ----------- Specifies if regex field-type should be allowed. Regex field-type has significantly higher computational overhead compared to other fields, so it should be avoided when another field-type can achieve the desired effect. Needs to be ``on`` for regex field-type to work. Module usage ------------ .. _param-mmnormalize-module-allowregex: .. _mmnormalize.parameter.module.allowregex-usage: .. code-block:: rsyslog module(load="mmnormalize" allowRegex="on") See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgssserverservicename.rst0000644000000000000000000000013215114522477030600 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.454642145 30 ctime=1764935921.463550248 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgssserverservicename.rst0000664000175000017500000000252215114522477030245 0ustar00rgerrger.. _param-imgssapi-inputgssserverservicename: .. _imgssapi.parameter.input.inputgssserverservicename: InputGSSServerServiceName ========================= .. index:: single: imgssapi; InputGSSServerServiceName single: InputGSSServerServiceName .. summary-start Sets the Kerberos service principal name used by the GSS server. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSServerServiceName :Scope: input :Type: word :Default: host :Required?: no :Introduced: 3.11.5 Description ----------- Specifies the service name for the GSS server, used to form the Service Principal Name (SPN). This can be a simple name like ``host`` or a compound name such as ``host/rsyslog.example.com``. If not specified, it defaults to ``host``. Input usage ----------- .. _imgssapi.parameter.input.inputgssserverservicename-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssServerServiceName "host/rsyslog.example.com" Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgssserverservicename: - $inputGssServerServiceName — maps to InputGSSServerServiceName (status: legacy) .. index:: single: imgssapi; $inputGssServerServiceName single: $inputGssServerServiceName See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-bracketing.rst0000644000000000000000000000013215114522477025414 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.459642268 30 ctime=1764935921.546551518 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-bracketing.rst0000664000175000017500000000571715114522477025072 0ustar00rgerrger.. _param-impstats-bracketing: .. _impstats.parameter.module.bracketing: bracketing ========== .. index:: single: impstats; bracketing single: bracketing .. summary-start Adds BEGIN and END marker messages so post-processing can group statistics blocks. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: bracketing :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.4.1 Description ----------- .. versionadded:: 8.4.1 This is a utility setting for folks who post-process impstats logs and would like to know the begin and end of a block of statistics. When ``bracketing`` is set to ``on``, impstats issues a ``BEGIN`` message before the first counter is issued, then all counter values are issued, and then an ``END`` message follows. As such, if and only if messages are kept in sequence, a block of stats counts can easily be identified by those BEGIN and END messages. **Note well:** in general, sequence of syslog messages is **not** strict and is not ordered in sequence of message generation. There are various occasions that can cause message reordering, some examples are: * using multiple threads * using UDP forwarding * using relay systems, especially with buffering enabled * using disk-assisted queues This is not a problem with rsyslog, but rather the way a concurrent world works. For strict order, a specific order predicate (e.g. a sufficiently fine-grained timestamp) must be used. As such, BEGIN and END records may actually indicate the begin and end of a block of statistics - or they may *not*. Any order is possible in theory. So the bracketing option does not in all cases work as expected. This is the reason why it is turned off by default. *However*, bracketing may still be useful for many use cases. First and foremost, while there are many scenarios in which messages become reordered, in practice it happens relatively seldom. So most of the time the statistics records will come in as expected and actually will be bracketed by the BEGIN and END messages. Consequently, if an application can handle occasional out-of-order delivery (e.g. by graceful degradation), bracketing may actually be a great solution. It is, however, very important to know and handle out of order delivery. For most real-world deployments, a good way to handle it is to ignore unexpected records and use the previous values for ones missing in the current block. To guard against two or more blocks being mixed, it may also be a good idea to never reset a value to a lower bound, except when that lower bound is seen consistently (which happens due to a restart). Note that such lower bound logic requires :ref:`param-impstats-resetcounters` (``resetCounters`` in camelCase examples) to be set to ``off``. Module usage ------------ .. _impstats.parameter.module.bracketing-usage: .. code-block:: rsyslog module(load="impstats" bracketing="on") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-bulkmode.rst0000644000000000000000000000013215114522477025726 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.468642489 30 ctime=1764935922.127560413 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-bulkmode.rst0000664000175000017500000000250015114522477025367 0ustar00rgerrger.. _param-omclickhouse-bulkmode: .. _omclickhouse.parameter.input.bulkmode: bulkMode ======== .. index:: single: omclickhouse; bulkMode single: bulkMode single: omclickhouse; bulkmode single: bulkmode .. summary-start Determines whether events are sent individually or batched together in bulk HTTP requests. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: bulkMode :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: not specified Description ----------- The "off" setting means logs are shipped one by one, each in its own HTTP request. The default "on" will send multiple logs in the same request. This is recommended, because it is many times faster than when ``bulkMode`` is turned off. The maximum number of logs sent in a single bulk request depends on your ``maxBytes`` and queue settings - usually limited by the `dequeue batch size `_. More information about queues can be found in the `rsyslog documentation on queues `_. Input usage ----------- .. _omclickhouse.parameter.input.bulkmode-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" bulkMode="off") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-keepfailedmessages.rst0000644000000000000000000000013215062756615026676 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.533719561 30 ctime=1764935922.463565557 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-keepfailedmessages.rst0000664000175000017500000000203615062756615026343 0ustar00rgerrger.. _param-omkafka-keepfailedmessages: .. _omkafka.parameter.module.keepfailedmessages: KeepFailedMessages ================== .. index:: single: omkafka; KeepFailedMessages single: KeepFailedMessages .. summary-start Persist failed messages for resending after restart. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: KeepFailedMessages :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If enabled, failed messages will be saved and loaded on shutdown/startup and resent after startup when Kafka is available. This setting requires ``resubmitOnFailure`` to be enabled. Action usage ------------ .. _param-omkafka-action-keepfailedmessages: .. _omkafka.parameter.action.keepfailedmessages: .. code-block:: rsyslog action(type="omkafka" KeepFailedMessages="on") Notes ----- - Originally documented as "binary"; uses boolean values. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-apiversionstr.rst0000644000000000000000000000013115062756615026150 xustar0030 mtime=1758190989.183640865 29 atime=1764928593.63747745 30 ctime=1764935921.325548135 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-apiversionstr.rst0000664000175000017500000000160515062756615025617 0ustar00rgerrger.. _param-imdocker-apiversionstr: .. _imdocker.parameter.module.apiversionstr: ApiVersionStr ============= .. index:: single: imdocker; ApiVersionStr single: ApiVersionStr .. summary-start Docker API version string like ``v1.27``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: ApiVersionStr :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=v1.27 :Required?: no :Introduced: 8.41.0 Description ----------- Specifies the version of Docker API to use. The value must match the format required by the Docker API, such as ``v1.27``. Module usage ------------ .. _param-imdocker-module-apiversionstr: .. _imdocker.parameter.module.apiversionstr-usage: .. code-block:: rsyslog module(load="imdocker" ApiVersionStr="...") See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-keepalive-interval.rst0000644000000000000000000000013015062756615026525 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.511535098 29 ctime=1764935921.59955233 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-keepalive-interval.rst0000664000175000017500000000264715062756615026204 0ustar00rgerrger.. _param-imptcp-keepalive-interval: .. _imptcp.parameter.input.keepalive-interval: KeepAlive.Interval ================== .. index:: single: imptcp; KeepAlive.Interval single: KeepAlive.Interval .. summary-start Sets the interval between keepalive probes. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: KeepAlive.Interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime. The default, 0, means that the operating system defaults are used. This has only effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imptcp-input-keepalive-interval: .. _imptcp.parameter.input.keepalive-interval-usage: .. code-block:: rsyslog input(type="imptcp" keepAlive.interval="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverkeepalive_intvl: - $InputPTCPServerKeepAlive_intvl — maps to KeepAlive.Interval (status: legacy) .. index:: single: imptcp; $InputPTCPServerKeepAlive_intvl single: $InputPTCPServerKeepAlive_intvl See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-defaulttag.rst0000644000000000000000000000013215062756615025564 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.677509458 30 ctime=1764935921.470550354 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-defaulttag.rst0000664000175000017500000000205015062756615025225 0ustar00rgerrger.. _param-imjournal-defaulttag: .. _imjournal.parameter.module.defaulttag: .. meta:: :tag: module:imjournal :tag: parameter:defaultTag defaultTag ========== .. index:: single: imjournal; defaultTag single: defaultTag .. summary-start Provides a default tag when both ``SYSLOG_IDENTIFIER`` and ``_COMM`` are missing. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: defaultTag :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=journal :Required?: no :Introduced: 8.2312.0 Description ----------- Defines the tag value used when neither an identifier string nor process name is available in the journal entry. Module usage ------------ .. _param-imjournal-module-defaulttag: .. _imjournal.parameter.module.defaulttag-usage: .. code-block:: rsyslog module(load="imjournal" defaultTag="...") Notes ----- - Earlier documentation incorrectly described this option as ``binary``. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-unlink.rst0000644000000000000000000000013215062756615024606 xustar0030 mtime=1758190989.197641063 30 atime=1764928597.106584075 30 ctime=1764935921.895556861 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-unlink.rst0000664000175000017500000000177715062756615024266 0ustar00rgerrger.. _param-imuxsock-unlink: .. _imuxsock.parameter.input.unlink: Unlink ====== .. index:: single: imuxsock; Unlink single: Unlink .. summary-start Controls whether the socket is unlinked on open and close. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: Unlink :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 7.3.9 Description ----------- If turned on (default), the socket is unlinked and re-created when opened and also unlinked when finally closed. Set it to off if you handle socket creation yourself. .. note:: Note that handling socket creation oneself has the advantage that a limited amount of messages may be queued by the OS if rsyslog is not running. .. versionadded:: 7.3.9 Input usage ----------- .. _param-imuxsock-input-unlink: .. _imuxsock.parameter.input.unlink-usage: .. code-block:: rsyslog input(type="imuxsock" unlink="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-socketbacklog.rst0000644000000000000000000000013215062756615025373 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.309559612 30 ctime=1764935921.757554749 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-socketbacklog.rst0000664000175000017500000000355015062756615025042 0ustar00rgerrger.. _param-imtcp-socketbacklog: .. _imtcp.parameter.input.socketbacklog: SocketBacklog ============= .. index:: single: imtcp; SocketBacklog single: SocketBacklog .. summary-start Sets the backlog length for pending TCP connections. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: SocketBacklog :Scope: input :Type: integer :Default: input=10% of configured connections :Required?: no :Introduced: 8.2502.0 Description ----------- Specifies the backlog parameter passed to the ``listen()`` system call. This parameter defines the maximum length of the queue for pending connections, which includes partially established connections (those in the SYN-ACK handshake phase) and fully established connections waiting to be accepted by the application. **Available starting with the 8.2502.0 series.** For more details, refer to the ``listen(2)`` man page. By default, the value is set to 10% of the configured connections to accommodate modern workloads. It can be adjusted to suit specific requirements, such as: - **High rates of concurrent connection attempts**: Increasing this value helps handle bursts of incoming connections without dropping them. - **Test environments with connection flooding**: Larger values are recommended to prevent SYN queue overflow. - **Servers with low traffic**: Lower values may be used to reduce memory usage. The effective backlog size is influenced by system-wide kernel settings, particularly ``net.core.somaxconn`` and ``net.ipv4.tcp_max_syn_backlog``. The smaller value between this parameter and the kernel limits is used as the actual backlog. Input usage ----------- .. _param-imtcp-input-socketbacklog: .. _imtcp.parameter.input.socketbacklog-usage: .. code-block:: rsyslog input(type="imtcp" socketBacklog="128") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmexternal-forcesingleinstance.rst0000644000000000000000000000013115071746523027641 xustar0030 mtime=1760021843.808420513 29 atime=1764928597.85060689 30 ctime=1764935921.980558163 rsyslog-8.2512.0/doc/source/reference/parameters/mmexternal-forcesingleinstance.rst0000664000175000017500000000344415071746523027313 0ustar00rgerrger.. _param-mmexternal-forcesingleinstance: .. _mmexternal.parameter.input.forcesingleinstance: forceSingleInstance =================== .. index:: single: mmexternal; forceSingleInstance single: forceSingleInstance .. summary-start Enforces that only a single instance of the external message modification plugin runs. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmexternal`. :Name: forceSingleInstance :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: 8.3.0 Description ----------- This is an expert parameter. By default, ``mmexternal`` starts an instance of the external program for each worker thread in the action's queue (the maximum number of worker threads can be specified with the :doc:`queue.workerThreads <../../rainerscript/queue_parameters>` parameter). Moreover, if the action is associated with a :doc:`disk-assisted queue <../../concepts/queues>`, an additional instance may be started to process items from disk. If you want to ensure that only a single instance of the program is ever running, regardless of the number of worker threads or queue type, set this parameter to ``"on"``. This is useful if the external program accesses a shared resource that does not support concurrent access. This parameter is equivalent to the :ref:`param-omprog-forcesingleinstance` parameter. Input usage ----------- .. _param-mmexternal-input-forcesingleinstance: .. _mmexternal.parameter.input.forcesingleinstance-usage: .. code-block:: rsyslog module(load="mmexternal") action( type="mmexternal" binary="/path/to/mmexternal.py" forceSingleInstance="on" ) Notes ----- - The type was previously documented as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/mmexternal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-hup-signal.rst0000644000000000000000000000013215062756615025016 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.127737694 30 ctime=1764935922.541566752 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-hup-signal.rst0000664000175000017500000000170015062756615024460 0ustar00rgerrger.. _param-omprog-hup-signal: .. _omprog.parameter.action.hup-signal: hup.signal ========== .. index:: single: omprog; hup.signal single: hup.signal .. summary-start Forwards a chosen signal to the program when rsyslog receives HUP. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: hup.signal :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: 8.9.0 Description ----------- Specifies which signal, if any, is to be forwarded to the external program when rsyslog receives a HUP signal. Currently, HUP, USR1, USR2, INT, and TERM are supported. If unset, no signal is sent on HUP. This is the default and what pre 8.9.0 versions did. Action usage ------------ .. _param-omprog-action-hup-signal: .. _omprog.parameter.action.hup-signal-usage: .. code-block:: rsyslog action(type="omprog" hup.signal="HUP") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-log-file.rst0000644000000000000000000000013215114522477025001 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.460642292 30 ctime=1764935921.555551656 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-log-file.rst0000664000175000017500000000262215114522477024447 0ustar00rgerrger.. _param-impstats-log-file: .. _impstats.parameter.module.log-file: log.file ======== .. index:: single: impstats; log.file single: log.file .. summary-start Writes impstats statistics records to the specified local file in addition to other outputs. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: log.file :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If specified, statistics data is written to the specified file. For robustness, this should be a local file. The file format cannot be customized; it consists of a date header, followed by a colon, followed by the actual statistics record, all on one line. Only very limited error handling is done, so if things go wrong stats records will probably be lost. Logging to file can be a useful alternative if for some reasons (e.g. full queues) the regular syslog stream method shall not be used solely. Note that turning on file logging does NOT turn off syslog logging. If that is desired, :ref:`param-impstats-log-syslog` (``logSyslog`` in camelCase examples) must be explicitly set to ``off``. Module usage ------------ .. _impstats.parameter.module.log-file-usage: .. code-block:: rsyslog module(load="impstats" logFile="/var/log/rsyslog-stats") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-azure_key.rst0000644000000000000000000000013115114522477027042 xustar0030 mtime=1764926783.029631711 29 atime=1764926783.46664244 30 ctime=1764935922.107560107 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-azure_key.rst0000664000175000017500000000172215114522477026511 0ustar00rgerrger.. _param-omazureeventhubs-azure_key: .. _omazureeventhubs.parameter.input.azure_key: azure_key ========= .. index:: single: omazureeventhubs; azure_key single: azure_key .. summary-start Provides the shared access key value used to sign Event Hubs requests. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: azure_key :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- Specifies the value of the "Event Hubs shared access key". This secret key string authenticates the connection and signs requests to the Event Hubs instance. Supply it unless ``amqpAddress`` already embeds the key. Input usage ----------- .. _omazureeventhubs.parameter.input.azure_key-usage: .. code-block:: rsyslog action(type="omazureeventhubs" azureKeyName="MyPolicy" azureKey="MySecretKey" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-serverrun.rst0000644000000000000000000000013215114522477024724 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.452642096 30 ctime=1764935921.315547982 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-serverrun.rst0000664000175000017500000000414615114522477024375 0ustar00rgerrger.. _param-imdiag-serverrun: .. _imdiag.parameter.input.serverrun: ServerRun ========= .. index:: single: imdiag; ServerRun single: ServerRun .. summary-start Creates the imdiag TCP listener on the specified port (``0`` selects an ephemeral port). .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ServerRun :Scope: input :Type: integer (port) :Default: input=none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- Starts the diagnostic control listener. The value is the TCP port number to bind. Specify ``0`` to request an ephemeral port from the operating system. The chosen port is recorded in the file specified by the mandatory :ref:`ListenPortFileName ` parameter. imdiag always uses the plain TCP (``ptcp``) :doc:`network stream driver <../../concepts/netstrm_drvr>`. As a result, parameters that normally tune stream driver authentication or permitted peers are accepted for compatibility but have no effect in current releases. This includes: * :ref:`param-imdiag-serverstreamdrivermode` * :ref:`param-imdiag-serverstreamdriverauthmode` * :ref:`param-imdiag-serverstreamdriverpermittedpeer` imdiag supports only a single listener. Attempting to configure ``ServerRun`` more than once logs an error and the additional configuration is ignored. Set module-level parameters such as :ref:`MaxSessions ` before invoking ``ServerRun``. Input usage ----------- .. _param-imdiag-input-serverrun: .. _imdiag.parameter.input.serverrun-usage: .. code-block:: rsyslog module(load="imdiag" maxSessions="20") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverRun="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagserverrun: - $IMDiagServerRun — maps to ServerRun (status: legacy) .. index:: single: imdiag; $IMDiagServerRun single: $IMDiagServerRun See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-tlslib.rst0000644000000000000000000000013215114522477025020 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.465642415 30 ctime=1764935921.696553815 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-tlslib.rst0000664000175000017500000000263015114522477024465 0ustar00rgerrger.. _param-imrelp-tls-tlslib: .. _imrelp.parameter.module.tls-tlslib: tls.tlsLib ========== .. index:: single: imrelp; tls.tlsLib single: tls.tlsLib .. summary-start Selects the TLS backend library that librelp should use for RELP operations. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.tlsLib :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: 8.1903.0 Description ----------- Permits to specify the TLS library used by librelp. All RELP protocol operations are actually performed by librelp and not rsyslog itself. The value specified is directly passed down to librelp. Depending on librelp version and build parameters, supported TLS libraries differ (or TLS may not be supported at all). In this case rsyslog emits an error message. Usually, the following options should be available: "openssl", "gnutls". Note that "gnutls" is the current default for historic reasons. We actually recommend to use "openssl". It provides better error messages and accepts a wider range of certificate types. If you have problems with the default setting, we recommend to switch to "openssl". Module usage ------------ .. _param-imrelp-module-tls-tlslib-usage: .. _imrelp.parameter.module.tls-tlslib-usage: .. code-block:: rsyslog module(load="imrelp" tls.tlsLib="openssl") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-busyretryinterval.rst0000644000000000000000000000013015071746523027755 xustar0029 mtime=1760021843.81142056 29 atime=1764928598.14361587 30 ctime=1764935922.022558806 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-busyretryinterval.rst0000664000175000017500000000262615071746523027431 0ustar00rgerrger.. _param-mmkubernetes-busyretryinterval: .. _mmkubernetes.parameter.action.busyretryinterval: busyretryinterval ================= .. index:: single: mmkubernetes; busyretryinterval single: busyretryinterval .. summary-start Sets the delay before retrying after a ``429 Busy`` response. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: busyretryinterval :Scope: action :Type: integer :Default: 5 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- The number of seconds to wait before retrying operations to the Kubernetes API server after receiving a `429 Busy` response. The default `"5"` means that the module will retry the connection every `5` seconds. Records processed during this time will _not_ have any additional metadata associated with them, so you will need to handle cases where some of your records have all of the metadata and some do not. If you want to have rsyslog suspend the plugin until the Kubernetes API server is available, set `busyretryinterval` to `"0"`. This will cause the plugin to return an error to rsyslog. Action usage ------------ .. _param-mmkubernetes-action-busyretryinterval: .. _mmkubernetes.parameter.action.busyretryinterval-usage: .. code-block:: rsyslog action(type="mmkubernetes" busyRetryInterval="5") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-azure_key_name.rst0000644000000000000000000000013115114522477030042 xustar0030 mtime=1764926783.029631711 29 atime=1764926783.46664244 30 ctime=1764935922.109560138 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-azure_key_name.rst0000664000175000017500000000177115114522477027515 0ustar00rgerrger.. _param-omazureeventhubs-azure_key_name: .. _omazureeventhubs.parameter.input.azure_key_name: azure_key_name ============== .. index:: single: omazureeventhubs; azure_key_name single: azure_key_name .. summary-start Specifies the shared access key name used to authenticate with Event Hubs. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: azure_key_name :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- Specifies the "Event Hubs shared access key name" (the shared access policy name) used to authenticate and authorize connections to the Event Hubs instance. Provide this value unless ``amqpAddress`` already supplies the credentials. Input usage ----------- .. _omazureeventhubs.parameter.input.azure_key_name-usage: .. code-block:: rsyslog action(type="omazureeventhubs" azureKeyName="MyPolicy" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omuxsock-abstract.rst0000644000000000000000000000013215114522477025112 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.487642955 30 ctime=1764935922.595567578 rsyslog-8.2512.0/doc/source/reference/parameters/omuxsock-abstract.rst0000664000175000017500000000354315114522477024563 0ustar00rgerrger.. _param-omuxsock-abstract: .. _omuxsock.parameter.module.abstract: abstract ========== .. index:: single: omuxsock; abstract single: abstract .. summary-start This indicates whether the socketName should be used as an abstract socket address or not. .. summary-end This parameter applies to :doc:`../../configuration/modules/omuxsock`. :Name: abstract :Scope: module, action :Type: boolean :Default: module="0", action="0" :Required?: no :Introduced: v8.2512 Description ----------- This indicates whether the socket name is abstract or not. Abstract socket names are generally only supported under Linux, and differ from non-abstract socket names by not requiring a name in the filesystem. The default is False (0). Module usage ------------ .. _param-omuxsock-action-abstract: .. _omuxsock.parameter.action.abstract-usage: If abstract is set at the module level, then it becomes the default abstract setting for the first unnamed action. It only applies to a single unnamed action, so it is primarily just a short-hand notation for when only a single omuxsock action is required. .. code-block:: rsyslog module(load="omuxsock" socketName="/tmp/socksample" abstract="0") Action usage ------------ .. code-block:: rsyslog action(type="omuxsock" socketName="/tmp/example" abstract="0") action(type="omuxsock" socketName="rsyslogd.msg.handler" abstract="1") .. note:: :ref:`param-omuxsock-socketname`, :ref:`param-omuxsock-abstract`, and :ref:`param-omuxsock-sockettype` constitute a logical configuration tuple. They are applied together as a whole tuple from a module level configuration to an action. Therefore, all three parameters must be explicitly specified in the action, or none may be specified in the action. In the latter case, the default is taken from the module. See also -------- See also :doc:`../../configuration/modules/omuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-internalmsgfacility.rst0000644000000000000000000000013215114522477026771 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.456642194 30 ctime=1764935921.518551089 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-internalmsgfacility.rst0000664000175000017500000000314415114522477026437 0ustar00rgerrger.. _param-imklog-internalmsgfacility: .. _imklog.parameter.module.internalmsgfacility: InternalMsgFacility =================== .. index:: single: imklog; InternalMsgFacility single: InternalMsgFacility .. summary-start Sets the facility used for messages that imklog generates internally. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: InternalMsgFacility :Scope: module :Type: facility :Default: Linux: "kern"; other platforms: "syslogd" :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This parameter sets the facility for messages that are generated internally by imklog. imklog generates some messages of itself (e.g. on problems, startup and shutdown) and these do not stem from the kernel. Historically, under Linux, these too have "kern" facility. Thus, on Linux platforms the default is "kern" while on others it is "syslogd". It is recommended to not change this setting unless you have a specific reason to do so. Module usage ------------ .. _param-imklog-module-internalmsgfacility: .. _imklog.parameter.module.internalmsgfacility-usage: .. code-block:: rsyslog module(load="imklog" internalMsgFacility="kern") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.kloginternalmsgfacility: - $KLogInternalMsgFacility — maps to InternalMsgFacility (status: legacy) .. index:: single: imklog; $KLogInternalMsgFacility single: $KLogInternalMsgFacility See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-rotation-sizelimitcommand.rst0000644000000000000000000000013215062756615030124 xustar0030 mtime=1758190989.208641219 30 atime=1764928600.215679293 30 ctime=1764935922.321563383 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-rotation-sizelimitcommand.rst0000664000175000017500000000262315062756615027573 0ustar00rgerrger.. _param-omfile-rotation-sizelimitcommand: .. _omfile.parameter.module.rotation-sizelimitcommand: rotation.sizeLimitCommand ========================= .. index:: single: omfile; rotation.sizeLimitCommand single: rotation.sizeLimitCommand .. summary-start Configures the script invoked when `rotation.sizeLimit` is exceeded. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: rotation.sizeLimitCommand :Scope: action :Type: string :Default: action=(empty) :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This sets the command executed when a file hits the configured size limit. Use together with :ref:`param-omfile-rotation-sizelimit`. Action usage ------------ .. _param-omfile-action-rotation-sizelimitcommand: .. _omfile.parameter.action.rotation-sizelimitcommand: .. code-block:: rsyslog action(type="omfile" rotation.sizeLimitCommand="...") Notes ----- - Legacy documentation referred to the type as ``binary``; the value is a command string. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.outchannel: - $outchannel — maps to rotation.sizeLimitCommand (status: legacy) .. index:: single: omfile; $outchannel single: $outchannel See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-containerrulebase.rst0000644000000000000000000000013115071746523027646 xustar0029 mtime=1760021843.81142056 30 atime=1764928598.171616727 30 ctime=1764935922.029558913 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-containerrulebase.rst0000664000175000017500000000212515071746523027313 0ustar00rgerrger.. _param-mmkubernetes-containerrulebase: .. _mmkubernetes.parameter.action.containerrulebase: containerrulebase ================= .. index:: single: mmkubernetes; containerrulebase single: containerrulebase .. summary-start Specifies the rulebase file used to parse ``CONTAINER_NAME`` values. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: containerrulebase :Scope: action :Type: word :Default: /etc/rsyslog.d/k8s_container_name.rulebase :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When processing journald logs, this is the rulebase used to match the CONTAINER_NAME property value and extract metadata. For the actual rules, see :ref:`param-mmkubernetes-containerrules`. Action usage ------------ .. _param-mmkubernetes-action-containerrulebase: .. _mmkubernetes.parameter.action.containerrulebase-usage: .. code-block:: rsyslog action(type="mmkubernetes" containerRuleBase="/etc/rsyslog.d/k8s_container_name.rulebase") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-supportoctetcountedframing.rst0000644000000000000000000000013215062756615030441 xustar0030 mtime=1758190989.191640978 30 atime=1764928595.468533777 30 ctime=1764935921.641552972 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-supportoctetcountedframing.rst0000664000175000017500000000310415062756615030103 0ustar00rgerrger.. _param-imptcp-supportoctetcountedframing: .. _imptcp.parameter.input.supportoctetcountedframing: SupportOctetCountedFraming ========================== .. index:: single: imptcp; SupportOctetCountedFraming single: SupportOctetCountedFraming .. summary-start Enables legacy octet-counted framing similar to RFC5425. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: SupportOctetCountedFraming :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The legacy octet-counted framing (similar to RFC5425 framing) is activated. This is the default and should be left unchanged until you know very well what you do. It may be useful to turn it off, if you know this framing is not used and some senders emit multi-line messages into the message stream. Input usage ----------- .. _param-imptcp-input-supportoctetcountedframing: .. _imptcp.parameter.input.supportoctetcountedframing-usage: .. code-block:: rsyslog input(type="imptcp" supportOctetCountedFraming="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserversupportoctetcountedframing: - $InputPTCPServerSupportOctetCountedFraming — maps to SupportOctetCountedFraming (status: legacy) .. index:: single: imptcp; $InputPTCPServerSupportOctetCountedFraming single: $InputPTCPServerSupportOctetCountedFraming See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-workerthreads.rst0000644000000000000000000000013215062756615025444 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.151554761 30 ctime=1764935921.790555254 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-workerthreads.rst0000664000175000017500000000424415062756615025114 0ustar00rgerrger.. _param-imtcp-workerthreads: .. _imtcp.parameter.module.workerthreads: WorkerThreads ============= .. index:: single: imtcp; WorkerThreads single: WorkerThreads .. summary-start Sets the default number of worker threads for listeners on epoll-enabled systems. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: WorkerThreads :Scope: module :Type: integer :Default: module=2 :Required?: no :Introduced: 8.2504.0 Description ----------- The ``WorkerThreads`` parameter defines the **default number of worker threads** for all ``imtcp`` listeners. This setting applies only on **epoll-enabled systems**. If ``epoll`` is unavailable, ``imtcp`` will always run in **single-threaded mode**, regardless of this setting. **Default value:** ``2`` **Allowed values:** ``1`` (single-threaded) to any reasonable number (should not exceed CPU cores). **Behavior and Recommendations** - If set to ``1``, ``imtcp`` operates in **single-threaded mode**, using the main event loop for processing. - If set to ``2`` or more, a **worker pool** is created, allowing multiple connections to be processed in parallel. - Setting this too high **can degrade performance** due to excessive thread switching. - A reasonable upper limit is **the number of available CPU cores**. **Scope and Overrides** - This is a **module-level parameter**, meaning it **sets the default** for all ``imtcp`` listeners. - Each listener instance can override this by setting the ``workerthreads`` **listener parameter**. **Example Configuration** The following sets a default of **4** worker threads for all listeners, while overriding it to **8** for a specific listener: .. code-block:: none module(load="imtcp" WorkerThreads="4") # Default for all listeners input(type="imtcp" port="514" workerthreads="8") # Overrides default, using 8 workers If ``WorkerThreads`` is not explicitly set, the default of ``2`` will be used. Module usage ------------ .. _param-imtcp-module-workerthreads: .. _imtcp.parameter.module.workerthreads-usage: .. code-block:: rsyslog module(load="imtcp" workerThreads="4") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv6-bits.rst0000644000000000000000000000013115071746523024550 xustar0030 mtime=1760021843.804420449 30 atime=1764928597.353591649 29 ctime=1764935921.93855752 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv6-bits.rst0000664000175000017500000000217715071746523024224 0ustar00rgerrger.. _param-mmanon-ipv6-bits: .. _mmanon.parameter.input.ipv6-bits: ipv6.bits ========= .. index:: single: mmanon; ipv6.bits single: ipv6.bits .. summary-start Sets how many low-order bits of IPv6 addresses are anonymized. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv6.bits :Scope: input :Type: positive integer :Default: input=96 :Required?: no :Introduced: 7.3.7 Description ----------- This sets the number of bits that should be anonymized (bits are from the right, so lower bits are anonymized first). This setting permits to save network information while still anonymizing user-specific data. The more bits you discard, the better the anonymization obviously is. The default of 96 bits reflects what German data privacy rules consider as being sufficiently anonymized. We assume, this can also be used as a rough but conservative guideline for other countries. Input usage ----------- .. _mmanon.parameter.input.ipv6-bits-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv6.bits="64") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-mode.rst0000644000000000000000000000013215062756615026211 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.167555253 30 ctime=1764935921.776555039 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-mode.rst0000664000175000017500000000315415062756615025660 0ustar00rgerrger.. _param-imtcp-streamdriver-mode: .. _imtcp.parameter.module.streamdriver-mode: .. _imtcp.parameter.input.streamdriver-mode: StreamDriver.Mode ================= .. index:: single: imtcp; StreamDriver.Mode single: StreamDriver.Mode .. summary-start Sets the driver mode for the selected network stream driver. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.Mode :Scope: module, input :Type: integer :Default: module=0, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the driver mode for the currently selected :doc:`network stream driver <../../concepts/netstrm_drvr>`. is driver specific. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-mode: .. _imtcp.parameter.module.streamdriver-mode-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.mode="...") Input usage ----------- .. _param-imtcp-input-streamdriver-mode: .. _imtcp.parameter.input.streamdriver-mode-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.mode="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverstreamdrivermode: - $InputTCPServerStreamDriverMode — maps to StreamDriver.Mode (status: legacy) .. index:: single: imtcp; $InputTCPServerStreamDriverMode single: $InputTCPServerStreamDriverMode See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-tls-mycert.rst0000644000000000000000000000013115114522477025043 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.472642587 30 ctime=1764935922.168561041 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-tls-mycert.rst0000664000175000017500000000155015114522477024511 0ustar00rgerrger.. _param-omdtls-tls-mycert: .. _omdtls.parameter.input.tls-mycert: tls.mycert ========== .. index:: single: omdtls; tls.mycert single: tls.mycert .. summary-start Specifies the certificate file presented by omdtls during the DTLS handshake. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: tls.mycert :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- Specifies the certificate file used by omdtls. This certificate is presented to peers during the DTLS handshake. Input usage ----------- .. _omdtls.parameter.input.tls-mycert-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" tls.myCert="/etc/rsyslog/omdtls.crt") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-pwd.rst0000644000000000000000000000013015114522477025375 xustar0029 mtime=1764926783.03163176 30 atime=1764926784.234661289 29 ctime=1764935922.21356173 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-pwd.rst0000664000175000017500000000151415114522477025044 0ustar00rgerrger.. _param-omelasticsearch-pwd: .. _omelasticsearch.parameter.module.pwd: pwd === .. index:: single: omelasticsearch; pwd single: pwd .. summary-start Password for basic HTTP authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: pwd :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Supplies the password when Elasticsearch requires basic authentication. This parameter cannot be combined with :ref:`param-omelasticsearch-apikey`. Action usage ------------ .. _param-omelasticsearch-action-pwd: .. _omelasticsearch.parameter.action.pwd: .. code-block:: rsyslog action(type="omelasticsearch" pwd="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmpstrucdata-sd_name.lowercase.rst0000644000000000000000000000013215071746523027536 xustar0030 mtime=1760021843.821420718 30 atime=1764928598.464625703 30 ctime=1764935922.081559709 rsyslog-8.2512.0/doc/source/reference/parameters/mmpstrucdata-sd_name.lowercase.rst0000664000175000017500000000211215071746523027176 0ustar00rgerrger.. _param-mmpstrucdata-sd_name.lowercase: .. _mmpstrucdata.parameter.action.sd_name.lowercase: sd_name.lowercase ================= .. index:: single: mmpstrucdata; sd_name.lowercase single: sd_name.lowercase .. summary-start Controls whether structured data element names (SDIDs) are lowercased. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmpstrucdata`. :Name: sd_name.lowercase :Scope: action :Type: boolean :Default: action="on" :Required?: no :Introduced: 8.32.0 Description ----------- Specifies if sd names (SDID) shall be lowercased. If set to "on", this is the case; if "off", then not. The default of "on" is used because that was the traditional mode of operations. It is generally advised to change the parameter to "off" if not otherwise required. Action usage ------------ .. _param-mmpstrucdata-action-sd_name.lowercase: .. _mmpstrucdata.parameter.action.sd_name.lowercase-usage: .. code-block:: rsyslog action(type="mmpstrucdata" sd_name.lowercase="off") See also -------- See also :doc:`../../configuration/modules/mmpstrucdata`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsendertrack-statefile.rst0000644000000000000000000000013215114522477026260 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.487642955 30 ctime=1764935922.565567119 rsyslog-8.2512.0/doc/source/reference/parameters/omsendertrack-statefile.rst0000664000175000017500000000247715114522477025736 0ustar00rgerrger.. _param-omsendertrack-statefile: .. _omsendertrack.parameter.input.statefile: statefile ========= .. index:: single: omsendertrack; statefile single: statefile .. summary-start Specifies the absolute path to the JSON file where omsendertrack persists sender statistics. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsendertrack`. :Name: statefile :Scope: input :Type: string :Default: input=none :Required?: yes :Introduced: 8.2506.0 (Proof-of-Concept) Description ----------- This mandatory parameter specifies the **absolute path to the JSON file** where sender information is stored. The module updates this file periodically based on the configured :ref:`interval ` and also upon rsyslog shutdown to preserve the latest statistics. **Important:** Ensure that the rsyslog user has appropriate write permissions to the directory where this ``statefile`` is located. Failure to do so will prevent the module from saving its state. Input usage ----------- .. _omsendertrack.parameter.input.statefile-usage: .. code-block:: rsyslog module(load="omsendertrack") action(type="omsendertrack" senderId="%hostname%" stateFile="/var/lib/rsyslog/senderstats.json") See also -------- See also :doc:`../../configuration/modules/omsendertrack`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-maxlisteners.rst0000644000000000000000000000013215062756615025276 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.128554055 30 ctime=1764935921.730554335 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-maxlisteners.rst0000664000175000017500000000274615062756615024753 0ustar00rgerrger.. _param-imtcp-maxlisteners: .. _imtcp.parameter.module.maxlisteners: .. _imtcp.parameter.input.maxlisteners: MaxListeners ============ .. index:: single: imtcp; MaxListeners single: MaxListeners .. summary-start Sets the maximum number of listener ports supported. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: MaxListeners :Scope: module, input :Type: integer :Default: module=20, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the maximum number of listeners (server ports) supported. This must be set before the first $InputTCPServerRun directive. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-maxlisteners: .. _imtcp.parameter.module.maxlisteners-usage: .. code-block:: rsyslog module(load="imtcp" maxListeners="50") Input usage ----------- .. _param-imtcp-input-maxlisteners: .. _imtcp.parameter.input.maxlisteners-usage: .. code-block:: rsyslog input(type="imtcp" port="514" maxListeners="50") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpmaxlisteners: - $InputTCPMaxListeners — maps to MaxListeners (status: legacy) .. index:: single: imtcp; $InputTCPMaxListeners single: $InputTCPMaxListeners See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-needparse.rst0000644000000000000000000000013215062756615024657 xustar0030 mtime=1758190989.185640893 30 atime=1764928594.119492291 30 ctime=1764935921.415549513 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-needparse.rst0000664000175000017500000000204515062756615024324 0ustar00rgerrger.. _param-imfile-needparse: .. _imfile.parameter.input.needparse: .. _imfile.parameter.needparse: needParse ========= .. index:: single: imfile; needParse single: needParse .. summary-start Forces messages to pass through configured parser modules. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: needParse :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: 8.1903.0 Description ----------- By default, read messages are sent to output modules without passing through parsers. Setting ``needParse`` to ``on`` makes rsyslog apply any defined parser modules to these messages. Input usage ----------- .. _param-imfile-input-needparse: .. _imfile.parameter.input.needparse-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" needParse="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsontransform-input.rst0000644000000000000000000000013115103346332026024 xustar0029 mtime=1762512090.62717594 30 atime=1764928598.072613695 30 ctime=1764935922.010558622 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsontransform-input.rst0000664000175000017500000000244515103346332025476 0ustar00rgerrger.. _param-mmjsontransform-input: .. _mmjsontransform.parameter.input.input: input ===== .. index:: single: mmjsontransform; input single: input .. summary-start Names the JSON property that provides the object to transform. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsontransform`. :Name: input :Scope: input :Type: string :Default: none :Required?: yes :Introduced: 8.2410.0 Description ----------- Specifies which message property contains the JSON object that will be rewritten. The value must be a property reference that begins with ``$`` (for example ``$!raw`` or ``$.normalized``). ``mmjsontransform`` validates the expression during configuration and rejects other prefixes. If the referenced property is missing at runtime, the action simply returns without altering the message. When the property exists but is not a JSON object, the module reports an error and the action fails, leaving the output property untouched. Input usage ----------- .. _param-mmjsontransform-input-usage: .. _mmjsontransform.parameter.input.input-usage: .. code-block:: rsyslog action(type="mmjsontransform" input="$!raw" output="$!normalized") See also -------- See also the :doc:`main mmjsontransform module documentation <../../configuration/modules/mmjsontransform>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-confparam.rst0000644000000000000000000000013115114522477025007 xustar0030 mtime=1764926783.027631661 29 atime=1764926783.45564217 30 ctime=1764935921.504550875 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-confparam.rst0000664000175000017500000000241215114522477024453 0ustar00rgerrger.. _param-imkafka-confparam: .. _imkafka.parameter.input.confparam: confparam ========= .. index:: single: imkafka; confparam single: confparam .. summary-start Passes arbitrary librdkafka configuration parameters to the imkafka consumer. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: confparam :Scope: input :Type: array :Default: input=``none`` :Required?: no :Introduced: 8.27.0 Description ----------- Permits to specify Kafka options. Rather than offering a myriad of config settings to match the Kafka parameters, we provide this setting here as a vehicle to set any Kafka parameter. This has the big advantage that Kafka parameters that come up in new releases can immediately be used. Note that we use librdkafka for the Kafka connection, so the parameters are actually those that librdkafka supports. As of our understanding, this is a superset of the native Kafka parameters. Input usage ----------- .. _imkafka.parameter.input.confparam-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="your-topic" confParam=["queued.min.messages=10000", "socket.timeout.ms=60000"]) See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omuxsock-template.rst0000644000000000000000000000013115114522477025121 xustar0030 mtime=1764926783.034631833 29 atime=1764926783.48864298 30 ctime=1764935922.604567716 rsyslog-8.2512.0/doc/source/reference/parameters/omuxsock-template.rst0000664000175000017500000000155315114522477024572 0ustar00rgerrger.. _param-omuxsock-template: .. _omuxsock.parameter.action.template: template ======== .. index:: single: omuxsock; template single: template .. summary-start Sets the template for formatting messages sent to the program. .. summary-end This parameter applies to :doc:`../../configuration/modules/omuxsock`. :Name: template :Scope: action :Type: word :Default: action=RSYSLOG_FileFormat :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Name of the :doc:`template <../../configuration/templates>` to use to format the log messages passed to the external program. Action usage ------------ .. _param-omuxsock-action-template: .. _omuxsock.parameter.action.template-usage: .. code-block:: rsyslog action(type="omuxsock" template="RSYSLOG_FileFormat") See also -------- See also :doc:`../../configuration/modules/omuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-tls-myprivkey.rst0000644000000000000000000000013115071746523027000 xustar0029 mtime=1760021843.81842067 30 atime=1764928598.276619944 30 ctime=1764935922.058559357 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-tls-myprivkey.rst0000664000175000017500000000221315071746523026443 0ustar00rgerrger.. _param-mmkubernetes-tls-myprivkey: .. _mmkubernetes.parameter.action.tls-myprivkey: tls.myprivkey ============= .. index:: single: mmkubernetes; tls.myprivkey single: tls.myprivkey .. summary-start Specifies the unencrypted private key corresponding to ``tls.mycert``. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: tls.myprivkey :Scope: action :Type: word :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This is the full path and file name of the file containing the private key corresponding to the cert :ref:`param-mmkubernetes-tls-mycert` used for doing client cert auth against Kubernetes. This file is in PEM format, and must be unencrypted, so take care to secure it properly. For example: `/etc/rsyslog.d/k8s-client-key.pem` Action usage ------------ .. _param-mmkubernetes-action-tls-myprivkey: .. _mmkubernetes.parameter.action.tls-myprivkey-usage: .. code-block:: rsyslog action(type="mmkubernetes" tls.myPrivKey="/etc/rsyslog.d/k8s-client-key.pem") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-batch-format.rst0000644000000000000000000000013115114522477025320 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.475642661 30 ctime=1764935922.354563888 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-batch-format.rst0000664000175000017500000000600015114522477024761 0ustar00rgerrger.. _param-omhttp-batch-format: .. _omhttp.parameter.input.batch-format: batch.format ============ .. index:: single: omhttp; batch.format single: batch.format .. summary-start Chooses how omhttp combines multiple messages when batching is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: batch.format :Scope: input :Type: word :Default: input=newline :Required?: no :Introduced: Not specified Description ----------- This parameter specifies how to combine multiple messages into a single batch. Valid options are *newline* (default), *jsonarray*, *kafkarest*, and *lokirest*. Each message on the "Inputs" line is the templated log line that is fed into the omhttp action, and the "Output" line describes the resulting payload sent to the configured HTTP server. 1. *newline* - Concatenates each message into a single string joined by newline (``"\\n"``) characters. This mode is default and places no restrictions on the structure of the input messages. .. code-block:: text Inputs: "message 1" "message 2" "message 3" Output: "message 1\nmessage 2\nmessage 3" 2. *jsonarray* - Builds a JSON array containing all messages in the batch. This mode requires that each message is parsable JSON, since the plugin parses each message as JSON while building the array. .. code-block:: text Inputs: {"msg": "message 1"} {"msg": "message 2"} {"msg": "message 3"} Output: [{"msg": "message 1"}, {"msg": "message 2"}, {"msg": "message 3"}] 3. *kafkarest* - Builds a JSON object that conforms to the `Kafka Rest Proxy specification `_. This mode requires that each message is parsable JSON, since the plugin parses each message as JSON while building the batch object. .. code-block:: text Inputs: {"msg": "message 1"} {"msg": "message 2"} {"msg": "message 3"} Output: {"records": [{"value": {"msg": "message 1"}}, {"value": {"msg": "message 2"}}, {"value": {"msg": "message 3"}}]} 4. *lokirest* - Builds a JSON object that conforms to the `Loki Rest specification `_. This mode requires that each message is parsable JSON, since the plugin parses each message as JSON while building the batch object. Additionally, the operator is responsible for providing index keys, and message values. .. code-block:: text Inputs: {"stream": {"tag1":"value1"}, values:[[ "%timestamp%", "message 1" ]]} {"stream": {"tag2":"value2"}, values:[[ "%timestamp%", "message 2" ]]} Output: {"streams": [{"stream": {"tag1":"value1"}, values:[[ "%timestamp%", "message 1" ]]},{"stream": {"tag2":"value2"}, values:[[ "%timestamp%", "message 2" ]]}]} Input usage ----------- .. _omhttp.parameter.input.batch-format-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" batch="on" batchFormat="jsonarray" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-key.rst0000644000000000000000000000013215062756615023645 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.406715684 30 ctime=1764935922.465565588 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-key.rst0000664000175000017500000000143715062756615023316 0ustar00rgerrger.. _param-omkafka-key: .. _omkafka.parameter.module.key: Key === .. index:: single: omkafka; Key single: Key .. summary-start Key used for partitioning messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Key :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Kafka key to be used for all messages. If a key is provided and ``partitions.auto="on"`` is set, then all messages will be assigned to a partition based on the key. Action usage ------------ .. _param-omkafka-action-key: .. _omkafka.parameter.action.key: .. code-block:: rsyslog action(type="omkafka" Key="mykey") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-annotation-match.rst0000644000000000000000000000013215071746523027406 xustar0030 mtime=1760021843.810420544 30 atime=1764928598.126615349 30 ctime=1764935922.020558775 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-annotation-match.rst0000664000175000017500000000231015071746523027046 0ustar00rgerrger.. _param-mmkubernetes-annotation-match: .. _mmkubernetes.parameter.action.annotation-match: annotation_match ================ .. index:: single: mmkubernetes; annotation_match single: annotation_match .. summary-start Selects pod or namespace annotations whose keys match given patterns. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: annotation_match :Scope: action :Type: array :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- By default no pod or namespace annotations will be added to the messages. This parameter is an array of patterns to match the keys of the `annotations` field in the pod and namespace metadata to include in the `$!kubernetes!annotations` (for pod annotations) or the `$!kubernetes!namespace_annotations` (for namespace annotations) message properties. Example: `["k8s.*master","k8s.*node"]` Action usage ------------ .. _param-mmkubernetes-action-annotation-match: .. _mmkubernetes.parameter.action.annotation-match-usage: .. code-block:: rsyslog action(type="mmkubernetes" annotationMatch="...") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-cacheentryttl.rst0000644000000000000000000000013115071746523027012 xustar0029 mtime=1760021843.81142056 30 atime=1764928598.152616145 30 ctime=1764935922.024558836 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-cacheentryttl.rst0000664000175000017500000000246015071746523026461 0ustar00rgerrger.. _param-mmkubernetes-cacheentryttl: .. _mmkubernetes.parameter.action.cacheentryttl: cacheentryttl ============= .. index:: single: mmkubernetes; cacheentryttl single: cacheentryttl .. summary-start Sets the maximum age of entries in the metadata cache. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: cacheentryttl :Scope: action :Type: integer :Default: 3600 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This parameter allows you to set the maximum age (time-to-live, or ttl) of an entry in the metadata cache. The value is in seconds. The default value is `3600` (one hour). When cache expiration is checked, if a cache entry has a ttl less than or equal to the current time, it will be removed from the cache. This option is only used if :ref:`param-mmkubernetes-cacheexpireinterval` is 0 or greater. This value must be 0 or greater, otherwise, if :ref:`param-mmkubernetes-cacheexpireinterval` is 0 or greater, you will get an error. Action usage ------------ .. _param-mmkubernetes-action-cacheentryttl: .. _mmkubernetes.parameter.action.cacheentryttl-usage: .. code-block:: rsyslog action(type="mmkubernetes" cacheEntryTtl="3600") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-serverinputname.rst0000644000000000000000000000013215114522477026120 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.452642096 30 ctime=1764935921.313547951 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-serverinputname.rst0000664000175000017500000000324115114522477025564 0ustar00rgerrger.. _param-imdiag-serverinputname: .. _imdiag.parameter.input.serverinputname: ServerInputName ================ .. index:: single: imdiag; ServerInputName single: ServerInputName .. summary-start Overrides the ``inputname`` property for the diagnostic TCP listener's own log messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ServerInputName :Scope: input :Type: string :Default: input=imdiag :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the ``inputname`` metadata assigned to log messages originating from the imdiag TCP listener itself (for example, connection warnings). This does **not** affect the ``inputname`` of messages injected via the control channel, which always remains ``imdiag``. This parameter must be configured before using :ref:`ServerRun `. This ensures the listener logs use the desired identifier from startup onward. Input usage ----------- .. _param-imdiag-input-serverinputname: .. _imdiag.parameter.input.serverinputname-usage: .. code-block:: rsyslog module(load="imdiag") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverInputName="diag-main" serverRun="19998") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagserverinputname: - $IMDiagServerInputName — maps to ServerInputName (status: legacy) .. index:: single: imdiag; $IMDiagServerInputName single: $IMDiagServerInputName See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-filegroup.rst0000644000000000000000000000013215062756615024734 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.375530919 30 ctime=1764935921.583552085 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-filegroup.rst0000664000175000017500000000160715062756615024404 0ustar00rgerrger.. _param-imptcp-filegroup: .. _imptcp.parameter.input.filegroup: FileGroup ========= .. index:: single: imptcp; FileGroup single: FileGroup .. summary-start Sets the group of the Unix-domain socket by group name. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FileGroup :Scope: input :Type: GID :Default: input=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the group for the domain socket. The parameter is a group name, for which the groupid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected. Input usage ----------- .. _param-imptcp-input-filegroup: .. _imptcp.parameter.input.filegroup-usage: .. code-block:: rsyslog input(type="imptcp" fileGroup="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-topic.rst0000644000000000000000000000013215114522477024160 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.456642194 30 ctime=1764935921.513551013 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-topic.rst0000664000175000017500000000137115114522477023626 0ustar00rgerrger.. _param-imkafka-topic: .. _imkafka.parameter.input.topic: topic ===== .. index:: single: imkafka; topic single: topic .. summary-start Identifies the Kafka topic from which imkafka consumes messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: topic :Scope: input :Type: string :Required?: yes :Introduced: 8.27.0 Description ----------- Specifies the name of the Kafka topic from which messages will be consumed. This is a mandatory parameter for the imkafka input. Input usage ----------- .. _imkafka.parameter.input.topic-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="static") See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-failonchownfailure.rst0000644000000000000000000000013215062756615026617 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.400531687 30 ctime=1764935921.578552008 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-failonchownfailure.rst0000664000175000017500000000166215062756615026270 0ustar00rgerrger.. _param-imptcp-failonchownfailure: .. _imptcp.parameter.input.failonchownfailure: FailOnChOwnFailure ================== .. index:: single: imptcp; FailOnChOwnFailure single: FailOnChOwnFailure .. summary-start Controls startup failure if changing socket owner, group, or mode fails. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FailOnChOwnFailure :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Rsyslog will not start if this is on and changing the file owner, group, or access permissions fails. Disable this to ignore these errors. Input usage ----------- .. _param-imptcp-input-failonchownfailure: .. _imptcp.parameter.input.failonchownfailure-usage: .. code-block:: rsyslog input(type="imptcp" failOnChOwnFailure="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-flowcontrol.rst0000644000000000000000000000013115114522477025276 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.461642317 29 ctime=1764935921.65055311 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-flowcontrol.rst0000664000175000017500000000345715114522477024754 0ustar00rgerrger.. _param-imrelp-flowcontrol: .. _imrelp.parameter.input.flowcontrol: flowControl =========== .. index:: single: imrelp; flowControl single: flowControl .. summary-start Fine-tunes RELP input flow control behavior between no, light, or full throttling. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: flowControl :Scope: input :Type: string :Default: input=light :Required?: no :Introduced: 8.1911.0 Description ----------- This parameter permits the fine-tuning of the flowControl parameter. Possible values are "no", "light", and "full". With "light" being the default and previously only value. Changing the flow control setting may be useful for some rare applications, this is an advanced setting and should only be changed if you know what you are doing. Most importantly, **rsyslog block incoming data and become unresponsive if you change flowcontrol to "full"**. While this may be a desired effect when intentionally trying to make it most unlikely that rsyslog needs to lose/discard messages, usually this is not what you want. General rule of thumb: **if you do not fully understand what this description here talks about, leave the parameter at default value**. This part of the documentation is intentionally brief, as one needs to have deep understanding of rsyslog to evaluate usage of this parameter. If someone has the insight, the meaning of this parameter is crystal-clear. If not, that someone will most likely make the wrong decision when changing this parameter away from the default value. Input usage ----------- .. _param-imrelp-input-flowcontrol-usage: .. _imrelp.parameter.input.flowcontrol-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" flowControl="light") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-port.rst0000644000000000000000000000013115062756615023543 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.259558077 29 ctime=1764935921.74655458 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-port.rst0000664000175000017500000000221415062756615023207 0ustar00rgerrger.. _param-imtcp-port: .. _imtcp.parameter.input.port: Port ==== .. index:: single: imtcp; Port single: Port .. summary-start Starts a TCP server on the specified port. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: Port :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- Starts a TCP server on the selected port. If port zero is selected, the OS automatically assigns a free port. Use ``listenPortFileName`` to learn which port was assigned. Input usage ----------- .. _param-imtcp-input-port: .. _imtcp.parameter.input.port-usage: .. code-block:: rsyslog input(type="imtcp" port="514") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverrun: - $InputTCPServerRun — maps to Port (status: legacy) .. index:: single: imtcp; $InputTCPServerRun single: $InputTCPServerRun See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-transport.rst0000644000000000000000000000013215071746523025006 xustar0030 mtime=1760021843.828420828 30 atime=1764928602.729756055 30 ctime=1764935922.585567425 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-transport.rst0000664000175000017500000000232015071746523024447 0ustar00rgerrger.. _param-omsnmp-transport: .. _omsnmp.parameter.module.transport: Transport ========= .. index:: single: omsnmp; Transport single: Transport .. summary-start Selects the transport protocol for SNMP communication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Transport :Scope: module :Type: string :Default: module=udp :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- Defines the transport type you wish to use. Technically we can support all transport types which are supported by NET-SNMP. To name a few possible values: udp, tcp, udp6, tcp6, icmp, icmp6 ... Module usage ------------ .. _param-omsnmp-module-transport: .. _omsnmp.parameter.module.transport-usage: .. code-block:: rsyslog action(type="omsnmp" transport="udp") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmptransport: - $actionsnmptransport — maps to Transport (status: legacy) .. index:: single: omsnmp; $actionsnmptransport single: $actionsnmptransport See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-timeoutgranularity.rst0000644000000000000000000000013215062756615026661 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.907485766 30 ctime=1764935921.447550002 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-timeoutgranularity.rst0000664000175000017500000000302315062756615026323 0ustar00rgerrger.. _param-imfile-timeoutgranularity: .. _imfile.parameter.module.timeoutgranularity: .. _imfile.parameter.timeoutgranularity: timeoutGranularity ================== .. index:: single: imfile; timeoutGranularity single: timeoutGranularity .. summary-start Interval in seconds for checking multi-line read timeouts. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: timeoutGranularity :Scope: module :Type: integer :Default: module=1 :Required?: no :Introduced: 8.23.0 Description ----------- Sets the interval in which multi-line-read timeouts are checked. The interval is specified in seconds. This establishes a lower limit on the length of the timeout. For example, if ``timeoutGranularity`` is 60 seconds and a ``readTimeout`` value of 10 seconds is used, the timeout is nevertheless only checked every 60 seconds (if there is no other activity in imfile). This means that the ``readTimeout`` is also only checked every 60 seconds, so a timeout can occur only after 60 seconds. Note that ``timeoutGranularity`` has some performance implication. The more frequently timeout processing is triggered, the more processing time is needed. This effect should be negligible, except if a very large number of files is being monitored. Module usage ------------ .. _param-imfile-module-timeoutgranularity: .. _imfile.parameter.module.timeoutgranularity-usage: .. code-block:: rsyslog module(load="imfile" timeoutGranularity="1") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-filecreatemode.rst0000644000000000000000000000013115062756615025716 xustar0030 mtime=1758190989.211641261 29 atime=1764928602.11973745 30 ctime=1764935922.536566675 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-filecreatemode.rst0000664000175000017500000000220115062756615025356 0ustar00rgerrger.. _param-omprog-filecreatemode: .. _omprog.parameter.action.filecreatemode: fileCreateMode ============== .. index:: single: omprog; fileCreateMode single: fileCreateMode .. summary-start Sets permissions for the output file when it is created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: fileCreateMode :Scope: action :Type: string :Default: action=0600 :Required?: no :Introduced: v8.38.0 Description ----------- Permissions the :ref:`param-omprog-output` file will be created with, in case the file does not exist. The value must be a 4-digit octal number, with the initial digit being zero. Please note that the actual permission depends on the rsyslogd process umask. If in doubt, use ``$umask 0000`` right at the beginning of the configuration file to remove any restrictions. Action usage ------------ .. _param-omprog-action-filecreatemode: .. _omprog.parameter.action.filecreatemode-usage: .. code-block:: rsyslog action(type="omprog" output="/var/log/prog.log" fileCreateMode="0640") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-port.rst0000644000000000000000000000013215114522477025110 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.469642513 30 ctime=1764935922.136560551 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-port.rst0000664000175000017500000000131115114522477024550 0ustar00rgerrger.. _param-omclickhouse-port: .. _omclickhouse.parameter.input.port: port ==== .. index:: single: omclickhouse; port single: port .. summary-start Sets the HTTP port used to connect to the ClickHouse server. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: port :Scope: input :Type: integer :Default: 8123 :Required?: no :Introduced: not specified Description ----------- HTTP port to use to connect to ClickHouse. Input usage ----------- .. _omclickhouse.parameter.input.port-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" port="9000") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-usespecialparser.rst0000644000000000000000000000013215062756615030354 xustar0030 mtime=1758190989.197641063 30 atime=1764928596.974580026 30 ctime=1764935921.890556785 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-usespecialparser.rst0000664000175000017500000000264015062756615030022 0ustar00rgerrger.. _param-imuxsock-syssock-usespecialparser: .. _imuxsock.parameter.module.syssock-usespecialparser: SysSock.UseSpecialParser ======================== .. index:: single: imuxsock; SysSock.UseSpecialParser single: SysSock.UseSpecialParser .. summary-start Uses a specialized parser for the typical system log socket format. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.UseSpecialParser :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.9.0 Description ----------- The equivalent of the ``UseSpecialParser`` input parameter, but for the system socket. If turned on (the default) a special parser is used that parses the format that is usually used on the system log socket (the one :manpage:`syslog(3)` creates). If set to "off", the regular parser chain is used, in which case the format on the log socket can be arbitrary. .. note:: When the special parser is used, rsyslog is able to inject a more precise timestamp into the message (it is obtained from the log socket). If the regular parser chain is used, this is not possible. Module usage ------------ .. _param-imuxsock-module-syssock-usespecialparser: .. _imuxsock.parameter.module.syssock-usespecialparser-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.useSpecialParser="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-tls-myprivkey.rst0000644000000000000000000000013115114522477025577 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.472642587 30 ctime=1764935922.170561072 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-tls-myprivkey.rst0000664000175000017500000000173515114522477025252 0ustar00rgerrger.. _param-omdtls-tls-myprivkey: .. _omdtls.parameter.input.tls-myprivkey: tls.myprivkey ============= .. index:: single: omdtls; tls.myprivkey single: tls.myprivkey .. summary-start Provides the private key that matches ``tls.mycert`` for DTLS authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: tls.myprivkey :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- The private key file corresponding to :ref:`tls.mycert `. This key is used for the cryptographic operations in the DTLS handshake. Input usage ----------- .. _omdtls.parameter.input.tls-myprivkey-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" tls.myCert="/etc/rsyslog/omdtls.crt" tls.myPrivKey="/etc/rsyslog/omdtls.key") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-permit-squarebracketsinhostnam0000644000000000000000000000013215062756615030520 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.249771908 30 ctime=1764935922.629568099 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-permit-squarebracketsinhostname.rst0000664000175000017500000000226415062756615031144 0ustar00rgerrger.. _param-pmrfc3164-permit-squarebracketsinhostname: .. _pmrfc3164.parameter.module.permit-squarebracketsinhostname: .. _pmrfc3164.parameter.module.permit.squareBracketsInHostname: permit.squareBracketsInHostname ================================ .. index:: single: pmrfc3164; permit.squareBracketsInHostname single: permit.squareBracketsInHostname .. summary-start Accept hostnames enclosed in ``[]``. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: permit.squareBracketsInHostname :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This option allows hostnames wrapped in square brackets to be parsed without the brackets. Module usage ------------ .. _param-pmrfc3164-module-permit-squarebracketsinhostname: .. _pmrfc3164.parameter.module.permit-squarebracketsinhostname-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" permit.squareBracketsInHostname="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-dynrestpath.rst0000644000000000000000000000013115114522477025316 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.476642685 30 ctime=1764935922.370564134 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-dynrestpath.rst0000664000175000017500000000215215114522477024763 0ustar00rgerrger.. _param-omhttp-dynrestpath: .. _omhttp.parameter.input.dynrestpath: dynrestpath =========== .. index:: single: omhttp; dynrestpath single: dynrestpath .. summary-start Enables using a template name in :ref:`param-omhttp-restpath` so each message can select a REST path dynamically. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: dynrestpath :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- When this parameter is set to ``on`` you can specify a template name in the :ref:`param-omhttp-restpath` parameter instead of the actual path. This way you can use dynamic REST paths for your messages based on the template you are using. Input usage ----------- .. _omhttp.parameter.input.dynrestpath-usage: .. code-block:: rsyslog template(name="tpl_dynamic_path" type="string" string="tenant/%hostname%/events") module(load="omhttp") action( type="omhttp" dynRestPath="on" restPath="tpl_dynamic_path" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-facility.rst0000644000000000000000000000013215114522477025107 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.459642268 30 ctime=1764935921.548551549 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-facility.rst0000664000175000017500000000150215114522477024551 0ustar00rgerrger.. _param-impstats-facility: .. _impstats.parameter.module.facility: facility ======== .. index:: single: impstats; facility single: facility .. summary-start Selects the numeric syslog facility value used for generated statistics messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: facility :Scope: module :Type: integer :Default: module=5 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The numerical syslog facility code to be used for generated messages. Default is 5 (syslog). This is useful for filtering messages. Module usage ------------ .. _impstats.parameter.module.facility-usage: .. code-block:: rsyslog module(load="impstats" facility="16") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omjournal-namespace.rst0000644000000000000000000000013115114522477025400 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.483642857 29 ctime=1764935922.43956519 rsyslog-8.2512.0/doc/source/reference/parameters/omjournal-namespace.rst0000664000175000017500000000277115114522477025054 0ustar00rgerrger.. _param-omjournal-namespace: .. _omjournal.parameter.input.namespace: namespace ========= .. index:: single: omjournal; namespace single: namespace .. summary-start Writes journal entries to a specific systemd journal namespace instead of the default target. .. summary-end This parameter applies to :doc:`../../configuration/modules/omjournal`. :Name: namespace :Scope: input :Type: word :Default: none :Required?: no :Introduced: 8.2406.0 (requires systemd v256+) Description ----------- Starting from systemd v256, the journal supports namespaces. This allows you to write to a specific namespace in the journal, which can be useful for isolating logs from different applications or components. However, this feature has important limitations: * This parameter is mutually exclusive with the ``template`` parameter. If both are specified for the same action, the action fails with an error. * Namespaces must be created before use. If a namespace does not exist, the action fails and logs an error. Create namespaces by adding directories under ``/var/log/journal/``. For more information, see the `systemd-journald.service(8) `_ man page. Input usage ----------- .. _param-omjournal-input-namespace: .. _omjournal.parameter.input.namespace-usage: .. code-block:: shell action(type="omjournal" namespace="audit-journal-namespace") See also -------- See also :doc:`../../configuration/modules/omjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdblookup-key.rst0000644000000000000000000000013215071746523024402 xustar0030 mtime=1760021843.807420497 30 atime=1764928597.763604222 30 ctime=1764935921.971558025 rsyslog-8.2512.0/doc/source/reference/parameters/mmdblookup-key.rst0000664000175000017500000000166315071746523024054 0ustar00rgerrger.. _param-mmdblookup-key: .. _mmdblookup.parameter.input.key: key === .. index:: single: mmdblookup; key single: key .. summary-start Identifies the message field that supplies the IP address to look up. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdblookup`. :Name: key :Scope: input :Type: string (word) :Default: none :Required?: yes :Introduced: 8.24.0 Description ----------- This parameter specifies the name of the field in the message that contains the IP address to be looked up. This is typically a JSON property obtained from a parsed message or structured log. Input usage ----------- .. _mmdblookup.parameter.input.key-usage: .. code-block:: rsyslog action(type="mmdblookup" key="!clientip" mmdbFile="/etc/rsyslog.d/GeoLite2-City.mmdb" fields=["!continent!code", "!location"]) See also -------- See also :doc:`../../configuration/modules/mmdblookup`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-keepalive-probes.rst0000644000000000000000000000013215062756615026015 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.101553227 30 ctime=1764935921.718554152 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-keepalive-probes.rst0000664000175000017500000000342215062756615025462 0ustar00rgerrger.. _param-imtcp-keepalive-probes: .. _imtcp.parameter.module.keepalive-probes: .. _imtcp.parameter.input.keepalive-probes: KeepAlive.Probes ================ .. index:: single: imtcp; KeepAlive.Probes single: KeepAlive.Probes .. summary-start Defines how many unacknowledged probes are sent before a connection is considered dead. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: KeepAlive.Probes :Scope: module, input :Type: integer :Default: module=0, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The number of unacknowledged probes to send before considering the connection dead and notifying the application layer. The default, 0, means that the operating system defaults are used. This has only effect if keep-alive is enabled. The functionality may not be available on all platforms. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-keepalive-probes: .. _imtcp.parameter.module.keepalive-probes-usage: .. code-block:: rsyslog module(load="imtcp" keepAlive.probes="...") Input usage ----------- .. _param-imtcp-input-keepalive-probes: .. _imtcp.parameter.input.keepalive-probes-usage: .. code-block:: rsyslog input(type="imtcp" port="514" keepAlive.probes="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverkeepalive_probes: - $InputTCPServerKeepAlive_probes — maps to KeepAlive.Probes (status: legacy) .. index:: single: imtcp; $InputTCPServerKeepAlive_probes single: $InputTCPServerKeepAlive_probes See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmtaghostname-forcelocalhostname.rst0000644000000000000000000000013215071746523030155 xustar0030 mtime=1760021843.823420749 30 atime=1764928598.753634555 30 ctime=1764935922.095559923 rsyslog-8.2512.0/doc/source/reference/parameters/mmtaghostname-forcelocalhostname.rst0000664000175000017500000000255215071746523027625 0ustar00rgerrger.. _param-mmtaghostname-forcelocalhostname: .. _mmtaghostname.parameter.input.forcelocalhostname: forceLocalHostname ================== .. index:: single: mmtaghostname; forceLocalHostname single: forceLocalHostname .. summary-start Forces the message ``HOSTNAME`` to the rsyslog ``localHostName`` value. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmtaghostname`. :Name: forceLocalHostname :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: at least 7.0, possibly earlier Description ----------- When enabled, this parameter forces the message's ``HOSTNAME`` field to the rsyslog value ``localHostName``. This is useful for setting a consistent hostname on messages that may not have one, e.g. those received via ``imudp`` or ``imtcp``. A common use case is with applications in auto-scaling environments (e.g. AWS), where instances may have ephemeral hostnames. Forcing the hostname to the rsyslog host's name can provide more meaningful and consistent hostnames in logs. Input usage ----------- .. _mmtaghostname.parameter.input.forcelocalhostname-usage: .. code-block:: rsyslog action(type="mmtaghostname" forceLocalHostname="on") Notes ----- - Legacy documentation referred to the type as ``Binary``; it is treated as boolean. See also -------- * :doc:`../../configuration/modules/mmtaghostname` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-ratelimit-burst.rst0000644000000000000000000000012715103061376026564 xustar0030 mtime=1762419454.850381068 29 atime=1764928594.62850795 28 ctime=1764935921.4865506 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-ratelimit-burst.rst0000664000175000017500000000243415103061376026227 0ustar00rgerrger.. _param-imjournal-ratelimit-burst: .. _imjournal.parameter.module.ratelimit-burst: .. meta:: :tag: module:imjournal :tag: parameter:Ratelimit.Burst Ratelimit.Burst =============== .. index:: single: imjournal; Ratelimit.Burst single: Ratelimit.Burst .. summary-start Maximum messages accepted within each rate-limit window. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: Ratelimit.Burst :Scope: module :Type: integer :Default: module=20000 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies how many messages are permitted during each ``Ratelimit.Interval`` period. Messages beyond this threshold are discarded until the interval expires. Module usage ------------ .. _param-imjournal-module-ratelimit-burst: .. _imjournal.parameter.module.ratelimit-burst-usage: .. code-block:: rsyslog module(load="imjournal" Ratelimit.Burst="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournalratelimitburst: - $imjournalRatelimitBurst — maps to Ratelimit.Burst (status: legacy) .. index:: single: imjournal; $imjournalRatelimitBurst single: $imjournalRatelimitBurst See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-keyfile.rst0000644000000000000000000000013215062756615026715 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.413562804 30 ctime=1764935921.773554993 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-keyfile.rst0000664000175000017500000000203015062756615026354 0ustar00rgerrger.. _param-imtcp-streamdriver-keyfile: .. _imtcp.parameter.input.streamdriver-keyfile: streamDriver.KeyFile ==================== .. index:: single: imtcp; streamDriver.KeyFile single: streamDriver.KeyFile .. summary-start Overrides ``DefaultNetstreamDriverKeyFile`` for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: streamDriver.KeyFile :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=global parameter :Required?: no :Introduced: 8.2108.0 Description ----------- .. versionadded:: 8.2108.0 This permits to override the ``DefaultNetstreamDriverKeyFile`` global parameter on the ``input()`` level. For further details, see the global parameter. Input usage ----------- .. _param-imtcp-input-streamdriver-keyfile: .. _imtcp.parameter.input.streamdriver-keyfile-usage: .. code-block:: rsyslog input(type="imtcp" streamDriver.keyFile="/etc/ssl/private/key.pem") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-threads.rst0000644000000000000000000000013215062756615024214 xustar0030 mtime=1758190989.195641035 30 atime=1764928596.723572321 30 ctime=1764935921.826555805 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-threads.rst0000664000175000017500000000220015062756615023652 0ustar00rgerrger.. _param-imudp-threads: .. _imudp.parameter.module.threads: Threads ======= .. index:: single: imudp; Threads single: Threads .. summary-start Number of worker threads receiving data; upper limit 32. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Threads :Scope: module :Type: integer :Default: module=1 :Required?: no :Introduced: 7.5.5 Description ----------- Number of worker threads to process incoming messages. These threads are utilized to pull data off the network. On a busy system, additional threads (but not more than there are CPUs/Cores) can help improving performance and avoiding message loss. Note that with too many threads, performance can suffer. There is a hard upper limit on the number of threads that can be defined. Currently, this limit is set to 32. It may increase in the future when massive multicore processors become available. Module usage ------------ .. _param-imudp-module-threads: .. _imudp.parameter.module.threads-usage: .. code-block:: rsyslog module(load="imudp" Threads="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-severity.rst0000644000000000000000000000013215062756615024563 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.960487398 30 ctime=1764935921.433549788 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-severity.rst0000664000175000017500000000255615062756615024237 0ustar00rgerrger.. _param-imfile-severity: .. _imfile.parameter.input.severity: .. _imfile.parameter.severity: Severity ======== .. index:: single: imfile; Severity single: Severity .. summary-start Sets the syslog severity for lines read from the file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: Severity :Scope: input :Type: word :Default: notice :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The syslog severity to be assigned to lines read. It can be specified in textual form (for example ``info`` or ``warning``) or as a number (for example ``6`` for ``info``). Textual form is recommended. Input usage ----------- .. _param-imfile-input-severity: .. _imfile.parameter.input.severity-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" Severity="notice") Notes ----- - See https://en.wikipedia.org/wiki/Syslog for severity numbers. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfileseverity: - ``$InputFileSeverity`` — maps to Severity (status: legacy) .. index:: single: imfile; $InputFileSeverity single: $InputFileSeverity See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-address.rst0000644000000000000000000000013215062756615024205 xustar0030 mtime=1758190989.191640978 30 atime=1764928596.275558568 30 ctime=1764935921.703553922 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-address.rst0000664000175000017500000000151015062756615023646 0ustar00rgerrger.. _param-imtcp-address: .. _imtcp.parameter.input.address: Address ======= .. index:: single: imtcp; Address single: Address .. summary-start Local address that the listener binds to; ``*`` uses all interfaces. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: Address :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- On multi-homed machines, specifies to which local address the listener should be bound. Input usage ----------- .. _param-imtcp-input-address: .. _imtcp.parameter.input.address-usage: .. code-block:: rsyslog input(type="imtcp" address="127.0.0.1" port="514") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-trapoid.rst0000644000000000000000000000013115071746523024413 xustar0029 mtime=1760021843.83042086 30 atime=1764928602.753756787 30 ctime=1764935922.588567471 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-trapoid.rst0000664000175000017500000000333115071746523024060 0ustar00rgerrger.. _param-omsnmp-trapoid: .. _omsnmp.parameter.module.trapoid: TrapOID ======= .. index:: single: omsnmp; TrapOID single: TrapOID .. summary-start Defines the notification OID used for SNMPv2 traps. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: TrapOID :Scope: module :Type: string :Default: module=1.3.6.1.4.1.19406.1.2.1 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- The default value means "ADISCON-MONITORWARE-MIB::syslogtrap". This configuration parameter is used for **SNMPv2** only. This is the OID which defines the trap-type, or notification-type rsyslog uses to send the trap. In order to decode this OID, you will need to have the ADISCON-MONITORWARE-MIB and ADISCON-MIB mibs installed on the receiver side. Downloads of these mib files can be found here: `https://www.adiscon.org/download/ADISCON-MIB.txt `_ `https://www.adiscon.org/download/ADISCON-MONITORWARE-MIB.txt `_ Thanks to the net-snmp mailinglist for the help and the recommendations ;). Module usage ------------ .. _param-omsnmp-module-trapoid: .. _omsnmp.parameter.module.trapoid-usage: .. code-block:: rsyslog action(type="omsnmp" trapOID="1.3.6.1.4.1.19406.1.2.1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmptrapoid: - $actionsnmptrapoid — maps to TrapOID (status: legacy) .. index:: single: omsnmp; $actionsnmptrapoid single: $actionsnmptrapoid See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-flowcontrol.rst0000644000000000000000000000013215062756615027352 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.911578092 30 ctime=1764935921.862556356 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-flowcontrol.rst0000664000175000017500000000232015062756615027013 0ustar00rgerrger.. _param-imuxsock-syssock-flowcontrol: .. _imuxsock.parameter.module.syssock-flowcontrol: SysSock.FlowControl =================== .. index:: single: imuxsock; SysSock.FlowControl single: SysSock.FlowControl .. summary-start Applies flow control to the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.FlowControl :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies if flow control should be applied to the system log socket. Module usage ------------ .. _param-imuxsock-module-syssock-flowcontrol: .. _imuxsock.parameter.module.syssock-flowcontrol-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.flowControl="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogflowcontrol: - $SystemLogFlowControl — maps to SysSock.FlowControl (status: legacy) .. index:: single: imuxsock; $SystemLogFlowControl single: $SystemLogFlowControl See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-fileownernum.rst0000644000000000000000000000013115062756615025451 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.367530673 30 ctime=1764935921.590552192 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-fileownernum.rst0000664000175000017500000000170315062756615025117 0ustar00rgerrger.. _param-imptcp-fileownernum: .. _imptcp.parameter.input.fileownernum: FileOwnerNum ============ .. index:: single: imptcp; FileOwnerNum single: FileOwnerNum .. summary-start Sets the owner of the Unix-domain socket by numeric UID. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FileOwnerNum :Scope: input :Type: integer :Default: input=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the file owner for the domain socket. The parameter is a numerical ID, which is used regardless of whether the user actually exists. This can be useful if the user mapping is not available to rsyslog during startup. Input usage ----------- .. _param-imptcp-input-fileownernum: .. _imptcp.parameter.input.fileownernum-usage: .. code-block:: rsyslog input(type="imptcp" fileOwnerNum="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-indextimeout.rst0000644000000000000000000000013215062756615027330 xustar0030 mtime=1758190989.203641148 30 atime=1764928599.601660512 30 ctime=1764935922.204561592 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-indextimeout.rst0000664000175000017500000000153515062756615027000 0ustar00rgerrger.. _param-omelasticsearch-indextimeout: .. _omelasticsearch.parameter.module.indextimeout: indexTimeout ============ .. index:: single: omelasticsearch; indexTimeout single: indexTimeout .. summary-start Milliseconds to wait for an indexing request to complete. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: indexTimeout :Scope: action :Type: integer :Default: action=0 :Required?: no :Introduced: 8.2204.0 Description ----------- Sets the client-side timeout for a log indexing request. `0` means no timeout. Action usage ------------ .. _param-omelasticsearch-action-indextimeout: .. _omelasticsearch.parameter.action.indextimeout: .. code-block:: rsyslog action(type="omelasticsearch" indexTimeout="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-discardtruncatedmsg.rst0000644000000000000000000000013115062756615026742 xustar0030 mtime=1758190989.184640879 29 atime=1764928594.10449183 30 ctime=1764935921.382549007 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-discardtruncatedmsg.rst0000664000175000017500000000226615062756615026415 0ustar00rgerrger.. _param-imfile-discardtruncatedmsg: .. _imfile.parameter.input.discardtruncatedmsg: .. _imfile.parameter.discardtruncatedmsg: discardTruncatedMsg =================== .. index:: single: imfile; discardTruncatedMsg single: discardTruncatedMsg .. summary-start Discards the truncated part of an overlong message instead of processing it. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: discardTruncatedMsg :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When messages are too long they are truncated and the remaining part is processed as a new message. If ``discardTruncatedMsg`` is ``on``, the truncated part is discarded instead. Input usage ----------- .. _param-imfile-input-discardtruncatedmsg: .. _imfile.parameter.input.discardtruncatedmsg-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" discardTruncatedMsg="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-userawmsg.rst0000644000000000000000000000013215071746523026014 xustar0030 mtime=1760021843.809420528 30 atime=1764928597.966610447 30 ctime=1764935922.003558515 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-userawmsg.rst0000664000175000017500000000173015071746523025461 0ustar00rgerrger.. _param-mmjsonparse-userawmsg: .. _mmjsonparse.parameter.input.userawmsg: useRawMsg ========= .. index:: single: mmjsonparse; useRawMsg single: useRawMsg single: mmjsonparse; userawmsg single: userawmsg .. summary-start Controls whether parsing operates on the raw message or only the MSG part. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: useRawMsg :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: 6.6.0 Description ----------- Specifies if the raw message should be used for parsing (``on``) or just the MSG part of the message (``off``). Notes ----- - Older documentation referred to this boolean setting as ``binary``. Input usage ----------- .. _mmjsonparse.parameter.input.userawmsg-usage: .. code-block:: rsyslog action(type="mmjsonparse" useRawMsg="on") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-retry-ruleset.rst0000644000000000000000000000013215114522477025600 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.480642783 30 ctime=1764935922.411564761 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-retry-ruleset.rst0000664000175000017500000000513715114522477025252 0ustar00rgerrger.. _param-omhttp-retry-ruleset: .. _omhttp.parameter.input.retry-ruleset: retry.ruleset ============= .. index:: single: omhttp; retry.ruleset single: retry.ruleset .. summary-start Names the ruleset where omhttp requeues failed messages when :ref:`param-omhttp-retry` is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: retry.ruleset :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- This parameter specifies the ruleset where this plugin should requeue failed messages if :ref:`param-omhttp-retry` is on. This ruleset generally would contain another omhttp action instance. **Important** - Note that the message that is queued on the retry ruleset is the templated output of the initial omhttp action. This means that no further templating should be done to messages inside this ruleset, unless retries should be templated differently than first-tries. An "echo template" does the trick here. .. code-block:: text template(name="tpl_echo" type="string" string="%msg%") This retry ruleset can recursively call itself as its own ``retry.ruleset`` to retry forever, but there is no timeout behavior currently implemented. Alternatively, the omhttp action in the retry ruleset could be configured to support ``action.resumeRetryCount`` as explained above in the :ref:`param-omhttp-retry` section. The benefit of this approach is that retried messages still hit the server in a batch format (though with a single message in it), and the ability to configure rsyslog to give up after some number of resume attempts so as to avoid resource exhaustion. Or, if some data loss or high latency is acceptable, do not configure retries with the retry ruleset itself. A single retry from the original ruleset might catch most failures, and errors from the retry ruleset could still be logged using the :ref:`param-omhttp-errorfile` parameter and sent later on via some other process. Input usage ----------- .. _omhttp.parameter.input.retry-ruleset-usage: .. code-block:: rsyslog module(load="omhttp") # This action enables the retry ruleset. action( type="omhttp" template="tpl_omhttp_json" retry="on" retryRuleSet="rs_omhttp_retry" ) # The "rs_omhttp_retry" ruleset itself could be defined as follows: ruleset(name="rs_omhttp_retry") { action( type="omhttp" template="tpl_echo" batch="on" batchFormat="jsonarray" batchMaxSize="5" ) } See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-device.rst0000644000000000000000000000013215062756615024021 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.768573702 30 ctime=1764935921.799555391 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-device.rst0000664000175000017500000000174515062756615023474 0ustar00rgerrger.. _param-imudp-device: .. _imudp.parameter.input.device: Device ====== .. index:: single: imudp; Device single: Device .. summary-start Binds UDP socket to a specific network device or VRF. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Device :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Bind socket to given device (e.g., ``eth0``). For Linux with VRF support, the ``Device`` option can be used to specify the VRF for the ``Address``. Examples: .. code-block:: rsyslog module(load="imudp") # needs to be done just once input(type="imudp" port="514" device="eth0") Input usage ----------- .. _param-imudp-input-device: .. _imudp.parameter.input.device-usage: .. code-block:: rsyslog input(type="imudp" Device="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-closetimeout.rst0000644000000000000000000000013215062756615025433 xustar0030 mtime=1758190989.205641176 30 atime=1764928600.081675197 30 ctime=1764935922.265562526 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-closetimeout.rst0000664000175000017500000000176215062756615025105 0ustar00rgerrger.. _param-omfile-closetimeout: .. _omfile.parameter.module.closetimeout: closeTimeout ============ .. index:: single: omfile; closeTimeout single: closeTimeout .. summary-start Specifies after how many minutes of inactivity a file is automatically closed. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: closeTimeout :Scope: action :Type: integer :Default: action=File: 0 DynaFile: 10 :Required?: no :Introduced: 8.3.3 Description ----------- Specifies after how many minutes of inactivity a file is automatically closed. Note that this functionality is implemented based on the :doc:`janitor process <../../concepts/janitor>`. See its doc to understand why and how janitor-based times are approximate. Action usage ------------ .. _param-omfile-action-closetimeout: .. _omfile.parameter.action.closetimeout: .. code-block:: rsyslog action(type="omfile" closeTimeout="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-compression.rst0000644000000000000000000000013115114522477026067 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.464642391 29 ctime=1764935921.68055357 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-compression.rst0000664000175000017500000000174115114522477025537 0ustar00rgerrger.. _param-imrelp-tls-compression: .. _imrelp.parameter.input.tls-compression: tls.compression =============== .. index:: single: imrelp; tls.compression single: tls.compression .. summary-start Controls whether TLS sessions compress payload data before transmission. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.compression :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not documented Description ----------- This controls if the TLS stream should be compressed (zipped). While this increases CPU use, the network bandwidth should be reduced. Note that typical text-based log records usually compress rather well. Input usage ----------- .. _param-imrelp-input-tls-compression-usage: .. _imrelp.parameter.input.tls-compression-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.compression="on") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-server.rst0000644000000000000000000000013215071746523024260 xustar0030 mtime=1760021843.827420812 30 atime=1764928602.714755598 30 ctime=1764935922.578567318 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-server.rst0000664000175000017500000000220215071746523023720 0ustar00rgerrger.. _param-omsnmp-server: .. _omsnmp.parameter.module.server: Server ====== .. index:: single: omsnmp; Server single: Server .. summary-start Defines the SNMP target host by hostname or IP address. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Server :Scope: module :Type: string :Default: module=none :Required?: yes :Introduced: at least 7.3.0, possibly earlier Description ----------- This can be a hostname or ip address, and is our snmp target host. This parameter is required, if the snmptarget is not defined, nothing will be send. Module usage ------------ .. _param-omsnmp-module-server: .. _omsnmp.parameter.module.server-usage: .. code-block:: rsyslog action(type="omsnmp" server="192.0.2.1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmptarget: - $actionsnmptarget — maps to Server (status: legacy) .. index:: single: omsnmp; $actionsnmptarget single: $actionsnmptarget See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-mycert.rst0000644000000000000000000000013215114522477025032 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.464642391 30 ctime=1764935921.684553631 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-mycert.rst0000664000175000017500000000147215114522477024502 0ustar00rgerrger.. _param-imrelp-tls-mycert: .. _imrelp.parameter.input.tls-mycert: tls.myCert ========== .. index:: single: imrelp; tls.myCert single: tls.myCert .. summary-start Points rsyslog to the server certificate presented during TLS handshakes. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.myCert :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- The machine certificate that is being used for TLS communication. Input usage ----------- .. _param-imrelp-input-tls-mycert-usage: .. _imrelp.parameter.input.tls-mycert-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.myCert="/etc/rsyslog/server.pem") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-allow_trailing.rst0000644000000000000000000000013115103346332026773 xustar0029 mtime=1762512090.62717594 30 atime=1764928597.958610201 30 ctime=1764935921.992558346 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-allow_trailing.rst0000664000175000017500000000274515103346332026450 0ustar00rgerrger.. _param-mmjsonparse-allow_trailing: .. _mmjsonparse.parameter.allow_trailing: allow_trailing ============== .. index:: single: mmjsonparse; allow_trailing single: allow_trailing single: trailing data .. summary-start Whether to allow non-whitespace data after the JSON object in find-json mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: allow_trailing :Scope: action :Type: boolean :Default: on :Required?: no :Introduced: 8.2506.0 Description ----------- Controls whether trailing non-whitespace characters are permitted after the parsed JSON object in find-json mode. - **on** (default): Allow trailing data after the JSON object. The JSON portion will be parsed and the trailing content ignored. - **off**: Reject messages with trailing non-whitespace content after the JSON object. Such messages will be treated as non-JSON. Whitespace characters (spaces, tabs, newlines) are always allowed after the JSON object regardless of this setting. This parameter is only effective when mode="find-json". Input usage ----------- .. _mmjsonparse.parameter.allow_trailing-usage: .. code-block:: rsyslog # Allow trailing data (default) action(type="mmjsonparse" mode="find-json" allow_trailing="on") # Reject messages with trailing data action(type="mmjsonparse" mode="find-json" allow_trailing="off") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`.rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-fsync.rst0000644000000000000000000000013115062756615024565 xustar0030 mtime=1758190989.186640907 29 atime=1764928594.66750915 30 ctime=1764935921.474550416 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-fsync.rst0000664000175000017500000000212115062756615024226 0ustar00rgerrger.. _param-imjournal-fsync: .. _imjournal.parameter.module.fsync: .. meta:: :tag: module:imjournal :tag: parameter:FSync FSync ===== .. index:: single: imjournal; FSync single: FSync .. summary-start Force ``fsync()`` on the state file to guard against crash corruption. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: FSync :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.1908.0 Description ----------- When enabled, the module synchronizes the state file to persistent storage after each write. This reduces the risk of duplicate messages after abrupt shutdowns at the cost of additional I/O. Module usage ------------ .. _param-imjournal-module-fsync: .. _imjournal.parameter.module.fsync-usage: .. code-block:: rsyslog module(load="imjournal" FSync="...") Notes ----- - Historic documentation called this a ``binary`` option; it is boolean. - May significantly impact performance with low ``PersistStateInterval`` values. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmsnmptrapd-severitymapping.rst0000644000000000000000000000013215071746523027231 xustar0030 mtime=1760021843.822420733 30 atime=1764928598.709633208 30 ctime=1764935922.091559862 rsyslog-8.2512.0/doc/source/reference/parameters/mmsnmptrapd-severitymapping.rst0000664000175000017500000000371315071746523026701 0ustar00rgerrger.. _param-mmsnmptrapd-severitymapping: .. _mmsnmptrapd.parameter.module.severitymapping: severityMapping =============== .. index:: single: mmsnmptrapd; severityMapping single: severityMapping .. summary-start Defines severity string to numeric code mappings. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmsnmptrapd`. :Name: severityMapping :Scope: module :Type: string :Default: module=none :Required?: no :Introduced: at least 5.8.1, possibly earlier Description ----------- This specifies the severity mapping table. It must be specified as a list. Note that **no whitespace** is supported inside the list, as it will likely lead to parsing errors. The list is constructed of Severity-Name/Severity-Value pairs, delimited by comma. Severity-Name is a case-sensitive string, e.g. ``warning`` and an associated numerical value (e.g. 4). Possible values are in the range 0..7 and are defined in `RFC5424, table 2 `_. The given sample would be specified as ``warning/4``. The mapping is defined when the module is loaded using the ``module()`` statement. This setting applies to all subsequent actions that use this module instance. To use different mappings, load separate instances of the module in different rulesets. Module usage ------------ .. _param-mmsnmptrapd-module-severitymapping: .. _mmsnmptrapd.parameter.module.severitymapping-usage: .. code-block:: rsyslog module(load="mmsnmptrapd" severityMapping="warning/4,error/3") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmsnmptrapd.parameter.legacy.mmsnmptrapdseveritymapping: - $mmsnmptrapdSeverityMapping — maps to severityMapping (status: legacy) .. index:: single: mmsnmptrapd; $mmsnmptrapdSeverityMapping single: $mmsnmptrapdSeverityMapping See also -------- See also :doc:`../../configuration/modules/mmsnmptrapd`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-cacheexpireinterval.rst0000644000000000000000000000013115071746523030166 xustar0029 mtime=1760021843.81142056 30 atime=1764928598.161616421 30 ctime=1764935922.026558867 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-cacheexpireinterval.rst0000664000175000017500000000353215071746523027636 0ustar00rgerrger.. _param-mmkubernetes-cacheexpireinterval: .. _mmkubernetes.parameter.action.cacheexpireinterval: cacheexpireinterval =================== .. index:: single: mmkubernetes; cacheexpireinterval single: cacheexpireinterval .. summary-start Controls how often to check for expired metadata cache entries. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: cacheexpireinterval :Scope: action :Type: integer :Default: -1 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This parameter allows you to expire entries from the metadata cache. The values are: - -1 (default) - disables metadata cache expiration - 0 - check cache for expired entries before every cache lookup - 1 or higher - the number is a number of seconds - check the cache for expired entries every this many seconds, when processing an entry The cache is only checked if processing a record from Kubernetes. There isn't some sort of housekeeping thread that continually runs cleaning up the cache. When an record from Kubernetes is processed: If `cacheexpireinterval` is -1, then do not check for cache expiration. If `cacheexpireinterval` is 0, then check for cache expiration. If `cacheexpireinterval` is greater than 0, check for cache expiration if the last time we checked was more than this many seconds ago. When cache expiration is checked, it will delete all cache entries which have a ttl less than or equal to the current time. The cache entry ttl is set using the :ref:`param-mmkubernetes-cacheentryttl`. Action usage ------------ .. _param-mmkubernetes-action-cacheexpireinterval: .. _mmkubernetes.parameter.action.cacheexpireinterval-usage: .. code-block:: rsyslog action(type="mmkubernetes" cacheExpireInterval="-1") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-begintransactionmark.rst0000644000000000000000000000013115062756615027153 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.094736688 29 ctime=1764935922.52256646 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-begintransactionmark.rst0000664000175000017500000000207015062756615026617 0ustar00rgerrger.. _param-omprog-begintransactionmark: .. _omprog.parameter.action.begintransactionmark: beginTransactionMark ===================== .. index:: single: omprog; beginTransactionMark single: beginTransactionMark .. summary-start Defines the marker sent to denote the start of a transaction. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: beginTransactionMark :Scope: action :Type: string :Default: action="BEGIN TRANSACTION" :Required?: no :Introduced: 8.31.0 Description ----------- Allows specifying the mark message that rsyslog will send to the external program to indicate the start of a transaction (batch). This parameter is ignored if :ref:`param-omprog-usetransactions` is disabled. Action usage ------------ .. _param-omprog-action-begintransactionmark: .. _omprog.parameter.action.begintransactionmark-usage: .. code-block:: rsyslog action(type="omprog" useTransactions="on" beginTransactionMark="BEGIN TRANSACTION") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-keepalive-interval.rst0000644000000000000000000000013215114522477026516 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.461642317 30 ctime=1764935921.653553156 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-keepalive-interval.rst0000664000175000017500000000213415114522477026162 0ustar00rgerrger.. _param-imrelp-keepalive-interval: .. _imrelp.parameter.input.keepalive-interval: keepAlive.interval ================== .. index:: single: imrelp; keepAlive.interval single: keepAlive.interval .. summary-start Determines the delay between successive keep-alive probes when enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: keepAlive.interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: Not documented Description ----------- The interval between subsequent keep-alive probes, regardless of what the connection has been exchanged in the meantime. The default, 0, means that the operating system defaults are used. This only has an effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imrelp-input-keepalive-interval-usage: .. _imrelp.parameter.input.keepalive-interval-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" keepAlive="on" keepAlive.interval="30") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-eventproperties.rst0000644000000000000000000000013215114522477030303 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.467642464 30 ctime=1764935922.118560275 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-eventproperties.rst0000664000175000017500000000330415114522477027747 0ustar00rgerrger.. _param-omazureeventhubs-eventproperties: .. _omazureeventhubs.parameter.input.eventproperties: eventproperties =============== .. index:: single: omazureeventhubs; eventproperties single: eventproperties .. summary-start Adds custom key-value properties to each AMQP message emitted by the action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: eventproperties :Scope: input :Type: array :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- The ``eventProperties`` configuration property is an array property used to add key-value pairs as additional properties to the encoded AMQP message object, providing additional information about the log event. These properties can be used for filtering, routing, and grouping log events in Azure Event Hubs. The ``eventProperties`` property is an array of strings, where each string is a key-value pair with the key and value separated by an equal sign. For example, the following configuration adds two event properties inside an action definition: .. code-block:: rsyslog action( type="omazureeventhubs" # ... other parameters eventProperties=["Table=TestTable", "Format=JSON"] ) In this example, the Table and Format keys are added to the message object as event properties, with the corresponding values of ``TestTable`` and ``JSON``, respectively. Input usage ----------- .. _omazureeventhubs.parameter.input.eventproperties-usage: .. code-block:: rsyslog action(type="omazureeventhubs" eventProperties=["Table=TestTable", "Format=JSON"] ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-listenportfilename.rst0000644000000000000000000000013115062756615026643 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.606538018 30 ctime=1764935921.609552483 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-listenportfilename.rst0000664000175000017500000000172015062756615026310 0ustar00rgerrger.. _param-imptcp-listenportfilename: .. _imptcp.parameter.input.listenportfilename: ListenPortFileName ================== .. index:: single: imptcp; ListenPortFileName single: ListenPortFileName .. summary-start Writes the port number being listened on into the specified file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: ListenPortFileName :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: 8.38.0 Description ----------- With this parameter you can specify the name for a file. In this file the port, imptcp is connected to, will be written. This parameter was introduced because the testbench works with dynamic ports. Input usage ----------- .. _param-imptcp-input-listenportfilename: .. _imptcp.parameter.input.listenportfilename-usage: .. code-block:: rsyslog input(type="imptcp" listenPortFileName="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-errorfile.rst0000644000000000000000000000013215114522477024743 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.476642685 30 ctime=1764935922.372564164 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-errorfile.rst0000664000175000017500000000247415114522477024416 0ustar00rgerrger.. _param-omhttp-errorfile: .. _omhttp.parameter.input.errorfile: errorfile ========= .. index:: single: omhttp; errorfile single: errorfile .. summary-start Specifies a file where omhttp records HTTP requests that return error responses. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: errorfile :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- Here you can set the name of a file where all errors will be written to. Any request that returns a 4XX or 5XX HTTP code is recorded in the error file. Each line is JSON formatted with ``"request"`` and ``"response"`` fields, example pretty-printed below. .. code-block:: text { "request": { "url": "https://example.com:443/path", "postdata": "mypayload" }, "response" : { "status": 400, "message": "error string" } } It is intended that a full replay of failed data is possible by processing this file. Input usage ----------- .. _omhttp.parameter.input.errorfile-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" errorFile="/var/log/rsyslog/omhttp.error" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-de-dot-separator.rst0000644000000000000000000000013215071746523027314 xustar0030 mtime=1760021843.813420591 30 atime=1764928598.195617463 30 ctime=1764935922.033558974 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-de-dot-separator.rst0000664000175000017500000000203415071746523026757 0ustar00rgerrger.. _param-mmkubernetes-de-dot-separator: .. _mmkubernetes.parameter.action.de-dot-separator: de_dot_separator ================ .. index:: single: mmkubernetes; de_dot_separator single: de_dot_separator .. summary-start Defines the string used to replace dots when ``de_dot`` is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: de_dot_separator :Scope: action :Type: word :Default: _ :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When processing labels and annotations, if the :ref:`param-mmkubernetes-de-dot` parameter is set to `"on"`, the key strings will have their `.` characters replaced with the string specified by the string value of this parameter. Action usage ------------ .. _param-mmkubernetes-action-de-dot-separator: .. _mmkubernetes.parameter.action.de-dot-separator-usage: .. code-block:: rsyslog action(type="mmkubernetes" deDotSeparator="_") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-retrievenewlogsfromstart.rst0000644000000000000000000000013215062756615030427 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.670478467 30 ctime=1764935921.344548426 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-retrievenewlogsfromstart.rst0000664000175000017500000000222415062756615030073 0ustar00rgerrger.. _param-imdocker-retrievenewlogsfromstart: .. _imdocker.parameter.module.retrievenewlogsfromstart: RetrieveNewLogsFromStart ======================== .. index:: single: imdocker; RetrieveNewLogsFromStart single: RetrieveNewLogsFromStart .. summary-start Whether to read newly discovered container logs from start; default ``on``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: RetrieveNewLogsFromStart :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.41.0 Description ----------- Specifies whether imdocker processes newly found container logs from the beginning. Containers that exist when imdocker starts are controlled by ``GetContainerLogOptions`` and its ``tail`` option. Module usage ------------ .. _param-imdocker-module-retrievenewlogsfromstart: .. _imdocker.parameter.module.retrievenewlogsfromstart-usage: .. code-block:: rsyslog module(load="imdocker" RetrieveNewLogsFromStart="...") Notes ----- - The original documentation described this as a binary option; it is a boolean parameter. See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv6-anonmode.rst0000644000000000000000000000013215071746523025410 xustar0030 mtime=1760021843.803420434 30 atime=1764928597.344591373 30 ctime=1764935921.936557489 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv6-anonmode.rst0000664000175000017500000000301515071746523025053 0ustar00rgerrger.. _param-mmanon-ipv6-anonmode: .. _mmanon.parameter.input.ipv6-anonmode: ipv6.anonMode ============= .. index:: single: mmanon; ipv6.anonMode single: ipv6.anonMode .. summary-start Defines how IPv6 addresses are anonymized by the mmanon action. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv6.anonMode :Scope: input :Type: string :Default: input=zero :Required?: no :Introduced: 7.3.7 Description ----------- The available modes are ``random``, ``random-consistent``, and ``zero``. The modes ``random`` and ``random-consistent`` are very similar, in that they both anonymize IP addresses by randomizing the last bits (any number) of a given address. However, while ``random`` mode assigns a new random IP address for every address in a message, ``random-consistent`` will assign the same randomized address to every instance of the same original address. The default ``zero`` mode will do full anonymization of any number of bits and it will also normalize the address, so that no information about the original IP address is available. Also note that an anonymized IPv6 address will be normalized, meaning there will be no abbreviations, leading zeros will **not** be displayed, and capital letters in the hex numerals will be lowercase. Input usage ----------- .. _mmanon.parameter.input.ipv6-anonmode-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv6.anonMode="random-consistent") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-addtlframedelimiter.rst0000644000000000000000000000013215062756615026562 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.059551937 30 ctime=1764935921.705553952 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-addtlframedelimiter.rst0000664000175000017500000000334115062756615026227 0ustar00rgerrger.. _param-imtcp-addtlframedelimiter: .. _imtcp.parameter.module.addtlframedelimiter: .. _imtcp.parameter.input.addtlframedelimiter: AddtlFrameDelimiter =================== .. index:: single: imtcp; AddtlFrameDelimiter single: AddtlFrameDelimiter .. summary-start Specifies an additional frame delimiter for message reception. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: AddtlFrameDelimiter :Scope: module, input :Type: integer :Default: module=-1, input=module parameter :Required?: no :Introduced: 4.3.1 Description ----------- This directive permits to specify an additional frame delimiter. The value must be the decimal ASCII code of the character to be used as the delimiter. For example, to use ``#`` as the delimiter, specify ``addtlFrameDelimiter="35"``. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-addtlframedelimiter: .. _imtcp.parameter.module.addtlframedelimiter-usage: .. code-block:: rsyslog module(load="imtcp" addtlFrameDelimiter="...") Input usage ----------- .. _param-imtcp-input-addtlframedelimiter: .. _imtcp.parameter.input.addtlframedelimiter-usage: .. code-block:: rsyslog input(type="imtcp" port="514" addtlFrameDelimiter="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserveraddtlframedelimiter: - $InputTCPServerAddtlFrameDelimiter — maps to AddtlFrameDelimiter (status: legacy) .. index:: single: imtcp; $InputTCPServerAddtlFrameDelimiter single: $InputTCPServerAddtlFrameDelimiter See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-name.rst0000644000000000000000000000013215062756615025722 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.904577877 30 ctime=1764935921.870556478 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-name.rst0000664000175000017500000000300115062756615025360 0ustar00rgerrger.. _param-imuxsock-syssock-name: .. _imuxsock.parameter.module.syssock-name: SysSock.Name ============ .. index:: single: imuxsock; SysSock.Name single: SysSock.Name .. summary-start Selects an alternate log socket instead of the default ``/dev/log``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.Name :Scope: module :Type: word :Default: module=/dev/log :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies an alternate log socket to be used instead of the default system log socket, traditionally ``/dev/log``. Unless disabled by the ``SysSock.Unlink`` setting, this socket is created upon rsyslog startup and deleted upon shutdown, according to traditional syslogd behavior. The behavior of this parameter is different for systemd systems. See the :ref:`imuxsock-systemd-details-label` section for details. Module usage ------------ .. _param-imuxsock-module-syssock-name: .. _imuxsock.parameter.module.syssock-name-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.name="/var/run/rsyslog/devlog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogsockname: - $SystemLogSocketName — maps to SysSock.Name (status: legacy) .. index:: single: imuxsock; $SystemLogSocketName single: $SystemLogSocketName See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-model.rst0000644000000000000000000000013215071746523024160 xustar0030 mtime=1760021843.800420386 30 atime=1764928597.238588123 30 ctime=1764935921.913557137 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-model.rst0000664000175000017500000000134215071746523023624 0ustar00rgerrger.. _param-mmaitag-model: .. _mmaitag.parameter.action.model: model ===== .. index:: single: mmaitag; model single: model .. summary-start Specifies the AI model identifier used by the provider. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: model :Scope: action :Type: string :Default: gemini-2.0-flash :Required?: no :Introduced: 9.0.0 Description ----------- AI model identifier to use. The meaning of the value is provider specific. Action usage ------------- .. _param-mmaitag-action-model: .. _mmaitag.parameter.action.model-usage: .. code-block:: rsyslog action(type="mmaitag" model="gemini-1.5-flash") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgssserverrun.rst0000644000000000000000000000013215114522477027103 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.454642145 30 ctime=1764935921.461550217 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgssserverrun.rst0000664000175000017500000000213715114522477026552 0ustar00rgerrger.. _param-imgssapi-inputgssserverrun: .. _imgssapi.parameter.input.inputgssserverrun: InputGSSServerRun ================= .. index:: single: imgssapi; InputGSSServerRun single: InputGSSServerRun .. summary-start Starts a dedicated GSSAPI syslog listener on the specified port. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSServerRun :Scope: input :Type: word :Default: none :Required?: no :Introduced: 3.11.5 Description ----------- Starts a GSSAPI server on the selected port. This listener runs independently from the TCP server provided by other modules. Input usage ----------- .. _imgssapi.parameter.input.inputgssserverrun-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssServerRun 1514 Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgssserverrun: - $inputGssServerRun — maps to InputGSSServerRun (status: legacy) .. index:: single: imgssapi; $inputGssServerRun single: $inputGssServerRun See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-getcontainerlogoptions.rst0000644000000000000000000000013115062756615030040 xustar0030 mtime=1758190989.183640865 29 atime=1764928593.66147819 30 ctime=1764935921.337548318 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-getcontainerlogoptions.rst0000664000175000017500000000216315062756615027507 0ustar00rgerrger.. _param-imdocker-getcontainerlogoptions: .. _imdocker.parameter.module.getcontainerlogoptions: GetContainerLogOptions ====================== .. index:: single: imdocker; GetContainerLogOptions single: GetContainerLogOptions .. summary-start HTTP query options for ``Get container logs`` requests; default ``timestamps=0&follow=1&stdout=1&stderr=1&tail=1``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: GetContainerLogOptions :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=timestamps=0&follow=1&stdout=1&stderr=1&tail=1 :Required?: no :Introduced: 8.41.0 Description ----------- Specifies the HTTP query component of a ``Get container logs`` API request. See the Docker API for available options. It is not necessary to prepend ``?``. Module usage ------------ .. _param-imdocker-module-getcontainerlogoptions: .. _imdocker.parameter.module.getcontainerlogoptions-usage: .. code-block:: rsyslog module(load="imdocker" GetContainerLogOptions="...") See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-usesystimestamp.rst0000644000000000000000000000013215062756615026565 xustar0030 mtime=1758190989.197641063 30 atime=1764928597.057582572 30 ctime=1764935921.901556953 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-usesystimestamp.rst0000664000175000017500000000313515062756615026233 0ustar00rgerrger.. _param-imuxsock-usesystimestamp: .. _imuxsock.parameter.input.usesystimestamp: UseSysTimeStamp =============== .. index:: single: imuxsock; UseSysTimeStamp single: UseSysTimeStamp .. summary-start Takes message timestamps from the system instead of the message itself. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: UseSysTimeStamp :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 5.9.1 Description ----------- This parameter instructs ``imuxsock`` to obtain message time from the system (via control messages) instead of using time recorded inside the message. This may be most useful in combination with systemd. Due to the usefulness of this functionality, we decided to enable it by default. As such, the behavior is slightly different than previous versions. However, we do not see how this could negatively affect existing environments. .. versionadded:: 5.9.1 Input usage ----------- .. _param-imuxsock-input-usesystimestamp: .. _imuxsock.parameter.input.usesystimestamp-usage: .. code-block:: rsyslog input(type="imuxsock" useSysTimeStamp="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketusesystimestamp: - $InputUnixListenSocketUseSysTimeStamp — maps to UseSysTimeStamp (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketUseSysTimeStamp single: $InputUnixListenSocketUseSysTimeStamp See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-specifictype.rst0000644000000000000000000000013215071746523025441 xustar0030 mtime=1760021843.828420828 30 atime=1764928602.776757489 30 ctime=1764935922.583567394 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-specifictype.rst0000664000175000017500000000225715071746523025113 0ustar00rgerrger.. _param-omsnmp-specifictype: .. _omsnmp.parameter.module.specifictype: SpecificType ============ .. index:: single: omsnmp; SpecificType single: SpecificType .. summary-start Defines the SNMPv1 specific trap number. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: SpecificType :Scope: module :Type: integer :Default: module=0 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- This is the specific trap number. This configuration parameter is used for **SNMPv1** only. It has no effect if **SNMPv2** is used. Module usage ------------ .. _param-omsnmp-module-specifictype: .. _omsnmp.parameter.module.specifictype-usage: .. code-block:: rsyslog action(type="omsnmp" specificType="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmpspecifictype: - $actionsnmpspecifictype — maps to SpecificType (status: legacy) .. index:: single: omsnmp; $actionsnmpspecifictype single: $actionsnmpspecifictype See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-uid.rst0000644000000000000000000000013215114522477024001 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.484642882 30 ctime=1764935922.501566139 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-uid.rst0000664000175000017500000000227015114522477023446 0ustar00rgerrger.. _param-omlibdbi-uid: .. _omlibdbi.parameter.input.uid: UID === .. index:: single: omlibdbi; UID single: UID .. summary-start Defines the user name that omlibdbi uses when authenticating to the database. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: UID :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Provide the account that has permission to write into the target database. Combine this with ``PWD`` to supply the password. Input usage ----------- .. _param-omlibdbi-input-uid-usage: .. _omlibdbi.parameter.input.uid-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbiusername: - $ActionLibdbiUserName — maps to UID (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiUserName single: $ActionLibdbiUserName See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-writeoperation.rst0000644000000000000000000000013215062756615027665 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.741664796 30 ctime=1764935922.258562419 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-writeoperation.rst0000664000175000017500000000171715062756615027337 0ustar00rgerrger.. _param-omelasticsearch-writeoperation: .. _omelasticsearch.parameter.module.writeoperation: writeoperation ============== .. index:: single: omelasticsearch; writeoperation single: writeoperation .. summary-start Bulk action type: `index` (default) or `create` to avoid overwrites. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: writeoperation :Scope: action :Type: word :Default: action=index :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Controls the operation sent in bulk requests. Use `create` to only add documents that do not yet exist. Requires `bulkid` and `dynbulkid`. Action usage ------------ .. _param-omelasticsearch-action-writeoperation: .. _omelasticsearch.parameter.action.writeoperation: .. code-block:: rsyslog action(type="omelasticsearch" writeoperation="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmexternal-binary.rst0000644000000000000000000000013215071746523025101 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.827606184 30 ctime=1764935921.978558132 rsyslog-8.2512.0/doc/source/reference/parameters/mmexternal-binary.rst0000664000175000017500000000166415071746523024554 0ustar00rgerrger.. _param-mmexternal-binary: .. _mmexternal.parameter.input.binary: binary ====== .. index:: single: mmexternal; binary single: binary .. summary-start Specifies the external message modification plugin executable that mmexternal invokes. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmexternal`. :Name: binary :Scope: input :Type: string :Default: none :Required?: yes :Introduced: 8.3.0 Description ----------- The name of the external message modification plugin to be called. This can be a full path name. Command-line arguments for the executable can also be included in the string. Input usage ----------- .. _param-mmexternal-input-binary: .. _mmexternal.parameter.input.binary-usage: .. code-block:: rsyslog module(load="mmexternal") action( type="mmexternal" binary="/path/to/mmexternal.py" ) See also -------- See also :doc:`../../configuration/modules/mmexternal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-listenportfilename.rst0000644000000000000000000000013215114522477026575 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.452642096 30 ctime=1764935921.308547874 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-listenportfilename.rst0000664000175000017500000000325515114522477026246 0ustar00rgerrger.. _param-imdiag-listenportfilename: .. _imdiag.parameter.input.listenportfilename: ListenPortFileName ================== .. index:: single: imdiag; ListenPortFileName single: ListenPortFileName .. summary-start Writes the port chosen for the diagnostic listener to the named file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ListenPortFileName :Scope: input :Type: string (filename) :Default: input=none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- Specifies a file that receives the TCP port number after the listener starts. Use :ref:`ServerRun ` to initialize the listener. The parameter is mandatory and must be provided before the listener is created. The file is overwritten each time the listener starts. When the listener is configured with port ``0`` (ephemeral port selection), this file is the only way to discover the actual port allocated by the operating system. Input usage ----------- .. _param-imdiag-input-listenportfilename: .. _imdiag.parameter.input.listenportfilename-usage: .. code-block:: rsyslog module(load="imdiag") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverRun="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiaglistenportfilename: - $IMDiagListenPortFileName — maps to ListenPortFileName (status: legacy) .. index:: single: imdiag; $IMDiagListenPortFileName single: $IMDiagListenPortFileName See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-freshstarttail.rst0000644000000000000000000000013215062756615025750 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.096491583 30 ctime=1764935921.396549221 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-freshstarttail.rst0000664000175000017500000000324315062756615025416 0ustar00rgerrger.. _param-imfile-freshstarttail: .. _imfile.parameter.input.freshstarttail: .. _imfile.parameter.freshstarttail: freshStartTail ============== .. index:: single: imfile; freshStartTail single: freshStartTail .. summary-start On first start, seeks to the end of existing files and processes only new lines. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: freshStartTail :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Causes rsyslog to seek to the end of input files at the initial start and process only new log messages. Useful when deploying rsyslog and only new logs are of interest. This parameter applies only to files that exist when rsyslog performs its initial processing of file monitors. .. warning:: Depending on the number and location of existing files, startup may take time. If another process creates a new file exactly during startup and writes data to it, rsyslog may treat that file as preexisting and skip it. The same risk exists for log data written between the last shutdown and the next start. Some data loss is therefore possible. The rsyslog team advises against activating ``freshStartTail``. Input usage ----------- .. _param-imfile-input-freshstarttail: .. _imfile.parameter.input.freshstarttail-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" freshStartTail="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-defaultseverity.rst0000644000000000000000000000013215062756615026663 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.637508227 30 ctime=1764935921.467550309 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-defaultseverity.rst0000664000175000017500000000242415062756615026331 0ustar00rgerrger.. _param-imjournal-defaultseverity: .. _imjournal.parameter.module.defaultseverity: .. meta:: :tag: module:imjournal :tag: parameter:DefaultSeverity DefaultSeverity =============== .. index:: single: imjournal; DefaultSeverity single: DefaultSeverity .. summary-start Fallback severity used if a journal entry lacks ``SYSLOG_PRIORITY``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: DefaultSeverity :Scope: module :Type: word :Default: module=notice :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the severity assigned to messages that do not provide the ``SYSLOG_PRIORITY`` field. Values may be given as names or numbers. Module usage ------------ .. _param-imjournal-module-defaultseverity: .. _imjournal.parameter.module.defaultseverity-usage: .. code-block:: rsyslog module(load="imjournal" DefaultSeverity="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournaldefaultseverity: - $ImjournalDefaultSeverity — maps to DefaultSeverity (status: legacy) .. index:: single: imjournal; $ImjournalDefaultSeverity single: $ImjournalDefaultSeverity See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-usetransactions.rst0000644000000000000000000000013215062756615026174 xustar0030 mtime=1758190989.212641276 30 atime=1764928602.085736413 30 ctime=1764935922.555566966 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-usetransactions.rst0000664000175000017500000000414115062756615025640 0ustar00rgerrger.. _param-omprog-usetransactions: .. _omprog.parameter.action.usetransactions: useTransactions =============== .. index:: single: omprog; useTransactions single: useTransactions .. summary-start Enables batch processing with begin and commit transaction markers. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: useTransactions :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.31.0 Description ----------- Specifies whether the external program processes the messages in :doc:`batches <../../development/dev_oplugins>` (transactions). When this switch is enabled, the logs sent to the program are grouped in transactions. At the start of a transaction, rsyslog sends a special mark message to the program (see :ref:`param-omprog-begintransactionmark`). At the end of the transaction, rsyslog sends another mark message (see :ref:`param-omprog-committransactionmark`). If :ref:`param-omprog-confirmmessages` is also set to "on", the program must confirm both the mark messages and the logs within the transaction. The mark messages must be confirmed by returning ``OK``, and the individual messages by returning ``DEFER_COMMIT`` (instead of ``OK``). Refer to the link below for details. .. seealso:: `Interface between rsyslog and external output plugins `_ .. warning:: This feature is currently **experimental**. It could change in future releases without keeping backwards compatibility with existing configurations or the specified interface. There is also a `known issue `_ with the use of transactions together with ``confirmMessages=on``. Action usage ------------ .. _param-omprog-action-usetransactions: .. _omprog.parameter.action.usetransactions-usage: .. code-block:: rsyslog action(type="omprog" useTransactions="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-statsname.rst0000644000000000000000000000013215062756615025054 xustar0030 mtime=1758190989.211641261 30 atime=1764928601.550720081 30 ctime=1764935922.479565802 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-statsname.rst0000664000175000017500000000151015062756615024515 0ustar00rgerrger.. _param-omkafka-statsname: .. _omkafka.parameter.module.statsname: statsName ========= .. index:: single: omkafka; statsName single: statsName .. summary-start Name of statistics instance for this action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: statsName :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: 8.2108.0 Description ----------- .. versionadded:: 8.2108.0 The name assigned to statistics specific to this action instance. Counters include ``submitted``, ``acked`` and ``failures``. Action usage ------------ .. _param-omkafka-action-statsname: .. _omkafka.parameter.action.statsname: .. code-block:: rsyslog action(type="omkafka" statsName="producer-1") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-name-appendport.rst0000644000000000000000000000013115062756615025653 xustar0030 mtime=1758190989.194641021 29 atime=1764928596.80857493 30 ctime=1764935921.803555453 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-name-appendport.rst0000664000175000017500000000311715062756615025322 0ustar00rgerrger.. _param-imudp-name-appendport: .. _imudp.parameter.input.name-appendport: Name.appendPort =============== .. index:: single: imudp; Name.appendPort single: Name.appendPort .. summary-start Appends listener port number to ``inputname``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Name.appendPort :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: 7.3.9 Description ----------- Appends the port to the ``inputname`` property. Note that when no ``name`` is specified, the default of ``imudp`` is used and the port is appended to that default. So, for example, a listener port of 514 in that case will lead to an ``inputname`` of ``imudp514``. The ability to append a port is most useful when multiple ports are defined for a single input and each of the ``inputname`` values shall be unique. Note that there currently is no differentiation between IPv4/v6 listeners on the same port. Examples: .. code-block:: rsyslog module(load="imudp") input(type="imudp" port=["10514","10515","10516"] name="udp" name.appendPort="on") .. code-block:: rsyslog module(load="imudp") input(type="imudp" port=["10514","10515","10516"] name="" name.appendPort="on") Input usage ----------- .. _param-imudp-input-name-appendport: .. _imudp.parameter.input.name-appendport-usage: .. code-block:: rsyslog input(type="imudp" Name.appendPort="...") Notes ----- - Earlier documentation described the type as ``binary``; this maps to boolean. See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmsnmptrapd-tag.rst0000644000000000000000000000013215071746523024556 xustar0030 mtime=1760021843.822420733 30 atime=1764928598.704633055 30 ctime=1764935922.093559892 rsyslog-8.2512.0/doc/source/reference/parameters/mmsnmptrapd-tag.rst0000664000175000017500000000263515071746523024230 0ustar00rgerrger.. _param-mmsnmptrapd-tag: .. _mmsnmptrapd.parameter.module.tag: tag === .. index:: single: mmsnmptrapd; tag single: tag .. summary-start Specifies the tag prefix that identifies messages for processing. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmsnmptrapd`. :Name: tag :Scope: module :Type: word (see :doc:`../../rainerscript/constant_strings`) :Default: module=snmptrapd :Required?: no :Introduced: at least 5.8.1, possibly earlier Description ----------- Tells the module which start string inside the tag to look for. The default is ``snmptrapd``. Note that a slash (``/``) is automatically appended to this tag for matching. You should not include a trailing slash unless you specifically need to match a double slash. For example, setting ``tag="tag/"`` results in a check for ``tag//`` at the start of the tag field. Module usage ------------ .. _param-mmsnmptrapd-module-tag: .. _mmsnmptrapd.parameter.module.tag-usage: .. code-block:: rsyslog module(load="mmsnmptrapd" tag="snmptrapd") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmsnmptrapd.parameter.legacy.mmsnmptrapdtag: - $mmsnmptrapdTag — maps to tag (status: legacy) .. index:: single: mmsnmptrapd; $mmsnmptrapdTag single: $mmsnmptrapdTag See also -------- See also :doc:`../../configuration/modules/mmsnmptrapd`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-addceetag.rst0000644000000000000000000000013215062756615024612 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.055490322 30 ctime=1764935921.372548854 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-addceetag.rst0000664000175000017500000000171315062756615024260 0ustar00rgerrger.. _param-imfile-addceetag: .. _imfile.parameter.input.addceetag: .. _imfile.parameter.addceetag: addCeeTag ========= .. index:: single: imfile; addCeeTag single: addCeeTag .. summary-start Adds the ``@cee:`` cookie to the message when enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: addCeeTag :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Turns on or off the addition of the ``@cee:`` cookie to the message object. Input usage ----------- .. _param-imfile-input-addceetag: .. _imfile.parameter.input.addceetag-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" addCeeTag="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dirgroupnum.rst0000644000000000000000000000013215062756615025272 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.950671191 30 ctime=1764935922.281562771 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dirgroupnum.rst0000664000175000017500000000314715062756615024743 0ustar00rgerrger.. _param-omfile-dirgroupnum: .. _omfile.parameter.module.dirgroupnum: dirGroupNum =========== .. index:: single: omfile; dirGroupNum single: dirGroupNum .. summary-start Set the group for directories newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dirGroupNum :Scope: module, action :Type: integer :Default: module=process user's primary group; action=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the group for directories newly created. Please note that this setting does not affect the group of directories already existing. The parameter is a numerical ID, which is used regardless of whether the group actually exists. This can be useful if the group mapping is not available to rsyslog during startup. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-dirgroupnum: .. _omfile.parameter.module.dirgroupnum-usage: .. code-block:: rsyslog module(load="builtin:omfile" dirGroupNum="...") Action usage ------------ .. _param-omfile-action-dirgroupnum: .. _omfile.parameter.action.dirgroupnum: .. code-block:: rsyslog action(type="omfile" dirGroupNum="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dirgroupnum: - $DirGroupNum — maps to dirGroupNum (status: legacy) .. index:: single: omfile; $DirGroupNum single: $DirGroupNum See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdblookup-container.rst0000644000000000000000000000013215071746523025574 xustar0030 mtime=1760021843.807420497 30 atime=1764928597.753603915 30 ctime=1764935921.966557948 rsyslog-8.2512.0/doc/source/reference/parameters/mmdblookup-container.rst0000664000175000017500000000162315071746523025242 0ustar00rgerrger.. _param-mmdblookup-container: .. _mmdblookup.parameter.module.container: container ========= .. index:: single: mmdblookup; container single: container .. summary-start Specifies the container for fields amended by mmdblookup. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdblookup`. :Name: container :Scope: module :Type: string (word) :Default: ``!iplocation`` :Required?: no :Introduced: 8.28.0 Description ----------- .. versionadded:: 8.28.0 This parameter specifies the JSON container (a JSON object) used to store the fields amended by mmdblookup within the rsyslog message. If not specified, it defaults to ``!iplocation``. Module usage ------------ .. _mmdblookup.parameter.module.container-usage: .. code-block:: rsyslog module(load="mmdblookup" container="!geo_ip") See also -------- See also :doc:`../../configuration/modules/mmdblookup`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-consoleloglevel.rst0000644000000000000000000000013215114522477026115 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.456642194 30 ctime=1764935921.516551059 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-consoleloglevel.rst0000664000175000017500000000331115114522477025557 0ustar00rgerrger.. _param-imklog-consoleloglevel: .. _imklog.parameter.module.consoleloglevel: ConsoleLogLevel ================ .. index:: single: imklog; ConsoleLogLevel single: ConsoleLogLevel .. summary-start Filters kernel console messages, printing only those with a severity up to the configured level. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: ConsoleLogLevel :Scope: module :Type: integer :Default: -1 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the console log level. If specified, only messages with up to the specified level are printed to the console. The default is -1, which means that the current settings are not modified. To get this behavior, do not specify ``consoleLogLevel`` in the configuration file. Note that this is a global parameter. Each time it is changed, the previous definition is reset. The active setting will be the last one defined when imklog actually starts processing. To avoid unexpected behavior, it is recommended to specify this directive only once. **Linux only**, ignored on other platforms (but may be specified). Module usage ------------ .. _param-imklog-module-consoleloglevel: .. _imklog.parameter.module.consoleloglevel-usage: .. code-block:: rsyslog module(load="imklog" consoleLogLevel="4") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.klogconsoleloglevel: - $klogConsoleLogLevel — maps to ConsoleLogLevel (status: legacy) .. index:: single: imklog; $klogConsoleLogLevel single: $klogConsoleLogLevel See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-errorfile.rst0000644000000000000000000000013215114522477026115 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.468642489 30 ctime=1764935922.129560444 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-errorfile.rst0000664000175000017500000000341115114522477025560 0ustar00rgerrger.. _param-omclickhouse-errorfile: .. _omclickhouse.parameter.input.errorfile: errorFile ========= .. index:: single: omclickhouse; errorFile single: errorFile single: omclickhouse; errorfile single: errorfile .. summary-start Specifies a file that receives bulk-mode failures along with the ClickHouse error response. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: errorFile :Scope: input :Type: word :Default: none :Required?: no :Introduced: not specified Description ----------- If specified, records failed in bulk mode are written to this file, including their error cause. Rsyslog itself does not process the file any more, but the idea behind that mechanism is that the user can create a script to periodically inspect the error file and react appropriately. As the complete request is included, it is possible to simply resubmit messages from that script. .. note:: When rsyslog has problems connecting to ClickHouse, a general error is assumed. However, if we receive negative responses during batch processing, we assume an error in the data itself (like a mandatory field is not filled in, a format error or something along those lines). Such errors cannot be solved by simply resubmitting the record. As such, they are written to the error file so that the user (script) can examine them and act appropriately. Note that e.g. after search index reconfiguration (e.g. dropping the mandatory attribute) a resubmit may be successful. Input usage ----------- .. _omclickhouse.parameter.input.errorfile-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" errorFile="clickhouse-error.log") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/immark-interval.rst0000644000000000000000000000013215114522477024543 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.458642243 30 ctime=1764935921.534551334 rsyslog-8.2512.0/doc/source/reference/parameters/immark-interval.rst0000664000175000017500000000203415114522477024206 0ustar00rgerrger.. _param-immark-interval: .. _immark.parameter.module.interval: interval ======== .. index:: single: immark; interval single: interval .. summary-start Specifies how often immark injects a mark message, in seconds. .. summary-end This parameter applies to :doc:`../../configuration/modules/immark`. :Name: interval :Scope: module :Type: integer (seconds) :Default: module=1200 (seconds) :Required?: no :Introduced: 3.0.0 Module usage ------------ .. _immark.parameter.module.interval-usage: .. code-block:: rsyslog module(load="immark" interval="1200") Legacy names (for reference) ---------------------------- Historic names/directives for compatibility. Do not use in new configs. .. _immark.parameter.legacy.markmessageperiod: - ``$MarkMessagePeriod`` — maps to interval (status: legacy) .. index:: single: immark; $MarkMessagePeriod single: $MarkMessagePeriod See also -------- .. seealso:: * ``action.writeAllMarkMessages`` in :doc:`../../configuration/actions` * :doc:`../../configuration/modules/immark` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmcount-appname.rst0000644000000000000000000000013115071746523024543 xustar0030 mtime=1760021843.804420449 29 atime=1764928597.46059493 30 ctime=1764935921.943557596 rsyslog-8.2512.0/doc/source/reference/parameters/mmcount-appname.rst0000664000175000017500000000253115071746523024211 0ustar00rgerrger.. _param-mmcount-appname: .. _mmcount.parameter.input.appname: appName ======= .. index:: single: mmcount; appName single: appName .. summary-start Selects the application name whose messages the mmcount action tracks. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmcount`. :Name: appName :Scope: input :Type: word :Default: none :Required?: yes :Introduced: 7.5.0 Description ----------- Specifies the syslog APP-NAME that must match for mmcount to process a message. When the application name of the current message does not match ``appName``, the action immediately returns without altering counters. If no match is found, no ``mmcount`` property is added to the message. For matching messages, mmcount increments counters based on the additional parameters. When :ref:`param-mmcount-key` is omitted, the module counts per-severity totals for the selected application. If :ref:`param-mmcount-key` is provided, counters are updated according to that parameter's logic. The updated total is written into the message's ``mmcount`` JSON property so later actions can react to it. Input usage ----------- .. _param-mmcount-appname-usage: .. _mmcount.parameter.input.appname-usage: .. code-block:: rsyslog action(type="mmcount" appName="gluster") See also -------- See also :doc:`../../configuration/modules/mmcount`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-container.rst0000644000000000000000000000013215114522477027027 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.467642464 30 ctime=1764935922.116560245 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-container.rst0000664000175000017500000000167715114522477026506 0ustar00rgerrger.. _param-omazureeventhubs-container: .. _omazureeventhubs.parameter.input.container: container ========= .. index:: single: omazureeventhubs; container single: container .. summary-start Identifies the Event Hubs instance that receives the formatted log messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: container :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- Specifies the name of the "Event Hubs Instance"—the specific event hub within the namespace—that should receive the forwarded log data. Define it unless ``amqpAddress`` already points at the desired event hub. Input usage ----------- .. _omazureeventhubs.parameter.input.container-usage: .. code-block:: rsyslog action(type="omazureeventhubs" container="MyEventHub" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-usesystimestamp.rst0000644000000000000000000000013215062756615030261 xustar0030 mtime=1758190989.197641063 30 atime=1764928596.947579197 30 ctime=1764935921.892556815 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-usesystimestamp.rst0000664000175000017500000000330515062756615027726 0ustar00rgerrger.. _param-imuxsock-syssock-usesystimestamp: .. _imuxsock.parameter.module.syssock-usesystimestamp: SysSock.UseSysTimeStamp ======================= .. index:: single: imuxsock; SysSock.UseSysTimeStamp single: SysSock.UseSysTimeStamp .. summary-start Obtains message time from the system instead of the message content. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.UseSysTimeStamp :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 5.9.1 Description ----------- The same as the input parameter ``UseSysTimeStamp``, but for the system log socket. This parameter instructs ``imuxsock`` to obtain message time from the system (via control messages) instead of using time recorded inside the message. This may be most useful in combination with systemd. Due to the usefulness of this functionality, we decided to enable it by default. As such, the behavior is slightly different than previous versions. However, we do not see how this could negatively affect existing environments. Module usage ------------ .. _param-imuxsock-module-syssock-usesystimestamp: .. _imuxsock.parameter.module.syssock-usesystimestamp-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.useSysTimeStamp="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogusesystimestamp: - $SystemLogUseSysTimeStamp — maps to SysSock.UseSysTimeStamp (status: legacy) .. index:: single: imuxsock; $SystemLogUseSysTimeStamp single: $SystemLogUseSysTimeStamp See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-cafile.rst0000644000000000000000000000013215062756615026510 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.395562252 30 ctime=1764935921.764554856 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-cafile.rst0000664000175000017500000000201115062756615026146 0ustar00rgerrger.. _param-imtcp-streamdriver-cafile: .. _imtcp.parameter.input.streamdriver-cafile: streamDriver.CAFile =================== .. index:: single: imtcp; streamDriver.CAFile single: streamDriver.CAFile .. summary-start Overrides ``DefaultNetstreamDriverCAFile`` for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: streamDriver.CAFile :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=global parameter :Required?: no :Introduced: 8.2108.0 Description ----------- .. versionadded:: 8.2108.0 This permits to override the ``DefaultNetstreamDriverCAFile`` global parameter on the ``input()`` level. For further details, see the global parameter. Input usage ----------- .. _param-imtcp-input-streamdriver-cafile: .. _imtcp.parameter.input.streamdriver-cafile-usage: .. code-block:: rsyslog input(type="imtcp" streamDriver.caFile="/etc/ssl/certs/ca.pem") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-permittedpeer.rst0000644000000000000000000000013215114522477026400 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.464642391 30 ctime=1764935921.689553707 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-permittedpeer.rst0000664000175000017500000000423215114522477026045 0ustar00rgerrger.. _param-imrelp-tls-permittedpeer: .. _imrelp.parameter.input.tls-permittedpeer: tls.permittedPeer ================= .. index:: single: imrelp; tls.permittedPeer single: tls.permittedPeer .. summary-start Restricts accepted clients to the listed certificate fingerprints or wildcard names. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.permittedPeer :Scope: input :Type: array :Default: input=none :Required?: no :Introduced: Not documented Description ----------- The ``tls.permittedPeer`` setting places access restrictions on this listener. Only peers which have been listed in this parameter may connect. The certificate presented by the remote peer is used for its validation. The *peer* parameter lists permitted certificate fingerprints. Note that it is an array parameter, so either a single or multiple fingerprints can be listed. When a non-permitted peer connects, the refusal is logged together with its fingerprint. So if the administrator knows this was a valid request, he can simply add the fingerprint by copy and paste from the logfile to rsyslog.conf. To specify multiple fingerprints, just enclose them in braces like this: .. code-block:: none tls.permittedPeer=["SHA1:...1", "SHA1:....2"] To specify just a single peer, you can either specify the string directly or enclose it in braces. You may also use wildcards to match a larger number of permitted peers, e.g. ``*.example.com``. When using wildcards to match larger number of permitted peers, please know that the implementation is similar to Syslog RFC5425 which means: This wildcard matches any left-most DNS label in the server name. That is, the subject ``*.example.com`` matches the server names ``a.example.com`` and ``b.example.com``, but does not match ``example.com`` or ``a.b.example.com``. Input usage ----------- .. _param-imrelp-input-tls-permittedpeer-usage: .. _imrelp.parameter.input.tls-permittedpeer-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.permittedPeer=["SHA1:0123456789ABCDEF0123456789ABCDEF01234567"]) See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-keepalive-time.rst0000644000000000000000000000013215062756615025461 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.108553441 30 ctime=1764935921.721554197 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-keepalive-time.rst0000664000175000017500000000344715062756615025135 0ustar00rgerrger.. _param-imtcp-keepalive-time: .. _imtcp.parameter.module.keepalive-time: .. _imtcp.parameter.input.keepalive-time: KeepAlive.Time ============== .. index:: single: imtcp; KeepAlive.Time single: KeepAlive.Time .. summary-start Sets the interval between last data and first keepalive probe. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: KeepAlive.Time :Scope: module, input :Type: integer :Default: module=0, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further. The default, 0, means that the operating system defaults are used. This has only effect if keep-alive is enabled. The functionality may not be available on all platforms. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-keepalive-time: .. _imtcp.parameter.module.keepalive-time-usage: .. code-block:: rsyslog module(load="imtcp" keepAlive.time="...") Input usage ----------- .. _param-imtcp-input-keepalive-time: .. _imtcp.parameter.input.keepalive-time-usage: .. code-block:: rsyslog input(type="imtcp" port="514" keepAlive.time="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverkeepalive_time: - $InputTCPServerKeepAlive_time — maps to KeepAlive.Time (status: legacy) .. index:: single: imtcp; $InputTCPServerKeepAlive_time single: $InputTCPServerKeepAlive_time See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhdfs-omhdfshost.rst0000644000000000000000000000013115114522477025074 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.474642636 30 ctime=1764935922.347563781 rsyslog-8.2512.0/doc/source/reference/parameters/omhdfs-omhdfshost.rst0000664000175000017500000000220015114522477024533 0ustar00rgerrger.. _param-omhdfs-omhdfshost: .. _omhdfs.parameter.module.omhdfshost: omhdfsHost ========== .. index:: single: omhdfs; omhdfsHost single: omhdfsHost .. summary-start Selects the hostname or IP address of the HDFS system omhdfs connects to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhdfs`. :Name: omhdfsHost :Scope: module :Type: word :Default: default :Required?: no :Introduced: Not documented Description ----------- Name or IP address of the HDFS host to connect to. Module usage ------------ .. _omhdfs.parameter.module.omhdfshost-usage: .. code-block:: none $ModLoad omhdfs $omhdfsHost hdfs01.example.net $omhdfsFileName /var/log/hdfs/system.log # write all messages to the specified HDFS host *.* :omhdfs: Legacy names (for reference) ---------------------------- Historic names/directives for compatibility. Do not use in new configs. .. _omhdfs.parameter.legacy.omhdfshost: - ``$OMHDFSHost`` — maps to ``omhdfsHost`` (status: legacy) .. index:: single: omhdfs; $OMHDFSHost single: $OMHDFSHost See also -------- See also :doc:`../../configuration/modules/omhdfs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-driverdirectory.rst0000644000000000000000000000013215114522477026440 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.484642882 30 ctime=1764935922.492566001 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-driverdirectory.rst0000664000175000017500000000267215114522477026113 0ustar00rgerrger.. _param-omlibdbi-driverdirectory: .. _omlibdbi.parameter.module.driverdirectory: DriverDirectory =============== .. index:: single: omlibdbi; DriverDirectory single: DriverDirectory .. summary-start Points libdbi to the directory that contains its driver shared objects. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: DriverDirectory :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: Not documented Description ----------- Set this global option only when libdbi cannot find its drivers automatically. It tells libdbi where the driver modules are installed. Most systems ship libdbi-driver packages that register the directory properly. Only installations that place drivers in nonstandard paths need this parameter. Module usage ------------ .. _param-omlibdbi-module-driverdirectory-usage: .. _omlibdbi.parameter.module.driverdirectory-usage: .. code-block:: rsyslog module(load="omlibdbi" driverDirectory="/usr/lib/libdbi") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbidriverdirectory: - $ActionLibdbiDriverDirectory — maps to DriverDirectory (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiDriverDirectory single: $ActionLibdbiDriverDirectory See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dircreatemode.rst0000644000000000000000000000013215062756615025526 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.877668957 30 ctime=1764935922.276562694 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dircreatemode.rst0000664000175000017500000000342415062756615025175 0ustar00rgerrger.. _param-omfile-dircreatemode: .. _omfile.parameter.module.dircreatemode: dirCreateMode ============= .. index:: single: omfile; dirCreateMode single: dirCreateMode .. summary-start Sets the creation mode for directories that are automatically generated. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dirCreateMode :Scope: module, action :Type: string (octal) :Default: module=0700; action=inherits module :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the file system permissions for directories automatically created by ``omfile``. The value must be a 4-digit octal number (e.g., ``0700``). When set at the module level, it defines the default mode for all ``omfile`` actions. When set at the action level, it overrides the module default for that specific action. Please note that the actual permissions depend on rsyslogd's process umask. If in doubt, use ``$umask 0000`` at the beginning of the configuration file to remove any restrictions. Module usage ------------ .. _param-omfile-module-dircreatemode: .. _omfile.parameter.module.dircreatemode-usage: .. code-block:: rsyslog module(load="builtin:omfile" dirCreateMode="0700") Action usage ------------ .. _param-omfile-action-dircreatemode: .. _omfile.parameter.action.dircreatemode: .. code-block:: rsyslog action(type="omfile" dirCreateMode="0755" ...) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dircreatemode: - $DirCreateMode — maps to dirCreateMode (status: legacy) .. index:: single: omfile; $DirCreateMode single: $DirCreateMode See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-addmetadata.rst0000644000000000000000000000013215062756615025142 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.047490076 30 ctime=1764935921.374548885 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-addmetadata.rst0000664000175000017500000000223215062756615024605 0ustar00rgerrger.. _param-imfile-addmetadata: .. _imfile.parameter.input.addmetadata: .. _imfile.parameter.addmetadata: addMetadata =========== .. index:: single: imfile; addMetadata single: addMetadata .. summary-start Turns metadata addition on or off; enabled by default when wildcards are used. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: addMetadata :Scope: input :Type: boolean :Default: auto (on with wildcards) :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Used to control whether file metadata is added to the message object. By default it is enabled for ``input()`` statements that contain wildcards and disabled otherwise. This parameter overrides the default behavior. Input usage ----------- .. _param-imfile-input-addmetadata: .. _imfile.parameter.input.addmetadata-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" addMetadata="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-startmsg-regex.rst0000644000000000000000000000013215062756615025665 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.965487552 30 ctime=1764935921.438549865 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-startmsg-regex.rst0000664000175000017500000000233415062756615025333 0ustar00rgerrger.. _param-imfile-startmsg-regex: .. _imfile.parameter.input.startmsg-regex: .. _imfile.parameter.startmsg-regex: startmsg.regex ============== .. index:: single: imfile; startmsg.regex single: startmsg.regex .. summary-start Regex that marks the beginning of a new message for multiline processing. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: startmsg.regex :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: no :Introduced: 8.10.0 Description ----------- Permits the processing of multi-line messages. When set, a message is terminated when the next one begins and ``startmsg.regex`` matches the line that identifies the start of a message. It is more flexible than ``readMode`` but has lower performance. ``startmsg.regex``, ``endmsg.regex`` and ``readMode`` cannot all be defined for the same input. Input usage ----------- .. _param-imfile-input-startmsg-regex: .. _imfile.parameter.input.startmsg-regex-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" startmsg.regex="^start") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmcount-key.rst0000644000000000000000000000013215071746523023713 xustar0030 mtime=1760021843.805420466 30 atime=1764928597.466595114 30 ctime=1764935921.945557627 rsyslog-8.2512.0/doc/source/reference/parameters/mmcount-key.rst0000664000175000017500000000246415071746523023365 0ustar00rgerrger.. _param-mmcount-key: .. _mmcount.parameter.input.key: key === .. index:: single: mmcount; key single: key .. summary-start Names the JSON property whose values are counted on matching messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmcount`. :Name: key :Scope: input :Type: word :Default: none (count messages per severity) :Required?: no :Introduced: 7.5.0 Description ----------- Directs mmcount to evaluate a structured property on each message that matches :ref:`param-mmcount-appname`. The value should be the RainerScript variable name used to access the JSON property (e.g., ``!gf_code``). If the named property is absent, mmcount leaves the message unchanged and no counter is modified. When the property exists, its value is converted into a string (JSON ``null`` becomes an empty string) and used to select which counter to increment. Without :ref:`param-mmcount-value`, mmcount creates a distinct counter for every observed value and writes the running total for that value into the message's ``mmcount`` property. Input usage ----------- .. _param-mmcount-key-usage: .. _mmcount.parameter.input.key-usage: .. code-block:: rsyslog action(type="mmcount" appName="glusterd" key="!gf_code") See also -------- See also :doc:`../../configuration/modules/mmcount`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-injectdelaymode.rst0000644000000000000000000000013215114522477026031 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.452642096 30 ctime=1764935921.306547844 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-injectdelaymode.rst0000664000175000017500000000340215114522477025474 0ustar00rgerrger.. _param-imdiag-injectdelaymode: .. _imdiag.parameter.module.injectdelaymode: InjectDelayMode =============== .. index:: single: imdiag; InjectDelayMode single: InjectDelayMode .. summary-start Sets the flow-control classification applied to messages injected by imdiag. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: InjectDelayMode :Scope: module :Type: string (``no``, ``light``, ``full``) :Default: module=no :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The diagnostics interface can inject messages into rsyslog's queues on demand. :ref:`InjectDelayMode ` assigns the flow-control policy used for those messages: ``no`` Injected messages bypass delay throttling. ``light`` Injected messages are marked "light delayable" so that queue congestion slows them while preserving capacity for non-throttleable inputs. ``full`` Injected messages are fully delayable and subject to the strongest throttling when queues fill up. Use this setting to prevent diagnostics traffic from overwhelming production inputs when the main queue is near capacity. Module usage ------------ .. _param-imdiag-module-injectdelaymode: .. _imdiag.parameter.module.injectdelaymode-usage: .. code-block:: rsyslog module(load="imdiag" injectDelayMode="light") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiaginjectdelaymode: - $IMDiagInjectDelayMode — maps to InjectDelayMode (status: legacy) .. index:: single: imdiag; $IMDiagInjectDelayMode single: $IMDiagInjectDelayMode See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-multiline.rst0000644000000000000000000000013115062756615024741 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.565536758 29 ctime=1764935921.61655259 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-multiline.rst0000664000175000017500000000154215062756615024410 0ustar00rgerrger.. _param-imptcp-multiline: .. _imptcp.parameter.input.multiline: MultiLine ========= .. index:: single: imptcp; MultiLine single: MultiLine .. summary-start Detects a new message only when LF is followed by '<' or end of input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: MultiLine :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Experimental parameter which causes rsyslog to recognize a new message only if the line feed is followed by a '<' or if there are no more characters. Input usage ----------- .. _param-imptcp-input-multiline: .. _imptcp.parameter.input.multiline-usage: .. code-block:: rsyslog input(type="imptcp" multiLine="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-flowcontrol.rst0000644000000000000000000000013215062756615025656 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.017581346 30 ctime=1764935921.835555943 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-flowcontrol.rst0000664000175000017500000000224015062756615025320 0ustar00rgerrger.. _param-imuxsock-flowcontrol: .. _imuxsock.parameter.input.flowcontrol: FlowControl =========== .. index:: single: imuxsock; FlowControl single: FlowControl .. summary-start Enables flow control on this input's socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: FlowControl :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies if flow control should be applied to the input being defined. Input usage ----------- .. _param-imuxsock-input-flowcontrol: .. _imuxsock.parameter.input.flowcontrol-usage: .. code-block:: rsyslog input(type="imuxsock" flowControl="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketflowcontrol: - $InputUnixListenSocketFlowControl — maps to FlowControl (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketFlowControl single: $InputUnixListenSocketFlowControl See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-createdirs.rst0000644000000000000000000000013215062756615025044 xustar0030 mtime=1758190989.206641191 30 atime=1764928600.174678039 30 ctime=1764935922.272562633 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-createdirs.rst0000664000175000017500000000215615062756615024514 0ustar00rgerrger.. _param-omfile-createdirs: .. _omfile.parameter.module.createdirs: createDirs ========== .. index:: single: omfile; createDirs single: createDirs .. summary-start Create directories on an as-needed basis. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: createDirs :Scope: action :Type: boolean :Default: action=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Create directories on an as-needed basis Action usage ------------ .. _param-omfile-action-createdirs: .. _omfile.parameter.action.createdirs: .. code-block:: rsyslog action(type="omfile" createDirs="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.createdirs: - $CreateDirs — maps to createDirs (status: legacy) .. index:: single: omfile; $CreateDirs single: $CreateDirs See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdblookup-mmdbfile.rst0000644000000000000000000000013215071746523025371 xustar0030 mtime=1760021843.807420497 30 atime=1764928597.771604467 30 ctime=1764935921.973558056 rsyslog-8.2512.0/doc/source/reference/parameters/mmdblookup-mmdbfile.rst0000664000175000017500000000163715071746523025044 0ustar00rgerrger.. _param-mmdblookup-mmdbfile: .. _mmdblookup.parameter.input.mmdbfile: mmdbfile ======== .. index:: single: mmdblookup; mmdbfile single: mmdbfile .. summary-start Specifies the path to the MaxMind DB file used for lookups. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdblookup`. :Name: mmdbfile :Scope: input :Type: string (word) :Default: none :Required?: yes :Introduced: 8.24.0 Description ----------- This parameter specifies the full path to the MaxMind DB file (for example, ``/etc/rsyslog.d/GeoLite2-City.mmdb``) to be used for IP lookups. Input usage ----------- .. _mmdblookup.parameter.input.mmdbfile-usage: .. code-block:: rsyslog action(type="mmdblookup" key="!clientip" mmdbFile="/etc/rsyslog.d/GeoLite2-City.mmdb" fields=["!continent!code", "!location"]) See also -------- See also :doc:`../../configuration/modules/mmdblookup`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-tag.rst0000644000000000000000000000013215071746523023633 xustar0030 mtime=1760021843.801420402 30 atime=1764928597.232587939 30 ctime=1764935921.918557213 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-tag.rst0000664000175000017500000000134515071746523023302 0ustar00rgerrger.. _param-mmaitag-tag: .. _mmaitag.parameter.action.tag: tag === .. index:: single: mmaitag; tag single: tag .. summary-start Names the message variable used to store the classification tag. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: tag :Scope: action :Type: string :Default: .aitag :Required?: no :Introduced: 9.0.0 Description ----------- Message variable name for the classification. If the name starts with ``$``, the leading ``$`` is stripped. Action usage ------------- .. _param-mmaitag-action-tag: .. _mmaitag.parameter.action.tag-usage: .. code-block:: rsyslog action(type="mmaitag" tag="$.aitag") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-ratelimit-burst.rst0000644000000000000000000000013215103061376030116 xustar0030 mtime=1762419454.852381127 30 atime=1764928596.934578798 30 ctime=1764935921.877556586 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-ratelimit-burst.rst0000664000175000017500000000243015103061376027561 0ustar00rgerrger.. _param-imuxsock-syssock-ratelimit-burst: .. _imuxsock.parameter.module.syssock-ratelimit-burst: SysSock.RateLimit.Burst ======================= .. index:: single: imuxsock; SysSock.RateLimit.Burst single: SysSock.RateLimit.Burst .. summary-start Sets the rate-limiting burst size in messages for the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.RateLimit.Burst :Scope: module :Type: integer :Default: module=200 :Required?: no :Introduced: 5.7.1 Description ----------- Specifies the rate-limiting burst in number of messages. The maximum is ``(2^31)-1``. Module usage ------------ .. _param-imuxsock-module-syssock-ratelimit-burst: .. _imuxsock.parameter.module.syssock-ratelimit-burst-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.rateLimit.burst="100") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogratelimitburst: - $SystemLogRateLimitBurst — maps to SysSock.RateLimit.Burst (status: legacy) .. index:: single: imuxsock; $SystemLogRateLimitBurst single: $SystemLogRateLimitBurst See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imgssapi-inputgsslistenportfilename.rst0000644000000000000000000000013215114522477030754 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.453642121 30 ctime=1764935921.451550064 rsyslog-8.2512.0/doc/source/reference/parameters/imgssapi-inputgsslistenportfilename.rst0000664000175000017500000000271215114522477030422 0ustar00rgerrger.. _param-imgssapi-inputgsslistenportfilename: .. _imgssapi.parameter.input.inputgsslistenportfilename: InputGSSListenPortFileName ========================== .. index:: single: imgssapi; InputGSSListenPortFileName single: InputGSSListenPortFileName .. summary-start Writes the listener's bound port number to the specified file. .. summary-end This parameter applies to :doc:`../../configuration/modules/imgssapi`. :Name: InputGSSListenPortFileName :Scope: input :Type: word :Default: none :Required?: no :Introduced: 8.38.0 Description ----------- Specifies the path to a file where the listener will write its bound port number upon startup. This is useful for integration with other services or in test environments that use dynamic ports. .. note:: If this parameter is set, a port of ``0`` for ``InputGSSServerRun`` is accepted. Otherwise, a port of ``0`` defaults to ``514``. Input usage ----------- .. _imgssapi.parameter.input.inputgsslistenportfilename-usage: .. code-block:: rsyslog module(load="imgssapi") $inputGssListenPortFileName "/var/run/rsyslog-gss-port" Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imgssapi.parameter.legacy.inputgsslistenportfilename: - $inputGssListenPortFileName — maps to InputGSSListenPortFileName (status: legacy) .. index:: single: imgssapi; $inputGssListenPortFileName single: $inputGssListenPortFileName See also -------- See also :doc:`../../configuration/modules/imgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-unlink.rst0000644000000000000000000000013215062756615026302 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.967579811 30 ctime=1764935921.883556677 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-unlink.rst0000664000175000017500000000205515062756615025750 0ustar00rgerrger.. _param-imuxsock-syssock-unlink: .. _imuxsock.parameter.module.syssock-unlink: SysSock.Unlink ============== .. index:: single: imuxsock; SysSock.Unlink single: SysSock.Unlink .. summary-start Controls whether the system socket is unlinked and recreated on start and stop. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.Unlink :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 7.3.9 Description ----------- If turned on (default), the system socket is unlinked and re-created when opened and also unlinked when finally closed. Note that this setting has no effect when running under systemd control (because systemd handles the socket. See the :ref:`imuxsock-systemd-details-label` section for details. Module usage ------------ .. _param-imuxsock-module-syssock-unlink: .. _imuxsock.parameter.module.syssock-unlink-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.unlink="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-confirmmessages.rst0000644000000000000000000000013115062756615026133 xustar0030 mtime=1758190989.211641261 29 atime=1764928602.06073565 30 ctime=1764935922.532566614 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-confirmmessages.rst0000664000175000017500000000367415062756615025612 0ustar00rgerrger.. _param-omprog-confirmmessages: .. _omprog.parameter.action.confirmmessages: confirmMessages =============== .. index:: single: omprog; confirmMessages single: confirmMessages .. summary-start Waits for the program to acknowledge each message via stdout. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: confirmMessages :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.31.0 Description ----------- Specifies whether the external program provides feedback to rsyslog via stdout. When this switch is set to "on", rsyslog will wait for the program to confirm each received message. This feature facilitates error handling: instead of having to implement a retry logic, the external program can rely on the rsyslog queueing capabilities. To confirm a message, the program must write a line with the word ``OK`` to its standard output. If it writes a line containing anything else, rsyslog considers that the message could not be processed, keeps it in the action queue, and re-sends it to the program later (after the period specified by the :doc:`action.resumeInterval <../../configuration/actions>` parameter). In addition, when a new instance of the program is started, rsyslog will also wait for the program to confirm it is ready to start consuming logs. This prevents rsyslog from starting to send logs to a program that could not complete its initialization properly. .. seealso:: `Interface between rsyslog and external output plugins `_ Action usage ------------ .. _param-omprog-action-confirmmessages: .. _omprog.parameter.action.confirmmessages-usage: .. code-block:: rsyslog action(type="omprog" confirmMessages="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonrewrite-input.rst0000644000000000000000000000013015103346332025471 xustar0029 mtime=1762512090.62717594 29 atime=1764928598.03261247 30 ctime=1764935922.005558545 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonrewrite-input.rst0000664000175000017500000000236715103346332025147 0ustar00rgerrger.. _param-mmjsonrewrite-input: .. _mmjsonrewrite.parameter.input.input: input ===== .. index:: single: mmjsonrewrite; input single: input .. summary-start Names the JSON property that supplies the tree to rewrite. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonrewrite`. :Name: input :Scope: input :Type: string :Default: none :Required?: yes :Introduced: 8.2410.0 Description ----------- Specifies which message property contains the JSON object that will be normalized. The value must be a property reference that begins with ``$`` (for example ``$!raw`` or ``$.structured``). ``mmjsonrewrite`` validates the expression at load time and rejects other prefixes. If the property is absent at runtime, the action returns without altering the message. When the property exists but does not resolve to a JSON object, the module logs an error and the action fails without creating the output tree. Input usage ----------- .. _param-mmjsonrewrite-input-usage: .. _mmjsonrewrite.parameter.input.input-usage: .. code-block:: rsyslog action(type="mmjsonrewrite" input="$!raw" output="$!structured") See also -------- See also the :doc:`main mmjsonrewrite module documentation <../../configuration/modules/mmjsonrewrite>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-address.rst0000644000000000000000000000013215103346332024350 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.747480838 30 ctime=1764935921.346548456 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-address.rst0000664000175000017500000000147015103346332024016 0ustar00rgerrger.. _param-imdtls-address: .. _imdtls.parameter.input.address: Address ======= .. index:: single: imdtls; address single: address .. summary-start Listens for DTLS syslog messages on the specified local IP address. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: address :Scope: input :Type: word :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Specifies the IP address on which the imdtls module will listen for incoming syslog messages. By default the module listens on all available network connections. Input usage ----------- .. _imdtls.parameter.input.address-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" address="192.0.2.1") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-compress.rst0000644000000000000000000000013115114522477024604 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.476642685 30 ctime=1764935922.367564088 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-compress.rst0000664000175000017500000000173415114522477024256 0ustar00rgerrger.. _param-omhttp-compress: .. _omhttp.parameter.input.compress: compress ======== .. index:: single: omhttp; compress single: compress .. summary-start Enables GZIP compression of each HTTP payload sent by omhttp. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: compress :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- When switched to ``on`` each message will be compressed as GZIP using zlib's deflate compression algorithm. A ``Content-Encoding: gzip`` HTTP header is added to each request when this feature is used. Set the :ref:`param-omhttp-compress-level` for fine-grained control. Input usage ----------- .. _omhttp.parameter.input.compress-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" compress="on" compressLevel="6" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-ratelimit-interval.rst0000644000000000000000000000013215103061376026363 xustar0030 mtime=1762419454.851381097 30 atime=1764928596.784574193 30 ctime=1764935921.815555637 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-ratelimit-interval.rst0000664000175000017500000000161315103061376026030 0ustar00rgerrger.. _param-imudp-ratelimit-interval: .. _imudp.parameter.input.ratelimit-interval: RateLimit.Interval ================== .. index:: single: imudp; RateLimit.Interval single: RateLimit.Interval .. summary-start Rate-limiting interval in seconds; ``0`` disables throttling. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: RateLimit.Interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: 7.3.1 Description ----------- The rate-limiting interval in seconds. Value 0 turns off rate limiting. Set it to a number of seconds (5 recommended) to activate rate-limiting. Input usage ----------- .. _param-imudp-input-ratelimit-interval: .. _imudp.parameter.input.ratelimit-interval-usage: .. code-block:: rsyslog input(type="imudp" RateLimit.Interval="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-pollinginterval.rst0000644000000000000000000000013115062756615026451 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.645477697 29 ctime=1764935921.34154838 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-pollinginterval.rst0000664000175000017500000000161315062756615026117 0ustar00rgerrger.. _param-imdocker-pollinginterval: .. _imdocker.parameter.module.pollinginterval: PollingInterval =============== .. index:: single: imdocker; PollingInterval single: PollingInterval .. summary-start Seconds between ``List Containers`` polls for new containers; default ``60``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: PollingInterval :Scope: module :Type: integer :Default: module=60 :Required?: no :Introduced: 8.41.0 Description ----------- Specifies the polling interval in seconds. imdocker polls for new containers by calling the ``List containers`` Docker API. Module usage ------------ .. _param-imdocker-module-pollinginterval: .. _imdocker.parameter.module.pollinginterval-usage: .. code-block:: rsyslog module(load="imdocker" PollingInterval="...") See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-variable.rst0000644000000000000000000000013215071746523025560 xustar0030 mtime=1760021843.820420702 30 atime=1764928598.425624508 30 ctime=1764935922.076559632 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-variable.rst0000664000175000017500000000205615071746523025227 0ustar00rgerrger.. _param-mmnormalize-variable: .. _mmnormalize.parameter.action.variable: variable ======== .. index:: single: mmnormalize; variable single: variable .. summary-start Normalizes the content of a specified variable instead of the default ``msg`` property. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: variable :Scope: action :Type: word :Default: action=msg :Required?: no :Introduced: 8.5.1 Description ----------- .. versionadded:: 8.5.1 Specifies if a variable instead of property ``msg`` should be used for normalization. A variable can be property, local variable, json-path etc. Please note that :ref:`param-mmnormalize-userawmsg` overrides this parameter, so if it is set, ``variable`` will be ignored and raw message will be used. Action usage ------------- .. _param-mmnormalize-action-variable: .. _mmnormalize.parameter.action.variable-usage: .. code-block:: rsyslog action(type="mmnormalize" variable="$.foo") See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-resetcounters.rst0000644000000000000000000000013215114522477026210 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.460642292 30 ctime=1764935921.560551733 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-resetcounters.rst0000664000175000017500000000301215114522477025650 0ustar00rgerrger.. _param-impstats-resetcounters: .. _impstats.parameter.module.resetcounters: resetcounters ============= .. index:: single: impstats; resetcounters single: resetcounters .. summary-start Controls whether impstats resets counters after emitting them so they show deltas. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: resetcounters :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- When set to ``on``, counters are automatically reset after they are emitted. In that case, they contain only deltas to the last value emitted. When set to ``off``, counters always accumulate their values. Note that in auto-reset mode not all counters can be reset. Some counters (like queue size) are directly obtained from internal objects and cannot be modified. Also, auto-resetting introduces some additional slight inaccuracies due to the multi-threaded nature of rsyslog and the fact that for performance reasons it cannot serialize access to counter variables. As an alternative to auto-reset mode, you can use rsyslog's statistics manipulation scripts to create delta values from the regular statistic logs. This is the suggested method if deltas are not necessarily needed in real-time. Module usage ------------ .. _impstats.parameter.module.resetcounters-usage: .. code-block:: rsyslog module(load="impstats" resetCounters="on") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-filenamerulebase.rst0000644000000000000000000000013215071746523027445 xustar0030 mtime=1760021843.813420591 30 atime=1764928598.211617953 30 ctime=1764935922.040559081 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-filenamerulebase.rst0000664000175000017500000000205015071746523027106 0ustar00rgerrger.. _param-mmkubernetes-filenamerulebase: .. _mmkubernetes.parameter.action.filenamerulebase: filenamerulebase ================ .. index:: single: mmkubernetes; filenamerulebase single: filenamerulebase .. summary-start Specifies the rulebase file used to match json-file log filenames. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: filenamerulebase :Scope: action :Type: word :Default: /etc/rsyslog.d/k8s_filename.rulebase :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When processing json-file logs, this is the rulebase used to match the filename and extract metadata. For the actual rules, see :ref:`param-mmkubernetes-filenamerules`. Action usage ------------ .. _param-mmkubernetes-action-filenamerulebase: .. _mmkubernetes.parameter.action.filenamerulebase-usage: .. code-block:: rsyslog action(type="mmkubernetes" filenameRuleBase="/etc/rsyslog.d/k8s_filename.rulebase") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-readmode.rst0000644000000000000000000000013115062756615024470 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.982488075 29 ctime=1764935921.42454965 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-readmode.rst0000664000175000017500000000311715062756615024137 0ustar00rgerrger.. _param-imfile-readmode: .. _imfile.parameter.input.readmode: .. _imfile.parameter.readmode: readMode ======== .. index:: single: imfile; readMode single: readMode .. summary-start Selects a built-in method for detecting multi-line messages (0–2). .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: readMode :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Provides support for processing some standard types of multi-line messages. It is less flexible than ``startmsg.regex`` or ``endmsg.regex`` but offers higher performance. ``readMode``, ``startmsg.regex`` and ``endmsg.regex`` cannot all be defined for the same input. The value ranges from 0 to 2: - 0 – line based (**default**; each line is a new message) - 1 – paragraph (blank line separates log messages) - 2 – indented (lines starting with a space or tab belong to the previous message) Input usage ----------- .. _param-imfile-input-readmode: .. _imfile.parameter.input.readmode-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" readMode="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilereadmode: - ``$InputFileReadMode`` — maps to readMode (status: legacy) .. index:: single: imfile; $InputFileReadMode single: $InputFileReadMode See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-workaroundjournalbug.rst0000644000000000000000000000013215062756615027730 xustar0030 mtime=1758190989.187640921 30 atime=1764928594.662508996 30 ctime=1764935921.500550814 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-workaroundjournalbug.rst0000664000175000017500000000224615062756615027400 0ustar00rgerrger.. _param-imjournal-workaroundjournalbug: .. _imjournal.parameter.module.workaroundjournalbug: .. meta:: :tag: module:imjournal :tag: parameter:WorkAroundJournalBug WorkAroundJournalBug ==================== .. index:: single: imjournal; WorkAroundJournalBug single: WorkAroundJournalBug .. summary-start Legacy flag with no current effect; retained for compatibility. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: WorkAroundJournalBug :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.37.0 Description ----------- Originally enabled a workaround for a journald bug. The option has had no effect since version 8.1910.0 and remains only for backward compatibility. Module usage ------------ .. _param-imjournal-module-workaroundjournalbug: .. _imjournal.parameter.module.workaroundjournalbug-usage: .. code-block:: rsyslog module(load="imjournal" WorkAroundJournalBug="...") Notes ----- - Historic documentation called this a ``binary`` option; it is boolean. - Deprecated; enabling or disabling changes nothing. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-parsetrusted.rst0000644000000000000000000000013215062756615026033 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.098583829 30 ctime=1764935921.846556111 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-parsetrusted.rst0000664000175000017500000000222615062756615025501 0ustar00rgerrger.. _param-imuxsock-parsetrusted: .. _imuxsock.parameter.input.parsetrusted: ParseTrusted ============ .. index:: single: imuxsock; ParseTrusted single: ParseTrusted .. summary-start Turns annotation data into JSON fields when annotation is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: ParseTrusted :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Equivalent to the ``SysSock.ParseTrusted`` module parameter, but applies to the input that is being defined. Input usage ----------- .. _param-imuxsock-input-parsetrusted: .. _imuxsock.parameter.input.parsetrusted-usage: .. code-block:: rsyslog input(type="imuxsock" parseTrusted="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.parsetrusted: - $ParseTrusted — maps to ParseTrusted (status: legacy) .. index:: single: imuxsock; $ParseTrusted single: $ParseTrusted See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-defaulttz.rst0000644000000000000000000000013215062756615024564 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.816575176 30 ctime=1764935921.797555361 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-defaulttz.rst0000664000175000017500000000302415062756615024227 0ustar00rgerrger.. _param-imudp-defaulttz: .. _imudp.parameter.input.defaulttz: DefaultTZ ========= .. index:: single: imudp; DefaultTZ single: DefaultTZ .. summary-start Experimental default timezone applied when none present. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: DefaultTZ :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This is an **experimental** parameter; details may change at any time and it may also be discontinued without any early warning. Permits to set a default timezone for this listener. This is useful when working with legacy syslog (RFC3164 et al) residing in different timezones. If set it will be used as timezone for all messages **that do not contain timezone info**. Currently, the format **must** be ``+/-hh:mm``, e.g. ``-05:00``, ``+01:30``. Other formats, including TZ names (like EST) are NOT yet supported. Note that consequently no daylight saving settings are evaluated when working with timezones. If an invalid format is used, "interesting" things can happen, among them malformed timestamps and ``rsyslogd`` segfaults. This will obviously be changed at the time this feature becomes non-experimental. Input usage ----------- .. _param-imudp-input-defaulttz: .. _imudp.parameter.input.defaulttz-usage: .. code-block:: rsyslog input(type="imudp" DefaultTZ="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-tlscfgcmd.rst0000644000000000000000000000013215114522477025475 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.465642415 30 ctime=1764935921.693553769 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-tlscfgcmd.rst0000664000175000017500000000330615114522477025143 0ustar00rgerrger.. _param-imrelp-tls-tlscfgcmd: .. _imrelp.parameter.input.tls-tlscfgcmd: tls.tlsCfgCmd ============= .. index:: single: imrelp; tls.tlsCfgCmd single: tls.tlsCfgCmd .. summary-start Forwards SSL_CONF-style commands to OpenSSL when using the openssl backend. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.tlsCfgCmd :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: 8.2001.0 Description ----------- The setting can be used if :ref:`param-imrelp-tls-tlslib` is set to "openssl" to pass configuration commands to the openssl library. OpenSSL Version 1.0.2 or higher is required for this feature. A list of possible commands and their valid values can be found in the `OpenSSL documentation `_. The setting can be single or multiline, each configuration command is separated by linefeed (\n). Command and value are separated by equal sign (=). Here are a few samples: Example 1 --------- This will allow all protocols except for SSLv2 and SSLv3: .. code-block:: none tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3" Example 2 --------- This will allow all protocols except for SSLv2, SSLv3 and TLSv1. It will also set the minimum protocol to TLSv1.2. .. code-block:: none tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1 MinProtocol=TLSv1.2" Input usage ----------- .. _param-imrelp-input-tls-tlscfgcmd-usage: .. _imrelp.parameter.input.tls-tlscfgcmd-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.tlsLib="openssl" tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-azureport.rst0000644000000000000000000000013215114522477027100 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.467642464 30 ctime=1764935922.113560199 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-azureport.rst0000664000175000017500000000227515114522477026552 0ustar00rgerrger.. _param-omazureeventhubs-azureport: .. _omazureeventhubs.parameter.input.azureport: azureport ========= .. index:: single: omazureeventhubs; azureport single: azureport .. summary-start Defines the TCP port used when connecting to the Event Hubs namespace. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: azureport :Scope: input :Type: word :Default: input=5671 :Required?: no :Introduced: v8.2304 Description ----------- Specifies the TCP port number used by the Event Hubs instance for incoming connections. The default port number for Event Hubs is 5671 for connections over the AMQP Secure Sockets Layer (SSL) protocol. This property is usually optional in the configuration file of the rsyslog output plugin, as the default value of 5671 is typically used. When ``amqpAddress`` is specified, the module ignores ``azurePort`` and always uses the default. Input usage ----------- .. _omazureeventhubs.parameter.input.azureport-usage: .. code-block:: rsyslog action(type="omazureeventhubs" azureHost="example.servicebus.windows.net" azurePort="5671" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-compression-zstd-workers.rst0000644000000000000000000000013215062756615027734 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.974671925 30 ctime=1764935922.269562587 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-compression-zstd-workers.rst0000664000175000017500000000304615062756615027403 0ustar00rgerrger.. _param-omfile-compression-zstd-workers: .. _omfile.parameter.module.compression-zstd-workers: compression.zstd.workers ======================== .. index:: single: omfile; compression.zstd.workers single: compression.zstd.workers .. summary-start In zstd mode, this enables to configure zstd-internal compression worker threads. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: compression.zstd.workers :Scope: module :Type: positive-integer :Default: module=zlib library default :Required?: no :Introduced: 8.2208.0 Description ----------- In zstd mode, this enables to configure zstd-internal compression worker threads. This setting has nothing to do with rsyslog workers. The zstd library provides an enhanced worker thread pool which permits multithreaed compression of serial data streams. Rsyslog fully supports this mode for optimal performance. Please note that for this parameter to have an effect, the zstd library must be compiled with multithreading support. As of this writing (2022), this is **not** the case for many frequently used distros and distro versions. In this case, you may want to custom install the zstd library with threading enabled. Note that this does not require a rsyslog rebuild. Module usage ------------ .. _param-omfile-module-compression-zstd-workers: .. _omfile.parameter.module.compression-zstd-workers-usage: .. code-block:: rsyslog module(load="builtin:omfile" compression.zstd.workers="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-filegroupnum.rst0000644000000000000000000000013215062756615025433 xustar0030 mtime=1758190989.207641205 30 atime=1764928599.918670212 30 ctime=1764935922.304563123 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-filegroupnum.rst0000664000175000017500000000311615062756615025100 0ustar00rgerrger.. _param-omfile-filegroupnum: .. _omfile.parameter.module.filegroupnum: fileGroupNum ============ .. index:: single: omfile; fileGroupNum single: fileGroupNum .. summary-start Set the group for files newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: fileGroupNum :Scope: module, action :Type: integer :Default: module=process user's primary group; action=system default :Required?: no :Introduced: 7.5.8 Description ----------- Set the group for files newly created. Please note that this setting does not affect the group of files already existing. The parameter is a numerical ID, which is used regardless of whether the group actually exists. This can be useful if the group mapping is not available to rsyslog during startup. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-filegroupnum: .. _omfile.parameter.module.filegroupnum-usage: .. code-block:: rsyslog module(load="builtin:omfile" fileGroupNum="...") Action usage ------------ .. _param-omfile-action-filegroupnum: .. _omfile.parameter.action.filegroupnum: .. code-block:: rsyslog action(type="omfile" fileGroupNum="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.filegroupnum: - $FileGroupNum — maps to fileGroupNum (status: legacy) .. index:: single: omfile; $FileGroupNum single: $FileGroupNum See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-ratelimit-interval.rst0000644000000000000000000000013215103061376026361 xustar0030 mtime=1762419454.851381097 30 atime=1764928596.317559857 30 ctime=1764935921.752554672 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-ratelimit-interval.rst0000664000175000017500000000166415103061376026034 0ustar00rgerrger.. _param-imtcp-ratelimit-interval: .. _imtcp.parameter.input.ratelimit-interval: RateLimit.Interval ================== .. index:: single: imtcp; RateLimit.Interval single: RateLimit.Interval .. summary-start Sets the rate-limiting interval in seconds. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: RateLimit.Interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the rate-limiting interval in seconds. Default value is ``0``, which turns off rate limiting. Set it to a number of seconds (``5`` recommended) to activate rate limiting. Input usage ----------- .. _param-imtcp-input-ratelimit-interval: .. _imtcp.parameter.input.ratelimit-interval-usage: .. code-block:: rsyslog input(type="imtcp" rateLimit.Interval="5") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ruleset.rst0000644000000000000000000000013115062756615024770 xustar0030 mtime=1758190989.196641049 29 atime=1764928596.99458064 30 ctime=1764935921.856556264 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ruleset.rst0000664000175000017500000000142215062756615024434 0ustar00rgerrger.. _param-imuxsock-ruleset: .. _imuxsock.parameter.input.ruleset: Ruleset ======= .. index:: single: imuxsock; Ruleset single: Ruleset .. summary-start Binds a specified ruleset to the input instead of the default ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: Ruleset :Scope: input :Type: string :Default: input=default ruleset :Required?: no :Introduced: 8.17.0 Description ----------- Binds specified ruleset to this input. If not set, the default ruleset is bound. Input usage ----------- .. _param-imuxsock-input-ruleset: .. _imuxsock.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imuxsock" ruleset="myRuleset") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-iobuffersize.rst0000644000000000000000000000013115062756615025412 xustar0030 mtime=1758190989.208641219 29 atime=1764928600.13967697 30 ctime=1764935922.316563307 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-iobuffersize.rst0000664000175000017500000000244215062756615025061 0ustar00rgerrger.. _param-omfile-iobuffersize: .. _omfile.parameter.module.iobuffersize: ioBufferSize ============ .. index:: single: omfile; ioBufferSize single: ioBufferSize .. summary-start Size of the buffer used to writing output data. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: ioBufferSize :Scope: action :Type: size :Default: action=4 KiB :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Size of the buffer used to writing output data. The larger the buffer, the potentially better performance is. The default of 4k is quite conservative, it is useful to go up to 64k, and 128k if you used gzip compression (then, even higher sizes may make sense) Action usage ------------ .. _param-omfile-action-iobuffersize: .. _omfile.parameter.action.iobuffersize: .. code-block:: rsyslog action(type="omfile" ioBufferSize="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.omfileiobuffersize: - $OMFileIOBufferSize — maps to ioBufferSize (status: legacy) .. index:: single: omfile; $OMFileIOBufferSize single: $OMFileIOBufferSize See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-timeout.rst0000644000000000000000000000013215062756615026300 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.594660298 30 ctime=1764935922.244562204 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-timeout.rst0000664000175000017500000000154015062756615025744 0ustar00rgerrger.. _param-omelasticsearch-timeout: .. _omelasticsearch.parameter.module.timeout: timeout ======= .. index:: single: omelasticsearch; timeout single: timeout .. summary-start How long Elasticsearch waits for a primary shard before failing. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: timeout :Scope: action :Type: word :Default: action=1m :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Controls the `timeout` query parameter for index operations. Example values use time units such as `1m`. Action usage ------------ .. _param-omelasticsearch-action-timeout: .. _omelasticsearch.parameter.action.timeout: .. code-block:: rsyslog action(type="omelasticsearch" timeout="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-remote.rst0000644000000000000000000000013215062756615024737 xustar0030 mtime=1758190989.187640921 30 atime=1764928594.672509304 30 ctime=1764935921.490550661 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-remote.rst0000664000175000017500000000166515062756615024413 0ustar00rgerrger.. _param-imjournal-remote: .. _imjournal.parameter.module.remote: .. meta:: :tag: module:imjournal :tag: parameter:Remote Remote ====== .. index:: single: imjournal; Remote single: Remote .. summary-start Also read journal files from remote sources. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: Remote :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.1910.0 Description ----------- When enabled, the module processes not only local journal files but also those originating from remote systems stored on the host. Module usage ------------ .. _param-imjournal-module-remote: .. _imjournal.parameter.module.remote-usage: .. code-block:: rsyslog module(load="imjournal" Remote="...") Notes ----- - Historic documentation called this a ``binary`` option; it is boolean. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-processonpoller.rst0000644000000000000000000000013115062756615026170 xustar0030 mtime=1758190989.191640978 29 atime=1764928595.32252929 30 ctime=1764935921.630552804 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-processonpoller.rst0000664000175000017500000000250615062756615025640 0ustar00rgerrger.. _param-imptcp-processonpoller: .. _imptcp.parameter.module.processonpoller: ProcessOnPoller =============== .. index:: single: imptcp; ProcessOnPoller single: ProcessOnPoller .. summary-start Processes messages on the poller thread when feasible to reduce resource use. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: ProcessOnPoller :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Instructs imptcp to process messages on poller thread opportunistically. This leads to lower resource footprint (as poller thread doubles up as message-processing thread too). "On" works best when imptcp is handling low ingestion rates. At high throughput though, it causes polling delay (as poller spends time processing messages, which keeps connections in read-ready state longer than they need to be, filling socket-buffer, hence eventually applying backpressure). It defaults to allowing messages to be processed on poller (for backward compatibility). Module usage ------------ .. _param-imptcp-module-processonpoller: .. _imptcp.parameter.module.processonpoller-usage: .. code-block:: rsyslog module(load="imptcp" processOnPoller="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-de-dot.rst0000644000000000000000000000013215071746523025316 xustar0030 mtime=1760021843.813420591 30 atime=1764928598.187617218 30 ctime=1764935922.035559005 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-de-dot.rst0000664000175000017500000000163415071746523024766 0ustar00rgerrger.. _param-mmkubernetes-de-dot: .. _mmkubernetes.parameter.action.de-dot: de_dot ====== .. index:: single: mmkubernetes; de_dot single: de_dot .. summary-start Replaces dots in annotation and label keys. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: de_dot :Scope: action :Type: boolean :Default: on :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When processing labels and annotations, if this parameter is set to `"on"`, the key strings will have their `.` characters replaced with the string specified by the :ref:`param-mmkubernetes-de-dot-separator` parameter. Action usage ------------ .. _param-mmkubernetes-action-de-dot: .. _mmkubernetes.parameter.action.de-dot-usage: .. code-block:: rsyslog action(type="mmkubernetes" deDot="on") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-tlsverifydepth.rst0000644000000000000000000000013215062756615030341 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.204556388 30 ctime=1764935921.785555177 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-tlsverifydepth.rst0000664000175000017500000000322515062756615030007 0ustar00rgerrger.. _param-imtcp-streamdriver-tlsverifydepth: .. _imtcp.parameter.module.streamdriver-tlsverifydepth: .. _imtcp.parameter.input.streamdriver-tlsverifydepth: StreamDriver.TlsVerifyDepth =========================== .. index:: single: imtcp; StreamDriver.TlsVerifyDepth single: StreamDriver.TlsVerifyDepth .. summary-start Specifies the maximum depth allowed for certificate chain verification. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.TlsVerifyDepth :Scope: module, input :Type: integer :Default: module=TLS library default, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the allowed maximum depth for the certificate chain verification. Support added in v8.2001.0, supported by GTLS and OpenSSL driver. If not set, the API default will be used. For OpenSSL, the default is 100 - see the doc for more: https://docs.openssl.org/1.1.1/man3/SSL_CTX_set_verify/ For GnuTLS, the default is 5 - see the doc for more: https://www.gnutls.org/manual/gnutls.html The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-tlsverifydepth: .. _imtcp.parameter.module.streamdriver-tlsverifydepth-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.tlsVerifyDepth="7") Input usage ----------- .. _param-imtcp-input-streamdriver-tlsverifydepth: .. _imtcp.parameter.input.streamdriver-tlsverifydepth-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.tlsVerifyDepth="7") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-version.rst0000644000000000000000000000013115071746523024436 xustar0029 mtime=1760021843.83042086 30 atime=1764928602.737756299 30 ctime=1764935922.592567532 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-version.rst0000664000175000017500000000220115071746523024076 0ustar00rgerrger.. _param-omsnmp-version: .. _omsnmp.parameter.module.version: Version ======= .. index:: single: omsnmp; Version single: Version .. summary-start Chooses whether SNMPv1 or SNMPv2c traps are sent. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Version :Scope: module :Type: integer :Default: module=1 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- There can only be two choices for this parameter for now. 0 means SNMPv1 will be used. 1 means SNMPv2c will be used. Any other value will default to 1. Module usage ------------ .. _param-omsnmp-module-version: .. _omsnmp.parameter.module.version-usage: .. code-block:: rsyslog action(type="omsnmp" version="1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmpversion: - $actionsnmpversion — maps to Version (status: legacy) .. index:: single: omsnmp; $actionsnmpversion single: $actionsnmpversion See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-framing-delimiter-regex.rst0000644000000000000000000000013115062756615027446 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.573537004 30 ctime=1764935921.594552253 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-framing-delimiter-regex.rst0000664000175000017500000000317715062756615027123 0ustar00rgerrger.. _param-imptcp-framing-delimiter-regex: .. _imptcp.parameter.input.framing-delimiter-regex: framing.delimiter.regex ======================= .. index:: single: imptcp; framing.delimiter.regex single: framing.delimiter.regex .. summary-start Uses a regular expression to identify the start of the next message. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: framing.delimiter.regex :Scope: input :Type: string :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Experimental parameter. It is similar to "MultiLine", but provides greater control of when a log message ends. You can specify a regular expression that characterizes the header to expect at the start of the next message. As such, it indicates the end of the current message. For example, one can use this setting to use an RFC3164 header as frame delimiter:: framing.delimiter.regex="^<[0-9]{1,3}>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)" Note that when oversize messages arrive this mode may have problems finding the proper frame terminator. There are some provisions inside imptcp to make these kinds of problems unlikely, but if the messages are very much over the configured MaxMessageSize, imptcp emits an error messages. Chances are great it will properly recover from such a situation. Input usage ----------- .. _param-imptcp-input-framing-delimiter-regex: .. _imptcp.parameter.input.framing-delimiter-regex-usage: .. code-block:: rsyslog input(type="imptcp" framing.delimiter.regex="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-maxbytes.rst0000644000000000000000000000013115114522477025757 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.469642513 29 ctime=1764935922.13456052 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-maxbytes.rst0000664000175000017500000000203515114522477025424 0ustar00rgerrger.. _param-omclickhouse-maxbytes: .. _omclickhouse.parameter.input.maxbytes: maxBytes ======== .. index:: single: omclickhouse; maxBytes single: maxBytes single: omclickhouse; maxbytes single: maxbytes .. summary-start Limits the maximum size of a bulk HTTP request when ``bulkMode`` is enabled. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: maxBytes :Scope: input :Type: size :Default: 104857600/100mb :Required?: no :Introduced: not specified Description ----------- When shipping logs with ``bulkMode`` **on**, ``maxBytes`` specifies the maximum size of the request body sent to ClickHouse. Logs are batched until either the buffer reaches ``maxBytes`` or the `dequeue batch size `_ is reached. Input usage ----------- .. _omclickhouse.parameter.input.maxbytes-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" maxBytes="64mb") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-tag.rst0000644000000000000000000000013215062756615023464 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.949487059 30 ctime=1764935921.445549972 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-tag.rst0000664000175000017500000000230315062756615023126 0ustar00rgerrger.. _param-imfile-tag: .. _imfile.parameter.input.tag: .. _imfile.parameter.tag: Tag === .. index:: single: imfile; Tag single: Tag .. summary-start Assigns a tag to messages read from the file; include a colon if desired. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: Tag :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- The tag to be assigned to messages read from this file. If a colon should follow the tag, include it in the value, for example ``Tag="myTag:"``. Input usage ----------- .. _param-imfile-input-tag: .. _imfile.parameter.input.tag-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="app:") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfiletag: - ``$InputFileTag`` — maps to Tag (status: legacy) .. index:: single: imfile; $InputFileTag single: $InputFileTag See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-user.rst0000644000000000000000000000013215114522477025102 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.470642538 30 ctime=1764935922.152560796 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-user.rst0000664000175000017500000000137015114522477024547 0ustar00rgerrger.. _param-omclickhouse-user: .. _omclickhouse.parameter.input.user: user ==== .. index:: single: omclickhouse; user single: user .. summary-start Sets the username for HTTP basic authentication against ClickHouse. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: user :Scope: input :Type: word :Default: none :Required?: no :Introduced: not specified Description ----------- If you have basic HTTP authentication deployed you can specify your user-name here. Input usage ----------- .. _omclickhouse.parameter.input.user-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" user="ingest") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmutf8fix-replacementchar.rst0000644000000000000000000000013115071746523026524 xustar0030 mtime=1760021843.823420749 30 atime=1764928598.954640712 29 ctime=1764935922.10256003 rsyslog-8.2512.0/doc/source/reference/parameters/mmutf8fix-replacementchar.rst0000664000175000017500000000170115071746523026170 0ustar00rgerrger.. _param-mmutf8fix-replacementchar: .. _mmutf8fix.parameter.input.replacementchar: replacementChar =============== .. index:: single: mmutf8fix; replacementChar single: replacementChar .. summary-start Defines the printable character used to substitute invalid sequences. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmutf8fix`. :Name: replacementChar :Scope: input :Type: string :Default: " " :Required?: no :Introduced: 7.5.4 Description ----------- This is the character that invalid sequences are replaced by. It is strongly recommended to use a printable US-ASCII character. Note that only the first byte of the provided string is used without validation. Input usage ----------- .. _mmutf8fix.parameter.input.replacementchar-usage: .. code-block:: rsyslog module(load="mmutf8fix") action(type="mmutf8fix" replacementChar="#") See also -------- See also :doc:`../../configuration/modules/mmutf8fix`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-addlf.rst0000644000000000000000000000013215071746523023766 xustar0030 mtime=1760021843.823420749 30 atime=1764928599.869668712 30 ctime=1764935922.260562449 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-addlf.rst0000664000175000017500000000477115071746523023443 0ustar00rgerrger.. _param-omfile-addlf: .. _omfile.parameter.module.addlf: addLF ===== .. index:: single: omfile; addLF single: addLF .. summary-start Appends an LF if a rendered message does not already end with one, ensuring full-line records. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: addLF :Scope: module, action :Type: boolean :Default: module=on; action=inherits module :Required?: no :Introduced: 8.2510.0 Description ----------- When enabled, the omfile action checks whether a rendered message already ends with an LF (line feed). If not, omfile appends one before writing, so that every record is a complete line regardless of the template used. In text-based logging, a line feed (LF) marks the end of a record. Without it, the record may appear as an incomplete line when viewed with standard tools such as ``cat`` or ``tail -f``. The extra byte is added transparently even when compression or cryptographic providers are active. If set at the module level, the value becomes the default for all omfile actions that do not explicitly define ``addLF``. Notes on default behavior ------------------------- Since **8.2510.0**, the default has been changed to ``on``. In earlier releases, messages without a trailing LF were written as incomplete lines. With the new default, rsyslog ensures that all records end with a line feed. This change aligns with common user expectations—especially when writing JSON logs, where line-separated records are the norm. If incomplete lines are desired, you can disable the feature either globally at the module level or for individual actions. Module usage ------------ .. _param-omfile-module-addlf: .. _omfile.parameter.module.addlf-usage: To override the default globally and allow incomplete lines, disable ``addLF`` at the module level: .. code-block:: rsyslog module(load="builtin:omfile" addLF="off") Action usage ------------ .. _param-omfile-action-addlf: .. _omfile.parameter.action.addlf: By default, actions inherit the module setting. No explicit parameter is needed: .. code-block:: rsyslog action(type="omfile" file="/var/log/messages") In rare cases, you may want to allow incomplete lines only for one action. You can disable ``addLF`` explicitly at the action level: .. code-block:: rsyslog action(type="omfile" file="/var/log/raw.log" addLF="off") See also -------- - :doc:`../../configuration/modules/omfile` .. meta:: :keywords: rsyslog, omfile, addLF, line termination, json logging, full line records rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-defaultseverity.rst0000644000000000000000000000013115062756615026457 xustar0030 mtime=1758190989.183640865 29 atime=1764928593.68747899 30 ctime=1764935921.330548211 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-defaultseverity.rst0000664000175000017500000000210215062756615026117 0ustar00rgerrger.. _param-imdocker-defaultseverity: .. _imdocker.parameter.module.defaultseverity: DefaultSeverity =============== .. index:: single: imdocker; DefaultSeverity single: DefaultSeverity .. summary-start Syslog severity assigned to received messages; default ``info``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: DefaultSeverity :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=info :Required?: no :Introduced: 8.41.0 Description ----------- The syslog severity to be assigned to log messages. Textual names such as ``info`` are suggested, though numeric values are also accepted. Module usage ------------ .. _param-imdocker-module-defaultseverity: .. _imdocker.parameter.module.defaultseverity-usage: .. code-block:: rsyslog module(load="imdocker" DefaultSeverity="...") Notes ----- - Numeric severity values are accepted but textual names are recommended. - See https://en.wikipedia.org/wiki/Syslog. See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-tls-cacert.rst0000644000000000000000000000013115114522477025001 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.472642587 30 ctime=1764935922.165560995 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-tls-cacert.rst0000664000175000017500000000172715114522477024455 0ustar00rgerrger.. _param-omdtls-tls-cacert: .. _omdtls.parameter.input.tls-cacert: tls.cacert ========== .. index:: single: omdtls; tls.cacert single: tls.cacert .. summary-start Defines the CA certificate used to verify client certificates. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: tls.cacert :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- The CA certificate that is being used to verify the client certificates. This parameter is required when :ref:`tls.authmode ` is set to ``fingerprint``, ``name``, or ``certvalid``. Input usage ----------- .. _omdtls.parameter.input.tls-cacert-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" tls.authMode="certvalid" tls.caCert="/etc/rsyslog/ca.pem") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-errorfile.rst0000644000000000000000000000013215062756615026603 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.676662807 30 ctime=1764935922.197561485 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-errorfile.rst0000664000175000017500000000155115062756615026251 0ustar00rgerrger.. _param-omelasticsearch-errorfile: .. _omelasticsearch.parameter.module.errorfile: errorFile ========= .. index:: single: omelasticsearch; errorFile single: errorFile .. summary-start File that receives records rejected during bulk mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: errorFile :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Failed bulk records are appended to this file with error details for later inspection or resubmission. Action usage ------------ .. _param-omelasticsearch-action-errorfile: .. _omelasticsearch.parameter.action.errorfile: .. code-block:: rsyslog action(type="omelasticsearch" errorFile="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-usespecialparser.rst0000644000000000000000000000013115062756615026657 xustar0030 mtime=1758190989.197641063 29 atime=1764928597.11458432 30 ctime=1764935921.899556922 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-usespecialparser.rst0000664000175000017500000000167515062756615026335 0ustar00rgerrger.. _param-imuxsock-usespecialparser: .. _imuxsock.parameter.input.usespecialparser: UseSpecialParser ================ .. index:: single: imuxsock; UseSpecialParser single: UseSpecialParser .. summary-start Selects the special parser tailored for default UNIX socket format. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: UseSpecialParser :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 8.9.0 Description ----------- Equivalent to the ``SysSock.UseSpecialParser`` module parameter, but applies to the input that is being defined. .. versionadded:: 8.9.0 The setting was previously hard-coded "on" Input usage ----------- .. _param-imuxsock-input-usespecialparser: .. _imuxsock.parameter.input.usespecialparser-usage: .. code-block:: rsyslog input(type="imuxsock" useSpecialParser="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-rulebase.rst0000644000000000000000000000013215071746523025575 xustar0030 mtime=1760021843.820420702 30 atime=1764928598.405623896 30 ctime=1764935922.072559571 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-rulebase.rst0000664000175000017500000000270715071746523025247 0ustar00rgerrger.. _param-mmnormalize-rulebase: .. _mmnormalize.parameter.action.rulebase: ruleBase ======== .. index:: single: mmnormalize; ruleBase single: ruleBase .. summary-start Sets the rulebase file used for normalization. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: ruleBase :Scope: action :Type: word :Default: none :Required?: yes :Introduced: at least 6.1.2, possibly earlier Description ----------- Specifies which rulebase file is to use. If there are multiple mmnormalize instances, each one can use a different file. However, a single instance can use only a single file. This parameter or :ref:`param-mmnormalize-rule` MUST be given, because normalization can only happen based on a rulebase. It is recommended that an be found in the `liblognorm manual `_. Action usage ------------- .. _param-mmnormalize-action-rulebase: .. _mmnormalize.parameter.action.rulebase-usage: .. code-block:: rsyslog action(type="mmnormalize" ruleBase="/path/to/rulebase.rb") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmnormalize.parameter.legacy.mmnormalizerulebase: - $mmnormalizeRuleBase — maps to ruleBase (status: legacy) .. index:: single: mmnormalize; $mmnormalizeRuleBase single: $mmnormalizeRuleBase See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-address.rst0000644000000000000000000000013215062756615024365 xustar0030 mtime=1758190989.187640921 30 atime=1764928595.453533316 30 ctime=1764935921.567551839 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-address.rst0000664000175000017500000000212415062756615024030 0ustar00rgerrger.. _param-imptcp-address: .. _imptcp.parameter.input.address: Address ======= .. index:: single: imptcp; Address single: Address .. summary-start Specifies the local address to bind the listener to. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Address :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- On multi-homed machines, specifies to which local address the listener should be bound. Input usage ----------- .. _param-imptcp-input-address: .. _imptcp.parameter.input.address-usage: .. code-block:: rsyslog input(type="imptcp" address="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverlistenip: - $InputPTCPServerListenIP — maps to Address (status: legacy) .. index:: single: imptcp; $InputPTCPServerListenIP single: $InputPTCPServerListenIP See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-token.rst0000644000000000000000000000013115071746523025261 xustar0029 mtime=1760021843.81842067 30 atime=1764928598.285620219 30 ctime=1764935922.061559403 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-token.rst0000664000175000017500000000163715071746523024735 0ustar00rgerrger.. _param-mmkubernetes-token: .. _mmkubernetes.parameter.action.token: token ===== .. index:: single: mmkubernetes; token single: token .. summary-start Specifies the authentication token string. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: token :Scope: action :Type: word :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- The token to use to authenticate to the Kubernetes API server. One of `token` or :ref:`param-mmkubernetes-tokenfile` is required if Kubernetes is configured with access control. Example: `UxMU46ptoEWOSqLNa1bFmH` Action usage ------------ .. _param-mmkubernetes-action-token: .. _mmkubernetes.parameter.action.token-usage: .. code-block:: rsyslog action(type="mmkubernetes" token="UxMU46ptoEWOSqLNa1bFmH") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-container.rst0000644000000000000000000000013215071746523025761 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.974610692 30 ctime=1764935921.994558377 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-container.rst0000664000175000017500000000225115071746523025425 0ustar00rgerrger.. _param-mmjsonparse-container: .. _mmjsonparse.parameter.input.container: container ========= .. index:: single: mmjsonparse; container single: container single: JSON container .. summary-start Sets the JSON container path where parsed properties are stored. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: container :Scope: input :Type: string :Default: $! :Required?: no :Introduced: 6.6.0 Description ----------- Specifies the JSON container (path) under which parsed elements should be placed. By default (``$!``), all parsed properties are merged into the root of the message properties. You can specify a different container: * To place data in a subtree of message properties, for example ``container="$!json"``. * To use a local variable, for example ``container="$.parses"``. * To use a global variable, for example ``container="$/parses"``. Input usage ----------- .. _mmjsonparse.parameter.input.container-usage: .. code-block:: rsyslog action(type="mmjsonparse" container="$.parses") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-reloadonhup.rst0000644000000000000000000000013215114522477025272 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.479642759 30 ctime=1764935922.402564623 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-reloadonhup.rst0000664000175000017500000000171515114522477024742 0ustar00rgerrger.. _param-omhttp-reloadonhup: .. _omhttp.parameter.input.reloadonhup: reloadonhup =========== .. index:: single: omhttp; reloadonhup single: reloadonhup .. summary-start Reinitializes libcurl handles on ``HUP`` signals so certificates can be refreshed without restarting rsyslog. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: reloadonhup :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- If this parameter is ``on``, the plugin will close and reopen any libcurl handles on a HUP signal. This option is primarily intended to enable reloading short-lived certificates without restarting rsyslog. Input usage ----------- .. _omhttp.parameter.input.reloadonhup-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" reloadOnHup="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-detect-headerless.rst0000644000000000000000000000013115062756615026455 xustar0029 mtime=1758190989.21364129 30 atime=1764928603.299773431 30 ctime=1764935922.606567747 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-detect-headerless.rst0000664000175000017500000000250315062756615026122 0ustar00rgerrger.. _param-pmrfc3164-detect-headerless: .. _pmrfc3164.parameter.module.detect-headerless: .. _pmrfc3164.parameter.module.detect.headerless: detect.headerless ================= .. index:: single: pmrfc3164; detect.headerless single: detect.headerless .. summary-start Enable detection of messages lacking standard syslog headers. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: detect.headerless :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.2508.0 Description ----------- When enabled, rsyslog applies extra heuristics to classify messages without a syslog header. A message is considered headerless only if: - It has no PRI header (facility/severity). - It does not start with an accepted timestamp. - It does not begin with whitespace followed by ``{`` or ``[``. Messages starting with ``{`` or ``[`` are treated as structured data (e.g., JSON) instead. Module usage ------------ .. _param-pmrfc3164-module-detect-headerless: .. _pmrfc3164.parameter.module.detect-headerless-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" detect.headerless="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-ratelimit-interval.rst0000644000000000000000000000013215103061376026541 xustar0030 mtime=1762419454.851381097 30 atime=1764928595.528535621 30 ctime=1764935921.634552865 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-ratelimit-interval.rst0000664000175000017500000000161015103061376026203 0ustar00rgerrger.. _param-imptcp-ratelimit-interval: .. _imptcp.parameter.input.ratelimit-interval: RateLimit.Interval ================== .. index:: single: imptcp; RateLimit.Interval single: RateLimit.Interval .. summary-start Specifies the rate-limiting interval in seconds. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: RateLimit.Interval :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the rate-limiting interval in seconds. Set it to a number of seconds (5 recommended) to activate rate-limiting. Input usage ----------- .. _param-imptcp-input-ratelimit-interval: .. _imptcp.parameter.input.ratelimit-interval-usage: .. code-block:: rsyslog input(type="imptcp" rateLimit.interval="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-rcvbufsize.rst0000644000000000000000000000013215062756615024744 xustar0030 mtime=1758190989.195641035 30 atime=1764928596.824575421 30 ctime=1764935921.817555667 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-rcvbufsize.rst0000664000175000017500000000314415062756615024412 0ustar00rgerrger.. _param-imudp-rcvbufsize: .. _imudp.parameter.input.rcvbufsize: RcvBufSize ========== .. index:: single: imudp; RcvBufSize single: RcvBufSize .. summary-start Requests specific socket receive buffer size; disables auto-tuning. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: RcvBufSize :Scope: input :Type: size :Default: input=0 :Required?: no :Introduced: 7.3.9 Description ----------- This requests a socket receive buffer of specific size from the operating system. It is an expert parameter, which should only be changed for a good reason. Note that setting this parameter disables Linux auto-tuning, which usually works pretty well. The default value is 0, which means "keep the OS buffer size unchanged". This is a size value. So in addition to pure integer values, sizes like ``256k``, ``1m`` and the like can be specified. Note that setting very large sizes may require root or other special privileges. Also note that the OS may slightly adjust the value or shrink it to a system-set max value if the user is not sufficiently privileged. Technically, this parameter will result in a ``setsockopt()`` call with ``SO_RCVBUF`` (and ``SO_RCVBUFFORCE`` if it is available). (Maximum Value: 1G) Examples: .. code-block:: rsyslog module(load="imudp") # needs to be done just once input(type="imudp" port="514" rcvbufSize="1m") Input usage ----------- .. _param-imudp-input-rcvbufsize: .. _imudp.parameter.input.rcvbufsize-usage: .. code-block:: rsyslog input(type="imudp" RcvBufSize="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-statsfile.rst0000644000000000000000000000013215062756615025053 xustar0030 mtime=1758190989.211641261 30 atime=1764928601.473717729 30 ctime=1764935922.476565756 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-statsfile.rst0000664000175000017500000000155715062756615024527 0ustar00rgerrger.. _param-omkafka-statsfile: .. _omkafka.parameter.module.statsfile: statsFile ========= .. index:: single: omkafka; statsFile single: statsFile .. summary-start Write librdkafka statistics JSON to this file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: statsFile :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, the JSON statistics from librdkafka are written to the specified file. Updates occur based on the ``statistics.interval.ms`` `confParam` value. Action usage ------------ .. _param-omkafka-action-statsfile: .. _omkafka.parameter.action.statsfile: .. code-block:: rsyslog action(type="omkafka" statsFile="/var/log/omkafka-stats.json") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-pwd.rst0000644000000000000000000000013215114522477024716 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.469642513 30 ctime=1764935922.138560582 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-pwd.rst0000664000175000017500000000133115114522477024360 0ustar00rgerrger.. _param-omclickhouse-pwd: .. _omclickhouse.parameter.input.pwd: pwd === .. index:: single: omclickhouse; pwd single: pwd .. summary-start Provides the password for HTTP basic authentication when required by ClickHouse. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: pwd :Scope: input :Type: word :Default: none :Required?: no :Introduced: not specified Description ----------- Password for basic authentication. Input usage ----------- .. _omclickhouse.parameter.input.pwd-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" user="ingest" pwd="s3cr3t") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-port.rst0000644000000000000000000000013215103346332023707 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.755481084 30 ctime=1764935921.351548533 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-port.rst0000664000175000017500000000140415103346332023352 0ustar00rgerrger.. _param-imdtls-port: .. _imdtls.parameter.input.port: Port ==== .. index:: single: imdtls; port single: port .. summary-start Binds the imdtls listener to the specified UDP port for DTLS traffic. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: port :Scope: input :Type: word :Default: 4433 :Required?: yes :Introduced: v8.2402.0 Description ----------- Specifies the UDP port to which the imdtls module will bind and listen for incoming connections. The default port number for DTLS is 4433. Input usage ----------- .. _imdtls.parameter.input.port-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" port="4433") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-ratelimitinterval.rst0000644000000000000000000000013215114522477026460 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.457642219 30 ctime=1764935921.531551288 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-ratelimitinterval.rst0000664000175000017500000000160215114522477026123 0ustar00rgerrger.. _param-imklog-ratelimitinterval: .. _imklog.parameter.module.ratelimitinterval: RatelimitInterval ================= .. index:: single: imklog; RatelimitInterval single: RatelimitInterval .. summary-start Sets the interval window for the imklog rate limiter in seconds. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: RatelimitInterval :Scope: module :Type: integer :Default: 0 :Required?: no :Introduced: 8.35.0 Description ----------- The rate-limiting interval in seconds. Value 0 turns off rate limiting. Set it to a number of seconds (5 recommended) to activate rate-limiting. Module usage ------------ .. _param-imklog-module-ratelimitinterval: .. _imklog.parameter.module.ratelimitinterval-usage: .. code-block:: rsyslog module(load="imklog" ratelimitInterval="5") See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-asyncrepl.rst0000644000000000000000000000013115062756615026611 xustar0029 mtime=1758190989.20164112 30 atime=1764928599.576659747 30 ctime=1764935922.179561209 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-asyncrepl.rst0000664000175000017500000000167115062756615026263 0ustar00rgerrger.. _param-omelasticsearch-asyncrepl: .. _omelasticsearch.parameter.module.asyncrepl: asyncrepl ========= .. index:: single: omelasticsearch; asyncrepl single: asyncrepl .. summary-start Deprecated option formerly enabling asynchronous replication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: asyncrepl :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Kept for compatibility; Elasticsearch removed support for asynchronous replication so this setting has no effect. Action usage ------------ .. _param-omelasticsearch-action-asyncrepl: .. _omelasticsearch.parameter.action.asyncrepl: .. code-block:: rsyslog action(type="omelasticsearch" asyncrepl="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ignoretimestamp.rst0000644000000000000000000000013115062756615026514 xustar0030 mtime=1758190989.196641049 30 atime=1764928597.002580886 29 ctime=1764935921.84255605 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ignoretimestamp.rst0000664000175000017500000000237215062756615026165 0ustar00rgerrger.. _param-imuxsock-ignoretimestamp: .. _imuxsock.parameter.input.ignoretimestamp: IgnoreTimestamp =============== .. index:: single: imuxsock; IgnoreTimestamp single: IgnoreTimestamp .. summary-start Ignores timestamps included in messages from this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: IgnoreTimestamp :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Ignore timestamps included in messages received from the input being defined. Input usage ----------- .. _param-imuxsock-input-ignoretimestamp: .. _imuxsock.parameter.input.ignoretimestamp-usage: .. code-block:: rsyslog input(type="imuxsock" ignoreTimestamp="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketignoremsgtimestamp: - $InputUnixListenSocketIgnoreMsgTimestamp — maps to IgnoreTimestamp (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketIgnoreMsgTimestamp single: $InputUnixListenSocketIgnoreMsgTimestamp See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-severity.rst0000644000000000000000000000013215114522477025155 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.460642292 30 ctime=1764935921.564551794 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-severity.rst0000664000175000017500000000146715114522477024631 0ustar00rgerrger.. _param-impstats-severity: .. _impstats.parameter.module.severity: severity ======== .. index:: single: impstats; severity single: severity .. summary-start Sets the syslog severity value that impstats assigns to emitted messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: severity :Scope: module :Type: integer :Default: module=6 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The numerical syslog severity code to be used for generated messages. Default is 6 (info). This is useful for filtering messages. Module usage ------------ .. _impstats.parameter.module.severity-usage: .. code-block:: rsyslog module(load="impstats" severity="7") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-force-tagendingbycolon.rst0000644000000000000000000000013115062756615027512 xustar0029 mtime=1758190989.21364129 30 atime=1764928603.273772639 30 ctime=1764935922.611567823 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-force-tagendingbycolon.rst0000664000175000017500000000216215062756615027160 0ustar00rgerrger.. _param-pmrfc3164-force-tagendingbycolon: .. _pmrfc3164.parameter.module.force-tagendingbycolon: .. _pmrfc3164.parameter.module.force.tagEndingByColon: force.tagEndingByColon ====================== .. index:: single: pmrfc3164; force.tagEndingByColon single: force.tagEndingByColon .. summary-start Require tags to end with a colon or set the tag to ``-``. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: force.tagEndingByColon :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.2508.0 Description ----------- When enabled, tags must end with a colon to be valid. Otherwise the tag is replaced with ``-`` without modifying the message. Module usage ------------ .. _param-pmrfc3164-module-force-tagendingbycolon: .. _pmrfc3164.parameter.module.force-tagendingbycolon-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" force.tagEndingByColon="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-tokenfile.rst0000644000000000000000000000013115071746523026121 xustar0029 mtime=1760021843.81842067 30 atime=1764928598.293620464 30 ctime=1764935922.063559433 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-tokenfile.rst0000664000175000017500000000176115071746523025573 0ustar00rgerrger.. _param-mmkubernetes-tokenfile: .. _mmkubernetes.parameter.action.tokenfile: tokenfile ========= .. index:: single: mmkubernetes; tokenfile single: tokenfile .. summary-start Reads the authentication token from the specified file. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: tokenfile :Scope: action :Type: word :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- The file containing the token to use to authenticate to the Kubernetes API server. One of `tokenfile` or :ref:`param-mmkubernetes-token` is required if Kubernetes is configured with access control. Example: `/etc/rsyslog.d/mmk8s.token` Action usage ------------ .. _param-mmkubernetes-action-tokenfile: .. _mmkubernetes.parameter.action.tokenfile-usage: .. code-block:: rsyslog action(type="mmkubernetes" tokenFile="/etc/rsyslog.d/mmk8s.token") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-template.rst0000644000000000000000000000013215114522477025737 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.470642538 30 ctime=1764935922.145560689 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-template.rst0000664000175000017500000000301615114522477025403 0ustar00rgerrger.. _param-omclickhouse-template: .. _omclickhouse.parameter.input.template: template ======== .. index:: single: omclickhouse; template single: template .. summary-start Selects the message template that renders the INSERT statement sent to ClickHouse. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: template :Scope: input :Type: word :Default: `` StdClickHouseFmt`` :Required?: no :Introduced: not specified Description ----------- This is the message format that will be sent to ClickHouse. The resulting string needs to be a valid INSERT Query, otherwise ClickHouse will return an error. Defaults to: .. note:: The leading space in `` StdClickHouseFmt`` is intentional. Rsyslog registers its built-in templates with a leading space in the internal configuration state, and the module looks up the default by that exact name. When overriding the parameter yourself, use the natural form ``StdClickHouseFmt`` (without the space) as shown below. .. code-block:: none "\"INSERT INTO rsyslog.SystemEvents (severity, facility, " "timestamp, hostname, tag, message) VALUES (" "%syslogseverity%, %syslogfacility%, " "'%timereported:::date-unixtimestamp%', '%hostname%', " "'%syslogtag%', '%msg%')\"" Input usage ----------- .. _omclickhouse.parameter.input.template-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" template="StdClickHouseFmt") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-ipfreebind.rst0000644000000000000000000000013215062756615024671 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.759573426 30 ctime=1764935921.801555422 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-ipfreebind.rst0000664000175000017500000000245315062756615024341 0ustar00rgerrger.. _param-imudp-ipfreebind: .. _imudp.parameter.input.ipfreebind: IpFreeBind ========== .. index:: single: imudp; IpFreeBind single: IpFreeBind .. summary-start Controls Linux ``IP_FREEBIND`` socket option for nonlocal binds. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: IpFreeBind :Scope: input :Type: integer :Default: input=2 :Required?: no :Introduced: 8.18.0 Description ----------- Manages the ``IP_FREEBIND`` option on the UDP socket, which allows binding it to an IP address that is nonlocal or not (yet) associated to any network interface. The parameter accepts the following values: - 0 - does not enable the ``IP_FREEBIND`` option on the UDP socket. If the ``bind()`` call fails because of ``EADDRNOTAVAIL`` error, socket initialization fails. - 1 - silently enables the ``IP_FREEBIND`` socket option if it is required to successfully bind the socket to a nonlocal address. - 2 - enables the ``IP_FREEBIND`` socket option and warns when it is used to successfully bind the socket to a nonlocal address. Input usage ----------- .. _param-imudp-input-ipfreebind: .. _imudp.parameter.input.ipfreebind-usage: .. code-block:: rsyslog input(type="imudp" IpFreeBind="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-timerequery.rst0000644000000000000000000000013215062756615025135 xustar0030 mtime=1758190989.195641035 30 atime=1764928596.691571338 30 ctime=1764935921.828555836 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-timerequery.rst0000664000175000017500000000373715062756615024613 0ustar00rgerrger.. _param-imudp-timerequery: .. _imudp.parameter.module.timerequery: TimeRequery =========== .. index:: single: imudp; TimeRequery single: TimeRequery .. summary-start Frequency of system time queries; lower values yield more precise timestamps. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: TimeRequery :Scope: module :Type: integer :Default: module=2 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This is a performance optimization. Getting the system time is very costly. With this setting, imudp can be instructed to obtain the precise time only once every n-times. This logic is only activated if messages come in at a very fast rate, so doing less frequent time calls should usually be acceptable. The default value is two, because we have seen that even without optimization the kernel often returns twice the identical time. You can set this value as high as you like, but do so at your own risk. The higher the value, the less precise the timestamp. .. note:: The time requery is based on executed system calls, not messages received. When batch sizes are used, multiple messages are obtained with one system call and all receive the same timestamp. At very high traffic the requery logic means time is queried only for every second batch by default. Do not set ``TimeRequery`` above 10 when input batches are used. Module usage ------------ .. _param-imudp-module-timerequery: .. _imudp.parameter.module.timerequery-usage: .. code-block:: rsyslog module(load="imudp" TimeRequery="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.udpservertimerequery: - $UDPServerTimeRequery — maps to TimeRequery (status: legacy) .. index:: single: imudp; $UDPServerTimeRequery single: $UDPServerTimeRequery See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omuxsock-sockettype.rst0000644000000000000000000000013115114522477025500 xustar0030 mtime=1764926783.034631833 29 atime=1764926783.48864298 30 ctime=1764935922.602567685 rsyslog-8.2512.0/doc/source/reference/parameters/omuxsock-sockettype.rst0000664000175000017500000000356615114522477025157 0ustar00rgerrger.. _param-omuxsock-sockettype: .. _omuxsock.parameter.module.sockettype: socketType ========== .. index:: single: omuxsock; socketType single: socketType .. summary-start This is the type of the socket (DGRAM, STREAM, SEQPACKET). .. summary-end This parameter applies to :doc:`../../configuration/modules/omuxsock`. :Name: socketType :Scope: module, action :Type: string :Default: module=DGRAM, action=DGRAM :Required?: no :Introduced: v8.2512 Description ----------- This indicates the type of socket. It can take on the value DGRAM to indicate a datagram socket type (the default) or STREAM to indicate a streaming socket type. When supported by the underlying operating system, it can also have the value SEQPACKET to indicate a sequenced packet socket type. Module usage ------------ .. _omuxsock.parameter.module.sockettype-usage: A socketType set at the module level becomes the default socketType for the first unnamed action. It only applies to a single unnamed action, so it is primarily just a short-hand notation for when only a single omuxsock action is required. .. code-block:: rsyslog module(load="omuxsock" socketType="DGRAM") Action usage ------------ .. _omuxsock.parameter.action.sockettype-usage: .. code-block:: rsyslog action(type="omuxsock" socketType="DGRAM") action(type="omuxsock" socketType="STREAM") action(type="omuxsock" socketType="SEQPACKET") .. note:: :ref:`param-omuxsock-socketname`, :ref:`param-omuxsock-abstract`, and :ref:`param-omuxsock-sockettype` constitute a logical configuration tuple. They are applied together as a whole tuple from a module level configuration to an action. Therefore, all three parameters must be explicitly specified in the action, or none may be specified in the action. In the latter case, the default is taken from the module. See also -------- See also :doc:`../../configuration/modules/omuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-container.rst0000644000000000000000000000013215071746523025241 xustar0030 mtime=1760021843.805420466 30 atime=1764928597.663601155 30 ctime=1764935921.950557703 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-container.rst0000664000175000017500000000257215071746523024713 0ustar00rgerrger.. _param-mmdarwin-container: .. _mmdarwin.parameter.module.container: container ========= .. index:: single: mmdarwin; container single: container .. summary-start Defines the JSON container path that holds mmdarwin's generated data. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: container :Scope: module :Type: word :Default: module="!mmdarwin" :Required?: no :Introduced: 8.2008.0 Description ----------- Set the JSON container path that mmdarwin uses when it writes Darwin metadata and response values back to the message. The container string must begin with :json:`"!"` or :json:`"."` so the path resolves to either the structured data in the message or a local variable tree. If no value is configured, mmdarwin stores data under :json:`"!mmdarwin"`. The module prefixes this container to the target specified by :ref:`param-mmdarwin-key` and to the generated :json:`"darwin_id"` field that tracks the request UUID. As a result, selecting a custom container lets you control where the Darwin score and identifier are recorded. Module usage ------------ .. _param-mmdarwin-module-container-usage: .. _mmdarwin.parameter.module.container-usage: .. code-block:: rsyslog module(load="mmdarwin" container="!darwin") action(type="mmdarwin" key="certitude") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-db.rst0000644000000000000000000000013115114522477023604 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.483642857 29 ctime=1764935922.48856594 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-db.rst0000664000175000017500000000227115114522477023253 0ustar00rgerrger.. _param-omlibdbi-db: .. _omlibdbi.parameter.input.db: DB == .. index:: single: omlibdbi; DB single: DB .. summary-start Names the database schema that omlibdbi writes to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: DB :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Set this to the database instance that should receive the syslog events. It must exist on the selected server and accept the credentials supplied via ``UID`` and ``PWD``. Input usage ----------- .. _param-omlibdbi-input-db-usage: .. _omlibdbi.parameter.input.db-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbidbname: - $ActionLibdbiDBName — maps to DB (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiDBName single: $ActionLibdbiDBName See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-community.rst0000644000000000000000000000013215071746523024776 xustar0030 mtime=1760021843.825420781 30 atime=1764928602.744756513 30 ctime=1764935922.568567165 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-community.rst0000664000175000017500000000204115071746523024437 0ustar00rgerrger.. _param-omsnmp-community: .. _omsnmp.parameter.module.community: Community ========= .. index:: single: omsnmp; Community single: Community .. summary-start Sets the SNMP community string. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: Community :Scope: module :Type: string :Default: module=public :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- This sets the used SNMP Community. Module usage ------------ .. _param-omsnmp-module-community: .. _omsnmp.parameter.module.community-usage: .. code-block:: rsyslog action(type="omsnmp" community="public") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmpcommunity: - $actionsnmpcommunity — maps to Community (status: legacy) .. index:: single: omsnmp; $actionsnmpcommunity single: $actionsnmpcommunity See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-resubmitonfailure.rst0000644000000000000000000000013215062756615026614 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.525719317 30 ctime=1764935922.474565725 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-resubmitonfailure.rst0000664000175000017500000000200515062756615026255 0ustar00rgerrger.. _param-omkafka-resubmitonfailure: .. _omkafka.parameter.module.resubmitonfailure: resubmitOnFailure ================= .. index:: single: omkafka; resubmitOnFailure single: resubmitOnFailure .. summary-start Retry failed messages when Kafka becomes available. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: resubmitOnFailure :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.28.0 Description ----------- .. versionadded:: 8.28.0 If enabled, failed messages will be resubmitted automatically when Kafka can send messages again. Messages rejected because they exceed the maximum size are dropped. Action usage ------------ .. _param-omkafka-action-resubmitonfailure: .. _omkafka.parameter.action.resubmitonfailure: .. code-block:: rsyslog action(type="omkafka" resubmitOnFailure="on") Notes ----- - Originally documented as "binary"; uses boolean values. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/immark-ruleset.rst0000644000000000000000000000013215114522477024402 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.458642243 30 ctime=1764935921.538551396 rsyslog-8.2512.0/doc/source/reference/parameters/immark-ruleset.rst0000664000175000017500000000224415114522477024050 0ustar00rgerrger.. _param-immark-ruleset: .. _immark.parameter.module.ruleset: ruleset ======= .. index:: single: immark; ruleset single: ruleset .. summary-start Routes mark messages to the named ruleset instead of the default. .. summary-end This parameter applies to :doc:`../../configuration/modules/immark`. :Name: ruleset :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none :Required?: no :Introduced: 8.2012.0 Description ----------- Set this parameter to bind mark messages emitted by immark to a specific ruleset. The module looks up the ruleset during configuration; if it is not found, immark logs a warning and continues with the default ruleset. If a ruleset is configured while :ref:`param-immark-use-syslogcall` remains ``on``, immark issues a warning and forces this parameter to ``off`` so the ruleset can take effect. Module usage ------------ .. _immark.parameter.module.ruleset-usage: .. code-block:: rsyslog module(load="immark" use.syslogCall="off" ruleset="markRouting") See also -------- .. seealso:: * :ref:`param-immark-use-syslogcall` * :doc:`../../configuration/modules/immark` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-killunresponsive.rst0000644000000000000000000000013215062756615026363 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.153738487 30 ctime=1764935922.544566797 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-killunresponsive.rst0000664000175000017500000000431415062756615026031 0ustar00rgerrger.. _param-omprog-killunresponsive: .. _omprog.parameter.action.killunresponsive: killUnresponsive ================ .. index:: single: omprog; killUnresponsive single: killUnresponsive .. summary-start Kills the program if it remains after the close timeout expires. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: killUnresponsive :Scope: action :Type: boolean :Default: action=the value of 'signalOnClose' :Required?: no :Introduced: 8.35.0 Description ----------- Specifies whether a KILL signal must be sent to the external program in case it does not terminate within the timeout indicated by :ref:`param-omprog-closetimeout` (when either the worker thread has been unscheduled, a restart of the program is being forced, or rsyslog is about to shutdown). If :ref:`param-omprog-signalonclose` is set to "on", the default value of ``killUnresponsive`` is also "on". In this case, the cleanup sequence of the child process is as follows: (1) a TERM signal is sent to the child, (2) the pipe with the child process is closed (the child will receive EOF on stdin), (3) rsyslog waits for the child process to terminate during :ref:`param-omprog-closetimeout`, (4) if the child has not terminated within the timeout, a KILL signal is sent to it. If :ref:`param-omprog-signalonclose` is set to "off", the default value of ``killUnresponsive`` is also "off". In this case, the child cleanup sequence is as follows: (1) the pipe with the child process is closed (the child will receive EOF on stdin), (2) rsyslog waits for the child process to terminate during :ref:`param-omprog-closetimeout`, (3) if the child has not terminated within the timeout, rsyslog ignores it. This parameter can be set to a different value than :ref:`param-omprog-signalonclose`, obtaining the corresponding variations of cleanup sequences described above. Action usage ------------ .. _param-omprog-action-killunresponsive: .. _omprog.parameter.action.killunresponsive-usage: .. code-block:: rsyslog action(type="omprog" killUnresponsive="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-healthchecktimeout.rst0000644000000000000000000000013115114522477026623 xustar0030 mtime=1764926783.032631784 29 atime=1764926783.47764271 30 ctime=1764935922.374564195 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-healthchecktimeout.rst0000664000175000017500000000155615114522477026277 0ustar00rgerrger.. _param-omhttp-healthchecktimeout: .. _omhttp.parameter.input.healthchecktimeout: healthchecktimeout ================== .. index:: single: omhttp; healthchecktimeout single: healthchecktimeout .. summary-start Sets the number of milliseconds omhttp waits before a health check request times out. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: healthchecktimeout :Scope: input :Type: integer :Default: input=3500 :Required?: no :Introduced: Not specified Description ----------- The time after which the health check will time out in milliseconds. Input usage ----------- .. _omhttp.parameter.input.healthchecktimeout-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" healthCheckTimeout="5000" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-tls-myprivkey.rst0000644000000000000000000000013215062756615027451 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.701663572 30 ctime=1764935922.251562311 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-tls-myprivkey.rst0000664000175000017500000000167615062756615027127 0ustar00rgerrger.. _param-omelasticsearch-tls-myprivkey: .. _omelasticsearch.parameter.module.tls-myprivkey: .. _omelasticsearch.parameter.module.tls.myprivkey: tls.myprivkey ============= .. index:: single: omelasticsearch; tls.myprivkey single: tls.myprivkey .. summary-start Unencrypted private key for `tls.mycert`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: tls.myprivkey :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- PEM file containing the private key corresponding to the client certificate. The key must not be encrypted. Action usage ------------ .. _param-omelasticsearch-action-tls-myprivkey: .. _omelasticsearch.parameter.action.tls-myprivkey: .. code-block:: rsyslog action(type="omelasticsearch" tls.myprivkey="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-schedulingpolicy.rst0000644000000000000000000000013215062756615026127 xustar0030 mtime=1758190989.195641035 30 atime=1764928596.699571584 30 ctime=1764935921.822555743 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-schedulingpolicy.rst0000664000175000017500000000253415062756615025577 0ustar00rgerrger.. _param-imudp-schedulingpolicy: .. _imudp.parameter.module.schedulingpolicy: SchedulingPolicy ================ .. index:: single: imudp; SchedulingPolicy single: SchedulingPolicy .. summary-start Selects OS scheduler policy like ``fifo`` for real-time handling. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: SchedulingPolicy :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Can be used to set the scheduler priority, if the necessary functionality is provided by the platform. Most useful to select ``fifo`` for real-time processing under Linux (and thus reduce chance of packet loss). Other options are ``rr`` and ``other``. Module usage ------------ .. _param-imudp-module-schedulingpolicy: .. _imudp.parameter.module.schedulingpolicy-usage: .. code-block:: rsyslog module(load="imudp" SchedulingPolicy="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.imudpschedulingpolicy: - $IMUDPSchedulingPolicy — maps to SchedulingPolicy (status: legacy) .. index:: single: imudp; $IMUDPSchedulingPolicy single: $IMUDPSchedulingPolicy See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-ziplevel.rst0000644000000000000000000000013215062756615024551 xustar0030 mtime=1758190989.209641233 30 atime=1764928600.097675686 30 ctime=1764935922.333563567 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-ziplevel.rst0000664000175000017500000000222515062756615024216 0ustar00rgerrger.. _param-omfile-ziplevel: .. _omfile.parameter.module.ziplevel: zipLevel ======== .. index:: single: omfile; zipLevel single: zipLevel .. summary-start If greater than 0, turns on gzip compression of the output file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: zipLevel :Scope: action :Type: integer :Default: action=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If greater than 0, turns on gzip compression of the output file. The higher the number, the better the compression, but also the more CPU is required for zipping. Action usage ------------ .. _param-omfile-action-ziplevel: .. _omfile.parameter.action.ziplevel: .. code-block:: rsyslog action(type="omfile" zipLevel="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.omfileziplevel: - $OMFileZipLevel — maps to zipLevel (status: legacy) .. index:: single: omfile; $OMFileZipLevel single: $OMFileZipLevel See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-tls-mycert.rst0000644000000000000000000000013115071746523026244 xustar0029 mtime=1760021843.81842067 30 atime=1764928598.268619699 30 ctime=1764935922.056559326 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-tls-mycert.rst0000664000175000017500000000175215071746523025716 0ustar00rgerrger.. _param-mmkubernetes-tls-mycert: .. _mmkubernetes.parameter.action.tls-mycert: tls.mycert ========== .. index:: single: mmkubernetes; tls.mycert single: tls.mycert .. summary-start Specifies the client certificate for authenticating to Kubernetes. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: tls.mycert :Scope: action :Type: word :Default: none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This is the full path and file name of the file containing the client cert for doing client cert auth against Kubernetes. This file is in PEM format. For example: `/etc/rsyslog.d/k8s-client-cert.pem` Action usage ------------ .. _param-mmkubernetes-action-tls-mycert: .. _mmkubernetes.parameter.action.tls-mycert-usage: .. code-block:: rsyslog action(type="mmkubernetes" tls.myCert="/etc/rsyslog.d/k8s-client-cert.pem") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-server.rst0000644000000000000000000000013215114522477024526 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.484642882 30 ctime=1764935922.497566078 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-server.rst0000664000175000017500000000236615114522477024201 0ustar00rgerrger.. _param-omlibdbi-server: .. _omlibdbi.parameter.input.server: Server ====== .. index:: single: omlibdbi; Server single: Server .. summary-start Specifies the hostname or address of the database server to connect to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: Server :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Use this to point omlibdbi at the host that runs the selected database engine. Combine it with the driver, credentials, and database name to form the full connection information. Input usage ----------- .. _param-omlibdbi-input-server-usage: .. _omlibdbi.parameter.input.server-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbihost: - $ActionLibdbiHost — maps to Server (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiHost single: $ActionLibdbiHost See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-permittedpeer.rst0000644000000000000000000000013215062756615025431 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.211556603 30 ctime=1764935921.743554534 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-permittedpeer.rst0000664000175000017500000000372115062756615025100 0ustar00rgerrger.. _param-imtcp-permittedpeer: .. _imtcp.parameter.module.permittedpeer: .. _imtcp.parameter.input.permittedpeer: PermittedPeer ============= .. index:: single: imtcp; PermittedPeer single: PermittedPeer .. summary-start Restricts connections to listed peer identities. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: PermittedPeer :Scope: module, input :Type: array :Default: module=none, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets permitted peer IDs. Only these peers are able to connect to the listener. semantics depend on the currently selected AuthMode and :doc:`network stream driver <../../concepts/netstrm_drvr>`. PermittedPeer may not be set in anonymous modes. PermittedPeer may be set either to a single peer or an array of peers either of type IP or name, depending on the tls certificate. Single peer: PermittedPeer="127.0.0.1" Array of peers: PermittedPeer=["test1.example.net","10.1.2.3","test2.example.net","..."] The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-permittedpeer: .. _imtcp.parameter.module.permittedpeer-usage: .. code-block:: rsyslog module(load="imtcp" permittedPeer="127.0.0.1") Input usage ----------- .. _param-imtcp-input-permittedpeer: .. _imtcp.parameter.input.permittedpeer-usage: .. code-block:: rsyslog input(type="imtcp" port="514" permittedPeer="127.0.0.1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverstreamdriverpermittedpeer: - $InputTCPServerStreamDriverPermittedPeer — maps to PermittedPeer (status: legacy) .. index:: single: imtcp; $InputTCPServerStreamDriverPermittedPeer single: $InputTCPServerStreamDriverPermittedPeer See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-reopenontruncate.rst0000644000000000000000000000013215062756615026304 xustar0030 mtime=1758190989.185640893 30 atime=1764928594.064490599 30 ctime=1764935921.429549727 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-reopenontruncate.rst0000664000175000017500000000235015062756615025750 0ustar00rgerrger.. _param-imfile-reopenontruncate: .. _imfile.parameter.input.reopenontruncate: .. _imfile.parameter.reopenontruncate: reopenOnTruncate ================ .. index:: single: imfile; reopenOnTruncate single: reopenOnTruncate .. summary-start Experimental: reopen the input file if it was truncated without changing its inode. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: reopenOnTruncate :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When activated, tells rsyslog to reopen the input file if it was truncated (the inode is unchanged but the file size on disk is smaller than the current offset in memory). This feature is experimental. Input usage ----------- .. _param-imfile-input-reopenontruncate: .. _imfile.parameter.input.reopenontruncate-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" reopenOnTruncate="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. - This parameter is **experimental** and may change. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-ratelimit-burst.rst0000644000000000000000000000013115103061376027725 xustar0030 mtime=1762419454.852381127 30 atime=1764928599.772665744 29 ctime=1764935922.21556176 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-ratelimit-burst.rst0000664000175000017500000000172315103061376027375 0ustar00rgerrger.. _param-omelasticsearch-ratelimit-burst: .. _omelasticsearch.parameter.module.ratelimit-burst: .. _omelasticsearch.parameter.module.ratelimit.burst: ratelimit.burst =============== .. index:: single: omelasticsearch; ratelimit.burst single: ratelimit.burst .. summary-start Maximum messages allowed in a rate-limit interval. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: ratelimit.burst :Scope: action :Type: integer :Default: action=20000 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Specifies the burst size permitted within `ratelimit.interval` when retry limiting is active. Action usage ------------ .. _param-omelasticsearch-action-ratelimit-burst: .. _omelasticsearch.parameter.action.ratelimit-burst: .. code-block:: rsyslog action(type="omelasticsearch" ratelimit.burst="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dirowner.rst0000644000000000000000000000013215062756615024550 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.926670456 30 ctime=1764935922.283562802 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dirowner.rst0000664000175000017500000000301715062756615024215 0ustar00rgerrger.. _param-omfile-dirowner: .. _omfile.parameter.module.dirowner: dirOwner ======== .. index:: single: omfile; dirOwner single: dirOwner .. summary-start Set the file owner for directories newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dirOwner :Scope: module, action :Type: uid :Default: module=process user; action=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the file owner for directories newly created. Please note that this setting does not affect the owner of directories already existing. The parameter is a user name, for which the userid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-dirowner: .. _omfile.parameter.module.dirowner-usage: .. code-block:: rsyslog module(load="builtin:omfile" dirOwner="...") Action usage ------------ .. _param-omfile-action-dirowner: .. _omfile.parameter.action.dirowner: .. code-block:: rsyslog action(type="omfile" dirOwner="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dirowner: - $DirOwner — maps to dirOwner (status: legacy) .. index:: single: omfile; $DirOwner single: $DirOwner See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-logpath.rst0000644000000000000000000000013215114522477024357 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.457642219 30 ctime=1764935921.522551151 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-logpath.rst0000664000175000017500000000223715114522477024027 0ustar00rgerrger.. _param-imklog-logpath: .. _imklog.parameter.module.logpath: LogPath ======= .. index:: single: imklog; LogPath single: LogPath .. summary-start Specifies the kernel log device or file that imklog reads. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: LogPath :Scope: module :Type: word :Default: Linux: "/proc/kmsg"; other platforms: "/dev/klog" :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines the path to the kernel log device or file that imklog reads from. If this parameter is not set, it defaults to "/proc/kmsg" on Linux and "/dev/klog" on other platforms. Module usage ------------ .. _param-imklog-module-logpath: .. _imklog.parameter.module.logpath-usage: .. code-block:: rsyslog module(load="imklog" logPath="/dev/klog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.klogpath: - $klogpath — maps to LogPath (status: legacy) .. index:: single: imklog; $klogpath single: $klogpath See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-pwd.rst0000644000000000000000000000013215114522477024012 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.484642882 30 ctime=1764935922.495566047 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-pwd.rst0000664000175000017500000000225115114522477023456 0ustar00rgerrger.. _param-omlibdbi-pwd: .. _omlibdbi.parameter.input.pwd: PWD === .. index:: single: omlibdbi; PWD single: PWD .. summary-start Sets the password for the database user defined via ``UID``. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: PWD :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Supply the password that matches the user provided through the ``UID`` parameter so omlibdbi can authenticate to the database. Input usage ----------- .. _param-omlibdbi-input-pwd-usage: .. _omlibdbi.parameter.input.pwd-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbipassword: - $ActionLibdbiPassword — maps to PWD (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiPassword single: $ActionLibdbiPassword See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-serverport.rst0000644000000000000000000000013215062756615027025 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.492657176 30 ctime=1764935922.234562051 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-serverport.rst0000664000175000017500000000152015062756615026467 0ustar00rgerrger.. _param-omelasticsearch-serverport: .. _omelasticsearch.parameter.module.serverport: Serverport ========== .. index:: single: omelasticsearch; Serverport single: Serverport .. summary-start Default port used when server URLs omit a port. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: Serverport :Scope: action :Type: integer :Default: action=9200 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Port applied to entries in `server` that lack an explicit port number. Action usage ------------ .. _param-omelasticsearch-action-serverport: .. _omelasticsearch.parameter.action.serverport: .. code-block:: rsyslog action(type="omelasticsearch" Serverport="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-timeout.rst0000644000000000000000000000013015103346332024407 xustar0030 mtime=1762512090.626175929 28 atime=1764928593.7624813 30 ctime=1764935921.356548609 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-timeout.rst0000664000175000017500000000170215103346332024055 0ustar00rgerrger.. _param-imdtls-timeout: .. _imdtls.parameter.input.timeout: Timeout ======= .. index:: single: imdtls; timeout single: timeout .. summary-start Closes idle DTLS sessions after the configured inactivity period. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: timeout :Scope: input :Type: word :Default: 1800 :Required?: no :Introduced: v8.2402.0 Description ----------- Specifies the DTLS session timeout. As DTLS runs on the connectionless UDP protocol, there are no automatic detections of a session timeout. The input closes the DTLS session if no data is received from the client for the configured timeout period. The default is 1800 seconds, which is equal to 30 minutes. Input usage ----------- .. _imdtls.parameter.input.timeout-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" timeout="900") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omlibdbi-driver.rst0000644000000000000000000000013215114522477024513 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.483642857 30 ctime=1764935922.490565971 rsyslog-8.2512.0/doc/source/reference/parameters/omlibdbi-driver.rst0000664000175000017500000000275315114522477024166 0ustar00rgerrger.. _param-omlibdbi-driver: .. _omlibdbi.parameter.input.driver: Driver ====== .. index:: single: omlibdbi; Driver single: Driver .. summary-start Selects the libdbi driver backend to use for this action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omlibdbi`. :Name: Driver :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Set this to the driver name that matches your database backend, as documented by libdbi-drivers. Common values include: - ``mysql`` (:doc:`../../configuration/modules/ommysql` is recommended instead) - ``firebird`` (Firebird and InterBase) - ``ingres`` - ``msql`` - ``Oracle`` - ``sqlite`` - ``sqlite3`` - ``freetds`` (Microsoft SQL and Sybase) - ``pgsql`` (:doc:`../../configuration/modules/ompgsql` is recommended instead) Input usage ----------- .. _param-omlibdbi-input-driver-usage: .. _omlibdbi.parameter.input.driver-usage: .. code-block:: rsyslog action(type="omlibdbi" driver="mysql" server="db.example.net" uid="dbwriter" pwd="sup3rSecret" db="syslog") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omlibdbi.parameter.legacy.actionlibdbidriver: - $ActionLibdbiDriver — maps to Driver (status: legacy) .. index:: single: omlibdbi; $ActionLibdbiDriver single: $ActionLibdbiDriver See also -------- See also :doc:`../../configuration/modules/omlibdbi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-proxyhost.rst0000644000000000000000000000013215114522477025031 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.478642734 30 ctime=1764935922.391564455 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-proxyhost.rst0000664000175000017500000000162515114522477024501 0ustar00rgerrger.. _param-omhttp-proxyhost: .. _omhttp.parameter.input.proxyhost: proxyhost ========= .. index:: single: omhttp; proxyhost single: proxyhost .. summary-start Sets the hostname of the HTTP proxy that omhttp should use. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: proxyhost :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- Configures the libcurl ``CURLOPT_PROXY`` option for HTTP requests issued by omhttp. For more details see the `libcurl documentation for CURLOPT_PROXY `_. Input usage ----------- .. _omhttp.parameter.input.proxyhost-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" proxyHost="proxy.internal.example" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-pwd.rst0000644000000000000000000000013215114522477023544 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.479642759 30 ctime=1764935922.395564516 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-pwd.rst0000664000175000017500000000130115114522477023203 0ustar00rgerrger.. _param-omhttp-pwd: .. _omhttp.parameter.input.pwd: pwd === .. index:: single: omhttp; pwd single: pwd .. summary-start Provides the password for HTTP basic authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: pwd :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The password for the user for basic auth. Input usage ----------- .. _omhttp.parameter.input.pwd-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" uid="api-user" pwd="s3cr3t!" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsendertrack-senderid.rst0000644000000000000000000000013215114522477026075 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.487642955 30 ctime=1764935922.563567088 rsyslog-8.2512.0/doc/source/reference/parameters/omsendertrack-senderid.rst0000664000175000017500000000311415114522477025540 0ustar00rgerrger.. _param-omsendertrack-senderid: .. _omsendertrack.parameter.input.senderid: senderid ======== .. index:: single: omsendertrack; senderid single: senderid .. summary-start Sets the template used to derive the unique sender identifier that omsendertrack tracks. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsendertrack`. :Name: senderid :Scope: input :Type: string :Default: input=RSYSLOG_FileFormat :Required?: no :Introduced: 8.2506.0 (Proof-of-Concept) Description ----------- This parameter defines the **template used to determine the sender's unique identifier**. The value produced by this template becomes the key for tracking individual senders within the module's internal statistics. For instance: * A simple template like ``"%hostname%"`` tracks each unique host that submits messages to rsyslog. * Using ``"%fromhost-ip%"`` tracks senders based on their IP address. * A more granular template such as ``"%hostname%-%app-name%"`` differentiates between applications on the same host. **Note:** The processing of this template for every incoming message can impact overall throughput, especially if complex templates are used. Choose your template wisely based on your tracking needs and performance considerations. Input usage ----------- .. _omsendertrack.parameter.input.senderid-usage: .. code-block:: rsyslog module(load="omsendertrack") action(type="omsendertrack" senderId="%hostname%" stateFile="/var/lib/rsyslog/senderstats.json") See also -------- See also :doc:`../../configuration/modules/omsendertrack`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-statsname.rst0000644000000000000000000000013215114522477027044 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.467642464 30 ctime=1764935922.120560306 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-statsname.rst0000664000175000017500000000204115114522477026505 0ustar00rgerrger.. _param-omazureeventhubs-statsname: .. _omazureeventhubs.parameter.input.statsname: statsname ========= .. index:: single: omazureeventhubs; statsname single: statsname .. summary-start Names the statistics counters that track this action instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: statsname :Scope: input :Type: word :Default: input=omazureeventhubs :Required?: no :Introduced: v8.2304 Description ----------- The name assigned to statistics specific to this action instance. The supported set of statistics tracked for this action instance are ``submitted``, ``accepted``, ``failures``, and ``othererrors``. Note that in global module statistics, the counter corresponding to ``othererrors`` is named ``failures_other``. Input usage ----------- .. _omazureeventhubs.parameter.input.statsname-usage: .. code-block:: rsyslog action(type="omazureeventhubs" statsName="custom-azure" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-networknamespace.rst0000644000000000000000000000013115114522477026120 xustar0030 mtime=1764926783.029631711 29 atime=1764926783.46664244 30 ctime=1764935921.737554442 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-networknamespace.rst0000664000175000017500000000273315114522477025572 0ustar00rgerrger.. _param-imtcp-networknamespace: .. _imtcp.parameter.input.networknamespace: NetworkNamespace ================ .. index:: single: imtcp; NetworkNamespace single: NetworkNamespace .. summary-start Sets the value for the ``networknamespace`` property. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: NetworkNamespace :Scope: module, input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: v8.2512 Description ----------- Sets the network namespace for the listener. - If not set, the listener operates in the default (startup) network namespace. - The specified namespace must exist before rsyslogd starts (e.g., created via ``ip netns add ``). - This feature requires rsyslog to be built with ``setns()`` support. An error will be logged if a namespace is configured but support is missing. - The underlying operating system must also support network namespaces. Input usage ----------- .. _param-imtcp-input-networknamespace: .. _imtcp.parameter.input.networknamespace-usage: .. code-block:: rsyslog input(type="imtcp" port="514" NetworkNamespace="routing") input(type="imtcp" port="514" NetworkNamespace="management") .. code-block:: rsyslog module(load="imtcp" NetworkNamespace="routing") input(type="imtcp" port="514") input(type="imtcp" port="514" NetworkNamespace="management") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-permittedpeer.rst0000644000000000000000000000013215103346332026374 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.831483425 30 ctime=1764935921.367548778 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-permittedpeer.rst0000664000175000017500000000364615103346332026051 0ustar00rgerrger.. _param-imdtls-tls-permittedpeer: .. _imdtls.parameter.input.tls-permittedpeer: tls.permittedPeer ================= .. index:: single: imdtls; tls.permittedPeer single: tls.permittedPeer .. summary-start Restricts DTLS clients to the listed certificate fingerprints or names. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.permittedPeer :Scope: input :Type: array :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- ``tls.permittedPeer`` places access restrictions on this listener. Only peers whose certificate fingerprint or name is listed in this array parameter may connect. The certificate presented by the remote peer is used for its validation. When a non-permitted peer connects, the refusal is logged together with its fingerprint. If the administrator knows this was a valid request, they can simply add the fingerprint by copy and paste from the logfile to ``rsyslog.conf``. To specify multiple fingerprints, enclose them in braces like this: .. code-block:: none tls.permittedPeer=["SHA1:...1", "SHA1:....2"] To specify just a single peer, you can either specify the string directly or enclose it in braces. You may also use wildcards to match a larger number of permitted peers, e.g. ``*.example.com``. When using wildcards to match a larger number of permitted peers, the implementation is similar to Syslog RFC5425. This wildcard matches any left-most DNS label in the server name. That is, the subject ``*.example.com`` matches the server names ``a.example.com`` and ``b.example.com``, but does not match ``example.com`` or ``a.b.example.com``. Input usage ----------- .. _imdtls.parameter.input.tls-permittedpeer-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.permittedPeer=["SHA1:11223344556677889900AABBCCDDEEFF00112233"]) See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-name.rst0000644000000000000000000000013215062756615023502 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.800574685 30 ctime=1764935921.806555499 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-name.rst0000664000175000017500000000311615062756615023147 0ustar00rgerrger.. _param-imudp-name: .. _imudp.parameter.input.name: Name ==== .. index:: single: imudp; Name single: Name .. summary-start Value assigned to ``inputname`` property for this listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: Name :Scope: input :Type: word :Default: input=imudp :Required?: no :Introduced: 8.3.3 Description ----------- Specifies the value of the ``inputname`` property. In older versions, this was always ``imudp`` for all listeners, which still is the default. Starting with 7.3.9 it can be set to different values for each listener. Note that when a single input statement defines multiple listener ports, the ``inputname`` will be the same for all of them. If you want to differentiate in that case, use ``name.appendPort`` to make them unique. Note that the ``name`` parameter can be an empty string. In that case, the corresponding ``inputname`` property will obviously also be the empty string. This is primarily meant to be used together with ``name.appendPort`` to set the ``inputname`` equal to the port. Examples: .. code-block:: rsyslog module(load="imudp") input(type="imudp" port=["10514","10515","10516"] name="udp" name.appendPort="on") .. code-block:: rsyslog module(load="imudp") input(type="imudp" port=["10514","10515","10516"] name="" name.appendPort="on") Input usage ----------- .. _param-imudp-input-name: .. _imudp.parameter.input.name-usage: .. code-block:: rsyslog input(type="imudp" Name="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-use.rst0000644000000000000000000000013215062756615025576 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.898577693 30 ctime=1764935921.886556723 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-use.rst0000664000175000017500000000360415062756615025245 0ustar00rgerrger.. _param-imuxsock-syssock-use: .. _imuxsock.parameter.module.syssock-use: SysSock.Use =========== .. index:: single: imuxsock; SysSock.Use single: SysSock.Use .. summary-start Enables listening on the system log socket or the path set by SysSock.Name. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.Use :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Listen on the default local log socket (``/dev/log``) or, if provided, use the log socket value assigned to the ``SysSock.Name`` parameter instead of the default. This is most useful if you run multiple instances of rsyslogd where only one shall handle the system log socket. Unless disabled by the ``SysSock.Unlink`` setting, this socket is created upon rsyslog startup and deleted upon shutdown, according to traditional syslogd behavior. The behavior of this parameter is different for systemd systems. For those systems, ``SysSock.Use`` still needs to be enabled, but the value of ``SysSock.Name`` is ignored and the socket provided by systemd is used instead. If this parameter is *not* enabled, then imuxsock will only be of use if a custom input is configured. See the :ref:`imuxsock-systemd-details-label` section for details. Module usage ------------ .. _param-imuxsock-module-syssock-use: .. _imuxsock.parameter.module.syssock-use-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.use="off") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.omitlocallogging: - $OmitLocalLogging — maps to SysSock.Use (status: legacy) .. index:: single: imuxsock; $OmitLocalLogging single: $OmitLocalLogging See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-notifyonconnectionclose.rst0000644000000000000000000000013215062756615027533 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.087552797 30 ctime=1764935921.739554473 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-notifyonconnectionclose.rst0000664000175000017500000000323615062756615027203 0ustar00rgerrger.. _param-imtcp-notifyonconnectionclose: .. _imtcp.parameter.module.notifyonconnectionclose: .. _imtcp.parameter.input.notifyonconnectionclose: NotifyOnConnectionClose ======================= .. index:: single: imtcp; NotifyOnConnectionClose single: NotifyOnConnectionClose .. summary-start Emits a message when a remote peer closes a connection. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: NotifyOnConnectionClose :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Instructs imtcp to emit a message if the remote peer closes a connection. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-notifyonconnectionclose: .. _imtcp.parameter.module.notifyonconnectionclose-usage: .. code-block:: rsyslog module(load="imtcp" notifyOnConnectionClose="on") Input usage ----------- .. _param-imtcp-input-notifyonconnectionclose: .. _imtcp.parameter.input.notifyonconnectionclose-usage: .. code-block:: rsyslog input(type="imtcp" port="514" notifyOnConnectionClose="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpservernotifyonconnectionclose: - $InputTCPServerNotifyOnConnectionClose — maps to NotifyOnConnectionClose (status: legacy) .. index:: single: imtcp; $InputTCPServerNotifyOnConnectionClose single: $InputTCPServerNotifyOnConnectionClose See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-bulkmode.rst0000644000000000000000000000013215062756615026414 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.617661001 30 ctime=1764935922.183561271 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-bulkmode.rst0000664000175000017500000000163615062756615026066 0ustar00rgerrger.. _param-omelasticsearch-bulkmode: .. _omelasticsearch.parameter.module.bulkmode: bulkmode ======== .. index:: single: omelasticsearch; bulkmode single: bulkmode .. summary-start Use the Elasticsearch Bulk API to send batched events. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: bulkmode :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If enabled, events are buffered and sent in bulk requests. Without it, each event is sent individually. Action usage ------------ .. _param-omelasticsearch-action-bulkmode: .. _omelasticsearch.parameter.action.bulkmode: .. code-block:: rsyslog action(type="omelasticsearch" bulkmode="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-schedulingpriority.rst0000644000000000000000000000013115062756615026510 xustar0030 mtime=1758190989.195641035 29 atime=1764928596.70857186 30 ctime=1764935921.824555774 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-schedulingpriority.rst0000664000175000017500000000222715062756615026160 0ustar00rgerrger.. _param-imudp-schedulingpriority: .. _imudp.parameter.module.schedulingpriority: SchedulingPriority ================== .. index:: single: imudp; SchedulingPriority single: SchedulingPriority .. summary-start Scheduler priority value when ``SchedulingPolicy`` is used. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: SchedulingPriority :Scope: module :Type: integer :Default: module=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Scheduling priority to use. Module usage ------------ .. _param-imudp-module-schedulingpriority: .. _imudp.parameter.module.schedulingpriority-usage: .. code-block:: rsyslog module(load="imudp" SchedulingPriority="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imudp.parameter.legacy.imudpschedulingpriority: - $IMUDPSchedulingPriority — maps to SchedulingPriority (status: legacy) .. index:: single: imudp; $IMUDPSchedulingPriority single: $IMUDPSchedulingPriority See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-dynakey.rst0000644000000000000000000000013215062756615024521 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.414715928 30 ctime=1764935922.450565358 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-dynakey.rst0000664000175000017500000000151315062756615024165 0ustar00rgerrger.. _param-omkafka-dynakey: .. _omkafka.parameter.module.dynakey: DynaKey ======= .. index:: single: omkafka; DynaKey single: DynaKey .. summary-start Treat `key` as a template for dynamic partition keys. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: DynaKey :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.1903 Description ----------- If set, the key parameter becomes a template for the key to base the partitioning on. Action usage ------------ .. _param-omkafka-action-dynakey: .. _omkafka.parameter.action.dynakey: .. code-block:: rsyslog action(type="omkafka" DynaKey="on" Key="keytemplate") Notes ----- - Originally documented as "binary"; uses boolean values. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-name.rst0000644000000000000000000000013215114522477023647 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.462642342 30 ctime=1764935921.664553325 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-name.rst0000664000175000017500000000135115114522477023313 0ustar00rgerrger.. _param-imrelp-name: .. _imrelp.parameter.input.name: name ==== .. index:: single: imrelp; name single: name .. summary-start Sets a human-readable name for the RELP listener instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: name :Scope: input :Type: string :Default: input=imrelp :Required?: no :Introduced: Not documented Description ----------- Assigns a name to the listener. If not specified, the default "imrelp" is used. Input usage ----------- .. _param-imrelp-input-name-usage: .. _imrelp.parameter.input.name-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" name="relpServer") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-supportoctetcountedframing.rst0000644000000000000000000000013215062756615030261 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.301559366 30 ctime=1764935921.787555208 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-supportoctetcountedframing.rst0000664000175000017500000000320115062756615027721 0ustar00rgerrger.. _param-imtcp-supportoctetcountedframing: .. _imtcp.parameter.input.supportoctetcountedframing: SupportOctetCountedFraming ========================== .. index:: single: imtcp; SupportOctetCountedFraming single: SupportOctetCountedFraming .. summary-start Enables legacy octet-counted framing compatibility. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: SupportOctetCountedFraming :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If set to ``on``, the legacy octet-counted framing (similar to RFC5425 framing) is activated. This should be left unchanged until you know very well what you do. It may be useful to turn it off if this framing is not used and some senders emit multi-line messages into the message stream. Input usage ----------- .. _param-imtcp-input-supportoctetcountedframing: .. _imtcp.parameter.input.supportoctetcountedframing-usage: .. code-block:: rsyslog input(type="imtcp" supportOctetCountedFraming="off") Notes ----- - Earlier documentation described the type as "binary"; this maps to boolean. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserversupportoctetcountedframing: - $InputTCPServerSupportOctetCountedFraming — maps to SupportOctetCountedFraming (status: legacy) .. index:: single: imtcp; $InputTCPServerSupportOctetCountedFraming single: $InputTCPServerSupportOctetCountedFraming See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-healthchecktimeout.rst0000644000000000000000000000013215114522477027776 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.469642513 30 ctime=1764935922.131560474 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-healthchecktimeout.rst0000664000175000017500000000175315114522477027450 0ustar00rgerrger.. _param-omclickhouse-healthchecktimeout: .. _omclickhouse.parameter.input.healthchecktimeout: healthCheckTimeout ================== .. index:: single: omclickhouse; healthCheckTimeout single: healthCheckTimeout single: omclickhouse; healthchecktimeout single: healthchecktimeout .. summary-start Sets the timeout, in milliseconds, for verifying ClickHouse availability. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: healthCheckTimeout :Scope: input :Type: int (milliseconds) :Default: 3500 :Required?: no :Introduced: not specified Description ----------- This parameter sets the timeout for checking the availability of ClickHouse. Value is given in milliseconds. Input usage ----------- .. _omclickhouse.parameter.input.healthchecktimeout-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" healthCheckTimeout="5000") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-ruleset.rst0000644000000000000000000000013115114522477024524 xustar0030 mtime=1764926783.027631661 29 atime=1764926783.45564217 30 ctime=1764935921.511550982 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-ruleset.rst0000664000175000017500000000230215114522477024166 0ustar00rgerrger.. _param-imkafka-ruleset: .. _imkafka.parameter.module.ruleset: .. _imkafka.parameter.input.ruleset: ruleset ======= .. index:: single: imkafka; ruleset single: ruleset .. summary-start Assigns the rsyslog ruleset that processes messages received via imkafka. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: ruleset :Scope: module, input :Type: string :Default: module=``none``; input=``none`` :Required?: no :Introduced: 8.27.0 Description ----------- Binds the input to a specific ruleset for processing. If not specified, messages are passed to the default ruleset. When set at the module level, the value becomes the default ruleset for inputs that do not override it. Module usage ------------ .. _imkafka.parameter.module.ruleset-usage: .. code-block:: rsyslog module(load="imkafka" ruleset="kafkaRules") # This input will use 'kafkaRules' ruleset input(type="imkafka" topic="my-topic") Input usage ----------- .. _imkafka.parameter.input.ruleset-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="static" ruleset="kafkaRules") See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-headerless-errorfile.rst0000644000000000000000000000013015062756615027175 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.333774467 28 ctime=1764935922.6165679 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-headerless-errorfile.rst0000664000175000017500000000213515062756615026644 0ustar00rgerrger.. _param-pmrfc3164-headerless-errorfile: .. _pmrfc3164.parameter.module.headerless-errorfile: .. _pmrfc3164.parameter.module.headerless.errorfile: headerless.errorfile ==================== .. index:: single: pmrfc3164; headerless.errorfile single: headerless.errorfile .. summary-start Append raw headerless input to a file before other processing. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: headerless.errorfile :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none :Required?: no :Introduced: 8.2508.0 Description ----------- If specified, raw headerless input is appended to this file before further processing. The file is created if it does not already exist. Module usage ------------ .. _param-pmrfc3164-module-headerless-errorfile: .. _pmrfc3164.parameter.module.headerless-errorfile-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" headerless.errorfile="/var/log/rsyslog-headerless.log") See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-pipelinename.rst0000644000000000000000000000013215062756615027260 xustar0030 mtime=1758190989.203641148 30 atime=1764928599.549658921 30 ctime=1764935922.211561699 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-pipelinename.rst0000664000175000017500000000161315062756615026725 0ustar00rgerrger.. _param-omelasticsearch-pipelinename: .. _omelasticsearch.parameter.module.pipelinename: pipelineName ============ .. index:: single: omelasticsearch; pipelineName single: pipelineName .. summary-start Ingest pipeline to run before indexing. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: pipelineName :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Adds an ingest pipeline name to the request so events are pre-processed before indexing. By default no pipeline is used. Action usage ------------ .. _param-omelasticsearch-action-pipelinename: .. _omelasticsearch.parameter.action.pipelinename: .. code-block:: rsyslog action(type="omelasticsearch" pipelineName="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv4-bits.rst0000644000000000000000000000013215071746523024547 xustar0030 mtime=1760021843.802420418 30 atime=1764928597.320590637 30 ctime=1764935921.927557351 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv4-bits.rst0000664000175000017500000000302115071746523024207 0ustar00rgerrger.. _param-mmanon-ipv4-bits: .. _mmanon.parameter.input.ipv4-bits: ipv4.bits ========= .. index:: single: mmanon; ipv4.bits single: ipv4.bits .. summary-start Sets how many low-order bits of IPv4 addresses are anonymized. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv4.bits :Scope: input :Type: positive integer :Default: input=16 :Required?: no :Introduced: 7.3.7 Description ----------- This sets the number of bits that should be anonymized (bits are from the right, so lower bits are anonymized first). This setting permits to save network information while still anonymizing user-specific data. The more bits you discard, the better the anonymization obviously is. The default of 16 bits reflects what German data privacy rules consider as being sufficiently anonymized. We assume, this can also be used as a rough but conservative guideline for other countries. Note: when in :ref:`simple mode `, only bits on a byte boundary can be specified. As such, any value other than 8, 16, 24 or 32 is invalid. If an invalid value is given, it is rounded to the next byte boundary (so we favor stronger anonymization in that case). For example, a bit value of 12 will become 16 in simple mode (an error message is also emitted). Input usage ----------- .. _mmanon.parameter.input.ipv4-bits-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv4.mode="simple" ipv4.bits="24") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-dockerapiunixsockaddr.rst0000644000000000000000000000013215062756615027621 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.629477204 30 ctime=1764935921.332548242 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-dockerapiunixsockaddr.rst0000664000175000017500000000167715062756615027300 0ustar00rgerrger.. _param-imdocker-dockerapiunixsockaddr: .. _imdocker.parameter.module.dockerapiunixsockaddr: DockerApiUnixSockAddr ===================== .. index:: single: imdocker; DockerApiUnixSockAddr single: DockerApiUnixSockAddr .. summary-start Unix socket path for Docker API connections; default ``/var/run/docker.sock``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: DockerApiUnixSockAddr :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=/var/run/docker.sock :Required?: no :Introduced: 8.41.0 Description ----------- Specifies the Docker unix socket address to use. Module usage ------------ .. _param-imdocker-module-dockerapiunixsockaddr: .. _imdocker.parameter.module.dockerapiunixsockaddr-usage: .. code-block:: rsyslog module(load="imdocker" DockerApiUnixSockAddr="...") See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-listcontainersoptions.rst0000644000000000000000000000013215062756615027716 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.653477943 30 ctime=1764935921.339548349 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-listcontainersoptions.rst0000664000175000017500000000202515062756615027361 0ustar00rgerrger.. _param-imdocker-listcontainersoptions: .. _imdocker.parameter.module.listcontainersoptions: ListContainersOptions ===================== .. index:: single: imdocker; ListContainersOptions single: ListContainersOptions .. summary-start HTTP query options appended to ``List Containers`` requests; omit leading ``?``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: ListContainersOptions :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module= :Required?: no :Introduced: 8.41.0 Description ----------- Specifies the HTTP query component of a ``List Containers`` API request. See the Docker API for available options. It is not necessary to prepend ``?``. Module usage ------------ .. _param-imdocker-module-listcontainersoptions: .. _imdocker.parameter.module.listcontainersoptions-usage: .. code-block:: rsyslog module(load="imdocker" ListContainersOptions="...") See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdocker-defaultfacility.rst0000644000000000000000000000013215062756615026412 xustar0030 mtime=1758190989.183640865 30 atime=1764928593.678478713 30 ctime=1764935921.327548165 rsyslog-8.2512.0/doc/source/reference/parameters/imdocker-defaultfacility.rst0000664000175000017500000000210215062756615026051 0ustar00rgerrger.. _param-imdocker-defaultfacility: .. _imdocker.parameter.module.defaultfacility: DefaultFacility =============== .. index:: single: imdocker; DefaultFacility single: DefaultFacility .. summary-start Syslog facility assigned to received messages; default ``user``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdocker`. :Name: DefaultFacility :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=user :Required?: no :Introduced: 8.41.0 Description ----------- The syslog facility to be assigned to log messages. Textual names such as ``user`` are suggested, though numeric values are also accepted. Module usage ------------ .. _param-imdocker-module-defaultfacility: .. _imdocker.parameter.module.defaultfacility-usage: .. code-block:: rsyslog module(load="imdocker" DefaultFacility="...") Notes ----- - Numeric facility values are accepted but textual names are recommended. - See https://en.wikipedia.org/wiki/Syslog. See also -------- See also :doc:`../../configuration/modules/imdocker`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-sync.rst0000644000000000000000000000013115071746523023667 xustar0030 mtime=1760021843.823420749 30 atime=1764928600.182678284 29 ctime=1764935922.32656346 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-sync.rst0000664000175000017500000000313115071746523023332 0ustar00rgerrger.. _param-omfile-sync: .. _omfile.parameter.module.sync: sync ==== .. index:: single: omfile; sync single: sync .. summary-start Enables file syncing capability of omfile. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: sync :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Enables file syncing capability of omfile. When enabled, rsyslog does a sync to the data file as well as the directory it resides after processing each batch. There currently is no way to sync only after each n-th batch. Enabling sync causes a severe performance hit. Actually, it slows omfile so much down, that the probability of losing messages **increases**. In short, you should enable syncing only if you know exactly what you do, and fully understand how the rest of the engine works, and have tuned the rest of the engine to lossless operations. Action usage ------------ .. _param-omfile-action-sync: .. _omfile.parameter.action.sync: .. code-block:: rsyslog action(type="omfile" sync="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.actionfileenablesync: - $ActionFileEnableSync — maps to sync (status: legacy) .. index:: single: omfile; $ActionFileEnableSync single: $ActionFileEnableSync See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-filegroup.rst0000644000000000000000000000013215062756615024713 xustar0030 mtime=1758190989.207641205 30 atime=1764928599.910669967 30 ctime=1764935922.302563092 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-filegroup.rst0000664000175000017500000000302715062756615024361 0ustar00rgerrger.. _param-omfile-filegroup: .. _omfile.parameter.module.filegroup: fileGroup ========= .. index:: single: omfile; fileGroup single: fileGroup .. summary-start Set the group for files newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: fileGroup :Scope: module, action :Type: gid :Default: module=process user's primary group; action=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the group for files newly created. Please note that this setting does not affect the group of files already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are not detected. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-filegroup: .. _omfile.parameter.module.filegroup-usage: .. code-block:: rsyslog module(load="builtin:omfile" fileGroup="...") Action usage ------------ .. _param-omfile-action-filegroup: .. _omfile.parameter.action.filegroup: .. code-block:: rsyslog action(type="omfile" fileGroup="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.filegroup: - $FileGroup — maps to fileGroup (status: legacy) .. index:: single: omfile; $FileGroup single: $FileGroup See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-keepalive-probes.rst0000644000000000000000000000013215114522477026164 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.461642317 30 ctime=1764935921.655553187 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-keepalive-probes.rst0000664000175000017500000000211415114522477025626 0ustar00rgerrger.. _param-imrelp-keepalive-probes: .. _imrelp.parameter.input.keepalive-probes: keepAlive.probes ================ .. index:: single: imrelp; keepAlive.probes single: keepAlive.probes .. summary-start Defines how many keep-alive retries occur before the connection is declared dead. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: keepAlive.probes :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: Not documented Description ----------- The number of keep-alive probes to send before considering the connection dead and notifying the application layer. The default, 0, means that the operating system defaults are used. This only has an effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imrelp-input-keepalive-probes-usage: .. _imrelp.parameter.input.keepalive-probes-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" keepAlive="on" keepAlive.probes="5") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-cacert.rst0000644000000000000000000000013215114522477024770 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.463642366 30 ctime=1764935921.678553539 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-cacert.rst0000664000175000017500000000163115114522477024435 0ustar00rgerrger.. _param-imrelp-tls-cacert: .. _imrelp.parameter.input.tls-cacert: tls.caCert ========== .. index:: single: imrelp; tls.caCert single: tls.caCert .. summary-start Specifies the CA certificate file used to validate client certificates. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.caCert :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- The CA certificate that is being used to verify the client certificates. Has to be configured if :ref:`param-imrelp-tls-authmode` is set to ``name`` or ``certvalid``. Input usage ----------- .. _param-imrelp-input-tls-cacert-usage: .. _imrelp.parameter.input.tls-cacert-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.caCert="/etc/rsyslog/ca.pem") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-mycert.rst0000644000000000000000000000013215103346332025026 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.806482655 30 ctime=1764935921.362548701 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-mycert.rst0000664000175000017500000000155715103346332024502 0ustar00rgerrger.. _param-imdtls-tls-mycert: .. _imdtls.parameter.input.tls-mycert: tls.myCert ========== .. index:: single: imdtls; tls.myCert single: tls.myCert .. summary-start Identifies the certificate file the imdtls listener presents to peers. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.myCert :Scope: input :Type: string :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Specifies the certificate file used by imdtls. This certificate is presented to peers during the DTLS handshake. Input usage ----------- .. _imdtls.parameter.input.tls-mycert-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.myCert="/etc/rsyslog/server.pem" tls.myPrivKey="/etc/rsyslog/server.key") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-aborttimeout.rst0000644000000000000000000000013215114522477025407 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.451642071 30 ctime=1764935921.303547798 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-aborttimeout.rst0000664000175000017500000000342215114522477025054 0ustar00rgerrger.. _param-imdiag-aborttimeout: .. _imdiag.parameter.module.aborttimeout: AbortTimeout ============ .. index:: single: imdiag; AbortTimeout single: AbortTimeout .. summary-start Starts a watchdog thread that aborts rsyslog if it runs longer than the configured time limit. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: AbortTimeout :Scope: module :Type: integer (seconds) :Default: module=none (disabled) :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- When set, ``AbortTimeout`` installs a guard thread that tracks the runtime of the rsyslog instance. The timer starts as soon as this configuration parameter is loaded and applies for the entire process runtime. If rsyslog remains active for longer than the configured number of seconds after the guard starts, the thread writes a status message to ``stderr`` and terminates the daemon with ``abort()``. The guard is intended for automated test environments to detect deadlocks or hangs. The guard can only be configured once during the lifetime of the process. A second attempt to configure the watchdog is ignored and logs an error. Values less than or equal to zero are rejected. Module usage ------------ .. _param-imdiag-module-aborttimeout: .. _imdiag.parameter.module.aborttimeout-usage: .. code-block:: rsyslog module(load="imdiag" abortTimeout="600") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagaborttimeout: - $IMDiagAbortTimeout — maps to AbortTimeout (status: legacy) .. index:: single: imdiag; $IMDiagAbortTimeout single: $IMDiagAbortTimeout See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-headerless-tag.rst0000644000000000000000000000013215062756615025761 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.316773949 30 ctime=1764935922.623568007 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-headerless-tag.rst0000664000175000017500000000165015062756615025427 0ustar00rgerrger.. _param-pmrfc3164-headerless-tag: .. _pmrfc3164.parameter.module.headerless-tag: .. _pmrfc3164.parameter.module.headerless.tag: headerless.tag ============== .. index:: single: pmrfc3164; headerless.tag single: headerless.tag .. summary-start Set the tag used for headerless messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: headerless.tag :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=headerless :Required?: no :Introduced: 8.2508.0 Description ----------- Specifies the tag to assign to detected headerless messages. Module usage ------------ .. _param-pmrfc3164-module-headerless-tag: .. _pmrfc3164.parameter.module.headerless-tag-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" headerless.tag="missing") See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-closetimeout.rst0000644000000000000000000000013215062756615025463 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.144738213 30 ctime=1764935922.527566537 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-closetimeout.rst0000664000175000017500000000224515062756615025132 0ustar00rgerrger.. _param-omprog-closetimeout: .. _omprog.parameter.action.closetimeout: closeTimeout ============ .. index:: single: omprog; closeTimeout single: closeTimeout .. summary-start Waits the specified milliseconds for the program to exit after stdin closes. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: closeTimeout :Scope: action :Type: integer :Default: action=5000 :Required?: no :Introduced: 8.35.0 Description ----------- Specifies how long rsyslog must wait for the external program to terminate (when either the worker thread has been unscheduled, a restart of the program is being forced, or rsyslog is about to shutdown) after closing the pipe, that is, after sending EOF to the stdin of the child process. The value must be expressed in milliseconds and must be greater than or equal to zero. See the :ref:`param-omprog-killunresponsive` parameter for more details. Action usage ------------ .. _param-omprog-action-closetimeout: .. _omprog.parameter.action.closetimeout-usage: .. code-block:: rsyslog action(type="omprog" closeTimeout="10000") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-partitions-usefixed.rst0000644000000000000000000000013115062756615027062 xustar0030 mtime=1758190989.210641247 29 atime=1764928601.45671721 30 ctime=1764935922.472565695 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-partitions-usefixed.rst0000664000175000017500000000163015062756615026527 0ustar00rgerrger.. _param-omkafka-partitions-usefixed: .. _omkafka.parameter.module.partitions-usefixed: Partitions.useFixed =================== .. index:: single: omkafka; Partitions.useFixed single: Partitions.useFixed .. summary-start Send all messages to a specific partition. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Partitions.useFixed :Scope: action :Type: integer :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If set, specifies the partition to which data is produced. All data goes to this partition; no other partition is used. Action usage ------------ .. _param-omkafka-action-partitions-usefixed: .. _omkafka.parameter.action.partitions-usefixed: .. code-block:: rsyslog action(type="omkafka" Partitions.useFixed="1") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-confparam.rst0000644000000000000000000000013215062756615025023 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.482718004 30 ctime=1764935922.448565327 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-confparam.rst0000664000175000017500000000166615062756615024500 0ustar00rgerrger.. _param-omkafka-confparam: .. _omkafka.parameter.module.confparam: ConfParam ========= .. index:: single: omkafka; ConfParam single: ConfParam .. summary-start Arbitrary librdkafka producer options `name=value`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: ConfParam :Scope: action :Type: array[string] :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Permits specifying Kafka options using ``name=value`` strings. Parameters are passed directly to librdkafka and support all its producer settings. Action usage ------------ .. _param-omkafka-action-confparam: .. _omkafka.parameter.action.confparam: .. code-block:: rsyslog action(type="omkafka" confParam=["compression.codec=snappy"]) Notes ----- - Multiple values may be set using array syntax. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-topic.rst0000644000000000000000000000013215062756615024173 xustar0030 mtime=1758190989.211641261 30 atime=1764928601.398715439 30 ctime=1764935922.483565863 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-topic.rst0000664000175000017500000000125515062756615023642 0ustar00rgerrger.. _param-omkafka-topic: .. _omkafka.parameter.module.topic: Topic ===== .. index:: single: omkafka; Topic single: Topic .. summary-start Kafka topic to produce to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Topic :Scope: action :Type: string :Default: action=none :Required?: yes :Introduced: at least 8.x, possibly earlier Description ----------- Specifies the topic to produce to. Action usage ------------ .. _param-omkafka-action-topic: .. _omkafka.parameter.action.topic: .. code-block:: rsyslog action(type="omkafka" Topic="mytopic") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-containerrules.rst0000644000000000000000000000013215071746523027177 xustar0030 mtime=1760021843.812420576 30 atime=1764928598.179616972 30 ctime=1764935922.031558943 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-containerrules.rst0000664000175000017500000000307715071746523026652 0ustar00rgerrger.. _param-mmkubernetes-containerrules: .. _mmkubernetes.parameter.action.containerrules: containerrules ============== .. index:: single: mmkubernetes; containerrules single: containerrules .. summary-start Defines lognorm rules to parse ``CONTAINER_NAME`` values for metadata. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: containerrules :Scope: action :Type: word :Default: SEE BELOW :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- .. note:: This directive is not supported with liblognorm 2.0.2 and earlier. For journald logs, there must be a message property `CONTAINER_NAME` which has a value matching these rules specified by this parameter. The default value is:: rule=:%k8s_prefix:char-to:_%_%container_name:char-to:.%.%container_hash:char-to:\ _%_%pod_name:char-to:_%_%namespace_name:char-to:_%_%not_used_1:char-to:_%_%not_u\ sed_2:rest% rule=:%k8s_prefix:char-to:_%_%container_name:char-to:_%_%pod_name:char-to:_%_%na\ mespace_name:char-to:_%_%not_used_1:char-to:_%_%not_used_2:rest% .. note:: In the above rules, the slashes ``\`` ending each line indicate line wrapping - they are not part of the rule. There are two rules because the `container_hash` is optional. Action usage ------------ .. _param-mmkubernetes-action-containerrules: .. _mmkubernetes.parameter.action.containerrules-usage: .. code-block:: rsyslog action(type="mmkubernetes" containerRules="...") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-headerless-drop.rst0000644000000000000000000000013115062756615026151 xustar0030 mtime=1758190989.214641304 29 atime=1764928603.34077468 30 ctime=1764935922.613567854 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-headerless-drop.rst0000664000175000017500000000205215062756615025615 0ustar00rgerrger.. _param-pmrfc3164-headerless-drop: .. _pmrfc3164.parameter.module.headerless-drop: .. _pmrfc3164.parameter.module.headerless.drop: headerless.drop =============== .. index:: single: pmrfc3164; headerless.drop single: headerless.drop .. summary-start Discard headerless messages after optional logging. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: headerless.drop :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.2508.0 Description ----------- When enabled, headerless messages are discarded after optional logging to ``headerless.errorfile`` and are not processed by later rules. Module usage ------------ .. _param-pmrfc3164-module-headerless-drop: .. _pmrfc3164.parameter.module.headerless-drop-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" headerless.drop="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/immark-use-syslogcall.rst0000644000000000000000000000013215114522477025665 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.458642243 30 ctime=1764935921.544551487 rsyslog-8.2512.0/doc/source/reference/parameters/immark-use-syslogcall.rst0000664000175000017500000000251415114522477025333 0ustar00rgerrger.. _param-immark-use-syslogcall: .. _immark.parameter.module.use-syslogcall: use.syslogCall =============== .. index:: single: immark; use.syslogCall single: use.syslogCall .. summary-start Chooses whether immark logs via syslog(3) or its internal pipeline. .. summary-end This parameter applies to :doc:`../../configuration/modules/immark`. :Name: use.syslogCall :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.2012.0 Description ----------- Controls how immark emits its periodic mark messages: * ``on`` (default) — immark calls the system ``syslog(3)`` interface. Messages bypass rsyslog's internal queueing and are handled like any other syslog API submission. * ``off`` — immark constructs the message internally and submits it to rsyslog's main queue. This enables features such as binding a custom :ref:`param-immark-ruleset` or applying mark-specific templates. If a ruleset is configured while ``use.syslogCall`` remains ``on``, immark issues a warning and forces this parameter to ``off`` so the ruleset can take effect. Module usage ------------ .. _immark.parameter.module.use-syslogcall-usage: .. code-block:: rsyslog module(load="immark" use.syslogCall="off") See also -------- .. seealso:: * :ref:`param-immark-ruleset` * :doc:`../../configuration/modules/immark` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpretrycodes.rst0000644000000000000000000000013215114522477026035 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.478642734 30 ctime=1764935922.388564409 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpretrycodes.rst0000664000175000017500000000167115114522477025506 0ustar00rgerrger.. _param-omhttp-httpretrycodes: .. _omhttp.parameter.input.httpretrycodes: httpretrycodes ============== .. index:: single: omhttp; httpretrycodes single: httpretrycodes .. summary-start Lists HTTP status codes that omhttp treats as retriable errors. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpretrycodes :Scope: input :Type: array :Default: input=2xx status codes :Required?: no :Introduced: Not specified Description ----------- An array of strings that defines a list of one or more HTTP status codes that are retriable by the omhttp plugin. By default non-2xx HTTP status codes are considered retriable. Input usage ----------- .. _omhttp.parameter.input.httpretrycodes-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpRetryCodes=["500", "502", "503"] ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-embeddedipv4-anonmode.rst0000644000000000000000000000013115071746523027057 xustar0030 mtime=1760021843.801420402 29 atime=1764928597.36959214 30 ctime=1764935921.920557244 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-embeddedipv4-anonmode.rst0000664000175000017500000000311615071746523026525 0ustar00rgerrger.. _param-mmanon-embeddedipv4-anonmode: .. _mmanon.parameter.input.embeddedipv4-anonmode: embeddedIpv4.anonMode ===================== .. index:: single: mmanon; embeddedIpv4.anonMode single: embeddedIpv4.anonMode .. summary-start Defines how IPv6 addresses with embedded IPv4 parts are anonymized. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: embeddedIpv4.anonMode :Scope: input :Type: string :Default: input=zero :Required?: no :Introduced: 7.3.7 Description ----------- The available modes are ``random``, ``random-consistent``, and ``zero``. The modes ``random`` and ``random-consistent`` are very similar, in that they both anonymize IP addresses by randomizing the last bits (any number) of a given address. However, while ``random`` mode assigns a new random IP address for every address in a message, ``random-consistent`` will assign the same randomized address to every instance of the same original address. The default ``zero`` mode will do full anonymization of any number of bits and it will also normalize the address, so that no information about the original IP address is available. Also note that an anonymized IPv6 address will be normalized, meaning there will be no abbreviations, leading zeros will **not** be displayed, and capital letters in the hex numerals will be lowercase. Input usage ----------- .. _mmanon.parameter.input.embeddedipv4-anonmode-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" embeddedIpv4.anonMode="random") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-usepid.rst0000644000000000000000000000013215062756615024735 xustar0030 mtime=1758190989.187640921 30 atime=1764928594.652508689 30 ctime=1764935921.495550737 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-usepid.rst0000664000175000017500000000217715062756615024410 0ustar00rgerrger.. _param-imjournal-usepid: .. _imjournal.parameter.module.usepid: .. meta:: :tag: module:imjournal :tag: parameter:UsePid UsePid ====== .. index:: single: imjournal; UsePid single: UsePid .. summary-start Selects which journal PID field to use: ``syslog``, ``system``, or ``both``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: UsePid :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=both :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Determines the journal field that supplies the process identifier. ``syslog`` Use ``SYSLOG_PID``. ``system`` Use ``_PID``. ``both`` Try ``SYSLOG_PID`` first and fall back to ``_PID``. If neither is available, the message is parsed without a PID. Module usage ------------ .. _param-imjournal-module-usepid: .. _imjournal.parameter.module.usepid-usage: .. code-block:: rsyslog module(load="imjournal" UsePid="...") Notes ----- - Case-insensitive values are accepted. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-starvationprotection-maxreads.rst0000644000000000000000000000013215062756615030663 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.160555038 30 ctime=1764935921.760554794 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-starvationprotection-maxreads.rst0000664000175000017500000000507115062756615030332 0ustar00rgerrger.. _param-imtcp-starvationprotection-maxreads: .. _imtcp.parameter.module.starvationprotection-maxreads: StarvationProtection.MaxReads ============================= .. index:: single: imtcp; StarvationProtection.MaxReads single: StarvationProtection.MaxReads .. summary-start Limits consecutive reads per connection before switching to another session. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StarvationProtection.MaxReads :Scope: module :Type: integer :Default: module=500 :Required?: no :Introduced: 8.2504.0 Description ----------- The ``StarvationProtection.MaxReads`` parameter defines the **maximum number of consecutive requests** a worker can process for a single connection before switching to another session. This mechanism prevents any single sender from **monopolizing imtcp's processing capacity**. **Default value:** ``500`` **Allowed values:** - ``0`` → Disables starvation protection (a single sender may dominate worker time). - Any positive integer → Specifies the maximum number of consecutive reads before switching. **Behavior and Use Cases** - When a connection continuously sends data, a worker will process it **up to MaxReads times** before returning it to the processing queue. - This ensures that **other active connections** get a chance to be processed. - Particularly useful in **high-volume environments** where a few senders might otherwise consume all resources. - In **single-threaded mode**, this still provides fairness but cannot fully prevent resource exhaustion. **Scope and Overrides** - This is a **module-level parameter**, meaning it **sets the default** for all ``imtcp`` listeners. - Each listener instance can override this by setting the ``starvationProtection.maxReads`` **listener parameter**. **Example Configuration** The following sets a **default of 300** reads per session before switching to another connection, while overriding it to **1000** for a specific listener: .. code-block:: none module(load="imtcp" StarvationProtection.MaxReads="300") # Default for all listeners input(type="imtcp" port="514" starvationProtection.MaxReads="1000") # Overrides default If ``StarvationProtection.MaxReads`` is not explicitly set, the default of ``500`` will be used. Module usage ------------ .. _param-imtcp-module-starvationprotection-maxreads: .. _imtcp.parameter.module.starvationprotection-maxreads-usage: .. code-block:: rsyslog module(load="imtcp" starvationProtection.maxReads="300") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-esversion-major.rst0000644000000000000000000000013215071746523027732 xustar0030 mtime=1760021843.823420749 30 atime=1764928599.508657666 30 ctime=1764935922.200561531 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-esversion-major.rst0000664000175000017500000000313715071746523027402 0ustar00rgerrger.. _param-omelasticsearch-esversion-major: .. _omelasticsearch.parameter.module.esversion-major: .. _omelasticsearch.parameter.module.esVersion.major: esVersion.major =============== .. index:: single: omelasticsearch; esVersion.major single: esVersion.major .. summary-start Deprecated manual override for the detected Elasticsearch/OpenSearch major version. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: esVersion.major :Scope: action :Type: integer :Default: action=0 (overridden when detection succeeds) :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- .. warning:: This parameter is deprecated as of rsyslog 8.2510.0. The module performs a best-effort probe at startup to discover the target platform (Elasticsearch or OpenSearch) and its version, and ``esVersion.major`` is automatically updated with the detected major version when the probe succeeds. .. versionchanged:: 8.2510.0 Automatically overridden when startup platform detection succeeds. This setting is only consulted when detection fails or when no servers are reachable during startup. Administrators may keep it configured as a fallback for air-gapped or permission-restricted environments, but future releases may remove the option entirely. Action usage ------------ .. _param-omelasticsearch-action-esversion-major: .. _omelasticsearch.parameter.action.esversion-major: .. code-block:: rsyslog action(type="omelasticsearch" esVersion.major="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-dynpipelinename.rst0000644000000000000000000000013215062756615027773 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.558659196 30 ctime=1764935922.190561378 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-dynpipelinename.rst0000664000175000017500000000172015062756615027437 0ustar00rgerrger.. _param-omelasticsearch-dynpipelinename: .. _omelasticsearch.parameter.module.dynpipelinename: dynPipelineName =============== .. index:: single: omelasticsearch; dynPipelineName single: dynPipelineName .. summary-start Treat `pipelineName` as a template name. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: dynPipelineName :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If enabled, the value of `pipelineName` is taken as a template whose result selects the pipeline. Action usage ------------ .. _param-omelasticsearch-action-dynpipelinename: .. _omelasticsearch.parameter.action.dynpipelinename: .. code-block:: rsyslog action(type="omelasticsearch" dynPipelineName="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-restpathtimeout.rst0000644000000000000000000000013015114522477026211 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.480642783 28 ctime=1764935922.4075647 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-restpathtimeout.rst0000664000175000017500000000150415114522477025657 0ustar00rgerrger.. _param-omhttp-restpathtimeout: .. _omhttp.parameter.input.restpathtimeout: restpathtimeout =============== .. index:: single: omhttp; restpathtimeout single: restpathtimeout .. summary-start Specifies how long omhttp waits for a dynamic REST path template to resolve. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: restpathtimeout :Scope: input :Type: integer :Default: input=none :Required?: no :Introduced: Not specified Description ----------- Timeout value for the configured :ref:`param-omhttp-restpath`. Input usage ----------- .. _omhttp.parameter.input.restpathtimeout-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" restPathTimeout="2000" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-ignoreownmessages.rst0000644000000000000000000000013215062756615030541 xustar0030 mtime=1758190989.196641049 30 atime=1764928596.891577478 30 ctime=1764935921.865556402 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-ignoreownmessages.rst0000664000175000017500000000226415062756615030211 0ustar00rgerrger.. _param-imuxsock-syssock-ignoreownmessages: .. _imuxsock.parameter.module.syssock-ignoreownmessages: SysSock.IgnoreOwnMessages ========================= .. index:: single: imuxsock; SysSock.IgnoreOwnMessages single: SysSock.IgnoreOwnMessages .. summary-start Ignores messages that originate from the same rsyslogd instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.IgnoreOwnMessages :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 7.3.7 Description ----------- Ignores messages that originated from the same instance of rsyslogd. There usually is no reason to receive messages from ourselves. This setting is vital when writing messages to the systemd journal. .. seealso:: See :doc:`omjournal <../../configuration/modules/omjournal>` module documentation for a more in-depth description. Module usage ------------ .. _param-imuxsock-module-syssock-ignoreownmessages: .. _imuxsock.parameter.module.syssock-ignoreownmessages-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.ignoreOwnMessages="off") See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-failonchownfailure.rst0000644000000000000000000000013215062756615026576 xustar0030 mtime=1758190989.207641205 30 atime=1764928600.165677764 30 ctime=1764935922.295562985 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-failonchownfailure.rst0000664000175000017500000000323015062756615026240 0ustar00rgerrger.. _param-omfile-failonchownfailure: .. _omfile.parameter.module.failonchownfailure: failOnChOwnFailure ================== .. index:: single: omfile; failOnChOwnFailure single: failOnChOwnFailure .. summary-start This option modifies behaviour of file creation. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: failOnChOwnFailure :Scope: action :Type: boolean :Default: action=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This option modifies behaviour of file creation. If different owners or groups are specified for new files or directories and rsyslogd fails to set these new owners or groups, it will log an error and NOT write to the file in question if that option is set to "on". If it is set to "off", the error will be ignored and processing continues. Keep in mind, that the files in this case may be (in)accessible by people who should not have permission. The default is "on". Action usage ------------ .. _param-omfile-action-failonchownfailure: .. _omfile.parameter.action.failonchownfailure: .. code-block:: rsyslog action(type="omfile" failOnChOwnFailure="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.failonchownfailure: - $FailOnCHOwnFailure — maps to failOnChOwnFailure (status: legacy) .. index:: single: omfile; $FailOnCHOwnFailure single: $FailOnCHOwnFailure See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-target.rst0000644000000000000000000000013215114522477024227 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.471642562 30 ctime=1764935922.159560903 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-target.rst0000664000175000017500000000145615114522477023701 0ustar00rgerrger.. _param-omdtls-target: .. _omdtls.parameter.input.target: target ====== .. index:: single: omdtls; target single: target .. summary-start Specifies the destination host name or IP address for omdtls. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: target :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: v8.2402.0 Description ----------- Specifies the target hostname or IP address to send log messages to. This parameter must be set; otherwise the action has no destination and messages cannot be delivered. Input usage ----------- .. _omdtls.parameter.input.target-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpignorablecodes.rst0000644000000000000000000000013215114522477026632 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.478642734 30 ctime=1764935922.385564363 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpignorablecodes.rst0000664000175000017500000000160215114522477026275 0ustar00rgerrger.. _param-omhttp-httpignorablecodes: .. _omhttp.parameter.input.httpignorablecodes: httpignorablecodes ================== .. index:: single: omhttp; httpignorablecodes single: httpignorablecodes .. summary-start Lists HTTP status codes that omhttp never retries. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpignorablecodes :Scope: input :Type: array :Default: input=none :Required?: no :Introduced: Not specified Description ----------- An array of strings that defines a list of one or more HTTP status codes that are not retriable by the omhttp plugin. Input usage ----------- .. _omhttp.parameter.input.httpignorablecodes-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpIgnorableCodes=["400", "404"] ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-azurehost.rst0000644000000000000000000000013215114522477027071 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.467642464 30 ctime=1764935922.111560168 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-azurehost.rst0000664000175000017500000000220215114522477026531 0ustar00rgerrger.. _param-omazureeventhubs-azurehost: .. _omazureeventhubs.parameter.input.azurehost: azurehost ========= .. index:: single: omazureeventhubs; azurehost single: azurehost .. summary-start Sets the fully qualified Event Hubs namespace host the action connects to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: azurehost :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- Specifies the fully qualified domain name (FQDN) of the Event Hubs instance that the rsyslog output plugin should connect to. The format of the hostname should be ``.servicebus.windows.net``, where ```` is the name of the Event Hubs namespace that was created in Microsoft Azure. This setting is required unless ``amqpAddress`` supplies the complete connection string. Input usage ----------- .. _omazureeventhubs.parameter.input.azurehost-usage: .. code-block:: rsyslog action(type="omazureeventhubs" azureHost="example.servicebus.windows.net" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-rule.rst0000644000000000000000000000013115071746523024741 xustar0030 mtime=1760021843.819420686 30 atime=1764928598.410624049 29 ctime=1764935922.07055954 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-rule.rst0000664000175000017500000000164215071746523024411 0ustar00rgerrger.. _param-mmnormalize-rule: .. _mmnormalize.parameter.action.rule: rule ==== .. index:: single: mmnormalize; rule single: rule .. summary-start Builds the rulebase from an array of strings. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: rule :Scope: action :Type: array :Default: none :Required?: yes :Introduced: 8.26.0 Description ----------- .. versionadded:: 8.26.0 Contains an array of strings which will be put together as the rulebase. This parameter or :ref:`param-mmnormalize-rulebase` MUST be given, because normalization can only happen based on a rulebase. Action usage ------------- .. _param-mmnormalize-action-rule: .. _mmnormalize.parameter.action.rule-usage: .. code-block:: rsyslog action(type="mmnormalize" rule=["rule=:%host:word% %ip:ipv4% user was logged out"]) See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-amqp_address.rst0000644000000000000000000000013115114522477027507 xustar0030 mtime=1764926783.029631711 29 atime=1764926783.46664244 30 ctime=1764935922.104560061 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-amqp_address.rst0000664000175000017500000000251515114522477027157 0ustar00rgerrger.. _param-omazureeventhubs-amqp_address: .. _omazureeventhubs.parameter.input.amqp_address: amqp_address ============ .. index:: single: omazureeventhubs; amqp_address single: amqp_address .. summary-start Provides a full AMQPS connection string that overrides individual Azure settings. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: amqp_address :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2304 Description ----------- Specifies the "Event Hubs connection string", a full AMQPS URL used to connect to the target Event Hubs instance. When this parameter is set, the host, key name, and key are parsed from the URL, overriding ``azureHost``, ``azureKeyName``, and ``azureKey``. The port is not parsed from the URL; it always defaults to ``5671`` and any configured ``azurePort`` value is ignored. A sample Event Hubs connection string URL is: .. code-block:: none amqps://:@.servicebus.windows.net/ Input usage ----------- .. _omazureeventhubs.parameter.input.amqp_address-usage: .. code-block:: rsyslog action(type="omazureeventhubs" amqpAddress="amqps://user:key@namespace.servicebus.windows.net/hub" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-defaultfacility.rst0000644000000000000000000000013215062756615026615 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.642508381 30 ctime=1764935921.465550278 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-defaultfacility.rst0000664000175000017500000000242315062756615026262 0ustar00rgerrger.. _param-imjournal-defaultfacility: .. _imjournal.parameter.module.defaultfacility: .. meta:: :tag: module:imjournal :tag: parameter:DefaultFacility DefaultFacility =============== .. index:: single: imjournal; DefaultFacility single: DefaultFacility .. summary-start Fallback facility used if a journal entry lacks ``SYSLOG_FACILITY``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: DefaultFacility :Scope: module :Type: word :Default: module=LOG_USER :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the facility assigned to messages missing the ``SYSLOG_FACILITY`` field. Values may be given as facility names or numbers. Module usage ------------ .. _param-imjournal-module-defaultfacility: .. _imjournal.parameter.module.defaultfacility-usage: .. code-block:: rsyslog module(load="imjournal" DefaultFacility="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournaldefaultfacility: - $ImjournalDefaultFacility — maps to DefaultFacility (status: legacy) .. index:: single: imjournal; $ImjournalDefaultFacility single: $ImjournalDefaultFacility See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-batch-maxbytes.rst0000644000000000000000000000013115114522477025664 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.475642661 30 ctime=1764935922.356563919 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-batch-maxbytes.rst0000664000175000017500000000166015114522477025334 0ustar00rgerrger.. _param-omhttp-batch-maxbytes: .. _omhttp.parameter.input.batch-maxbytes: batch.maxbytes ============== .. index:: single: omhttp; batch.maxbytes single: batch.maxbytes .. summary-start Limits the serialized size of each batched HTTP payload. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: batch.maxbytes :Scope: input :Type: Size :Default: input=10485760 (10MB) :Required?: no :Introduced: Not specified Description ----------- ``batch.maxbytes`` and ``maxbytes`` do the same thing, ``maxbytes`` is included for backwards compatibility. This parameter specifies the maximum size in bytes for each batch. Input usage ----------- .. _omhttp.parameter.input.batch-maxbytes-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" batch="on" batchMaxBytes="5m" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-topicconfparam.rst0000644000000000000000000000013215062756615026062 xustar0030 mtime=1758190989.211641261 30 atime=1764928601.489718218 30 ctime=1764935922.486565909 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-topicconfparam.rst0000664000175000017500000000160515062756615025530 0ustar00rgerrger.. _param-omkafka-topicconfparam: .. _omkafka.parameter.module.topicconfparam: TopicConfParam ============== .. index:: single: omkafka; TopicConfParam single: TopicConfParam .. summary-start Arbitrary librdkafka topic options `name=value`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: TopicConfParam :Scope: action :Type: array[string] :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- In essence the same as ``ConfParam``, but for Kafka topic options. Action usage ------------ .. _param-omkafka-action-topicconfparam: .. _omkafka.parameter.action.topicconfparam: .. code-block:: rsyslog action(type="omkafka" topicConfParam=["acks=all"]) Notes ----- - Multiple values may be set using array syntax. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-traptype.rst0000644000000000000000000000013115071746523024621 xustar0029 mtime=1760021843.83042086 30 atime=1764928602.792757977 30 ctime=1764935922.590567502 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-traptype.rst0000664000175000017500000000271515071746523024273 0ustar00rgerrger.. _param-omsnmp-traptype: .. _omsnmp.parameter.module.traptype: TrapType ======== .. index:: single: omsnmp; TrapType single: TrapType .. summary-start Selects the SNMPv1 generic trap type. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: TrapType :Scope: module :Type: integer :Default: module=6 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- There are only 7 Possible trap types defined which can be used here. These trap types are: .. code-block:: none 0 = SNMP_TRAP_COLDSTART 1 = SNMP_TRAP_WARMSTART 2 = SNMP_TRAP_LINKDOWN 3 = SNMP_TRAP_LINKUP 4 = SNMP_TRAP_AUTHFAIL 5 = SNMP_TRAP_EGPNEIGHBORLOSS 6 = SNMP_TRAP_ENTERPRISESPECIFIC .. note:: Any other value will default to 6 automatically. This configuration parameter is used for **SNMPv1** only. It has no effect if **SNMPv2** is used. Module usage ------------ .. _param-omsnmp-module-traptype: .. _omsnmp.parameter.module.traptype-usage: .. code-block:: rsyslog action(type="omsnmp" trapType="6") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmptraptype: - $actionsnmptraptype — maps to TrapType (status: legacy) .. index:: single: omsnmp; $actionsnmptraptype single: $actionsnmptraptype See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-permit-atsignsinhostname.rst0000644000000000000000000000013215062756615030125 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.264772365 30 ctime=1764935922.625568037 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-permit-atsignsinhostname.rst0000664000175000017500000000221615062756615027572 0ustar00rgerrger.. _param-pmrfc3164-permit-atsignsinhostname: .. _pmrfc3164.parameter.module.permit-atsignsinhostname: .. _pmrfc3164.parameter.module.permit.AtSignsInHostname: permit.AtSignsInHostname ========================= .. index:: single: pmrfc3164; permit.AtSignsInHostname single: permit.AtSignsInHostname .. summary-start Allow ``@`` in hostnames, typically from syslog-ng relays. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: permit.AtSignsInHostname :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.2508.0 Description ----------- This option allows hostnames to include at-sign characters, which is useful when syslog-ng relays prefix source names with ``@``. Module usage ------------ .. _param-pmrfc3164-module-permit-atsignsinhostname: .. _pmrfc3164.parameter.module.permit-atsignsinhostname-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" permit.AtSignsInHostname="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-broker.rst0000644000000000000000000000013215062756615024341 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.389715165 30 ctime=1764935922.443565251 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-broker.rst0000664000175000017500000000134615062756615024011 0ustar00rgerrger.. _param-omkafka-broker: .. _omkafka.parameter.module.broker: Broker ====== .. index:: single: omkafka; Broker single: Broker .. summary-start List of Kafka brokers in `host:port` form. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Broker :Scope: action :Type: array[string] :Default: action=localhost:9092 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Specifies the broker(s) to use. Action usage ------------ .. _param-omkafka-action-broker: .. _omkafka.parameter.action.broker: .. code-block:: rsyslog action(type="omkafka" Broker=["host1:9092","host2:9092"]) See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-address.rst0000644000000000000000000000013115114522477024353 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.461642317 29 ctime=1764935921.64855308 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-address.rst0000664000175000017500000000145515114522477024025 0ustar00rgerrger.. _param-imrelp-address: .. _imrelp.parameter.input.address: address ======= .. index:: single: imrelp; address single: address .. summary-start Forces the RELP listener to bind to the specified local IP address or hostname. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: address :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: 8.37.0 Description ----------- Bind the RELP server to that address. If not specified, the server will be bound to the wildcard address. Input usage ----------- .. _param-imrelp-input-address-usage: .. _imrelp.parameter.input.address-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" address="203.0.113.5") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-bulkid.rst0000644000000000000000000000013015062756615026062 xustar0029 mtime=1758190989.20164112 30 atime=1764928599.726664337 29 ctime=1764935922.18156124 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-bulkid.rst0000664000175000017500000000150315062756615025527 0ustar00rgerrger.. _param-omelasticsearch-bulkid: .. _omelasticsearch.parameter.module.bulkid: bulkid ====== .. index:: single: omelasticsearch; bulkid single: bulkid .. summary-start Unique identifier assigned to each record. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: bulkid :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Specifies a static value or template used as the document `_id`. Required with `writeoperation="create"`. Action usage ------------ .. _param-omelasticsearch-action-bulkid: .. _omelasticsearch.parameter.action.bulkid: .. code-block:: rsyslog action(type="omelasticsearch" bulkid="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-mode.rst0000644000000000000000000000013215062756615023635 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.883485026 30 ctime=1764935921.410549436 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-mode.rst0000664000175000017500000000311015062756615023274 0ustar00rgerrger.. _param-imfile-mode: .. _imfile.parameter.module.mode: .. _imfile.parameter.mode: Mode ==== .. index:: single: imfile; Mode single: Mode .. summary-start Selects `inotify`, `polling`, or `fen` mode for file monitoring. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: Mode :Scope: module :Type: word :Default: module=inotify :Required?: no :Introduced: 8.1.5 Description ----------- This specifies if imfile shall run in inotify ("inotify") or polling ("polling") mode. Traditionally, imfile used polling mode, which is much more resource-intense (and slower) than inotify mode. It is suggested that users turn on "polling" mode only if they experience strange problems in inotify mode. In theory, there should never be a reason to enable "polling" mode and later versions will most probably remove it. If a legacy "$ModLoad" statement is used, the default is *polling*. This default was kept to prevent problems with old configurations. It might change in the future. On Solaris, the FEN API is used instead of INOTIFY. You can set the mode to fen or inotify (which is automatically mapped to fen on Solaris OS). Please note that the FEN is limited compared to INOTIFY. Deep wildcard matches may not work because of the API limits for now. Module usage ------------ .. _param-imfile-module-mode: .. _imfile.parameter.module.mode-usage: .. code-block:: rsyslog module(load="imfile" Mode="inotify") Notes ----- - Solaris uses the FEN API; deep wildcard matches may fail. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-usepidfromsystem.rst0000644000000000000000000000013215062756615027066 xustar0030 mtime=1758190989.187640921 30 atime=1764928594.646508504 30 ctime=1764935921.497550768 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-usepidfromsystem.rst0000664000175000017500000000223115062756615026530 0ustar00rgerrger.. _param-imjournal-usepidfromsystem: .. _imjournal.parameter.module.usepidfromsystem: .. meta:: :tag: module:imjournal :tag: parameter:UsePidFromSystem UsePidFromSystem ================ .. index:: single: imjournal; UsePidFromSystem single: UsePidFromSystem .. summary-start Use ``_PID`` instead of ``SYSLOG_PID`` as the process identifier. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: UsePidFromSystem :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Retrieves the trusted ``_PID`` field from the journal instead of ``SYSLOG_PID``. This option overrides ``UsePid`` and is deprecated; use ``UsePid="system"`` for equivalent behavior. Module usage ------------ .. _param-imjournal-module-usepidfromsystem: .. _imjournal.parameter.module.usepidfromsystem-usage: .. code-block:: rsyslog module(load="imjournal" UsePidFromSystem="...") Notes ----- - Legacy documentation referred to this as a ``binary`` option. - Deprecated; prefer ``UsePid``. See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-restpath.rst0000644000000000000000000000013215114522477024604 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.479642759 30 ctime=1764935922.404564654 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-restpath.rst0000664000175000017500000000154515114522477024255 0ustar00rgerrger.. _param-omhttp-restpath: .. _omhttp.parameter.input.restpath: restpath ======== .. index:: single: omhttp; restpath single: restpath .. summary-start Sets the REST path portion of the request URL used by omhttp. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: restpath :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The REST path you want to use. Do not include the leading slash character. If the full path looks like ``localhost:5000/my/path``, ``restpath`` should be ``my/path``. Input usage ----------- .. _omhttp.parameter.input.restpath-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" restPath="logs/v1/events" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-maxsessions.rst0000644000000000000000000000013215062756615025134 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.136554301 30 ctime=1764935921.732554366 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-maxsessions.rst0000664000175000017500000000270015062756615024577 0ustar00rgerrger.. _param-imtcp-maxsessions: .. _imtcp.parameter.module.maxsessions: .. _imtcp.parameter.input.maxsessions: MaxSessions =========== .. index:: single: imtcp; MaxSessions single: MaxSessions .. summary-start Sets the maximum number of sessions supported. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: MaxSessions :Scope: module, input :Type: integer :Default: module=200, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the maximum number of sessions supported. This must be set before the first $InputTCPServerRun directive. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-maxsessions: .. _imtcp.parameter.module.maxsessions-usage: .. code-block:: rsyslog module(load="imtcp" maxSessions="500") Input usage ----------- .. _param-imtcp-input-maxsessions: .. _imtcp.parameter.input.maxsessions-usage: .. code-block:: rsyslog input(type="imtcp" port="514" maxSessions="500") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpmaxsessions: - $InputTCPMaxSessions — maps to MaxSessions (status: legacy) .. index:: single: imtcp; $InputTCPMaxSessions single: $InputTCPMaxSessions See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-sig-provider.rst0000644000000000000000000000013215062756615025331 xustar0030 mtime=1758190989.208641219 30 atime=1764928600.190678529 30 ctime=1764935922.323563414 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-sig-provider.rst0000664000175000017500000000214215062756615024774 0ustar00rgerrger.. _param-omfile-sig-provider: .. _omfile.parameter.module.sig-provider: sig.Provider ============ .. index:: single: omfile; sig.Provider single: sig.Provider .. summary-start Selects a signature provider for log signing. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: sig.Provider :Scope: action :Type: word :Default: action=no signature provider :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Selects a signature provider for log signing. By selecting a provider, the signature feature is turned on. Currently there is one signature provider available: ":doc:`ksi_ls12 <../../configuration/modules/sigprov_ksi12>`". Previous signature providers ":doc:`gt <../../configuration/modules/sigprov_gt>`" and ":doc:`ksi <../../configuration/modules/sigprov_ksi>`" are deprecated. Action usage ------------ .. _param-omfile-action-sig-provider: .. _omfile.parameter.action.sig-provider: .. code-block:: rsyslog action(type="omfile" sig.Provider="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmfields-separator.rst0000644000000000000000000000013215071746523025241 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.886607994 30 ctime=1764935921.990558316 rsyslog-8.2512.0/doc/source/reference/parameters/mmfields-separator.rst0000664000175000017500000000257115071746523024712 0ustar00rgerrger.. _param-mmfields-separator: .. _mmfields.parameter.input.separator: separator ========= .. index:: single: mmfields; separator single: separator .. summary-start Sets the character that separates fields when mmfields extracts them. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmfields`. :Name: separator :Scope: input :Type: char :Default: ``,`` :Required?: no :Introduced: 7.5.1 Description ----------- This parameter specifies the character used to separate fields. The module currently accepts only a single character. Multi-character separators are not supported by ``mmfields`` but can be implemented via the RainerScript method. CEF does not require multi-character separators, so this limitation is usually acceptable. If you need multi-character separators in ``mmfields``, please request this feature on the rsyslog mailing list and describe the use case; support can be added when there is a documented requirement. The fields are named f\ *nbr*, where *nbr* is the field number starting with one and being incremented for each field. Input usage ----------- .. _param-mmfields-input-separator-usage: .. _mmfields.parameter.input.separator-usage: .. code-block:: rsyslog module(load="mmfields") action(type="mmfields" separator=",") See also -------- This parameter is part of the :doc:`../../configuration/modules/mmfields` module. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-tls-mycert.rst0000644000000000000000000000013215062756615026715 xustar0030 mtime=1758190989.205641176 30 atime=1764928599.693663327 30 ctime=1764935922.248562266 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-tls-mycert.rst0000664000175000017500000000160015062756615026356 0ustar00rgerrger.. _param-omelasticsearch-tls-mycert: .. _omelasticsearch.parameter.module.tls-mycert: .. _omelasticsearch.parameter.module.tls.mycert: tls.mycert ========== .. index:: single: omelasticsearch; tls.mycert single: tls.mycert .. summary-start Client certificate for mutual TLS authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: tls.mycert :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- PEM file containing the client certificate presented to Elasticsearch. Action usage ------------ .. _param-omelasticsearch-action-tls-mycert: .. _omelasticsearch.parameter.action.tls-mycert: .. code-block:: rsyslog action(type="omelasticsearch" tls.mycert="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-authmode.rst0000644000000000000000000000013115103346332025330 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.788482101 29 ctime=1764935921.35854864 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-authmode.rst0000664000175000017500000000223215103346332024774 0ustar00rgerrger.. _param-imdtls-tls-authmode: .. _imdtls.parameter.input.tls-authmode: tls.authMode ============ .. index:: single: imdtls; tls.authMode single: tls.authMode .. summary-start Defines the mutual authentication method used for DTLS clients. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.authMode :Scope: input :Type: string :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Sets the mode used for mutual authentication. Supported values are: * **fingerprint**: Authentication based on certificate fingerprint. * **name**: Authentication based on the ``subjectAltName`` and, as a fallback, the ``subject common name``. * **certvalid**: Requires a valid certificate for authentication. If any other value is provided, or if the parameter is omitted, anonymous authentication (**certanon**) is used, which does not require a client certificate. Input usage ----------- .. _imdtls.parameter.input.tls-authmode-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.authMode="certvalid") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-allowunsignedcerts.rst0000644000000000000000000000013215114522477030040 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.468642489 30 ctime=1764935922.125560383 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-allowunsignedcerts.rst0000664000175000017500000000202715114522477027505 0ustar00rgerrger.. _param-omclickhouse-allowunsignedcerts: .. _omclickhouse.parameter.input.allowunsignedcerts: allowUnsignedCerts ================== .. index:: single: omclickhouse; allowUnsignedCerts single: allowUnsignedCerts single: omclickhouse; allowunsignedcerts single: allowunsignedcerts .. summary-start Allows connections to servers that present unsigned TLS certificates. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: allowUnsignedCerts :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: not specified Description ----------- The module accepts connections to servers, which have unsigned certificates. If this parameter is disabled, the module will verify whether the certificates are authentic. Input usage ----------- .. _omclickhouse.parameter.input.allowunsignedcerts-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" allowUnsignedCerts="off") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-skipverifyhost.rst0000644000000000000000000000013215114522477027215 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.470642538 30 ctime=1764935922.143560658 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-skipverifyhost.rst0000664000175000017500000000203515114522477026661 0ustar00rgerrger.. _param-omclickhouse-skipverifyhost: .. _omclickhouse.parameter.input.skipverifyhost: skipVerifyHost ============== .. index:: single: omclickhouse; skipVerifyHost single: skipVerifyHost single: omclickhouse; skipverifyhost single: skipverifyhost .. summary-start Controls whether the module disables host name verification for HTTPS connections. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: skipVerifyHost :Scope: input :Type: boolean :Default: off :Required?: no :Introduced: not specified Description ----------- If ``"on"``, this will set the curl ``CURLOPT_SSL_VERIFYHOST`` option to ``0``. .. warning:: You are strongly discouraged to set this to ``"on"``. It is primarily useful only for debugging or testing. Input usage ----------- .. _omclickhouse.parameter.input.skipverifyhost-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" skipVerifyHost="on") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-maxdatasize.rst0000644000000000000000000000013215114522477025241 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.462642342 30 ctime=1764935921.662553294 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-maxdatasize.rst0000664000175000017500000000207315114522477024707 0ustar00rgerrger.. _param-imrelp-maxdatasize: .. _imrelp.parameter.input.maxdatasize: maxDataSize =========== .. index:: single: imrelp; maxDataSize single: maxDataSize .. summary-start Sets the max message size the RELP listener accepts before oversize handling. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: maxDataSize :Scope: input :Type: size_nbr :Default: input=:doc:`global(maxMessageSize) <../../rainerscript/global>` :Required?: no :Introduced: Not documented Description ----------- Sets the max message size (in bytes) that can be received. Messages that are too long are handled as specified in parameter :ref:`param-imrelp-oversizemode`. Note that maxDataSize cannot be smaller than the global parameter :doc:`global(maxMessageSize) <../../rainerscript/global>`. Input usage ----------- .. _param-imrelp-input-maxdatasize-usage: .. _imrelp.parameter.input.maxdatasize-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" maxDataSize="10k") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-subject-text.rst0000644000000000000000000000013215114522477025336 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.486642931 30 ctime=1764935922.517566384 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-subject-text.rst0000664000175000017500000000230015114522477024775 0ustar00rgerrger.. _param-ommail-subject-text: .. _ommail.parameter.input.subject-text: subjectText =========== .. index:: single: ommail; subjectText single: subjectText .. summary-start Sets a fixed subject line instead of generating one from a template. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: subjectText :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: 8.5.0 Description ----------- Use this parameter to set a **constant** subject text. Choose :ref:`param-ommail-subject-template` when the subject should be generated from a template. The ``subjectTemplate`` and ``subjectText`` parameters cannot both be configured within a single action. If neither is specified, a default, non-configurable subject line will be generated. Input usage ------------ .. _ommail.parameter.input.subject-text-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" subjectText="rsyslog detected disk problem" ) See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpcontenttype.rst0000644000000000000000000000013115114522477026225 xustar0030 mtime=1764926783.032631784 29 atime=1764926783.47764271 30 ctime=1764935922.376564225 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpcontenttype.rst0000664000175000017500000000217515114522477025677 0ustar00rgerrger.. _param-omhttp-httpcontenttype: .. _omhttp.parameter.input.httpcontenttype: httpcontenttype =============== .. index:: single: omhttp; httpcontenttype single: httpcontenttype .. summary-start Overrides the HTTP ``Content-Type`` header that omhttp sends with each request. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpcontenttype :Scope: input :Type: word :Default: input=application/json; charset=utf-8 :Required?: no :Introduced: Not specified Description ----------- The HTTP ``Content-Type`` header sent with each request. This parameter will override other defaults. If a batching mode is specified, the correct content type is automatically configured. The ``Content-Type`` header can also be configured using the :ref:`param-omhttp-httpheaders` parameter; configure it in only one place. Input usage ----------- .. _omhttp.parameter.input.httpcontenttype-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpContentType="application/cloudevents+json" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-skipverifyhost.rst0000644000000000000000000000013215114522477026043 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.481642808 30 ctime=1764935922.421564914 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-skipverifyhost.rst0000664000175000017500000000176015114522477025513 0ustar00rgerrger.. _param-omhttp-skipverifyhost: .. _omhttp.parameter.input.skipverifyhost: skipverifyhost ============== .. index:: single: omhttp; skipverifyhost single: skipverifyhost .. summary-start Controls whether omhttp verifies the HTTPS server hostname. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: skipverifyhost :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- If ``"on"``, this will set the curl `CURLOPT_SSL_VERIFYHOST `_ option to ``0``. You are strongly discouraged to set this to ``"on"``. It is primarily useful only for debugging or testing. Input usage ----------- .. _omhttp.parameter.input.skipverifyhost-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" skipVerifyHost="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-rebindinterval.rst0000644000000000000000000000013115062756615027621 xustar0030 mtime=1758190989.203641148 29 atime=1764928599.78166602 30 ctime=1764935922.220561837 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-rebindinterval.rst0000664000175000017500000000166315062756615027274 0ustar00rgerrger.. _param-omelasticsearch-rebindinterval: .. _omelasticsearch.parameter.module.rebindinterval: rebindinterval ============== .. index:: single: omelasticsearch; rebindinterval single: rebindinterval .. summary-start Operations after which to reconnect; `-1` disables periodic reconnect. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: rebindinterval :Scope: action :Type: integer :Default: action=-1 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- After this many operations the module drops and re-establishes the connection. Useful behind load balancers. Action usage ------------ .. _param-omelasticsearch-action-rebindinterval: .. _omelasticsearch.parameter.action.rebindinterval: .. code-block:: rsyslog action(type="omelasticsearch" rebindinterval="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-port.rst0000644000000000000000000000013215114522477023701 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.485642906 30 ctime=1764935922.511566292 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-port.rst0000664000175000017500000000240215114522477023343 0ustar00rgerrger.. _param-ommail-port: .. _ommail.parameter.input.port: port ==== .. index:: single: ommail; port single: port .. summary-start Sets the SMTP port number or service name that ommail uses to send mail. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: port :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: 8.5.0 Description ----------- Port number or name of the SMTP port to be used. While the module may fall back to port 25 in some legacy scenarios, this parameter is required and must be set explicitly in modern configurations. Input usage ------------ .. _ommail.parameter.input.port-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailsmtpport: - $ActionMailSMTPPort — maps to port (status: legacy) .. index:: single: ommail; $ActionMailSMTPPort single: $ActionMailSMTPPort See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-compress-level.rst0000644000000000000000000000013115114522477025711 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.476642685 30 ctime=1764935922.365564057 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-compress-level.rst0000664000175000017500000000220115114522477025351 0ustar00rgerrger.. _param-omhttp-compress-level: .. _omhttp.parameter.input.compress-level: compress.level ============== .. index:: single: omhttp; compress.level single: compress.level .. summary-start Sets the zlib compression level used when :ref:`param-omhttp-compress` is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: compress.level :Scope: input :Type: integer :Default: input=-1 :Required?: no :Introduced: Not specified Description ----------- Specify the zlib compression level if :ref:`param-omhttp-compress` is enabled. Check the `zlib manual `_ for further documentation. ``-1`` is the default value that strikes a balance between best speed and best compression. ``0`` disables compression. ``1`` results in the fastest compression. ``9`` results in the best compression. Input usage ----------- .. _omhttp.parameter.input.compress-level-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" compress="on" compressLevel="9" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-deletestateonfilemove.rst0000644000000000000000000000013215062756615027300 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.899485519 30 ctime=1764935921.379548961 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-deletestateonfilemove.rst0000664000175000017500000000317415062756615026751 0ustar00rgerrger.. _param-imfile-deletestateonfilemove: .. _imfile.parameter.input.deletestateonfilemove: .. _imfile.parameter.deletestateonfilemove: deleteStateOnFileMove ===================== .. index:: single: imfile; deleteStateOnFileMove single: deleteStateOnFileMove .. summary-start Removes the state file when a monitored file is moved or renamed. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: deleteStateOnFileMove :Scope: module, input :Type: boolean :Default: module=off; input=inherits module :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- When set to ``on`` at module scope, the state file for a monitored file is removed when that file is moved or rotated away. By default the state file is kept. The input parameter controls whether the state file is deleted when its associated file is moved or renamed. It inherits the module setting unless explicitly configured. Enabling it prevents orphaned state files. Module usage ------------ .. _param-imfile-module-deletestateonfilemove: .. _imfile.parameter.module.deletestateonfilemove-usage: .. code-block:: rsyslog module(load="imfile" deleteStateOnFileMove="on") Input usage ----------- .. _param-imfile-input-deletestateonfilemove: .. _imfile.parameter.input.deletestateonfilemove-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" deleteStateOnFileMove="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-discardtruncatedmsg.rst0000644000000000000000000000013215062756615026612 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.219556849 30 ctime=1764935921.709554014 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-discardtruncatedmsg.rst0000664000175000017500000000255515062756615026265 0ustar00rgerrger.. _param-imtcp-discardtruncatedmsg: .. _imtcp.parameter.module.discardtruncatedmsg: .. _imtcp.parameter.input.discardtruncatedmsg: DiscardTruncatedMsg =================== .. index:: single: imtcp; DiscardTruncatedMsg single: DiscardTruncatedMsg .. summary-start Discards data beyond the truncation point in octet-stuffing mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: DiscardTruncatedMsg :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Normally when a message is truncated in octet stuffing mode the part that is cut off is processed as the next message. When this parameter is activated, the part that is cut off after a truncation is discarded and not processed. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-discardtruncatedmsg: .. _imtcp.parameter.module.discardtruncatedmsg-usage: .. code-block:: rsyslog module(load="imtcp" discardTruncatedMsg="on") Input usage ----------- .. _param-imtcp-input-discardtruncatedmsg: .. _imtcp.parameter.input.discardtruncatedmsg-usage: .. code-block:: rsyslog input(type="imtcp" port="514" discardTruncatedMsg="on") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-mode.rst0000644000000000000000000000013115103346332024710 xustar0029 mtime=1762512090.62717594 30 atime=1764928597.934609466 30 ctime=1764935922.001558484 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-mode.rst0000664000175000017500000000245615103346332024364 0ustar00rgerrger.. _param-mmjsonparse-mode: .. _mmjsonparse.parameter.mode: mode ==== .. index:: single: mmjsonparse; mode single: mode single: parsing mode .. summary-start Specifies the parsing mode for JSON content detection. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: mode :Scope: action :Type: string :Default: cookie :Required?: no :Introduced: 8.2506.0 Description ----------- Sets the parsing mode to determine how JSON content is detected and processed. - **cookie** (default): Legacy CEE cookie mode. Expects messages to begin with the configured cookie (default "@cee:") followed by JSON content. This preserves backward compatibility with existing configurations. - **find-json**: Scans the message to locate the first valid top-level JSON object "{...}" regardless of its position. The module uses a tokenizer-aware scanner that respects quotes and escapes to find complete JSON objects. Input usage ----------- .. _mmjsonparse.parameter.mode-usage: .. code-block:: rsyslog # Legacy CEE cookie mode (default) action(type="mmjsonparse" mode="cookie") # Find-JSON scanning mode action(type="mmjsonparse" mode="find-json") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`.rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dirownernum.rst0000644000000000000000000000013215062756615025270 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.934670701 30 ctime=1764935922.285562832 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dirownernum.rst0000664000175000017500000000310615062756615024734 0ustar00rgerrger.. _param-omfile-dirownernum: .. _omfile.parameter.module.dirownernum: dirOwnerNum =========== .. index:: single: omfile; dirOwnerNum single: dirOwnerNum .. summary-start Set the file owner for directories newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dirOwnerNum :Scope: module, action :Type: integer :Default: module=process user; action=system default :Required?: no :Introduced: 7.5.8 Description ----------- Set the file owner for directories newly created. Please note that this setting does not affect the owner of directories already existing. The parameter is a numerical ID, which is used regardless of whether the user actually exists. This can be useful if the user mapping is not available to rsyslog during startup. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-dirownernum: .. _omfile.parameter.module.dirownernum-usage: .. code-block:: rsyslog module(load="builtin:omfile" dirOwnerNum="...") Action usage ------------ .. _param-omfile-action-dirownernum: .. _omfile.parameter.action.dirownernum: .. code-block:: rsyslog action(type="omfile" dirOwnerNum="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dirownernum: - $DirOwnerNum — maps to dirOwnerNum (status: legacy) .. index:: single: omfile; $DirOwnerNum single: $DirOwnerNum See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-ratelimit-burst.rst0000644000000000000000000000013215103061376025676 xustar0030 mtime=1762419454.851381097 30 atime=1764928596.792574439 30 ctime=1764935921.813555606 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-ratelimit-burst.rst0000664000175000017500000000141715103061376025345 0ustar00rgerrger.. _param-imudp-ratelimit-burst: .. _imudp.parameter.input.ratelimit-burst: RateLimit.Burst =============== .. index:: single: imudp; RateLimit.Burst single: RateLimit.Burst .. summary-start Maximum messages permitted per rate-limiting burst. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: RateLimit.Burst :Scope: input :Type: integer :Default: input=10000 :Required?: no :Introduced: 7.3.1 Description ----------- Specifies the rate-limiting burst in number of messages. Input usage ----------- .. _param-imudp-input-ratelimit-burst: .. _imudp.parameter.input.ratelimit-burst-usage: .. code-block:: rsyslog input(type="imudp" RateLimit.Burst="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-reportfailures.rst0000644000000000000000000000013215062756615026015 xustar0030 mtime=1758190989.212641276 30 atime=1764928602.077736169 30 ctime=1764935922.548566858 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-reportfailures.rst0000664000175000017500000000303315062756615025460 0ustar00rgerrger.. _param-omprog-reportfailures: .. _omprog.parameter.action.reportfailures: reportFailures ============== .. index:: single: omprog; reportFailures single: reportFailures .. summary-start Logs a warning when the program signals an error while confirming messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: reportFailures :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.38.0 Description ----------- Specifies whether rsyslog must internally log a warning message whenever the program returns an error when confirming a message. The logged message will include the error line returned by the program. This parameter is ignored when :ref:`param-omprog-confirmmessages` is set to "off". Enabling this flag can be useful to log the problems detected by the program. However, the information that can be logged is limited to a short error line, and the logs will be tagged as originated by the 'syslog' facility (like the rest of rsyslog logs). To avoid these shortcomings, consider the use of the :ref:`param-omprog-output` parameter to capture the stderr of the program. Action usage ------------ .. _param-omprog-action-reportfailures: .. _omprog.parameter.action.reportfailures-usage: .. code-block:: rsyslog action(type="omprog" confirmMessages="on" reportFailures="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-authmode.rst0000644000000000000000000000013215062756615027073 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.174555468 30 ctime=1764935921.762554825 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-authmode.rst0000664000175000017500000000334115062756615026540 0ustar00rgerrger.. _param-imtcp-streamdriver-authmode: .. _imtcp.parameter.module.streamdriver-authmode: .. _imtcp.parameter.input.streamdriver-authmode: StreamDriver.AuthMode ===================== .. index:: single: imtcp; StreamDriver.AuthMode single: StreamDriver.AuthMode .. summary-start Sets stream driver authentication mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.AuthMode :Scope: module, input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets stream driver authentication mode. Possible values and meaning depend on the :doc:`network stream driver <../../concepts/netstrm_drvr>`. used. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-authmode: .. _imtcp.parameter.module.streamdriver-authmode-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.authMode="...") Input usage ----------- .. _param-imtcp-input-streamdriver-authmode: .. _imtcp.parameter.input.streamdriver-authmode-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.authMode="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverstreamdriverauthmode: - $InputTCPServerStreamDriverAuthMode — maps to StreamDriver.AuthMode (status: legacy) .. index:: single: imtcp; $InputTCPServerStreamDriverAuthMode single: $InputTCPServerStreamDriverAuthMode See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-retry.rst0000644000000000000000000000013215114522477024117 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.480642783 30 ctime=1764935922.414564807 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-retry.rst0000664000175000017500000000443215114522477023566 0ustar00rgerrger.. _param-omhttp-retry: .. _omhttp.parameter.input.retry: retry ===== .. index:: single: omhttp; retry single: retry .. summary-start Enables omhttp's internal retry logic that requeues failed requests for another attempt. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: retry :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- This parameter specifies whether failed requests should be retried using the custom retry logic implemented in this plugin. Requests returning 5XX HTTP status codes are considered retriable. If retry is enabled, set :ref:`param-omhttp-retry-ruleset` as well. Note that retries are generally handled in rsyslog by setting ``action.resumeRetryCount="-1"`` (or some other integer), and the plugin lets rsyslog know it should start retrying by suspending itself. This is still the recommended approach in the two cases enumerated below when using this plugin. In both of these cases, the output plugin transaction interface is not used. That is, from rsyslog core's point of view, each message is contained in its own transaction. 1. Batching is off (``batch="off"``) 2. Batching is on and the maximum batch size is 1 (``batch="on" batchMaxSize="1"``) This custom retry behavior is the result of a bug in rsyslog's handling of transaction commits. See `this issue `_ for full details. Essentially, if rsyslog hands omhttp 4 messages, and omhttp batches them up but the request fails, rsyslog will only retry the LAST message that it handed the plugin, instead of all 4, even if the plugin returns the correct "defer commit" statuses for messages 1, 2, and 3. This means that omhttp cannot rely on ``action.resumeRetryCount`` for any transaction that processes more than a single message, and explains why the 2 above cases do work correctly. It looks promising that issue will be resolved at some point, so this behavior can be revisited at that time. Input usage ----------- .. _omhttp.parameter.input.retry-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" retry="on" retryRuleSet="rs_omhttp_retry" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-port.rst0000644000000000000000000000013215114522477023713 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.463642366 30 ctime=1764935921.668553386 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-port.rst0000664000175000017500000000177315114522477023367 0ustar00rgerrger.. _param-imrelp-port: .. _imrelp.parameter.input.port: port ==== .. index:: single: imrelp; port single: port .. summary-start Starts a RELP server instance that listens on the specified TCP port. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: port :Scope: input :Type: string :Default: input=none :Required?: yes :Introduced: Not documented Description ----------- Starts a RELP server on the selected port. Input usage ----------- .. _param-imrelp-input-port-usage: .. _imrelp.parameter.input.port-usage: .. code-block:: rsyslog input(type="imrelp" port="2514") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imrelp.parameter.legacy.inputrelpserverrun: - $InputRELPServerRun — maps to port (status: legacy) .. index:: single: imrelp; $InputRELPServerRun single: $InputRELPServerRun See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-closetimeout.rst0000644000000000000000000000013215062756615025571 xustar0030 mtime=1758190989.209641233 30 atime=1764928601.516719042 30 ctime=1764935922.445565282 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-closetimeout.rst0000664000175000017500000000162315062756615025237 0ustar00rgerrger.. _param-omkafka-closetimeout: .. _omkafka.parameter.module.closetimeout: closeTimeout ============ .. index:: single: omkafka; closeTimeout single: closeTimeout .. summary-start Milliseconds to wait for pending messages on shutdown. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: closeTimeout :Scope: action :Type: integer :Default: action=2000 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Sets the time to wait in ms for draining messages submitted to the Kafka handle before closing it. The maximum across all actions is used as librdkafka's unload timeout. Action usage ------------ .. _param-omkafka-action-closetimeout: .. _omkafka.parameter.action.closetimeout: .. code-block:: rsyslog action(type="omkafka" closeTimeout="2000") See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-maxsessions.rst0000644000000000000000000000013215114522477025245 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.452642096 30 ctime=1764935921.310547905 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-maxsessions.rst0000664000175000017500000000252615114522477024716 0ustar00rgerrger.. _param-imdiag-maxsessions: .. _imdiag.parameter.module.maxsessions: MaxSessions =========== .. index:: single: imdiag; MaxSessions single: MaxSessions .. summary-start Limits the number of concurrent diagnostic control connections accepted. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: MaxSessions :Scope: module :Type: integer :Default: module=20 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines how many client sessions the diagnostic listener accepts at once. By default the listener allows 20 concurrent sessions. The limit must be set before :ref:`ServerRun ` creates the TCP listener. Additional connection attempts beyond the configured number are rejected. Module usage ------------ .. _param-imdiag-module-maxsessions: .. _imdiag.parameter.module.maxsessions-usage: .. code-block:: rsyslog module(load="imdiag" maxSessions="10") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagmaxsessions: - $IMDiagMaxSessions — maps to MaxSessions (status: legacy) .. index:: single: imdiag; $IMDiagMaxSessions single: $IMDiagMaxSessions See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-readtimeout.rst0000644000000000000000000000013215062756615025233 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.891485273 30 ctime=1764935921.426549681 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-readtimeout.rst0000664000175000017500000000321115062756615024674 0ustar00rgerrger.. _param-imfile-readtimeout: .. _imfile.parameter.input.readtimeout: .. _imfile.parameter.readtimeout: readTimeout =========== .. index:: single: imfile; readTimeout single: readTimeout .. summary-start Sets the multi-line read timeout in seconds; module value provides the default. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: readTimeout :Scope: module, input :Type: integer :Default: module=0; input=inherits module :Required?: no :Introduced: 8.23.0 Description ----------- The module parameter defines the default value for input ``readTimeout`` settings. The value is the number of seconds before partially read messages are timed out. At input scope, this can be used with ``startmsg.regex`` (but not ``readMode``). If specified, partial multi-line reads are timed out after the specified interval. The current message fragment is processed and the next fragment arriving is treated as a completely new message. This is useful when a file is infrequently written and a late next message would otherwise delay processing for a long time. Module usage ------------ .. _param-imfile-module-readtimeout: .. _imfile.parameter.module.readtimeout-usage: .. code-block:: rsyslog module(load="imfile" readTimeout="0") Input usage ----------- .. _param-imfile-input-readtimeout: .. _imfile.parameter.input.readtimeout-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" readTimeout="0") Notes ----- - Use only with ``startmsg.regex``; ignored with ``readMode``. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-tls-authmode.rst0000644000000000000000000000013115114522477025346 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.472642587 30 ctime=1764935922.163560964 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-tls-authmode.rst0000664000175000017500000000230715114522477025015 0ustar00rgerrger.. _param-omdtls-tls-authmode: .. _omdtls.parameter.input.tls-authmode: tls.authmode ============ .. index:: single: omdtls; tls.authmode single: tls.authmode .. summary-start Sets the DTLS peer authentication method used by the action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: tls.authmode :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- Sets the mode of authentication to be used. Supported values are ``fingerprint``, ``name``, or ``certvalid``. * ``fingerprint``: Authentication based on certificate fingerprint. * ``name``: Authentication based on the ``subjectAltName`` and, as a fallback, the subject common name. * ``certvalid``: Requires a valid certificate for authentication. If this parameter is not set, or if an unsupported value is provided, the action falls back to anonymous authentication (no client certificate required). Input usage ----------- .. _omdtls.parameter.input.tls-authmode-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" tls.authMode="certvalid") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-preservecase.rst0000644000000000000000000000013215062756615025247 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.234557309 30 ctime=1764935921.748554611 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-preservecase.rst0000664000175000017500000000240315062756615024712 0ustar00rgerrger.. _param-imtcp-preservecase: .. _imtcp.parameter.module.preservecase: .. _imtcp.parameter.input.preservecase: PreserveCase ============ .. index:: single: imtcp; PreserveCase single: PreserveCase .. summary-start Controls whether the case of fromhost is preserved. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: PreserveCase :Scope: module, input :Type: boolean :Default: module=on, input=module parameter :Required?: no :Introduced: 8.37.0 Description ----------- This parameter is for controlling the case in fromhost. If preservecase is set to "off", the case in fromhost is not preserved. E.g., 'host1.example.org' the message was received from 'Host1.Example.Org'. Default to "on" for the backward compatibility. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-preservecase: .. _imtcp.parameter.module.preservecase-usage: .. code-block:: rsyslog module(load="imtcp" preserveCase="off") Input usage ----------- .. _param-imtcp-input-preservecase: .. _imtcp.parameter.input.preservecase-usage: .. code-block:: rsyslog input(type="imtcp" port="514" preserveCase="off") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/immark-use-markflag.rst0000644000000000000000000000013215114522477025275 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.458642243 30 ctime=1764935921.541551441 rsyslog-8.2512.0/doc/source/reference/parameters/immark-use-markflag.rst0000664000175000017500000000214115114522477024737 0ustar00rgerrger.. _param-immark-use-markflag: .. _immark.parameter.module.use-markflag: use.markFlag ============= .. index:: single: immark; use.markFlag single: use.markFlag .. summary-start Controls whether emitted mark messages carry the ``MARK`` flag bit. .. summary-end This parameter applies to :doc:`../../configuration/modules/immark`. :Name: use.markFlag :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: 8.2012.0 Description ----------- When enabled, immark tags generated messages with the ``MARK`` flag. This allows actions to filter or suppress them via settings such as the ``action.writeAllMarkMessages`` parameter in :doc:`../../configuration/actions`. Disable the flag when mark messages should be treated exactly like ordinary log entries. Module usage ------------ .. _immark.parameter.module.use-markflag-usage: .. code-block:: rsyslog module(load="immark" use.markFlag="off") See also -------- .. seealso:: * :ref:`param-immark-interval` * :doc:`../../configuration/modules/immark` * ``action.writeAllMarkMessages`` in :doc:`../../configuration/actions` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-ratelimit-burst.rst0000644000000000000000000000013215103061376025674 xustar0030 mtime=1762419454.851381097 30 atime=1764928596.325560103 30 ctime=1764935921.750554641 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-ratelimit-burst.rst0000664000175000017500000000152515103061376025343 0ustar00rgerrger.. _param-imtcp-ratelimit-burst: .. _imtcp.parameter.input.ratelimit-burst: RateLimit.Burst =============== .. index:: single: imtcp; RateLimit.Burst single: RateLimit.Burst .. summary-start Defines the maximum number of messages allowed per rate-limit interval. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: RateLimit.Burst :Scope: input :Type: integer :Default: input=10000 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies the rate-limiting burst in number of messages. Default is ``10,000``. Input usage ----------- .. _param-imtcp-input-ratelimit-burst: .. _imtcp.parameter.input.ratelimit-burst-usage: .. code-block:: rsyslog input(type="imtcp" rateLimit.Burst="20000") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-template.rst0000644000000000000000000000013115114522477024553 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.471642562 30 ctime=1764935922.161560934 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-template.rst0000664000175000017500000000256715114522477024232 0ustar00rgerrger.. _param-omdtls-template: .. _omdtls.parameter.module.template: .. _omdtls.parameter.input.template: template ======== .. index:: single: omdtls; template single: template .. summary-start Selects the template used to format messages sent through omdtls actions. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: template :Scope: module, input :Type: word :Default: module=none, input=RSYSLOG_FileFormat :Required?: no :Introduced: v8.2402.0 Description ----------- Selects the template that formats messages for omdtls actions. If an action does not specify this parameter, it uses ``RSYSLOG_FileFormat``. The module parameter is defined for compatibility but is currently ignored. The module has always defaulted actions to ``RSYSLOG_FileFormat`` (see ``plugins/omdtls/omdtls.c``), even though earlier documentation mentioned ``RSYSLOG_TraditionalForwardFormat``. Update existing configurations only if you require a different template. Module usage ------------ .. _omdtls.parameter.module.template-usage: .. code-block:: rsyslog module(load="omdtls" template="ForwardingTemplate") Input usage ----------- .. _omdtls.parameter.input.template-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" template="ForwardingTemplate") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-tls-cacert.rst0000644000000000000000000000013215114522477025013 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.482642833 30 ctime=1764935922.427565006 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-tls-cacert.rst0000664000175000017500000000152115114522477024456 0ustar00rgerrger.. _param-omhttp-tls-cacert: .. _omhttp.parameter.input.tls-cacert: tls.cacert ========== .. index:: single: omhttp; tls.cacert single: tls.cacert .. summary-start Points omhttp to the CA bundle used to verify HTTPS servers. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: tls.cacert :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- This parameter sets the path to the Certificate Authority (CA) bundle. Expects ``.pem`` format. Input usage ----------- .. _omhttp.parameter.input.tls-cacert-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" tlsCaCert="/etc/ssl/certs/ca-bundle.pem" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmdarwin-response.rst0000644000000000000000000000013215071746523025115 xustar0030 mtime=1760021843.806420481 30 atime=1764928597.688601922 30 ctime=1764935921.959557841 rsyslog-8.2512.0/doc/source/reference/parameters/mmdarwin-response.rst0000664000175000017500000000320015071746523024554 0ustar00rgerrger.. _param-mmdarwin-response: .. _mmdarwin.parameter.input.response: response ======== .. index:: single: mmdarwin; response single: response .. summary-start Controls whether Darwin returns a score, forwards data, or does both. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmdarwin`. :Name: response :Scope: input :Type: word :Default: input="no" :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Tells the Darwin filter what to do next: * :json:`"no"`: no response will be sent, nothing will be sent to next filter. * :json:`"back"`: a score for the input will be returned by the filter, nothing will be forwarded to the next filter. * :json:`"darwin"`: the data provided will be forwarded to the next filter (in the format specified in the filter's configuration), no response will be given to mmdarwin. * :json:`"both"`: the filter will respond to mmdarwin with the input's score AND forward the data (in the format specified in the filter's configuration) to the next filter. .. note:: Please be mindful when setting this parameter, as the called filter will only forward data to the next configured filter if you ask the filter to do so with :json:`"darwin"` or :json:`"both"`. If a next filter is configured but you ask for a :json:`"back"` response, the next filter **WILL NOT** receive anything! Input usage ----------- .. _param-mmdarwin-input-response-usage: .. _mmdarwin.parameter.input.response-usage: .. code-block:: rsyslog action(type="mmdarwin" response="both") See also -------- See also :doc:`../../configuration/modules/mmdarwin`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhdfs-omhdfsport.rst0000644000000000000000000000013115114522477025103 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.474642636 30 ctime=1764935922.349563812 rsyslog-8.2512.0/doc/source/reference/parameters/omhdfs-omhdfsport.rst0000664000175000017500000000242715114522477024555 0ustar00rgerrger.. _param-omhdfs-omhdfsport: .. _omhdfs.parameter.module.omhdfsport: omhdfsPort ========== .. index:: single: omhdfs; omhdfsPort single: omhdfsPort .. summary-start Specifies the TCP port number used to reach the configured HDFS host. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhdfs`. :Name: omhdfsPort :Scope: module :Type: integer :Default: 0 :Required?: no :Introduced: Not documented Description ----------- Port on which to connect to the HDFS host. Module usage ------------ .. _omhdfs.parameter.module.omhdfsport-usage: <<<<<<< HEAD .. code-block:: none ======= .. code-block:: text >>>>>>> 717d9e259 (doc: restructure and modernize project history; add origins page and xrefs) $ModLoad omhdfs $omhdfsHost hdfs01.example.net $omhdfsPort 8020 $omhdfsFileName /var/log/hdfs/system.log # write all messages to the specified HDFS host and port *.* :omhdfs: Legacy names (for reference) ---------------------------- Historic names/directives for compatibility. Do not use in new configs. .. _omhdfs.parameter.legacy.omhdfsport: - ``$OMHDFSPort`` — maps to ``omhdfsPort`` (status: legacy) .. index:: single: omhdfs; $OMHDFSPort single: $OMHDFSPort See also -------- See also :doc:`../../configuration/modules/omhdfs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-persiststateinterval.rst0000644000000000000000000000013215062756615027743 xustar0030 mtime=1758190989.186640907 30 atime=1764928594.608507335 30 ctime=1764935921.483550553 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-persiststateinterval.rst0000664000175000017500000000263015062756615027410 0ustar00rgerrger.. _param-imjournal-persiststateinterval: .. _imjournal.parameter.module.persiststateinterval: .. meta:: :tag: module:imjournal :tag: parameter:PersistStateInterval PersistStateInterval ==================== .. index:: single: imjournal; PersistStateInterval single: PersistStateInterval .. summary-start Saves the journal cursor after every N messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: PersistStateInterval :Scope: module :Type: integer :Default: module=10 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines how often the module writes its position in the journal to the state file. The cursor is saved after each ``PersistStateInterval`` messages so rsyslog resumes from the last processed entry on restart. Module usage ------------ .. _param-imjournal-module-persiststateinterval: .. _imjournal.parameter.module.persiststateinterval-usage: .. code-block:: rsyslog module(load="imjournal" PersistStateInterval="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournalpersiststateinterval: - $imjournalPersistStateInterval — maps to PersistStateInterval (status: legacy) .. index:: single: imjournal; $imjournalPersistStateInterval single: $imjournalPersistStateInterval See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-checkextendedkeypurpo0000644000000000000000000000013215062756615031053 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.188555897 30 ctime=1764935921.769554932 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-checkextendedkeypurpose.rst0000664000175000017500000000301715062756615031657 0ustar00rgerrger.. _param-imtcp-streamdriver-checkextendedkeypurpose: .. _imtcp.parameter.module.streamdriver-checkextendedkeypurpose: .. _imtcp.parameter.input.streamdriver-checkextendedkeypurpose: streamDriver.checkExtendedKeyPurpose ==================================== .. index:: single: imtcp; StreamDriver.checkExtendedKeyPurpose single: StreamDriver.checkExtendedKeyPurpose .. summary-start Checks certificate extended key purpose for compatibility with rsyslog operation. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: StreamDriver.checkExtendedKeyPurpose :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Whether to check also purpose value in extended fields part of certificate for compatibility with rsyslog operation. (driver-specific) The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-streamdriver-checkextendedkeypurpose: .. _imtcp.parameter.module.streamdriver-checkextendedkeypurpose-usage: .. code-block:: rsyslog module(load="imtcp" streamDriver.checkExtendedKeyPurpose="on") Input usage ----------- .. _param-imtcp-input-streamdriver-checkextendedkeypurpose: .. _imtcp.parameter.input.streamdriver-checkextendedkeypurpose-usage: .. code-block:: rsyslog input(type="imtcp" port="514" streamDriver.checkExtendedKeyPurpose="on") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-permit-slashesinhostname.rst0000644000000000000000000000013215062756615030117 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.256772121 30 ctime=1764935922.627568068 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-permit-slashesinhostname.rst0000664000175000017500000000210515062756615027561 0ustar00rgerrger.. _param-pmrfc3164-permit-slashesinhostname: .. _pmrfc3164.parameter.module.permit-slashesinhostname: .. _pmrfc3164.parameter.module.permit.slashesInHostname: permit.slashesInHostname ======================== .. index:: single: pmrfc3164; permit.slashesInHostname single: permit.slashesInHostname .. summary-start Allow ``/`` in hostnames, useful for syslog-ng relay chains. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: permit.slashesInHostname :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.20.0 Description ----------- This option allows hostnames to include slash characters. Module usage ------------ .. _param-pmrfc3164-module-permit-slashesinhostname: .. _pmrfc3164.parameter.module.permit-slashesinhostname-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" permit.slashesInHostname="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-template.rst0000644000000000000000000000013215062756615024562 xustar0030 mtime=1758190989.212641276 30 atime=1764928602.045735193 30 ctime=1764935922.553566935 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-template.rst0000664000175000017500000000153315062756615024230 0ustar00rgerrger.. _param-omprog-template: .. _omprog.parameter.action.template: template ======== .. index:: single: omprog; template single: template .. summary-start Sets the template for formatting messages sent to the program. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: template :Scope: action :Type: word :Default: action=RSYSLOG_FileFormat :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Name of the :doc:`template <../../configuration/templates>` to use to format the log messages passed to the external program. Action usage ------------ .. _param-omprog-action-template: .. _omprog.parameter.action.template-usage: .. code-block:: rsyslog action(type="omprog" template="RSYSLOG_FileFormat") See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-persiststateinterval.rst0000644000000000000000000000013115062756615027207 xustar0030 mtime=1758190989.185640893 29 atime=1764928593.96248746 30 ctime=1764935921.419549574 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-persiststateinterval.rst0000664000175000017500000000350315062756615026655 0ustar00rgerrger.. _param-imfile-persiststateinterval: .. _imfile.parameter.input.persiststateinterval: .. _imfile.parameter.persiststateinterval: PersistStateInterval ==================== .. index:: single: imfile; PersistStateInterval single: PersistStateInterval .. summary-start Controls how often the state file is written based on processed line count. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: PersistStateInterval :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Specifies how often the state file is written when processing the input file. A value of ``0`` means the state file is written when the monitored file is closed, typically at rsyslog shutdown. Any other value ``n`` causes the state file to be written after at least every ``n`` processed lines. This setting can guard against message duplication due to fatal errors but may reduce performance if set to a low value. Rsyslog may write state files more frequently if needed. **Note: If this parameter is not set, state files are not created.** Input usage ----------- .. _param-imfile-input-persiststateinterval: .. _imfile.parameter.input.persiststateinterval-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" PersistStateInterval="0") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilepersiststateinterval: - ``$InputFilePersistStateInterval`` — maps to PersistStateInterval (status: legacy) .. index:: single: imfile; $InputFilePersistStateInterval single: $InputFilePersistStateInterval See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmexternal-output.rst0000644000000000000000000000013215071746523025155 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.842606644 30 ctime=1764935921.985558239 rsyslog-8.2512.0/doc/source/reference/parameters/mmexternal-output.rst0000664000175000017500000000271115071746523024622 0ustar00rgerrger.. _param-mmexternal-output: .. _mmexternal.parameter.input.output: output ====== .. index:: single: mmexternal; output single: output .. summary-start Writes the external plugin's standard output and standard error to a helper log file for debugging. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmexternal`. :Name: output :Scope: input :Type: string :Default: none :Required?: no :Introduced: 8.3.0 Description ----------- This is a debug aid. If set, this is a filename where the combined standard output and standard error stream from the plugin is logged before rsyslog parses it as a JSON response. Note that the output is also being processed as usual by rsyslog. Setting this parameter thus gives insight into the internal processing that happens between plugin and rsyslog core. .. warning:: The external program's standard error stream is captured together with standard output. Any data written to stderr is intermingled with the JSON response from stdout and will likely cause parsing failures. Ensure the external program does not write to stderr. Input usage ----------- .. _param-mmexternal-input-output: .. _mmexternal.parameter.input.output-usage: .. code-block:: rsyslog module(load="mmexternal") action( type="mmexternal" binary="/path/to/mmexternal.py" output="/var/log/mmexternal-debug.log" ) See also -------- See also :doc:`../../configuration/modules/mmexternal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-gnutlsprioritystring.rst0000644000000000000000000000013115062756615027124 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.226557064 29 ctime=1764935921.71455409 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-gnutlsprioritystring.rst0000664000175000017500000000725315062756615026600 0ustar00rgerrger.. _param-imtcp-gnutlsprioritystring: .. _imtcp.parameter.module.gnutlsprioritystring: .. _imtcp.parameter.input.gnutlsprioritystring: gnutlsPriorityString ==================== .. index:: single: imtcp; gnutlsPriorityString single: gnutlsPriorityString .. summary-start Provides driver-specific TLS configuration via a priority string. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: gnutlsPriorityString :Scope: module, input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module=none, input=module parameter :Required?: no :Introduced: 8.29.0 Description ----------- The "gnutls priority string" parameter in rsyslog offers enhanced customization for secure communications, allowing detailed configuration of TLS driver properties. This includes specifying handshake algorithms and other settings for GnuTLS, as well as implementing OpenSSL configuration commands. Initially developed for GnuTLS, the "gnutls priority string" has evolved since version v8.1905.0 to also support OpenSSL, broadening its application and utility in network security configurations. This update signifies a key advancement in rsyslog's capabilities, making the "gnutls priority string" an essential feature for advanced TLS configuration. .. versionadded:: 8.29.0 **Configuring Driver-Specific Properties** This configuration string is used to set properties specific to different drivers. Originally designed for the GnuTLS driver, it has been extended to support OpenSSL configuration commands from version v8.1905.0 onwards. **GNUTLS Configuration** In GNUTLS, this setting determines the handshake algorithms and options for the TLS session. It's designed to allow user overrides of the library's default settings. If you leave this parameter unset (NULL), the system will revert to the default settings. For more detailed information on priority strings in GNUTLS, you can refer to the GnuTLS Priority Strings Documentation available at [GnuTLS Website](https://gnutls.org/manual/html_node/Priority-Strings.html). **OpenSSL Configuration** This feature is compatible with OpenSSL Version 1.0.2 and above. It enables the passing of configuration commands to the OpenSSL library. You can find a comprehensive list of commands and their acceptable values in the `OpenSSL Documentation `_. **General Configuration Guidelines** The configuration can be formatted as a single line or across multiple lines. Each command within the configuration is separated by a linefeed (``\n``). To differentiate between a command and its corresponding value, use an equal sign (``=``). Below are some examples to guide you in formatting these commands. Example 1 --------- This will allow all protocols except for SSLv2 and SSLv3: .. code-block:: none gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3" Example 2 --------- This will allow all protocols except for SSLv2, SSLv3 and TLSv1. It will also set the minimum protocol to TLSv1.2 .. code-block:: none gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1 MinProtocol=TLSv1.2" The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-gnutlsprioritystring: .. _imtcp.parameter.module.gnutlsprioritystring-usage: .. code-block:: rsyslog module(load="imtcp" gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3") Input usage ----------- .. _param-imtcp-input-gnutlsprioritystring: .. _imtcp.parameter.input.gnutlsprioritystring-usage: .. code-block:: rsyslog input(type="imtcp" port="514" gnutlsPriorityString="Protocol=ALL,-SSLv2,-SSLv3") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-rotation-sizelimit.rst0000644000000000000000000000013215062756615026565 xustar0030 mtime=1758190989.208641219 30 atime=1764928600.207679048 30 ctime=1764935922.319563353 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-rotation-sizelimit.rst0000664000175000017500000000335315062756615026235 0ustar00rgerrger.. _param-omfile-rotation-sizelimit: .. _omfile.parameter.module.rotation-sizelimit: rotation.sizeLimit ================== .. index:: single: omfile; rotation.sizeLimit single: rotation.sizeLimit .. summary-start This permits to set a size limit on the output file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: rotation.sizeLimit :Scope: action :Type: size :Default: action=0 (disabled) :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This permits to set a size limit on the output file. When the limit is reached, rotation of the file is tried. The rotation script needs to be configured via `rotation.sizeLimitCommand`. Please note that the size limit is not exact. Some excess bytes are permitted to prevent messages from being split across two files. Also, a full batch of messages is not terminated in between. As such, in practice, the size of the output file can grow some KiB larger than configured. Also avoid to configure a too-low limit, especially for busy files. Calling the rotation script is relatively performance intense. As such, it could negatively affect overall rsyslog performance. Action usage ------------ .. _param-omfile-action-rotation-sizelimit: .. _omfile.parameter.action.rotation-sizelimit: .. code-block:: rsyslog action(type="omfile" rotation.sizeLimit="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.outchannel: - $outchannel — maps to rotation.sizeLimit (status: legacy) .. index:: single: omfile; $outchannel single: $outchannel See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-escapelf-replacement.rst0000644000000000000000000000013215062756615026770 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.999488599 30 ctime=1764935921.386549068 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-escapelf-replacement.rst0000664000175000017500000000245015062756615026435 0ustar00rgerrger.. _param-imfile-escapelf-replacement: .. _imfile.parameter.input.escapelf-replacement: .. _imfile.parameter.escapelf-replacement: escapeLF.replacement ==================== .. index:: single: imfile; escapeLF.replacement single: escapeLF.replacement .. summary-start Overrides the default LF escape sequence when ``escapeLF`` is ``on``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: escapeLF.replacement :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: depending on use :Required?: no :Introduced: 8.2001.0 Description ----------- Works together with ``escapeLF``. It is honored only if ``escapeLF="on"``. It permits replacing the default escape sequence, which historically may be ``#012`` or ``\n``. If not configured, that default remains. Examples: .. code-block:: rsyslog escapeLF.replacement=" " escapeLF.replacement="[LF]" escapeLF.replacement="" Input usage ----------- .. _param-imfile-input-escapelf-replacement: .. _imfile.parameter.input.escapelf-replacement-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" escapeLF="on" escapeLF.replacement="[LF]") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-subject-template.rst0000644000000000000000000000013215114522477026165 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.486642931 30 ctime=1764935922.515566353 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-subject-template.rst0000664000175000017500000000322115114522477025627 0ustar00rgerrger.. _param-ommail-subject-template: .. _ommail.parameter.input.subject-template: subjectTemplate ================ .. index:: single: ommail; subjectTemplate single: subjectTemplate .. summary-start Selects the template used to generate the mail subject line. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: subjectTemplate :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: 8.5.0 Description ----------- The name of the template to be used as the mail subject. Use this parameter when message content should appear in the subject. If you just need a constant subject line, use :ref:`param-ommail-subject-text` instead. The ``subjectTemplate`` and ``subjectText`` parameters cannot both be configured within a single action. If neither is specified, a default, non-configurable subject line will be generated. Input usage ------------ .. _ommail.parameter.input.subject-template-usage: .. code-block:: rsyslog module(load="ommail") template(name="mailSubject" type="string" string="Alert: %msg%") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" subjectTemplate="mailSubject" ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailsubject: - $ActionMailSubject — maps to subjectTemplate (status: legacy) .. index:: single: ommail; $ActionMailSubject single: $ActionMailSubject See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-escapelf.rst0000644000000000000000000000013215062756615024473 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.991488353 30 ctime=1764935921.389549115 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-escapelf.rst0000664000175000017500000000232215062756615024136 0ustar00rgerrger.. _param-imfile-escapelf: .. _imfile.parameter.input.escapelf: .. _imfile.parameter.escapelf: escapeLF ======== .. index:: single: imfile; escapeLF single: escapeLF .. summary-start Escapes embedded LF characters in multi-line messages as ``#012`` when enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: escapeLF :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Only meaningful when multi-line messages are processed. LF characters inside messages cause issues with many tools. If set to ``on``, LF characters are escaped to the sequence ``#012``. By default escaping is enabled. If turned off, test carefully. When using plain TCP syslog with embedded LFs, enable octet-counted framing. Input usage ----------- .. _param-imfile-input-escapelf: .. _imfile.parameter.input.escapelf-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" escapeLF="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-ratelimit-burst.rst0000644000000000000000000000013215114522477026101 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.479642759 30 ctime=1764935922.397564547 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-ratelimit-burst.rst0000664000175000017500000000205015114522477025542 0ustar00rgerrger.. _param-omhttp-ratelimit-burst: .. _omhttp.parameter.input.ratelimit-burst: ratelimit.burst =============== .. index:: single: omhttp; ratelimit.burst single: ratelimit.burst .. summary-start Sets how many messages the retry ruleset may emit within each rate-limiting window. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: ratelimit.burst :Scope: input :Type: integer :Default: input=20000 :Required?: no :Introduced: Not specified Description ----------- This parameter sets the rate limiting behavior for the :ref:`param-omhttp-retry-ruleset`. It specifies the maximum number of messages that can be emitted within the :ref:`param-omhttp-ratelimit-interval` interval. For further information, see the description there. Input usage ----------- .. _omhttp.parameter.input.ratelimit-burst-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" retry="on" rateLimitBurst="1000" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-ruleset.rst0000644000000000000000000000013215114522477024766 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.460642292 30 ctime=1764935921.562551763 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-ruleset.rst0000664000175000017500000000175615114522477024443 0ustar00rgerrger.. _param-impstats-ruleset: .. _impstats.parameter.module.ruleset: ruleset ======= .. index:: single: impstats; ruleset single: ruleset .. summary-start Binds impstats-generated messages to the specified ruleset for further processing. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: ruleset :Scope: module :Type: string :Default: module=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Binds the listener to a specific :doc:`ruleset <../../concepts/multi_ruleset>`. **Note** that setting ``ruleset`` and setting :ref:`param-impstats-log-syslog` (``logSyslog`` in camelCase examples) to ``off`` are mutually exclusive because syslog stream processing must be enabled to use a ruleset. Module usage ------------ .. _impstats.parameter.module.ruleset-usage: .. code-block:: rsyslog module(load="impstats" ruleset="impstatsRules") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-ignoreolderthan.rst0000644000000000000000000000013215062756615026075 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.135492783 30 ctime=1764935921.398549252 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-ignoreolderthan.rst0000664000175000017500000000206715062756615025546 0ustar00rgerrger.. _param-imfile-ignoreolderthan: .. _imfile.parameter.input.ignoreolderthan: .. _imfile.parameter.ignoreolderthan: ignoreOlderThan =============== .. index:: single: imfile; ignoreOlderThan single: ignoreOlderThan .. summary-start Ignores newly discovered files older than the specified number of seconds. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: ignoreOlderThan :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: 8.2108.0 Description ----------- Instructs imfile to ignore a discovered file that has not been modified in the given number of seconds. Once the file is discovered, it is no longer ignored and new data will be read. The default ``0`` disables this option. Input usage ----------- .. _param-imfile-input-ignoreolderthan: .. _imfile.parameter.input.ignoreolderthan-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" ignoreOlderThan="0") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-ruleset.rst0000644000000000000000000000013215114522477024412 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.463642366 30 ctime=1764935921.673553463 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-ruleset.rst0000664000175000017500000000217315114522477024061 0ustar00rgerrger.. _param-imrelp-ruleset: .. _imrelp.parameter.module.ruleset: ruleset ======= .. index:: single: imrelp; ruleset single: ruleset .. summary-start Assigns a ruleset to all RELP listeners created by the module instance. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: ruleset :Scope: module :Type: word :Default: module=none :Required?: no :Introduced: 7.5.0 Description ----------- Binds the specified ruleset to **all** RELP listeners. This can be overridden at the instance level. Module usage ------------ .. _param-imrelp-module-ruleset-usage: .. _imrelp.parameter.module.ruleset-usage: .. code-block:: rsyslog module(load="imrelp" ruleset="relpRuleset") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imrelp.parameter.legacy.inputrelpserverbindruleset: - $InputRELPServerBindRuleset — maps to ruleset (status: legacy) .. index:: single: imrelp; $InputRELPServerBindRuleset single: $InputRELPServerBindRuleset See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-keepalive-probes.rst0000644000000000000000000000013115062756615026174 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.502534822 30 ctime=1764935921.602552375 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-keepalive-probes.rst0000664000175000017500000000271015062756615025641 0ustar00rgerrger.. _param-imptcp-keepalive-probes: .. _imptcp.parameter.input.keepalive-probes: KeepAlive.Probes ================ .. index:: single: imptcp; KeepAlive.Probes single: KeepAlive.Probes .. summary-start Sets the number of unacknowledged keepalive probes before the connection is considered dead. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: KeepAlive.Probes :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- The number of unacknowledged probes to send before considering the connection dead and notifying the application layer. The default, 0, means that the operating system defaults are used. This has only effect if keep-alive is enabled. The functionality may not be available on all platforms. Input usage ----------- .. _param-imptcp-input-keepalive-probes: .. _imptcp.parameter.input.keepalive-probes-usage: .. code-block:: rsyslog input(type="imptcp" keepAlive.probes="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverkeepalive_probes: - $InputPTCPServerKeepAlive_probes — maps to KeepAlive.Probes (status: legacy) .. index:: single: imptcp; $InputPTCPServerKeepAlive_probes single: $InputPTCPServerKeepAlive_probes See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv4-enable.rst0000644000000000000000000000013215071746523025034 xustar0030 mtime=1760021843.802420418 30 atime=1764928597.303590116 30 ctime=1764935921.929557382 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv4-enable.rst0000664000175000017500000000153715071746523024506 0ustar00rgerrger.. _param-mmanon-ipv4-enable: .. _mmanon.parameter.input.ipv4-enable: ipv4.enable =========== .. index:: single: mmanon; ipv4.enable single: ipv4.enable .. summary-start Enables or disables IPv4 address anonymization for the mmanon action. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv4.enable :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: 7.3.7 Description ----------- This parameter controls whether ``mmanon`` will attempt to find and anonymize IPv4 addresses. If set to ``off``, all other ``ipv4.*`` parameters for this action are ignored. Input usage ----------- .. _mmanon.parameter.input.ipv4-enable-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv4.enable="off") See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-forcesingleinstance.rst0000644000000000000000000000013215062756615026774 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.161738731 30 ctime=1764935922.539566721 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-forcesingleinstance.rst0000664000175000017500000000326315062756615026444 0ustar00rgerrger.. _param-omprog-forcesingleinstance: .. _omprog.parameter.action.forcesingleinstance: forceSingleInstance =================== .. index:: single: omprog; forceSingleInstance single: forceSingleInstance .. summary-start Runs only one instance of the program regardless of worker threads. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: forceSingleInstance :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: v8.1.6 Description ----------- By default, the omprog action will start an instance (process) of the external program per worker thread (the maximum number of worker threads can be specified with the :doc:`queue.workerThreads <../../rainerscript/queue_parameters>` parameter). Moreover, if the action is associated to a :doc:`disk-assisted queue <../../concepts/queues>`, an additional instance will be started when the queue is persisted, to process the items stored on disk. If you want to force a single instance of the program to be executed, regardless of the number of worker threads or the queue type, set this flag to "on". This is useful when the external program uses or accesses some kind of shared resource that does not allow concurrent access from multiple processes. .. note:: Before version v8.38.0, this parameter had no effect. Action usage ------------ .. _param-omprog-action-forcesingleinstance: .. _omprog.parameter.action.forcesingleinstance-usage: .. code-block:: rsyslog action(type="omprog" forceSingleInstance="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-ratelimit-severity.rst0000644000000000000000000000013215103061376027135 xustar0030 mtime=1762419454.852381127 30 atime=1764928597.041582081 30 ctime=1764935921.853556218 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-ratelimit-severity.rst0000664000175000017500000000244615103061376026607 0ustar00rgerrger.. _param-imuxsock-ratelimit-severity: .. _imuxsock.parameter.input.ratelimit-severity: RateLimit.Severity ================== .. index:: single: imuxsock; RateLimit.Severity single: RateLimit.Severity .. summary-start Defines the severity level at or below which messages are rate-limited. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: RateLimit.Severity :Scope: input :Type: integer :Default: input=1 :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies the severity of messages that shall be rate-limited. .. seealso:: https://en.wikipedia.org/wiki/Syslog#Severity_level Input usage ----------- .. _param-imuxsock-input-ratelimit-severity: .. _imuxsock.parameter.input.ratelimit-severity-usage: .. code-block:: rsyslog input(type="imuxsock" rateLimit.severity="5") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.imuxsockratelimitseverity: - $IMUXSockRateLimitSeverity — maps to RateLimit.Severity (status: legacy) .. index:: single: imuxsock; $IMUXSockRateLimitSeverity single: $IMUXSockRateLimitSeverity See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-allowunsignedcerts.rst0000644000000000000000000000013115062756615030525 xustar0029 mtime=1758190989.20164112 30 atime=1764928599.709663817 30 ctime=1764935922.174561133 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-allowunsignedcerts.rst0000664000175000017500000000170315062756615030173 0ustar00rgerrger.. _param-omelasticsearch-allowunsignedcerts: .. _omelasticsearch.parameter.module.allowunsignedcerts: allowunsignedcerts ================== .. index:: single: omelasticsearch; allowunsignedcerts single: allowunsignedcerts .. summary-start Disable TLS peer verification (insecure, for testing only). .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: allowunsignedcerts :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Sets the curl `CURLOPT_SSL_VERIFYPEER` option to `0`. Strongly discouraged outside of testing. Action usage ------------ .. _param-omelasticsearch-action-allowunsignedcerts: .. _omelasticsearch.parameter.action.allowunsignedcerts: .. code-block:: rsyslog action(type="omelasticsearch" allowunsignedcerts="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-ruleset.rst0000644000000000000000000000013215062756615024423 xustar0030 mtime=1758190989.191640978 30 atime=1764928595.426532486 30 ctime=1764935921.636552896 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-ruleset.rst0000664000175000017500000000211715062756615024070 0ustar00rgerrger.. _param-imptcp-ruleset: .. _imptcp.parameter.input.ruleset: Ruleset ======= .. index:: single: imptcp; Ruleset single: Ruleset .. summary-start Binds the specified ruleset to this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Ruleset :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Binds specified ruleset to this input. If not set, the default ruleset is bound. Input usage ----------- .. _param-imptcp-input-ruleset: .. _imptcp.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imptcp" ruleset="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverbindruleset: - $InputPTCPServerBindRuleset — maps to Ruleset (status: legacy) .. index:: single: imptcp; $InputPTCPServerBindRuleset single: $InputPTCPServerBindRuleset See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imjournal-ratelimit-interval.rst0000644000000000000000000000013115103061376027244 xustar0030 mtime=1762419454.850381068 30 atime=1764928594.623507796 29 ctime=1764935921.48855063 rsyslog-8.2512.0/doc/source/reference/parameters/imjournal-ratelimit-interval.rst0000664000175000017500000000300615103061376026710 0ustar00rgerrger.. _param-imjournal-ratelimit-interval: .. _imjournal.parameter.module.ratelimit-interval: .. meta:: :tag: module:imjournal :tag: parameter:Ratelimit.Interval Ratelimit.Interval ================== .. index:: single: imjournal; Ratelimit.Interval single: Ratelimit.Interval .. summary-start Time window in seconds for rate limiting; 0 disables the limit. .. summary-end This parameter applies to :doc:`../../configuration/modules/imjournal`. :Name: Ratelimit.Interval :Scope: module :Type: integer :Default: module=600 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Defines the interval over which message rate limiting is applied. If more than ``Ratelimit.Burst`` messages arrive during this interval, additional messages are silently discarded and a discard notice is emitted at the end of the interval. Module usage ------------ .. _param-imjournal-module-ratelimit-interval: .. _imjournal.parameter.module.ratelimit-interval-usage: .. code-block:: rsyslog module(load="imjournal" Ratelimit.Interval="...") Notes ----- - Setting the value to ``0`` disables rate limiting and is generally not recommended. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _imjournal.parameter.legacy.imjournalratelimitinterval: - $imjournalRatelimitInterval — maps to Ratelimit.Interval (status: legacy) .. index:: single: imjournal; $imjournalRatelimitInterval single: $imjournalRatelimitInterval See also -------- See also :doc:`../../configuration/modules/imjournal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omuxsock-socketname.rst0000644000000000000000000000013115114522477025437 xustar0030 mtime=1764926783.034631833 29 atime=1764926783.48864298 30 ctime=1764935922.599567639 rsyslog-8.2512.0/doc/source/reference/parameters/omuxsock-socketname.rst0000664000175000017500000000317515114522477025112 0ustar00rgerrger.. _param-omuxsock-socketname: .. _omuxsock.parameter.module.socketname: socketName ========== .. index:: single: omuxsock; socketName single: socketName .. summary-start This is the name of the socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/omuxsock`. :Name: socketName :Scope: module, action :Type: string :Default: action=none :Required?: yes :Introduced: v8.2512 Description ----------- This is the name of the socket. There is no default. Every socket **must** be named. Module usage ------------ .. _param-omuxsock-module-socketname: .. _omuxsock.parameter.module.socketname-usage: A socketName set at the module level becomes the default socketName for the first unnamed action. It only applies to a single unnamed action, so it is primarily just a short-hand notation for when only a single omuxsock action is required. .. code-block:: rsyslog module(load="omuxsock" socketName="/tmp/socksample") Action usage ------------ .. _param-omuxsock-action-socketname: .. _omuxsock.parameter.action.socketname-usage: .. code-block:: rsyslog action(type="omuxsock" socketName="/tmp/socksample") .. note:: :ref:`param-omuxsock-socketname`, :ref:`param-omuxsock-abstract`, and :ref:`param-omuxsock-sockettype` constitute a logical configuration tuple. They are applied together as a whole tuple from a module level configuration to an action. Therefore, all three parameters must be explicitly specified in the action, or none may be specified in the action. In the latter case, the default is taken from the module. See also -------- See also :doc:`../../configuration/modules/omuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-oversizemode.rst0000644000000000000000000000013215114522477025442 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.462642342 30 ctime=1764935921.666553355 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-oversizemode.rst0000664000175000017500000000236215114522477025111 0ustar00rgerrger.. _param-imrelp-oversizemode: .. _imrelp.parameter.input.oversizemode: oversizeMode ============ .. index:: single: imrelp; oversizeMode single: oversizeMode .. summary-start Determines how messages larger than MaxDataSize are handled by the listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: oversizeMode :Scope: input :Type: string :Default: input=truncate :Required?: no :Introduced: 8.35.0 Description ----------- This parameter specifies how messages that are too long will be handled. For this parameter the length of the parameter :ref:`param-imrelp-maxdatasize` is used. - truncate: Messages will be truncated to the maximum message size. - abort: This is the behaviour until version 8.35.0. Upon receiving a message that is too long imrelp will abort. - accept: Messages will be accepted even if they are too long and an error message will be output. Using this option does have associated risks. Input usage ----------- .. _param-imrelp-input-oversizemode-usage: .. _imrelp.parameter.input.oversizemode-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" maxDataSize="10k" oversizeMode="truncate") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omgssapi-gssforwardservicename.rst0000644000000000000000000000013115114522477027663 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.473642612 30 ctime=1764935922.337563628 rsyslog-8.2512.0/doc/source/reference/parameters/omgssapi-gssforwardservicename.rst0000664000175000017500000000316315114522477027333 0ustar00rgerrger.. _param-omgssapi-gssforwardservicename: .. _omgssapi.parameter.module.gssforwardservicename: GssForwardServiceName ===================== .. index:: single: omgssapi; GssForwardServiceName single: GssForwardServiceName .. summary-start Sets the Kerberos service principal base name used when omgssapi establishes a GSSAPI-secured forwarding session. .. summary-end This parameter applies to :doc:`../../configuration/modules/omgssapi`. :Name: GssForwardServiceName :Scope: module :Type: string :Default: host :Required?: no :Introduced: 1.21.2 Description ----------- Specifies the service name used by the client when forwarding GSS-API wrapped messages. If unset, the module uses ``host`` as the base name. The actual service principal is constructed by appending ``@`` and the hostname that follows the ``:omgssapi:`` selector in legacy configurations. In legacy syntax this is configured with ``$GssForwardServiceName rsyslog``. Module usage ------------ .. _param-omgssapi-module-gssforwardservicename: .. _omgssapi.parameter.module.gssforwardservicename-usage: .. code-block:: rsyslog module(load="omgssapi" gssForwardServiceName="rsyslog") action(type="omgssapi" target="receiver.mydomain.com") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omgssapi.parameter.legacy.gssforwardservicename: - $GssForwardServiceName — maps to GssForwardServiceName (status: legacy) .. index:: single: omgssapi; $GssForwardServiceName single: $GssForwardServiceName See also -------- See also :doc:`../../configuration/modules/omgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omgssapi-actiongssforwarddefaulttemplate0000644000000000000000000000013115114522477031131 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.473642612 30 ctime=1764935922.335563598 rsyslog-8.2512.0/doc/source/reference/parameters/omgssapi-actiongssforwarddefaulttemplate.rst0000664000175000017500000000353215114522477031410 0ustar00rgerrger.. _param-omgssapi-actiongssforwarddefaulttemplate: .. _omgssapi.parameter.module.actiongssforwarddefaulttemplate: ActionGSSForwardDefaultTemplate =============================== .. index:: single: omgssapi; ActionGSSForwardDefaultTemplate single: ActionGSSForwardDefaultTemplate .. summary-start Sets the default output template omgssapi applies when a forwarding action omits an explicit template. .. summary-end This parameter applies to :doc:`../../configuration/modules/omgssapi`. :Name: ActionGSSForwardDefaultTemplate :Scope: module :Type: string :Default: RSYSLOG_TraditionalForwardFormat :Required?: no :Introduced: 3.12.4 Description ----------- Sets a new default template for the GSS-API forwarding action. When no template is specified in the forwarding rule, omgssapi falls back to this value. By default the module uses the built-in ``RSYSLOG_TraditionalForwardFormat`` template, matching the legacy syslog forward format. Legacy syntax configures this with directives such as ``$ActionGSSForwardDefaultTemplate RSYSLOG_ForwardFormat``. Module usage ------------ .. _param-omgssapi-module-actiongssforwarddefaulttemplate: .. _omgssapi.parameter.module.actiongssforwarddefaulttemplate-usage: .. code-block:: rsyslog module( load="omgssapi" actionGssForwardDefaultTemplate="RSYSLOG_ForwardFormat" ) action(type="omgssapi" target="receiver.mydomain.com") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omgssapi.parameter.legacy.actiongssforwarddefaulttemplate: - $ActionGSSForwardDefaultTemplate — maps to ActionGSSForwardDefaultTemplate (status: legacy) .. index:: single: omgssapi; $ActionGSSForwardDefaultTemplate single: $ActionGSSForwardDefaultTemplate See also -------- See also :doc:`../../configuration/modules/omgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-usepidfromsystem.rst0000644000000000000000000000013215062756615030424 xustar0030 mtime=1758190989.197641063 30 atime=1764928596.918578307 30 ctime=1764935921.888556754 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-usepidfromsystem.rst0000664000175000017500000000266715062756615030103 0ustar00rgerrger.. _param-imuxsock-syssock-usepidfromsystem: .. _imuxsock.parameter.module.syssock-usepidfromsystem: SysSock.UsePIDFromSystem ======================== .. index:: single: imuxsock; SysSock.UsePIDFromSystem single: SysSock.UsePIDFromSystem .. summary-start Obtains the logged PID from the log socket itself. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.UsePIDFromSystem :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 5.7.0 Description ----------- Specifies if the pid being logged shall be obtained from the log socket itself. If so, the TAG part of the message is rewritten. It is recommended to turn this option on, but the default is "off" to keep compatible with earlier versions of rsyslog. Module usage ------------ .. _param-imuxsock-module-syssock-usepidfromsystem: .. _imuxsock.parameter.module.syssock-usepidfromsystem-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.usePIDFromSystem="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogusepidfromsystem: - $SystemLogUsePIDFromSystem — maps to SysSock.UsePIDFromSystem (status: legacy) .. index:: single: imuxsock; $SystemLogUsePIDFromSystem single: $SystemLogUsePIDFromSystem See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmnormalize-path.rst0000644000000000000000000000013215071746523024727 xustar0030 mtime=1760021843.819420686 30 atime=1764928598.420624355 30 ctime=1764935922.067559494 rsyslog-8.2512.0/doc/source/reference/parameters/mmnormalize-path.rst0000664000175000017500000000170515071746523024376 0ustar00rgerrger.. _param-mmnormalize-path: .. _mmnormalize.parameter.action.path: path ==== .. index:: single: mmnormalize; path single: path .. summary-start Sets the JSON path where parsed elements are stored. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmnormalize`. :Name: path :Scope: action :Type: word :Default: action=$! :Required?: no :Introduced: at least 6.1.2, possibly earlier Description ----------- Specifies the JSON path under which parsed elements should be placed. By default, all parsed properties are merged into root of message properties. You can place them under a subtree, instead. You can place them in local variables, also, by setting ``path="$."``. Action usage ------------- .. _param-mmnormalize-action-path: .. _mmnormalize.parameter.action.path-usage: .. code-block:: rsyslog action(type="mmnormalize" path="$!subtree") See also -------- See also :doc:`../../configuration/modules/mmnormalize`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-tls-mycert.rst0000644000000000000000000000013215114522477025055 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.482642833 30 ctime=1764935922.430565052 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-tls-mycert.rst0000664000175000017500000000153415114522477024524 0ustar00rgerrger.. _param-omhttp-tls-mycert: .. _omhttp.parameter.input.tls-mycert: tls.mycert ========== .. index:: single: omhttp; tls.mycert single: tls.mycert .. summary-start Supplies the client certificate file used for HTTPS mutual authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: tls.mycert :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- This parameter sets the path to the SSL client certificate. Expects ``.pem`` format. Input usage ----------- .. _omhttp.parameter.input.tls-mycert-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" tlsMyCert="/etc/rsyslog/certs/omhttp-client.pem" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-proxyport.rst0000644000000000000000000000013215114522477025040 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.478642734 30 ctime=1764935922.393564486 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-proxyport.rst0000664000175000017500000000161215114522477024504 0ustar00rgerrger.. _param-omhttp-proxyport: .. _omhttp.parameter.input.proxyport: proxyport ========= .. index:: single: omhttp; proxyport single: proxyport .. summary-start Sets the port number of the HTTP proxy used by omhttp. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: proxyport :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- Configures the libcurl ``CURLOPT_PROXYPORT`` option for HTTP requests issued by omhttp. For more details see the `libcurl documentation for CURLOPT_PROXYPORT `_. Input usage ----------- .. _omhttp.parameter.input.proxyport-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" proxyPort="8080" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-cacert.rst0000644000000000000000000000013115103346332024763 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.797482378 29 ctime=1764935921.36054867 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-cacert.rst0000664000175000017500000000163715103346332024437 0ustar00rgerrger.. _param-imdtls-tls-cacert: .. _imdtls.parameter.input.tls-cacert: tls.caCert ========== .. index:: single: imdtls; tls.caCert single: tls.caCert .. summary-start Specifies the CA certificate file used to verify DTLS client certificates. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.caCert :Scope: input :Type: string :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- The CA certificate that is being used to verify the client certificates. This file must be configured if ``tls.authMode`` is set to ``fingerprint``, ``name`` or ``certvalid``. Input usage ----------- .. _imdtls.parameter.input.tls-cacert-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.caCert="/etc/rsyslog/ca.pem" tls.authMode="certvalid") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-allowunsignedcerts.rst0000644000000000000000000000013115114522477026665 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.474642636 30 ctime=1764935922.351563842 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-allowunsignedcerts.rst0000664000175000017500000000204615114522477026334 0ustar00rgerrger.. _param-omhttp-allowunsignedcerts: .. _omhttp.parameter.input.allowunsignedcerts: allowunsignedcerts ================== .. index:: single: omhttp; allowunsignedcerts single: allowunsignedcerts .. summary-start Controls whether omhttp skips server certificate validation when using HTTPS. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: allowunsignedcerts :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- If ``"on"``, this will set the curl `CURLOPT_SSL_VERIFYPEER `_ option to ``0``. You are strongly discouraged to set this to ``"on"``. It is primarily useful only for debugging or testing. Input usage ----------- .. _omhttp.parameter.input.allowunsignedcerts-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" useHttps="on" allowUnsignedCerts="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-maxbytesperminute.rst0000644000000000000000000000013215062756615026476 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.081491122 30 ctime=1764935921.401549298 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-maxbytesperminute.rst0000664000175000017500000000223515062756615026144 0ustar00rgerrger.. _param-imfile-maxbytesperminute: .. _imfile.parameter.input.maxbytesperminute: .. _imfile.parameter.maxbytesperminute: MaxBytesPerMinute ================= .. index:: single: imfile; MaxBytesPerMinute single: MaxBytesPerMinute .. summary-start Drops messages when the total bytes per minute exceed the specified limit. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: MaxBytesPerMinute :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Instructs rsyslog to enqueue only up to the specified number of bytes as messages per minute. Once the limit is reached, subsequent messages are discarded. Messages are not truncated; an entire message is dropped if it would exceed the limit. The default ``0`` disables this check. Input usage ----------- .. _param-imfile-input-maxbytesperminute: .. _imfile.parameter.input.maxbytesperminute-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" MaxBytesPerMinute="0") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-dynsearchindex.rst0000644000000000000000000000013215062756615027622 xustar0030 mtime=1758190989.202641134 30 atime=1764928599.525658186 30 ctime=1764935922.193561424 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-dynsearchindex.rst0000664000175000017500000000176015062756615027272 0ustar00rgerrger.. _param-omelasticsearch-dynsearchindex: .. _omelasticsearch.parameter.module.dynsearchindex: dynSearchIndex ============== .. index:: single: omelasticsearch; dynSearchIndex single: dynSearchIndex .. summary-start Treat `searchIndex` as a template name instead of a literal. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: dynSearchIndex :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If enabled, the value of `searchIndex` is interpreted as the name of a template whose expansion becomes the index name. Action usage ------------ .. _param-omelasticsearch-action-dynsearchindex: .. _omelasticsearch.parameter.action.dynsearchindex: .. code-block:: rsyslog action(type="omelasticsearch" dynSearchIndex="...") Notes ----- - Previously documented as a "binary" option. See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-ratelimitburst.rst0000644000000000000000000000013215114522477025773 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.457642219 30 ctime=1764935921.529551258 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-ratelimitburst.rst0000664000175000017500000000153315114522477025441 0ustar00rgerrger.. _param-imklog-ratelimitburst: .. _imklog.parameter.module.ratelimitburst: RatelimitBurst ============== .. index:: single: imklog; RatelimitBurst single: RatelimitBurst .. summary-start Specifies how many messages imklog can emit within the configured rate-limiting interval. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: RatelimitBurst :Scope: module :Type: integer :Default: 10000 :Required?: no :Introduced: 8.35.0 Description ----------- Specifies the rate-limiting burst in number of messages. Set it high to preserve all boot-up messages. Module usage ------------ .. _param-imklog-module-ratelimitburst: .. _imklog.parameter.module.ratelimitburst-usage: .. code-block:: rsyslog module(load="imklog" ratelimitBurst="20000") See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-certfile.rst0000644000000000000000000000013115062756615027061 xustar0030 mtime=1758190989.193641006 29 atime=1764928596.42156305 30 ctime=1764935921.767554902 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-certfile.rst0000664000175000017500000000256615062756615026537 0ustar00rgerrger.. _param-imtcp-streamdriver-certfile: .. _imtcp.parameter.input.streamdriver-certfile: streamDriver.CertFile ===================== .. index:: single: imtcp; streamDriver.CertFile single: streamDriver.CertFile .. summary-start Overrides ``DefaultNetstreamDriverCertFile`` for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: streamDriver.CertFile :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=global parameter :Required?: no :Introduced: 8.2108.0 Description ----------- .. versionadded:: 8.2108.0 This permits to override the ``DefaultNetstreamDriverCertFile`` global parameter on the ``input()`` level. For further details, see the global parameter. .. note:: The GnuTLS driver sends all certificates contained in the file specified via ``StreamDriver.CertFile`` to connecting clients. To expose intermediate certificates, the file must contain the server certificate first, followed by the intermediate certificates. This capability was added in rsyslog version 8.36.0. Input usage ----------- .. _param-imtcp-input-streamdriver-certfile: .. _imtcp.parameter.input.streamdriver-certfile-usage: .. code-block:: rsyslog input(type="imtcp" streamDriver.certFile="/etc/ssl/certs/cert.pem") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-statsname.rst0000644000000000000000000000013215114522477024740 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.471642562 30 ctime=1764935922.156560857 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-statsname.rst0000664000175000017500000000242015114522477024402 0ustar00rgerrger.. _param-omdtls-statsname: .. _omdtls.parameter.input.statsname: statsname ========= .. index:: single: omdtls; statsname single: statsname .. summary-start Enables a dedicated per-action statistics counter identified by the provided name. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: statsname :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- This parameter assigns a unique name to a dedicated statistics counter for the ``omdtls`` action instance. When set, rsyslog tracks separate "submitted" and "failures" counters for this action that can be retrieved via the :doc:`impstats <../../configuration/modules/impstats>` module by referencing the specified name. This makes it easier to monitor the performance and health of individual DTLS forwarding actions. If left unset, the action contributes only to the global ``omdtls`` statistics origin. Input usage ----------- .. _omdtls.parameter.input.statsname-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" statsName="dtls_to_server1") See also -------- See also :doc:`../../configuration/modules/omdtls`, :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-notifyonconnectionopen.rst0000644000000000000000000000013215062756615027367 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.079552551 30 ctime=1764935921.741554504 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-notifyonconnectionopen.rst0000664000175000017500000000160715062756615027037 0ustar00rgerrger.. _param-imtcp-notifyonconnectionopen: .. _imtcp.parameter.module.notifyonconnectionopen: NotifyOnConnectionOpen ====================== .. index:: single: imtcp; NotifyOnConnectionOpen single: NotifyOnConnectionOpen .. summary-start Emits a message when a remote peer opens a connection. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: NotifyOnConnectionOpen :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Instructs imtcp to emit a message if the remote peer opens a connection. Module usage ------------ .. _param-imtcp-module-notifyonconnectionopen: .. _imtcp.parameter.module.notifyonconnectionopen-usage: .. code-block:: rsyslog module(load="imtcp" notifyOnConnectionOpen="on") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsendertrack-cmdfile.rst0000644000000000000000000000013215114522477025703 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.486642931 30 ctime=1764935922.558567012 rsyslog-8.2512.0/doc/source/reference/parameters/omsendertrack-cmdfile.rst0000664000175000017500000000261215114522477025350 0ustar00rgerrger.. _param-omsendertrack-cmdfile: .. _omsendertrack.parameter.input.cmdfile: cmdfile ======= .. index:: single: omsendertrack; cmdfile single: cmdfile .. summary-start Defines the absolute path to the command file that omsendertrack reads when rsyslog receives a HUP signal. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsendertrack`. :Name: cmdfile :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: 8.2506.0 (Proof-of-Concept) Description ----------- This optional parameter allows you to specify the **absolute path to a command file**. This file *is designed to be processed when rsyslog receives a HUP signal* (for example via ``systemctl reload rsyslog``). **Note:** Command file support is currently **not implemented** in this proof-of-concept version of the module. When implemented, this feature is intended to allow dynamic control over the module's behavior, such as resetting statistics for specific senders, without requiring an rsyslog restart. Input usage ----------- .. _omsendertrack.parameter.input.cmdfile-usage: .. code-block:: rsyslog module(load="omsendertrack") action(type="omsendertrack" senderId="%hostname%" stateFile="/var/lib/rsyslog/senderstats.json" cmdFile="/var/lib/rsyslog/sendercommands.txt") See also -------- See also :doc:`../../configuration/modules/omsendertrack`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-batch.rst0000644000000000000000000000013115114522477024032 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.475642661 30 ctime=1764935922.361563996 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-batch.rst0000664000175000017500000000513115114522477023477 0ustar00rgerrger.. _param-omhttp-batch: .. _omhttp.parameter.input.batch: batch ===== .. index:: single: omhttp; batch single: batch .. summary-start Enables batching so omhttp queues messages and submits them in a single HTTP request. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: batch :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not specified Description ----------- Batch and ``bulkmode`` do the same thing, ``bulkmode`` is included for backwards compatibility. See the :ref:`param-omhttp-batch-format` section for a detailed breakdown of how batching is implemented. This parameter activates batching mode, which queues messages and sends them as a single request. There are several related parameters that specify the format and size of the batch: they are :ref:`param-omhttp-batch-format`, :ref:`param-omhttp-batch-maxbytes`, and :ref:`param-omhttp-batch-maxsize`. Note that rsyslog core is the ultimate authority on when a batch must be submitted, due to the way that batching is implemented. This plugin implements the `output plugin transaction interface `_. There may be multiple batches in a single transaction, but a batch will never span multiple transactions. This means that if :ref:`param-omhttp-batch-maxsize` or :ref:`param-omhttp-batch-maxbytes` is set very large, you may never actually see batches hit this size. Additionally, the number of messages per transaction is determined by the size of the main, action, and ruleset queues as well. The plugin flushes a batch early if either the configured :ref:`param-omhttp-batch-maxsize` is reached or if adding the next message would exceed :ref:`param-omhttp-batch-maxbytes` once serialized (format overhead included). When :ref:`param-omhttp-dynrestpath` is enabled, a change of the effective REST path also forces a flush so that each batch targets a single path. Additionally, due to some open issues with rsyslog and the transaction interface, batching requires some nuanced :ref:`param-omhttp-retry` configuration. By default, omhttp signals transport/server failures to rsyslog core (suspend/resume), which performs retries. The :ref:`param-omhttp-retry-ruleset` mechanism remains available for advanced per-message retry handling in batch mode. Input usage ----------- .. _omhttp.parameter.input.batch-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" batch="on" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-flushontxend.rst0000644000000000000000000000013215062756615025440 xustar0030 mtime=1758190989.208641219 30 atime=1764928600.130676694 30 ctime=1764935922.314563276 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-flushontxend.rst0000664000175000017500000000417215062756615025110 0ustar00rgerrger.. _param-omfile-flushontxend: .. _omfile.parameter.module.flushontxend: flushOnTXEnd ============ .. index:: single: omfile; flushOnTXEnd single: flushOnTXEnd .. summary-start Omfile has the capability to write output using a buffered writer. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: flushOnTXEnd :Scope: action :Type: boolean :Default: action=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Omfile has the capability to write output using a buffered writer. Disk writes are only done when the buffer is full. So if an error happens during that write, data is potentially lost. Bear in mind that the buffer may become full only after several hours or a rsyslog shutdown (however a buffer flush can still be forced by sending rsyslogd a HUP signal). In cases where this is unacceptable, set FlushOnTXEnd to "on". Then, data is written at the end of each transaction (for pre-v5 this means after each log message) and the usual error recovery thus can handle write errors without data loss. Note that this option severely reduces the effect of zip compression and should be switched to "off" for that use case. Also note that the default -on- is primarily an aid to preserve the traditional syslogd behaviour. If you are using dynamic file names (dynafiles), flushes can actually happen more frequently. In this case, a flush can also happen when the file name changes within a transaction. Action usage ------------ .. _param-omfile-action-flushontxend: .. _omfile.parameter.action.flushontxend: .. code-block:: rsyslog action(type="omfile" flushOnTXEnd="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.omfileflushontxend: - $OMFileFlushOnTXEnd — maps to flushOnTXEnd (status: legacy) .. index:: single: omfile; $OMFileFlushOnTXEnd single: $OMFileFlushOnTXEnd See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-searchindex.rst0000644000000000000000000000013215062756615027107 xustar0030 mtime=1758190989.204641162 30 atime=1764928599.516657911 30 ctime=1764935922.227561944 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-searchindex.rst0000664000175000017500000000153415062756615026556 0ustar00rgerrger.. _param-omelasticsearch-searchindex: .. _omelasticsearch.parameter.module.searchindex: searchIndex =========== .. index:: single: omelasticsearch; searchIndex single: searchIndex .. summary-start Elasticsearch index where events are written. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: searchIndex :Scope: action :Type: word :Default: action=system :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Name of the target Elasticsearch index. When unset it defaults to `system`. Action usage ------------ .. _param-omelasticsearch-action-searchindex: .. _omelasticsearch.parameter.action.searchindex: .. code-block:: rsyslog action(type="omelasticsearch" searchIndex="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-ratelimit-interval.rst0000644000000000000000000000013215103061376030603 xustar0030 mtime=1762419454.852381127 30 atime=1764928596.926578553 30 ctime=1764935921.879556616 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-ratelimit-interval.rst0000664000175000017500000000312315103061376030246 0ustar00rgerrger.. _param-imuxsock-syssock-ratelimit-interval: .. _imuxsock.parameter.module.syssock-ratelimit-interval: SysSock.RateLimit.Interval ========================== .. index:: single: imuxsock; SysSock.RateLimit.Interval single: SysSock.RateLimit.Interval .. summary-start Sets the rate-limiting interval in seconds for the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.RateLimit.Interval :Scope: module :Type: integer :Default: module=0 :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies the rate-limiting interval in seconds. Default value is 0, which turns off rate limiting. Set it to a number of seconds (5 recommended) to activate rate-limiting. The default of 0 has been chosen as people experienced problems with this feature activated by default. Now it needs an explicit opt-in by setting this parameter. Module usage ------------ .. _param-imuxsock-module-syssock-ratelimit-interval: .. _imuxsock.parameter.module.syssock-ratelimit-interval-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.rateLimit.interval="5") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogratelimitinterval: - $SystemLogRateLimitInterval — maps to SysSock.RateLimit.Interval (status: legacy) .. index:: single: imuxsock; $SystemLogRateLimitInterval single: $SystemLogRateLimitInterval See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-keepalive.rst0000644000000000000000000000013215114522477024674 xustar0030 mtime=1764926783.028631686 30 atime=1764926783.462642342 30 ctime=1764935921.659553248 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-keepalive.rst0000664000175000017500000000144015114522477024337 0ustar00rgerrger.. _param-imrelp-keepalive: .. _imrelp.parameter.input.keepalive: keepAlive ========= .. index:: single: imrelp; keepAlive single: keepAlive .. summary-start Toggles TCP keep-alive probes for RELP listener sockets. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: keepAlive :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: Not documented Description ----------- Enable or disable keep-alive packets at the TCP socket layer. By default keep-alive is disabled. Input usage ----------- .. _param-imrelp-input-keepalive-usage: .. _imrelp.parameter.input.keepalive-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" keepAlive="on") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-name.rst0000644000000000000000000000013215062756615023500 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.284558844 30 ctime=1764935921.734554396 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-name.rst0000664000175000017500000000232615062756615023147 0ustar00rgerrger.. _param-imtcp-name: .. _imtcp.parameter.input.name: Name ==== .. index:: single: imtcp; Name single: Name .. summary-start Sets the value for the ``inputname`` property. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: Name :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=imtcp :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets a name for the ``inputname`` property. If no name is set, ``imtcp`` is used by default. Setting a name is not strictly necessary but can be useful to filter based on which input received the message. Input usage ----------- .. _param-imtcp-input-name: .. _imtcp.parameter.input.name-usage: .. code-block:: rsyslog input(type="imtcp" name="tcp1" port="514") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverinputname: - $InputTCPServerInputName — maps to Name (status: legacy) .. index:: single: imtcp; $InputTCPServerInputName single: $InputTCPServerInputName See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-endmsg-regex.rst0000644000000000000000000000013215062756615025276 xustar0030 mtime=1758190989.184640879 30 atime=1764928593.968487644 30 ctime=1764935921.384549038 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-endmsg-regex.rst0000664000175000017500000000264615062756615024752 0ustar00rgerrger.. _param-imfile-endmsg-regex: .. _imfile.parameter.input.endmsg-regex: .. _imfile.parameter.endmsg-regex: endmsg.regex ============ .. index:: single: imfile; endmsg.regex single: endmsg.regex .. summary-start Regex that identifies the end of a multi-line message. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: endmsg.regex :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: no :Introduced: 8.38.0 Description ----------- Allows processing of multi-line messages. A message is terminated when ``endmsg.regex`` matches the line that marks the end of the message. It is more flexible than ``readMode`` but has lower performance. ``endmsg.regex``, ``startmsg.regex`` and ``readMode`` cannot all be defined for the same input. Examples: .. code-block:: none date stdout P start of message date stdout P middle of message date stdout F end of message Here ``endmsg.regex="^[^ ]+ stdout F "`` matches the line with ``F`` and assembles the message ``start of message middle of message end of message``. Input usage ----------- .. _param-imfile-input-endmsg-regex: .. _imfile.parameter.input.endmsg-regex-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" endmsg.regex="pattern") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-mailfrom.rst0000644000000000000000000000013215114522477024523 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.485642906 30 ctime=1764935922.506566216 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-mailfrom.rst0000664000175000017500000000231615114522477024171 0ustar00rgerrger.. _param-ommail-mailfrom: .. _ommail.parameter.input.mailfrom: mailFrom ======== .. index:: single: ommail; mailFrom single: mailFrom .. summary-start Defines the sender email address placed in outgoing messages from ommail. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: mailFrom :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: 8.5.0 Description ----------- This mandatory parameter defines the email address used as the sender. It will appear in the ``From:`` header of the email. Input usage ------------ .. _ommail.parameter.input.mailfrom-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailfrom: - $ActionMailFrom — maps to mailFrom (status: legacy) .. index:: single: ommail; $ActionMailFrom single: $ActionMailFrom See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdiag-serverstreamdrivermode.rst0000644000000000000000000000013215114522477027474 xustar0030 mtime=1764926783.026631637 30 atime=1764926783.453642121 30 ctime=1764935921.320548058 rsyslog-8.2512.0/doc/source/reference/parameters/imdiag-serverstreamdrivermode.rst0000664000175000017500000000331615114522477027143 0ustar00rgerrger.. _param-imdiag-serverstreamdrivermode: .. _imdiag.parameter.input.serverstreamdrivermode: ServerStreamDriverMode ====================== .. index:: single: imdiag; ServerStreamDriverMode single: ServerStreamDriverMode .. summary-start Accepts a numeric stream driver mode value, but imdiag forces the plain TCP driver so the setting is ignored. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdiag`. :Name: ServerStreamDriverMode :Scope: input :Type: integer :Default: input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Provides the mode number consumed by the selected :doc:`network stream driver <../../concepts/netstrm_drvr>`. imdiag always uses the plain TCP (``ptcp``) stream driver, which does not act on the provided mode value. The parameter remains available for configuration compatibility and possible future extensions, but it does not alter behavior in current releases. Input usage ----------- .. _param-imdiag-input-serverstreamdrivermode: .. _imdiag.parameter.input.serverstreamdrivermode-usage: .. code-block:: rsyslog module(load="imdiag") input(type="imdiag" listenPortFileName="/var/run/rsyslog/imdiag.port" serverStreamDriverMode="1" serverRun="19998") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imdiag.parameter.legacy.imdiagserverstreamdrivermode: - $IMDiagServerStreamDriverMode — maps to ServerStreamDriverMode (status: legacy) .. index:: single: imdiag; $IMDiagServerStreamDriverMode single: $IMDiagServerStreamDriverMode See also -------- See also :doc:`../../configuration/modules/imdiag`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-syssock-ratelimit-severity.rst0000644000000000000000000000013215103061376030631 xustar0030 mtime=1762419454.852381127 30 atime=1764928596.940578982 30 ctime=1764935921.881556647 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-syssock-ratelimit-severity.rst0000664000175000017500000000262515103061376030302 0ustar00rgerrger.. _param-imuxsock-syssock-ratelimit-severity: .. _imuxsock.parameter.module.syssock-ratelimit-severity: SysSock.RateLimit.Severity ========================== .. index:: single: imuxsock; SysSock.RateLimit.Severity single: SysSock.RateLimit.Severity .. summary-start Specifies which message severity levels are rate-limited on the system log socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: SysSock.RateLimit.Severity :Scope: module :Type: integer :Default: module=1 :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Specifies the severity of messages that shall be rate-limited. .. seealso:: https://en.wikipedia.org/wiki/Syslog#Severity_level Module usage ------------ .. _param-imuxsock-module-syssock-ratelimit-severity: .. _imuxsock.parameter.module.syssock-ratelimit-severity-usage: .. code-block:: rsyslog module(load="imuxsock" sysSock.rateLimit.severity="5") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.systemlogratelimitseverity: - $SystemLogRateLimitSeverity — maps to SysSock.RateLimit.Severity (status: legacy) .. index:: single: imuxsock; $SystemLogRateLimitSeverity single: $SystemLogRateLimitSeverity See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omdtls-tls-tlscfgcmd.rst0000644000000000000000000000013115114522477025506 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.472642587 30 ctime=1764935922.172561102 rsyslog-8.2512.0/doc/source/reference/parameters/omdtls-tls-tlscfgcmd.rst0000664000175000017500000000331015114522477025150 0ustar00rgerrger.. _param-omdtls-tls-tlscfgcmd: .. _omdtls.parameter.input.tls-tlscfgcmd: tls.tlscfgcmd ============= .. index:: single: omdtls; tls.tlscfgcmd single: tls.tlscfgcmd .. summary-start Passes additional OpenSSL configuration commands to fine-tune DTLS behavior. .. summary-end This parameter applies to :doc:`../../configuration/modules/omdtls`. :Name: tls.tlscfgcmd :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: v8.2402.0 Description ----------- Used to pass additional OpenSSL configuration commands. This can be used to fine-tune the OpenSSL settings by passing configuration commands to the OpenSSL library. OpenSSL Version 1.0.2 or higher is required for this feature. A list of possible commands and their valid values can be found in the `SSL_CONF_cmd documentation `_. The setting can be single or multiline, each configuration command is separated by linefeed (``\n``). Command and value are separated by an equal sign (``=``). Here are a few samples: Example 1 ~~~~~~~~~ This will allow all protocols except for SSLv2 and SSLv3: .. code-block:: none tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3" Example 2 ~~~~~~~~~ This will allow all protocols except for SSLv2, SSLv3 and TLSv1. It will also set the minimum protocol to TLSv1.2 .. code-block:: none tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1\nMinProtocol=TLSv1.2" Input usage ----------- .. _omdtls.parameter.input.tls-tlscfgcmd-usage: .. code-block:: rsyslog action(type="omdtls" target="192.0.2.1" port="4433" tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3") See also -------- See also :doc:`../../configuration/modules/omdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpheaderkey.rst0000644000000000000000000000013115114522477025612 xustar0030 mtime=1764926783.032631784 29 atime=1764926783.47764271 30 ctime=1764935922.379564271 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpheaderkey.rst0000664000175000017500000000206015114522477025255 0ustar00rgerrger.. _param-omhttp-httpheaderkey: .. _omhttp.parameter.input.httpheaderkey: httpheaderkey ============= .. index:: single: omhttp; httpheaderkey single: httpheaderkey .. summary-start Defines the single custom HTTP header name to send with each omhttp request. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpheaderkey :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The header key. Currently only a single additional header/key pair is configurable with this parameter. To specify multiple headers use the :ref:`param-omhttp-httpheaders` parameter. This parameter, along with :ref:`param-omhttp-httpheadervalue`, may be deprecated in the future. Input usage ----------- .. _omhttp.parameter.input.httpheaderkey-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpHeaderKey="X-Event-Source" httpHeaderValue="logs" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-signalonclose.rst0000644000000000000000000000013215062756615025607 xustar0030 mtime=1758190989.212641276 30 atime=1764928602.134737907 30 ctime=1764935922.551566904 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-signalonclose.rst0000664000175000017500000000267415062756615025264 0ustar00rgerrger.. _param-omprog-signalonclose: .. _omprog.parameter.action.signalonclose: signalOnClose ============= .. index:: single: omprog; signalOnClose single: signalOnClose .. summary-start Sends a TERM signal to the program before closing its stdin. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: signalOnClose :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: 8.23.0 Description ----------- Specifies whether a TERM signal must be sent to the external program before closing it (when either the worker thread has been unscheduled, a restart of the program is being forced, or rsyslog is about to shutdown). If this switch is set to "on", rsyslog will send a TERM signal to the child process before closing the pipe. That is, the process will first receive a TERM signal, and then an EOF on stdin. No signal is issued if this switch is set to "off" (default). The child process can still detect it must terminate because reading from stdin will return EOF. See the :ref:`param-omprog-killunresponsive` parameter for more details. Action usage ------------ .. _param-omprog-action-signalonclose: .. _omprog.parameter.action.signalonclose-usage: .. code-block:: rsyslog action(type="omprog" signalOnClose="on") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imsolaris-imsolarislogsocketname.rst0000644000000000000000000000013115114522477030216 xustar0030 mtime=1764926783.029631711 29 atime=1764926783.46664244 30 ctime=1764935921.700553876 rsyslog-8.2512.0/doc/source/reference/parameters/imsolaris-imsolarislogsocketname.rst0000664000175000017500000000245515114522477027671 0ustar00rgerrger.. _param-imsolaris-imsolarislogsocketname: .. _imsolaris.parameter.module.imsolarislogsocketname: IMSolarisLogSocketName ====================== .. index:: single: imsolaris; IMSolarisLogSocketName single: IMSolarisLogSocketName .. summary-start Specifies the Solaris log stream device imsolaris reads, defaulting to ``/dev/log``. .. summary-end This parameter applies to :doc:`../../configuration/modules/imsolaris`. .. note:: This is a legacy global directive. The imsolaris module does not support the modern ``module()``/``input()`` syntax. :Name: IMSolarisLogSocketName :Scope: module :Type: string (path) :Default: /dev/log :Required?: no :Introduced: Not documented Description ----------- This directive specifies the path to the Solaris log socket (stream) for reading local application and kernel messages. If omitted, it defaults to ``/dev/log``. Since directive names are case-insensitive, the canonical form ``$IMSolarisLogSocketName`` is recommended for readability. Module usage ------------ .. _param-imsolaris-module-imsolarislogsocketname-usage: .. _imsolaris.parameter.module.imsolarislogsocketname-usage: .. code-block:: rsyslog $ModLoad imsolaris $IMSolarisLogSocketName "/var/run/rsyslog/solaris.log" See also -------- See also :doc:`../../configuration/modules/imsolaris`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-fileowner.rst0000644000000000000000000000013215062756615024711 xustar0030 mtime=1758190989.208641219 30 atime=1764928599.894669477 30 ctime=1764935922.307563169 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-fileowner.rst0000664000175000017500000000302115062756615024351 0ustar00rgerrger.. _param-omfile-fileowner: .. _omfile.parameter.module.fileowner: fileOwner ========= .. index:: single: omfile; fileOwner single: fileOwner .. summary-start Set the file owner for files newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: fileOwner :Scope: module, action :Type: uid :Default: module=process user; action=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the file owner for files newly created. Please note that this setting does not affect the owner of files already existing. The parameter is a user name, for which the userid is obtained by rsyslogd during startup processing. Interim changes to the user mapping are *not* detected. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-fileowner: .. _omfile.parameter.module.fileowner-usage: .. code-block:: rsyslog module(load="builtin:omfile" fileOwner="...") Action usage ------------ .. _param-omfile-action-fileowner: .. _omfile.parameter.action.fileowner: .. code-block:: rsyslog action(type="omfile" fileOwner="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.fileowner: - $FileOwner — maps to fileOwner (status: legacy) .. index:: single: omfile; $FileOwner single: $FileOwner See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-fileownernum.rst0000644000000000000000000000013015062756615025427 xustar0030 mtime=1758190989.208641219 30 atime=1764928599.902669722 28 ctime=1764935922.3095632 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-fileownernum.rst0000664000175000017500000000310615062756615025075 0ustar00rgerrger.. _param-omfile-fileownernum: .. _omfile.parameter.module.fileownernum: fileOwnerNum ============ .. index:: single: omfile; fileOwnerNum single: fileOwnerNum .. summary-start Set the file owner for files newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: fileOwnerNum :Scope: module, action :Type: integer :Default: module=process user; action=system default :Required?: no :Introduced: 7.5.8 Description ----------- Set the file owner for files newly created. Please note that this setting does not affect the owner of files already existing. The parameter is a numerical ID, which is used regardless of whether the user actually exists. This can be useful if the user mapping is not available to rsyslog during startup. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-fileownernum: .. _omfile.parameter.module.fileownernum-usage: .. code-block:: rsyslog module(load="builtin:omfile" fileOwnerNum="...") Action usage ------------ .. _param-omfile-action-fileownernum: .. _omfile.parameter.action.fileownernum: .. code-block:: rsyslog action(type="omfile" fileOwnerNum="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.fileownernum: - $FileOwnerNum — maps to fileOwnerNum (status: legacy) .. index:: single: omfile; $FileOwnerNum single: $FileOwnerNum See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imuxsock-annotate.rst0000644000000000000000000000013215062756615025117 xustar0030 mtime=1758190989.195641035 30 atime=1764928597.090583584 30 ctime=1764935921.830555866 rsyslog-8.2512.0/doc/source/reference/parameters/imuxsock-annotate.rst0000664000175000017500000000231315062756615024562 0ustar00rgerrger.. _param-imuxsock-annotate: .. _imuxsock.parameter.input.annotate: Annotate ======== .. index:: single: imuxsock; Annotate single: Annotate .. summary-start Enables annotation and trusted properties for this input. .. summary-end This parameter applies to :doc:`../../configuration/modules/imuxsock`. :Name: Annotate :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 7.0.0, possibly earlier Description ----------- Turn on annotation/trusted properties for the input that is being defined. See the :ref:`imuxsock-trusted-properties-label` section for more info. Input usage ----------- .. _param-imuxsock-input-annotate: .. _imuxsock.parameter.input.annotate-usage: .. code-block:: rsyslog input(type="imuxsock" annotate="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imuxsock.parameter.legacy.inputunixlistensocketannotate: - $InputUnixListenSocketAnnotate — maps to Annotate (status: legacy) .. index:: single: imuxsock; $InputUnixListenSocketAnnotate single: $InputUnixListenSocketAnnotate See also -------- See also :doc:`../../configuration/modules/imuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-streamdriver-crlfile.rst0000644000000000000000000000013215062756615026705 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.404562528 30 ctime=1764935921.771554963 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-streamdriver-crlfile.rst0000664000175000017500000000213515062756615026352 0ustar00rgerrger.. _param-imtcp-streamdriver-crlfile: .. _imtcp.parameter.input.streamdriver-crlfile: streamDriver.CRLFile ==================== .. index:: single: imtcp; streamDriver.CRLFile single: streamDriver.CRLFile .. summary-start Overrides the CRL file set via the global configuration. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: streamDriver.CRLFile :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=global parameter :Required?: no :Introduced: 8.2308.0 Description ----------- .. versionadded:: 8.2308.0 This permits to override the CRL (Certificate revocation list) file set via ``global()`` config object at the per-action basis. This parameter is ignored if the netstream driver and/or its mode does not need or support certificates. Input usage ----------- .. _param-imtcp-input-streamdriver-crlfile: .. _imtcp.parameter.input.streamdriver-crlfile-usage: .. code-block:: rsyslog input(type="imtcp" streamDriver.crlFile="/etc/ssl/crl.pem") See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dirgroup.rst0000644000000000000000000000013215062756615024552 xustar0030 mtime=1758190989.206641191 30 atime=1764928599.942670946 30 ctime=1764935922.278562725 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dirgroup.rst0000664000175000017500000000303215062756615024214 0ustar00rgerrger.. _param-omfile-dirgroup: .. _omfile.parameter.module.dirgroup: dirGroup ======== .. index:: single: omfile; dirGroup single: dirGroup .. summary-start Set the group for directories newly created. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dirGroup :Scope: module, action :Type: gid :Default: module=process user's primary group; action=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the group for directories newly created. Please note that this setting does not affect the group of directories already existing. The parameter is a group name, for which the groupid is obtained by rsyslogd on during startup processing. Interim changes to the user mapping are not detected. When set on the module, the value becomes the default for actions. Module usage ------------ .. _param-omfile-module-dirgroup: .. _omfile.parameter.module.dirgroup-usage: .. code-block:: rsyslog module(load="builtin:omfile" dirGroup="...") Action usage ------------ .. _param-omfile-action-dirgroup: .. _omfile.parameter.action.dirgroup: .. code-block:: rsyslog action(type="omfile" dirGroup="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.dirgroup: - $DirGroup — maps to dirGroup (status: legacy) .. index:: single: omfile; $DirGroup single: $DirGroup See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omclickhouse-usehttps.rst0000644000000000000000000000013115114522477026002 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.470642538 29 ctime=1764935922.14956075 rsyslog-8.2512.0/doc/source/reference/parameters/omclickhouse-usehttps.rst0000664000175000017500000000156315114522477025454 0ustar00rgerrger.. _param-omclickhouse-usehttps: .. _omclickhouse.parameter.input.usehttps: useHttps ======== .. index:: single: omclickhouse; useHttps single: useHttps single: omclickhouse; usehttps single: usehttps .. summary-start Controls whether HTTPS is used by default when no scheme is specified for the ClickHouse server. .. summary-end This parameter applies to :doc:`/configuration/modules/omclickhouse`. :Name: useHttps :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: not specified Description ----------- Default scheme to use when sending events to ClickHouse if none is specified on a server. Input usage ----------- .. _omclickhouse.parameter.input.usehttps-usage: .. code-block:: rsyslog module(load="omclickhouse") action(type="omclickhouse" useHttps="off") See also -------- See also :doc:`/configuration/modules/omclickhouse`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omprog-binary.rst0000644000000000000000000000013215062756615024233 xustar0030 mtime=1758190989.211641261 30 atime=1764928602.053735437 30 ctime=1764935922.524566491 rsyslog-8.2512.0/doc/source/reference/parameters/omprog-binary.rst0000664000175000017500000000257615062756615023711 0ustar00rgerrger.. _param-omprog-binary: .. _omprog.parameter.action.binary: binary ====== .. index:: single: omprog; binary single: binary .. summary-start Specifies the command line of the external program to execute. .. summary-end This parameter applies to :doc:`../../configuration/modules/omprog`. :Name: binary :Scope: action :Type: string :Default: none :Required?: yes :Introduced: at least 5.x, possibly earlier Description ----------- Full path and command line parameters of the external program to execute. Arbitrary external programs should be placed under the /usr/libexec/rsyslog directory. That is, the binaries put in this namespaced directory are meant for the consumption of rsyslog, and are not intended to be executed by users. In legacy config, it is **not possible** to specify command line parameters. Action usage ------------ .. _param-omprog-action-binary: .. _omprog.parameter.action.binary-usage: .. code-block:: rsyslog action(type="omprog" binary="/usr/libexec/rsyslog/log.sh") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omprog.parameter.legacy.actionomprogbinary: - $ActionOMProgBinary — maps to binary (status: legacy) .. index:: single: omprog; $ActionOMProgBinary single: $ActionOMProgBinary See also -------- See also :doc:`../../configuration/modules/omprog`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmfields-jsonroot.rst0000644000000000000000000000013115071746523025115 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.889608086 29 ctime=1764935921.98755827 rsyslog-8.2512.0/doc/source/reference/parameters/mmfields-jsonroot.rst0000664000175000017500000000156015071746523024564 0ustar00rgerrger.. _param-mmfields-jsonroot: .. _mmfields.parameter.input.jsonroot: jsonroot ======== .. index:: single: mmfields; jsonroot single: jsonroot .. summary-start Sets the JSON path that receives the extracted fields. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmfields`. :Name: jsonroot :Scope: input :Type: string :Default: ``!`` :Required?: no :Introduced: 7.5.1 Description ----------- This parameter specifies into which JSON path the extracted fields shall be written. The default is to use the JSON root object itself. Input usage ----------- .. _param-mmfields-input-jsonroot-usage: .. _mmfields.parameter.input.jsonroot-usage: .. code-block:: rsyslog module(load="mmfields") action(type="mmfields" jsonRoot="!mmfields") See also -------- This parameter is part of the :doc:`../../configuration/modules/mmfields` module. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-notifyonconnectionclose.rst0000644000000000000000000000013215062756615027713 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.476534023 30 ctime=1764935921.621552666 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-notifyonconnectionclose.rst0000664000175000017500000000247015062756615027362 0ustar00rgerrger.. _param-imptcp-notifyonconnectionclose: .. _imptcp.parameter.input.notifyonconnectionclose: NotifyOnConnectionClose ======================= .. index:: single: imptcp; NotifyOnConnectionClose single: NotifyOnConnectionClose .. summary-start Emits a message when a remote peer closes the connection. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: NotifyOnConnectionClose :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Instructs imptcp to emit a message if a remote peer closes the connection. Input usage ----------- .. _param-imptcp-input-notifyonconnectionclose: .. _imptcp.parameter.input.notifyonconnectionclose-usage: .. code-block:: rsyslog input(type="imptcp" notifyOnConnectionClose="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpservernotifyonconnectionclose: - $InputPTCPServerNotifyOnConnectionClose — maps to NotifyOnConnectionClose (status: legacy) .. index:: single: imptcp; $InputPTCPServerNotifyOnConnectionClose single: $InputPTCPServerNotifyOnConnectionClose See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-serverport.rst0000644000000000000000000000013215114522477025165 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.481642808 30 ctime=1764935922.418564868 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-serverport.rst0000664000175000017500000000140215114522477024626 0ustar00rgerrger.. _param-omhttp-serverport: .. _omhttp.parameter.input.serverport: serverport ========== .. index:: single: omhttp; serverport single: serverport .. summary-start Specifies the TCP port that omhttp uses when connecting to the configured HTTP server. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: serverport :Scope: input :Type: integer :Default: input=443 :Required?: no :Introduced: Not specified Description ----------- The port you want to connect to. Input usage ----------- .. _omhttp.parameter.input.serverport-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" serverPort="8443" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-searchtype.rst0000644000000000000000000000013215065245277026761 xustar0030 mtime=1758808767.291657809 30 atime=1764928599.533658431 30 ctime=1764935922.229561975 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-searchtype.rst0000664000175000017500000000160615065245277026430 0ustar00rgerrger.. _param-omelasticsearch-searchtype: .. _omelasticsearch.parameter.module.searchtype: searchType ========== .. index:: single: omelasticsearch; searchType single: searchType .. summary-start Elasticsearch type to use; empty string omits the type. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: searchType :Scope: action :Type: word :Default: action=events :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Specifies the document type. Set to an empty string to omit the type which is required for Elasticsearch 7 and later. Action usage ------------ .. _param-omelasticsearch-action-searchtype: .. _omelasticsearch.parameter.action.searchtype: .. code-block:: rsyslog action(type="omelasticsearch" searchType="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-maxsessions.rst0000644000000000000000000000013215062756615025314 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.312528983 30 ctime=1764935921.614552559 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-maxsessions.rst0000664000175000017500000000230015062756615024753 0ustar00rgerrger.. _param-imptcp-maxsessions: .. _imptcp.parameter.module.maxsessions: .. _imptcp.parameter.input.maxsessions: MaxSessions =========== .. index:: single: imptcp; MaxSessions single: MaxSessions .. summary-start Limits the number of open sessions. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: MaxSessions :Scope: module, input :Type: integer :Default: module=0; input=0 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Maximum number of open sessions allowed. When used as a module parameter this value becomes the default inherited by each ``input()`` instance but is not a global maximum. When set inside an input, it applies to that listener. A setting of zero or less than zero means no limit. Module usage ------------ .. _param-imptcp-module-maxsessions: .. _imptcp.parameter.module.maxsessions-usage: .. code-block:: rsyslog module(load="imptcp" maxSessions="...") Input usage ----------- .. _param-imptcp-input-maxsessions: .. _imptcp.parameter.input.maxsessions-usage: .. code-block:: rsyslog input(type="imptcp" maxSessions="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omazureeventhubs-template.rst0000644000000000000000000000013215114522477026660 xustar0030 mtime=1764926783.030631735 30 atime=1764926783.468642489 30 ctime=1764935922.122560337 rsyslog-8.2512.0/doc/source/reference/parameters/omazureeventhubs-template.rst0000664000175000017500000000357615114522477026337 0ustar00rgerrger.. _param-omazureeventhubs-template: .. _omazureeventhubs.parameter.input.template: template ======== .. index:: single: omazureeventhubs; template single: template .. summary-start Selects the rsyslog template that formats messages sent to Event Hubs. .. summary-end This parameter applies to :doc:`../../configuration/modules/omazureeventhubs`. :Name: template :Scope: input :Type: word :Default: input=RSYSLOG_FileFormat :Required?: no :Introduced: v8.2304 Description ----------- Specifies the template used to format and structure the log messages that will be sent from rsyslog to Microsoft Azure Event Hubs. The message template can include rsyslog variables, such as the timestamp, hostname, or process name, and it can use rsyslog macros, such as ``$rawmsg`` or ``$json``, to control the formatting of log data. For a message template sample with valid JSON output see the sample below: .. code-block:: rsyslog template(name="generic" type="list" option.jsonf="on") { property(outname="timestamp" name="timereported" dateFormat="rfc3339" format="jsonf") constant(value='"source": "EventHubMessage", ') # Note trailing comma and space for JSON concatenation property(outname="host" name="hostname" format="jsonf") property(outname="severity" name="syslogseverity" caseConversion="upper" format="jsonf" datatype="number") property(outname="facility" name="syslogfacility" format="jsonf" datatype="number") property(outname="appname" name="syslogtag" format="jsonf") property(outname="message" name="msg" format="jsonf" ) property(outname="etlsource" name="$myhostname" format="jsonf") } Input usage ----------- .. _omazureeventhubs.parameter.input.template-usage: .. code-block:: rsyslog action(type="omazureeventhubs" template="generic" ...) See also -------- See also :doc:`../../configuration/modules/omazureeventhubs`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-file.rst0000644000000000000000000000013215062756615023636 xustar0030 mtime=1758190989.207641205 30 atime=1764928600.064674677 30 ctime=1764935922.297563016 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-file.rst0000664000175000017500000000223015062756615023277 0ustar00rgerrger.. _param-omfile-file: .. _omfile.parameter.module.file: File ==== .. index:: single: omfile; File single: File .. summary-start This creates a static file output, always writing into the same file. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: File :Scope: action :Type: string :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This creates a static file output, always writing into the same file. If the file already exists, new data is appended to it. Existing data is not truncated. If the file does not already exist, it is created. Files are kept open as long as rsyslogd is active. This conflicts with external log file rotation. In order to close a file after rotation, send rsyslogd a HUP signal after the file has been rotated away. Either file or dynaFile can be used, but not both. If both are given, dynaFile will be used. Action usage ------------ .. _param-omfile-action-file: .. _omfile.parameter.action.file: .. code-block:: rsyslog action(type="omfile" File="...") See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-unlink.rst0000644000000000000000000000013215062756615024240 xustar0030 mtime=1758190989.191640978 30 atime=1764928595.408531933 30 ctime=1764935921.646553049 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-unlink.rst0000664000175000017500000000144615062756615023711 0ustar00rgerrger.. _param-imptcp-unlink: .. _imptcp.parameter.input.unlink: Unlink ====== .. index:: single: imptcp; Unlink single: Unlink .. summary-start Unlinks a Unix-domain socket before listening and after closing. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Unlink :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If a unix domain socket is being used this controls whether or not the socket is unlinked before listening and after closing. Input usage ----------- .. _param-imptcp-input-unlink: .. _imptcp.parameter.input.unlink-usage: .. code-block:: rsyslog input(type="imptcp" unlink="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omuxsock-networknamespace.rst0000644000000000000000000000013215114522477026655 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.487642955 30 ctime=1764935922.597567609 rsyslog-8.2512.0/doc/source/reference/parameters/omuxsock-networknamespace.rst0000664000175000017500000000443115114522477026323 0ustar00rgerrger.. _param-omuxsock-networknamespace: .. _omuxsock.parameter.module.networknamespace: networkNamespace ================ .. index:: single: omuxsock; networkNamespace single: networkNamespace .. summary-start This is the name of the network namespace. .. summary-end This parameter applies to :doc:`../../configuration/modules/omuxsock`. :Name: networkNamespace :Scope: module, action :Type: string :Default: module=none, action=none :Required?: no :Introduced: v8.2512 Description ----------- Sets a name for the ``networknamespace`` property. If no network namespace is set, the local (startup) network namespace is used by default. The namespace must be created (and interfaces appropriately configured) prior to starting rsyslogd. rsyslogd must be explicitly built with namespace support, otherwise an error will occur when the namespace is subsequently used against an input stream. The underlying operating system must also support the setns() system call, otherwise the input instance will be unable to bind within the given namespace. .. note:: The network namespace should exist as a named file under /var/run/netns/. In particular, the namespace must be created prior to starting rsyslogd. Rsyslogd must be explicitly built with namespace support, otherwise an error will occur when the namespace is subsequently used by an output action. The underlying operating system must also support the setns() system call, otherwise the output action will be unable to operate within the given namespace. Module usage ------------ .. _omuxsock.parameter.networknamespace-usage: If networkNamespace is set at the module level, then it becomes the default networkNamespace setting for all omuxsock actions. .. code-block:: rsyslog module(load="omuxsock" networkNamespace="management") Action usage ------------ .. _omuxsock.parameter.action.networknamespace: An empty string (``""``) can be used at the action level to override a module level ``networkNamespace`` setting and explicitly use the startup network namespace for that action. .. code-block:: rsyslog action(type="omuxsock" socketName="/tmp/example" networkNamespace="routing") action(type="omuxsock" socketName="rsyslogd.msg.handler" networkNamespace="") See also -------- See also :doc:`../../configuration/modules/omuxsock`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-maxbytes.rst0000644000000000000000000000013215062756615026446 xustar0030 mtime=1758190989.203641148 30 atime=1764928599.625661246 30 ctime=1764935922.206561623 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-maxbytes.rst0000664000175000017500000000154715062756615026121 0ustar00rgerrger.. _param-omelasticsearch-maxbytes: .. _omelasticsearch.parameter.module.maxbytes: maxbytes ======== .. index:: single: omelasticsearch; maxbytes single: maxbytes .. summary-start Maximum size of a bulk request body when bulkmode is enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: maxbytes :Scope: action :Type: word :Default: action=100m :Required?: no :Introduced: 8.23.0 Description ----------- Events are batched until this size or the dequeue batch size is reached. Set to match Elasticsearch `http.max_content_length`. Action usage ------------ .. _param-omelasticsearch-action-maxbytes: .. _omelasticsearch.parameter.action.maxbytes: .. code-block:: rsyslog action(type="omelasticsearch" maxbytes="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmanon-ipv4-replacechar.rst0000644000000000000000000000013215071746523026057 xustar0030 mtime=1760021843.803420434 30 atime=1764928597.327590852 30 ctime=1764935921.934557458 rsyslog-8.2512.0/doc/source/reference/parameters/mmanon-ipv4-replacechar.rst0000664000175000017500000000233115071746523025522 0ustar00rgerrger.. _param-mmanon-ipv4-replacechar: .. _mmanon.parameter.input.ipv4-replacechar: ipv4.replaceChar ================ .. index:: single: mmanon; ipv4.replaceChar single: ipv4.replaceChar .. summary-start Sets the character used to overwrite anonymized IPv4 octets in simple mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmanon`. :Name: ipv4.replaceChar :Scope: input :Type: character :Default: input=x :Required?: no :Introduced: 7.3.7 Description ----------- In simple mode, this sets the character that the to-be-anonymized part of the IP address is to be overwritten with. In any other mode the parameter is ignored if set. Input usage ----------- .. _mmanon.parameter.input.ipv4-replacechar-usage: .. code-block:: rsyslog module(load="mmanon") action(type="mmanon" ipv4.mode="simple" ipv4.replaceChar="*") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _mmanon.parameter.legacy.replacementchar: - replacementchar — maps to ipv4.replacechar (status: legacy) .. index:: single: mmanon; replacementchar single: replacementchar See also -------- :doc:`../../configuration/modules/mmanon` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-sortfiles.rst0000644000000000000000000000013215062756615024723 xustar0030 mtime=1758190989.185640893 30 atime=1764928593.915486012 30 ctime=1764935921.435549819 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-sortfiles.rst0000664000175000017500000000206215062756615024367 0ustar00rgerrger.. _param-imfile-sortfiles: .. _imfile.parameter.module.sortfiles: .. _imfile.parameter.sortfiles: sortFiles ========= .. index:: single: imfile; sortFiles single: sortFiles .. summary-start Processes files in sorted order when enabled. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: sortFiles :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.32.0 Description ----------- If this parameter is set to ``on``, the files will be processed in sorted order. Due to the inherent asynchronicity of the operations involved in tracking files, it is not possible to guarantee this sorted order, as it also depends on operation mode and OS timing. Module usage ------------ .. _param-imfile-module-sortfiles: .. _imfile.parameter.module.sortfiles-usage: .. code-block:: rsyslog module(load="imfile" sortFiles="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-allowunsignedcerts.rst0000644000000000000000000000013215071746523030056 xustar0030 mtime=1760021843.810420544 30 atime=1764928598.135615625 30 ctime=1764935922.017558729 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-allowunsignedcerts.rst0000664000175000017500000000176115071746523027527 0ustar00rgerrger.. _param-mmkubernetes-allowunsignedcerts: .. _mmkubernetes.parameter.action.allowunsignedcerts: allowunsignedcerts ================== .. index:: single: mmkubernetes; allowunsignedcerts single: allowunsignedcerts .. summary-start Disables TLS peer certificate verification. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: allowunsignedcerts :Scope: action :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If `"on"`, this will set the curl `CURLOPT_SSL_VERIFYPEER` option to `0`. You are strongly discouraged to set this to `"on"`. It is primarily useful only for debugging or testing. Action usage ------------ .. _param-mmkubernetes-action-allowunsignedcerts: .. _mmkubernetes.parameter.action.allowunsignedcerts-usage: .. code-block:: rsyslog action(type="mmkubernetes" allowUnsignedCerts="on") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imdtls-tls-tlscfgcmd.rst0000644000000000000000000000013215103346332025471 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.823483179 30 ctime=1764935921.370548823 rsyslog-8.2512.0/doc/source/reference/parameters/imdtls-tls-tlscfgcmd.rst0000664000175000017500000000315215103346332025136 0ustar00rgerrger.. _param-imdtls-tls-tlscfgcmd: .. _imdtls.parameter.input.tls-tlscfgcmd: tls.tlsCfgCmd ============= .. index:: single: imdtls; tls.tlsCfgCmd single: tls.tlsCfgCmd .. summary-start Passes additional OpenSSL configuration commands to fine-tune DTLS handling. .. summary-end This parameter applies to :doc:`../../configuration/modules/imdtls`. :Name: tls.tlsCfgCmd :Scope: input :Type: string :Default: none :Required?: no :Introduced: v8.2402.0 Description ----------- Used to pass additional OpenSSL configuration commands. This can be used to fine-tune the OpenSSL settings by passing configuration commands to the OpenSSL library. OpenSSL version 1.0.2 or higher is required for this feature. A list of possible commands and their valid values can be found in the `documentation `_. The setting can be single or multiline, each configuration command is separated by linefeed (``\n``). Command and value are separated by equal sign (``=``). Examples ~~~~~~~~ This will allow all protocols except for SSLv2 and SSLv3: .. code-block:: none tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3" This will allow all protocols except for SSLv2, SSLv3 and TLSv1 and will also set the minimum protocol to TLSv1.2: .. code-block:: none tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1\nMinProtocol=TLSv1.2" Input usage ----------- .. _imdtls.parameter.input.tls-tlscfgcmd-usage: .. code-block:: rsyslog module(load="imdtls") input(type="imdtls" tls.tlsCfgCmd="Protocol=ALL,-SSLv2,-SSLv3") See also -------- See also :doc:`../../configuration/modules/imdtls`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-skipverifyhost.rst0000644000000000000000000000013215071746523027233 xustar0030 mtime=1760021843.815420623 30 atime=1764928598.237618749 30 ctime=1764935922.047559188 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-skipverifyhost.rst0000664000175000017500000000172715071746523026706 0ustar00rgerrger.. _param-mmkubernetes-skipverifyhost: .. _mmkubernetes.parameter.action.skipverifyhost: skipverifyhost ============== .. index:: single: mmkubernetes; skipverifyhost single: skipverifyhost .. summary-start Skips verification of the Kubernetes API server hostname. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: skipverifyhost :Scope: action :Type: boolean :Default: off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- If `"on"`, this will set the curl `CURLOPT_SSL_VERIFYHOST` option to `0`. You are strongly discouraged to set this to `"on"`. It is primarily useful only for debugging or testing. Action usage ------------ .. _param-mmkubernetes-action-skipverifyhost: .. _mmkubernetes.parameter.action.skipverifyhost-usage: .. code-block:: rsyslog action(type="mmkubernetes" skipVerifyHost="on") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imudp-batchsize.rst0000644000000000000000000000013215062756615024536 xustar0030 mtime=1758190989.194641021 30 atime=1764928596.716572106 30 ctime=1764935921.794555315 rsyslog-8.2512.0/doc/source/reference/parameters/imudp-batchsize.rst0000664000175000017500000000266115062756615024207 0ustar00rgerrger.. _param-imudp-batchsize: .. _imudp.parameter.module.batchsize: BatchSize ========= .. index:: single: imudp; BatchSize single: BatchSize .. summary-start Maximum messages retrieved per ``recvmmsg()`` call when available. .. summary-end This parameter applies to :doc:`../../configuration/modules/imudp`. :Name: BatchSize :Scope: module :Type: integer :Default: module=32 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This parameter is only meaningful if the system supports ``recvmmsg()`` (newer Linux systems do this). The parameter is silently ignored if the system does not support it. If supported, it sets the maximum number of UDP messages that can be obtained with a single OS call. For systems with high UDP traffic, a relatively high batch size can reduce system overhead and improve performance. However, this parameter should not be overdone. For each buffer, max message size bytes are statically required. Also, a too-high number leads to reduced efficiency, as some structures need to be completely initialized before the OS call is done. We would suggest to not set it above a value of 128, except if experimental results show that this is useful. Module usage ------------ .. _param-imudp-module-batchsize: .. _imudp.parameter.module.batchsize-usage: .. code-block:: rsyslog module(load="imudp" BatchSize="...") See also -------- See also :doc:`../../configuration/modules/imudp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-server.rst0000644000000000000000000000013215114522477024260 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.480642783 30 ctime=1764935922.416564838 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-server.rst0000664000175000017500000000155115114522477023726 0ustar00rgerrger.. _param-omhttp-server: .. _omhttp.parameter.input.server: server ====== .. index:: single: omhttp; server single: server .. summary-start Defines the list of HTTP server hostnames or IP addresses that omhttp connects to. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: server :Scope: input :Type: array :Default: input=localhost :Required?: no :Introduced: Not specified Description ----------- The server address you want to connect to. Specify one or more entries to enable client-side load-balancing behavior provided by libcurl. Input usage ----------- .. _omhttp.parameter.input.server-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" server=["api1.example.net", "api2.example.net"] ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-interval.rst0000644000000000000000000000013215114522477025127 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.459642268 30 ctime=1764935921.553551625 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-interval.rst0000664000175000017500000000212315114522477024571 0ustar00rgerrger.. _param-impstats-interval: .. _impstats.parameter.module.interval: interval ======== .. index:: single: impstats; interval single: interval .. summary-start Configures how often, in seconds, impstats emits statistics messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: interval :Scope: module :Type: integer (seconds) :Default: module=300 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Sets the interval, in **seconds**, at which messages are generated. Please note that the actual interval may be a bit longer. We do not try to be precise and so the interval is actually a sleep period which is entered after generating all messages. So the actual interval is what is configured here plus the actual time required to generate messages. In general, the difference should not really matter. Module usage ------------ .. _impstats.parameter.module.interval-usage: .. code-block:: rsyslog module(load="impstats" interval="600") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/im3195-input3195listenport.rst0000644000000000000000000000013215103346332026163 xustar0030 mtime=1762512090.626175929 30 atime=1764928593.318467626 30 ctime=1764935921.301547767 rsyslog-8.2512.0/doc/source/reference/parameters/im3195-input3195listenport.rst0000664000175000017500000000211515103346332025626 0ustar00rgerrger.. _param-im3195-input3195listenport: .. _im3195.parameter.module.input3195listenport: Input3195ListenPort ------------------- .. index:: single: im3195; Input3195ListenPort single: im3195; $Input3195ListenPort .. summary-start The TCP port on which im3195 listens for RFC 3195 messages. The default is 601. .. summary-end This parameter applies to :doc:`../../configuration/modules/im3195`. .. note:: This is a legacy global directive. The im3195 module does not support the modern ``input()`` syntax. :Name: Input3195ListenPort :Scope: module :Type: integer :Default: 601 :Required?: no :Introduced: Not documented Description ~~~~~~~~~~~ The default port is 601, the IANA-assigned port for the BEEP protocol on which RFC 3195 is based. Since directive names are case-insensitive, the PascalCase form ``$Input3195ListenPort`` is recommended for readability. Module usage ~~~~~~~~~~~~ .. _im3195.parameter.module.input3195listenport-usage: .. code-block:: rsyslog $ModLoad im3195 $Input3195ListenPort 1601 See also ~~~~~~~~ :doc:`../../configuration/modules/im3195` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omsnmp-messageoid.rst0000644000000000000000000000013215071746523025072 xustar0030 mtime=1760021843.826420797 30 atime=1764928602.760757001 30 ctime=1764935922.573567241 rsyslog-8.2512.0/doc/source/reference/parameters/omsnmp-messageoid.rst0000664000175000017500000000301515071746523024535 0ustar00rgerrger.. _param-omsnmp-messageoid: .. _omsnmp.parameter.module.messageoid: MessageOID ========== .. index:: single: omsnmp; MessageOID single: MessageOID .. summary-start Specifies the OID for the message variable carrying the syslog text. .. summary-end This parameter applies to :doc:`../../configuration/modules/omsnmp`. :Name: MessageOID :Scope: module :Type: string :Default: module=1.3.6.1.4.1.19406.1.2.1 :Required?: no :Introduced: at least 7.3.0, possibly earlier Description ----------- This OID will be used as a variable, type "OCTET STRING". This variable will contain up to 255 characters of the original syslog message including syslog header. It is recommend to use the default OID. In order to decode this OID, you will need to have the ADISCON-MONITORWARE-MIB and ADISCON-MIB mibs installed on the receiver side. To download these custom mibs, see the description of :ref:`param-omsnmp-trapoid`. Module usage ------------ .. _param-omsnmp-module-messageoid: .. _omsnmp.parameter.module.messageoid-usage: .. code-block:: rsyslog action(type="omsnmp" messageOID="1.3.6.1.4.1.19406.1.2.1") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omsnmp.parameter.legacy.actionsnmpsyslogmessageoid: - $actionsnmpsyslogmessageoid — maps to MessageOID (status: legacy) .. index:: single: omsnmp; $actionsnmpsyslogmessageoid single: $actionsnmpsyslogmessageoid See also -------- See also :doc:`../../configuration/modules/omsnmp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-filegroupnum.rst0000644000000000000000000000013215062756615025454 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.383531165 30 ctime=1764935921.585552115 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-filegroupnum.rst0000664000175000017500000000170015062756615025116 0ustar00rgerrger.. _param-imptcp-filegroupnum: .. _imptcp.parameter.input.filegroupnum: FileGroupNum ============ .. index:: single: imptcp; FileGroupNum single: FileGroupNum .. summary-start Sets the group of the Unix-domain socket by numeric GID. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FileGroupNum :Scope: input :Type: integer :Default: input=system default :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the group for the domain socket. The parameter is a numerical ID, which is used regardless of whether the group actually exists. This can be useful if the group mapping is not available to rsyslog during startup. Input usage ----------- .. _param-imptcp-input-filegroupnum: .. _imptcp.parameter.input.filegroupnum-usage: .. code-block:: rsyslog input(type="imptcp" fileGroupNum="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-compression-mode.rst0000644000000000000000000000013215062756615026223 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.544536113 30 ctime=1764935921.571551901 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-compression-mode.rst0000664000175000017500000000163415062756615025673 0ustar00rgerrger.. _param-imptcp-compression-mode: .. _imptcp.parameter.input.compression-mode: Compression.mode ================ .. index:: single: imptcp; Compression.mode single: Compression.mode .. summary-start Selects decompression mode matching compression used by omfwd. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Compression.mode :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This is the counterpart to the compression modes set in :doc:`omfwd <../../configuration/modules/omfwd>`. Please see its documentation for details. Input usage ----------- .. _param-imptcp-input-compression-mode: .. _imptcp.parameter.input.compression-mode-usage: .. code-block:: rsyslog input(type="imptcp" compression.mode="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-disablelfdelimiter.rst0000644000000000000000000000013215062756615026404 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.066552152 30 ctime=1764935921.707553983 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-disablelfdelimiter.rst0000664000175000017500000000406515062756615026055 0ustar00rgerrger.. _param-imtcp-disablelfdelimiter: .. _imtcp.parameter.module.disablelfdelimiter: .. _imtcp.parameter.input.disablelfdelimiter: DisableLFDelimiter ================== .. index:: single: imtcp; DisableLFDelimiter single: DisableLFDelimiter .. summary-start Disables LF as a frame delimiter to allow a custom delimiter. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: DisableLFDelimiter :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Industry-standard plain text tcp syslog uses the LF to delimit syslog frames. However, some users brought up the case that it may be useful to define a different delimiter and totally disable LF as a delimiter (the use case named were multi-line messages). This mode is non-standard and will probably come with a lot of problems. However, as there is need for it and it is relatively easy to support, we do so. Be sure to turn this setting to "on" only if you exactly know what you are doing. You may run into all sorts of troubles, so be prepared to wrangle with that! The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-disablelfdelimiter: .. _imtcp.parameter.module.disablelfdelimiter-usage: .. code-block:: rsyslog module(load="imtcp" disableLFDelimiter="on") Input usage ----------- .. _param-imtcp-input-disablelfdelimiter: .. _imtcp.parameter.input.disablelfdelimiter-usage: .. code-block:: rsyslog input(type="imtcp" port="514" disableLFDelimiter="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverdisablelfdelimiter: - $InputTCPServerDisableLFDelimiter — maps to DisableLFDelimiter (status: legacy) .. index:: single: imtcp; $InputTCPServerDisableLFDelimiter single: $InputTCPServerDisableLFDelimiter See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/ommail-server.rst0000644000000000000000000000013215114522477024223 xustar0030 mtime=1764926783.033631809 30 atime=1764926783.485642906 30 ctime=1764935922.513566323 rsyslog-8.2512.0/doc/source/reference/parameters/ommail-server.rst0000664000175000017500000000246315114522477023674 0ustar00rgerrger.. _param-ommail-server: .. _ommail.parameter.input.server: server ====== .. index:: single: ommail; server single: server .. summary-start Specifies the hostname or IP address of the SMTP server used by ommail actions. .. summary-end This parameter applies to :doc:`../../configuration/modules/ommail`. :Name: server :Scope: input :Type: word :Default: input=none :Required?: yes :Introduced: 8.5.0 Description ----------- Name or IP address of the SMTP server to be used. While a default of 127.0.0.1 (the local machine) exists for legacy configurations, this parameter is required and must be set explicitly in modern configurations. Input usage ------------ .. _ommail.parameter.input.server-usage: .. code-block:: rsyslog module(load="ommail") action( type="ommail" server="mail.example.net" port="25" mailFrom="rsyslog@example.net" mailTo="operator@example.net" ) Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _ommail.parameter.legacy.actionmailsmtpserver: - $ActionMailSMTPServer — maps to server (status: legacy) .. index:: single: ommail; $ActionMailSMTPServer single: $ActionMailSMTPServer See also -------- See also :doc:`../../configuration/modules/ommail`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-filecreatemode.rst0000644000000000000000000000013215062756615025710 xustar0030 mtime=1758190989.188640936 30 atime=1764928595.391531411 30 ctime=1764935921.581552054 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-filecreatemode.rst0000664000175000017500000000206715062756615025361 0ustar00rgerrger.. _param-imptcp-filecreatemode: .. _imptcp.parameter.input.filecreatemode: FileCreateMode ============== .. index:: single: imptcp; FileCreateMode single: FileCreateMode .. summary-start Sets access permissions for the Unix-domain socket. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: FileCreateMode :Scope: input :Type: octalNumber :Default: input=0644 :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Set the access permissions for the domain socket. The value given must always be a 4-digit octal number, with the initial digit being zero. Please note that the actual permission depend on rsyslogd's process umask. If in doubt, use "``$umask 0000``" right at the beginning of the configuration file to remove any restrictions. Input usage ----------- .. _param-imptcp-input-filecreatemode: .. _imptcp.parameter.input.filecreatemode-usage: .. code-block:: rsyslog input(type="imptcp" fileCreateMode="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/immark-markmessagetext.rst0000644000000000000000000000013215114522477026123 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.458642243 30 ctime=1764935921.536551365 rsyslog-8.2512.0/doc/source/reference/parameters/immark-markmessagetext.rst0000664000175000017500000000210115114522477025561 0ustar00rgerrger.. _param-immark-markmessagetext: .. _immark.parameter.module.markmessagetext: markMessageText ================ .. index:: single: immark; markMessageText single: markMessageText .. summary-start Overrides the text that immark injects for each mark message. .. summary-end This parameter applies to :doc:`../../configuration/modules/immark`. :Name: markMessageText :Scope: module :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: module="-- MARK --" :Required?: no :Introduced: 8.2012.0 Description ----------- Provide a custom string that immark uses when it emits the periodic mark message. If unset, immark falls back to the historical ``-- MARK --`` text. The string may include whitespace and other characters supported by :doc:`../../rainerscript/constant_strings`. Module usage ------------ .. _immark.parameter.module.markmessagetext-usage: .. code-block:: rsyslog module(load="immark" markMessageText="-- CUSTOM MARK --") See also -------- .. seealso:: * :ref:`param-immark-interval` * :doc:`../../configuration/modules/immark` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-filenamerules.rst0000644000000000000000000000013215071746523026775 xustar0030 mtime=1760021843.814420607 30 atime=1764928598.220618228 30 ctime=1764935922.042559112 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-filenamerules.rst0000664000175000017500000000237615071746523026451 0ustar00rgerrger.. _param-mmkubernetes-filenamerules: .. _mmkubernetes.parameter.action.filenamerules: filenamerules ============= .. index:: single: mmkubernetes; filenamerules single: filenamerules .. summary-start Defines lognorm rules to parse json-file log filenames for metadata. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: filenamerules :Scope: action :Type: word :Default: SEE BELOW :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- .. note:: This directive is not supported with liblognorm 2.0.2 and earlier. When processing json-file logs, these are the lognorm rules to use to match the filename and extract metadata. The default value is:: rule=:/var/log/containers/%pod_name:char-to:_%_%namespace_name:char-to:_%_%contai\ ner_name_and_id:char-to:.%.log .. note:: In the above rules, the slashes ``\`` ending each line indicate line wrapping - they are not part of the rule. Action usage ------------ .. _param-mmkubernetes-action-filenamerules: .. _mmkubernetes.parameter.action.filenamerules-usage: .. code-block:: rsyslog action(type="mmkubernetes" filenameRules="...") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-flowcontrol.rst0000644000000000000000000000013115062756615025307 xustar0029 mtime=1758190989.18964095 30 atime=1764928595.553536389 30 ctime=1764935921.592552222 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-flowcontrol.rst0000664000175000017500000000153715062756615024762 0ustar00rgerrger.. _param-imptcp-flowcontrol: .. _imptcp.parameter.input.flowcontrol: flowControl =========== .. index:: single: imptcp; flowControl single: flowControl .. summary-start Throttles the sender when the receiver queue is nearly full. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: flowControl :Scope: input :Type: boolean :Default: input=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Flow control is used to throttle the sender if the receiver queue is near-full preserving some space for input that can not be throttled. Input usage ----------- .. _param-imptcp-input-flowcontrol: .. _imptcp.parameter.input.flowcontrol-usage: .. code-block:: rsyslog input(type="imptcp" flowControl="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-log-syslog.rst0000644000000000000000000000013215114522477025402 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.460642292 30 ctime=1764935921.557551686 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-log-syslog.rst0000664000175000017500000000226715114522477025055 0ustar00rgerrger.. _param-impstats-log-syslog: .. _impstats.parameter.module.log-syslog: log.syslog ========== .. index:: single: impstats; log.syslog single: log.syslog .. summary-start Enables or disables sending statistics to the regular syslog stream. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: log.syslog :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- This is a boolean setting specifying if data should be sent to the usual syslog stream. This is useful if custom formatting or more elaborate processing is desired. However, output is placed under the same restrictions as regular syslog data, especially in regard to the queue position (stats data may sit for an extended period of time in queues if they are full). If set to ``off``, the :ref:`param-impstats-ruleset` parameter cannot be used, as syslog stream processing is required for rulesets. Module usage ------------ .. _impstats.parameter.module.log-syslog-usage: .. code-block:: rsyslog module(load="impstats" logSyslog="off") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-notifyonconnectionopen.rst0000644000000000000000000000013215062756615027547 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.484534269 30 ctime=1764935921.623552697 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-notifyonconnectionopen.rst0000664000175000017500000000167315062756615027222 0ustar00rgerrger.. _param-imptcp-notifyonconnectionopen: .. _imptcp.parameter.input.notifyonconnectionopen: NotifyOnConnectionOpen ====================== .. index:: single: imptcp; NotifyOnConnectionOpen single: NotifyOnConnectionOpen .. summary-start Emits a message when a remote peer opens a connection. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: NotifyOnConnectionOpen :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Instructs imptcp to emit a message if a remote peer opens a connection. Hostname of the remote peer is given in the message. Input usage ----------- .. _param-imptcp-input-notifyonconnectionopen: .. _imptcp.parameter.input.notifyonconnectionopen-usage: .. code-block:: rsyslog input(type="imptcp" notifyOnConnectionOpen="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omkafka-partitions-auto.rst0000644000000000000000000000013215062756615026217 xustar0030 mtime=1758190989.210641247 30 atime=1764928601.439716691 30 ctime=1764935922.468565634 rsyslog-8.2512.0/doc/source/reference/parameters/omkafka-partitions-auto.rst0000664000175000017500000000176115062756615025670 0ustar00rgerrger.. _param-omkafka-partitions-auto: .. _omkafka.parameter.module.partitions-auto: Partitions.Auto =============== .. index:: single: omkafka; Partitions.Auto single: Partitions.Auto .. summary-start Use librdkafka's automatic partitioning. .. summary-end This parameter applies to :doc:`../../configuration/modules/omkafka`. :Name: Partitions.Auto :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Librdkafka provides an automatic partitioning function that distributes messages into all partitions configured for a topic. Action usage ------------ .. _param-omkafka-action-partitions-auto: .. _omkafka.parameter.action.partitions-auto: .. code-block:: rsyslog action(type="omkafka" Partitions.Auto="on") Notes ----- - Originally documented as "binary"; uses boolean values. - Overrides other partitioning settings when enabled. See also -------- See also :doc:`../../configuration/modules/omkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-msgdiscardingerror.rst0000644000000000000000000000013215062756615026601 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.111492045 30 ctime=1764935921.412549467 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-msgdiscardingerror.rst0000664000175000017500000000217015062756615026245 0ustar00rgerrger.. _param-imfile-msgdiscardingerror: .. _imfile.parameter.input.msgdiscardingerror: .. _imfile.parameter.msgdiscardingerror: msgDiscardingError ================== .. index:: single: imfile; msgDiscardingError single: msgDiscardingError .. summary-start Controls whether an error is logged when a message is truncated. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: msgDiscardingError :Scope: input :Type: boolean :Default: on :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- By default an error message is emitted when a message is truncated. If ``msgDiscardingError`` is ``off``, no error is shown upon truncation. Input usage ----------- .. _param-imfile-input-msgdiscardingerror: .. _imfile.parameter.input.msgdiscardingerror-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" msgDiscardingError="on") Notes ----- - Legacy documentation used the term ``binary`` for the type. It is treated as boolean. See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-discardtruncatedmsg.rst0000644000000000000000000000013115062756615026771 xustar0030 mtime=1758190989.188640936 29 atime=1764928595.34953012 30 ctime=1764935921.576551977 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-discardtruncatedmsg.rst0000664000175000017500000000201015062756615026427 0ustar00rgerrger.. _param-imptcp-discardtruncatedmsg: .. _imptcp.parameter.input.discardtruncatedmsg: DiscardTruncatedMsg =================== .. index:: single: imptcp; DiscardTruncatedMsg single: DiscardTruncatedMsg .. summary-start Discards the remaining part of a message after truncation. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: DiscardTruncatedMsg :Scope: input :Type: boolean :Default: input=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- When a message is split because it is too long the second part is normally processed as the next message. This can cause problems. When this parameter is turned on the part of the message after the truncation will be discarded. Input usage ----------- .. _param-imptcp-input-discardtruncatedmsg: .. _imptcp.parameter.input.discardtruncatedmsg-usage: .. code-block:: rsyslog input(type="imptcp" discardTruncatedMsg="...") See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imkafka-broker.rst0000644000000000000000000000013115114522477024325 xustar0030 mtime=1764926783.026631637 29 atime=1764926783.45564217 30 ctime=1764935921.502550845 rsyslog-8.2512.0/doc/source/reference/parameters/imkafka-broker.rst0000664000175000017500000000154015114522477023772 0ustar00rgerrger.. _param-imkafka-broker: .. _imkafka.parameter.input.broker: broker ====== .. index:: single: imkafka; broker single: broker .. summary-start Selects the Kafka broker(s) imkafka connects to when consuming messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/imkafka`. :Name: broker :Scope: input :Type: array :Default: input=``localhost:9092`` :Required?: no :Introduced: 8.27.0 Description ----------- Specifies the broker or brokers to use. Provide a single Kafka address or a list of bootstrap servers for a cluster. Input usage ----------- .. _imkafka.parameter.input.broker-usage: .. code-block:: rsyslog module(load="imkafka") input(type="imkafka" topic="your-topic" broker=["localhost:9092", "localhost:9093"]) See also -------- See also :doc:`../../configuration/modules/imkafka`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-ruleset.rst0000644000000000000000000000013215062756615024243 xustar0030 mtime=1758190989.193641006 30 atime=1764928596.293559121 30 ctime=1764935921.755554718 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-ruleset.rst0000664000175000017500000000217615062756615023715 0ustar00rgerrger.. _param-imtcp-ruleset: .. _imtcp.parameter.input.ruleset: Ruleset ======= .. index:: single: imtcp; Ruleset single: Ruleset .. summary-start Binds the listener to a specific ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: Ruleset :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Binds the listener to a specific :doc:`ruleset <../../concepts/multi_ruleset>`. Input usage ----------- .. _param-imtcp-input-ruleset: .. _imtcp.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imtcp" port="514" ruleset="remote") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverbindruleset: - $InputTCPServerBindRuleset — maps to Ruleset (status: legacy) .. index:: single: imtcp; $InputTCPServerBindRuleset single: $InputTCPServerBindRuleset See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-prioritystring.rst0000644000000000000000000000013215114522477026637 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.465642415 30 ctime=1764935921.691553738 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-prioritystring.rst0000664000175000017500000000272515114522477026311 0ustar00rgerrger.. _param-imrelp-tls-prioritystring: .. _imrelp.parameter.input.tls-prioritystring: tls.priorityString ================== .. index:: single: imrelp; tls.priorityString single: tls.priorityString .. summary-start Passes a custom GnuTLS priority string to fine-tune cryptographic parameters. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.priorityString :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- This parameter allows passing the so-called "priority string" to GnuTLS. This string gives complete control over all crypto parameters, including compression settings. For this reason, when ``tls.priorityString`` is specified, the :ref:`param-imrelp-tls-compression` parameter has no effect and is ignored. Full information about how to construct a priority string can be found in the GnuTLS manual. At the time of writing, this information was contained in `section 6.10 of the GnuTLS manual `_. **Note: this is an expert parameter.** Do not use if you do not exactly know what you are doing. Input usage ----------- .. _param-imrelp-input-tls-prioritystring-usage: .. _imrelp.parameter.input.tls-prioritystring-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.priorityString="NONE:+COMP-DEFLATE") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-ruleset-input.rst0000644000000000000000000000013215114522477025547 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.463642366 30 ctime=1764935921.671553432 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-ruleset-input.rst0000664000175000017500000000151215114522477025212 0ustar00rgerrger.. _param-imrelp-ruleset-input: .. _imrelp.parameter.input.ruleset: ruleset ======= .. index:: single: imrelp; ruleset (input) single: ruleset (imrelp input) .. summary-start Overrides the module-wide ruleset binding for this specific RELP listener. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: ruleset :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- Binds the specified ruleset to this listener. This overrides the module-level ruleset parameter. Input usage ----------- .. _param-imrelp-input-ruleset-usage: .. _imrelp.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" ruleset="relpListenerRules") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omelasticsearch-uid.rst0000644000000000000000000000013115114522477025365 xustar0029 mtime=1764926783.03163176 30 atime=1764926784.234661289 30 ctime=1764935922.253562342 rsyslog-8.2512.0/doc/source/reference/parameters/omelasticsearch-uid.rst0000664000175000017500000000151615114522477025035 0ustar00rgerrger.. _param-omelasticsearch-uid: .. _omelasticsearch.parameter.module.uid: uid === .. index:: single: omelasticsearch; uid single: uid .. summary-start User name for basic HTTP authentication. .. summary-end This parameter applies to :doc:`../../configuration/modules/omelasticsearch`. :Name: uid :Scope: action :Type: word :Default: action=none :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Supplies the user name when Elasticsearch requires basic authentication. This parameter cannot be combined with :ref:`param-omelasticsearch-apikey`. Action usage ------------ .. _param-omelasticsearch-action-uid: .. _omelasticsearch.parameter.action.uid: .. code-block:: rsyslog action(type="omelasticsearch" uid="...") See also -------- See also :doc:`../../configuration/modules/omelasticsearch`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-max_scan_bytes.rst0000644000000000000000000000013115103346332026763 xustar0029 mtime=1762512090.62717594 30 atime=1764928597.949609925 30 ctime=1764935921.999558454 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-max_scan_bytes.rst0000664000175000017500000000263715103346332026440 0ustar00rgerrger.. _param-mmjsonparse-max_scan_bytes: .. _mmjsonparse.parameter.max_scan_bytes: max_scan_bytes ============== .. index:: single: mmjsonparse; max_scan_bytes single: max_scan_bytes single: scan limit .. summary-start Maximum number of bytes to scan when searching for JSON content in find-json mode. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: max_scan_bytes :Scope: action :Type: positive integer :Default: 65536 :Required?: no :Introduced: 8.2506.0 Description ----------- Sets the maximum number of bytes to scan when searching for JSON objects in find-json mode. This prevents performance issues with very large messages by limiting the amount of data that will be examined. When the scan limit is reached without finding a complete JSON object, the message is treated as non-JSON and processed through the fallback path (creating a simple JSON object with the original message as the "msg" field). This parameter is only effective when mode="find-json". Input usage ----------- .. _mmjsonparse.parameter.max_scan_bytes-usage: .. code-block:: rsyslog # Scan up to 32KB for JSON content action(type="mmjsonparse" mode="find-json" max_scan_bytes="32768") # Use default 64KB scan limit action(type="mmjsonparse" mode="find-json") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`.rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imrelp-tls-myprivkey.rst0000644000000000000000000000013215114522477025566 xustar0030 mtime=1764926783.029631711 30 atime=1764926783.464642391 30 ctime=1764935921.687553677 rsyslog-8.2512.0/doc/source/reference/parameters/imrelp-tls-myprivkey.rst0000664000175000017500000000153715114522477025240 0ustar00rgerrger.. _param-imrelp-tls-myprivkey: .. _imrelp.parameter.input.tls-myprivkey: tls.myPrivKey ============= .. index:: single: imrelp; tls.myPrivKey single: tls.myPrivKey .. summary-start References the private key file that matches the configured tls.myCert. .. summary-end This parameter applies to :doc:`../../configuration/modules/imrelp`. :Name: tls.myPrivKey :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: Not documented Description ----------- The machine private key for the configured :ref:`param-imrelp-tls-mycert`. Input usage ----------- .. _param-imrelp-input-tls-myprivkey-usage: .. _imrelp.parameter.input.tls-myprivkey-usage: .. code-block:: rsyslog input(type="imrelp" port="2514" tls="on" tls.myPrivKey="/etc/rsyslog/server.key") See also -------- See also :doc:`../../configuration/modules/imrelp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-dynafile-donotsuspend.rst0000644000000000000000000000013215062756615027235 xustar0030 mtime=1758190989.207641205 30 atime=1764928599.959671466 30 ctime=1764935922.288562878 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-dynafile-donotsuspend.rst0000664000175000017500000000213715062756615026704 0ustar00rgerrger.. _param-omfile-dynafile-donotsuspend: .. _omfile.parameter.module.dynafile-donotsuspend: dynafile.donotsuspend ===================== .. index:: single: omfile; dynafile.donotsuspend single: dynafile.donotsuspend .. summary-start This permits SUSPENDing dynafile actions. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: dynafile.donotsuspend :Scope: module :Type: boolean :Default: module=on :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- This permits SUSPENDing dynafile actions. Traditionally, SUSPEND mode was never entered for dynafiles as it would have blocked overall processing flow. Default is not to suspend (and thus block). Module usage ------------ .. _param-omfile-module-dynafile-donotsuspend: .. _omfile.parameter.module.dynafile-donotsuspend-usage: .. code-block:: rsyslog module(load="builtin:omfile" dynafile.donotsuspend="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omgssapi-gssmode.rst0000644000000000000000000000013115114522477024721 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.473642612 30 ctime=1764935922.340563674 rsyslog-8.2512.0/doc/source/reference/parameters/omgssapi-gssmode.rst0000664000175000017500000000264715114522477024377 0ustar00rgerrger.. _param-omgssapi-gssmode: .. _omgssapi.parameter.module.gssmode: GssMode ======= .. index:: single: omgssapi; GssMode single: GssMode .. summary-start Chooses whether omgssapi requests integrity-only or encrypted message protection for GSSAPI sessions. .. summary-end This parameter applies to :doc:`../../configuration/modules/omgssapi`. :Name: GssMode :Scope: module :Type: string :Default: encryption :Required?: no :Introduced: 1.21.2 Description ----------- Specifies the GSS-API protection level used by the client. The available modes are: - ``integrity`` — only authenticates clients and verifies message integrity. - ``encryption`` — provides the same guarantees as ``integrity`` and encrypts messages when both peers support it. Legacy configurations set this directive with statements such as ``$GssMode encryption``. Module usage ------------ .. _param-omgssapi-module-gssmode: .. _omgssapi.parameter.module.gssmode-usage: .. code-block:: rsyslog module(load="omgssapi" gssMode="encryption") action(type="omgssapi" target="receiver.mydomain.com") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omgssapi.parameter.legacy.gssmode: - $GssMode — maps to GssMode (status: legacy) .. index:: single: omgssapi; $GssMode single: $GssMode See also -------- See also :doc:`../../configuration/modules/omgssapi`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-expert-initialprompt.rst0000644000000000000000000000013115071746523027257 xustar0030 mtime=1760021843.799420371 30 atime=1764928597.243588276 29 ctime=1764935921.90855706 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-expert-initialprompt.rst0000664000175000017500000000211715071746523026725 0ustar00rgerrger.. _param-mmaitag-expert-initialprompt: .. _mmaitag.parameter.action.expert-initialprompt: expert.initialPrompt ===================== .. index:: single: mmaitag; expert.initialPrompt single: expert.initialPrompt .. summary-start Provides a custom prompt text used by the AI provider before classifying messages. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: expert.initialPrompt :Scope: action :Type: string :Default: Task: Classify the log message that follows. Output: Exactly one label from this list: NOISE, REGULAR, IMPORTANT, CRITICAL. Restrictions: No other text, explanations, formatting, or newline characters. :Required?: no :Introduced: 9.0.0 Description ----------- Optional custom prompt text. If unset, the default value is used. Action usage ------------- .. _param-mmaitag-action-expert-initialprompt: .. _mmaitag.parameter.action.expert-initialprompt-usage: .. code-block:: rsyslog action(type="mmaitag" expert.initialPrompt="Classify precisely") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imtcp-keepalive.rst0000644000000000000000000000013215062756615024525 xustar0030 mtime=1758190989.192640992 30 atime=1764928596.094553012 30 ctime=1764935921.723554228 rsyslog-8.2512.0/doc/source/reference/parameters/imtcp-keepalive.rst0000664000175000017500000000263715062756615024201 0ustar00rgerrger.. _param-imtcp-keepalive: .. _imtcp.parameter.module.keepalive: .. _imtcp.parameter.input.keepalive: KeepAlive ========= .. index:: single: imtcp; KeepAlive single: KeepAlive .. summary-start Enables TCP keep-alive packets on connections. .. summary-end This parameter applies to :doc:`../../configuration/modules/imtcp`. :Name: KeepAlive :Scope: module, input :Type: boolean :Default: module=off, input=module parameter :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Enable or disable keep-alive packets at the tcp socket layer. The default is to disable them. The same-named input parameter can override this module setting. Module usage ------------ .. _param-imtcp-module-keepalive: .. _imtcp.parameter.module.keepalive-usage: .. code-block:: rsyslog module(load="imtcp" keepAlive="on") Input usage ----------- .. _param-imtcp-input-keepalive: .. _imtcp.parameter.input.keepalive-usage: .. code-block:: rsyslog input(type="imtcp" port="514" keepAlive="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imtcp.parameter.legacy.inputtcpserverkeepalive: - $InputTCPServerKeepAlive — maps to KeepAlive (status: legacy) .. index:: single: imtcp; $InputTCPServerKeepAlive single: $InputTCPServerKeepAlive See also -------- See also :doc:`../../configuration/modules/imtcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imptcp-port.rst0000644000000000000000000000013215062756615023724 xustar0030 mtime=1758190989.190640964 30 atime=1764928595.332529598 30 ctime=1764935921.627552758 rsyslog-8.2512.0/doc/source/reference/parameters/imptcp-port.rst0000664000175000017500000000201515062756615023366 0ustar00rgerrger.. _param-imptcp-port: .. _imptcp.parameter.input.port: Port ==== .. index:: single: imptcp; Port single: Port .. summary-start Selects the TCP port on which to listen. .. summary-end This parameter applies to :doc:`../../configuration/modules/imptcp`. :Name: Port :Scope: input :Type: string :Default: input=none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Select a port to listen on. It is an error to specify both ``path`` and ``port``. Input usage ----------- .. _param-imptcp-input-port: .. _imptcp.parameter.input.port-usage: .. code-block:: rsyslog input(type="imptcp" port="...") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imptcp.parameter.legacy.inputptcpserverrun: - $InputPTCPServerRun — maps to Port (status: legacy) .. index:: single: imptcp; $InputPTCPServerRun single: $InputPTCPServerRun See also -------- See also :doc:`../../configuration/modules/imptcp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-httpheadervalue.rst0000644000000000000000000000013115114522477026136 xustar0030 mtime=1764926783.032631784 29 atime=1764926783.47764271 30 ctime=1764935922.383564333 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-httpheadervalue.rst0000664000175000017500000000156615114522477025613 0ustar00rgerrger.. _param-omhttp-httpheadervalue: .. _omhttp.parameter.input.httpheadervalue: httpheadervalue =============== .. index:: single: omhttp; httpheadervalue single: httpheadervalue .. summary-start Provides the value for the single custom HTTP header defined by :ref:`param-omhttp-httpheaderkey`. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: httpheadervalue :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The header value for :ref:`param-omhttp-httpheaderkey`. Input usage ----------- .. _omhttp.parameter.input.httpheadervalue-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" httpHeaderKey="X-Insert-Key" httpHeaderValue="apikey" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmkubernetes-kubernetesurl.rst0000644000000000000000000000013215071746523027034 xustar0030 mtime=1760021843.814420607 30 atime=1764928598.228618474 30 ctime=1764935922.044559142 rsyslog-8.2512.0/doc/source/reference/parameters/mmkubernetes-kubernetesurl.rst0000664000175000017500000000162415071746523026503 0ustar00rgerrger.. _param-mmkubernetes-kubernetesurl: .. _mmkubernetes.parameter.action.kubernetesurl: KubernetesURL ============= .. index:: single: mmkubernetes; KubernetesURL single: KubernetesURL .. summary-start Specifies the URL of the Kubernetes API server. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmkubernetes`. :Name: KubernetesURL :Scope: action :Type: word :Default: https://kubernetes.default.svc.cluster.local:443 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- The URL of the Kubernetes API server. Example: `https://localhost:8443`. Action usage ------------ .. _param-mmkubernetes-action-kubernetesurl: .. _mmkubernetes.parameter.action.kubernetesurl-usage: .. code-block:: rsyslog action(type="mmkubernetes" kubernetesUrl="https://localhost:8443") See also -------- See also :doc:`../../configuration/modules/mmkubernetes`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/pmrfc3164-remove-msgfirstspace.rst0000644000000000000000000000013215062756615027236 xustar0030 mtime=1758190989.214641304 30 atime=1764928603.281772883 30 ctime=1764935922.632568145 rsyslog-8.2512.0/doc/source/reference/parameters/pmrfc3164-remove-msgfirstspace.rst0000664000175000017500000000220415062756615026700 0ustar00rgerrger.. _param-pmrfc3164-remove-msgfirstspace: .. _pmrfc3164.parameter.module.remove-msgfirstspace: .. _pmrfc3164.parameter.module.remove.msgFirstSpace: remove.msgFirstSpace ==================== .. index:: single: pmrfc3164; remove.msgFirstSpace single: remove.msgFirstSpace .. summary-start Remove the first space after the tag to improve RFC3164/RFC5424 interoperability. .. summary-end This parameter applies to :doc:`../../configuration/modules/pmrfc3164`. :Name: remove.msgFirstSpace :Scope: module :Type: boolean :Default: module=off :Required?: no :Introduced: 8.2508.0 Description ----------- RFC3164 places a space after the tag. When enabled, this option removes that first space so RFC3164 and RFC5424 messages can mix more easily. Module usage ------------ .. _param-pmrfc3164-module-remove-msgfirstspace: .. _pmrfc3164.parameter.module.remove-msgfirstspace-usage: .. code-block:: rsyslog parser(name="custom.rfc3164" type="pmrfc3164" remove.msgFirstSpace="on") Notes ----- - Legacy docs referred to this as a ``binary`` option, which maps to a boolean. See also -------- See also :doc:`../../configuration/modules/pmrfc3164`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-maxsubmitatonce.rst0000644000000000000000000000013215062756615026114 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.015489092 30 ctime=1764935921.408549405 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-maxsubmitatonce.rst0000664000175000017500000000206415062756615025562 0ustar00rgerrger.. _param-imfile-maxsubmitatonce: .. _imfile.parameter.input.maxsubmitatonce: .. _imfile.parameter.maxsubmitatonce: MaxSubmitAtOnce =============== .. index:: single: imfile; MaxSubmitAtOnce single: MaxSubmitAtOnce .. summary-start Sets the maximum batch size that imfile submits at once. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: MaxSubmitAtOnce :Scope: input :Type: integer :Default: 1024 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- An expert option that defines the maximum number of messages a single input batch may contain. The default of ``1024`` suits most applications. Modify only if familiar with rsyslog's batch processing semantics. Input usage ----------- .. _param-imfile-input-maxsubmitatonce: .. _imfile.parameter.input.maxsubmitatonce-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" MaxSubmitAtOnce="1024") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmaitag-apikey.rst0000644000000000000000000000013215071746523024342 xustar0030 mtime=1760021843.799420371 30 atime=1764928597.255588644 30 ctime=1764935921.904556999 rsyslog-8.2512.0/doc/source/reference/parameters/mmaitag-apikey.rst0000664000175000017500000000145615071746523024014 0ustar00rgerrger.. _param-mmaitag-apikey: .. _mmaitag.parameter.action.apikey: apiKey ====== .. index:: single: mmaitag; apiKey single: apiKey .. summary-start Sets the API key used to authenticate with the provider. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmaitag`. :Name: apiKey :Scope: action :Type: string :Default: none :Required?: no (either ``apiKey`` or :ref:`param-mmaitag-apikey_file` must be set) :Introduced: 9.0.0 Description ----------- API key for the provider. This parameter takes precedence over :ref:`param-mmaitag-apikey_file`. Action usage ------------- .. _param-mmaitag-action-apikey: .. _mmaitag.parameter.action.apikey-usage: .. code-block:: rsyslog action(type="mmaitag" apiKey="ABC") See also -------- * :doc:`../../configuration/modules/mmaitag` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmjsonparse-cookie.rst0000644000000000000000000000013215071746523025250 xustar0030 mtime=1760021843.808420513 30 atime=1764928597.942609711 30 ctime=1764935921.996558408 rsyslog-8.2512.0/doc/source/reference/parameters/mmjsonparse-cookie.rst0000664000175000017500000000224315071746523024715 0ustar00rgerrger.. _param-mmjsonparse-cookie: .. _mmjsonparse.parameter.input.cookie: cookie ====== .. index:: single: mmjsonparse; cookie single: cookie single: CEE cookie .. summary-start Defines the cookie string that must appear before the JSON content of a message. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmjsonparse`. :Name: cookie :Scope: input :Type: string :Default: @cee: :Required?: no :Introduced: 6.6.0 Description ----------- Permits setting the cookie that must be present in front of the JSON part of the message. Most importantly, this can be set to the empty string ("") to not require any cookie. In this case, leading spaces are permitted in front of the JSON. No characters, including whitespace, are permitted after the JSON object. If trailing characters must be handled, a tool like the :doc:`mmnormalize module <../../configuration/modules/mmnormalize>` can be used. Input usage ----------- .. _mmjsonparse.parameter.input.cookie-usage: .. code-block:: rsyslog action(type="mmjsonparse" cookie="") See also -------- See also the :doc:`main mmjsonparse module documentation <../../configuration/modules/mmjsonparse>`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imklog-permitnonkernelfacility.rst0000644000000000000000000000013215114522477027662 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.457642219 30 ctime=1764935921.527551227 rsyslog-8.2512.0/doc/source/reference/parameters/imklog-permitnonkernelfacility.rst0000664000175000017500000000307215114522477027330 0ustar00rgerrger.. _param-imklog-permitnonkernelfacility: .. _imklog.parameter.module.permitnonkernelfacility: PermitNonKernelFacility ======================= .. index:: single: imklog; PermitNonKernelFacility single: PermitNonKernelFacility .. summary-start Controls whether imklog submits kernel log messages that use non-kernel facilities. .. summary-end This parameter applies to :doc:`../../configuration/modules/imklog`. :Name: PermitNonKernelFacility :Scope: module :Type: boolean :Default: off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- At least under BSD the kernel log may contain entries with non-kernel facilities. This setting controls how those are handled. The default is "off", in which case these messages are ignored. Switch it to on to submit non-kernel messages to rsyslog processing. Notes ----- - Legacy documentation referred to the type as "binary"; it behaves as a boolean value. Module usage ------------ .. _param-imklog-module-permitnonkernelfacility: .. _imklog.parameter.module.permitnonkernelfacility-usage: .. code-block:: rsyslog module(load="imklog" permitNonKernelFacility="on") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imklog.parameter.legacy.klogpermitnonkernelfacility: - $KLogPermitNonKernelFacility — maps to PermitNonKernelFacility (status: legacy) .. index:: single: imklog; $KLogPermitNonKernelFacility single: $KLogPermitNonKernelFacility See also -------- :doc:`../../configuration/modules/imklog` rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-maxlinesperminute.rst0000644000000000000000000000013215062756615026462 xustar0030 mtime=1758190989.184640879 30 atime=1764928594.072490845 30 ctime=1764935921.405549359 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-maxlinesperminute.rst0000664000175000017500000000210615062756615026125 0ustar00rgerrger.. _param-imfile-maxlinesperminute: .. _imfile.parameter.input.maxlinesperminute: .. _imfile.parameter.maxlinesperminute: MaxLinesPerMinute ================= .. index:: single: imfile; MaxLinesPerMinute single: MaxLinesPerMinute .. summary-start Limits how many lines per minute are enqueued as messages; excess lines are discarded. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: MaxLinesPerMinute :Scope: input :Type: integer :Default: 0 :Required?: no :Introduced: at least 8.x, possibly earlier Description ----------- Instructs rsyslog to enqueue up to the specified maximum number of lines as messages per minute. Lines above this value are discarded. The default ``0`` means no lines are discarded. Input usage ----------- .. _param-imfile-input-maxlinesperminute: .. _imfile.parameter.input.maxlinesperminute-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" MaxLinesPerMinute="0") See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-statsname.rst0000644000000000000000000000013215114522477024751 xustar0030 mtime=1764926783.032631784 30 atime=1764926783.481642808 30 ctime=1764935922.423564945 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-statsname.rst0000664000175000017500000000174215114522477024421 0ustar00rgerrger.. _param-omhttp-statsname: .. _omhttp.parameter.input.statsname: statsname ========= .. index:: single: omhttp; statsname single: statsname .. summary-start Assigns a dedicated statistics counter origin name for this omhttp action. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: statsname :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The name assigned to statistics specific to this action instance. The supported set of statistics tracked for this action instance are **submitted**, **acked**, **failures**. See the `Statistic Counter` section of :doc:`../../configuration/modules/omhttp` for more details. Input usage ----------- .. _omhttp.parameter.input.statsname-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" statsName="omhttp_api" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omhttp-checkpath.rst0000644000000000000000000000013115114522477024703 xustar0029 mtime=1764926783.03163176 30 atime=1764926783.475642661 30 ctime=1764935922.363564026 rsyslog-8.2512.0/doc/source/reference/parameters/omhttp-checkpath.rst0000664000175000017500000000302115114522477024344 0ustar00rgerrger.. _param-omhttp-checkpath: .. _omhttp.parameter.input.checkpath: checkpath ========= .. index:: single: omhttp; checkpath single: checkpath .. summary-start Defines the health-check endpoint that omhttp polls to decide when to resume after suspension. .. summary-end This parameter applies to :doc:`../../configuration/modules/omhttp`. :Name: checkpath :Scope: input :Type: word :Default: input=none :Required?: no :Introduced: Not specified Description ----------- The health check path you want to use. Do not include the leading slash character. If the full path looks like ``localhost:5000/my/path``, ``checkpath`` should be ``my/path``. When this parameter is set, omhttp utilizes this path to determine if it is safe to resume (from suspend mode) and communicates this status back to rsyslog core. This parameter defaults to ``none``, which implies that health checks are not needed, and it is always safe to resume from suspend mode. **Important** - Note that it is highly recommended to set a valid health check path, as this allows omhttp to better determine whether it is safe to retry. See the `rsyslog action queue documentation for more info `_ regarding general rsyslog suspend and resume behavior. Input usage ----------- .. _omhttp.parameter.input.checkpath-usage: .. code-block:: rsyslog module(load="omhttp") action( type="omhttp" checkPath="health" ) See also -------- See also :doc:`../../configuration/modules/omhttp`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/impstats-format.rst0000644000000000000000000000013215114522477024573 xustar0030 mtime=1764926783.027631661 30 atime=1764926783.459642268 30 ctime=1764935921.550551579 rsyslog-8.2512.0/doc/source/reference/parameters/impstats-format.rst0000664000175000017500000000263215114522477024242 0ustar00rgerrger.. _param-impstats-format: .. _impstats.parameter.module.format: format ====== .. index:: single: impstats; format single: format .. summary-start Specifies which output format impstats uses for emitted statistics records. .. summary-end This parameter applies to :doc:`../../configuration/modules/impstats`. :Name: format :Scope: module :Type: word :Default: module=legacy :Required?: no :Introduced: 8.16.0 Description ----------- .. versionadded:: 8.16.0 Specifies the format of emitted stats messages. The default of ``legacy`` is compatible with pre v6-rsyslog. The other options provide support for structured formats (note that ``cee`` is actually "project lumberjack" logging). The ``json-elasticsearch`` format supports the broken ElasticSearch JSON implementation. ES 2.0 no longer supports valid JSON and disallows dots inside names. The ``json-elasticsearch`` format option replaces those dots by the bang ("!") character. So ``discarded.full`` becomes ``discarded!full``. Options: * ``json`` * ``json-elasticsearch`` * ``cee`` * ``legacy`` * ``prometheus`` .. note:: The ``prometheus`` option is available in builds that include the 2025-07-15 enhancement noted in the ``ChangeLog``. Module usage ------------ .. _impstats.parameter.module.format-usage: .. code-block:: rsyslog module(load="impstats" format="json") See also -------- See also :doc:`../../configuration/modules/impstats`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/imfile-ruleset.rst0000644000000000000000000000013115062756615024373 xustar0030 mtime=1758190989.185640893 29 atime=1764928594.03948983 30 ctime=1764935921.431549757 rsyslog-8.2512.0/doc/source/reference/parameters/imfile-ruleset.rst0000664000175000017500000000232115062756615024036 0ustar00rgerrger.. _param-imfile-ruleset: .. _imfile.parameter.input.ruleset: .. _imfile.parameter.ruleset: Ruleset ======= .. index:: single: imfile; Ruleset single: Ruleset .. summary-start Binds the input instance to a specific ruleset. .. summary-end This parameter applies to :doc:`../../configuration/modules/imfile`. :Name: Ruleset :Scope: input :Type: string (see :doc:`../../rainerscript/constant_strings`) :Default: none :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- Binds the listener to a specific :doc:`ruleset <../../concepts/multi_ruleset>`. Input usage ----------- .. _param-imfile-input-ruleset: .. _imfile.parameter.input.ruleset-usage: .. code-block:: rsyslog input(type="imfile" File="/var/log/example.log" Tag="example" Ruleset="myrules") Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _imfile.parameter.legacy.inputfilebindruleset: - ``$InputFileBindRuleset`` — maps to Ruleset (status: legacy) .. index:: single: imfile; $InputFileBindRuleset single: $InputFileBindRuleset See also -------- See also :doc:`../../configuration/modules/imfile`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/mmexternal-interface-input.rst0000644000000000000000000000013115071746523026711 xustar0030 mtime=1760021843.808420513 29 atime=1764928597.83560643 30 ctime=1764935921.983558208 rsyslog-8.2512.0/doc/source/reference/parameters/mmexternal-interface-input.rst0000664000175000017500000000327015071746523026360 0ustar00rgerrger.. _param-mmexternal-interface-input: .. _mmexternal.parameter.input.interface-input: interface.input =============== .. index:: single: mmexternal; interface.input single: interface.input .. summary-start Selects which message representation mmexternal passes to the external plugin. .. summary-end This parameter applies to :doc:`../../configuration/modules/mmexternal`. :Name: interface.input :Scope: input :Type: string :Default: msg :Required?: no :Introduced: 8.3.0 Description ----------- This parameter controls what part of the message is passed to the external program's standard input. It can be set to one of the following values: * ``"msg"`` (default): Passes the MSG part of the syslog message. * ``"rawmsg"``: Passes the complete, original syslog message as received by rsyslog, including headers. * ``"fulljson"``: Passes the complete rsyslog message object (with all properties) as a JSON object string. This corresponds to the ``jsonmesg`` dynamic message property. This setting **must** match the external plugin's expectations. Check the external plugin documentation for what needs to be used. .. note:: When processing multi-line messages, you **must** use ``"fulljson"``. This ensures that embedded line breaks are encoded properly and do not cause parsing errors in the external plugin interface. Input usage ----------- .. _param-mmexternal-input-interface-input: .. _mmexternal.parameter.input.interface-input-usage: .. code-block:: rsyslog module(load="mmexternal") action( type="mmexternal" binary="/path/to/mmexternal.py" interfaceInput="fulljson" ) See also -------- See also :doc:`../../configuration/modules/mmexternal`. rsyslog-8.2512.0/doc/source/reference/parameters/PaxHeaders/omfile-asyncwriting.rst0000644000000000000000000000013015062756615025436 xustar0030 mtime=1758190989.205641176 29 atime=1764928600.12267645 29 ctime=1764935922.26256248 rsyslog-8.2512.0/doc/source/reference/parameters/omfile-asyncwriting.rst0000664000175000017500000000275315062756615025113 0ustar00rgerrger.. _param-omfile-asyncwriting: .. _omfile.parameter.module.asyncwriting: asyncWriting ============ .. index:: single: omfile; asyncWriting single: asyncWriting .. summary-start If turned on, the files will be written in asynchronous mode via a separate thread. .. summary-end This parameter applies to :doc:`../../configuration/modules/omfile`. :Name: asyncWriting :Scope: action :Type: boolean :Default: action=off :Required?: no :Introduced: at least 5.x, possibly earlier Description ----------- If turned on, the files will be written in asynchronous mode via a separate thread. In that case, double buffers will be used so that one buffer can be filled while the other buffer is being written. Note that in order to enable FlushInterval, AsyncWriting must be set to "on". Otherwise, the flush interval will be ignored. Action usage ------------ .. _param-omfile-action-asyncwriting: .. _omfile.parameter.action.asyncwriting: .. code-block:: rsyslog action(type="omfile" asyncWriting="...") Notes ----- - Legacy documentation referred to the type as ``binary``; this maps to ``boolean``. Legacy names (for reference) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Historic names/directives for compatibility. Do not use in new configs. .. _omfile.parameter.legacy.omfileasyncwriting: - $OMFileASyncWriting — maps to asyncWriting (status: legacy) .. index:: single: omfile; $OMFileASyncWriting single: $OMFileASyncWriting See also -------- See also :doc:`../../configuration/modules/omfile`. rsyslog-8.2512.0/doc/source/reference/PaxHeaders/templates0000644000000000000000000000013215114544362020462 xustar0030 mtime=1764935922.752569982 30 atime=1764935930.378686728 30 ctime=1764935922.752569982 rsyslog-8.2512.0/doc/source/reference/templates/0000775000175000017500000000000015114544362020203 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-reserved-names.rst0000644000000000000000000000013215062756615026215 xustar0030 mtime=1758190989.215641318 30 atime=1764928604.241802124 30 ctime=1764935922.739569783 rsyslog-8.2512.0/doc/source/reference/templates/templates-reserved-names.rst0000664000175000017500000001510015062756615025656 0ustar00rgerrger.. _ref-templates-reserved-names: Reserved template names ======================= .. summary-start Names beginning with ``RSYSLOG_`` are reserved. The following templates are predefined and may be used without explicit definition. .. summary-end Template names starting with ``RSYSLOG_`` are reserved for rsyslog. Do not create custom templates with this prefix to avoid conflicts. The following predefined templates are available: **RSYSLOG_TraditionalFileFormat** – "old style" default log file format with low-precision timestamps. .. code-block:: none template(name="RSYSLOG_TraditionalFileFormat" type="string" string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n") **RSYSLOG_FileFormat** – modern logfile format similar to TraditionalFileFormat with high-precision timestamps and timezone information. .. code-block:: none template(name="RSYSLOG_FileFormat" type="list") { property(name="timereported" dateFormat="rfc3339") constant(value=" ") property(name="hostname") constant(value=" ") property(name="syslogtag") property(name="msg" spIfNo1stSp="on") property(name="msg" dropLastLf="on") constant(value="\n") } **RSYSLOG_TraditionalForwardFormat** – traditional forwarding format with low-precision timestamps. Useful when sending to older syslogd instances. .. code-block:: none template(name="RSYSLOG_TraditionalForwardFormat" type="string" string="<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%") **RSYSLOG_SysklogdFileFormat** – sysklogd compatible log file format. Use with options ``$SpaceLFOnReceive on``, ``$EscapeControlCharactersOnReceive off`` and ``$DropTrailingLFOnReception off`` for full compatibility. .. code-block:: none template(name="RSYSLOG_SysklogdFileFormat" type="string" string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%\n") **RSYSLOG_ForwardFormat** – high-precision forwarding format similar to the traditional one but with high-precision timestamps and timezone information. .. code-block:: none template(name="RSYSLOG_ForwardFormat" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%") **RSYSLOG_SyslogProtocol23Format** – format from IETF draft *ietf-syslog-protocol-23*, close to `RFC5424 `_. .. code-block:: none template(name="RSYSLOG_SyslogProtocol23Format" type="string" string="<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n") **RSYSLOG_DebugFormat** – used for troubleshooting property problems. Write to a log file only; do **not** use for production or forwarding. .. code-block:: none template(name="RSYSLOG_DebugFormat" type="list") { constant(value="Debug line with all properties:\nFROMHOST: '") property(name="fromhost") constant(value="', fromhost-ip: '") property(name="fromhost-ip") constant(value="', HOSTNAME: '") property(name="hostname") constant(value="', PRI: '") property(name="pri") constant(value=",\nsyslogtag '") property(name="syslogtag") constant(value="', programname: '") property(name="programname") constant(value="', APP-NAME: '") property(name="app-name") constant(value="', PROCID: '") property(name="procid") constant(value="', MSGID: '") property(name="msgid") constant(value="',\nTIMESTAMP: '") property(name="timereported") constant(value="', STRUCTURED-DATA: '") property(name="structured-data") constant(value="',\nmsg: '") property(name="msg") constant(value="'\nescaped msg: '") property(name="msg" controlCharacters="drop") constant(value="'\ninputname: ") property(name="inputname") constant(value=" rawmsg: '") property(name="rawmsg") constant(value="'\n$!:") property(name="$!") constant(value="\n$.:") property(name="$.") constant(value="\n$/:") property(name="$/") constant(value="\n\n") } **RSYSLOG_WallFmt** – information about host and time followed by the syslogtag and message. .. code-block:: none template(name="RSYSLOG_WallFmt" type="string" string="\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n%syslogtag%%msg%\n\r") **RSYSLOG_StdUsrMsgFmt** – syslogtag followed by the message. .. code-block:: none template(name="RSYSLOG_StdUsrMsgFmt" type="string" string=" %syslogtag%%msg%\n\r") **RSYSLOG_StdDBFmt** – insert command for table ``SystemEvents`` in MariaDB/MySQL. .. code-block:: none template(name="RSYSLOG_StdDBFmt" type="list") { constant(value="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag)") constant(value=" values ('") property(name="msg") constant(value="', ") property(name="syslogfacility") constant(value=", '") property(name="hostname") constant(value="', ") property(name="syslogpriority") constant(value=", '") property(name="timereported" dateFormat="date-mysql") constant(value="', '") property(name="timegenerated" dateFormat="date-mysql") constant(value="', ") property(name="iut") constant(value=", '") property(name="syslogtag") constant(value="')") } **RSYSLOG_StdPgSQLFmt** – insert command for table ``SystemEvents`` in pgsql. .. code-block:: none template(name="RSYSLOG_StdPgSQLFmt" type="string" string="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')") **RSYSLOG_spoofadr** – message containing only the sender's IP address. .. code-block:: none template(name="RSYSLOG_spoofadr" type="string" string="%fromhost-ip%") **RSYSLOG_StdJSONFmt** – JSON structure containing message properties. .. code-block:: none template(name="RSYSLOG_StdJSONFmt" type="string" string="{\"message\":\"%msg:::json%\",\"fromhost\":\"%HOSTNAME:::json%\",\"facility\":\"%syslogfacility-text%\",\"priority\":\"%syslogpriority-text%\",\"timereported\":\"%timereported:::date-rfc3339%\",\"timegenerated\":\"%timegenerated:::date-rfc3339%\"}") rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-legacy.rst0000644000000000000000000000013215062756615024541 xustar0030 mtime=1758190989.215641318 30 atime=1764928604.243802185 30 ctime=1764935922.734569706 rsyslog-8.2512.0/doc/source/reference/templates/templates-legacy.rst0000664000175000017500000000172415062756615024211 0ustar00rgerrger.. _ref-templates-legacy: Legacy ``$template`` statement ============================== .. summary-start Historic syntax supporting only string templates. Kept for compatibility with older configurations. .. summary-end Legacy format provides limited functionality but is still frequently encountered. Only string templates are supported with the syntax: .. code-block:: none $template myname, Here *myname* is the template name (similar to ``name="myname"`` in the modern format) and ```` is the same as the ``string`` parameter in modern templates. Example modern template: .. code-block:: none template(name="tpl3" type="string" string="%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" ) Equivalent legacy statement: .. code-block:: none $template tpl3,"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-statement-constant.rst0000644000000000000000000000013215071746523027125 xustar0030 mtime=1760021843.840421017 30 atime=1764928604.228801728 30 ctime=1764935922.741569814 rsyslog-8.2512.0/doc/source/reference/templates/templates-statement-constant.rst0000664000175000017500000000374215071746523026577 0ustar00rgerrger.. _ref-templates-statement-constant: Constant statement ================== .. summary-start Outputs literal text. Supports escape sequences and optional JSON field formatting when an outname and format are specified. .. summary-end This statement specifies constant text. It is primarily intended for text-based output so constant fragments, such as newlines, can be included. Example from the testbench: :: template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n") } The following escape sequences are recognized inside the constant text: - ``\\`` – single backslash - ``\n`` – LF - ``\ooo`` – three octal digits representing a character (``\101`` is ``"A"``). Exactly three digits must be given. - ``\xhh`` – two hexadecimal digits representing a character (``\x41`` is ``"A"``). Exactly two digits must be given. If an unsupported character follows a backslash, behavior is unpredictable. When creating structured outputs, constant text without an ``outname`` parameter is ignored. To include constant data in the name/value tree, provide ``outname`` as shown: .. code-block:: none template(name="outfmt" type="list") { property(name="$!usr!msgnum") constant(value="\n" outname="IWantThisInMyDB") } To generate a constant JSON field the ``format`` parameter can be used: .. code-block:: none template(name="outfmt" type="list" option.jsonf="on") { property(outname="message" name="msg" format="jsonf") constant(outname="@version" value="1" format="jsonf") } Here the constant statement generates ``"@version":"1"``. Both ``value`` and ``format`` must be specified. When you want dotted ``outname`` values to be emitted as nested objects, enable ``option.jsonftree="on"`` on the template instead of ``option.jsonf``. Parameters ---------- - ``value`` – constant value to emit - ``outname`` – output field name for structured outputs - ``format`` – empty or ``jsonf`` rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-examples.rst0000644000000000000000000000013215071746523025110 xustar0030 mtime=1760021843.840421017 30 atime=1764928604.238802033 30 ctime=1764935922.732569676 rsyslog-8.2512.0/doc/source/reference/templates/templates-examples.rst0000664000175000017500000001142715071746523024561 0ustar00rgerrger.. _ref-templates-examples: Template examples ================= .. summary-start Practical templates for files, forwarding, databases, JSON output, and dynamic file names. .. summary-end Standard template for writing to files -------------------------------------------------- .. code-block:: none template(name="FileFormat" type="list") { property(name="timestamp" dateFormat="rfc3339") constant(value=" ") property(name="hostname") constant(value=" ") property(name="syslogtag") property(name="msg" spIfNo1stSp="on") property(name="msg" dropLastLf="on") constant(value="\n") } Equivalent string template: .. code-block:: none template(name="FileFormat" type="string" string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n") Standard template for forwarding to a remote host (RFC3164) -------------------------------------------------------------- .. code-block:: none template(name="ForwardFormat" type="list") { constant(value="<") property(name="pri") constant(value=">") property(name="timestamp" dateFormat="rfc3339") constant(value=" ") property(name="hostname") constant(value=" ") property(name="syslogtag" position.from="1" position.to="32") property(name="msg" spIfNo1stSp="on") property(name="msg") } Equivalent string template: .. code-block:: none template(name="ForwardFormat" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%") Standard template for writing to the MariaDB/MySQL database -------------------------------------------------------------------------- .. code-block:: none template(name="StdSQLformat" type="list" option.sql="on") { constant(value="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag)") constant(value=" values ('") property(name="msg") constant(value="', ") property(name="syslogfacility") constant(value=", '") property(name="hostname") constant(value="', ") property(name="syslogpriority") constant(value=", '") property(name="timereported" dateFormat="mysql") constant(value="', '") property(name="timegenerated" dateFormat="mysql") constant(value="', ") property(name="iut") constant(value=", '") property(name="syslogtag") constant(value="')") } Equivalent string template: .. code-block:: none template(name="StdSQLformat" type="string" option.sql="on" string="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')") Generating JSON --------------- Useful for RESTful APIs such as ElasticSearch. .. code-block:: none template(name="outfmt" type="list" option.jsonf="on") { property(outname="@timestamp" name="timereported" dateFormat="rfc3339" format="jsonf") property(outname="host" name="hostname" format="jsonf") property(outname="severity" name="syslogseverity" caseConversion="upper" format="jsonf" dataType="number") property(outname="facility" name="syslogfacility" format="jsonf" dataType="number") property(outname="syslog-tag" name="syslogtag" format="jsonf") property(outname="source" name="app-name" format="jsonf" onEmpty="null") property(outname="message" name="msg" format="jsonf") } Produces output similar to: .. code-block:: none {"@timestamp":"2018-03-01T01:00:00+00:00", "host":"192.0.2.8", "severity":7, "facility":20, "syslog-tag":"tag", "source":"tag", "message":" msgnum:00000000:"} Pretty-printed: .. code-block:: none { "@timestamp": "2018-03-01T01:00:00+00:00", "host": "192.0.2.8", "severity": 7, "facility": 20, "syslog-tag": "tag", "source": "tag", "message": " msgnum:00000000:" } If ``onEmpty="null"`` is used and ``source`` is empty: .. code-block:: none {"@timestamp":"2018-03-01T01:00:00+00:00", "host":"192.0.2.8", "severity":7, "facility":20, "syslog-tag":"tag", "source":null, "message":" msgnum:00000000:"} .. note:: The output is not pretty-printed in actual use to avoid waste of resources. Creating dynamic file names for ``omfile`` --------------------------------------------------------- Templates can generate dynamic file names. For example, to split syslog messages by host name: .. code-block:: none template(name="DynFile" type="string" string="/var/log/system-%HOSTNAME%.log") rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-type-list.rst0000644000000000000000000000013115071746523025223 xustar0030 mtime=1760021843.841421033 30 atime=1764928604.215801333 29 ctime=1764935922.74656989 rsyslog-8.2512.0/doc/source/reference/templates/templates-type-list.rst0000664000175000017500000002057415071746523024700 0ustar00rgerrger.. _ref-templates-type-list: .. _templates.parameter.type-list: List template type ================== .. index:: single: template; type=list single: templates; list type .. meta:: :keywords: rsyslog, template type, list, constant statement, property statement, JSON, schema mapping, data pipeline, ECS, LEEF .. summary-start List templates build output from a sequence of constant and property statements. They are ideal for schema mapping when fields must be added one by one. .. summary-end :Name: ``type="list"`` :Scope: template :Type: list :Introduced: 5.9.6 Description -------------------------------------------------------------------------------- The *list template type* generates output from a sequence of **constant** and **property** statements enclosed in curly braces. Use it when you need to build structured output **field by field** or perform explicit schema mapping. - **Property statement** — emit values from rsyslog properties or variables into the output (see :ref:`ref-templates-statement-property`). - **Constant statement** — set fixed values or inject literal text into the output (see :ref:`ref-templates-statement-constant`). List templates work well for: - **Schema mapping**: assign each output field one by one. - **Structure-aware outputs** such as :ref:`ref-ommongodb` or :ref:`ref-omelasticsearch`. - **Text outputs** such as :ref:`ref-omfile` where you need constant text (e.g., line breaks). Compared to :ref:`ref-templates-type-subtree`, list templates are more verbose but provide maximum control. Prefer list templates when you **don’t yet have** a complete schema tree (e.g., while building an ECS mapping from scratch). Generic data pipeline -------------------------------------------------------------------------------- List templates are a key **data pipeline** step for mapping: .. mermaid:: flowchart TD A["Input
(imudp, imtcp, imkafka)"] B["Parser
(mmjsonparse, mmaudit)"] C["Template
list (mapping)"] D["Action
(omfile, omelasticsearch)"] A --> B --> C --> D Example: simple ECS mapping (jsonftree) -------------------------------------------------------------------------------- A minimal list template that emits selected ECS fields in JSON format. Use ``option.jsonftree="on"`` so dotted ``outname`` values become nested objects instead of flat strings: .. code-block:: none template(name="ecs_min" type="list" option.jsonftree="on") { property(outname="@timestamp" name="timereported" format="jsonf" dateFormat="rfc3339") property(outname="event.original" name="msg" format="jsonf") property(outname="host.hostname" name="hostname" format="jsonf") property(outname="log.level" name="syslogseverity-text" format="jsonf") } This produces valid JSON without hand-crafted quoting or braces. Example: fixing a field with a constant (jsonftree) -------------------------------------------------------------------------------- Sometimes you need to set a **fixed JSON field** (e.g., a version marker or a tag). Use a **constant** statement with `outname` and `format="jsonf"` so the encoder handles quoting consistently: .. code-block:: none template(name="ecs_fix" type="list" option.jsonftree="on") { property(outname="@timestamp" name="timereported" format="jsonf" dateFormat="rfc3339") property(outname="event.original" name="msg" format="jsonf") /* fixed field via constant, encoded as JSON */ constant(outname="@version" value="1" format="jsonf") } Example: Palo Alto firewall (LEEF → ECS) -------------------------------------------------------------------------------- A practical case is mapping Palo Alto firewall logs into ECS fields. The typical workflow looks like this: .. mermaid:: flowchart TD A["Input
(imtcp)"] B["Parser
(mmleefparse)"] C["Template
list (LEEF→ECS mapping)"] D["Action
(omelasticsearch)"] A --> B --> C --> D The list template performs field-by-field mapping using ``jsonftree`` to keep dotted field names properly nested: .. code-block:: none template(name="outfmt" type="list" option.jsonftree="on") { property(outname="@timestamp" name="timereported" format="jsonf" dateFormat="rfc3339") property(outname="event.created" name="$!leef!fields!ReceiveTime" format="jsonf") property(outname="observer.serial_number" name="$!leef!fields!SerialNumber" format="jsonf") property(outname="event.category" name="$!leef!fields!Type" format="jsonf") property(outname="event.action" name="$!leef!fields!Subtype" format="jsonf") property(outname="client.ip" name="$!leef!fields!src" format="jsonf") property(outname="source.ip" name="$!leef!fields!src" format="jsonf") property(outname="server.ip" name="$!leef!fields!dst" format="jsonf") property(outname="destination.ip" name="$!leef!fields!dst" format="jsonf") property(outname="client.user.name" name="$!leef!fields!usrName" format="jsonf") property(outname="source.user.name" name="$!leef!fields!usrName" format="jsonf") property(outname="server.user.name" name="$!leef!fields!DestinationUser" format="jsonf") property(outname="destination.user.name" name="$!leef!fields!DestinationUser" format="jsonf") property(outname="network.application" name="$!leef!fields!Application" format="jsonf") property(outname="client.port" name="$!leef!fields!srcPort" format="jsonf" dataType="number") property(outname="source.port" name="$!leef!fields!srcPort" format="jsonf" dataType="number") property(outname="destination.port" name="$!leef!fields!dstPort" format="jsonf" dataType="number") property(outname="server.port" name="$!leef!fields!dstPort" format="jsonf" dataType="number") property(outname="labels" name="$!leef!fields!Flags" format="jsonf") property(outname="network.transport" name="$!leef!fields!proto" format="jsonf") property(outname="event.outcome" name="$!leef!fields!action" format="jsonf") property(outname="network.bytes" name="$!leef!fields!totalBytes" format="jsonf" dataType="number") property(outname="client.bytes" name="$!leef!fields!srcBytes" format="jsonf" dataType="number") property(outname="source.bytes" name="$!leef!fields!srcBytes" format="jsonf" dataType="number") property(outname="server.bytes" name="$!leef!fields!dstBytes" format="jsonf" dataType="number") property(outname="destination.bytes" name="$!leef!fields!dstBytes" format="jsonf" dataType="number") property(outname="network.packets" name="$!leef!fields!totalPackets" format="jsonf" dataType="number") property(outname="event.start" name="$!leef!fields!StartTime" format="jsonf") property(outname="event.duration" name="$!leef!fields!ElapsedTime" format="jsonf" dataType="number") property(outname="client.packets" name="$!leef!fields!srcPackets" format="jsonf" dataType="number") property(outname="source.packets" name="$!leef!fields!srcPackets" format="jsonf" dataType="number") property(outname="server.packets" name="$!leef!fields!dstPackets" format="jsonf" dataType="number") property(outname="destination.packets" name="$!leef!fields!dstPackets" format="jsonf" dataType="number") property(outname="observer.hostname" name="$!leef!fields!DeviceName" format="jsonf") } Notes -------------------------------------------------------------------------------- - Prefer `property(... format="jsonf")` for dynamic fields; use **`constant(outname=…, format="jsonf")`** for small fixed values. - Best used when mapping output **field by field**. - For complete schema trees, prefer :ref:`ref-templates-type-subtree`. See also -------------------------------------------------------------------------------- - :ref:`ref-templates-type-subtree` - :ref:`ref-templates-statement-constant` - :ref:`ref-templates-statement-property` - :ref:`ref-mmleefparse` - :ref:`ref-ommongodb` - :ref:`ref-omelasticsearch` - :ref:`ref-omfile` - :ref:`ref-templates` rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-type-string.rst0000644000000000000000000000013215062756615025562 xustar0030 mtime=1758190989.215641318 30 atime=1764928604.221801516 30 ctime=1764935922.750569951 rsyslog-8.2512.0/doc/source/reference/templates/templates-type-string.rst0000664000175000017500000000160615062756615025231 0ustar00rgerrger.. _ref-templates-type-string: String template type ==================== .. summary-start Uses a single template string mixing constants and replacement variables. Best suited for textual output with simple manipulation needs. .. summary-end String templates closely resemble the legacy ``$template`` statement. They have a mandatory parameter ``string`` which holds the template string to be applied. The string mixes constant text and replacement variables processed by the :doc:`property replacer <../../configuration/property_replacer>`. Example: .. code-block:: none template(name="tpl3" type="string" string="%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n" ) The text between percent signs is interpreted by the property replacer, which reads message properties and applies options for formatting and processing. rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-options.rst0000644000000000000000000000013215071746523024765 xustar0030 mtime=1760021843.840421017 30 atime=1764928604.235801942 30 ctime=1764935922.737569752 rsyslog-8.2512.0/doc/source/reference/templates/templates-options.rst0000664000175000017500000000375015071746523024436 0ustar00rgerrger.. _ref-templates-options: Template options ================ .. summary-start Global modifiers applied to a template. Include SQL and JSON helpers and case sensitivity control. .. summary-end Template options influence the whole template and are specified as parameters of the ``template()`` object. They are distinct from property options which apply only to individual properties. Available options (case-insensitive): ``option.sql`` Format string for MariaDB/MySQL. Replaces single quotes (``'``) and backslashes (``\\``) by escaped counterparts (``\\'`` and ``\\\\``). MySQL must run with ``NO_BACKSLASH_ESCAPES`` turned off. ``option.stdsql`` Format string for standards-compliant SQL servers. Replaces single quotes by doubled quotes (``''``). Use this with MySQL when ``NO_BACKSLASH_ESCAPES`` is enabled. ``option.json`` Escape data suitable for JSON. ``option.jsonf`` Render the template as a JSON object, adding braces and commas between elements. ``option.jsonftree`` Render as JSON like ``option.jsonf`` but also interpret dotted ``outname`` segments (for example ``event.dataset.name``) as nested objects. When this option is not set, dotted names remain flat strings in the output to preserve legacy behaviour. ``option.caseSensitive`` Treat property names as case sensitive. Normally names are converted to lowercase at definition time. Enable this if JSON (``$!*``), local (``!.``), or global (``$!``) properties contain uppercase letters. Options ``option.sql``, ``option.stdsql``, ``option.json``, ``option.jsonf``, and ``option.jsonftree`` are mutually exclusive. Either ``option.sql`` or ``option.stdsql`` must be specified when writing into a database to guard against SQL injection. The database writer checks for the presence of one of these options and refuses to run otherwise. These options can also be useful when generating files intended for later import into a database. Do not enable them without need as they introduce extra processing overhead. rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-type-plugin.rst0000644000000000000000000000013115062756615025551 xustar0030 mtime=1758190989.215641318 30 atime=1764928604.223801576 29 ctime=1764935922.74856992 rsyslog-8.2512.0/doc/source/reference/templates/templates-type-plugin.rst0000664000175000017500000000125715062756615025223 0ustar00rgerrger.. _ref-templates-type-plugin: Plugin template type ==================== .. summary-start Delegates string generation to a plugin for maximum performance. Configuration selects the plugin by name. .. summary-end In plugin templates, the output string is generated by a plugin (also called a *string generator*). The format is fixed as coded in the plugin, which offers high performance at the cost of flexibility. The template parameter ``plugin`` specifies the generator name, and the plugin must be loaded before use. Configuration example: .. code-block:: none template(name="tpl4" type="plugin" plugin="mystrgen") Refer to the plugin's documentation for further details. rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-statement-property.rst0000644000000000000000000000013115062756615027162 xustar0030 mtime=1758190989.215641318 29 atime=1764928604.23080179 30 ctime=1764935922.743569844 rsyslog-8.2512.0/doc/source/reference/templates/templates-statement-property.rst0000664000175000017500000000705715062756615026640 0ustar00rgerrger.. _ref-templates-statement-property: Property statement ================== .. summary-start Extracts and optionally transforms message properties. Supports substring, case, regex, JSON formatting, and more. .. summary-end The property statement inserts property values. It can access any property and offers numerous options to select portions of a property or modify its text. Parameters ---------- - ``name`` – property to access - ``outname`` – output field name for structured outputs - ``dateFormat`` – date format for date-related properties. See :doc:`property replacer <../../configuration/property_replacer>` for available formats. The property replacer documentation currently lists options for string templates. The names here omit the ``date-`` prefix (e.g. ``year`` rather than ``date-year``). To build custom formats, combine multiple property statements: .. code-block:: none property(name="timereported" dateFormat="year") constant(value="-") property(name="timereported" dateFormat="month") constant(value="-") property(name="timereported" dateFormat="day") - ``date.inUTC`` – show date in UTC. Available since 8.18.0. - ``caseConversion`` – convert text case; ``lower`` or ``upper`` - ``controlCharacters`` – handle control characters: ``escape``, ``space``, or ``drop`` - ``securePath`` – create safe paths for dynafile templates; ``drop`` or ``replace`` - ``format`` – field format. Supported values: - ``csv`` – generate CSV data - ``json`` – JSON-encode content without field header - ``jsonf`` – complete JSON field - ``jsonr`` – avoid double escaping while keeping JSON safe - ``jsonfr`` – combination of ``jsonf`` and ``jsonr`` - ``position.to`` – end position. Since 8.2302.0, negative values strip characters from the end. For example, ``position.from="2" position.to="-1"`` removes the first and last character. This is handy when removing surrounding characters such as brackets: .. code-block:: none property(name="msg" position.from="2" position.to="-1") With an input of ``[abc]`` the result is ``abc``. This is especially useful when parsing ``STRUCTURED-DATA`` fields. - ``position.relativeToEnd`` – interpret positions relative to end of string (since 7.3.10) - ``fixedWidth`` – pad string with spaces up to ``position.to`` when shorter; ``on`` or ``off`` (default) (since 8.13.0) - ``compressSpace`` – compress multiple spaces to one, applied after substring extraction (since 8.18.0) - ``field.number`` – select this field match - ``field.delimiter`` – decimal value of delimiter character - ``regex.expression`` – regular expression - ``regex.type`` – ``ERE`` or ``BRE`` - ``regex.noMatchMode`` – action when there is no match - ``regex.match`` – match to use - ``regex.subMatch`` – submatch to use - ``dropLastLf`` – drop trailing LF - ``mandatory`` – if ``on``, always emit field for structured outputs even when empty - ``spIfNo1stSp`` – expert option for RFC3164 processing - ``dataType`` – for ``jsonf`` format only; sets JSON data type. Rsyslog properties are strings, but some consuming systems require numbers or booleans. ``dataType`` controls how the ``jsonf`` field is emitted. Supported values: - ``number`` – emit numeric value, using 0 if empty - ``string`` – emit as string (default) - ``auto`` – use number if integer, otherwise string - ``bool`` – emit ``true`` unless value is empty or ``0`` - ``onEmpty`` – for ``jsonf`` format only; handling of empty values: ``keep``, ``skip``, or ``null`` rsyslog-8.2512.0/doc/source/reference/templates/PaxHeaders/templates-type-subtree.rst0000644000000000000000000000013215071746523025722 xustar0030 mtime=1760021843.841421033 30 atime=1764928604.218801424 30 ctime=1764935922.752569982 rsyslog-8.2512.0/doc/source/reference/templates/templates-type-subtree.rst0000664000175000017500000000544015071746523025371 0ustar00rgerrger.. _ref-templates-type-subtree: .. _templates.parameter.type-subtree: Subtree template type ===================== .. index:: single: template; type=subtree single: templates; subtree type .. summary-start Builds output from a full JSON subtree (CEE). Best used when the schema has already been remapped and an appropriate variable tree exists. .. summary-end :Name: ``type="subtree"`` :Scope: template :Type: subtree :Introduced: 7.1.4 Description ----------- The *subtree template type* generates output from a complete (CEE/JSON) subtree. This is useful when working with **data pipelines** where schema mapping is done beforehand and a full variable tree (e.g. ``$!ecs``) is available. This method is required when an entire subtree must be placed at the root of the generated object. With other template types, only sub-containers can be produced. Constant text cannot be inserted inside subtree templates. Subtree templates are often used with structured outputs such as :ref:`ommongodb `, :ref:`omelasticsearch `, or with text-based outputs like :ref:`omfile `. They are particularly effective after message transformation with parsing modules such as :ref:`mmjsonparse `, :ref:`mmaudit `, or :ref:`mmleefparse `. Example: ECS mapping -------------------- A typical workflow is to normalize message content into an ECS-compatible subtree and then export it with a subtree template: .. code-block:: none set $!ecs!event!original = $msg; set $!ecs!host!hostname = $hostname; set $!ecs!log!level = $syslogseverity-text; set $!ecs!observer!type = "rsyslog"; template(name="ecs_tpl" type="subtree" subtree="$!ecs") Here the message is mapped into ECS fields under ``$!ecs``. The complete ECS subtree is then emitted as JSON by the template. Data pipeline usage ------------------- Subtree templates are a natural part of rsyslog data pipelines: .. mermaid:: flowchart TD A["Input
(imudp, imtcp, imkafka)"] B["Parser
(mmjsonparse, mmaudit, ...)"] C["Schema Tree
($!ecs)"] D["Template
type=subtree"] E["Action
(omfile, omkafka, ...)"] A --> B --> C --> D --> E Alternative mapping approach ---------------------------- If you do **not** yet have a remapped schema tree, consider using a :ref:`list template ` instead. List templates allow mapping fields one-by-one into structured output before exporting. Notes ----- * Use subtree templates when a full schema tree is already present. * Use list templates when building or remapping the schema incrementally. See also -------- * :ref:`ref-templates-type-list` * :ref:`ref-templates` * :ref:`ref-ommongodb` * :ref:`ref-omelasticsearch` * :ref:`ref-omfile` * :ref:`ref-omkafka` rsyslog-8.2512.0/doc/source/reference/PaxHeaders/properties0000644000000000000000000000013215114544362020660 xustar0030 mtime=1764935922.730569645 30 atime=1764935930.377686713 30 ctime=1764935922.730569645 rsyslog-8.2512.0/doc/source/reference/properties/0000775000175000017500000000000015114544362020401 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogpriority.rst0000644000000000000000000000013215071746523026240 xustar0030 mtime=1760021843.836420954 30 atime=1764928603.787788299 30 ctime=1764935922.685568956 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogpriority.rst0000664000175000017500000000164515071746523025712 0ustar00rgerrger.. _prop-message-syslogpriority: .. _properties.message.syslogpriority: syslogpriority ============== .. index:: single: properties; syslogpriority single: syslogpriority .. summary-start Provides the same numeric value as :ref:`prop-message-syslogseverity` for historical reasons. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogpriority :Category: Message Properties :Type: integer Description ----------- An alias for :ref:`prop-message-syslogseverity` - included for historical reasons (be careful: it still is the severity, not PRI!). The alias mirrors the same derived value even for inputs without a syslog header. Usage ----- .. _properties.message.syslogpriority-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogpriority") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogseverity-text.rst0000644000000000000000000000013215071746523027213 xustar0030 mtime=1760021843.836420954 30 atime=1764928603.782788147 30 ctime=1764935922.688569002 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogseverity-text.rst0000664000175000017500000000331315071746523026657 0ustar00rgerrger.. _prop-message-syslogseverity-text: .. _properties.message.syslogseverity-text: .. _properties.alias.syslogpriority-text: syslogseverity-text =================== .. index:: single: properties; syslogseverity-text single: syslogseverity-text .. summary-start Returns the textual syslog severity defined in RFC 5424 Table 2. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogseverity-text :Category: Message Properties :Type: string :Aliases: syslogpriority-text Description ----------- Returns the textual name of the syslog severity defined in RFC 3164 and RFC 5424 (Table 2, ``emerg`` through ``debug``). These strings describe how urgent the sending application considered the event. They map directly to the numeric values reported by :ref:`prop-message-syslogseverity`. When rsyslog processes a message that lacked a syslog header, this property reports the configured or inferred severity label instead of a name supplied by the sender. Usage ----- .. _properties.message.syslogseverity-text-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogseverity-text") } Notes ~~~~~ - Canonical severities: ``emerg``, ``alert``, ``crit``, ``err``, ``warning``, ``notice``, ``info``, ``debug``. - Filter by name with comparisons such as ``if $syslogseverity-text == 'warning'``. Keep in mind that emitters may use small spelling variations like ``warn``. - Severity remains independent from the facility; both combine into ``PRI`` (``PRI = facility * 8 + severity``). Aliases ~~~~~~~ - syslogpriority-text — alias for syslogseverity-text See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-iut.rst0000644000000000000000000000013115071746523023716 xustar0030 mtime=1760021843.832420891 30 atime=1764928603.763787568 29 ctime=1764935922.64856839 rsyslog-8.2512.0/doc/source/reference/properties/message-iut.rst0000664000175000017500000000136515071746523023370 0ustar00rgerrger.. _prop-message-iut: .. _properties.message.iut: iut === .. index:: single: properties; iut single: iut .. summary-start Holds the monitorware InfoUnitType value when present. .. summary-end This property belongs to the **Message Properties** group. :Name: iut :Category: Message Properties :Type: string Description ----------- The monitorware InfoUnitType - used when talking to a `MonitorWare `_ backend (also for `Adiscon LogAnalyzer `_). Usage ----- .. _properties.message.iut-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="iut") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-uuid.rst0000644000000000000000000000013115071746523024063 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.843790006 30 ctime=1764935922.702569217 rsyslog-8.2512.0/doc/source/reference/properties/message-uuid.rst0000664000175000017500000000271615071746523023536 0ustar00rgerrger.. _prop-message-uuid: .. _properties.message.uuid: uuid ==== .. index:: single: properties; uuid single: uuid .. summary-start Exposes a per-message UUID generated on first access when enabled. .. summary-end This property belongs to the **Message Properties** group. :Name: uuid :Category: Message Properties :Type: string Description ----------- .. note:: Only available if rsyslog is built with ``--enable-uuid``. A UUID for the message. It is not present by default, but will be created on first read of the uuid property. Thereafter, in the local rsyslog instance, it will always be the same value. This is also true if rsyslog is restarted and messages stayed in an on-disk queue. Note well: the UUID is **not** automatically transmitted to remote syslog servers when forwarding. If that is needed, a special template needs to be created that contains the uuid. Likewise, the receiver must parse that UUID from that template. The uuid property is most useful if you would like to track a single message across multiple local destination. An example is messages being written to a database as well as to local files. Usage ----- .. _properties.message.uuid-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="uuid") } Notes ~~~~~ The UUID is generated lazily on first access and remains local unless explicitly forwarded. See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-month.rst0000644000000000000000000000013215071746523025077 xustar0030 mtime=1760021843.839421001 30 atime=1764928603.882791194 30 ctime=1764935922.718569461 rsyslog-8.2512.0/doc/source/reference/properties/system-time-month.rst0000664000175000017500000000123115071746523024540 0ustar00rgerrger.. _prop-system-time-month: .. _properties.system-time.month: $month ====== .. index:: single: properties; $month single: $month .. summary-start Provides the current month as a two-digit number. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $month :Category: Time-Related System Properties :Type: integer Description ----------- The current month (2-digit). Usage ----- .. _properties.system-time.month-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$month") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-procid.rst0000644000000000000000000000013215071746523024376 xustar0030 mtime=1760021843.834420923 30 atime=1764928603.828789549 30 ctime=1764935922.662568604 rsyslog-8.2512.0/doc/source/reference/properties/message-procid.rst0000664000175000017500000000203115071746523024036 0ustar00rgerrger.. _prop-message-procid: .. _properties.message.procid: procid ====== .. index:: single: properties; procid single: procid .. summary-start Carries the PROCID header field defined in RFC 5424 Section 6.2.6. .. summary-end This property belongs to the **Message Properties** group. :Name: procid :Category: Message Properties :Type: string Description ----------- Carries the ``PROCID`` header field defined in RFC 5424 Section 6.2.6. The field has no fixed syntax; senders often use it for a process name, PID, transaction identifier, or other origin-specific token, and RFC 5424 allows the NILVALUE (``-``) when no value applies. When rsyslog ingests messages without a syslog header, this property holds the configured or inferred value for the source instead of a transmitted header field. Usage ----- .. _properties.message.procid-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="procid") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-jsonmesg.rst0000644000000000000000000000013115071746523024742 xustar0030 mtime=1760021843.832420891 30 atime=1764928603.848790158 29 ctime=1764935922.65056842 rsyslog-8.2512.0/doc/source/reference/properties/message-jsonmesg.rst0000664000175000017500000000274115071746523024413 0ustar00rgerrger.. _prop-message-jsonmesg: .. _properties.message.jsonmesg: jsonmesg ======== .. index:: single: properties; jsonmesg single: jsonmesg .. summary-start Provides the entire message object as a JSON representation. .. summary-end This property belongs to the **Message Properties** group. :Name: jsonmesg :Category: Message Properties :Type: JSON :Introduced: 8.3.0 Description ----------- The whole message object as JSON representation. Note that the JSON string will *not* include an LF and it will contain *all other message properties* specified here as respective JSON containers. It also includes all message variables in the "$!" subtree (this may be null if none are present). This property is primarily meant as an interface to other systems and tools that want access to the full property set (namely external plugins). Note that it contains the same data items potentially multiple times. For example, parts of the syslog tag will by contained in the rawmsg, syslogtag, and programname properties. As such, this property has some additional overhead. Thus, it is suggested to be used only when there is actual need for it. Usage ----- .. _properties.message.jsonmesg-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="jsonmesg") } Notes ~~~~~ Use this property when consumers require the complete structured message in a single JSON object. See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-inputname.rst0000644000000000000000000000013215071746523025116 xustar0030 mtime=1760021843.832420891 30 atime=1764928603.839789884 30 ctime=1764935922.646568359 rsyslog-8.2512.0/doc/source/reference/properties/message-inputname.rst0000664000175000017500000000257115071746523024567 0ustar00rgerrger.. _prop-message-inputname: .. _properties.message.inputname: inputname ========= .. index:: single: properties; inputname single: inputname .. summary-start Identifies the rsyslog input module instance that produced the message. .. summary-end This property belongs to the **Message Properties** group. :Name: inputname :Category: Message Properties :Type: string Description ----------- The name of the input module that generated the message (e.g. "imuxsock", "imudp"). Note that not all modules necessarily provide this property. If not provided, it is an empty string. Also note that the input module may provide any value of its liking. Most importantly, it is **not** necessarily the module input name. Internal sources can also provide inputnames. Currently, "rsyslogd" is defined as inputname for messages internally generated by rsyslogd, for example startup and shutdown and error messages. This property is considered useful when trying to filter messages based on where they originated - e.g. locally generated messages ("rsyslogd", "imuxsock", "imklog") should go to a different place than messages generated somewhere else. Usage ----- .. _properties.message.inputname-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="inputname") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-fromhost-ip.rst0000644000000000000000000000013215071746523025365 xustar0030 mtime=1760021843.831420875 30 atime=1764928603.732786624 30 ctime=1764935922.636568206 rsyslog-8.2512.0/doc/source/reference/properties/message-fromhost-ip.rst0000664000175000017500000000145415071746523025035 0ustar00rgerrger.. _prop-message-fromhost-ip: .. _properties.message.fromhost-ip: fromhost-ip =========== .. index:: single: properties; fromhost-ip single: fromhost-ip .. summary-start Provides the message source as an IP address just like :ref:`prop-message-fromhost`. .. summary-end This property belongs to the **Message Properties** group. :Name: fromhost-ip :Category: Message Properties :Type: string Description ----------- The same as :ref:`prop-message-fromhost`, but always as an IP address. Local inputs (like imklog) use 127.0.0.1 in this property. Usage ----- .. _properties.message.fromhost-ip-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="fromhost-ip") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-qhour.rst0000644000000000000000000000013215071746523025110 xustar0030 mtime=1760021843.839421001 30 atime=1764928603.922792413 30 ctime=1764935922.725569568 rsyslog-8.2512.0/doc/source/reference/properties/system-time-qhour.rst0000664000175000017500000000143415071746523024556 0ustar00rgerrger.. _prop-system-time-qhour: .. _properties.system-time.qhour: $qhour ====== .. index:: single: properties; $qhour single: $qhour .. summary-start Indicates the current quarter-hour within the hour. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $qhour :Category: Time-Related System Properties :Type: integer Description ----------- The current quarter hour we are in. Much like :ref:`prop-system-time-hhour`, but values range from 0 to 3 (for the four quarter hours that are in each hour). Usage ----- .. _properties.system-time.qhour-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$qhour") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-bom.rst0000644000000000000000000000013115071746523023572 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.854790341 30 ctime=1764935922.704569247 rsyslog-8.2512.0/doc/source/reference/properties/system-bom.rst0000664000175000017500000000134715071746523023244 0ustar00rgerrger.. _prop-system-bom: .. _properties.system.bom: $bom ==== .. index:: single: properties; $bom single: $bom .. summary-start Emits the UTF-8 byte-order mark for use in templates when required. .. summary-end This property belongs to the **System Properties** group. :Name: $bom :Category: System Properties :Type: string Description ----------- The UTF-8 encoded Unicode byte-order mask (BOM). This may be useful in templates for RFC5424 support, when the character set is known to be Unicode. Usage ----- .. _properties.system.bom-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$bom") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogfacility.rst0000644000000000000000000000013115071746523026162 xustar0030 mtime=1760021843.835420939 30 atime=1764928603.768787721 29 ctime=1764935922.68056888 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogfacility.rst0000664000175000017500000000335715071746523025637 0ustar00rgerrger.. _prop-message-syslogfacility: .. _properties.message.syslogfacility: syslogfacility ============== .. index:: single: properties; syslogfacility single: syslogfacility .. summary-start Contains the numeric syslog facility extracted from the message. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogfacility :Category: Message Properties :Type: integer Description ----------- Reports the numeric syslog facility defined in RFC 3164 and RFC 5424 (Table 1 of RFC 5424). The field is a 5-bit code describing the general origin of the message (for example 3 for ``daemon`` or 20 for ``local4``). Facility values combine with severity to form the PRI value (``PRI = facility * 8 + severity``), but otherwise remain independent. For inputs received without a syslog header, rsyslog supplies this value from configuration or other metadata. Usage ----- .. _properties.message.syslogfacility-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogfacility") } Notes ~~~~~ - Common facility codes: - **0** ``kern`` - **1** ``user`` - **2** ``mail`` - **3** ``daemon`` - **4** ``auth`` - **5** ``syslog`` - **6** ``lpr`` - **7** ``news`` - **8** ``uucp`` - **9** ``cron`` - **10** ``authpriv`` - **11** ``ftp`` - **12-15** reserved/OS-specific - **16-23** ``local0``..``local7`` - Applications assign facilities themselves, so naming can diverge by platform. The ``local0``..``local7`` range is intentionally left for site-defined uses. - Filter or route by facility, for example ``if $syslogfacility == 3`` or with legacy selectors such as ``mail.*``. See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-pri.rst0000644000000000000000000000013215071746523023710 xustar0030 mtime=1760021843.833420907 30 atime=1764928603.754787294 30 ctime=1764935922.660568573 rsyslog-8.2512.0/doc/source/reference/properties/message-pri.rst0000664000175000017500000000214115071746523023352 0ustar00rgerrger.. _prop-message-pri: .. _properties.message.pri: pri === .. index:: single: properties; pri single: pri .. summary-start Provides the undecoded PRI header value defined by RFC 5424 Section 6.2.1. .. summary-end This property belongs to the **Message Properties** group. :Name: pri :Category: Message Properties :Type: string Description ----------- Contains the raw ``PRI`` header value from RFC 5424 Section 6.2.1, which is written as ```` in front of the syslog message. The integer inside the angle brackets encodes facility and severity per ``PRIVAL = facility * 8 + severity``. Facilities 0 through 23 and severities 0 through 7 follow the tables in RFC 5424 (Tables 1 and 2). When rsyslog reads data without a syslog header, the ``PRI`` value is derived from input metadata or configuration so downstream templates can still compute facility and severity. Usage ----- .. _properties.message.pri-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="pri") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-now-unixtimestamp.rst0000644000000000000000000000013115071746523027461 xustar0030 mtime=1760021843.839421001 29 atime=1764928603.93779287 30 ctime=1764935922.721569507 rsyslog-8.2512.0/doc/source/reference/properties/system-time-now-unixtimestamp.rst0000664000175000017500000000332215071746523027126 0ustar00rgerrger.. _prop-system-time-now-unixtimestamp: .. _properties.system-time.now-unixtimestamp: $now-unixtimestamp ================== .. index:: single: properties; $now-unixtimestamp single: $now-unixtimestamp .. summary-start Exposes the current time as a monotonically increasing Unix timestamp. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $now-unixtimestamp :Category: Time-Related System Properties :Type: integer Description ----------- The current time as a unix timestamp (seconds since epoch). This actually is a monotonically increasing counter and as such can also be used for any other use cases that require such counters. Usage ----- .. _properties.system-time.now-unixtimestamp-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$now-unixtimestamp") } Additional example: .. code-block:: none # Get Unix timestamp of current message set $.tnow = $$now-unixtimestamp # Rate limit info to 5 every 60 seconds if ($!severity == 6 and $!facility == 17) then { if (($.tnow - $/trate) > 60) then { # 5 seconds window expired, allow more messages set $/trate = $.tnow; set $/ratecount = 0; } if ($/ratecount > 5) then { # discard message stop } else { set $/ratecount = $/ratecount + 1; } } Notes ~~~~~ .. note:: By definition, there is no "UTC equivalent" of the ``$now-unixtimestamp`` property. - Properties that include hyphens require the double dollar form (``$$``) when used in expressions so the parser does not treat the hyphen as subtraction. See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-hhour.rst0000644000000000000000000000013215071746523025077 xustar0030 mtime=1760021843.838420986 30 atime=1764928603.913792139 30 ctime=1764935922.711569354 rsyslog-8.2512.0/doc/source/reference/properties/system-time-hhour.rst0000664000175000017500000000140615071746523024544 0ustar00rgerrger.. _prop-system-time-hhour: .. _properties.system-time.hhour: $hhour ====== .. index:: single: properties; $hhour single: $hhour .. summary-start Indicates whether the current minute is in the first or second half of the hour. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $hhour :Category: Time-Related System Properties :Type: integer Description ----------- The current half hour we are in. From minute 0 to 29, this is always 0 while from 30 to 59 it is always 1. Usage ----- .. _properties.system-time.hhour-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$hhour") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-protocol-version.rst0000644000000000000000000000013215071746523026442 xustar0030 mtime=1760021843.834420923 30 atime=1764928603.813789092 30 ctime=1764935922.667568681 rsyslog-8.2512.0/doc/source/reference/properties/message-protocol-version.rst0000664000175000017500000000211515071746523026105 0ustar00rgerrger.. _prop-message-protocol-version: .. _properties.message.protocol-version: protocol-version ================ .. index:: single: properties; protocol-version single: protocol-version .. summary-start Carries the VERSION header field defined by RFC 5424 Section 6.2.2. .. summary-end This property belongs to the **Message Properties** group. :Name: protocol-version :Category: Message Properties :Type: string Description ----------- Contains the RFC 5424 Section 6.2.2 ``VERSION`` header field that signals which syslog message format the sender used. RFC 5424 assigns ``1`` to the standard defined in the specification and reserves future numbers for later revisions. When rsyslog consumes data without a native syslog header, this property reflects the configured or inferred version value for that input, commonly ``1``. Usage ----- .. _properties.message.protocol-version-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="protocol-version") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-minute.rst0000644000000000000000000000013215071746523025253 xustar0030 mtime=1760021843.838420986 30 atime=1764928603.930792656 30 ctime=1764935922.716569431 rsyslog-8.2512.0/doc/source/reference/properties/system-time-minute.rst0000664000175000017500000000124315071746523024717 0ustar00rgerrger.. _prop-system-time-minute: .. _properties.system-time.minute: $minute ======= .. index:: single: properties; $minute single: $minute .. summary-start Returns the current minute as a two-digit number. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $minute :Category: Time-Related System Properties :Type: integer Description ----------- The current minute (2-digit). Usage ----- .. _properties.system-time.minute-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$minute") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-source.rst0000644000000000000000000000013215071746523024416 xustar0030 mtime=1760021843.835420939 30 atime=1764928603.721786289 30 ctime=1764935922.673568772 rsyslog-8.2512.0/doc/source/reference/properties/message-source.rst0000664000175000017500000000122215071746523024057 0ustar00rgerrger.. _prop-message-source: .. _properties.message.source: source ====== .. index:: single: properties; source single: source .. summary-start Provides the same hostname value as :ref:`prop-message-hostname`. .. summary-end This property belongs to the **Message Properties** group. :Name: source :Category: Message Properties :Type: string Description ----------- Alias for :ref:`prop-message-hostname`. Usage ----- .. _properties.message.source-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="source") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-structured-data.rst0000644000000000000000000000013215071746523026231 xustar0030 mtime=1760021843.835420939 30 atime=1764928603.818789244 30 ctime=1764935922.676568818 rsyslog-8.2512.0/doc/source/reference/properties/message-structured-data.rst0000664000175000017500000000213715071746523025700 0ustar00rgerrger.. _prop-message-structured-data: .. _properties.message.structured-data: structured-data =============== .. index:: single: properties; structured-data single: structured-data .. summary-start Provides the STRUCTURED-DATA field defined in RFC 5424 Section 6.3. .. summary-end This property belongs to the **Message Properties** group. :Name: structured-data :Category: Message Properties :Type: string Description ----------- Contains the ``STRUCTURED-DATA`` portion of a syslog message as defined in RFC 5424 Section 6.3. The field holds zero or more SD-ELEMENT blocks with ASCII SD-IDs and UTF-8 parameter values. When no structured data is present, RFC 5424 requires the NILVALUE (``-``). For events ingested without a syslog header, rsyslog populates this property with structured data derived from configuration or input metadata, if any. Usage ----- .. _properties.message.structured-data-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="structured-data") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-myhostname.rst0000644000000000000000000000013215071746523025202 xustar0030 mtime=1760021843.838420986 30 atime=1764928603.856790402 30 ctime=1764935922.706569278 rsyslog-8.2512.0/doc/source/reference/properties/system-myhostname.rst0000664000175000017500000000134015071746523024644 0ustar00rgerrger.. _prop-system-myhostname: .. _properties.system.myhostname: $myhostname =========== .. index:: single: properties; $myhostname single: $myhostname .. summary-start Returns the local host name as rsyslog knows it. .. summary-end This property belongs to the **System Properties** group. :Name: $myhostname :Category: System Properties :Type: string Description ----------- The name of the current host as it knows itself (probably useful for filtering in a generic way). Usage ----- .. _properties.system.myhostname-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$myhostname") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-hour.rst0000644000000000000000000000013215071746523024727 xustar0030 mtime=1760021843.838420986 30 atime=1764928603.905791895 30 ctime=1764935922.713569385 rsyslog-8.2512.0/doc/source/reference/properties/system-time-hour.rst0000664000175000017500000000124415071746523024374 0ustar00rgerrger.. _prop-system-time-hour: .. _properties.system-time.hour: $hour ===== .. index:: single: properties; $hour single: $hour .. summary-start Returns the current hour in 24-hour format. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $hour :Category: Time-Related System Properties :Type: integer Description ----------- The current hour in military (24 hour) time (2-digit). Usage ----- .. _properties.system-time.hour-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$hour") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-rawmsg-after-pri.rst0000644000000000000000000000013215071746523026305 xustar0030 mtime=1760021843.834420923 30 atime=1764928603.712786014 30 ctime=1764935922.669568711 rsyslog-8.2512.0/doc/source/reference/properties/message-rawmsg-after-pri.rst0000664000175000017500000000256715071746523025763 0ustar00rgerrger.. _prop-message-rawmsg-after-pri: .. _properties.message.rawmsg-after-pri: rawmsg-after-pri ================ .. index:: single: properties; rawmsg-after-pri single: rawmsg-after-pri .. summary-start Contains the raw message content with the syslog PRI removed when present. .. summary-end This property belongs to the **Message Properties** group. :Name: rawmsg-after-pri :Category: Message Properties :Type: string Description ----------- Almost the same as :ref:`prop-message-rawmsg`, but the syslog PRI is removed. If no PRI was present, ``rawmsg-after-pri`` is identical to :ref:`prop-message-rawmsg`. Note that the syslog PRI is a header field that contains information on syslog facility and severity. It is enclosed in greater-than and less-than characters, e.g. ``<191>``. This field is often not written to log files, but usually needs to be present for the receiver to properly classify the message. There are some rare cases where one wants the raw message, but not the PRI. You can use this property to obtain that. In general, you should know that you need this format, otherwise stay away from the property. Usage ----- .. _properties.message.rawmsg-after-pri-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="rawmsg-after-pri") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogpriority-text.rst0000644000000000000000000000013215071746523027222 xustar0030 mtime=1760021843.836420954 30 atime=1764928603.794788513 30 ctime=1764935922.683568926 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogpriority-text.rst0000664000175000017500000000162115071746523026666 0ustar00rgerrger.. _prop-message-syslogpriority-text: .. _properties.message.syslogpriority-text: syslogpriority-text =================== .. index:: single: properties; syslogpriority-text single: syslogpriority-text .. summary-start Returns the same textual severity string as :ref:`prop-message-syslogseverity-text`. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogpriority-text :Category: Message Properties :Type: string Description ----------- An alias for :ref:`prop-message-syslogseverity-text`. The rendered string matches the derived severity name even when no syslog header was present on receipt. Usage ----- .. _properties.message.syslogpriority-text-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogpriority-text") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogtag.rst0000644000000000000000000000013115071746523025131 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.744786989 30 ctime=1764935922.692569063 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogtag.rst0000664000175000017500000000123115071746523024573 0ustar00rgerrger.. _prop-message-syslogtag: .. _properties.message.syslogtag: syslogtag ========= .. index:: single: properties; syslogtag single: syslogtag .. summary-start Returns the TAG field extracted from the syslog message header. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogtag :Category: Message Properties :Type: string Description ----------- TAG from the message. Usage ----- .. _properties.message.syslogtag-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogtag") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-rawmsg.rst0000644000000000000000000000013215071746523024416 xustar0030 mtime=1760021843.834420923 30 atime=1764928603.707785862 30 ctime=1764935922.671568742 rsyslog-8.2512.0/doc/source/reference/properties/message-rawmsg.rst0000664000175000017500000000153215071746523024063 0ustar00rgerrger.. _prop-message-rawmsg: .. _properties.message.rawmsg: rawmsg ====== .. index:: single: properties; rawmsg single: rawmsg .. summary-start Provides the received message exactly as rsyslog stored it. .. summary-end This property belongs to the **Message Properties** group. :Name: rawmsg :Category: Message Properties :Type: string Description ----------- The message "as is". Should be useful for debugging and also if a message should be forwarded totally unaltered. Please notice *EscapecontrolCharactersOnReceive* is enabled by default, so it may be different from what was received in the socket. Usage ----- .. _properties.message.rawmsg-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="rawmsg") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-hostname.rst0000644000000000000000000000013215071746523024734 xustar0030 mtime=1760021843.831420875 30 atime=1764928603.717786167 30 ctime=1764935922.644568328 rsyslog-8.2512.0/doc/source/reference/properties/message-hostname.rst0000664000175000017500000000136115071746523024401 0ustar00rgerrger.. _prop-message-hostname: .. _properties.message.hostname: .. _properties.alias.source: hostname ======== .. index:: single: properties; hostname single: hostname .. summary-start Captures the hostname transmitted within the syslog message. .. summary-end This property belongs to the **Message Properties** group. :Name: hostname :Category: Message Properties :Type: string :Aliases: source Description ----------- Hostname from the message. Usage ----- .. _properties.message.hostname-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="hostname") } Aliases ~~~~~~~ - source — alias for hostname See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-timegenerated.rst0000644000000000000000000000013115071746523025732 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.799788665 30 ctime=1764935922.694569094 rsyslog-8.2512.0/doc/source/reference/properties/message-timegenerated.rst0000664000175000017500000000254615071746523025406 0ustar00rgerrger.. _prop-message-timegenerated: .. _properties.message.timegenerated: timegenerated ============= .. index:: single: properties; timegenerated single: timegenerated .. summary-start Records when rsyslog received the message with high resolution. .. summary-end This property belongs to the **Message Properties** group. :Name: timegenerated :Category: Message Properties :Type: timestamp Description ----------- Timestamp captured when the operating system hands the message to rsyslog's reception buffer. The value reflects the precise moment rsyslog accepted the event, before any queueing or ruleset processing begins. If several messages are delivered in the same receive buffer (for example when TCP transports multiple entries together), they all carry the same ``timegenerated`` stamp because rsyslog accepted them at the same instant. The timestamp remains stable even if the message spends time in an in-memory or disk queue. As a result, ``timegenerated`` is usually newer than ``timereported`` (which comes from the sender) but still older than ``$now``, which is evaluated later during processing. Usage ----- .. _properties.message.timegenerated-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="timegenerated") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-programname.rst0000644000000000000000000000013215071746523025426 xustar0030 mtime=1760021843.834420923 30 atime=1764928603.749787142 30 ctime=1764935922.664568635 rsyslog-8.2512.0/doc/source/reference/properties/message-programname.rst0000664000175000017500000000303515071746523025073 0ustar00rgerrger.. _prop-message-programname: .. _properties.message.programname: programname =========== .. index:: single: properties; programname single: programname .. summary-start Extracts the static program name portion from the syslog tag. .. summary-end This property belongs to the **Message Properties** group. :Name: programname :Category: Message Properties :Type: string Description ----------- The "static" part of the tag, as defined by BSD syslogd. For example, when TAG is "named[12345]", programname is "named". Precisely, the programname is terminated by either (whichever occurs first): - end of tag - nonprintable character - ':' - '[' - '/' The above definition has been taken from the FreeBSD syslogd sources. Please note that some applications include slashes in the static part of the tag, e.g. "app/foo[1234]". In this case, programname is "app". If they store an absolute path name like in "/app/foo[1234]", programname will become empty (""). If you need to actually store slashes as part of the programname, you can use the global option: .. code-block:: rsyslog global(parser.permitSlashInProgramName="on") to permit this. Then, a syslogtag of "/app/foo[1234]" will result in programname being "/app/foo". Note: this option is available starting at rsyslogd version 8.25.0. Usage ----- .. _properties.message.programname-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="programname") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-now.rst0000644000000000000000000000013215071746523024555 xustar0030 mtime=1760021843.839421001 30 atime=1764928603.867790737 30 ctime=1764935922.723569538 rsyslog-8.2512.0/doc/source/reference/properties/system-time-now.rst0000664000175000017500000000211315071746523024216 0ustar00rgerrger.. _prop-system-time-now: .. _properties.system-time.now: $now ==== .. index:: single: properties; $now single: $now .. summary-start Yields the current local date stamp when the message is processed. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $now :Category: Time-Related System Properties :Type: timestamp Description ----------- Reports the local system date stamp (``YYYY-MM-DD``) at the moment rsyslog processes the message. The value is independent of the event payload and changes whenever the ruleset advances to the next message. ``$now`` is always a little newer than ``timegenerated`` because rsyslog only evaluates it during processing, after the event has left the input queue. When queues back up, the gap between the two can grow from fractions of a second to minutes or hours. Usage ----- .. _properties.system-time.now-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$now") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogseverity.rst0000644000000000000000000000013215071746523026231 xustar0030 mtime=1760021843.836420954 30 atime=1764928603.777787995 30 ctime=1764935922.690569033 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogseverity.rst0000664000175000017500000000353015071746523025676 0ustar00rgerrger.. _prop-message-syslogseverity: .. _properties.message.syslogseverity: .. _properties.alias.syslogpriority: syslogseverity ============== .. index:: single: properties; syslogseverity single: syslogseverity .. summary-start Provides the numeric syslog severity extracted from the message. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogseverity :Category: Message Properties :Type: integer :Aliases: syslogpriority Description ----------- Reports the numeric syslog severity defined in RFC 3164 and RFC 5424 (Table 2 of RFC 5424). The field is a 3-bit integer from 0 (``emerg``) to 7 (``debug``); smaller numbers indicate higher urgency. The sending application chooses this value, so real-world usage can vary and mappings are sometimes fuzzy. Severity combines with the facility code to form the PRI value (``PRI = facility * 8 + severity``). When rsyslog accepts messages without a syslog header, the severity comes from configured defaults or input metadata rather than a value that was transmitted on the wire. Usage ----- .. _properties.message.syslogseverity-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogseverity") } Notes ~~~~~ - Canonical severities: - **0** ``emerg`` - **1** ``alert`` - **2** ``crit`` - **3** ``err`` - **4** ``warning`` - **5** ``notice`` - **6** ``info`` - **7** ``debug`` - Filter by number or name; for example ``if $syslogseverity <= 3 then ...`` routes urgent messages (``emerg`` through ``err``). - The textual property :ref:`prop-message-syslogseverity-text` exposes the same information as words. Legacy selector syntax such as ``*.err`` works as well. Aliases ~~~~~~~ - syslogpriority — alias for syslogseverity See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-msgid.rst0000644000000000000000000000013215071746523024221 xustar0030 mtime=1760021843.832420891 30 atime=1764928603.834789731 30 ctime=1764935922.655568497 rsyslog-8.2512.0/doc/source/reference/properties/message-msgid.rst0000664000175000017500000000177215071746523023674 0ustar00rgerrger.. _prop-message-msgid: .. _properties.message.msgid: msgid ===== .. index:: single: properties; msgid single: msgid .. summary-start Carries the MSGID header field defined in RFC 5424 Section 6.2.7. .. summary-end This property belongs to the **Message Properties** group. :Name: msgid :Category: Message Properties :Type: string Description ----------- Carries the ``MSGID`` header field defined in RFC 5424 Section 6.2.7. The value identifies the semantic type of the event (for example an SMTP transaction label) and RFC 5424 allows the NILVALUE (``-``) when the sender cannot provide one. When rsyslog processes messages that lacked a syslog header at ingestion, the property contains the configured or inferred MSGID value rather than an on-the-wire header. Usage ----- .. _properties.message.msgid-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="msgid") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-pri-text.rst0000644000000000000000000000013215071746523024672 xustar0030 mtime=1760021843.833420907 30 atime=1764928603.758787416 30 ctime=1764935922.657568527 rsyslog-8.2512.0/doc/source/reference/properties/message-pri-text.rst0000664000175000017500000000176615071746523024350 0ustar00rgerrger.. _prop-message-pri-text: .. _properties.message.pri-text: pri-text ======== .. index:: single: properties; pri-text single: pri-text .. summary-start Formats the RFC 5424 PRI header as facility.severity with the numeric PRI appended. .. summary-end This property belongs to the **Message Properties** group. :Name: pri-text :Category: Message Properties :Type: string Description ----------- Formats the RFC 5424 Section 6.2.1 ``PRI`` value as ``facility.severity`` and appends the numeric ```` (for example ``local0.err<133>``). Facility and severity names follow Tables 1 and 2 from RFC 5424. For inputs that lack a syslog header, rsyslog derives the facility and severity from configuration or other metadata before rendering this property. Usage ----- .. _properties.message.pri-text-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="pri-text") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-msg.rst0000644000000000000000000000013115071746523023703 xustar0030 mtime=1760021843.832420891 29 atime=1764928603.70278571 30 ctime=1764935922.653568466 rsyslog-8.2512.0/doc/source/reference/properties/message-msg.rst0000664000175000017500000000116415071746523023352 0ustar00rgerrger.. _prop-message-msg: .. _properties.message.msg: msg === .. index:: single: properties; msg single: msg .. summary-start Returns the MSG part of the processed syslog message. .. summary-end This property belongs to the **Message Properties** group. :Name: msg :Category: Message Properties :Type: string Description ----------- The MSG part of the message (aka "the message"). Usage ----- .. _properties.message.msg-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="msg") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-fromhost.rst0000644000000000000000000000013215071746523024757 xustar0030 mtime=1760021843.831420875 30 atime=1764928603.727786471 30 ctime=1764935922.641568283 rsyslog-8.2512.0/doc/source/reference/properties/message-fromhost.rst0000664000175000017500000000215515071746523024426 0ustar00rgerrger.. _prop-message-fromhost: .. _properties.message.fromhost: fromhost ======== .. index:: single: properties; fromhost single: fromhost .. summary-start Reports the hostname of the system from which the message was received. .. summary-end This property belongs to the **Message Properties** group. :Name: fromhost :Category: Message Properties :Type: string Description ----------- Hostname of the system the message was received from (in a relay chain, this is the system immediately in front of us and not necessarily the original sender). This is a DNS-resolved name, except if that is not possible or DNS resolution has been disabled. Reverse lookup results are cached; see :ref:`reverse_dns_cache` for controlling cache timeout. Forward lookups for outbound connections are not cached by rsyslog and are resolved via the system resolver whenever a connection is made. Usage ----- .. _properties.message.fromhost-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="fromhost") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-year.rst0000644000000000000000000000013215071746523024712 xustar0030 mtime=1760021843.840421017 30 atime=1764928603.875790981 30 ctime=1764935922.730569645 rsyslog-8.2512.0/doc/source/reference/properties/system-time-year.rst0000664000175000017500000000121615071746523024356 0ustar00rgerrger.. _prop-system-time-year: .. _properties.system-time.year: $year ===== .. index:: single: properties; $year single: $year .. summary-start Returns the current year as a four-digit number. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $year :Category: Time-Related System Properties :Type: integer Description ----------- The current year (4-digit). Usage ----- .. _properties.system-time.year-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$year") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-syslogfacility-text.rst0000644000000000000000000000013215071746523027145 xustar0030 mtime=1760021843.835420939 30 atime=1764928603.772787842 30 ctime=1764935922.678568849 rsyslog-8.2512.0/doc/source/reference/properties/message-syslogfacility-text.rst0000664000175000017500000000302415071746523026610 0ustar00rgerrger.. _prop-message-syslogfacility-text: .. _properties.message.syslogfacility-text: syslogfacility-text =================== .. index:: single: properties; syslogfacility-text single: syslogfacility-text .. summary-start Returns the textual syslog facility defined in RFC 5424 Table 1. .. summary-end This property belongs to the **Message Properties** group. :Name: syslogfacility-text :Category: Message Properties :Type: string Description ----------- Returns the human-readable name of the syslog facility (such as ``daemon`` or ``local4``). The names follow the RFC 3164 and RFC 5424 mappings and correspond directly to the numeric property :ref:`prop-message-syslogfacility`. When the input does not supply a syslog header, rsyslog emits the configured or inferred facility name for the message instead. Usage ----- .. _properties.message.syslogfacility-text-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="syslogfacility-text") } Notes ~~~~~ - Expect the canonical names ``kern``, ``user``, ``mail``, ``daemon``, ``auth``, ``syslog``, ``lpr``, ``news``, ``uucp``, ``cron``, ``authpriv``, ``ftp``, system-reserved slots, and ``local0``..``local7``. - Some systems expose small spelling differences; compare strings carefully if you expect portable configurations. - Facility selection is independent from severity, but both values combine into ``PRI`` (``PRI = facility * 8 + severity``). See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-day.rst0000644000000000000000000000013215071746523024527 xustar0030 mtime=1760021843.838420986 30 atime=1764928603.890791438 30 ctime=1764935922.709569323 rsyslog-8.2512.0/doc/source/reference/properties/system-time-day.rst0000664000175000017500000000123415071746523024173 0ustar00rgerrger.. _prop-system-time-day: .. _properties.system-time.day: $day ==== .. index:: single: properties; $day single: $day .. summary-start Returns the current day of the month as a two-digit number. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $day :Category: Time-Related System Properties :Type: integer Description ----------- The current day of the month (2-digit). Usage ----- .. _properties.system-time.day-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$day") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-fromhost-port.rst0000644000000000000000000000013215071746523025741 xustar0030 mtime=1760021843.831420875 30 atime=1764928603.738786807 30 ctime=1764935922.638568236 rsyslog-8.2512.0/doc/source/reference/properties/message-fromhost-port.rst0000664000175000017500000000150415071746523025405 0ustar00rgerrger.. _prop-message-fromhost-port: .. _properties.message.fromhost-port: fromhost-port ============= .. index:: single: properties; fromhost-port single: fromhost-port .. summary-start Reports the numeric source port of the sender in line with :ref:`prop-message-fromhost`. .. summary-end This property belongs to the **Message Properties** group. :Name: fromhost-port :Category: Message Properties :Type: string Description ----------- The same as :ref:`prop-message-fromhost`, but contains the numeric source port of the sender. Local inputs provide an empty string. Usage ----- .. _properties.message.fromhost-port-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="fromhost-port") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-timereported.rst0000644000000000000000000000013015071746523025617 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.803788787 29 ctime=1764935922.69756914 rsyslog-8.2512.0/doc/source/reference/properties/message-timereported.rst0000664000175000017500000000241315071746523025265 0ustar00rgerrger.. _prop-message-timereported: .. _properties.message.timereported: .. _properties.alias.timestamp: timereported ============ .. index:: single: properties; timereported single: timereported .. summary-start Captures the timestamp present in the original message header. .. summary-end This property belongs to the **Message Properties** group. :Name: timereported :Category: Message Properties :Type: timestamp :Aliases: timestamp Description ----------- Timestamp copied from the sender supplied header. It represents when the originating application believes the event occurred, so accuracy depends on the remote clock, time zone configuration, and transport delays. Older transports frequently provide only second-level resolution. Messages that spent time on relays or queues can arrive with a ``timereported`` value that is minutes or hours behind ``timegenerated`` or ``$now``. Treat the field as a hint rather than an absolute truth when correlating events. Usage ----- .. _properties.message.timereported-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="timereported") } Aliases ~~~~~~~ - timestamp — alias for timereported See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-timestamp.rst0000644000000000000000000000013015071746523025117 xustar0029 mtime=1760021843.83742097 30 atime=1764928603.808788939 29 ctime=1764935922.69956917 rsyslog-8.2512.0/doc/source/reference/properties/message-timestamp.rst0000664000175000017500000000130715071746523024566 0ustar00rgerrger.. _prop-message-timestamp: .. _properties.message.timestamp: timestamp ========= .. index:: single: properties; timestamp single: timestamp .. summary-start Provides the same value as :ref:`prop-message-timereported` from the message header. .. summary-end This property belongs to the **Message Properties** group. :Name: timestamp :Category: Message Properties :Type: timestamp Description ----------- Alias for :ref:`prop-message-timereported`. Usage ----- .. _properties.message.timestamp-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="timestamp") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/system-time-wday.rst0000644000000000000000000000013215071746523024716 xustar0030 mtime=1760021843.840421017 30 atime=1764928603.897791651 30 ctime=1764935922.727569599 rsyslog-8.2512.0/doc/source/reference/properties/system-time-wday.rst0000664000175000017500000000131415071746523024361 0ustar00rgerrger.. _prop-system-time-wday: .. _properties.system-time.wday: $wday ===== .. index:: single: properties; $wday single: $wday .. summary-start Returns the current weekday number as defined by ``gmtime()``. .. summary-end This property belongs to the **Time-Related System Properties** group. :Name: $wday :Category: Time-Related System Properties :Type: integer Description ----------- The current week day as defined by ``gmtime()``. 0=Sunday, ..., 6=Saturday. Usage ----- .. _properties.system-time.wday-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="$wday") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/reference/properties/PaxHeaders/message-app-name.rst0000644000000000000000000000013215071746523024614 xustar0030 mtime=1760021843.831420875 30 atime=1764928603.823789396 30 ctime=1764935922.634568175 rsyslog-8.2512.0/doc/source/reference/properties/message-app-name.rst0000664000175000017500000000210615071746523024257 0ustar00rgerrger.. _prop-message-app-name: .. _properties.message.app-name: app-name ======== .. index:: single: properties; app-name single: app-name .. summary-start Carries the APP-NAME header field defined in RFC 5424 Section 6.2.5. .. summary-end This property belongs to the **Message Properties** group. :Name: app-name :Category: Message Properties :Type: string Description ----------- Carries the ``APP-NAME`` header field defined in RFC 5424 Section 6.2.5, which identifies the originator application with up to 48 printable characters. RFC 5424 permits the NILVALUE (``-``) when an application cannot supply a value. When rsyslog receives events without a native syslog header (for example from imfile inputs or JSON payloads), this property reflects a configured default or an inferred placeholder instead of a transmitted header value. Usage ----- .. _properties.message.app-name-usage: .. code-block:: rsyslog template(name="example" type="list") { property(name="app-name") } See also -------- See :doc:`../../configuration/properties` for the category overview. rsyslog-8.2512.0/doc/source/PaxHeaders/conf_helpers.py0000644000000000000000000000013215114522477017627 xustar0030 mtime=1764926783.022631539 30 atime=1764926784.231661215 30 ctime=1764935920.602537066 rsyslog-8.2512.0/doc/source/conf_helpers.py0000664000175000017500000001276315114522477017304 0ustar00rgerrger# Helper functions for main conf.py Sphinx build configuration import datetime import re import shutil import subprocess # Resolve git executable to avoid relying on PATH (Bandit B607) # # Note: Building docs from a release/dist tarball should NOT require git. # If git is unavailable or the working directory is not a git repository, # we degrade gracefully and return placeholder values so Sphinx can build. GIT_EXE = shutil.which("git") def _run_git(args): """Run a git command and return decoded stdout, or None on failure. We explicitly handle environments where git is missing or the current directory is not a git repository (e.g., dist tarball builds). """ if GIT_EXE is None: return None try: output_bytes = subprocess.check_output([GIT_EXE] + args) return output_bytes.decode("utf-8").strip() except (subprocess.CalledProcessError, FileNotFoundError): return None def get_current_branch(): """Return the current branch we are on or the branch that the detached head is pointed to""" current_branch = _run_git(['rev-parse', '--abbrev-ref', 'HEAD']) if not current_branch: return 'unknown' if current_branch == 'HEAD': # This means we are operating in a detached head state, will need to # parse out the branch that the commit is from. # Decode "bytes" type to UTF-8 string to avoid Python 3 error: # "TypeError: a bytes-like object is required, not 'str'"" # https://docs.python.org/3/library/stdtypes.html#bytes.decode branches_output = _run_git(['branch']) if not branches_output: return 'unknown' branches = branches_output.split('\n') for branch in branches: # Git marks the current branch, or in this case the branch # we are currently detached from with an asterisk if '*' in branch: # Split on the remote/branch separator, grab the # last entry in the list and then strip off the trailing # parentheis detached_from_branch = branch.split('/')[-1].replace(')', '') return detached_from_branch else: # The assumption is that we are on a branch at this point. Return that. return current_branch def get_current_stable_version(): """Return the current X.Y stable version number from the latest git tag""" def get_latest_tag(): """"Helper function: Return the latest git tag""" git_tag_output = _run_git(['tag', '--list', 'v*']) if not git_tag_output: return None git_tag_list = re.sub('[A-Za-z]', '', git_tag_output).split('\n') git_tag_list.sort(key=lambda s: [int(u) for u in s.split('.')]) # The latest tag is the last in the list git_tag_latest = git_tag_list[-1] return git_tag_latest latest_tag = get_latest_tag() if not latest_tag: # Fallback for non-git environments (e.g., release tarball builds) return '0.0' # Return 'X.Y' from 'X.Y.Z' return latest_tag[:-2] def get_next_stable_version(): """Return the next stable version""" current_version = get_current_stable_version() # Break apart 'x.y' value, increment y and then concatenate into 'x.y' again try: next_version = "{}.{}".format( int(current_version.split('.')[0]), int(current_version.split('.')[1]) + 1 ) except (IndexError, ValueError): # Conservative fallback if parsing fails next_version = '0.1' return next_version def get_current_commit_hash(): """Return commit hash string""" commit_hash = _run_git(['log', '--pretty=format:%h', 'HEAD', '-n1']) return commit_hash if commit_hash else 'nogit' def get_release_string(release_type, release_string_detail, version): """Return a release string representing the type of build. Verbose for dev builds and with sparse version info for release builds""" if release_type == "dev": # Used in dev builds DATE = datetime.date.today() TODAY = DATE.strftime('%Y%m%d') # The detailed release string is too long for the rsyslog.com 'better' # theme and perhaps too long for other themes as well, so we set the # level to 'simple' by default (to be explicit) and # allow overriding by command-line if desired. if release_string_detail == "simple": # 'rsyslog' prefix is already set via 'project' variable in conf.py # HASH # 'docs' string suffix is already ... release_string = "{}".format(get_current_commit_hash()) elif release_string_detail == "detailed": # The verbose variation of the release string. This was previously # the default when using the 'classic' theme, but proves to be # too long when viewed using alternate themes. If requested # via command-line override this format is used. release_string = "{}-{}-{}-{}".format( get_next_stable_version(), get_current_branch(), TODAY, get_current_commit_hash() ) else: # This means that someone set a value that we do not # have a format defined for. Return an error string instead # to help make it clear what happened. release_string = "invalid value for release_string_detail" else: release_string = "{}".format(version) return release_string rsyslog-8.2512.0/doc/source/PaxHeaders/community.rst0000644000000000000000000000013215055605325017362 xustar0030 mtime=1756826325.616800185 30 atime=1764865531.974853527 30 ctime=1764935920.560536422 rsyslog-8.2512.0/doc/source/community.rst0000664000175000017500000000373215055605325017033 0ustar00rgerrgerCommunity Resources =================== The rsyslog project is supported by a vibrant community and official resources that help users learn, troubleshoot, and stay up to date. Primary Resources ----------------- - `AI "rsyslog assistant" experiment `_ An AI-powered assistant designed to help with configuration questions, troubleshooting, and learning rsyslog concepts. - `GitHub Discussions `_ A community forum for questions, ideas, and feedback. - `rsyslog mailing list `_ A long-standing mailing list where the community exchanges knowledge and support. - `Rainer Gerhards' blog `_ Insights and updates from the maintainer of rsyslog. Filter for *syslog* and *rsyslog* tags for relevant content. Self-Help --------- For general support and troubleshooting, start with these resources: - `AI "rsyslog assistant" `_ - `GitHub Discussions `_ - `rsyslog mailing list `_ - `GitHub issue tracker `_ Professional Support -------------------- For guaranteed response times, private consultations, or expert help, consider `Adiscon’s professional services `_. Adiscon is the main sponsor of rsyslog, and using its services helps fund the continued development of the project. Legacy Resources ---------------- The following resources may still be helpful but are no longer actively updated. New users are encouraged to start with the **AI assistant** and **GitHub Discussions** listed above for the most current information. - `rsyslog video tutorials `_ These tutorials are slightly dated but still provide useful background on common rsyslog concepts and configurations. rsyslog-8.2512.0/doc/source/PaxHeaders/direct_queue_rsyslog2.png0000644000000000000000000000013215055603742021635 xustar0030 mtime=1756825570.256068377 30 atime=1764931123.369033855 30 ctime=1764935921.060544078 rsyslog-8.2512.0/doc/source/direct_queue_rsyslog2.png0000664000175000017500000003007615055603742021307 0ustar00rgerrger‰PNG  IHDR¬‘ŒÃåsBITÛáOà pHYsêe¤ IDATxœíy|MÇÿÿŸ7»ÄNľ´µ+JJQŠ.TQÔR>­òAµ¥Õ6EjK• ÔRµt±´µ´”úص>%Uj_b$„”D‰¬w~œþòäÞÜsï™›Ìó‘‡ÇuîÜ÷¼ÎÌœó:3gΓ; …Bd}°ößÿÐIóU²‹B¾JvQÈ׉d?ú裧OŸæÜNž<Ù¶m[ÝU* Ã1™LÖþ[€ŸÈðsk;£l{ä[¹r凶7ŸgžyÆIwOÉ. ù*Ùþ¹BQ0Lê_¡P(Ùq±w'99‰Ie?¶’Iæw|w{F ± 3æ}ì3Z…B¡È ;à Nô¦wš4¢‘ Õ±-8)¤,fq=êmg{1Š-§€d’¹ŠUòh:éFkQ(ya—¡¤œ˜Â”lˆÇxì$']ìß5)”Ä¿˜Ås™CŒç9_êF‹²3æïøn SÂkC›0Z‘B¡È 7}Ãää¦l`CÖØQAÊ ÀMnÎcÞB&’¨mÉH§s3æu¬›Ìä0´-“™l¬$…B‘/ºõ²,Ð\Á—GxDu,!û=˜+\™Íì¬H%Õ„I L˜¼ñ¾Â•ò”7P¤U˜1o`Ãd&Ÿå¬ .fÌ&L-iù-Má8"û߃[rÛhUbÁÚ£U‚yTœÆpžóñÑ6˜1çøª4¥½ðÊj"Ù›‹ã?. ÏY<Â#ç9ÿ`I6¢Qg:W¤b*T Â³<+Ý ABÉÉÂ»ØÆR»'3ù4§5KÈJ2œáõ©ÑG…ý"8`{GpDÃSXÏ5®U¡J t0†xâ?ã³9̉'^»ÂÍúêQ­AÿË,Û-h§øìàL3È0cÞÊÖ8âr”dŽÿºãþO´¥m/ð‚#îígfrè×®qíׯÿ߇»wIJ"9™ôn) ÔrÜÚL2í.ɘ0eýåøoÞÛ-ßh¿Ä*‚Š`a„ºÔuËó>‚nCIÚƒ .¨p™ËÎ;‘Æ≟Íì9ÌI&YÛâ‚K-jàÀmnGy–³ÿã»ÙK,PjÃö:¯ç} `5áá9Âñãœ8Áñã\½Jö¦b2áïOõêx{ÿß_ñâx{óÜs—Ÿ¬<ƒ_óuÙCN`Â~Tä±QÏT(œg%Å?Ÿù!„įm™Ç¼·y[Ç,Š7¹9éKX’5¹ó~x™—³§¹ÌåìœÆ´(¢L˜úÓÿ3>³é>DRûöñßÿ²};.ü³ÑË‹æÍiܘÆñ÷§Jüü¨PS>§Ñpƒ ^Éʬ]¨D¥+\É]T(’"ì@¼ˆŸ*¦–¥T•’E²=r) \—‹Á.ÂA3Ñì¡i̼[ìî%z!ðÞÓÄ´‘b]6iiâÛoEÏžÂÅE€Ñ°¡ 6ˆ „ÙlË.„‹ð‹» wæ‰y¶DS(À.Æ ¡ÙCQF lä¤8ÙCô@°]lÏ#Y¨}\<ŽÀWø†ŠP‹BŸ=+ÆŽeË %KŠ—_Ë–‰èh}tg#BDŒ£<„GeQY]((’c÷µ’’Hú–oG0B àÚÈìdgÞϘ1/eé&¤’ºŒe˜kÒsç7ŽmÛZµbøpú÷§xq½UßGQ3™ùd¤]3R(¶ Ñ+„„Öî¹øLejΉ­áá²v-&¯¾ÊĉԪåHyÉ${ãíÈ …U(c(œÄÛ—¾»Ù=€«XõOw-3“™3 "#ƒþý™1ƒ5 ªP(äCç%1’P†2;ÙÙ~kXS“šÓ˜FX}ûrâíÚBË–FkT(’"ÙÓ³úѵk×Ö­[3f̨Zµêßÿ½oß¾ÚµkoÛ¶-99¹AƒÁÁÁÀ€Ì›7¯mÛ¶IIIû÷ïïÔ©Shhh||üóÏ?¿råJà­·Þ –/_>hРŒŒŒÐÐÐaÆ={6..nôèÑ¿üò 0mÚ´%K–ëׯŸ#„8yòäùóç…aaaBDFFîÚµ+!!!>>~ëÖ­—/_ÖGbF†4(º¥îºù™«ÄŠX}Â*ŒãÌ™3ÀÌ™3…åË—þùç…½{÷öññBÌŸ?8vìØÉ“'ýüüV®\)„ BLžýôÓ×^{M±sçÎáÇGDDDEE?þ÷ßBÌœ9ó§Ÿ~BlÞ¼Yûá©S§Ö®]›`ØnÛõ9…ÁddˆAƒˆÁƒ7f®GðŠxÅhM [ÑÏž=+„X±b…vNY³fÍĉ…Û·oâ£tÒæçºÔý…_¼ðZÄ¢?ù¨Mí&4iHçyº! Ÿà  ÍZÑ (KÙºÔõÄÓ|Üq7c¾Ç=í”EÔE.—¹¼›Ýd\çújVG‘Jê"íg?ð_-g9°•­òaiŽÛù={˜2…¶mYµ —ªØïéL¿ÆµùÌwœ…Bá„¶¡¤“œœËܬXÂ’‘ŒÜÅ®f4 !d ã±xâKQÊ®îqÏ„É ¯;ÜI'½<åos;–ØÚÔvЫunÜ Y3228z”ªU³“IfSš^ãÚ%.Îѳ"I9–W(l¤ÃMn®fõ8Æ}ÌÇóñÎøâ{‘‹­i튫ÑêKÇŽüö[·Ò­Ûƒ_nfó‹¼øþó Ÿ8^š¢ÜàFa—¸¤ýE•@BII$%“\ŒbfÌ·¸••þÁ·M”§|Qî‚ór‚W¹zžóYn¸Ýå®ýrÏø L°_| qzcˆ#Îß×xí+¾ºÄ¥â/A‰¢»Ïš5 Èøñ|úinIšÓü—®q-ï—¾* äö±Oû»Îõ¬í&Lõ©_œâY¨à‰g"‰}¿¦öW‚KXbàî8a„ýÆoÚ_YÛ«Rµ>õÝq÷ÀÃ~¹÷£ßØ/¾…8·1¬d囼yžóIdÚ­ÈPîÝã‘GÈÈ ,Œ¹žôײv³øßüÛ‘êùr•«_ðÅ*VE ¸àÒšÖmi[—ºu¨S›ÚU©ª‹ìÄ9έbÕjV‡¸âÚ‚OñÔc<Ö”¦ i˜÷»0 N¹«dLfrAu©Û….fÌþøW¥jþ¿,ÜÌKD+Väá @ozW¤¢2yˆõ¬_ÈÂßøM Òpƒ:Ðá)žRo»³7é¤É—ËYþ¾øŽg|g:·§½6½ˆbèSä[ñ-‚…b¡ÑBd":ZøøˆfÍDff¾iE ‚ýB=k0fa^+ÖÖµ”%‡‹áˆ?ŒUT¸#îhoÓ^4ùŽxçOñ§Ñ¢dÁ™Œ!CdLÓ?›…y®˜k6½r²°ñþûÄîÝ–¤Ñ®Âu¨joQŠ<Ø/ö7͵7î­+2D†ÑŠŠ "#D„Å<"Ù$6­H:rÞc8uêÔêÕ«Mù½ç=‹Ò¥K¿ÿþûVõQ‚ƒƒïÞµâ¶þàÁƒyäà&7Ѩ m6±)ô{÷îݽ{wÞ1³ï`ݺu_}õUËõ$''kKh刓cÇŽõõµbzèºuëN:eyú¶-Z<óÚkT«Æ‘#–¤¿zõj{ÚÇTˆyoö{.™yM¢ÕvÐÍÍM[\Ör–,YróæÍqò {÷îÍš5³<þ‘#G´m-¤råÊÆ ³<=0}útañ8“É4tèP???K§‘ö>ïÏg¾{ºû“¡O¶ mç‘æ‘'·_5lذGênß¾½téRËÓãÆóô´büdíÚµÚ*~Ò¡CmÍc 9þü?þøÐ¯ZP>>>#GæórÀøÿ:Ïù¦4ÈÄèEÑÉIV¬cúÒK/Õ©SÇòôüý÷ß-O_³fÍÞ½{[ž>%%eáÂ…y$x° ^{íµÒ¥Kç7‡Q¬_¿ÞrM@µjÕ¬õ¢Š+Z•ÅæÍ›cEì›âÍL‘yE\É·£0eÊ«âkëaYέ[·òz?—.]²*‹~ýúYM·nIJeÆÿí·ßxt¶(¾———Uú…5²j–/_nU|myZËiÞ¼¹µ»àêjÝDçƒZö’¸ÔR´DPáj*[ðàÁVé?wîœUúøøx«²èÔ©“Uñƒƒƒ­Š¿aëâûûûç-Y$ã\„‹ðY)VjµuO-G[~Êr¦NjUü®]»ZÿöíÛVÅ.^¼˜oØœ=†””mý^ qqq©P¡‚U²nÞ¼™÷âÀ9$•)Sf¦×ÌùøþhIþ/HLLLLL|h¨‡âååU¶lÙ|“ea6›¯_¿žºlTªTÉÍÍŠûü·oß¶d5ö¬½óëÝÛõÒ%¢¢ð¶hžnjjêÑÛGª ¼;pzìtò+(“ÉT­Z5K"gqýúõ´4+ö.W®\‰<ï™ç 11Ñr‡BxzzZx9ŸÅåË—*·ô~~~^^ùÜ+ÞÉÎôÈ$s:Ó‡Þ'Þr=>>>V]T¥¥¥Yu9Ô®]ÛÅÅŠÇ0£¢¢rk¨-¨òåË—)SÆòø‰‰‰V­>íææ–Ûåüu®w¡ËiNw¡Ë—|YÚó… 222,Ï¢jÕª>>>–§¿uëVLLL rT‰%ªW¯nyüÌÌLí À’sF½zõ´—äìÓUà /A‰2”ÙÅ®.t1ZŽ”?NÓ¦ŒËœ9Vý®­¢ˆŠ"ÊAdy¶°¥}ÊRv;ÛÒÐh9Eˆœxžç¯sý3>{õJ’ü‘úŒ íi_›Ú™d*WÈ•U«F²öwÝéMôiNë/Iñ[ÙÚ‡>¨ð¿)Wp$¿òk[ÚÞáÎf6+W°yŸcÈ$Ó×Íl>ÃwÜ–#1[¶P¿>ÖÜÓhMkà‡aÝý…µüʯ=éY™Ê{Ù[›ÚFË)B„ú,Ï–¢ÔÏüÜ‚FËqäí1ô¢×$&5¡É+¼b´‰¹x‘sçxþùü´%-M˜qHwQŠìDÙ›Þå(÷'*Wp$—¸ÔƒžxîcŸr«´ÇHbQEwÉ#ËÙ²à… ðÓÒ”®O}e v%ôþô¿Ã]쪈uóñ¶p›ÛÏó|<ñÛÙ^ŸúFËq2dì1\áŠ;îG8ò5_­Ez¶l¡tiÚ¶-د[Ñê§’±b·Â* <À ‚:ÐÁh-E‹þô?Ïùå,ױ䓓 Áš§°œéŒA zÓ»2•3Ȱë*†…´4öï§KÜ x¦­2ÈÐV‰QèÎŽÌfvg:ȇFk)Z|Í×»Øõ&obŽa½½‰Œ¤zu¦O'!AÇÀÒ!1˜0…2•©Ej-Ãräii<ùdho¬S£Iö@ Æ0Æ ¯å,W‚I4Ñc[‹ZÁëü?ÿ!9™>*äö W{#.˜àö´W³Ê,âða€¿«Ö„&žx*c°?ðÃAŽc\Ö³T Ç0ŠQw¸³ŒeÅ)®{ðÊ•1àÎìaÚ´Bhr=à6žñ³™}˜Ãó¸ÑZœ!CX³†øx x~(­iCÌeò”¯¢À¤ò(¦ržó>Xñ ¬ÂFpàIžư/ùÒNYDGS³&©©&BPº4ï¾Ë[oQ²¤òt4ù÷ßò×ÿ‚~hZ7š]ÓÃZ}óèÁ×seoØh €àÍ Ì.n/·%ìá!oï²à¥ßôJ¨wJ«6ÚÁ©++²ë²“o½ÑpÁþۆˣJZ:ª:ûY×Äf¿6}ù‚ÇMû©ŠŒ$û:…ÏòÇß¶µk ¦}Äú>Ì}Cr3‡. ™Ûªš¹%.ÁÝ•aߺ ɪËÃfߘéÙ’.l¹vÔuWWÛU¸ÑpÙ7Þž¹Èåvù˜YCþN“HU¡Òì`|«¾ß¼wÞÿž=U=t±7³™ŒŒ‡åtäßcHN&=ýþߨ¡FM ~Þ¾ý2.KûÆÞyÞ|õáàAøüsF¶%Ìÿø_;Ú-e鼡—´"ÎA0 ö¸ù©Èƒgyv/{/pÁûåró&5jšŠÿôJ–dìXÞy‡|W³vòï1Ø0|mÅ)™DÒ-·[Þj.’…hkZ¿Füð®aÅ–мYÄ"W\G0Âh!E‹«\ÝÁŽ! ±«+³f‘’òÏç%;–±c %hH1+)•ÔÁ ¾ÎuõÞf+¨YÓÆ0U¨b¤ŒA/’I^Ǻçx®5ŒÖR´XÅ*3æ¡ µk.7o²h€“&qõ*\Ø\I–Ä8ÀU¬êD§ZÔ2Z‹ópå ..X³tûCñij<壈ÒE”b+[SIí‡u¯ZRØÎ7|S“šíhg×\fÍÂÃñãyç¬y+£“!…1t¤c<ñj Uë¸r…Ê•±æEŒ¹á‡Ÿê1èŶ¸âÚnF )Z„zžó™hÂ~·õ¸w²e¹z•R¥ì—‰?”EÔ4¦%’XŒbFkq*ÂÃmGÒPÆ fÌÛØÖ†6e±â€ ÛÙÈF` íšK±b|ðAáwd0†ÿò߉L<Å)£…8™™DDP£†.Áüð‹%ö÷òOªÈ“?øãoþ~‚,v«°…=ì©A µŠª^o ¯óúŸü©Öž´Ž„22°òmÛ¹¡ÝóWÛÙË^@#9˜Xbr´ŒRx0ØÒI&¸µ<Ña¬¼‘”ºM%V3VõâG¼ñVoît0{ÙkÆü4O-¤ð`°1ìdg ëYo¬ ç#9t651Évþâ¯&4qÅÕh!E‹=ì1aRÆ #ÏJz†g~áµdžÕhÆP\ŸÅ#UAns;œpuƒÁñáHmjW¢’ÑB ÷r°#+ ÏXyBס$m MqºD+²áМæF )Z˜1Ÿæ´¾Ó#A zÒ³½ Ôà¬èÚcð H!%ß”Š<8ÉI )MR´'ü.wÑÈh!… #‡’2É !Ä—Âûø ýеǠŒA"ˆj¢ÏÃ% Ñfº«ƒ¾i I$ý‹(À‰Ñõæ³'ž&L©¤ê­ÈADIJ–¦Ð­›#7ZGMƒ¾i ³˜Lð5®9Ý]#³ÙœiOúöí[¬XžÏë:”dÂ䉧å=†›7o†„„è’µóòÔSO½ðÂ}÷™#‰´÷ºžŠ‰$¨MmäµcÇŽyóæÕ©SÇÃÃC< à¡Û-ùÖÞ?Ï‘à½÷ÞëÕ+×a|7mogÍš¥o &$$+VìçŸöñÉõ½†MiÚƒ©¨oÖy „hÞ¼yZZZ¹råò8/gddäý­½u>óÌ3ùƒ®CI€UưsçNÝŒÓqæÌ™ÆAD þþmINN~çw|}}[´haÓŠ#^®\¹%K–<þøã?ýôS¾;Gœ7ÞŽyê÷ßß¶m›íqLÙÈñß±1Anߦ¦æ5Bàܹsçܹs¶ïmvnݺ•‡1ô¡Oúè›o¾;v¬D‰©©©®÷ãááájÜÜܬJ¿xñâŸ~úiÔ¨Q÷éÎÈÀ-[÷îÁ¡$³—‚O%ðÂËrc¸{÷.°}ûöæÍ‹è œ—^zéäɓٷ¤r‹[Õ¨f”¤´´´/¿´×[ŽL½zõÒÒÒ,¼‹%¶ eòM¶dÉ’°°°¹sçÚ¬ŽãÇW­ZÕ–·íìзoß¾}ûêwÚ´i'Ny¾®#˜Îô¼C]¹r¥X±b•*é0ܤUIŸ>}V®\i{4;ñÒK/ !rÃúõüõï¾KÅŠpÿPRJ _|ÁåË|öY3µÊ\\\€’%K–+W®À9:59¶Ä+å°¢@ž|òI—ýû÷ë"IkÛ/¾øâˆ#l¿œ4öç®®®µk[:4K¬%XvìØ±wï^]ŒÁ××·L™ü­È©±×=­Öó6†Rþæï|C5kÖ¬S§N6lÐKXÞª çá {÷&0Ï?gäHÆÿg(ÉÕ•Ï?gÆ nÜàøq[2õÂËò›Ï–TnáæÁ:J$(A ˃$%%¹ØÐÉ{PP£FgŸ}V¯˜NAqvÔ +ö½ùœ÷¹ã íšûCqVcpwç£xí5æÌáóÏ©W Q#nÝèÕ‹FŸÇ½téÒ{÷î½ýöÛygjUAÃut—»Xi úRd+%–XõìˆîØë·|›é®¼ÍÛñ—䆳0x0µj¤¥qêÀíÛÚ˜81·h_}õÕ’%KòÍTƒU(c„ 2H°äƒÂ* 3†k\›Ïü£µ“€Üpbcps#(è¾-B`2Ñ£Mm½bòÄ3‰$ËRôÎAÙQÆ qÄ „zHVw 3†6´‰#ÎÞo\z'6`ÀêÖÍ9û(÷î‚å4§¹å‹ ÍsPv¬#ÍV‹£Ï“% hVжÀ—ê1èŽaÆp“›ûØO¼ä†sƒ«+AA˜ÍYIyî9·umZ3æìÜÍîh¢-THÑ;eçÁ:Ò–ÚÎ$Ó EE´Rb‰Eƒ0Ìrð%^:Ìa; È ç6 _?ê×ÿ§Ó “&ÙžãOütšÓ÷¸L°… )zç ìø¬gýqr]•¯hžƒ²cI!…”¼;^ºK¢èUŠºÇ`':”ô Ÿxãý#?v¥kg:¿È‹Ã>“™é¤ûá÷/äLga’<–(Ô¤²¥Çp˜Ã7¸±™Í¡„>Ã3šÇ”¡Ì f\åêd&Ïc^ )zç ì˜L&á*ö²W›Í¸ãîŽ{–1¬eí£õµŽ™ÃRè1æ9†Où´%L˜L˜êQÏ‘×Vò<›®še V‘½Ž±È÷ì6à†Û†«ªãÿ‡|DDP2É¡„Þàà°9,…cŒ¡2•?æcк ޼¶’ÿà±ÐL˜lœ®š-”æ7ù¢Œ!{Õ§þû¼ŸÕcІF+RÑXU…›wy·6µ³/墕¿Ãæ°z {òy cã±bsðµ•ü…CI:ºªÇ`%9êèC>¬IMí<%ùÞvvŒªBŒ'ž X})ò›Ã¢° ÃŒÁ÷,x…W¼Àªü…=}¯Œ”1XEŽ:*F±…,ÔÎSÕ©Þ™Î2¨*Ü<˳/òbÖ`C¾sXVa˜1OóôlfÛI@nÈðXh ªÇ` Öѳ<Û›ÞÀ¼áb·ÃÊZU…›¹ÌõÀCóÏa)ôi ñê%ù ‡’TÁ@ZGó˜ç‹ï¿ø—!’p†¶­/5©ù!jw<‡¥Ðc°18ù5”$?­£ªTÝÁǯ$Ÿ…üm[wÞçýÔ<‡¥Ð£ŒA:ÔP’üäVGŽUmväoÛºã…×|æ{ãmÈüàBŒ2é0d(I‹¦ŒÁBälErª²7Ýé¾…Ž”.Ü(c5”$?r¶"9U9€¡ 5ZBaCƒt(c9[‘œªΈ2éP÷äGοmÈÕ«WOŸ>m´ §Aƒt¨éªò£K ÌŸ?Á‚:)ghÛ2vìØ¶mÛ­ÂipcèÝ»÷Ô©yg}ÁÿàQCIò£K ¬X±båÊ•:)ghÛ gÁ€e·­e÷îݶÉBþƒGß¡¤[·n™Íæ *äLƒUÈYò·m…³àÆ /ò<%yâiI´=zÄÅÅ=›Ï[é•1X…œ% ÛV8 N0”¤/òùäÛãhÈðä«Ð—Çx¬ÕôÍ7†˜ T°$¥29K@þ¶­pœÀôEþƒ'_…‰$žáÌüaI´>ø`̘1ù&K#-ޏŠT´P!RV®Ã³äoÛ gA½A:òUØ„&&LÇ8fI´_ý5...ßd§9-öB¤­\‡!g Èß¶΂ê1HG¾ KQªµö±OÇL×±èAKK[¹Cοm+œe Òa‰Â>ô #ìW~Õ+Óø¡>õ›ÐÄ’ÄÒV®Ã³äoÛ gAƒtX¢p c<ð!D—á—K\²|ò«´•ë0ä,ùÛ¶ÂYPÆ –(ôÃï^Ù–?±u"oI£]Žroò¦å ‘²r†œ% ÛV8 ʤÃB…AyãÝ›Þó·-ÙMbR8á!„”§¼å ‘²r†œ% ÛV8 ʤÃB…5¨±ŠUQDõ¥¯…KY<ÈbÏc^g:f°U ‘²r†œ% ÛV8 ʤÃr…=é9 ûØ÷ÏÝæ¶µ…2šÑi¼†5Ù_ð`‰B¤¬\‡!g Èß¶΂2é°JáT¦¾Ïû;ÙÙœæ>ÙÄ;ïñ^+ZíaåƒHY ‘²r†V²!ÛV8 ʤÃ*…®¸ÎdæüG\ Zô§ÿaç‘ÞŒy)K«S} kF1êW~õÅ· ‘²r†œ% ÛV8 êÉgé(€Â>ôiD£ILZǺïù¾ ]šÒ´ÍZÐ"Å?%¥rÊ.váÌV¶îeo:é i8yèd‹NɋѮÈÙ¼åoÛ g¡(ƒÑò¡`‡w}êÏ÷‘D~ʧßñÝvüóÅ÷Ïð àwOzö¤gÖÛ~ ¬)+×aÈYÊzQABUÙ±E¡?þ X°€‘DåèQŽ®X²"õvê'ŸøâÛÔ-må: 9K@þ¶m C‡íÔɦ.r‘Â^ÆP¶lÙQ£F5mÚÔöP+Vôõµz<7ÞxãçŸ^¯hö@—ÃÛü{Ðcû7Ûãââ†ÕCÚ?”,YrÁ‚?þ¸Ž1‹Æ5ª\¹r¶Ùµk—¾ý×1cÆ$&&ê°0Ñ£‡Eë€)4Ô%†tìÛ·ïÒ¥K¯¿þº.ÑâââΞ=«K4…Â1ü÷¿ÿ-]ºtëÖ­r“'Ož2eJDD„¿¿¿ÑZ싽z ŠÓ¡C‡:èíÕW_½wïž^Ñ ÇЭ[7£%iTA¡P(,"&&&&&¦~ýúîîîFk±/Ê …BqözÀM¡P(NŠ2…B¡P܇2…B¡P܇2…B¡P܇1Æ0mÚ´òå˧¥¥å–`Μ9Ú‡—_~¹`Y„„„øøøì· …BQ”1Æ~üñÇlÞ¼9·YưnݺÄÝ¿©R¥ ¨Obìê©{öìiÓ¦Mûöí›7oþóÏ?\e‘Ä®Usâĉ€€€§žzªeË–»ví*¸J…„ÃÙ¿ÿo¼qáÂ…^xAÖ¾}û€€€:DGG !,XàááѾ}û &øùù !Nž<Ù¦M›6mÚœ>}Z‹S¥J•Ñ£G?öØcsçÎ͑Ÿqã<¨ý¶Ñ¼yó·Þzkݺu¹%°e¯SSSµÑÑÑ5jÔ(pœ¢‰]«ææÍ›‰‰‰BˆˆˆˆÚµk8N!`êÔ©åÊ•Ëj«¢}èÓ§OâÏ;·nݺ>>>ÔW(0À^ýõÐÐP!DçΣ££;tè°sçNí«ÌÌLíCÖ!¤}hÛ¶í¯¿þ*„øý÷ßÛµk§}UºtéË—/ÇÇÇשS'{üK—.õïß_Øvʉyòd ))©}ûö<òÈÞ½{Ÿ~úiÀl6k哃ڵkÿïÿkÛ¶íjÕª¥mÌmµçÔÔTOOO téÒñññöÚ“B‡ªF1|øðêÕ«¿÷Þ{vÛÙINNÞ¶m[TT³jÕªsçÎe½eá¡… \¼xñ©§ž._¾¬môöö®Y³&žžîéN‡ÑΤ°”N::t(ë¿]ºtY½zu»ví:vì¨õ£…£FêÒ¥Kpp°vÉsìØ±'žxBëJŸ|contains|startswith|endswith|re_match|re_extract)\s*"[^"]*"\s+', bygroups(Name.Tag, Operator.Word, String.Double), 'legacy_action'), # RainerScript Keywords (r'\b(%s)\b' % '|'.join(keywords), Keyword.Reserved), (r'\b(%s)\b' % '|'.join(objects), Keyword.Declaration), (r'\b(on|off|yes|no|true|false)\b', Keyword.Constant), # Operators (r'(&&|\|\||and|or|not)\b', Operator.Word), (r'(=|==|!=|<>|<=|>=|<|>|:=|contains_i|startswith_i|contains|startswith|endswith)', Operator), # Variables and Properties (r'\$[a-zA-Z0-9_.-]+', Name.Variable), (r'\$\![\w\.-]+', Name.Variable.Instance), (r'\$\.[\w\.-]+', Name.Variable.Global), # Built-in functions (r'\b(%s)\b' % '|'.join(builtins), Name.Builtin), # Strings (r'"', String.Double, 'double_string'), (r"'", String.Single, 'single_string'), (r'`', String.Backtick, 'backtick_string'), # Numbers (r'\b(0x[0-9a-fA-F]+)\b', Number.Hex), (r'\b\d+\b', Number.Integer), # Punctuation (r'[{}(),;\\\[\].&]', Punctuation), # Identifiers (r'[a-zA-Z_][a-zA-Z0-9_-]*', Name), # <<<--- THIS IS THE CHANGE: Added '-' to allowed identifier characters # Legacy Directives (r'^\$\w+', Keyword.Pseudo), ], 'comment': [ (r'[^*/]+', Comment.Multiline), (r'/\*', Comment.Multiline, '#push'), (r'\*/', Comment.Multiline, '#pop'), (r'[*/]', Comment.Multiline), ], 'double_string': [ (r'\\"', String.Escape), (r'[^"]+', String.Double), (r'"', String.Double, '#pop'), ], 'single_string': [ (r"\\'", String.Escape), (r"[^']+", String.Single), (r"'", String.Single, '#pop'), ], 'backtick_string': [ (r"\\`", String.Escape), (r"[^`]+", String.Backtick), (r"`", String.Backtick, '#pop'), ], 'legacy_action': [ (r'~', Operator, '#pop'), (r'-?/[^;\s]+', Name.Constant, '#pop'), (r'\S+', Name.Constant), (r'.*?\n', Text, '#pop'), ], } # --- Sphinx Extension setup function --- def setup(app): from sphinx.highlighting import PygmentsBridge app.add_lexer('rainerscript', RainerScriptLexer) app.add_lexer('rsyslog', RainerScriptLexer) return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, } rsyslog-8.2512.0/doc/source/PaxHeaders/whitepapers0000644000000000000000000000013215114544362017061 xustar0030 mtime=1764935922.871571804 30 atime=1764935930.264684983 30 ctime=1764935922.871571804 rsyslog-8.2512.0/doc/source/whitepapers/0000775000175000017500000000000015114544362016602 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/syslog_protocol.rst0000644000000000000000000000013215114522477023134 xustar0030 mtime=1764926783.034631833 30 atime=1764926784.236661338 30 ctime=1764935922.871571804 rsyslog-8.2512.0/doc/source/whitepapers/syslog_protocol.rst0000664000175000017500000003132415114522477022603 0ustar00rgerrgersyslog-protocol support in rsyslog ================================== `rsyslog `_ **provides a trial implementation of the proposed** `syslog-protocol `_ **standard.** The intention of this implementation is to find out what inside syslog-protocol is causing problems during implementation. As syslog-protocol is a standard under development, its support in rsyslog is highly volatile. It may change from release to release. So while it provides some advantages in the real world, users are cautioned against using it right now. If you do, be prepared that you will probably need to update all of your rsyslogds with each new release. If you try it anyhow, please provide feedback as that would be most beneficial for us. Currently supported message format ---------------------------------- Due to recent discussion on syslog-protocol, we do not follow any specific revision of the draft but rather the candidate ideas. The format supported currently is: **``VERSION SP TIMESTAMP SP HOSTNAME SP APP-NAME SP PROCID SP MSGID SP [SD-ID]s SP MSG``** Field syntax and semantics are as defined in IETF I-D syslog-protocol-15. Capabilities Implemented ------------------------ - receiving message in the supported format (see above) - sending messages in the supported format - relaying messages - receiving messages in either legacy or -protocol format and transforming them into the other one - virtual availability of TAG, PROCID, APP-NAME, MSGID, SD-ID no matter if the message was received via legacy format, API or syslog-protocol format (non-present fields are being emulated with great success) - maximum message size is set via preprocessor #define - syslog-protocol messages can be transmitted both over UDP and plain TCP with some restrictions on compliance in the case of TCP Findings -------- This lists what has been found during implementation: - The same receiver must be able to support both legacy and syslog-protocol syslog messages. Anything else would be a big inconvenience to users and would make deployment much harder. The detection must be done automatically (see below on how easy that is). - **NUL characters inside MSG** cause the message to be truncated at that point. This is probably a major point for many C-based implementations. No measures have yet been taken against this. Modifying the code to "cleanly" support NUL characters is non-trivial, even though rsyslogd already has some byte-counted string library (but this is new and not yet available everywhere). - **character encoding in MSG**: it is problematic to do the right UTF-8 encoding. The reason is that we pick up the MSG from the local domain socket (which got it from the syslog(3) API). The text obtained does not include any encoding information, but it does include non US-ASCII characters. It may also include any other encoding. Other than by guessing based on the provided text, I have no way to find out what it is. In order to make the syslogd do anything useful, I have now simply taken the message as is and stuffed it into the MSG part. Please note that I think this will be a route that other implementers would take, too. - A minimal parser is easy to implement. It took me roughly 2 hours to add it to rsyslogd. This includes the time for restructuring the code to be able to parse both legacy syslog as well as syslog-protocol. The parser has some restrictions, though - STRUCTURED-DATA field is extracted, but not validated. Structured data "[test ]]" is not caught as an error. Nor are any other errors caught. For my needs with this syslogd, that level of structured data processing is probably sufficient. I do not want to parse/validate it in all cases. This is also a performance issue. I think other implementers could have the same view. As such, we should not make validation a requirement. - MSG is not further processed (e.g. Unicode not being validated) - the other header fields are also extracted, but no validation is performed right now. At least some validation should be easy to add (not done this because it is a proof-of-concept and scheduled to change). - Universal access to all syslog fields (missing ones being emulated) was also quite easy. It took me around another 2 hours to integrate emulation of non-present fields into the code base. - The version at the start of the message makes it easy to detect if we have legacy syslog or syslog-protocol. Do NOT move it to somewhere inside the middle of the message, that would complicate things. It might not be totally fail-safe to just rely on "1 " as the "cookie" for a syslog-protocol. Eventually, it would be good to add some more uniqueness, e.g. "@#1 ". - I have no (easy) way to detect truncation if that happens on the UDP stack. All I see is that I receive e.g. a 4K message. If the message was e.g. 6K, I received two chunks. The first chunk (4K) is correctly detected as a syslog-protocol message, the second (2K) as legacy syslog. I do not see what we could do against this. This questions the usefulness of the TRUNCATE bit. Eventually, I could look at the UDP headers and see that it is a fragment. I have looked at a network sniffer log of the conversation. This looks like two totally-independent messages were sent by the sender stack. - The maximum message size is currently being configured via a preprocessor #define. It can easily be set to 2K or 4K, but more than 4K is not possible because of UDP stack limitations. Eventually, this can be worked around, but I have not done this yet. - rsyslogd can accept syslog-protocol formatted messages but is able to relay them in legacy format. I find this a must in real-life deployments. For this, I needed to do some field mapping so that APP-NAME/PROCID are mapped into a TAG. - rsyslogd can also accept legacy syslog message and relay them in syslog-protocol format. For this, I needed to apply some sub-parsing of the TAG, which on most occasions provides correct results. There might be some misinterpretations but I consider these to be mostly non-intrusive. - Messages received from the syslog API (the normal case under \*nix) also do not have APP-NAME and PROCID and I must parse them out of TAG as described directly above. As such, this algorithm is absolutely vital to make things work on \*nix. - I have an issue with messages received via the syslog(3) API (or, to be more precise, via the local domain socket this API writes to): These messages contain a timestamp, but that timestamp does neither have the year nor the high-resolution time. The year is no real issue, I just take the year of the reception of that message. There is a very small window of exposure for messages read from the log immediately after midnight Jan 1st. The message in the domain socket might have been written immediately before midnight in the old year. I think this is acceptable. However, I can not assign a high-precision timestamp, at least it is somewhat off if I take the timestamp from message reception on the local socket. An alternative might be to ignore the timestamp present and instead use that one when the message is pulled from the local socket (I am talking about IPC, not the network - just a reminder...). This is doable, but eventually not advisable. It looks like this needs to be resolved via a configuration option. - rsyslogd already advertised its origin information on application startup (in a syslog-protocol-14 compatible format). It is fairly easy to include that with any message if desired (not currently done). - A big problem I noticed are malformed messages. In -syslog-protocol, we recommend/require to discard malformed messages. However, in practice users would like to see everything that the syslogd receives, even if it is in error. For the first version, I have not included any error handling at all. However, I think I would deliberately ignore any "discard" requirement. My current point of view is that in my code I would eventually flag a message as being invalid and allow the user to filter on this invalidness. So these invalid messages could be redirected into special bins. - The error logging recommendations (those I insisted on;)) are not really practical. My application has its own error logging philosophy and I will not change this to follow a draft. - Relevance of support for leap seconds and senders without knowledge of time is questionable. I have not made any specific provisions in the code nor would I know how to handle that differently. I could, however, pull the local reception timestamp in this case, so it might be useful to have this feature. I do not think any more about this for the initial proof-of-concept. Note it as a potential problem area, especially when logging to databases. - The HOSTNAME field for internally generated messages currently contains the hostname part only, not the FQDN. This can be changed inside the code base, but it requires some thinking so that thinks are kept compatible with legacy syslog. I have not done this for the proof-of-concept, but I think it is not really bad. Maybe an hour or half a day of thinking. - It is possible that I did not receive a TAG with legacy syslog or via the syslog API. In this case, I can not generate the APP-NAME. For consistency, I have used "-" in such cases (just like in PROCID, MSGID and STRUCTURED-DATA). - As an architectural side-effect, syslog-protocol formatted messages can also be transmitted over non-standard syslog/raw tcp. This implementation uses the industry-standard LF termination of tcp syslog records. As such, syslog-protocol messages containing an LF will be broken invalidly. There is nothing that can be done against this without specifying a TCP transport. This issue might be more important than one thinks on first thought. The reason is the wide deployment of syslog/tcp via industry standard. **Some notes on syslog-transport-udp-06** - I did not make any low-level modifications to the UDP code and think I am still basically covered with this I-D. - I deliberately violate section 3.3 insofar as that I do not necessarily accept messages destined to port 514. This feature is user-required and a must. The same applies to the destination port. I am not sure if the "MUST" in section 3.3 was meant that this MUST be an option, but not necessarily be active. The wording should be clarified. - section 3.6: I do not check checksums. See the issue with discarding messages above. The same solution will probably be applied in my code.   Conclusions/Suggestions ----------------------- These are my personal conclusions and suggestions. Obviously, they must be discussed ;) - NUL should be disallowed in MSG - As it is not possible to definitely know the character encoding of the application-provided message, MSG should **not** be specified to use UTF-8 exclusively. Instead, it is suggested that any encoding may be used but UTF-8 is preferred. To detect UTF-8, the MSG should start with the UTF-8 byte order mask of "EF BB BF" if it is UTF-8 encoded (see section 155.9 of `https://www.unicode.org/versions/Unicode4.0.0/ch15.pdf `_) - Requirements to drop messages should be reconsidered. I guess I would not be the only implementer ignoring them. - Logging requirements should be reconsidered and probably be removed. - It would be advisable to specify "-" for APP-NAME is the name is not known to the sender. - The implications of the current syslog/tcp industry standard on syslog-protocol should be further evaluated and be fully understood .. _concept-model-whitepapers-syslog_protocol: Conceptual model ---------------- - syslog-protocol introduces a structured header (PRI, VERSION, TIMESTAMP, HOSTNAME, APP-NAME, PROCID, MSGID, SD, MSG) to standardize message framing. - rsyslog auto-detects legacy vs. protocol messages, mapping missing fields (e.g., TAG to APP-NAME/PROCID) to maintain compatibility during transition. - Parsing focuses on minimal validation for performance; structured data may be accepted without strict checks to avoid drop-induced data loss. - Message transport (UDP/TCP) imposes limits: UDP fragmentation and LF-delimited TCP can truncate or split protocol frames. - Encoding and NUL handling are implementation challenges; messages are often forwarded as-is because source encoding is unknown. - Rules for discarding malformed messages are relaxed in practice; marking and routing invalid messages preserves observability.   rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue_rsyslog.png0000644000000000000000000000013115055603742024105 xustar0030 mtime=1756825570.265068523 29 atime=1764929145.53682283 30 ctime=1764935922.853571528 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue_rsyslog.png0000664000175000017500000002434115055603742023556 0ustar00rgerrger‰PNG  IHDR¬‘ŒÃåsBITÛáOà pHYsêe¤ IDATxœíytÅÚ‡Ÿ„l„û ‘EÙ¾Hà‚ ¢‚"•íƒ^P<^‘EE#² "²) *"—‚¢—v D ’uêû£½¹aI2Cfº«gê99œ¡§ç­_×[Ý¿®îêj7!@ +„(ø`ë¿wýC“–«d»B¹J¶+”k"Ù5:zô(·áݾ}{»«T(†ãææfë¿wñ~nëÊf”íˆrkÖ¬yÇ–ãáïïÿ裚tó”lW(WɾëŸ+w‡›:ÁWè‰ËW|Õ~¾ø­E¡PÜw£(\ –µ¬mLãïøN¹‚B!3F P8?,ëX7i'8áŽû6­H¡P‡2…±`ù†o¦2õ8ǵ%ÏðL#«J¡PºÇ p± S™z”£î¸[°n¸EݘÆF«“ˆ‚·üÝqyéWV\3BOz†VLkT=…ˆoùvÓsØw@s µÞäMŒÞ+䌠wž&Ä 7íß[þ¬_¨-oHÃâ RÆ °Ž¼<Ž#&† HM%#ƒë×ÉÈ lY>ú¨ðŠ—¹¼‰MG9J!KÐH&y{JÙ¦ïb¡;Pz æ`:ÁNÁ^{s‰¨KIŠ"¸~ˆ¶oçÔ)NŸæüù;¯Ö°!'Nܾ8–Øwyw«òÈÓ–¸áæƒÏ9ÎU£šãT+ŠÒ£ŒAQ!øê+"#Ù³‡Ã‡ÑÚF­Z4lHp0 L:T¨@¹røùáï_|¼3œy÷>ã³{x…Wf1ËÑÛ¡P(Jƒ2'NðÙg¬ZõwÏ 8˜Îÿþ«U«”±Ïqî=Þ[ÉÊ\rµNCuªÛA³B¡p Ê\!ظ‘U«øö[€à`FŽdà@í^Tqïóþr–‡6‡9v¯P(ì…2æûï™2…¨(4ˆ!ChÕÊÑe&0y“˜@€£ËR(w‡2—ä×_4ˆØXÊ—güxƧB£5) YPÆàbdg3u*³fáãÃK/1q"•+­I¡PÈ…zŽÁ•8x!CˆŽ¦kW–/§n]£) Q³«º ‹Ѫ±±ÌŸÏÎÊ EQ8­1„††¶iÓxï½÷/_¾¼gÏž   mÛ¶eff6nÜ8<<xî¹ç |øá‡íÛ·ÏÈÈØ»wo·nÝ"##SSS{÷î½bÅ `ܸq“&M–-[öüóÏçååEFF>üøñã)))aaaßÿ=0}úôÅ‹ëׯŸ:u*pðàÁéÓ§'&&¦¤¤Ìš5ë·ß~Ó‚|÷ÝwÀ®]»>ÿüsàäÉ“kÖ¬¹zõjjjêúõëcbbìY ¯¾JXÍšqö,cÇâ¦Þâ¢P@nn®"///999338wîÜùó瘘˜¨¨(mIDD„ö­Q8­14oÞ¼E‹@57nìåååããS§N___!„¿¿¿——`±XrssŒŒŒË—/ׯ_‰‰ÉÌÌÌÍÍŠŠJLL"##ýõWàÀ_ý5púôéeË–%%%¥¥¥-Z´H;â/]ºtݺuÀæÍ›ß{ï=à?þ˜ËìÙôêÅÞ½TSO››ŒŒŒï¾ûîìÙ³ÀÁƒãââ€+W®\»v °X,%ü^a ‡š2eʹsç’““_~ùåmÛ¶&LÐN+ç̙ӯ_?`Ó¦M:t8vìXlll³fÍ´³ÉæÍ›:4höÍ9sæxyy9räСCU«VÕVkܸñ+¯¼Œ;ö±ÇÖ®]z¾¨¹ôA(î–üü|‹Åb±X222²³³…©©©×®]B¤¤¤$$$!ÒÒÒbbbnܸ‘}ôèÑK—. !¢££O:%„8yòä¾}û„ ;wîLKKKMMݺuë™3gì#1'G´o/@ .rsíSa(ÇŽf̘!„¨ZµjïÞ½…ýû÷÷÷÷BÌŸ?8tèPtttíÚµW¬X!„ ™4i’bêÔ©{÷î5R½ÙÐ:ô?üðùsç€iÓ¦ !êÖ­Û³gO!ĨQ£…k×® >xðàÙ³g[µjµjÕ*!Ä“O>9eÊ!Ä|ðâ‹/ !vìØ1räÈøøøÄÄĉ'þòË/Bˆ3f|ûí·BˆÍ›7k?6œœLÓ¦X,=J•*z”¨0”<ò y—‹Â‰qc¸ÈÅ5¬™À„·xë-Þ:ƱbˆiC›2”1Z¾<õß|Ö-ôéc´…ø‹¿Nr2–Xí/‘Ä4Ò2ÈÈ #“̲”µ`I&¹`ýÛ_ûU•ª‰$¸ æå0‡ãˆ;Å©‚?<®sÝq%Ndâë¼î¸øVbzcH!%€€yq%+c‰-G9?ü|ñ5Z—A|þ9C†0bK–-Eq÷œæôöh¸P°Ü ·†4,G¹‚¿jTóÆ;ô;¾kZûóÃo1‹ Üsq’“?ñ“öO|Áò@ÒÐO/¼Wú<ÇsŽ‹o%æ6†¬x‰—NqJ HhK[£Jj*õëS±"ÑÑ”+g´…ÍÄ÷ Ÿ¬fu €;îmhÓžöÁ7 AAª‹Eâ'V³z kÎq(C™V´êHÇxà!jBWšYΔ›šGÞT¦NcZ0Á=èaÁR‡:ØÿÝ2&#<œ”V®T®`.b=ë²ð'~ˆ&4yžç;Ó¹#}ð1Z““Kî§|ºŒe80‘‰ÝéÞ‰NÚpv×Ä”=†Õ¬Ìà…,ãµHÃùóÓ¢?ÿl´…µÄW|5‰Ig8Sžò8ŒaÚÐ8…£I%u æ2÷*WkPc 1¨W•)0S!ŸüÌhF³A J&y4£V$Ó¦qã3f­Ca-?óó˼|€,gù ¼àr% "Ÿüy̛” 2îçþ¬èK_£EÉÅ­=†#GެY³ÆÍêÙ7+V¬øÚk¯ÙTdxxøõë6ÜÖñÄ 4°~ýýû÷ÿòË/Ö¯_¿~ýþýû[¿~VVÖÂ… ‹YáöŠzñÅ+V¬XBÜ[¦ÈX¿~½õš€{î¹ÇÖY8ªW¯nS›7o¾*®¾$^ÊùgÅY‹°ÿí·ß¶)¾6–õ$''—ôfbccm*bÀ€6ÅßÓ²¥qø°•ñúé'›âûøøØ¤_Ñ´iS›ŠX¶l™Mñµéi­§E‹¶nB™2¶¿ï߿ߚ°±"¶µh Z\5jÚðàÁ6é?qâ„MúÔÔT›ŠèÖ­›MñÃÃÃmŠÿÍ7ߨ¿N:ÅDË™Äwáî/üWˆÚBmÞSëѦŸ²žwÞyǦø¡¡¡6Å¿råŠMñ˜˜˜ÃÞÚcÈÊÊÒæïµww÷j6Îä|ñâÅâ'¾ER¥J•føÌx‹·~å×Ö´.1~zzzzzúCݟʶ¼ÞÒb±\¸p¡äõ Q£F ®Ú]¹rÅšÙØµ­sËÎlÓÆ-(ˆß~³2~vvváÓyJª(77·{î¹ÇÊà.\Èɱáaï*UªøùùY¿~zzºõ-„ðöö¶òt¾€3gÎÜ1TQë×®]Ûǧ„{Å;ØÑ—¾ùä¿Ë»C“‡¦^Kµ^¿¿¿M'U9996ÎAAAî¶<*Ÿ˜˜XTC½cEU­ZµR¥JÖÇOOO·iöi¢Nç/p¡=Žr´=>åÓ{ø»=Ÿ>}://Ïú"ýýý­_?99ùÒ¥KŬpKEùùùÕµå%ZùùùÚ€5Ç:ûî»O{é@1È~óùçüð«D¥ììA£åHÉêÕ ÌÒ¥ f´Eq|ÇwOñTe*og{š-Ç…8ÌáÞô¾À…yÌ{‰—Œ–c¤6¨G½k\K&ÙO£åÈJ‡DGsþ¼¥*3[ÙÚŸþÕ¨¶›ÝA-Ç…ø‘ã1ø’/{ÓÛh9æ@ÞQIùä—¡Ìf6ã˜r…"‰åçŸ S® 3?òãã<^“šÊt&’È^ôª@…-lQCQ­G^cx’'äÁ·yûA4Z‹ÄhÞyÆhŠ"I ¡?ý«Påw~¯Žm#/¥!–ؾôõÆ{{ÒÐh9fBRcH'=‘D×òÈz¾ÿž€BBŒÖ¡¸3¹ädà5®íd§r=¹Â•ÞôN%u;Û•+ØŠŒ“õŸå¬'žQD}ÆgFk‘›´4öî¥Glò¤Ð“ILÚǾiLëLg£µ¸xŠSËXfÇšÏÌdölly ˬHg ÑŸþ5©™GžCg1tvì '‡Þê~š¤üÁ³˜Õîoð†ÑZ\‹Ïøl';_â¥çyÞŽa}}IH n]Þ}—´4;–G%íf÷QŽªQe%3bË—sé¶<‡¡ÐhG»C:Á‰‚Qó H"©18ÌárØyPFR÷ÞKV+ò꫌Kùòö-A äê1¤Nx':)W°Šßçþû•+ÈÉ×|½Ÿý˜ \AgÆ0æ×–²Ôî®Ô¬É¨Q×®ñæ›Ô­ËôéNØ{«Ç0‘‰³˜õ´¤¥ÑZ¤'+‹òå0€U«Œ–¢¸•,²Ñ(‹¬Sœòdže¥dûÚÑn8Ã?åS‘”Dýúdg¸¹!+òÊ+Œç<½‡’aÕ*øûó×µãBK™Ü“Þhÿ°¢D9ZÀ],4JÀ½W~ŸöýÃ_´šóŸFãUµÈ¦*!tiô¸M|RgÛHyTI+ÀŽªŽÏ MoþãCOŸöºXÇqª(<Ï…óÙCÉ£Y¶mcíZ”Àô7Yÿó‡ý KirÇ 4‹šU³¨•GX˶øéÍaK¹PϲLªêÊŒEîWª^š9ärŽDªœ^@Vóý©G|9úÆ©:7©êŽ“½Y,äåÝù+ÓQr!3“ÜÜ›「¦»¥Õö 7hiÎçŽ.ËðækFâÓOII¡B‡•¡¸ö³?„×y=œp£µ¸½èµ›Ý§9]‡:Ž+åâEêÕ#;!þî+”/Ïøñüë_”8›µY(¹Çà«ËCfå(ŸAF²G²¯‘o%ÇS·®r YÄ¢2”Å(£…¸qÄE1„!u`æL²²þþìçÇøñŒï<– !Ũ¤l²3øÔ{›m 1‘:ŽÝwA&™ëX÷þQzFkq-V³Ú‚e(CZÊÅ‹,ZàïÏ”)ÄÅñÖ[Îæ Hb ûØ·šÕ?aÛÛc\!¸p@å£Ò±•­ÙdÀ¶W-)JÏç|^ŸúèàÐRfÎÄËë–`ˋ̈́nºÐ%•T5…ª \¾Lv66¾yF¡ßñ]Êô¤§ÑB\‹H"Oqj2“ÝpÜm=nÜ reââœÿ ®ñ=†D§3=ô²”5Z‹yHLTA6,X¶±­-m+£ž:Ô• l1È¡¥”-Ë¿ÿíü®€ Æðþ3™ÉG8b´S¡½ïPƒdüʯ—¹Ü‡>F q9~à‡zÔS³¨Ú ãaÃ~çw5÷¤mho¯ZÕhŠ›ØÍn@]GÒ™«\=ÈÁnt3Zˆó`°1ä’Nø½Üë·±JL†6\®¤WÏ+t&Š(_|Õûœuf7»-XºÒÕh!΃Áưƒ“˜´žõÆÊ0š1x+7•‹(¢äÁ2”1Zˆkñ?¸á¦ŒÁŽ<*éQÝÊVõ.V›Q=ù¸Â•8âã1£…¸QDTƒF q î1ìgWºV£š±2̇2ùˆ" hA £…¸,G9ª.ßÙ#A çñ'yÒ@ fE›óWƒLD <ÄCF q-Îqî:×›ÒÔh!N…‘—’òÉŸÍìœôÙA‡’—¨W=KE<ñ@}ê-ĵÐFº«ƒ}1òÈ’AÆ?ù§LLÙ²™™êõmòO|yÊWÄéæÍ‘­£¦ŒÁ¾i 3™NøyΛÅbÉw$Ï<óLÙ²Å>®Íy›™ù¿%99xz:ršïÿqñâÅÙ³gëPÌtìØ±OŸ›dK ÁÑóz*n' ˆ ÊŠˆˆøðÃ4hàåå%îpÇåÖ|ëèŸß²Â«¯¾úä“E^Æ÷жvæÌ™ö­Á´´´²eËnÙ²Åß¿È÷>ȃ}é[êö-º„-Z´ÈÉÉ©R¥J1Çå¼¼¼â¿u´ÎG}ôVc8tˆûïÿßM…råà¿Æ`±°d »wóÕWަ±cÇ»7ÓqìØ±[Œ!žxÇ×effþë_ÿ hÕª•#+zþ¼J•*‹/nÙ²å·ß~[↧⋯>BýòË/Û¶m+}·BÜòßÛ)å E}›­Ý§,àÚµk'Nœ(ýÖ&------99¹cxš§Ÿæiû–["‡òóóËÎÎ.s3^^^eƒ‡‡‡MëüñÇß~ûí˜1cnÒ]«AA„†2z4­[ÿÝcÈÈ 2’°0`½~Ï‚\¿~ؾ}{‹.:ç‰'žˆŽŽ.¼$‹¬d’ïá£$åää|ú©£Þr¬3÷Ýw_NNŽ•g`W¹Z‰J%®¶xñâ“'OÎ;·ÔêøóÏ?Ksà.½Gã<óÌ3Ï<óŒ}ãNŸ>}òäÉ¢Ø×Ãu¡K!ïònñ¡Îž=[¶lÙ5ìp¹IKÉSO=µbÅŠÒGsO<ñ„âVc¨V×_gÜ8V¬ eKZ¶˜>ˆ„ F úöÕM¡»»;P¾|ù*UªèV¨Txyyݲä*W¢ 6TH»víÜÝÝ÷îÝkIZÛîׯߨQ£J:iìÏË”)dí¥¡«\µfKDDÄîÝ»íb •*•lE¦ÆQ÷´¬o Yd]ær‰¡š7oÞ­[·o¾ùÆ^ŠWe8E*=š¥K9|˜¨(¢¢¶oÿû«‘#ñÔoÒrk’ëÜÜž£tÒ?ü¬’‘‘¡Y¬½$õêÕëÕ«—½bš‚R ì¨9+Ž}Ž¡øcÇ~ö/a‰CÜŽ‰ÁÃ>ºÃíå2e1¢¨hK–,™7ož]*c¸CŽ®sÁ¾¸lR¬¼”¤° GC‰Íô,g_æåp€¢0±1:0hÐ-kÓ·o1óo¯\¹rñâÅvèºÇ ”1HByi¤)c°;†ÃyÎÏgþA:H@Q˜Û€>ÀÏïý!=Za¸æ1¨0Ê$!…PÉÚÃŒ¡-mSHqô—nÇôÆP³&o½…¶‚»;AAtï®›6 ×<æöe”£œAŠ\4))¤ªÇ`w 3†‹\ÜÞTR$ (Lo Àر4j`±0z´>µÆ5A…¹=GÚTÛ,)rѤ\å*Ê€aưŸýOðÄüá Eá ÆàéÉÂ…ÞÞ ª‹¨›pÍcPanÏ‘/¾@&™EüÂá¸fR4cP—’ìŽaÃUCÙÄ&ýŸucºtaÀ|| ™+É5A…¹=Ge)‹2ݹÁ ½‚ç¬f ¨Ðžöú߬scæÏ'!Áñrî€kƒ £z ’ Í„‘E–ÑBœ Ã.%}Íו©I¤ƒ…óCµj?ÿ¬;®y *Œ2IÐ:jZ¿AaG 3†¦4}•WkQËAŠÂyŒÁ8\óT˜¢ŒÁÀ#”k&E3Õc°;†]JjIË–Üt»‘=èáèË…¦8ìʯ×;Fõ$ÁTÁè×cˆ'~Ó’HÒþETco`p’“¡„~Â':ÜD2ÅaW~…¸Þ1¨0êæ³$¨ƒƒÐÏîážxâïáž'y2‚O<ýðË'ÿu^oJÓ"þÿs˜[„I¾ó˜B!®w *Œ5=†,²Žs\OI¸^RÔ=¡ë=†÷yßßl %´;ÝûÑo$#g0#—ÜÚÔîCŸ"‚ÙY˜ä;)âzǠ¸¹¹‰2b7»W‚'žžxÃZÖ6¢QUªê) ×KŠõ—’ºuë6xð`Ç+rt½ÇPjÓ™>ŽqÀe.Ob’?µ;ŠQº¼gÔ‡]ùâzǠ¸¹¹‰\± #9œáCZê¾øÞàÆ)NaÌ.v d`ñ¯gX²d‰›]ŸZ—¿åØ;^J:ÏùÚÔ¾eͰ°0ýd™½G%ftSšºÿ·\í„Ëá /*ÔÙ³g?ûì3; “|ç1…B”11é×¹þ:¯×¦öSùßðÍU®Æ›K.DPº¢JçBuÆQŒêA lÈ#ÏowܳÈJ'ý5^kF37ÜÐÀh™¦Ç€áªè0ˆA«Y­ýW F£ßÄÑòï<öU8cÆ {…*@CAŽžåÙ¥,-|³Ac$# .“ê¯Ê¹™Å¬F4ÚÁŽšÔÅ(|Nr²! µúŒaqzŒyÀí>ðÃÏ 77Üîã>=Ï­äßyL¡e ÿÝüE,òij° xà1„!ƪrbêPç Þ’HšÆ´L2#‰ü‹¿Ýư8=ÆCMj¾Å[¡uô<·’ç1…B”1üwóÒð5^+è1h—F«SÝXUÎÍ+¼D{¡Ã—Vÿºaqz ›c,cಔÕùÜJþÇ QÆPhóßàúÔ׎SQâmg}T91Þx/`Á-o¿(~ ‹Â& 3O<°àYžÕy.uùwS(DC¡Í/KÙ…,ÔŽSu©Û½ß©wGUÎM/zõ£_Áņǰ(lÂ0cºÒu³$ (äßyL¡e 7o~/zõ§?0‚îÛ­lUåÜÌe®^š7è<†Åé1Ò0âÕKòï<¦Pˆ2†Û6ÿC> àŸüÓI˜¡åØ—úÔƒ7´» :aqz 6ý‘ç1…B¤L®nÜ1GF¡ÿLòÈßrìÎk¼Vz€ÎcXœe Òa …H™\Ý(*Gú¿ª¶0ò·»ãƒÏ|æûâkÈø`'Fƒt˜B!R&W7äÌ‘œªÍc<¶…ú_”vn”1H‡)"eruCÎÉ©J†2Ôh Ά2é0…B¤L®nÈ™#9U)̈2é0…B¤L®nÈYò·‰‹‹;zô¨Ñ*Lƒ2é0…B¤L®nØ¥æÏŸ¿`Á;)3´?~|ûöíVaL` ýû÷çwJGCþÇ QÆPêX¾|ùŠ+ì¤ÌÐrfÁ€i·me×®]¥R€ü;}&''[,–jÕªÙ+ Êd­ùÛ¶Â,˜Àì‹ü;}öíÛ7%%åøq{¾•^Úäꆜ5 ÛV˜\J²/òï<¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݳäo9 ³ ŒAF$W(mruCÎ0EÛV˜e Òa …H™\ݳäo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAM¢'¦Pˆ”ÉÕ »Ô@·nÝÜÝíyf&Ë1¯¾úÊb±­Â4˜À&MšT¿~ýÒÇXkâuxIDATÑpss“¼}È¿{+c°K Ìž=ÛNrþFþ–c žžžFK0&0†‰'–>Hòï<¦Pˆ2ùj@þ–£0 &0û"ÿÎc_…›6m²{IÚäꆜ5 ÛV˜e Òa_…U«VµW¨¤M®nÈYò·m…YP£’¤Ã ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݳäo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ݰK üõ×_ýõ—ZŽLš4éÿø‡Ñ*Lƒ &ÑÛ¶m[•*UZ·n]úP˜aç1…B”1”ºzöìéîî~àÀ;‰2Á»F äøñãû÷ï7Z…i0AáÙgŸ}ÿý÷KGÇ]ù¢ŒA¾¿å(Ì‚ ŒÁ¾È¿óØWá¿ÿýï±cÇÚ+š†´ÉÕ 9k@þ¶­0 &¸”d_äßyì«ðÇLII±W4 i“«rÖ€üm[aTA:L¡)“«rÖ€ü-Ga”1H‡)"eruCοå(Ì‚2é0…B¤L®nÈYò·…YPÆ ¦Pˆ”ÉÕ 9k@þ–£0 ʤà ‘2¹º!g ÈßrfAƒt˜B!R&W7ä¬ù[ŽÂ,(cS(DÊäꆜ5 ËQ˜e Òa …H™\ÝÐj@6äo9 ³ ŒA:L¡)“«rÖ€ü-Ga”1H‡ü 5L!ÒAÈÙ¼ÍÒròãŠÆ`´„÷–6¹º!g ÈßrfAÍ•$¦Pˆ”ÉÕ 9k@þ–c C‡íÖ­›Ñ*Lƒ£Œ¡råÊcÆŒy衇Jªzõꥣ1bĈ޽{Û+š#÷._¾ü‚ Z¶li´ÃhÖ¬Ù˜1cªT©Rš ;wî´oÿuìØ±ééév èLôíÛ×h fBöc ²gÏžØØØaÆÙ%ZHHHJJÊñãÇíM¡Ð‡ÿüç?+VlÓ¦ÑBnbêÔ©o¿ýv|||:uŒÖâXÕcPÜ5;wîܹ³½¢½ð 7nܰW4…Bzöìi´—Fõ …Â*.]ºtéÒ¥† zzz­Å±(cP( ÅM8j¸ªB¡P(LŠ2…B¡PÜ„2…B¡PÜ„2…B¡PÜ„1Æ0}úôªU«æääµÂœ9s´O?ýôÝ1{ölÿ»û­B¡P¸2ÆÃÆŸ{î¹Í›7µB1¬[·î.â_½zuïÞ½*T¸K}ãPOýá‡Ú¶mÛ©S§-ZlÙ²åîUº$MÍáÇCBB:vìØºuë;wÞ½J…„îìÝ»wĈ§OŸîÓ§âäÉ“:u éܹsRR’bÁ‚^^^:uzýõ×k×®-„ˆŽŽnÛ¶mÛ¶mCBBŽ=ªÅ©U«VXXØ<0wîÜ[Š˜0aÂþýûµß:-Z´7nܺuëŠZ¡4[­}HJJªW¯Þ]ÇqMšš‹/¦§§ !âãヂ‚î:ŽðÎ;ïT©R¥ ­ÞÎìÙ³µO=õÔ]ÄŸ;wnpp°¿¿ÿ]ês 0†aÆEFF !ºwïž””Ô¹sç;vh_åççk v!íCûöíüñG!Ä/¿üÒ¡Cí«Š+ž9s&55µAƒ…ãÇÆÆ8P”n?”÷Üs'NœÎh ŽöT!DDDD›6mªW¯åø rtHªoß¾kÖ¬qðÖÈ‹nì|G›ÐÛV­Z5mÚ4íóõë×[¶lÙ¹sç]»viKŠÚ…Úµk·wï^qó.T°Î-ÆðÈ#hÆãííÝ¿‡nŽžèà©—+W®råÊC† ™6mÚäÉ“½½½¿øâ‹5jýúõ íÒ¥‹¶æÂ… Gåîî,Y²¤ø""##µëׯwÔ–èΆ FŽ9uêT ##£S§N÷ßÿîÝ»»ví X,­~n!((èçŸnß¾ý¾}ûî½÷^maQ³=ggg{{{+VLMMuÔ–8:¤F1räȺuë¾úê«ÛÙÉÌÌܶm[bb"péÒ¥Õ«WŸ8q¢à- w¬d &&¦cÇŽ@HHÈ™3g´…¾¾¾õë×rssõn:Œv&…µtëÖí·ß~+øo=Ö¬YÓ¡C‡.]ºhýh!Ę1czôè®ò:tè‘GѺÒÑÑÑÚ:Eu¶>þøãN:µoß¾uëÖÛ·o×a£œR³qãFí I§NºvíªÃFIˆ× pñƒšDO¡P˜ƒîÝ»‡‡‡·nÝZûohhè!C/^œŸŸ_øzCXXXLLL—.]>úè£ÄÄÄ?ÿü³ðõ†&MšZÏ£^½zçÎ+\Ê—_~¹téR­37|øðê¼™2 ŒA¡P(7¡¦ÄP( ÅM(cP( ÅM(cP( ÅM(cP( ÅM(cP( ÅM(cP( ÅMü?Ùå^yV4IEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/queue_analogy_tv.png0000644000000000000000000000013215055603742023215 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.530822713 30 ctime=1764935922.862571666 rsyslog-8.2512.0/doc/source/whitepapers/queue_analogy_tv.png0000664000175000017500000004445215055603742022672 0ustar00rgerrger‰PNG  IHDRë8ô;LwsBITÛáOà pHYsÐй‹çŸ IDATxœíÝw\S×ßðOKöRQdƒ7ÕZ«­J­uÕ]·uàh뮥\m©¨ÕÚV­£¿ÖV[[«m]åqTqáAPAd„™óüq1 ! ; |ß/ÿ8Üœ{ï ćs﹇Ç!ºC$Â’%HLĹsÚn !ºŽG NtKa!‘›‹‡áâ¢íÖ¢Ó ´ÝBÊ25EPÃÏ?k»)„è:Jp¢{F@ NÈKÑ( Ñ=4BHÕPœèH!¤j(Á‰N¢Bª€FQˆN¢Bª€úàD'Ñ@ !U@ Nt ¤ò24ŠBt ¤ò2Ô'ºŠRyJp¢Ã†h … Ñ( ÑaÝ»#2< ¤¢õÁ‰ @)„T„œè°ž=K ”à„hB£(D‡=x4BˆFÔ':ÌÝ ¤¢%8Ñm4BHÅ(Á‰nëÑ£´p´ÚBt%8Ñm\ÜÛ¹¹01ÑvkÑ-t%“è¶¼8ÑmqqÊøp÷®öšBˆÎ¡'ºMíæ;Zj!ºˆœè6µ ˜ 7WKM!DçP‚ݦ–àr9®^ÕRSÑ9”àD‡åä &F}#ÝVHÈ ”àD‡EF¢¤D}#%8!/P‚¦1¬/_ÝKJp¢Ó4Τ‹ßàM!DQ‚]ÅX…ÏB¡BP‚݇ÌLÍ/ÑS®@ NtW%1M}pBP‚ÝUILß½Kóz%8Ñ]•$xI Íë!”àDG©Îåáñ4T B(Á‰ŽRË£qcJpBA‚ @ÛM õ@5 ÍÍ5T y=„èo‚3°£8êWà·kµÝRToDQMp ‹ÒÍë!D¼4»süFlqgÁð›ábˆµÝ(R§Ôæò¨&x‡Ê2 ¤&OŸ\™ÝŸ¸ûÅ]ó‰æþ_ùçý÷9>×vÓHRËck[fÜ×WY¦y=¤ÉÓWËn§±N;Cvf8e|mø5ÏGÝðÆF5š¹…êTœúà¤ÉÓõטÝÎÆlc àͱoR7¼±Qfµo×/>´4¯‡4yº›à•g·¢ZˆauÃÕ/,,sÏIf&,-KË4¯‡4y<¦{·d1°_ñë'9ŸÜÝ}8ÍpZå´j*¦ª·ª!²!'–ŸX¾ey(B¸©¤îåäÀƦÌÂÍš¡àÅ=£|~™—Ö­ÃÊ• Ú3ÓZ‚ëHv+„P7\ï¨Íå±±ÁÙ³èØ –y”Uj*Þ{¢¤††ÉJ·ÿ÷%8©={û‚àà[ ÞÏ?÷Ìj°cmÇÁµ5Þ]9 ×?jsyâã1gärlÙ‚›7•ÕFÂ÷ßÃÐ àƒ”Ûi^i’jžàrÈu0»Bè¦ý¢6—ÇÆ;v 2={¢¸Xù’L†I“‹/¿Ä€Êít1“4I5Ea`31óÏœ?Ÿí~¦ c&•ކ¢‹—D$j»9äe4ÎåéÜ/ÂË ¥[ÄØ±¥en^\¼˜×Sùí+„TGPÐÐú>ůåjÒ_„EßF}ûlÖ³VSZéT¿[ÕZ¬='=‡,<ŽyLÝp=PÑ\¯Ì})ª×zh^iòªàÛ±=ü`8l7,°] ›Ù-”W‡¯.X_SæšÕèi8ÕšË£Šæõ¦­z ¾ÛƒÃÇ£6>ؘ‡¼zjY (²;ocžuõ¶uÛà C6C3m7TªZsyTѼÒ´U#Áñ½óÝGqÔ|йxx'v¾|Ïú§šÝöAö_¬û"Ù5y*¦j»]¤jªø8”òÊÏë!¤)©j‚«Æ÷,̰\°\ºáå³;É5iQ¿[‹®]»V½ÔÖå©:Z¯‡4mUJðòñ `9–k·NÙ­³RRRz÷î}êÔ©*ծʺ<¡õzHÓöò×ßmuÃ)»u\PPPaaáÀ«”ãªsyŒ!•VãL±±xüXù%Íë!MÌK¼’ø†6ºá”ÝzÇã}òÉ'.]ºôòWÝâbtìˆ1cý’s$%aêTtèP¦&õÁISY‚Wßœë†Svë—   Î;så—ä¸ÚeLcc> ?¿ s<= ÂÛ{÷‚ÏÇŒ´^©Äÿý·aÆÜFúÁ¨0Á«ßhn8e·>RtÃ*ÌqÕ_» 8¸LŽçç++|ý5Üݱu+d2LœˆØXìÞMózH%zôèñ믿º¸¸¬[·.;;[ÛÍ©k¬œóìü86ŽwÇûoÛU¾‚šPŠm°M°•0ÉK+W˶F+ÀV`%ìÚÁ¾ÈgùUß=åá8L™Ü¾}›1&“É¢¢¢îܹ£(ß½{—1&•JÕÊÑÑÑŒ±ââbE¹¨¨(***&&FQ¾wïc¬°°P­Ë+((P”óóó£¢¢âââåû÷ï3ÆòòòÔÊñññŒ1‰D¢(çææFEE%$$(Ê<`Œåä䨕>|ÈËÎÎV”³²²¢¢¢=z¤('&&2Æž?®VNJJbŒeff*Êb±8**êñãÇŠò“'Ocjå§OŸ2ÆD"‘¢œžž•œœ,—Ëýüü4~êzõêõÏ?ÿ0ÆXv6ãóÀÆç³œœÒ^r2 f¦¦¥/©þãñØÛo³»w•?é™3•¯®[WOiþüóOîƒgmmòüùsÕnÞdnnY¼Pþ£Wçÿçê×ïéÁƒ5yk|:›Ž?§ðfÞ…¬°*G1—˜c¶°-5i‚&µÌnNËÃQ …Œ1îׯ¥¥%c,33€­­-cL$ppp`Œ={ö @‹-cOŸ>ЪU+ÆXRRÆØÃ‡¸»»3Æîß¿ÀËË‹1vïÞ=íÚµcŒÝ½{€¯¯/cìÖ­[:uêÄ»~ý:€.]º0Æ"##tïÞ1ößÿq¹Æ;þ<€ÀÀ@ÆØ¿ÿþ  _¿~Œ±3gÎ0`cìŸþ0hÐ ÆØ‰' <˜1öÇ bŒýöÛo†Î;r䀑#G2Æ~úé'cÆŒaŒýðÃÆÏ;pà€I“&1ÆöíÛ`Ê”)Œ±o¿ýÀôéÓc_ý5€Ù³g3ƾúê+sçÎeŒ…‡‡fŒ………X´hclòäÉ•ô:vìxë믕g??õ!—ãÊ:ìòeõj{ö(+ RÝÏ i z¨ÜãdiiùñÇ‹Åbµ:ú˜àFQ,`KÀAÄ}'LNÁ”|ä—¯¦ªGÃëxÌ„/®'ÈçóýýýU˾¾¾ ýýý;tèÀÈÈHcÙØØØßß¿]»vjeÿ¶mÛ055õ÷÷÷ññÑXööö`ff¦VöòòR”===…Bessswwwµ²………¢liiéïïïææ¦(»ººª•­­­ýýý]\\å6mÚ¨•mllüýýØÚÚª•[µjÀÎÎNQ¶··W+;99¨dðÑÅÅeîܹ>))ÊMåïoÙ[·¢kWå–íÛËÜ>X~Gš×C4 Q”³³³×®]ëêêºråÊŒŒ í5ª.”õ#ì>AÖÁ1ÓOaøÔð=ö^Ë«äWAí»áuÒïV•Çòð'šE6«ÍAHeeeY[[—ÿȹ¸¸ìÞ½»¨¨ˆ1ÆVvHöíÓ| ^½”u®\ÑPA.g66Ê:qqõø®ˆÞêÕ«WùO£P(\ºtizz:k4}pŽ|R¬S~\ú£Ï|ÙAÙ¾5û,“-+éצN×*¥­[·>þ\u —Ýqqq3fÌ066®Õ\U5š×#—ËKJJ0ÆŠŠŠŠŠŠ¸yyyyyy\9++‹|“Éd"‘H,J¥)))éé銋‹“’’RRR%$$ýå—_._¾ ))éÿûߥK—<|øpÿþý.\¿gÏn€.66öë¯¿Žˆˆ½}ûösçθ}ûvXXØÙ³gܸqcóæÍÜÀ]dddhhèéÓ§ü÷ߟ~ú)w-úüùó«V­âôÎ;·téÒ¿ÿþÀ©S§/^ü×_8qâÄüùó¹òï¿ÿþþûïså£GNŸ>ýäÉ“~úé§É“'s僎7Ž+ïÝ»wÔ¨Q\y÷îÝo¿ý6WÞ±cÇСC¹ã|ùå—ƒ âÊ[¶léß¿?׆õë×rm éÑ£Ç?ÿüóé§Ÿ–ÿH$’M›6¹ºº~ôÑGb±ÖW«­ò¡ÎõÁG²‘Ü—%¬äGö£O¦ÏKûã5è†×y¿[õÁµH­^¦ß­pïž²7bkËärÍÇziœ1¶f¢NÆ{ï™››s-RSSMMMÛ´iÃ{úô)ŸÏwvvfe/lpÙZõ QQQ¨Ý…W_}•UçÂÆ[o½ÅöÂÆ¶mÛ éÂÆgŸ}à£>bŒmÚ´ À²eËcëׯ°råJÆØš5k¬^½š1ÆÝ´fÍÆØªU«¬_¿ž1¶lÙ27ndŒ}ôÑG¶lÙÂ[¼x1€°°0ÆØ‚ „‡‡3ÆæÎ `ÇŽŒ±Ù³gصkclÆŒ¾ýö[ÆØÔ©SìÝ»—16iÒ$û÷ïgŒ?À¡C‡222x/‡íêêºmÛŸz×ù 0ƒ1£¬Gý¼ôçç!±»c÷í;8íà§ ;°CõÁ­ËËW´X±ñÁÆ÷Ýß@Pùa×bí&ɦ¼=yH‡ý4ûå®Ëgc6uº EÜÅÅeÅŠ“'O66.÷bµxm›W ¿v-77×ÔÔ”ûª°°ë_óx¼’’®ßÍãñø|>ŸÏÀçóMMM¹ú|>ßÜÜ\(044´±±±´´äÊŽŽŽ¶¶¶Œ[µjåèèÀÄÄÄÅÅ…ô755õôôlݺ533³víÚq„BaÇŽ=<<XXXtíÚ•»øaiiÙ³gOµµu`` waÆÎήÿþ;vààà0hÐ Í›7:th×®]´lÙrøðáݺuкuëQ£FõìÙ“ûn7Ž.pss›+·mÛöý÷ßçÊ:tæÊ;v\¼xqŸ>}tîÜyéÒ¥ÜöîÝ»¯ZµŠ+÷êÕëÓO?åŽÿÊ+¯„††rçíß¿ÿ–-[¸«…477çʃ¶··ïÞ½;€·Þz«uëÖFŒáå厗wß}×ÏÏ›=0a„nݺqïwÊ”):u0sæÌr±æÎûÖ[oq¨.\8zôhî{øÑGMš4‰»È´råÊY³fq>ýôÓàà`ww÷ÐÐP¦é‰‡‡ÇÇ<~üø;wøaaúv»aùPW냫zi¼*Ýðzíw«¢>¸¶ppÍýnUªw®YSaµªôÁ³³·¬Èù|Ijj~~>cL.—I¥R®–¼¢n>iìÒÒÒÌÌÔ× pssÛ³gâãѨÆÁ5âúãÑÖÑW>NãÝMıcÇ6mÚ¤ﮈê€õ®]ؽEE59ßÍ›˜>½t¹5€WR"ˆŽnÖ¬glllhXú·f%D“Æí³Ï>ËW™æââòÍ7ßÄÆÆN™2EññÐG5Ye­’_€§hRv7)“&MzIv£ìº<RR0kÜÝñå—e&aVîÒ% ‚.]ðóÏàó•Ûé)DEFFÆÎ¥‰äìì¼k×®¸¸¸éÓ§i·aµWóµê5æ¸E²EA8)»á”ÝD3Õuy|}qø0:uBr2-‚‹ BCQùèÓ§ñê«èÝ'N@ À‡â³Ï”¯R‚Ÿþ¹D"iÕªÕŽ;îß¿?kÖ¬—t/ôGmÿ|(ónÑ]L‡ø²x„ûˆIDážBºVI4P Ù^½0jFŽÄ‰ Å¥KX¹›7cÞ<,XPf/ÆpìBC ÖÖFp0ll‹E‹J«qózhÌ„b±ø×_ Ÿ1c†âúvUÔ~!ùP7@ê9þu,†ãïð¿ñ ö3µ“ÝrÈ·ad yNRå×åáñ0d† Á¿ÿbýzœ>õëñå—°´TÖœ0 àèˆÅ‹ñþûÊE5¹õz¸Gsëõxy5Ð{!:,++ëîÝ»z=Ø]‰š¢h:–ÁŒ‰±ŽùqÙ<9B|°áƒ§®Ox̤%‡pÈ[ì½lÝ2܆k[×;5©ªÊçòôë‡S§på Þz ùùPyŸgglÛ†G°dI™5‘i½¢‰»»{coÔm‚sxàÁS,Æbc4Üx—Ý>bŸ ¡v&¸ÍrÛ·jß-á­k©*Õuylm5w–»uñc¸u vvÊ«V!!óæ¡™¦>ÚRiìɯ¦”üˆCÄ! _'@·Yn«íWÇxÃÆò›ªÏåñõ…— B%÷¨&8õÁIõ=zdùÎ;ƒU·””ÔüjŠ¡!“É4ïn`ÀT?õ%%¼éÓktŠ5L‡Pvë%Õx­ñãPÊëÖ ¥7†sëõ¨³R©ŽQPÕ‘‰ ØíÛ‰'Þ«Ùß{ïõ?Žôöî +ë”PXºì¿ÿ:%'·?t¨LFÕìÎF=Ž9Ên=¦¶²Z]±°@ûö¸sx±^OÿþuvpÒØñx01)³¥_?Þ¯¿ÚÉk|̜㘘›#/ϬmÛÒ½ÅÇÛ b¨v®š©ûqð >Þ=Ãmߪ}qöq“1™â[¨ÎåáóÑ­[]œRHÝéÖ ‚ââZådBbcËl‰µéÝ»V Sг¼£~wc :—§mÛ:èèÑ»w—–)ÁI혙ÁÛ[~î\«V­$+$%™3¦y¤»U+ cÈÍ5nÞü*©Ô :Ú†+dd˜øúÖM õ&ø(»Õ`}ø;wbúôŽª‘HJ‡P84¯‡ÔÚ„ ¿üÒöúuͯFFº¸ä–ÿˆ%&šûú–…¼óçÛ•Ÿþ9iS}DmèAüQv76ª7¢äçcÎ|ñ֮Ř15OÛÂBì܉‘ž®ÜHózH­-^l°xq…£(¦¦lË– åÊçÌyýçŸMÜÝÔQTW@§ÇÁi¼»R›Ë³};ÚµCBÆŽE×®øûïj°¸»vÁË#=½{—X§R§¤R´i#oݺ„ûW\¬¹ÏÁëÓ§´Ž³³<:º¾ÚSa>ÁdÚ Jêw7ZjsyæÌÁìÙØ¿!!¸qo¼W_ņ –3.O&ÃÁƒX³@—.X»o¾‰µkKŸšàòeLž\?ï„4EŒáÙ3Þ®]ç[ 5Ü©²nÝÅä¡¡½Š‹ëkRº†@4‚zãÊÂ+Ž —º.‹¹/]p§Qv7råçòðù˜2cÇ⫯Šsçг'†ÇúõðñÑ|¹‡#$qqСÖ¬ÁÛo—ÂÐí(¤>Éå¼S§œ«^?+«³‹Ç4-;t§W¬þoïx ›©6K=ªãüX¾ü†ž?§y=¤®””`Æjï5}:š7¯‡Ö@Ó*k §Ø©žù=±X›x›Ml“„IªºöÏ=B2K®Je“d=2<°X ·t·}lŸ”I«x.¢O|}•kL>­¹Î³glî\flÌÖ¬kÙR¹K»v¥¶g“Vð!Q=Ë™3õ÷nѮʜS³¯b‚Sv7-ÙÙŒÏ/ V>ŸåäTV9!§XýRùÏɉíØÁ*Y~“•]sݺº}„莗'8§º9þÒ§ìnŠNR«Ÿ_•v¹y“Y[+÷Z°€åWa]ì={”» RËV“¦F nedÁ ¯¿þúæÍ›U«­X±bøðájû^¿~=00ÐÌÌL(úúú;vLã)âããAí›ZÕçT=Ç+IpÊî¦kÍe°ÎšUÕ½ª²V½š{÷”»ØÚ2Z¢žTŸZÈ~ÿý÷:uR|)—Ë]\\Ž9¢º‹T*mÞ¼ù×_]\\,“É®\¹òÿ÷U9xU/Á9UÉq NÙÝÔ ¬ Ö}ûªºW \.g66ʽââjÜdÒd©…lnn®™™Ytt4÷å… ¬¬¬ UwIJJ244”Édj‡ÊËË›9s¦­­­••ÕÔ©S \]]üää*]/Ô¨&3z`À¥f—NÍ9Õóãž™ÿd.]±Ô9Áy36sKkDssÈKÖå©[<”_Ò=…¤Ö„Bá°aÃ:Ä}yèСQ£F™”}À “““““Ó»ï¾ûûï¿§¥¥)¶Ï›7/???11ñÉ“'b±8$$äŸþ‰D"‘´lYÕö4¨qös*ê+úàÔï&¥TG66|8»v­J;V·ž“Ã6ndr¯Ù³kÙvÒ•èøóÏ?]]]cR©ÔÎÎ.""¢ü^‰‰‰³gÏöððàñx½{÷ŽÏÏÏ766‰D\…ÈÈHwwwmŽ¢”§šã–ñ–›Ø&.Á¿b_µÉhCÙMclï^e¤rw¤ðxlð`véÒKv¬z‚gf²2ã'Ü¿Žëð}&¢|ÈJ¥R‡‹/?~¼M›6òJ¯¯¤¥¥?¾OŸ>‰‰‰,_°°°°³³Ó­ç¨æ8îá ì&Jªwø-[Æ–.eææ¥_¾ö;{¶Â«’àéélùrfaQZ­_?öûïÊ;_zç"!åh ÙùóçÏ™3gìØ±Ë—/énݺecc#‘HLLLòËÞC• s Î9ÅNõ,ì‰`)ÚˆÛPv“RåçòˆÅlõjåÍ‚½{³“'5ìXy‚§¤°Å‹•c&o¼ÁΟ×pFš×CªIc‚_¹rÅÖÖVõ’¦*‘H´~ýúG1Ʋ²²fÏžýúë¯3Æ&Nœ8kÖ¬¬¬,ÆXrrò™3gÄb±AZZZ-Y÷ ÎéÈ:z2Ï$–TOÇ'z¦’¹<ÙÙlýzfo_új×®ì·ßÊÜÿWQ‚'%±9s˜©ié€Ì°a,2²ÌIi^©…Š:¼¼¼üýý5î’““3vìX''§fÍšY[[1âéÓ§Œ±¼¼¼yóæ988…B//¯mÛ¶1ÆæÍ›gaaaiiY›{Qê+ÁåLÎ+a%õt|¢g^:—G"aŸÎZ´PÖùé'VR˜¦gÓ¦•N»70`£G³[·4“æõÆ®¾žÎ€n?œ4œ—.m,`ñb<|ˆíÛáìŒÛ·1f Ú·ÇþýP}øZb"&NDÛ¶øî;Èå˜8ÑÑøé'øùi8¦ê‰¸õzi\4?›:6dNœ(-ïÛ÷’gvcÿ~l܈ÀÔ……¥/@.‡±1&OƲeps«ì8ŒÁÎNù8ò¸8Z¯‡42ÔG&õ¯ºsyŒ1}:bc±?Ú¶UÆ7##Ì›‡„ìÞý’øÀã•Y)‚æõF‡œÔ?µuyªØ64Äĉ¸{ÞÞÊ¿ý†mÛкuUO­6BHãB Nê_ùuyªÎÀ¶¶Ê/mlªwjZ¯‡4j”à¤þ©F§©)¤Ò†;µP¨ü…q÷.rsîÔ„Ô?JpRÿTüÈxzbûvÔïI¯\ÁÛo£W/å-(%%¸zµ~OJHâ'õ,'11¥e´k‡¤$ÌŸlØ€ììº?ãéÓxí5ôècÇЬ:tP¾D)¤q¡'õ,2%%¥åp÷.~û°nÑ IDAT Ý»#=+V M¬Xôô:8‘\^zä×_ÇÙ³°²ÂÊ•HLÄâÅÊ:”à¤q¡'õLm.‡aÃpù2ΜÁ€ÈÎÆ† puEp0?®á)d28__ ŽÈH4oŽ‘”„uë`oOózH#F Nê™ê(ªaÚ¿?NBd$†Ga!¶mƒ‡¦LAll5^P€¯¾‚§'&MBL \\°c>ÄÒ¥°°(­ãí­¼ƒE,F||-ß!ºƒœÔ§—Îå ÀÑ£¸s“&1ìÛ‡öí1r$®_É‘sr°iÜÜ0w.Ñ®öïG|<æÌA³fejÒ¼ÒxQ‚“úTŹ<íÚáûïKó×ÄGŽ kW „ˆ •E"|ü1Ú´Á²eHMUþ˜8†¬ØGózH#E NêSµæòpc •ŽüóúõCïÞxþ\Y', ..X·YYeÆa *ý$Ó¼ÒHQ‚“ú¤—U\򯄱ÌuÈK—pïžòÕDAA™k¡UÑ­›2âi^iDj˜àB¡P( '|aàÀ[¶lQ­¶råÊwÞyGmß7n¼òÊ+ÀÜÜÜÏÏï÷ßOHH …Õj·ËÇ›7o^³·@ÂK*[++Œ4tÛ[·ÆøñèÖ­G³°@ûö¥eš×C‘&¸D"‘H$·nÝ’&L˜ðÃ?(ê0Æ~øá‡ &¨î(“Ɇ 2a„¬¬¬¬¬¬o¿ýÖÚںƭwssKMM­ñî¤~©Îåáó«‘¹b1/†þ÷? 7ÿ=~ŒÑ£Ñ£ΫFch …4JµYBm¢ÜÜ\Õåã.\¸`eeUXX¨ºKRR’¡¡¡L&SÝèêê @ ‚äädÕê–322†*¼¼¼vîÜ)Ô‘‘1bÄ [[Û… J¥´>§V©®ËchÈÂÃYQÑKvÉËc¡¡ÌÒR}±ùŠþ½ù¦æÕyÔ\»ÆÚ·§õzHãS—ãàB¡pذa‡â¾Õ^ P–Õî69yþþ˜<IIšÛ1c€èhåFš×CÚÄù•@ÿüóOWWWƘT*µ³³‹ˆˆ(¿WbbâìÙ³=<Ÿ¯XûùäÉ“ÞÞÞµyw¤¶Vv{-b~~Ê50/SóèQæã£¡‹íêÊd={*·9ÂÆŒa<žzM¶x1ËÈP39™ÍšÅŒŒÀÌÌØ²eÌÚZY?.®¿„Ô‡:Np©TêààpñâÅãÇ·iÓF®ºâx9iiiãÇïÓ§OUüÑ£G¦¦¦Š:÷îÝSKðò¬¬¬jóîH­ÈåÌÆF™˜±±¬¤„íßÏ\]K·² Øùóe2Vü³³c_~Y:êR~¥ã«WÙk¯iØËÊŠ…†²”¶l33+½™5‹qk¿ù¦²æ¾}ÚüæRGêønBCCÃ1cÆ:tèСCãÆãUzÿ¯ƒƒÃ’%KbbbÔª1Ƥ¿x摽½½T*U|™Tî¯f;;»ââbÕ ŽŽŽuò¦HM”ŸËc`€‰‹­[áà€óçѧqéR™¬Z…°`Œ5¼kWœ>¿þB§Ne¶geaÅ ´j…QP€Ñ£]»À ÍѼÒèÔýýà&Løé§ŸŽ;¦v '###44411@vvöÎ;»tébmm]PP _'''@ðÛo¿…‡‡sAPPÐ’%K D"ѺuëÔŽ, ‡ ¢¨2vìØ:w¤ª*šËclŒwÞÁ AæàbÖ,ÄÇcíZåSM*1h®_ÇÁƒpu-³gwqÁرefÒí(¤Ñ©ûïÖ­›­­­··w»víÊ¿jbbr÷îÝ>}ú˜™™¹ººŠD¢½{÷ÚØØÌ™3ÇÓÓÓÊÊ*%%…Ï燇‡O›6ÍËË«W¯^Š}wïÞ-‰ìííÇ_þàß}÷]NNŽ£££O@@ÀŠ+êüÝ‘ªÒ8—çùs,] //8 ~=ÓÀãÇcíZ´hQ³`Ü8¬_õ—=ÂðáèÝ.”n¡y=¤ñÑö0i¤|}•ƒÎ§O³‚¶eK™‘qÅ¿îÝÙ›o2>ŸÌÜœ}ú)ËÉ)s¨òãà §O³€€Ò—<=Ù;ï0@Ã)Þz‹q7¹ª¶êÌ™†ûnR?hV=©jsyâãáí>RŽŒs|}qü8._ƉˆŠBPrsñÉ'ððÀ¶m(.®ìׯcà@ €«Wáä„Ý»ƒ#G™3Õo:üýwøùaútøù)7Ò@ i´ý+„4FªsyLM5tŠÙÞ½¬ìÄ.Æ»p*o%ù©¿dhˆiÓ°z5*ž¾[ÆñãX¾wïjx).®ÂG–¢hœÔ5µuyðxèß±±Ø´©Jñ ”¹yÜÈH¹}À€2·xWÅСˆŠÂ¦M(ÿüK 'zŽœÔµÇÕ¯X2†³gñÆ8p2Y5elŒà`té¢Ü²~}µ{Í11˜2+WB"Qé¥k¹¢Û(ÁI]kÓ—/#(H}ˆùÞ=Lš//ìÚ…¢¢j°òõw*qãFŽ„¯¯†ß­[#<›6ÕðÈ„èJpRºwÇï¿#* ï¾ >¿ÌKáý÷áæ†/¾@^^}5à Œ®]qäˆúÔ!OO|û-0¾úšÈ„èJpRoüüð¿ÿ!&S§–Ë’‚>P®xY‡þù}û"0'Oª?BÖ×?ü€{÷0mZ…O\!D¯P‚“zæå…ï¾CBæÍSïófdàãáâ‚+ðâ©85$—ã·ß€Aƒ4Ü>Ø­Ží[;VýoBô%8iÎÎØ¶ aɘ›—y);6ÀÕ âéÓjY&áCðóÃðá¸vMýÕ~ýpê®\Á[oѭߤñ¡' ÈÑ›6!) !!°±)óR~>¶n…»;fÌ@BB•ŽV\Œo¾&L(³C†àâEœ;WÕõì ÑC”à¤ÁY[ã“O”„-[мy™—Š‹ñí·ðñÁøñšçàpq?s&<(ó’FÂ8~*¶$¤Q¢9™D« ±g6oÖ°Ð%‡aðb.T®qæ ®\AXD"õúFF7Ë–ÁǧޛMˆn ':@*Å¡Cظqq^µ²RÞ¯bn®á¹Þ¦¦˜2K–ÀÅ¥^›Iˆ®¡':C.Ç/¿`ÃDEUu¡³fც·.!%8Ñ1ŒáÏ?ú’‡–X[cþ|ÃÖ¶¡ZFˆÎ¡'ºêÜ9¬_3gÔ·;:bÑ"¼ÿ~•ÖÒ$¤Q£'ºíʬ_ãÇÁZ·ÆGaútš O‡œèƒÔTüø#æÏ§•„¨¢'„}E3z!D_Q‚Bˆ¾¢'„}E N!úŠœÔJBBÇ …fff]»v½yófµö …>l®ö|« …B¡P(¸3rjÚpBJpR[@"‘H$’¡C‡Îš5«º»»¹¹¥¦¦V¥&w–[·n)Î()¿xqí×í ©W”à¤nŒ1âʳ^ÃÃÃAïÞ½¹b±8((H(z{{Ÿ>}/z⊽ÄbñÈ‘#---íìì-Z$«tm{•¿ùæ›qãÆJ¥`Íš5îß¿ïää ??Ö¬YvvvÖÖÖÓ¦M+,,äîääTƒß@„h%8©2™ìðáÃ:uRlñööŽŠŠÊÊÊòòòZ´h·qæÌ™ÖÖÖ"‘èÂ… (œiÓ¦™™™¥¦¦ÆÄÄ\ºtiÆ •œTcåÀÀÀóçϸqㆣ£ã… œ?>00À¼yóòóóŸ}úœ?þüùó}ûöõóó»yó&×OOO/..öðð°²²²²²0`@vv6333KKË:ùnÒ(ÁIÝ077ß²eKXX—‰YYY³gÏÞ·o_vvvDDc €½½½T*M±,}R¹uyìì슋‹U+(â¾¼J*FDDܼy³K—.‡‹Å¾¾¾vvv&&&Ïž=ËÊÊÊÊÊÊÎΕ_ë‡ýA NêLÇŽ;vìÈuË‹‹KJJlllŠ‹‹·nÝÊUAAAK–,)((‰DëÖ­S;‚P(2dˆ¢BHHÈØ±c+:]%•þùg##£W^ye×®]½zõ200£G^´h÷k&%%åìÙ³õò½ ¤AP‚“º4wîÜ;vÈår‡¥K—véÒÅÇÇÇ××WQa÷îÝ"‘ÈÞÞ>00püøñåðÝwßåää8::úøø¬X±¢’ÓUTÙßߟ1Ö§OR©”+صk—‘‘‘———¹¹ù«¯¾SgožGÏ&$„}E}pBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœBô%8!„è+Cm7€—))Az:22 A$*-äçÃÑöö°·‡]iA Ðv[ iP”àD'=x€Ó§ˆ¤¤Tu/¡Ý»£o_ €=ÀãÕg Ñ>cLÛm ä…çÏñãØ»W¯*7òùppPv´¹‚™ÒÒÊôÊE"äå)÷jÞ&`Ê´k×ðA NtC^BC†‚°¶Æo o_ôí oïªö¦³²pî""ð÷߈-ÝøúëØ¾^^õÕrB´‡œh›\Žýû±reéhÉk¯aÆ ¼ý6LLjuØ«W±w/~øÙÙ04ÄìÙ ­m4™Á fÁÚnƒvÌÆì¶h«íV4y/báB\»½z!, ݺÕåñÅb„„`×.Èd°±Á'Ÿàý÷adT—§ Zuò$nÝÒv#´ÁÛÇ`MôßIv’-JNfcÆ0ÌÙ™ýð“Ëëë\ÑÑlРҟ¼³3;w®¾NDÜôéÚŽ-ý1‚1Æ ðÀ G¸¶£4œØƒm·¢iûë/LœˆŒ X²~3³z<]»vøë/üù'>øqqèß~ˆÐPÒ½XÄàÁèØQÛh(÷ïãÈÅW Ì@Û¿GÔ`6˜úàZ#•²+˜ØàÁL"iг—”°-[ŸÏÖ»7{ò¤AÏNê×ÿö[m·£=ªìƒÓœLÒ€RR0`BCa`€qüxCÏÁ10À‡âüy8;ãâEøû㯿´„Ô)JpÒPNŸ†¿?""à䄳g±t©ÖfÜôì‰70d220dV®„L¦–R;”à¤þ•” $ƒ!=ƒáæMj¹I¶¶øãlÜ„†bÀ€jÌü$DgP‚“ú÷Ö[øôSðxX»'NÀÞ^Û ðxXºgÏ¢eKDDÀÇh»M„T%8©.€‰ <=a c¹–-á๹HHÐvk©ûïD%>òóñ;EEÚnÐ GŽ KDEÑC ‰ž¢'õ»bSS|õz÷ÖþxEq1,À¨QÈÎÆ¨QèÕKËí!¤F(ÁICyï=ü÷<=qý:ºtQ“ÐЈðpcûv>LS{ˆž¢' ¨S'\»VÚó9k×¢¤¤¡ÛðóÏðóCd$ÜÜpáæÎmèRw(ÁIò°ÀáÃØ¾&&X½nnøßÿÐ0ÈŒ‰Áo`ôhäæbøp\¿Ž®]⼄ÔJp¢ sçâÒ%´iƒÇ1núôAdd=žN,ÆüùèØÿ Û¶áèQXYÕã i”àDK:wÆÃ‡Ø»-ZàÒ%ôèÉ“‘œ\Çg‘J//lßóæ!) óæÕñYÑJp¢=xï=Ü¿+`b‚ýûѦ ¦NÅupð¬,„…¡}{,X€ÌL „[·°m-ò@Jp¢mB!֯ǽ{5 r9öîE—.èÔ Ÿ|‚³gQ\\C1†»w±cƃ­-/F|<¼½qü8þú‹Ì$ÝDEtƒ‹ Ft4¾ûàÖ­Ò•Wx¾ªGppÀ A4£FÁظ>ÛJˆöQ‚ÝÃã!(AA ‘àÉ“2m®ŸGÇ2½r“¶[OHá'ºM(DÛ¶hKkR¢]É$„}E NÑ9r¹\ÛMДà¤&ÒÓÓ/^üôéSm7„4NsæÌ ËÏÏ×vCt]µÿüó¼¼¼Ú0""bذaÓ§OOKKËÉÉ ;}út]µ¶ÎU=Íj>ŠÂçóÇŒ‹}êððp''§Y³f‰Åâ‘#GZZZÚÙÙ-Z´H&“‹ÅAAAB¡ÐÛÛ[ñ½S팫–³³³'Mšdmmmee5qâDnc~~þ¬Y³ìì쬭­§M›VXX¨vÞ¿RÎÎÎï½÷€ÂÂÂððpww÷E‹¥¦¦j»]¤‘øä“Ox<€´´´?üÐÍÍmË–-5Îñ%K–lÞ¼yôèÑÆÆÆ}úôùþûï”+EªØÙÙµiÓæ¿ÿþSd×®]ÎÎÎfffÍ›7 Ó_\aëÖ­®®®W¯^ýüóÏœ/_¾ÌU.e(—¢U|_5Op™Löã?úøø(Ú””””””´sçÎiÓ¦™™™¥¦¦ÆÄÄ\ºtiÆ fΜimm-‰.\¸ðÒ¿_fΜ)•J?~œ‘‘1÷ÅœçÍ›—ŸŸŸ˜˜øäɱX¢vÞ¿R3Ë—/722âÊ_~ù¥»»û|––¦Ý†‘FÀßßÿí·ßV|™žž¾dÉWW×Í›7K$’j*77÷êÕ«#GŽ,ÿ’ư*((ÈÎÎNKK›2eÊÒ¥K¹šb±xþüù¿þúk~~~llì€*:]AAANNNjjêôéÓßyç¼¼¼ÔÔÔ3f,[¶Œ« 1ÊPÃ4c0`¬ÊâããXZZZZZöîÝûÎ;ÜF—••ÅËÍÍåóùiii\ý“'Oz{{K$>ŸŸššªØ(¸¹‚jY"‘**sòóóE"÷edd¤»»»êy«n0 †Ÿ3NMM-**bŒeee‰D¢ââbÆXNNNff¦T*åZ’-“ɸH$’’’ÆXaaaAAW......–ËåŒ1™LÆUn:¦OŸ^þ3efföá‡*>ÌÆ†ìùs­¶´Ro¾Éö×_Ún)#**Šë†«±··ß¸qcnn.clút°o¿­ì8‰‰‰&&&å·k +.UòòòcwïÞµ¶¶æ^ÍÉÉ155=xð D"á¶hŒ/ÕÝ£££UeccÃ*ˆ2V6E+wô(؈Œ1VÃq𬬬¬¬¬ .tèÐAñŸÖÒÒ@FF†‘‘‘·þ7àââ’––&‰ŒŒŒ+9¾H$244TT椧§{xxXYYYYY 0 ;;[õ¼Õµiü¦æÍ›Ÿ;wÀèÑ£ííí#"" >ÜÆÆæüùó† biiyñâE …ÜßA¯¾új³fÍ®^½  wïÞÆÆÆ×¯_Э[7CCÛ7oèÔ©Çã®ôvìØÑÐÐðÞ½{üüüLLLîß¿À×××ÌÌìáÇ\ÙÜÜ<)) @‡¬¬¬’““´oßÞÖÖ–hß¾½ƒƒƒH$âÊ-Z´xþü9WnÕªUNN€víÚµiÓ†ûc³]»vnnnÜßhíÚµóôô”J¥\ÙÇLJ»a«]»víÛ· —Ë}}}ýýýÈd²N:uëÖ @QQQ—.]úôé    àÕW_ ‘Hzôè§è†+äççöÙgnnnK—.åZ«VìÝ;hР7nX²dÉ믿`ñâÅýû÷¿}û6€ààà~ýúݽ{Àœ9s^y啘˜3gÎìÓ§7¨8uêÔ^½zq?âI“&õèÑ#!!Àرc»uëÆý¸GÕµkWîÇ=|øðÎ;?yòÀСC;vìÈýèßxã ___îGÿÚk¯µoß>==À+¯¼Ò¶m[±X  W¯^ÞÞÞÜÇ ÀÓÓ“ûtêÔÉÝÝû´oßÞÕÕµ  €———³³37ÌêêêÚªU«’’­ZµjÙ²%ÆX‹-œœœH¥R‡V­Z(,,´³³kݺ5€¼¼<ggg999VVVmÚ´ðüùs îwFF†P(tuuššjffæææ 99ÙÔÔÔÃÃÀãÇ===<|øÏç{yy¸ÿ>Çóññ騱£Æ®®H$Z¶l™‹‹Ë† ¤Ò—÷ÇmllŠ‹‹sssÕ¶k +ffffffLLLCÒæææGýþûúöí{åÊ•ŠN§ØÝØØXõPEEE¨8ÊP£4«û9™vvvÅÅÅéééÜ÷%))ÉÑÑÑÞÞ^*•ªnä*s½`Ç}:ØÛÛËd2EeÅaMLLž={Ö¬Y3ÅFî?Fۘ͘·hÑÂÄÄ€•••ƒƒƒ±±1 [[[.•„B¡••W633377çóùLMMÍÌ̸²±±±‰‰‰CCCCCC®Ì{@IIIÉ‹åĤR©â3Áõåcòòò¸ßírss³³³¹rvvvff&W‹Åܯnééé\ùÙ³gÏŸ?çÊÉÉÉ999\9)))??Ÿ+?|ø°èÅ"ññññÜÅ \èຠ†††ärù­[·LMM¹ò7™LvíÚ5 ®|åÊkkkÃ&yyyÛ¶m344\ÿ²ŸÅ¿ÿþ»zõꨨ(CCþ}ûnÙ²…ûÞÀn$$üsýú‡~àÆgΜÉÌÌpóæÍÿý—Kɨ¨¨óçÏsÿånݺuéÒ%.1oݺÉeÄíÛ·¯_¿Î¥ç;w¢¢¢¸»)¢££ïܹÃ%ittô½{÷¸rLLÌýû÷¹ŸNll샸OH\\\bb"W¾ÿþÓ§O¹_À Ïž=ã~‚]>ÌÌÌäʉ‰‰ÙÙÙ\ùñãÇŠÖÓ§O¹äädîoMÏž=SÜ‚ššÊ}¶y<žH$2~ñx±X¬øß÷üùsÅG(;;[ÑSÎÍÍåê3Æòòò¸ €‚‚Åǯ¨¨ˆ{SŒ1©Tª8Ž\.çÚ ú‡U¼~S³fÍ,-- Ô;å™››üòË/S¦LQÝ®1¬*9Λo¾ùæ›oJ¥Ò­[·Ž?þìÙ³åãë¥4FY-T%Ó§ZµIDATEñ‡CEƒ‚‚&OžœŸŸŸžžÞ£GÆØÛo¿­ØØ§O®¾L&³´´­—ŸDEÞ|“×·o?uê”X,fŒ)œ1vóæÍsçÎq¿#£¢¢"""¸ß¯\šs¿/¹4çþ®¿}ûöåË—¹Ð¼sçNdd¤âïèk×®q¿S£££oܸÁ…é½{÷¢¢¢ c±±±·oßær!..îîÝ»ÜàÞýû÷cbb¸ÀMHHˆ‹‹ãÊ<à~³?bî#‘˜˜øèÑ#®üøñ㤤$îGÿäÉÅÇ#99999™û<{öìÙ³g\9---==+‹D"®£ —ËÅb1÷MËåÏŸ?ç¾ r¹<;;›{ãr¹\"‘poV.—çççsoP.—roJ.—sgŒÉd2Å ®Uª*EqrrÚ¾};÷«Ê( cìßÿµ³³;|øpQQQIIÉùóç'NœÈ4…•ƱÆXJJʉ'¸ÿ°»wïöððÐ_í®Z.e¬‚hÕHu¥^<==}øðáæææ666óçÏç>‚éééƒÞÞÞ;wîTÔÿþûï­­­·nÝªØøüùó±cÇr£í“&Mâ6æååÍ›7ÏÁÁA(zyymÛ¶M_¼±***âþ|Veaa±råJî¿}©J< à›o¾QÝ2gΜ÷ß¿¢O^^ÞÌ™3mmm­¬¬¦NÊeDµ*k@ãà:éwÞQûtµlÙ2<<\õçXÅgŒ]¼xqÀ€––– k×®dšÂª¢ÏÒ“'OzõêennnffÖ¥K—‹/2MñU•/e¬Á¼ ¯+»víRýßeiiùñÇs}Ø2*Npîp®7§áééYѧÊ”)&LÈÍÍÍÍÍ6lØÒ¥KYÅÿU4VÖ€\÷ܺuKµÞ²eË­[·–ÿ\õo4TœžMHj¨¨¨(44”+[YY-X°`Á‚ÖÖÖÕ:Hff¦‰‰ 7°® ¸Z[^AAÁ¡C‡’““¹{oW®\9vìØ7Ö¾2Ñ5kÖ¬aŒhÑ¢ÅÒ¥KgΜYGÇ %8©¡={ö<~üØÚÚzáÂ…ÁÁÁV5Zú»I ''G5ÄÓÓÓ+úM ¸ŽÏ}É3®x‡jU&:åÎ;¿þúkóæÍ—,Y2{ölÊîŠP‚“š(**Úµkך5k‚ƒƒkv7'ÇÂÂ" àðáê÷•ÿôÓOýû÷×xŸRE×ñ«U™è¾Ý»woÙ²eöìÙÜ­x¤"ôlBRb±øêÕ«üqm⛳iÓ¦eË–=z´¤¤¤  `ëÖ­?üðòeËœœœÁo¿ýVTTÎU£G^´hw?_JJÊÙ³gT«2Ñ}[·n]¼x1Å÷KQ‚“šhÙ²e]HôíÛ÷èÑ£[·nå·qãÆÿý×ÃÃÏ燇‡O›6ÍËË«W¯^Šú»ví222òòò277õÕW¹ 5ÕªLt7©‚TÝ‹Bê[•gÕß¹sÇÚÚzÿþý Ш2è^½ÕÄïE¡_tD‡tèÐáäÉ“OŸ>UÌß#„T‚®dÝÒ½{÷îÝ»k»„èêƒBˆ¾¢'„}E N!úŠœBô%8!„è+JpBÑW”à„¢¯(Á !D_Q‚Bˆ¾¢'„}E N!úŠœ4”?Dq±¶¡ÉÉ“¸xQÛ ¤&(ÁIýûì3˜˜à»ïл7=ÒvkTcÑ" ‚œ  •‹¢(ÁIý›2—.ÁÝ×®¡sgüú«¶HJÂ+¯àË/ad„ðpüñÌ͵Ý&Bª‡œ4ˆÎqý:FŒ@VFŒÀ¢EZQùãtîŒ+WàêŠ 0¾6CHMQ‚“†bi‰_~ÁÖ­02—_â•W”¤…fH¥X²Æ!3Æáúuh¡„ÔCrÈ=á©í–4œ¤h» MXp0zöĘ1¸r;#43f ÁEŒÅ„ ¸~FFظ‹Çk S“ú´y3öï×v#JF†²\ºFO´ÓÒàæMŒ?ÿÄìÙøê+„…¡ÿú=ir2V¬À` ­[ãèQtíZ¿g$ èþ}Ü¿¯íFhï{ í6hGs47ƒ™¶[Ñ´=Š%Kðà¼ý6¶l‡GÝŸ¥ ŸŽ‘—SS,^ŒåË!Öý‰ˆ6$$ 5UÛÐ;;øø€ÇÓvKHVT„/¿Dh(rr`d„… ñÑG°·¯›ƒ3†_~Ap0RSÁãaäHlÞ —º98!:€œè€´4¬\‰½{!—ÃÈAA˜9Ö|úöm8€ï¿‡H]º , uØdBt%8ÑOŸâã±?är06FŸ>èÛ^^pr‚ìíak«ë¹¹‰‘‘))8{ý…¬¬ÒWmm±d >úˆ®X’F‰œè±{÷âÈ\¾¬áU¯4Ê…B¤¤ %¥4îÕ´háÃñÞ{t§ iÜ(Á‰®ÊËéS8s))Ê^¶X µO¬¹9ìíKc½yst놾}áí­¥FÒ (Á‰^a¬4Ê%´l‰–-î^rBtÏÿª«Sÿ#VæIEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/syslog_parsing.rst0000644000000000000000000000013215114522477022736 xustar0030 mtime=1764926783.034631833 30 atime=1764926784.236661338 30 ctime=1764935922.869571773 rsyslog-8.2512.0/doc/source/whitepapers/syslog_parsing.rst0000664000175000017500000003430215114522477022404 0ustar00rgerrgersyslog parsing in rsyslog ========================= *Written by* `Rainer Gerhards `_, `Großrinderfeld `_ *(2008-09-23)* **We regularly receive messages asking why** `rsyslog `_ **parses this or that message incorrectly.** Of course, it turns out that rsyslog does the right thing, but the message sender does not. And also of course, this is not even of the slightest help to the end user experiencing the problem ;). So I thought I write this paper. It describes the problem source and shows potential solutions (aha!). Syslog Standardization ---------------------- The syslog protocol has not been standardized until relatively recently. The first document "smelling" a bit like a standard is :rfc:`3164`, which dates back to August 2001. The problem is that this document is no real standard. It has assigned "informational" status by the `IETF `_ which means it provides some hopefully useful information but does not demand anything. It is impossible to "comply" to an informational document. This, of course, doesn't stop marketing guys from telling they comply to RFC3164 and it also does not stop some techs to tell you "this and that does not comply to RFC3164, so it is 's fault". Then, there is :rfc:`3195`, which is a real standard. In it's section 3 it makes (a somewhat questionable) reference to (informational) RFC 3164 which may be interpreted in a way that RFC3195 standardizes the format laid out in RFC 3164 by virtue of referencing them. So RFC3195 seems to extend its standardization domain to the concepts laid out in RFC 3164 (which is why I tend to find that reference questionable). In that sense, RFC3195 standardizes the format informationally described in RFC3164, Section 4. But it demands it only for the scope of RFC3195, which is syslog over BEEP - and NOT syslog over UDP. So one may argue whether or not the RFC3164 format could be considered a standard for any non-BEEP (including UDP) syslog, too. In the strict view I tend to have, it does not. Referring to the RFC3195 context usually does not help, because there are virtually no RFC3195 implementations available (at this time, I would consider this RFC a failure). Now let's for a short moment assume that RFC3195 would somehow be able to demand RFC3164 format for non-BEEP syslog. So we could use RFC3164 format as a standard. But does that really help? Let's cite RFC 3164, right at the beginning of section 4 (actually, this is the first sentence): :: The payload of any IP packet that has a UDP destination port of 514 MUST be treated as a syslog message. Think a bit about it: this means that whatever is send to port 514 must be considered a valid syslog message. No format at all is demanded. So if "this is junk" is sent to UDP port 514 - voila, we have a valid message (interestingly, it is no longer a syslog message if it is sent to port 515 ;)). You may now argue that I am overdoing. So let's cite RFC 3164, Section 5.4, Example 2: Example 2 Use the BFG! While this is a valid message, it has extraordinarily little useful information. As you can see, RFC3164 explicitly states that no format at all is required. Now a side-note is due: all of this does not mean that the RFC3164 authors did not know what they were doing. No, right the contrary is true: RFC3164 mission is to describe what has been seen in practice as syslog messages and the conclusion is quite right that there is no common understanding on the message format. This is also the reason why RFC3164 is an informational document: it provides useful information, but does not precisely specify anything. After all of this bashing, I now have to admit that RFC3164 has some format recommendations laid out in section 4. The format described has quite some value in it and implementers recently try to follow it. This format is usually meant when someone tells you that a software is "RFC3164 compliant" or expects "RFC3164 compliant messages". I also have to admit that rsyslog also uses this format and, in the sense outlined here, expects messages received to be "RFC3164 compliant" (knowingly that such a beast does not exist - I am simply lying here ;)). Please note that there is some relief of the situation in reach. There is a new normative syslog RFC series upcoming, and it specifies a standard message format. At the time of this writing, the main documents are sitting in the RFC editor queue waiting for a transport mapping to be completed. I personally expect them to be assigned RFC numbers in 2009. Update: the numbers are now assigned and the base RFC is :rfc:`5424`. Practical Format Requirements ----------------------------- From a practical point of view, the message format expected (and generated by default in legacy mode) is: :: TIMESTAMP SP HOST SP TAG MSG(Freetext) SP is the ASCII "space" character and the definition of the rest of the fields can be taken from RFC3164. Please note that there also is a lot of confusion on what syntax and semantics the TAG actually has. This format is called "legacy syslog" because it is not well specified (as you know by now) and has been "inherited from the real world". Rsyslog offers two parsers: one for the upcoming RFC series and one for legacy format. We concentrate on the later. That parser applies some logic to detect missing hostnames, is able to handle various ways the TIMESTAMP is typically malformed. In short it applies a lot of guesswork in trying to figure out what a message really means. I am sure the guessing algorithm can be improved, and I am always trying that when I see new malformed messages (and there is an ample set of them...). However, this finds its limits where it is not possible to differentiate between two entities which could be either. For example, look at this message: :: <144>Tue Sep 23 11:40:01 taghost sample message Does it contain a hostname? Maybe. The value "taghost" is a valid hostname. Of course, it is also a valid tag. If it is a hostname, the tag's value is "sample" and the msg value is "message". Or is the hostname missing, the tag is "taghost" and msg is "sample message"? As a human, I tend to say the later interpretation is correct. But that's hard to tell the message parser (and, no, I do not intend to apply artificial intelligence just to guess what the hostname value is...). One approach is to configure the parser so that it never expects hostnames. This becomes problematic if you receive messages from multiple devices. Over time, I may implement parser conditionals, but this is not yet available and I am not really sure if it is needed complexity... Things like this, happen. Even more scary formats happen in practice. Even from mainstream vendors. For example, I was just asked about this message (which, btw, finally made me write this article here): :: "<130> [ERROR] iapp_socket_task.c 399: iappSocketTask: iappRecvPkt returned error" If you compare it with the format RFC3164 "suggests", you'll quickly notice that the message is "a bit" malformed. Actually, even my human intelligence is not sufficient to guess if there is a TAG or not (is "[ERROR]" a tag or part of the message). I may not be the smartest guy, but don't expect me to program a parser that is smarter than me. To the best of my knowledge, these vendor's device's syslog format can be configured, so it would probably be a good idea to include a (sufficiently well-formed) timestamp, the sending hostname and (maybe?) a tag to make this message well parsable. I will also once again take this sample and see if we can apply some guesswork. For example, "[" can not be part of a well-formed TIMESTAMP, so logic can conclude there is not TIMESTAMP. Also, "[" can not be used inside a valid hostname, so logic can conclude that the message contains no hostname. Even if I implement this logic (which I will probably do), this is a partial solution: it is impossible to guess if there is a tag or not (honestly!). And, even worse, it is a solution only for those set of messages that can be handled by the logic described. Now consider this hypothetical message: :: "<130> [ERROR] host.example.net 2008-09-23 11-40-22 PST iapp_socket_task.c 399: iappSocketTask: iappRecvPkt returned error" Obviously, it requires additional guesswork. If we iterate over all the cases, we can very quickly see that it is impossible to guess everything correct. In the example above we can not even surely tell if PST should be a timezone or some other message property. A potential solution is to generate a parser-table based parser, but this requires considerable effort and also has quite some runtime overhead. I try to avoid this for now (but I may do it, especially if someone sponsors this work ;)). Side-note: if you want to be a bit scared about potential formats, you may want to have a look at my paper "`On the Nature of Syslog Data `_\ ". Work-Around ----------- **The number one work-around is to configure your devices so that they emit (sufficiently) well-formed messages.** You should by now know what these look like. If that cure is not available, there are some things you can do in rsyslog to handle the situation. First of all, be sure to read about :doc:`rsyslog.conf format <../configuration/basic_structure>` and the :doc:`property replacer <../configuration/property_replacer>` specifically. You need to understand that everything is configured in rsyslog. And that the message is parsed into properties. There are also properties available which do not stem back directly to parsing. Most importantly, %fromhost% property holds the name of the system rsyslog received the message from. In non-relay cases, this can be used instead of hostname. In relay cases, there is no cure other than to either fix the original sender or at least one of the relays in front of the rsyslog instance in question. Similarly, you can use %timegenerated% instead of %timereported%. Timegenerated is the time the message hit rsyslog for the first time. For non-relayed, locally connected peers, Timegenerated should be a very close approximation of the actual time a message was formed at the sender (depending, of course, on potential internal queueing inside the sender). Also, you may use the %rawmsg% property together with the several extraction modes the property replacer supports. Rawmsg contains the message as it is received from the remote peer. In a sense, you can implement a post-parser with this method. To use these properties, you need to define your own templates and assign them. Details can be found in the above-quoted documentation. Just let's do a quick example. Let's say you have the horrible message shown above and can not fix the sending device for some good reason. In rsyslog.conf, you used to say: :: *.* /var/log/somefile Of course, things do not work out well with that ill-formed message. So you decide to dump the rawmsg to the file and pull the remote host and time of message generation from rsyslog's internal properties (which, btw, is clever, because otherwise there is no indication of these two properties...). So you need to define a template for that and make sure the template is used with your file logging action. This is how it may look: :: $template, MalformedMsgFormater,"%timegenerated% %fromhost% %rawmsg:::drop-last-lf%\n" *.* /var/log/somefile;MalformedMsgFormatter This will make your log much nicer, but not look perfect. Experiment a bit with the available properties and replacer extraction options to fine-tune it to your needs. The Ultimate Solution... ------------------------ Is available with rsyslog 5.3.4 and above. Here, we can define so-called custom parsers. These are plugin modules, written in C and adapted to a specific message format need. The big plus of custom parsers is that they offer excellent performance and unlimited possibilities - far better than any work-around could do. Custom parsers can be `bound to specific rule sets `_ (and thus listening) ports with relative ease. The only con is that they must be written. However, if you are lucky, a parser for your device may already exist. If not, you can opt to write it yourself, what is not too hard if you know some C. Alternatively, Adiscon can program one for you as part of the `rsyslog professional services offering `_. In any case, you should seriously consider custom parsers as an alternative if you can not reconfigure your device to send decent message format. Wrap-Up ------- Syslog message format is not sufficiently standardized. There exists a weak "standard" format, which is used by a good number of implementations. However, there exist many others, including mainstream vendor implementations, which have a (sometimes horribly) different format. Rsyslog tries to deal with anomalies but can not guess right in all instances. If possible, the sender should be configured to submit well-formed messages. If that is not possible, you can work around these issues with rsyslog's property replacer and template system. Or you can use a suitable message parser or write one for your needs. I hope this is a useful guide. You may also have a look at the `rsyslog troubleshooting guide `_ for further help and places where to ask questions. .. _concept-model-whitepapers-syslog_parsing: Conceptual model ---------------- - Legacy syslog message format is underspecified; parsers must tolerate malformed inputs and often rely on heuristics. - RFC3164 provides only informational guidance, so vendors emit divergent formats that can blur hostname, tag, and message boundaries. - Parser ambiguity arises when tokens can represent multiple fields; without clear delimiters, deterministic recovery is impossible. - rsyslog exposes internal properties (e.g., fromhost, timegenerated, rawmsg) to rebuild structured output when parsing fails. - Custom C parsers can be bound per ruleset to normalize proprietary formats efficiently, avoiding heavy regex-based workarounds. - The safest path is to configure senders to emit well-formed messages, reducing guesswork and preserving semantic fidelity. rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue_rsyslog2.png0000644000000000000000000000013215055603742024170 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.539822889 30 ctime=1764935922.855571559 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue_rsyslog2.png0000664000175000017500000003007615055603742023642 0ustar00rgerrger‰PNG  IHDR¬‘ŒÃåsBITÛáOà pHYsêe¤ IDATxœíy|MÇÿÿŸ7»ÄNľ´µ+JJQŠ.TQÔR>­òAµ¥Õ6EjK• ÔRµt±´µ´”úص>%Uj_b$„”D‰¬w~œþòäÞÜsï™›Ìó‘‡ÇuîÜ÷¼ÎÌœó:3gΓ; …Bd}°ößÿÐIóU²‹B¾JvQÈ׉d?ú裧OŸæÜNž<Ù¶m[ÝU* Ã1™LÖþ[€ŸÈðsk;£l{ä[¹r凶7ŸgžyÆIwOÉ. ù*Ùþ¹BQ0Lê_¡P(Ùq±w'99‰Ie?¶’Iæw|w{F ± 3æ}ì3Z…B¡È ;à Nô¦wš4¢‘ Õ±-8)¤,fq=êmg{1Š-§€d’¹ŠUòh:éFkQ(ya—¡¤œ˜Â”lˆÇxì$']ìß5)”Ä¿˜Ås™CŒç9_êF‹²3æïøn SÂkC›0Z‘B¡È 7}Ãää¦l`CÖØQAÊ ÀMnÎcÞB&’¨mÉH§s3æu¬›Ìä0´-“™l¬$…B‘/ºõ²,Ð\Á—GxDu,!û=˜+\™Íì¬H%Õ„I L˜¼ñ¾Â•ò”7P¤U˜1o`Ãd&Ÿå¬ .fÌ&L-iù-Má8"û߃[rÛhUbÁÚ£U‚yTœÆpžóñÑ6˜1çøª4¥½ðÊj"Ù›‹ã?. ÏY<Â#ç9ÿ`I6¢Qg:W¤b*T Â³<+Ý ABÉÉÂ»ØÆR»'3ù4§5KÈJ2œáõ©ÑG…ý"8`{GpDÃSXÏ5®U¡J t0†xâ?ã³9̉'^»ÂÍúêQ­AÿË,Û-h§øìàL3È0cÞÊÖ8âr”dŽÿºãþO´¥m/ð‚#îígfrè×®qíׯÿ߇»wIJ"9™ôn) ÔrÜÚL2í.ɘ0eýåøoÞÛ-ßh¿Ä*‚Š`a„ºÔuËó>‚nCIÚƒ .¨p™ËÎ;‘Æ≟Íì9ÌI&YÛâ‚K-jàÀmnGy–³ÿã»ÙK,PjÃö:¯ç} `5áá9Âñãœ8Áñã\½Jö¦b2áïOõêx{ÿß_ñâx{óÜs—Ÿ¬<ƒ_óuÙCN`Â~Tä±QÏT(œg%Å?Ÿù!„įm™Ç¼·y[Ç,Š7¹9éKX’5¹ó~x™—³§¹ÌåìœÆ´(¢L˜úÓÿ3>³é>DRûöñßÿ²};.ü³ÑË‹æÍiܘÆñ÷§Jüü¨PS>§Ñpƒ ^Éʬ]¨D¥+\É]T(’"ì@¼ˆŸ*¦–¥T•’E²=r) \—‹Á.ÂA3Ñì¡i̼[ìî%z!ðÞÓÄ´‘b]6iiâÛoEÏžÂÅE€Ñ°¡ 6ˆ „ÙlË.„‹ð‹» wæ‰y¶DS(À.Æ ¡ÙCQF lä¤8ÙCô@°]lÏ#Y¨}\<ŽÀWø†ŠP‹BŸ=+ÆŽeË %KŠ—_Ë–‰èh}tg#BDŒ£<„GeQY]((’c÷µ’’Hú–oG0B àÚÈìdgÞϘ1/eé&¤’ºŒe˜kÒsç7ŽmÛZµbøpú÷§xq½UßGQ3™ùd¤]3R(¶ Ñ+„„Öî¹øLejΉ­áá²v-&¯¾ÊĉԪåHyÉ${ãíÈ …U(c(œÄÛ—¾»Ù=€«XõOw-3“™3 "#ƒþý™1ƒ5 ªP(äCç%1’P†2;ÙÙ~kXS“šÓ˜FX}ûrâíÚBË–FkT(’"ÙÓ³úѵk×Ö­[3f̨Zµêßÿ½oß¾ÚµkoÛ¶-99¹AƒÁÁÁÀ€Ì›7¯mÛ¶IIIû÷ïïÔ©Shhh||üóÏ?¿råJà­·Þ –/_>hРŒŒŒÐÐÐaÆ={6..nôèÑ¿üò 0mÚ´%K–ëׯŸ#„8yòäùóç…aaaBDFFîÚµ+!!!>>~ëÖ­—/_ÖGbF†4(º¥îºù™«ÄŠX}Â*ŒãÌ™3ÀÌ™3…åË—þùç…½{÷öññBÌŸ?8vìØÉ“'ýüüV®\)„ BLžýôÓ×^{M±sçÎáÇGDDDEE?þ÷ßBÌœ9ó§Ÿ~BlÞ¼Yûá©S§Ö®]›`ØnÛõ9…ÁddˆAƒˆÁƒ7f®GðŠxÅhM [ÑÏž=+„X±b…vNY³fÍĉ…Û·oâ£tÒæçºÔý…_¼ðZÄ¢?ù¨Mí&4iHçyº! Ÿà  ÍZÑ (KÙºÔõÄÓ|Üq7c¾Ç=í”EÔE.—¹¼›Ýd\çújVG‘Jê"íg?ð_-g9°•­òaiŽÛù={˜2…¶mYµ —ªØïéL¿ÆµùÌwœ…Bá„¶¡¤“œœËܬXÂ’‘ŒÜÅ®f4 !d ã±xâKQÊ®îqÏ„É ¯;ÜI'½<åos;–ØÚÔvЫunÜ Y3228z”ªU³“IfSš^ãÚ%.Îѳ"I9–W(l¤ÃMn®fõ8Æ}ÌÇóñÎøâ{‘‹­i튫ÑêKÇŽüö[·Ò­Ûƒ_nfó‹¼øþó Ÿ8^š¢ÜàFa—¸¤ýE•@BII$%“\ŒbfÌ·¸••þÁ·M”§|Qî‚ór‚W¹zžóYn¸Ýå®ýrÏø L°_| qzcˆ#Îß×xí+¾ºÄ¥â/A‰¢»Ïš5 Èøñ|úinIšÓü—®q-ï—¾* äö±Oû»Îõ¬í&Lõ©_œâY¨à‰g"‰}¿¦öW‚KXbàî8a„ýÆoÚ_YÛ«Rµ>õÝq÷ÀÃ~¹÷£ßØ/¾…8·1¬d囼yžóIdÚ­ÈPîÝã‘GÈÈ ,Œ¹žôײv³øßüÛ‘êùr•«_ðÅ*VE ¸àÒšÖmi[—ºu¨S›ÚU©ª‹ìÄ9έbÕjV‡¸âÚ‚OñÔc<Ö”¦ i˜÷»0 N¹«dLfrAu©Û….fÌþøW¥jþ¿,ÜÌKD+Väá @ozW¤¢2yˆõ¬_ÈÂßøM Òpƒ:Ðá)žRo»³7é¤É—ËYþ¾øŽg|g:·§½6½ˆbèSä[ñ-‚…b¡ÑBd":ZøøˆfÍDff¾iE ‚ýB=k0fa^+ÖÖµ”%‡‹áˆ?ŒUT¸#îhoÓ^4ùŽxçOñ§Ñ¢dÁ™Œ!CdLÓ?›…y®˜k6½r²°ñþûÄîÝ–¤Ñ®Âu¨joQŠ<Ø/ö7͵7î­+2D†ÑŠŠ "#D„Å<"Ù$6­H:rÞc8uêÔêÕ«Mù½ç=‹Ò¥K¿ÿþûVõQ‚ƒƒïÞµâ¶þàÁƒyäà&7Ѩ m6±)ô{÷îݽ{wÞ1³ï`ݺu_}õUËõ$''kKh刓cÇŽõõµbzèºuëN:eyú¶-Z<óÚkT«Æ‘#–¤¿zõj{ÚÇTˆyoö{.™yM¢ÕvÐÍÍM[\Ör–,YróæÍqò {÷îÍš5³<þ‘#G´m-¤råÊÆ ³<=0}útañ8“É4tèP???K§‘ö>ïÏg¾{ºû“¡O¶ mç‘æ‘'·_5lذGênß¾½téRËÓãÆóô´büdíÚµÚ*~Ò¡CmÍc 9þü?þøÐ¯ZP>>>#GæórÀøÿ:Ïù¦4ÈÄèEÑÉIV¬cúÒK/Õ©SÇòôüý÷ß-O_³fÍÞ½{[ž>%%eáÂ…y$x° ^{íµÒ¥Kç7‡Q¬_¿ÞrM@µjÕ¬õ¢Š+Z•ÅæÍ›cEì›âÍL‘yE\É·£0eÊ«âkëaYέ[·òz?—.]²*‹~ýúYM·nIJeÆÿí·ßxt¶(¾———Uú…5²j–/_nU|myZËiÞ¼¹µ»àêjÝDçƒZö’¸ÔR´DPáj*[ðàÁVé?wîœUúøøx«²èÔ©“Uñƒƒƒ­Š¿aëâûûûç-Y$ã\„‹ðY)VjµuO-G[~Êr¦NjUü®]»ZÿöíÛVÅ.^¼˜oØœ=†””mý^ qqq©P¡‚U²nÞ¼™÷âÀ9$•)Sf¦×ÌùøþhIþ/HLLLLL|h¨‡âååU¶lÙ|“ea6›¯_¿žºlTªTÉÍÍŠûü·oß¶d5ö¬½óëÝÛõÒ%¢¢ð¶hžnjjêÑÛGª ¼;pzìtò+(“ÉT­Z5K"gqýúõ´4+ö.W®\‰<ï™ç 11Ñr‡BxzzZx9ŸÅåË—*·ô~~~^^ùÜ+ÞÉÎôÈ$s:Ó‡Þ'Þr=>>>V]T¥¥¥Yu9Ô®]ÛÅÅŠÇ0£¢¢rk¨-¨òåË—)SÆòø‰‰‰V­>íææ–Ûåüu®w¡ËiNw¡Ë—|YÚó… 222,Ï¢jÕª>>>–§¿uëVLLL rT‰%ªW¯nyüÌÌLí À’sF½zõ´—äìÓUà /A‰2”ÙÅ®.t1ZŽ”?NÓ¦ŒËœ9Vý®­¢ˆŠ"ÊAdy¶°¥}ÊRv;ÛÒÐh9Eˆœxžç¯sý3>{õJ’ü‘úŒ íi_›Ú™d*WÈ•U«F²öwÝéMôiNë/Iñ[ÙÚ‡>¨ð¿)Wp$¿òk[ÚÞáÎf6+W°yŸcÈ$Ó×Íl>ÃwÜ–#1[¶P¿>ÖÜÓhMkà‡aÝý…µüʯ=éY™Ê{Ù[›ÚFË)B„ú,Ï–¢ÔÏüÜ‚FËqäí1ô¢×$&5¡É+¼b´‰¹x‘sçxþùü´%-M˜qHwQŠìDÙ›Þå(÷'*Wp$—¸ÔƒžxîcŸr«´ÇHbQEwÉ#ËÙ²à… ðÓÒ”®O}e v%ôþô¿Ã]쪈uóñ¶p›ÛÏó|<ñÛÙ^ŸúFËq2dì1\áŠ;îG8ò5_­Ez¶l¡tiÚ¶-د[Ñê§’±b·Â* <À ‚:ÐÁh-E‹þô?Ïùå,ױ䓓 Áš§°œéŒA zÓ»2•3Ȱë*†…´4öï§KÜ x¦­2ÈÐV‰QèÎŽÌfvg:ȇFk)Z|Í×»Øõ&obŽa½½‰Œ¤zu¦O'!AÇÀÒ!1˜0…2•©Ej-Ãräii<ùdho¬S£Iö@ Æ0Æ ¯å,W‚I4Ñc[‹ZÁëü?ÿ!9™>*äö W{#.˜àö´W³Ê,âða€¿«Ö„&žx*c°?ðÃAŽc\Ö³T Ç0ŠQw¸³ŒeÅ)®{ðÊ•1àÎìaÚ´Bhr=à6žñ³™}˜Ãó¸ÑZœ!CX³†øx x~(­iCÌeò”¯¢À¤ò(¦ržó>Xñ ¬ÂFpàIžư/ùÒNYDGS³&©©&BPº4ï¾Ë[oQ²¤òt4ù÷ßò×ÿ‚~hZ7š]ÓÃZ}óèÁ×seoØh €àÍ Ì.n/·%ìá!oï²à¥ßôJ¨wJ«6ÚÁ©++²ë²“o½ÑpÁþۆˣJZ:ª:ûY×Äf¿6}ù‚ÇMû©ŠŒ$û:…ÏòÇß¶µk ¦}Äú>Ì}Cr3‡. ™Ûªš¹%.ÁÝ•aߺ ɪËÃfߘéÙ’.l¹vÔuWWÛU¸ÑpÙ7Þž¹Èåvù˜YCþN“HU¡Òì`|«¾ß¼wÞÿž=U=t±7³™ŒŒ‡åtäßcHN&=ýþߨ¡FM ~Þ¾ý2.KûÆÞyÞ|õáàAøüsF¶%Ìÿø_;Ú-e鼡—´"ÎA0 ö¸ù©Èƒgyv/{/pÁûåró&5jšŠÿôJ–dìXÞy‡|W³vòï1Ø0|mÅ)™DÒ-·[Þj.’…hkZ¿Füð®aÅ–мYÄ"W\G0Âh!E‹«\ÝÁŽ! ±«+³f‘’òÏç%;–±c %hH1+)•ÔÁ ¾ÎuõÞf+¨YÓÆ0U¨b¤ŒA/’I^Ǻçx®5ŒÖR´XÅ*3æ¡ µk.7o²h€“&qõ*\Ø\I–Ä8ÀU¬êD§ZÔ2Z‹ópå ..X³tûCñij<壈ÒE”b+[SIí‡u¯ZRØÎ7|S“šíhg×\fÍÂÃñãyç¬y+£“!…1t¤c<ñj Uë¸r…Ê•±æEŒ¹á‡Ÿê1èŶ¸âÚnF )Z„zžó™hÂ~·õ¸w²e¹z•R¥ì—‰?”EÔ4¦%’XŒbFkq*ÂÃmGÒPÆ fÌÛØÖ†6e±â€ ÛÙÈF` íšK±b|ðAáwd0†ÿò߉L<Å)£…8™™DDP£†.Áüð‹%ö÷òOªÈ“?øãoþ~‚,v«°…=ì©A µŠª^o ¯óúŸü©Öž´Ž„22°òmÛ¹¡ÝóWÛÙË^@#9˜Xbr´ŒRx0ØÒI&¸µ<Ña¬¼‘”ºM%V3VõâG¼ñVoît0{ÙkÆü4O-¤ð`°1ìdg ëYo¬ ç#9t651Évþâ¯&4qÅÕh!E‹=ì1aRÆ #ÏJz†g~áµdžÕhÆP\ŸÅ#UAns;œpuƒÁñáHmjW¢’ÑB ÷r°#+ ÏXyBס$m MqºD+²áМæF )Z˜1Ÿæ´¾Ó#A zÒ³½ Ôà¬èÚcð H!%ß”Š<8ÉI )MR´'ü.wÑÈh!… #‡’2É !Ä—Âûø ýеǠŒA"ˆj¢ÏÃ% Ñfº«ƒ¾i I$ý‹(À‰Ñõæ³'ž&L©¤ê­ÈADIJ–¦Ð­›#7ZGMƒ¾i ³˜Lð5®9Ý]#³ÙœiOúöí[¬XžÏë:”dÂ䉧å=†›7o†„„è’µóòÔSO½ðÂ}÷™#‰´÷ºžŠ‰$¨MmäµcÇŽyóæÕ©SÇÃÃC< à¡Û-ùÖÞ?Ï‘à½÷ÞëÕ+×a|7mogÍš¥o &$$+VìçŸöñÉõ½†MiÚƒ©¨oÖy „hÞ¼yZZZ¹råò8/gddäý­½u>óÌ3ùƒ®CI€UưsçNÝŒÓqæÌ™ÆAD þþmINN~çw|}}[´haÓŠ#^®\¹%K–<þøã?ýôS¾;Gœ7ÞŽyê÷ßß¶m›íqLÙÈñß±1Anߦ¦æ5Bàܹsçܹs¶ïmvnݺ•‡1ô¡Oúè›o¾;v¬D‰©©©®÷ãááájÜÜܬJ¿xñâŸ~úiÔ¨Q÷éÎÈÀ-[÷îÁ¡$³—‚O%ðÂËrc¸{÷.°}ûöæÍ‹è œ—^zéäɓٷ¤r‹[Õ¨f”¤´´´/¿´×[ŽL½zõÒÒÒ,¼‹%¶ eòM¶dÉ’°°°¹sçÚ¬ŽãÇW­ZÕ–·íìзoß¾}ûêwÚ´i'Ny¾®#˜Îô¼C]¹r¥X±b•*é0ܤUIŸ>}V®\i{4;ñÒK/ !rÃúõüõï¾KÅŠpÿPRJ _|ÁåË|öY3µÊ\\\€’%K–+W®À9:59¶Ä+å°¢@ž|òI—ýû÷ë"IkÛ/¾øâˆ#l¿œ4öç®®®µk[:4K¬%XvìØ±wï^]ŒÁ××·L™ü­È©±×=­Öó6†Rþæï|C5kÖ¬S§N6lÐKXÞª çá {÷&0Ï?gäHÆÿg(ÉÕ•Ï?gÆ nÜàøq[2õÂËò›Ï–TnáæÁ:J$(A ˃$%%¹ØÐÉ{PP£FgŸ}V¯˜NAqvÔ +ö½ùœ÷¹ã íšûCqVcpwç£xí5æÌáóÏ©W Q#nÝèÕ‹FŸÇ½téÒ{÷î½ýöÛygjUAÃut—»Xi úRd+%–XõìˆîØë·|›é®¼ÍÛñ—䆳0x0µj¤¥qêÀíÛÚ˜81·h_}õÕ’%KòÍTƒU(c„ 2H°äƒÂ* 3†k\›Ïü£µ“€Üpbcps#(è¾-B`2Ñ£Mm½bòÄ3‰$ËRôÎAÙQÆ qÄ „zHVw 3†6´‰#ÎÞo\z'6`ÀêÖÍ9û(÷î‚å4§¹å‹ ÍsPv¬#ÍV‹£Ï“% hVжÀ—ê1èŽaÆp“›ûØO¼ä†sƒ«+AA˜ÍYIyî9·umZ3æìÜÍîh¢-THÑ;eçÁ:Ò–ÚÎ$Ó EE´Rb‰Eƒ0Ìrð%^:Ìa; È ç6 _?ê×ÿ§Ó “&ÙžãOütšÓ÷¸L°… )zç ìø¬gýqr]•¯hžƒ²cI!…”¼;^ºK¢èUŠºÇ`':”ô Ÿxãý#?v¥kg:¿È‹Ã>“™é¤ûá÷/äLga’<–(Ô¤²¥Çp˜Ã7¸±™Í¡„>Ã3šÇ”¡Ì f\åêd&Ïc^ )zç ì˜L&á*ö²W›Í¸ãîŽ{–1¬eí£õµŽ™ÃRè1æ9†Où´%L˜L˜êQÏ‘×Vò<›®še V‘½Ž±È÷ì6à†Û†«ªãÿ‡|DDP2É¡„Þàà°9,…cŒ¡2•?æcк ޼¶’ÿà±ÐL˜lœ®š-”æ7ù¢Œ!{Õ§þû¼ŸÕcІF+RÑXU…›wy·6µ³/墕¿Ãæ°z {òy cã±bsðµ•ü…CI:ºªÇ`%9êèC>¬IMí<%ùÞvvŒªBŒ'ž X})ò›Ã¢° ÃŒÁ÷,x…W¼Àªü…=}¯Œ”1XEŽ:*F±…,ÔÎSÕ©Þ™Î2¨*Ü<˳/òbÖ`C¾sXVa˜1OóôlfÛI@nÈðXh ªÇ` Öѳ<Û›ÞÀ¼áb·ÃÊZU…›¹ÌõÀCóÏa)ôi ñê%ù ‡’TÁ@ZGó˜ç‹ï¿ø—!’p†¶­/5©ù!jw<‡¥Ðc°18ù5”$?­£ªTÝÁǯ$Ÿ…üm[wÞçýÔ<‡¥Ð£ŒA:ÔP’üäVGŽUmväoÛºã…×|æ{ãmÈüàBŒ2é0d(I‹¦ŒÁBälErª²7Ýé¾…Ž”.Ü(c5”$?r¶"9U9€¡ 5ZBaCƒt(c9[‘œªΈ2éP÷äGοmÈÕ«WOŸ>m´ §Aƒt¨éªò£K ÌŸ?Á‚:)ghÛ2vìØ¶mÛ­ÂipcèÝ»÷Ô©yg}ÁÿàQCIò£K ¬X±båÊ•:)ghÛ gÁ€e·­e÷îݶÉBþƒGß¡¤[·n™Íæ *äLƒUÈYò·m…³àÆ /ò<%yâiI´=zÄÅÅ=›Ï[é•1X…œ% ÛV8 N0”¤/òùäÛãhÈðä«Ð—Çx¬ÕôÍ7†˜ T°$¥29K@þ¶­pœÀôEþƒ'_…‰$žáÌüaI´>ø`̘1ù&K#-ޏŠT´P!RV®Ã³äoÛ gA½A:òUØ„&&LÇ8fI´_ý5...ßd§9-öB¤­\‡!g Èß¶΂ê1HG¾ KQªµö±OÇL×±èAKK[¹Cοm+œe Òa‰Â>ô #ìW~Õ+Óø¡>õ›ÐÄ’ÄÒV®Ã³äoÛ gAƒtX¢p c<ð!D—á—K\²|ò«´•ë0ä,ùÛ¶ÂYPÆ –(ôÃï^Ù–?±u"oI£]Žroò¦å ‘²r†œ% ÛV8 ʤÃB…AyãÝ›Þó·-ÙMbR8á!„”§¼å ‘²r†œ% ÛV8 ʤÃB…5¨±ŠUQDõ¥¯…KY<ÈbÏc^g:f°U ‘²r†œ% ÛV8 ʤÃr…=é9 ûØ÷ÏÝæ¶µ…2šÑi¼†5Ù_ð`‰B¤¬\‡!g Èß¶΂2é°JáT¦¾Ïû;ÙÙœæ>ÙÄ;ïñ^+ZíaåƒHY ‘²r†V²!ÛV8 ʤÃ*…®¸ÎdæüG\ Zô§ÿaç‘ÞŒy)K«S} kF1êW~õÅ· ‘²r†œ% ÛV8 êÉgé(€Â>ôiD£ILZǺïù¾ ]šÒ´ÍZÐ"Å?%¥rÊ.váÌV¶îeo:é i8yèd‹NɋѮÈÙ¼åoÛ g¡(ƒÑò¡`‡w}êÏ÷‘D~ʧßñÝvüóÅ÷Ïð àwOzö¤gÖÛ~ ¬)+×aÈYÊzQABUÙ±E¡?þ X°€‘DåèQŽ®X²"õvê'ŸøâÛÔ-må: 9K@þ¶m C‡íÔɦ.r‘Â^ÆP¶lÙQ£F5mÚÔöP+Vôõµz<7ÞxãçŸ^¯hö@—ÃÛü{Ðcû7Ûãââ†ÕCÚ?”,YrÁ‚?þ¸Ž1‹Æ5ª\¹r¶Ùµk—¾ý×1cÆ$&&ê°0Ñ£‡Eë€)4Ô%†tìÛ·ïÒ¥K¯¿þº.ÑâââΞ=«K4…Â1ü÷¿ÿ-]ºtëÖ­r“'Ož2eJDD„¿¿¿ÑZ싽z ŠÓ¡C‡:èíÕW_½wïž^Ñ ÇЭ[7£%iTA¡P(,"&&&&&¦~ýúîîîFk±/Ê …BqözÀM¡P(NŠ2…B¡P܇2…B¡P܇2…B¡P܇1Æ0mÚ´òå˧¥¥å–`Μ9Ú‡—_~¹`Y„„„øøøì· …BQ”1Æ~üñÇlÞ¼9·YưnݺÄÝ¿©R¥ ¨Obìê©{öìiÓ¦Mûöí›7oþóÏ?\e‘Ä®Usâĉ€€€§žzªeË–»ví*¸J…„ÃÙ¿ÿo¼qáÂ…^xAÖ¾}û€€€:DGG !,XàááѾ}û &øùù !Nž<Ù¦M›6mÚœ>}Z‹S¥J•Ñ£G?öØcsçÎ͑Ÿqã<¨ý¶Ñ¼yó·Þzkݺu¹%°e¯SSSµÑÑÑ5jÔ(pœ¢‰]«ææÍ›‰‰‰BˆˆˆˆÚµk8N!`êÔ©åÊ•Ëj«¢}èÓ§OâÏ;·nݺ>>>ÔW(0À^ýõÐÐP!DçΣ££;tè°sçNí«ÌÌLíCÖ!¤}hÛ¶í¯¿þ*„øý÷ßÛµk§}UºtéË—/ÇÇÇשS'{üK—.õïß_Øvʉyòd ))©}ûö<òÈÞ½{Ÿ~úiÀl6k哃ڵkÿïÿkÛ¶íjÕª¥mÌmµçÔÔTOOO téÒñññöÚ“B‡ªF1|øðêÕ«¿÷Þ{vÛÙINNÞ¶m[TT³jÕªsçÎe½eá¡… \¼xñ©§ž._¾¬môöö®Y³&žžîéN‡ÑΤ°”N::t(ë¿]ºtY½zu»ví:vì¨õ£…£FêÒ¥Kpp°vÉsìØ±'žxBëJŸéûN¾ë–nWܬdý:â¼/ï—H‰~ꃆ5ΰ7AûMðÏ”Ji¥TÊ«éþV™”}*Ÿþ.¿§%=õAGœ¨D?‘ODÄï_§Ó_ jæ¿Ä?ãGöí¯ÈM˜ù3ù»ZäÉWòU‡tL3 ûË7"#‡åðOòÓ¤LN=¤.É¥*© w1Xi†÷Tõ¯„² LÊþón÷Ù,ßypX·I›´õ…|ñ‹üöR‚dO°|äÁ!9Ô.íiI÷JïgòYØŒmÁò Ëð!9ô‡üñ³üö.cg°|OäIT¢³dVØ‹†ÍÁ`{žéÀz € € € € € € € € €ÿx¿[·n?~Üð+çÏŸßØØhþššš?~l8¼k×®U«Vwuu]¸pÁp¸¢¢¢¾¾ÞpxllìàÁƒ†Ã"ràÀ‚‚Ãácǎݽ{×pxÛ¶mëׯ7¾råÊéÓ§ ‡KJJöìÙc8,"9 Çb±¥K—Ÿ9sæòåˆÃUUUµµµ†ÃCCCG5ž={vKK‹á°ˆ´´´ŒŽŽ×ÕÕ­]»Öp8‘Hœ;wÎpxåÊ• †Ãããã9ýðîß¿¿¨¨ÈpøÄ‰†Ã[¶l©©©1ßäÁºwï^[[›áW.Y²$§ÛÇ>|h8¼yófó`õõõ™¯][[k¬d2i~Í"ÒÜÜl¬ÎÎÎÞÞ^ÃáåË—›ëöíÛæk¯Y³&§µ··›¿þ´®®ÎúÈÎlñ<,À*££RV&OŸŠˆËÞ½ÒÐ ……a¯ް«,^,ß|#Ž#"26&±˜”•Ùs´•ÛÖ³g²}{þ–€ÉII$$“yqÑu%›µäh+òÿ#/ñ<¹?O›F6+"â8âøS)¹_ž<Ñ,þ†Øæ‡äûï_œw)(¯¿–o¿•>u­ ,À*©”|ø¡$“""Ѩ=©òåö_B3Ü?J2iaª|aöH¥¤¼\¾üÒÂTù8ÂìñçŸ20 ï½öyÃ5xâ(5555555þ~âh<?uê”뺎㸮;u&ØÓ™…oyOÇã"˜éìì¼víÚÔ]ç{ùâ4ŸÊǤÒoö?ãëû;X“““ãããžçe³ÙWNó©\O³þ{^@äMúø&]±bE2™<{ölØw@vìØñÔ3M¼›ãêêêÆÆÆi6ó™îžçÞÁ<]¡•{F£Ñþþþááá°¯¡¸¸xëÖ­íííSï%/_|½O…;É·Û¸qcssó4€0_K8•Õwx—íܹ³¿¿?ì-ræºn$Âk`ßQÄAJ¥REEEGŽ {؉`!Hžç¥R©t:ö"°Á Á Á Á Á Á Á Á Á Á Á Á Á ï+„ Í›7¯»»{Ù²ea/;,)‰lذ!ì-`-þK@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚@ ‚… MLLÄb±D"ö"°ÁBÒétkkëÕ«WÃ^v"XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÔ XÒœ9sêëëËËËÃ^vŠ„½¬RXXÇÃÞÖâ € € € € € € € € € € € € € AÊd27nÜ {؉`!Hããã'Ož {؉`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`Pƒ`PÃñ`, some of the concepts are hard to grasp even for experienced people. I think this is because rsyslog uses a very high layer of abstraction which includes things that look quite unnatural, like queues that do **not** actually queue... With this document, I take a different approach: I will not describe every specific detail of queue operation but hope to be able to provide the core idea of how queues are used in rsyslog by using an analogy. I will compare the rsyslog data flow with real-life traffic flowing at an intersection. But first let's set the stage for the rsyslog part. The graphic below describes the data flow inside rsyslog: .. figure:: dataflow.png :align: center :alt: rsyslog data flow rsyslog data flow Note that there is a `video tutorial `_ available on the data flow. It is not perfect, but may aid in understanding this picture. For our needs, the important fact to know is that messages enter rsyslog on "the left side" (for example, via UDP), are preprocessed, put into the so-called main queue, taken off that queue, filtered and are placed into one or several action queues (depending on filter results). They leave rsyslog on "the right side" where output modules (like the file or database writer) consume them. So there are always **two** stages where a message (conceptually) is queued - first in the main queue and later on in *n* action specific queues (with *n* being the number of actions that the message in question needs to be processed by, what is being decided by the "Filter Engine"). As such, a message will be in at least two queues during its lifetime (with the exception of messages being discarded by the queue itself, but for the purpose of this document, we will ignore that possibility). Also, it is vitally important to understand that **each** action has a queue sitting in front of it. If you have dug into the details of rsyslog configuration, you have probably seen that a queue mode can be set for each action. And the default queue mode is the so-called "direct mode", in which "the queue does not actually enqueue data". That sounds silly, but is not. It is an important abstraction that helps keep the code clean. To understand this, we first need to look at who is the active component. In our data flow, the active part always sits to the left of the object. For example, the "Preprocessor" is being called by the inputs and calls itself into the main message queue. That is, the queue receiver is called, it is passive. One might think that the "Parser & Filter Engine" is an active component that actively pulls messages from the queue. This is wrong! Actually, it is the queue that has a pool of worker threads, and these workers pull data from the queue and then call the passively waiting Parser and Filter Engine with those messages. So the main message queue is the active part, the Parser and Filter Engine is passive. Let's now try an analogy for this part: Think about a TV show. The show is produced in some TV studio, from there sent (actively) to a radio tower. The radio tower passively receives from the studio and then actively sends out a signal, which is passively received by your TV set. In our simplified view, we have the following picture: .. figure:: queue_analogy_tv.png :align: center :alt: rsyslog queues and TV analogy rsyslog queues and TV analogy The lower part of the picture lists the equivalent rsyslog entities, in an abstracted way. Every queue has a producer (in the above sample the input) and a consumer (in the above sample the Parser and Filter Engine). Their active and passive functions are equivalent to the TV entities that are listed on top of the rsyslog entity. For example, a rsyslog consumer can never actively initiate reception of a message in the same way a TV set cannot actively "initiate" a TV show - both can only "handle" (display or process) what is sent to them. Now let's look at the action queues: here, the active part, the producer, is the Parser and Filter Engine. The passive part is the Action Processor. The latter does any processing that is necessary to call the output plugin, in particular it processes the template to create the plugin calling parameters (either a string or vector of arguments). From the action queue's point of view, Action Processor and Output form a single entity. Again, the TV set analogy holds. The Output **does not** actively ask the queue for data, but rather passively waits until the queue itself pushes some data to it. Armed with this knowledge, we can now look at the way action queue modes work. My analogy here is a junction, as shown below (note that the colors in the pictures below are **not** related to the colors in the pictures above!): .. figure:: direct_queue0.png :align: center :alt: This is a very simple real-life traffic case: one road joins another. We look at traffic on the straight road, here shown by blue and green arrows. Traffic in the opposing direction is shown in blue. Traffic flows without any delays as long as nobody takes turns. To be more precise, if the opposing traffic takes a (right) turn, traffic still continues to flow without delay. However, if a car in the red traffic flow intends to do a (left, then) turn, the situation changes: .. figure:: direct_queue1.png :align: center :alt: The turning car is represented by the green arrow. It cannot turn unless there is a gap in the "blue traffic stream". And as this car blocks the roadway, the remaining traffic (now shown in red, which should indicate the block condition), must wait until the "green" car has made its turn. So a queue will build up on that lane, waiting for the turn to be completed. Note that in the examples below I do not care that much about the properties of the opposing traffic. That is, because its structure is not really important for what I intend to show. Think about the blue arrow as being a traffic stream that most of the time blocks left-turners, but from time to time has a gap that is sufficiently large for a left-turn to complete. Our road network designers know that this may be unfortunate, and for more important roads and junctions, they came up with the concept of turning lanes: .. figure:: direct_queue2.png :align: center :alt: Now, the car taking the turn can wait in a special area, the turning lane. As such, the "straight" traffic is no longer blocked and can flow in parallel to the turning lane (indicated by a now-green-again arrow). However, the turning lane offers only finite space. So if too many cars intend to take a left turn, and there is no gap in the "blue" traffic, we end up with this well-known situation: .. figure:: direct_queue3.png :align: center :alt: The turning lane is now filled up, resulting in a tailback of cars intending to left turn on the main driving lane. The end result is that "straight" traffic is again being blocked, just as in our initial problem case without the turning lane. In essence, the turning lane has provided some relief, but only for a limited amount of cars. Street system designers now try to weight cost vs. benefit and create (costly) turning lanes that are sufficiently large to prevent traffic jams in most, but not all cases. **Now let's dig a bit into the mathematical properties of turning lanes.** We assume that cars all have the same length. So, units of cars, the length is always one (which is nice, as we don't need to care about that factor any longer ;)). A turning lane has finite capacity of *n* cars. As long as the number of cars wanting to take a turn is less than or equal to *n*, "straight traffic" is not blocked (or the other way round, traffic is blocked if at least *n + 1* cars want to take a turn!). We can now find an optimal value for *n*: it is a function of the probability that a car wants to turn and the cost of the turning lane (as well as the probability there is a gap in the "blue" traffic, but we ignore this in our simple sample). If we start from some finite upper bound of *n*, we can decrease *n* to a point where it reaches zero. But let's first look at *n = 1*, in which case exactly one car can wait on the turning lane. More than one car, and the rest of the traffic is blocked. Our everyday logic indicates that this is actually the lowest boundary for *n*. In an abstract view, however, *n* can be zero and that works nicely. There still can be *n* cars at any given time on the turning lane, it just happens that this means there can be no car at all on it. And, as usual, if we have at least *n + 1* cars wanting to turn, the main traffic flow is blocked. True, but *n + 1 = 0 + 1 = 1* so as soon as there is any car wanting to take a turn, the main traffic flow is blocked (remember, in all cases, I assume no sufficiently large gaps in the opposing traffic). This is the situation our everyday perception calls "road without turning lane". In my math model, it is a "road with turning lane of size 0". The subtle difference is important: my math model guarantees that, in an abstract sense, there always is a turning lane, it may just be too short. But it exists, even though we don't see it. And now I can claim that even in my small home village, all roads have turning lanes, which is rather impressive, isn't it? ;) **And now we finally have arrived at rsyslog's queues!** Rsyslog action queues exists for all actions just like all roads in my village have turning lanes! And as in this real-life sample, it may be hard to see the action queues for that reason. In rsyslog, the "direct" queue mode is the equivalent to the 0-sized turning lane. And actions queues are the equivalent to turning lanes in general, with our real-life *n* being the maximum queue size. The main traffic line (which sometimes is blocked) is the equivalent to the main message queue. And the periods without gaps in the opposing traffic are equivalent to execution time of an action. In a rough sketch, the rsyslog main and action queues look like in the following picture. .. figure:: direct_queue_rsyslog.png :align: center :alt: We need to read this picture from right to left (otherwise I would need to redo all the graphics ;)). In action 3, you see a 0-sized turning lane, aka an action queue in "direct" mode. All other queues are run in non-direct modes, but with different sizes greater than 0. Let us first use our car analogy: Assume we are in a car on the main lane that wants to take turn into the "action 4" road. We pass action 1, where a number of cars wait in the turning lane and we pass action 2, which has a slightly smaller, but still not filled up turning lane. So we pass that without delay, too. Then we come to "action 3", which has no turning lane. Unfortunately, the car in front of us wants to turn left into that road, so it blocks the main lane. So, this time we need to wait. An observer standing on the sidewalk may see that while we need to wait, there are still some cars in the "action 4" turning lane. As such, even though no new cars can arrive on the main lane, cars still turn into the "action 4" lane. In other words, an observer standing in "action 4" road is unable to see that traffic on the main lane is blocked. Now on to rsyslog: Other than in the real-world traffic example, messages in rsyslog can - at more or less the same time - "take turns" into several roads at once. This is done by duplicating the message if the road has a non-zero-sized "turning lane" - or in rsyslog terms a queue that is running in any non-direct mode. If so, a deep copy of the message object is made, that placed into the action queue and then the initial message proceeds on the "main lane". The action queue then pushes the duplicates through action processing. This is also the reason why a discard action inside a non-direct queue does not seem to have an effect. Actually, it discards the copy that was just created, but the original message object continues to flow. In action 1, we have some entries in the action queue, as we have in action 2 (where the queue is slightly shorter). As we have seen, new messages pass action one and two almost instantaneously. However, when a messages reaches action 3, its flow is blocked. Now, message processing must wait for the action to complete. Processing flow in a direct mode queue is something like a U-turn: .. figure:: direct_queue_directq.png :align: center :alt: message processing in an rsyslog action queue in direct mode message processing in an rsyslog action queue in direct mode The message starts to execute the action and once this is done, processing flow continues. In a real-life analogy, this may be the route of a delivery man who needs to drop a parcel in a side street before he continues driving on the main route. As a side-note, think of what happens with the rest of the delivery route, at least for today, if the delivery truck has a serious accident in the side street. The rest of the parcels won't be delivered today, will they? This is exactly how the discard action works. It drops the message object inside the action and thus the message will no longer be available for further delivery - but as I said, only if the discard is done in a direct mode queue (I am stressing this example because it often causes a lot of confusion). Back to the overall scenario. We have seen that messages need to wait for action 3 to complete. Does this necessarily mean that at the same time no messages can be processed in action 4? Well, it depends. As in the real-life scenario, action 4 will continue to receive traffic as long as its action queue ("turn lane") is not drained. In our drawing, it is not. So action 4 will be executed while messages still wait for action 3 to be completed. Now look at the overall picture from a slightly different angle: .. figure:: direct_queue_rsyslog2.png :align: center :alt: message processing in an rsyslog action queue in direct mode message processing in an rsyslog action queue in direct mode The number of all connected green and red arrows is four - one each for action 1, 2 and 4 (this one is dotted as action 4 was a special case) and one for the "main lane" as well as action 3 (this one contains the sole red arrow). **This number is the lower bound for the number of threads in rsyslog's output system ("right-hand part" of the main message queue)!** Each of the connected arrows is a continuous thread and each "turn lane" is a place where processing is forked onto a new thread. Also, note that in action 3 the processing is carried out on the main thread, but not in the non-direct queue modes. I have said this is "the lower bound for the number of threads...". This is with good reason: the main queue may have more than one worker thread (individual action queues currently do not support this, but could do in the future - there are good reasons for that, too but exploring why would finally take us away from what we intend to see). Note that you configure an upper bound for the number of main message queue worker threads. The actual number varies depending on a lot of operational variables, most importantly the number of messages inside the queue. The number *t\_m* of actually running threads is within the integer-interval [0,confLimit] (with confLimit being the operator configured limit, which defaults to 5). Output plugins may have more than one thread created by themselves. It is quite unusual for an output plugin to create such threads and so I assume we do not have any of these. Then, the overall number of threads in rsyslog's filtering and output system is *t\_total = t\_m + number of actions in non-direct modes*. Add the number of inputs configured to that and you have the total number of threads running in rsyslog at a given time (assuming again that inputs utilize only one thread per plugin, a not-so-safe assumption). A quick side-note: I gave the lower bound for *t\_m* as zero, which is somewhat in contrast to what I wrote at the beginning of the last paragraph. Zero is actually correct, because rsyslog stops all worker threads when there is no work to do. This is also true for the action queues. So the ultimate lower bound for a rsyslog output system without any work to carry out actually is zero. But this bound will never be reached when there is continuous flow of activity. And, if you are curious: if the number of workers is zero, the worker wakeup process is actually handled within the threading context of the "left-hand-side" (or producer) of the queue. After being started, the worker begins to play the active queue component again. All of this, of course, can be overridden with configuration directives. When looking at the threading model, one can simply add n lanes to the main lane but otherwise retain the traffic analogy. This is a very good description of the actual process (think what this means to the "turning lanes"; hint: there still is only one per action!). **Let's try to do a warp-up:** I have hopefully been able to show that in rsyslog, an action queue "sits in front of" each output plugin. Messages are received and flow, from input to output, over various stages and two level of queues to the outputs. Actions queues are always present, but may not easily be visible when in direct mode (where no actual queuing takes place). The "road junction with turning lane" analogy well describes the way - and intent - of the various queue levels in rsyslog. On the output side, the queue is the active component, **not** the consumer. As such, the consumer cannot ask the queue for anything (like n number of messages) but rather is activated by the queue itself. As such, a queue somewhat resembles a "living thing" whereas the outputs are just tools that this "living thing" uses. **Note that I left out a couple of subtleties**, especially when it comes to error handling and terminating a queue (you hopefully have now at least a rough idea why I say "terminating **a queue**" and not "terminating an action" - *who is the "living thing"?*). An action returns a status to the queue, but it is the queue that ultimately decides which messages can finally be considered processed and which not. Please note that the queue may even cancel an output right in the middle of its action. This happens, if configured, if an output needs more than a configured maximum processing time and is a guard condition to prevent slow outputs from deferring a rsyslog restart for too long. Especially in this case re-queuing and cleanup is not trivial. Also, note that I did not discuss disk-assisted queue modes. The basic rules apply, but there are some additional constraints, especially in regard to the threading model. Transitioning between actual disk-assisted mode and pure-in-memory-mode (which is done automatically when needed) is also far from trivial and a real joy for an implementer to work on ;). If you have not done so before, it may be worth reading :doc:`Understanding rsyslog Queues <../concepts/queues>`, which most importantly lists all the knobs you can turn to tweak queue operation. .. _concept-model-whitepapers-queues_analogy: Conceptual model ---------------- - rsyslog message flow mirrors traffic: the main queue drives processing and pushes work to passive consumers. - Every action conceptually has a queue; "direct" mode is equivalent to a zero-capacity turning lane that still gates flow. - Non-direct queues duplicate messages for parallel delivery, isolating slow actions from the main path. - Queue workers are the active agents pulling from queues and invoking parsers or actions; consumers never request data. - Queue capacity and worker counts bound concurrency: more lanes/queues increase parallelism, while zero-capacity queues serialize. - Shutdown, error handling, and timeouts are governed by the queue, which decides completion and can cancel long-running actions. rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/reliable_logging.rst0000644000000000000000000000013215114522477023160 xustar0030 mtime=1764926783.034631833 30 atime=1764926784.236661338 30 ctime=1764935922.866571727 rsyslog-8.2512.0/doc/source/whitepapers/reliable_logging.rst0000664000175000017500000001201415114522477022622 0ustar00rgerrgerHow reliable should reliable logging be? ======================================== With any logging, you need to decide what you want to do if the log cannot be written * do you want the application to stop because it can't write a log message or * do you want the application to continue, but not write the log message Note that this decision is still there even if you are not logging remotely, your local disk partition where you are writing logs can fill up, become read-only, or have other problems. The RFC for syslog (dating back a couple of decades, well before rsyslog started) specify that the application writing the log message should block and wait for the log message to be processed. Rsyslog (like every other modern syslog daemon) fudges this a bit and buffers the log data in RAM rather than following the original behavior of writing the data to disk and doing a fsync before acknowledging the log message. If you have a problem with your output from rsyslog, your application will keep running until rsyslog fills it's queues, and then it will stop. When you configure rsyslog to send the logs to another machine (either to rsyslog on another machine or to some sort of database), you introduce a significant new set of failure modes for the output from rsyslog. You can configure the size of the rsyslog memory queues (I had one machine dedicated to running rsyslog where I created queues large enough to use >100G of ram for logs) You can configure rsyslog to spill from it's memory queues to disk queues (disk assisted queue mode) when it fills it's memory queues. You can create a separate set of queues for the action that has a high probability of failing (sending to a remote machine via TCP in this case), but this doesn't buy you more time, it just means that other logs can continue to be written when the remote system is down. You can configure rsyslog to have high/low watermark levels, when the queue fills past the high watermark, rsyslog will start discarding logs below a specified severity, and stop doing so when it drops below the low watermark level For rsyslog -> \*syslog, you can use UDP for your transport so that the logs will get dropped at the network layer if the remote system is unresponsive. You have lots of options. If you are really concerned with reliability, I should point out that using TCP does not eliminate the possibility of losing logs when a remote system goes down. When you send a message via TCP, the sender considers it sent when it's handed to the OS to send it. The OS has a window of how much data it allows to be outstanding (sent without acknowledgement from the remote system), and when the TCP connection fails (due to a firewall or a remote machine going down), the sending OS has no way to tell the application what data what data is outstanding, so the outstanding data will be lost. This is a smaller window of loss than UDP, which will happily keep sending your data forever, but it's still a potential for loss. Rsyslog offers the RELP (Reliable Event Logging Protocol), which addresses this problem by using application level acknowledgements so no messages can get lost due to network issues. That just leaves memory buffering (both in rsyslog and in the OS after rsyslog tells the OS to write the logs) as potential data loss points. Those failures will only trigger if the system crashes or rsyslog is shutdown (and yes, there are ways to address these as well) The reason why nothing today operates without the possibility of losing log messages is that making the logs completely reliable absolutely kills performance. With buffering, rsyslog can handle 400,000 logs/sec on a low-mid range machine. With utterly reliable logs and spinning disks, this rate drops to <100 logs/sec. With a $5K PCI SSD card, you can get up to ~4,000 logs/sec (in both cases, at the cost of not being able to use the disk for anything else on the system (so if you do use the disk for anything else, performance drops from there, and pretty rapidly). This is why traditional syslog had a reputation for being very slow. See Also -------- * https://rainer.gerhards.net/2008/04/on-unreliability-of-plain-tcp-syslog.html .. _concept-model-whitepapers-reliable_logging: Conceptual model ---------------- - Reliability is a policy choice: block the application when logging stalls or drop messages to keep workloads running. - rsyslog decouples applications via in-memory queues, only halting writers when queues saturate. - Disk-assisted queues extend buffer capacity and persistence but introduce latency and eventual disk exhaustion risks. - Per-action queues isolate unreliable destinations so other actions can continue during outages. - High/low watermarks and severity-based discard policies bound backlog growth under sustained failures. - Transport choice defines delivery guarantees: UDP sacrifices reliability; TCP reduces loss window but can drop in-flight data; RELP adds application-level acknowledgements. - Absolute durability is limited by OS and disk flush semantics; stronger guarantees trade away throughput by orders of magnitude. rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue_directq.png0000644000000000000000000000013115055603742024036 xustar0030 mtime=1756825570.265068523 29 atime=1764929145.53782285 30 ctime=1764935922.850571482 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue_directq.png0000664000175000017500000002353315055603742023511 0ustar00rgerrger‰PNG  IHDRVÒž›®sBITÛáOà pHYsÐй‹çŸ IDATxœíwxTUÞÇ?“N ´@ ½@D ½¨HQÄ.ëbE—¢²Ë몈(¬ˆ€K}A¥IOwEŠt $ôHH!“óþqycL=3¹3wrs>Ož<3wNùÍ9ßùžsÏ=Ç"„pww·ÁÍÍ­èÁRŽÛ‘Ũã.’ Uæ8 à!„Bäåå‰BQH­\?ÔŽ;öíÛð°X,Zûׄ@‡«wÁT¨Î9®~«ôâÙgŸ½-ù‡,‹»»»q!)R¸š*•~ÜCÒŽ·oß^;Ÿ!„±Ÿ¨Bá6³9„V´2:—ÃÍÀº7°á @QØÌæbžåÙæ47:WÄ£ì$`¦0å×ö³ßeò¿Eitåb3›'3y;ÛÅ,vGõs‹ÁÙ.`îæîxâw²óoüÍÍP¢(–D{Ñk KŒÄ~´_þ{¸GkÿMi:”¡Fåª;`àÖ‹õEgÚ_sÑÜ*¬N«]Q&VaýV|ÛItB"B®‹ëFGd›Ä¦.¢Kþ×Lû[,—ëâ (Ôøµ¿/Å—N¨Z!CŽÈY(¶-ò?b†ÑAÙL±ASÑ4WäëâØ+ZŸ'; oNóýìW½Ã¹ÉÍyÌ{÷Nr2ÿ`8áG9ê·&'‡C‡øí7$-Œ ÒÓIO×\ªÁàÕžšç/J_ú6¥©“ã5„;¹ó!²5—£$ ¤Æ¯Ñ—¾MhâˆzÅ2˜Á]èRðÈU®~ÌÇ3™y‘‹…/`Á£<êÄèŠã÷ßIHà§Ÿ8|˜cÇ8{¶”´)õ ;å´È\—ŒXÌb[s9äŠÀW|5Œa‚Åe kÖ°ÆU+Š¥! ó%à g>àƒñ¯Ü(6e4Ñi¤èÜ!9™„IH %åO/yzÒ´)IHøûã燿?þþYÁ—‡²àk¾Î£˜¹ƒð@g:;é-Š}fÇQ.à ßâ­’>•y0šhGÔ«(–îtoCà"ˆÈ £Ì,, iXŸúèОöèІp¯Î¥K,]ÊÂ…üüóˆ'.Ž&MˆŒ$4´ÌbJúÊ…vŒc^xé¸IpèHÃq`¨ê&Ü Ð„‹ðl‘íЪ%qI\š &TUŠŽœ!¨%jEŠÈj¢ZÑ—<…gÑ™X–%²tˆ#'G¬\)î»OxyÝ®!8XÜ¿˜5K8 Jžo[:Å~åf‹Ù:lRœqE ØOå_â_N¨ZQ)"e¬ë!< µsásVœB䉼d‘¼N¬{K¼5P ¬%jå§ £Ä¨b£—u³²ÄŒ¢víÛåyxˆþýÅÿþ¯ÈÖíW¡ÐW.L„©Ÿœ’pÞ¼€BŸŠ2®Àqdˆb–‚*ðªxµØÄ‡ÅáYbV´ˆÎOßB´øN|gC}99bÎz»ª–-Å{ï‰óçõy3E(ø•SF $œ'?e\„]bWOÑ3_Eà5q­”ô©"uª˜Ú@4ÐÒw]¶‹íeWóå—¢~ýÛ•´k'Ö¬Ñí ”Šö•k ¨Ÿœbq¶hhŸJ„ˆPŸŠë°Elé(:j­úïâïe¦Ï9³Ä¬üÂ01,]¤Ÿô·ßDLÌ¿üË—ÛÝÕ·›‘r@pr¥c$@#U¤ @Qˆ<‘·B¬h.š×µnŠ›2YÒEúT1µª¨Š BDì»þ\bž˜=[øû ~~â½÷œßø¥£Ö PÆŠõßü»&5ûÒW2K2ÉCú_þë÷û¼ÿ4O¤¦2f ë×<ü03gä°¨v¢$@¡9ä¼ÄK3™ <Â# zÖÒ3žk× aölî»ÏèÅã>yòd£cp 6oÞwäÈ‘~ýúmÚ´©ÿþÇ߸qã°aÃRRRzôè±qãÆÇ{ìܹs1117n|öÙg/_¾Ü©S§7¾üòËiiiíÚµÛ´iÓ¤I“222Ú´i³yóæéÓ§ggg7oÞéÓ§Ï÷ß¼÷Þ{±±±k×®Þzë­»îºK{üÚk¯µjÕJKó /ÜqÇÚcq?÷¯_:ªJ&³ž²NØÚï¿WæßÅQ.à6aaaO<ñÄ AƒüüüÂÂÂFŽÙ¿ÿ€€€zõê=øàƒ}úô ª[·î€âããkÔ¨Q«V­øøø{ï½7$$¤Fݺu‹‹‹«]»vPPPttt=êÖ­[µjÕ¨¨¨ØØØÐÐÐ*Uª´lÙ2666,,ÌÃãQ£Fݺu B„‡‡ÇÆÆ6hÐàÖ­[µk×îÞ½{Æ 322‚ƒƒ»wïqõêÕªU«öèÑãŽ;î8þ¼··w\\\ddä©S§,KÏž=###;–››Û«W¯ÈÈÈýû÷gfföíÛ722r×®]ׯ_0`@ddä¶mÛ®\¹2xðà;î¸Ã!'Ñjå™g"^›ÛnÛÿsßÞ Õj±ö ‡CêRè„ Pè„<ôK—âëË’%úö£ß-n­de?úœ¢DTG@¡'²t)ÞÞ$$0pà½Ü;é1šÑ©¤œ¢D” PèÁìÙ<ý4žž¬Yý÷jÇb W±ª+]·°E­Þ隨±€2È&;„ìhC›+\‰#î^¸À…Ö´nLãILÊ&»;Ý7°á ž¸ÈÅÎtÞĦ—xé×ÚÓ>„·y;ƒŒV´Úƶ™ÌÌ&» M’HZÀ‚\r#ˆØÅ®å,ˆPB÷±o#-XjQëG’HrÇ=˜àßùý<ð à g’IöÀÃ_£Oß~ËèÑóç3xpþa –žô\Â’ýì÷À£Ý ‹PQ2ª#ð'´[ͯpå~î×n°¿ÉÍžô|žç –$’2ȸÀO<Ïqî&7µ%·Nsz [Žp8Á‰¬ØË^à0‡?çó$’€Ýì~Ÿ÷I´”7°ØÄ¦çy~5«•¬ÉȬ–°d–± øŒÏºÒU[æ>hMë/øÂˆ3T„={2«•wÞá‘G ½XêÚJÄçï§P+û¸"Æì#à‚Ä$’xžóÕ¨–Hâ®\ãZA÷roÙdð_¹áÖ….Õ©¾}7¸Qz@ú$’BГžßòma@q X ­’Ön3˜Ñ–¶@g:Of²¶šM:Œg¼¶†JÚŒb”–¦Í1HËÛ†±ÄjeÖ¡N[ÚjuLf&#F›Ëðá¼öZ±Ibˆy˜‡±h"ÿÍ¿ ¢l œœì |">©%j'…w‰»$‰$!Äâ‡â€Zy¶ ž{N€hÕJd•¶ˆÈIq²Š¨b–ÿŠÿ:-4…$•±#EÖ|ækF}';Ïs~9ËYÌÊ$³€bZÐB`•ÆÆÌš…·7‹á]ÚrÃa„ý…¿Ä_ù«Ó¢SHR¯¼À 3™9†1s™û ¿\åjWº:dU<sõ*­Zqú4Ó§óòËe&O'ýî¸À…MlŠ#Î *$©,. ƒŒiLÅ(à5^ëLçû¹hMëntSíßfþòNŸ¦kW&LIîÿxƳ˜åàȶa~ ,¹¨­œ›BŠ6€§°Ÿ½{i×ww~ý• $3]äba·¸õ¿5@6—ÂјÜìc_{Úÿ‡ÿÔ¤æ|°}ªýëÀ믓—Ç /È· &5‡1ÌŠõ>qXd ›1¹ ˜ÈÄiLëOÿ•¬4:³˜H÷îT«ÆñãÛ”u7»ÛÑ.˜àR\e^S¥Çœ. ™ä±ŒˆÉL~‰—¾æk£#2 Bðꫯ¼bkû¢ˆêLç+\YÅ*ýcSØE1.@±oß¾üÇùÿežz{{·mÛÖ¾P®_¿¾gÏùº > ɯ7—ÜB®rõS>ËØ2ëMNNÖÞo±U”^u‹-Z´haßûMJJúõ×_åßlÁãñññáááöÕ»lÙ²óçÏÛwžŸ­[·ÊÃS¯¿þНm?ãï¼óŽÕjýÏ]ÿYÛkm‹C-†|=D²j__߉'Ú÷fÏ;÷î»ïÊŸØ‚O›4iòÜsÏÙWoRRÒgŸ}VfÅFÒ·oßáÇÛWïÂ… W­ZU¨ð¸¸¸gžy¦ÄwOk.`Û~(ª¢S%ÀºÔíNwuW¿ÃY» O½Ê‹ ¢õÎsþW~Õ«LÓ³p!‰‰ú[Q%à×:Ðá §3ÝèXÌÎÍ›$$àîN¯^:–Ú….Àü¨c™æ&6–øxºucóf=‹­ðß5¤áJV nõw8›7“•EÇŽÔ¨¡c©Úúˆû±ö^e#<œÇㇸçºtaÃ}Š­°šÕ׸¦V¤uZ/ ¯ìFã’´¢Jläõ×o/ѶcññDGSþ "+¤Ìeîæ(tDó½{ë[jKZ¢$ÀFê×g̘?žþø#}úp×]¬^ÝSü*ØìÀŸøi9Ë_çõŒŽ¥rpý:ÕªQ¥ iixè¹ä¼@”FÚ%.U§ºŽ%››Ó§‰Œ$+«ðñ¨(þö7 Àbcϸ‚í#ð¯mfsªLb’ѱTx„¸ý——÷ÇãBOݶíñ"·yë´4ÒS–òR )- š¶Üç¿cÙ¡ýw¦ÅêTf¹R:¹:»SÖ®MrráOs÷n ¢m[Þ|“ÁƒmY ÈÍ%1Ñø3Ҳƌ3Ý&Z¿}ñ­,õE)oJþÂî÷aî®;ŸÖs(ðÿùW žØñ̬ÃÌŽu@é•‘½{yõU7FþVY HOÏß-Ò ,‚ÐTRZÂwoˆ °Xpsûãþ_ѧnî!›_ý£B|KLYf!%½tV„¥@hÇÓá¿èV¦£SºB`/¿ÌÁƒÅ|¬­[3y2ƒÙÖ•OOzö4òŒnûåªí½ê“¨Ýc\êóp…êlMi-ws¶F}eK.9æS÷1¸÷Ñ3Ÿ?ªáfeË–bÚË–LšÄý÷ÛÖø5d%ÀÏõëm.]G¦sj%¹÷r=ÈÈ0*7orä^^6ØJ[ЦuŸå¬# 7+S§þéi³fLšÄ!6*{*ÌEÁWx%ôŒ0:ÊıcX­4i‚——#ŠW`+[·²uëíÇMš°x1û÷3t¨ý퟊"‹Xt ¾øzSÚÞu 9} ~}¯IÀÎ8¨|ó¡Y€Føâ dÄîÛª¯sý)žÊ ãjàˆiE ¤¦ÔsÔæ+5¨á‰çe.ßâ–'žªÅ4lßNr2óçóðÃzNѨEÖCp‚ñ˜ZaÊÜ@ ¸®îV³z>ó³ÉÖÖ™Q8w€ºÔE]0W—€Á Î&[»·\álΟ(Çö0e¢® Ž«K@(¡˜`t•mk¹rlæS&J Ç¥ÇV³º+]¿á£©¬dgc±Ü^¤Â1h5` ®.ÛØv„#FR)¹u «//{æKL0pkŽ«BQ:.ݘÉÌÞônC£©”h«Røø8´|€l²Z‹¢\Z¼ðÈ@££¨¬8E¼ðBI€¡¸nGà~'|*SËNªpÙÙàp ÐnúP` ®+{Ù{ŠSç8gt •Í8r,%.€ëvžçùÞè¼j­ÂÕP`8®+Ùd7¢‘ÑQTbüü22Z‰’ÃqQ È$3€€–´ÜÍn‹Ä~A§OŸ¾~ýzݺužk’››k-  Q#9aÕfݼYø¸Õª×æ¢Ø+7oÞ\±b…^1TB:uê©=¾-_|ñ…sê êß¿™É’IÎ%÷·dÚ?ðæ›oΟ?áÂ…#GŽ,wŒÅ°aÆŸ~ú)((ÈÝݽÌffyrK×®]ûìÙâ¦â Qøú±°mß|ÃûïÛy‹à…—K96åJNN~ä‘GôŠ¡2oÞ¼?I€âÑG´€£››ÛöíÛ£££KOÖŒfyä¥"Y¬ÕjÜõûu*ĸqã’‹.ÝîJxxx¸KP³fÍâó_ºÄøñ NïÞ·ä==ñò";›Ü\<<8{–—_fñb¾úª¤nÞ¼ùûï¿ûúúFDDH†mÁâ…W6Ù¹äzH{Òõë×Mš4éÔ©“dEAòÛ?ù.`Ô¨QN¨øûï¿?þ¼Ö\K'‹,|“,ÙÑàïï 0 ^½z2-ÍA”ÔÎÝäÖ‘øâ‹/Æ÷ÔSOÍž=»ðk5kÒ±#ýûÎOðøãÔª…¯/99¤¥±p!S¦pý:uê0°Ä™»w‰éÚµëÖüî$ðÆ;›ìl²å% J•*@\\ÜÇ,_‘¢X<‹Å2þ|'TÖ½{÷óçÏËla6éS˜ò!>Çs2%;ZªW¯L˜0!ÆAë68«Õš•••››[üËO?ͼyüò '2e ÷Ýw{yª»ïæèÑÛiÆŒÁ³Ä¾, `ëuù³ƒüð“Ì¢UaqäÌåʃSçhŸ™L¯5tÐfÊàh °ïËíj”¿‡}t{D '‡/¿äÒ%àöïáÁر¥`ßY²cDPI€Ž8U4¿*óy—wóÈ{ˆ‡$KV Oi-§kWF”¼L{¿~¥¯&¬$ "â¢.à,g-X|‘½S]I€ RñÿÏÿPµjñ/=õTéYí;KÚ€’£pQp'wºáv™Ë’%k 9*fæ)êÖeRq»6GFrÏ=¥gµï,õ£_aòC¿( Ðux„üÆ!ÊÈSvËyþyš7/|pܸ2×¯ŽŠŠ:sæÌêի價Á,8Å©,Ï¥$@G p2Jª@øã/Yò’%KNŸ>Ý­[·rÅW2æÙø==ùè£?ññaôh‰|žuêÔ –é>¹ÂàÞÉ$S2—’qÑŽ@:é6•\­Zµºuëú8ìÎVsH€†TËéуüãé!T¯®{$™d~ÀÚãÓœžM‘Ù % $@G\±#IfUªÊ['` °-þþóöB”=hs™{žóùOÿÁ?$¥_I€Ž¸¢ È!'€ùËNÀ`õëóÆmÛRÖ„n;È!ç]Þ-xä"?äC™¼JtÄ]@ i¤]à‚S‚’ÂL`CËyñE7vXÈÂTR ü'ÿ¼ÊÕ2ó* ÐWtV¬é¤k£D.‚9$Àæø½¼Fn ¯>öÕ5¬Ñ7’\r§3½èñk\{÷ÊÌ®$@G\ÑœætUª¶£S‚’ aS˹QÛïŠåª•²ï첉/ùò8Ç‹}éC>,Ó* ÐWt~øùã@€S‚’Â`Gü¹äòÿøô"¼¿ó÷’^M'½XƒP%:âŠ. :Õopcû ÏCjU G` а©åh¿ÿúJÀ7|sˆCÚãf4‹&ÁˆB´ƒ³™}šÓ¥” $@GŒw³:]&™…ÖþŽïžæi‡†W æ»]€;ºM»ˆiL"ˆXÈÂýìoHC`Npâ>¨G½L2ßæíÒ Q Æ»+Ö~ôûŒÏ jAMjÖ¡Ž6]ìÇúÐgƒzÑ˙ѤÒ~Ûtï|Ï÷¸0‡9G82’‘î¸kú’K®/¾ãœãs˜“@ N”Tˆ’1~‚pÃ6–±¡„>Ïó‡9 Ô¤f]ê^áÊD&¶¢Õ÷|Jh?ú93Ú‚˜ÃhÛÈ%÷w~Ç8On/=¢®i à÷8ÆâP)÷* Ч® \ÒpàC<ô)ŸncÛG|4‹YÝè6éÞxw¤c~Ÿp,cõí‘Ú„9$À†0 Ð­ðBÜpkJÓ’ Q #NmT% Z°|ÄGíiŸK®@$’˜HbÁžxŽaŒÓâ,Š9$@æ–£ûX@Qò;òY”èˆñÃmhó%ÎBÈ@m#z£0‡¸‚ (J±. t”èˆñÃùLejþe¡B”¢ÎÁ`ޏ(XåŒÅU\PjÿàE7¡Iwº;6²²0“¸ZG Ðp  JtÄ…\0ŠQ(¼9Ä“<)¹§ã0‡¨Ž€¢(.ä –YÌ*ø›ã‹ï£8i§£R0‡h>;°ª#`,®å€v´Ë‹ÕcXAe–ìèÆi pôìÀ'N¸¹¹Én[úÿ(`,®å4ÞæíêÜ^¦êIž”)¹jÕªîîîYYY匰$Ì!v`kG@aëYR.ÀX\ÎÕ©®M#oOût)YÛZW­ ,ƒã:åÙG@¹£0~‚p±ŒaL{ÚË_ T‹ˆËà莀}gI¹c1`v ÌWÄ ·9ÌiIKÉ’­V«ÅbQ[‰È`ÇEA'¸%FaÀ=2._5H‘——çááÀ÷b °#~Õ0=®8h+ŽÞM ³H€8Á¨Ž€±¸âp ­8z sI€ãf*P1 p¨hTt pôì@å*"ÊHQ9]€@ä‘'?)@ VD” Â`kü¶Þ#¤:å¤0‡hÈ·[§ªŽ@ED¹)Ì!¶Æoë=BÊTD” Â`+Îé(`,.:AØ&”Ø„«uÔp ±àTGÀ(TG@Qå¤0‡h¸š PcQÃR˜CÔEAEQÔp æ[Q. 2à» •%6!ßrl pww¯]»vµjÕlŠG ‹Kì&TNÜÜÜêÔ©S£F }‹-ˆ9$ÀѪU«ž={ÖÖ¨TGÀXÌàš5kvæÌ}Ë,„9$@ÃqÃö¡:Æb†±'` pôEAûP.ÀXÌpEÀ ˜ClÅ [ ¡\€Ñ( …™$ÀÕ:j8ÐXÌ05È ˜C\³# ¹›:JtÁ „@ż(¶ºGw” 0å¤0‡ØwQP š5(…9$@ÃqSƒìC ‹”ÂL r•å¤0‡8zv }(`,ÊHa¦o›º(¨(ˆrRTN fV”  ájUGÀX”  . *Š¢\€æ[Q+jjf’Wë¨á@cQ„¥¨¸‘Ä5;Zyä dÃS #ÊHa ÐpµÙØÞP #j8P sH€\À/¿ü²gÏG/"¬$@GÌ0xñâÅ={ö8tí0sH@é¬gýqŽ—’1Ãp 0‡ØA,±íiŽs_ð…#ÊŸÁŒ›ÜÀ€Ò#*„’1ƒ pf’[[ŽvƒÀë¼~–³úFò¿}ȇZá6eT #ÊHa °/þ! éKßK\Å(ù=¿Ê$‹¬x ƒŒQŒê@›ò* Ðå¤0‡hØÚr,Xæ1¯µ6°á9žÓ+Œ±ŒÝǾ¦4ýˆlÍ«$@G” Â`wüµ¨µ…,óqþMÄvcÅú8/b‘>_óµ?þ¶– $@G” ÂPâ‰_Æ2O<§1m clÚ ¼ V¬Cò9Ÿû㿊U-iiG!JtD¹)Ì$v·œ! YÁ |æ1¯%-·³ÝÖV²2‚ˆoø¦:Õ7±éî±/%:¢\€æ€òÇß~;ÙÙ”¦G9CÌP†î`GÙõ"6±éÈÀSœjLãììHG»ÃP #ÊHa¦o[9ßËܹ}S˜â…×W|Õ….5©9‘‰kY[èžÂ“œ\Ū)L©Nõ{¹w‹ ü˜s¸1˃’1à ÂN@¹€‚xáõ7þö}ʧŸñÙYÎNcšöR á–MvAE¨Oý'yr cB)JtÄ ¨ˆ É ¡WË %t*S'3ùk¾þ™Ÿæçù1´üu¨ÓšÖÑDw¥k,±tk±JtÄ w :sH€#âwÃm(Có×L'ÝŠÕŠÕ÷@u¯NCI€Ž( …9$À Øq‘ߔ舔ÂL`‚–£$@GÔEA)Ì!=þ|”èˆrR˜C4LÐr”èˆrR˜C*züù( Ðå¤0‡8ï¾ûnþüùW¯^uh-JtÄ W–.]š••õàƒúùùé[r>f’‡¶œI“&íÛ·¯C‡AA²›Ø’1ü€W^y%%%%>>^I@é8!~çœ(%:b†„Õ>6áЖ£$ Âa†á@%’( (І•¸J*æqj7!ITG@Qå¤0‡¨Ž€¢(æq•Š.Ê( ¢\€ÊH¢$ Â¡\€æ å1‰ °X,J\%Ž ï„yyy½€Y$@uE©ð.À9cæ ÕP¤ÂOV rŠ¢TøŽ€’[Q.@QÕ \€¢(ÊHa pJ*ÊHa& PEA”  :Š¢TøUƒ”ØŠC[Έ#¢££ëׯï¸*P +N•ÀÍÍM߆äçç÷Æo8nÉ0 sH€â3fŒ£«@I€®8[,K^^žB¯Ï/ à­·ÞÒ¥¨Rˆˆˆxã75jäèŠJïÞ½ƒƒƒÛµkgt åeüøñiiiŽÖýJ‚ÅÉ¿l^^^·nݲZ­ŽžÒ«P(dp¶ ˜8qbE·Ó …™p¶ P(.Åÿã;Î#âÓIEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/dataflow.png0000644000000000000000000000013215055603742021447 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.528822674 30 ctime=1764935922.839571314 rsyslog-8.2512.0/doc/source/whitepapers/dataflow.png0000664000175000017500000006003115055603742021113 0ustar00rgerrger‰PNG  IHDR1–ÍÌsBITÛáOà pHYsÐй‹çŸ IDATxœìÝy~üÝB&“mll444TUUÇŽ+)))..>dÈ––:N§Óëêêrss‹‹‹ß½{—žžŽ~ÈÈÈlذaõêÕ’’’¸~ ˆ'ÀÄAüêóçÏK–,yøð!@\\ÜÛÛÛÆÆfòäÉì·ÐØØxøðáèèè/_¾† vüøqKKKNE ñ ˜ ˆ/;wnÕªU555²²²îîî"""}níîÝ»¡¡¡hŽYµjUtt´˜˜vÁB|&â3t:}ýúõIII€ $&&6¬ÿÍ"²ÿþÍ›7·´´P(”Ó§O«««÷¿YˆÁÄAüäéÓ§öööoß¾Û»wïÊ•+±m¿  `Ù²e………‘‘‘^^^Û. ÞñcÇŽ¹¹¹!¢©©yúôiNôÒÜÜìëë ÈìÙ³/]º$$$Ä‰Ž žñ‡˜˜˜M›6!âáá±oß>AAAŽv—••µ`Á‚êêê3f¤§§“Éd¬Znkkc0XµÆQƒô„ ˆçýùçŸ"‘xàÀ®uZTT4jÔ(€®®î?°jVOOï¯=v}ÿþ«OÍ_à¤Gâi‚øúúFGG ;vÌÑÑ‘k]«ªªfeeÍš5+;;ÛØØøÖ­[222X5.,,L$±j s---È M‰‚xƒÁXµjUbb¢°°ð™3g,XÀå³²²LMM_¾|9}úôÛ·o3“–ïÝ»§««‹ISœ ++[QQw¸áÝŒ Aƒ\{{»ƒƒCbb¢¸¸ø¥K—¸ŸPrrr÷ïß×ÒÒzóæ‘‘ÑÛ·oq â&˜ ˆµ¶¶ZZZž9sFRRòæÍ›fff83|øð;wî}úôÉÀÀ ¸¸Ç` .€‰‚xQiiéíÛ·îîîx‡$%%wíÚ%((XUUuêÔ)¼Ã8 &âi»wï Ä; ððáCssóööv¿Ül õL Ä»F-((¸cÇŽuëÖáøu|ûöíÙ³g×ÖÖ¢ú`î&â]iii¢¢¢û÷ï_±bEGG÷c¸xñâܹsÝÝÝmmm¹Ä}01@O³´´¼víÚ!CŽ?ngg×ÖÖÆÍÞOž>>·nÝJNN–••ŪýÎÎÎ;wnÙ²¥½½]KKëÔ©S'NĪñÁÌÇÇ'!!ï(Ø¢¨¨øáØ ˆŸˆˆˆÄÆÆÎž=ÛÅÅåÖ­[jjj)))æææýoùóç϶¶¶ÙÙÙD"Ñ××7""‚w–a°µµ9yòd¯ÆÇǯY³àââ‚.lÇ›Èdr–_å4ƒñãÇô1L ÄæÌ™óòåK—ëׯ[XX˜››÷mdéÇ»víJNNnii‘““;qâÄÌ™31¹ÏêëëëëëüøÑÜÜ,**Ú}fbàå¬ˆŽŽÆ|Å= •••)**¢áÅgâK222W¯^ݲe‹°°pVVÖœ9s(JHHȳgÏØ¬]YYyèÐ!SSÓqãÆ%$$´¶¶®X±âõë×<•iii666óæÍ»rå  ¤¤ÄÐÐÐÈÈÈÁÁpòäÉÒÒRccãÇS©ÔÂÂB}}}}}}ƒ¢¢"´ …âáᡦ¦‡ç'áðŒ‚ø@ óöö>|øðž={JJJ""""""ÄÄÄ444TUUÇŽ+))I&“‡ ÒÜÜL§Óétz]]]^^^QQѧOŸÐ"$$äàààçç7a¼?S.\¸œœÜÞÞ¾nÝ:[[ÛuëÖíÙ³G[[ îèè¸sçÎ{÷îâââ¼¼¼bbb´µµŸ>}êåå…Ö›ª­­ 6l˜ŽŽÎúõëñý8|&âod2yÓ¦MëÖ­ËÌÌLOOOOOÿôéÓ£G=zôë7Š‹‹›™™Y[[[YY 6Œ;ÑöVUUUnnîÒ¥K¯^½ª¯¯///×ÖÖô8ÛîË—/è«Ó¦Mûúõ+ºqèСòòòó`L 4 Μ9sæÌ™qqqUUUEEEÅÅÅ555õõõ¢¢¢d2™L&KHH¨©©Q(eeeÞŸ³vþüùmÛ¶999.^¼(//ÿìÙ³©S§2 47t:5jTNNzÆ€®K àýÉk`b€ fĈ4F£áΜ9“ššŠ>655]»vmll¬››‰DRTT.**rqqQVVÞ³gNǶ#IIÉ{÷î]ºt)$$„¹¯±---544ÐÇÍÍÍ{÷îUVV dV£ë-ƒáëë«§§g``àëëû³ÏÏ~›½ÚAØX»v-:Áõùógooï1cÆc~-//ßÐРP(+V¬°´´ì±J§ô¤‰N§ïرCIIiëÖ­õõõ½m0&&†H$>~üøáDZ±±=îA¿akkëèèø³W™ß ... CTTtË–-,kjj¶mÛ6vìXOOÏ>`ÕWAAÁˆ#Ðö}}}¯_¿ŽVIzôèQLLŒ——&½ØÛÛOŸ>ÝÄÄÄÔÔÔÜÜÜÒÒrÞ¼y ,X´h‘ݲe˯\¹"%%Åòƺºº°°0%%¥¨¨¨¦¦&ö{LMMefÿ³gÏ¢©T*ú@CC£kÝ@…Bqvv¦P(èØZ×=Á‹ öâ“#ñžââbôoþ·{ÖÕÕ™™™Í˜1£©©©Ç&Mš„UTÛ¶mÌ;—F£éêꢥú”””F5lØ02™,((ø‹o"‘hoo¯«« xüøqßb=z4F›>}znn.‚ ***èö‰'2÷¡P(1114Í××·o½üñÇLJHÉÈȸ¹¹:ôÛ~©Tj×§èæQ]]ùïÏTVV¶¬¬ìãÇ&&&Ý÷DØþ@o½UTTDÎ|† þ†V¥nnn¾r劭­mII‰››@PPPHIIa0.[¶,...55]€@ $&&R(…B122zôè‘»»;;ÅGkkk»NHfA žîJpvvÞ²e‹­­m?>îÿ]c`>eÖÅc©’äååÕÿó†ÔÔT‘În:::˜étº··wccc÷·5ÊÇÇgåÊ•ÞÞÞlö(&&V__/!!hllì¾°O÷ÿ[2™¬  ¨©©ùõžìƒ‰‚ø÷«R«««oÛ¶MøDDD˜ïß¿oiiɲ?@X°`Á¶mÛTTT°ÿüÿÉ*I“'O9rä¯÷ ëžÆŽëçççââ",,Ü«—,Y¹}ûv@TT”ºH$¢%Ó«««Á¿ôétzyy9`èСÝ÷}Ê01@Ã¥*µ”””‘‘Q/EEE±l¡Ñh‘‘‘èð&˜…XžR©ÔîU’8­ºº:&&¦ë– &øûû;88üzTígÖ¯_ïçç§§§G$õôôÂÂÂÐíººº:::è·?³n ½½½””TPPгgÏöíÛ×}O–Ù &âcbĈàààU«V õ¹)~©®®lnnŽãZ@,ck˜€‰‚ $$$ûøø 2ïX¸A– L a`Ë–-Ýçy `ágWà€2"A¾ø(+àUX‰À3‚xË|½²²²•+W677#’pùòåÔÔTiii“ÐÐÐ;v0Ÿ.\¸°Ç©|ºººß¾}C/Æ@?ñ+ƒáçç÷àÁ"‘¨¯¯¿sçÎsW Ë|½µk×FEEihh|üøÑÝݽ´´4==-8vìóé¬Y³ºOåC +©ªªâü©xL į˜•8ÁÁÁqqq6lÀ;(Œ±Ì×{õêó3¶µµ%%%EGG777;::ZXXt}ÚãT>)))˜Øñ«ÔÔÔŒŒ ô±¿¿ÿ¬Y³Ð/M*•ŠÞ¨¡¡qñâÅ®c/héÍßîÀ;XæëQ(”½{÷N˜0ÐÞÞÞÑÑahhØÔÔ¤¥¥eaa¡¥¥Å|ÚãT¾þL=T`b€ ~ÕÜÜŒV[ÉäWLc{¹uëVowÀË|½ýû÷{zzÒét‰D£ÑrssZ[[W­ZX¼x1óéÌ™397•oÀƒ‰‚ø;•8YÆ^z»î(J×ùzŠŠŠ×®]ûÙΗ/_îúôSù _ƒ‰‚øK%Nt{×úšêêê]Ç^ØÜâ„ÏŸ?¿xñï(~Šy%ÀÄAü ­Ä©¯¯_WW§©©yüøqt{×úš,c/è k¿Ýâ„ðððððp¼£` L į˜•8sss===kkkÑÇXêkv{ùí¶äååÑ…6yßèÑ£L 4hiieggãôSxGÑ m: AÔO¹¹¹xÇ𪪪bbbxGA4x L:ïþ#//OSSï( ‚¯ÿ»Æ0mÚ4|ã¼zõª©© ï( ‚;‘HÌÉÉÁ; ¥¥•——‡wAƒ¼ø AýL AÐÀy á€ÇË òê 01@ï*//÷îݸqãðZ[[¯^½ŠUkîîîX5a&âEŠŠŠ3f̸{÷®¶¶öÕ«Wõôôð§¡¡aÞ¼y=>|ø’%KúÓ”šš@À*0ŽÄ;|D"±³³ïHþï®$8‚PmmmçÏŸ'“É/^œ9s&^‘üøñÃÂÂ"''G^^þöíÛ'NÄ+ˆ;àÅgâQBBBgΜY±bN·²²ºté.aTTTçääŒ7.33f…Á&â]$éÈ‘#ëׯoiiY´hÑéÓ§¹ÀÇŒŒ ¨TjffæØ±c¹„ ˜ ˆwµ¶¶ÆÄÄ„öövGGÇÇs­÷ׯ_½{÷nÚ´i÷îÝ“••åZ×¾`b€ ^ÔÙÙ™œœ~üPQQøøø:tˆ@ ÄÇÇëéé½yó†C½·´´lذÁÀÀàßÿ5kÖÍ›7Ñe¥¡Á&â!™™™úúúóçÏõês#óz¯»»û£G”••Ÿ={¦¥¥uìØ1ÌxõꕎŽNll¬  à®]»nÞ¼),,Œy/ƒ‰‚x‹/,--i4ÚãÇ»n'‰ãÇg>ÕÕÕÍËËstt¤Óé®®®‹/®©©Á$Aâãã§M›öòåˉ'>~üØÇLJH„_ƒü©CÎ>|ø`oo?eÊ”×^VPPíºEBBâĉ§OŸ–””<þ¼ššÚÁƒÛÚÚúÃýû÷===›››ÝÝÝsss§L™ÒŸ!¾áæû÷ïk×®UUU=}ú4ƒÁèqôCwK—.}ñâ…žžÞ—/_Ö¬Yƒ^ .**êUÍÍÍqqqcÆŒ166ÎÌÌ”––¾xñâáÇÅÅÅ{ýa –Ä€ |466üº>Ä/&”)(( 2dÈâÅ‹ÕÕÕ)Š‚‚‚¤¤$™LE¤®®ŽN§×ÖÖæåå¿}ûöÂ… ‚†îåååéé9tèPì?*Äo`I Âßׯ_KJJ^¿~}ðàÁ‚‚‚®/%$$xxxü¶…¿þúëÆçÏŸ¯¯¯ïþ*‰Dêño\@@`æÌ™666...ð0ú?ðW‚ð''''''G§Ó „…… ³ì3›%(-Z´hÑ¢ÄÄÄ7n¼}û¶¸¸¸¨¨¨¢¢¢¶¶–N§755„¡C‡Š‹‹KJJª©©©ªªR©Ô¹sçÂ|u×‹ß —¤¤¤>ô¿fÍš>¼‚ŠŠ 777@TTÔÛ·o÷ïßnÿÙ5† –í Þ_±¯¿+}Ë €øøø¾½‚ A\\\ªªªÌÍÍ×­[L&“RRRüñGÿÛ‡Yê•^üºP©T…BñððPSS‹‹‹C·S(ggg …rçÎæn ÀÉ“'KKK¹Yã‚øK\\Ü7FŒ‘””D ddd6nÜØG‚ ì‰D„ “&MBDVVöÓ§OT*Ý.++[VVöñãGæn‚¨««w}ão¡÷M?xð€!hÀxùò¥ˆˆ@¸tésc]]ÝðáÜœð‹ ¼z}ÝièСòòò‰„n!“É –˜‚ôªe:Ø·oŸAo£‚ >ÕÒÒbooßÒÒ²jÕª¹sç2·KHH¶´´à4hõzä±û=×t:½¼¼¼¼¼½šH$Òéô/_¾TWW£;°™!ÐLsþüùÌÌÌÞFA|Êßß¿  @EE%::šå%OOO\¢‚9 .IIIIÍž=;((àáá¡««Êœ)cbbbiiyêÔ©_·ƒÎûg0®®®MMMý ‚xÜÍ›7ãââ„„„N:%&&Æòª®®..AƒܨTjaaaÿCA'¸Mœ8ñõë×7nܳgOÿÛ„ žUUU¥®®þíÛ·¨¨(___¼Ã ÿçnbÛ²e‹  `llì£GðŽ‚8ÈÍÍíÛ·o3fÌðööÆ;ú &§ L'Nô÷÷g0+V¬€WÞ êСC—.]’––>~ü8œdñ^ü ¦R©¯_¿ Ã;Â^IIɦM›‡=z4Þá@+^L BBBIIIÑÑÑ999x‡AXjkk³··ojjrqqY´hÞá@Px11¦NêããÓÙÙ¹bÅŠÖÖV¼Ã Ì„„„äåå7.66ïX ¨g<šaaaªªª¯^½Úºu+Þ±@6þùçŸÝ»w ¤¤¤ 2ïp ¨g¼›DDDŽ;F"‘¢¢¢òòòð‚ú«¦¦ÆÉɉÁ`„††êèèàýï&€®®î† :::\\\ú¹¤-áÎÃã¼¼ÜÐÐ000ïX èWx:1ÂÃÃ'L˜ðòåËíÛ·ã õ]rròùóç%%%Ož<ɬ3A¼‰×ƒ¨¨èÑ£G‰DâŽ;^¼xw8Ôïß¿_¿~=àÀcÇŽÅ;ú ^O CCõk×¶µµ­X±¢££ïp ¨w:::–-[foow8ô{|Û·oWVVÎËËÛ¹s'Þ±@P‡ggg+((À¥ !~Á‰A\\üÈ‘#!<<üÕ«Wx‡Aìzøðá¶mÛH$ÒÉ“'%%%ñ‚ØÂ‰`ll¼jÕªÖÖÖ+Vô§,qM}}½££cgg§¿¿¿‘‘Þá@»ø&1vîÜ9vìØœœœîKš@òôô,--ÕÖÖ†U¿ þÂO‰aÈ!‡&aaa%%%x‡A¿ræÌ™””2™œ’’"((ˆw8Ô ü”¦¦¦nnn---®®® ïp ¨g?~\³f &&füøñx‡A½Ãg‰°k×.yyùGÁdoêìì\¾|ymm­««+Þá@P¯ñ_b””ݲe ‘H<~üø°aøÙu}}ý_ý•ŸŸ_\\üæÍ›ººº®)aÈ!’’’ŠŠŠªªªZZZS§N2e 7à¾ËËËCØðãÇ999À¾}ûØÙ‚¸ ¡¡½¢àããõNëêê"""TUU{üƒ•’’êñ¥¡C‡zzzææær-Tˆ_–/_ιoù>غu«‚‚;{^ºtÉÚÚšL&¿|ùRQQ‘ÓAÐo¹»»9rDCC#;;[XX˜ÓÝDFFž;w-#""âàà ªªªªªJ¥R%%%%$$˜;Óéôººº×¯_¦¤¤Ðétô¥Ù³gÐh4N ñ ‚ xÇÐw§Nš1cFFF@À;þF§Ó¿ÿ^YYùýû÷†††Q£FÉÈÈŒ9røðáðÿ–.\°±±}öì…Báh_mmmÁÁÁÑÑÑ ƒD"mÚ´ÉÒÒÒÈȨWê¹¹¹—.]ŠŠŠjii,]ºôàÁƒpz6xŸ²ôË¿ÿþ+##8xð ޱ𙖖–›7oúúú)**þâ …@ üñÇêêê666III•••xÇ΋¾|ù‚^Q8pà§û*))ÑÒÒB4îîîUUUýi­¡¡ÁÛÛ[@@0vìØ`'Ä¿ø;1 ò÷߆ òñãG¼cáOž ÌÿÊÊÊäååRRRgΜÁ¼}¦û÷ï3 ))ùìÙ3Îuñ²pÆ8{öì’%K$%% »nÿþ=<<üÀúúú?»«ܺu«¼¼üúõëæææ6{îܹ 6|ûöMHHhóæÍAAA"""ýo6##ÃÝݽ¬¬ŒD"­Y³&""‚s_ß’’’èMúÝGÀxJYY™§§§††ÆóçÏ1löÅ‹³gÏþþýûÔ©S¯\¹‚^Wã:nggwíÚ5QQÑ¿þúkΜ9íâA$1.\˜––fiiyåÊ•®ÛKKK÷ìÙƒ È8€V°áM–––×®]Ã01|üøÑÝÝýöíÛ€éÓ§'$$`››››ÃÃÃwïÞÝÞÞ.++{ðàAkkk ÛgBC}}=¶ƒ'˜{ùò¥ºº:¶‰!;;{Μ9555sæÌáZjd0ëÖ­‹JII±µµÅ°ñªª*+++ ä ^˜¾Ž O IDATœÏX°óíÛ7iiiÀñãÇ»n·±±155E‡’¸pÇH ‡fX %]»v ½õPZZúÈ‘#œ»(ZPP```€þ:­^½º­­ ó.Ðs‘úúzÌ[ƺ,9†CId2`kkÛÚÚŠU³lò÷÷H¤£GbØì—/_ðù²ë=### ?8Àû3üñGll¬££ãÆMMMeee÷îÝûûï¿'L˜0a¼äªÝ»wûûûwvvZ[[£ÅŸ9וJÍÊÊŠŒŒ =xð`IIÉùóç¹\ b@ºté’]KK‹‹‹Kbb".ò³Ø±c‡„„D`` ››[CCƒ——†9òêÕ«6ˆ­üü|www¼£ÀÞ™ csçÎX[[#ÒÑÑ¡®®}ª££óáÃ==½Ë—/s­ë&55ÕÁÁ¡½½=$$$&&ߙ瞞žIII¡¡¡~~~8FqÍ@K rrr{öì¬[·.((ˆ¹½¡¡¿ ¸$77wÚ´i?VTT|ôèÑüù󹃬¬ì½{÷æÏŸ‰ ”»¸)&&†Á`Œ9rõêÕxÇ666èm GŽÁ;ˆTbhmm-,,9r$…B©®®®®®f¾4àí[· >þL£ÑrrrÔÔÔðŠDDDääÉ“;wîXXXÀÜÐ[è)Bee¥‘‘QYY¾ÁÔÖÖΞ=»  ß0 nâûÄPWW·dÉMMÍaƉˆˆ¨©©YYY±ìÆ,$9P=z´µµUPPpóæÍÇÇ;àââ2yòdÀÍ›7ÛÛÛñ‡Ï (Êû÷p\ἪªjÆŒ>D§×¡%• ïƒ¤¤dLLŒ¦¦fmmí/vðg ¨öööyóæíÝ»ß0^¾|©­­ŸŸ˲öÇÞ½{MLLг@lg̱‰ÙµŠŠ Ëô h`ãûÄøã?Ž;öäÉæÝôÝ øÄ€ÊÙÚÚ2ŒM›6­X±¢µµ—H.^¼h``PVV¦§§‡ùB}#&&võêUKKËÊÊÊ3fº ÞèÑ£óóó±³g .H¤Ý»w£Ñ¢LýŸ²Û‡y £G¦Ñhýì}XÍc˜>}: ++ }ÚÑÑáêêŠþ߆„„pº&ö¡C‡ÐÊÞ³fÍ¢ÓéèÆªª*ÀÈ‘#ûß>œÇÀûaݺu\ûêÿ™ÔÔÔÊÊÊþ·#&&ö矺ººnÞ¼ùܹs‚ðWÁ…ººzNN΢E‹²²²tttüýý8ºÒdFFÆêÕ«ß½{'))yæÌ ÎõÅ&IIÉ{÷î•——ÛÙÙÍœ9³Ç} ›Kž±¿''H¤#GŽLœ8Ñßß?<<üöíÛ§NRRR¼£êêjww÷´´4@@@wjªC<ŠH$âŸA¦L™°8cè*33m5HÎP6l@/ÿN˜0áîÝ»ØEúÿ}ÿþÝÞÞýïUWW¯¨¨èú*Žg “&MBP©Ô#GŽOš4 =P@DUUÕÅÅÅÜÜ|ûöí“'O666þóÏ?KKKMMM Xöd§S10eee¡ç‚'Ožìg/,îܹƒN\:tèÙ³gY^…g ƒÊ¿ùÌÈÈèéÓ§ÇŽóòò$“Ÿ™H$ÒÞ½{mmm=<< gΜ¹|ùòÝ»wcu3+‚ Gõóóûñㇸ¸xXXØÆyívÆ‚‚‚#F,[¶ÌÕÕõÇfffh¡Ðšš___UUÕñãǧ§§S(AæÎ¥¡¡V¥½uëV×=ñþ(`hh˜ŸŸ¿jÕª³gÏ:::¦¦¦žhii655iiiQ(”½{÷¢…x™“òxsÝÉÉÉÒÒÒÇÇçøñã;wîŒ555µ¶¶ž7o;7õ544\¿~===ýÊ•+õõõ™‹/¢Ë>ó ´´4›æææ+W®ØÚÚ–””¸¹¹…”””“'O–––/[¶,...55uåÊ•˜˜H¡P ÅÈÈèÑ£GîîîëׯÇåSÌŸ?ÇŽ¸tͦéÓ§£Gƒ%1ôSW2ñ½ Ù[JJJ7nܸråÊþýûoݺE$ÍÍÍeddFŽÙõ_2™üõë×ÊÊÊïß¿£ÿ~ûöíúõëÌkørrr^^^è’+𿺄›`b`K]]±±1‚ h")))ô6•W¯^mذݧ­­-666--M[[;** ÏpÙ&((È s ¬ Ãî éÇzæÌ™ÔÔTô±©©éÚµkcccÝÜÜH$’¢¢â‰'&&&–––è-±±±îîîH$Â:á}[º^É]ÎFY.W b»ü!Aè B(eeåëׯX*G1Kû ³j?~ÌÒsH0??Ÿs¡01ôËþýûùèr%A;`b` ËHæSEEÅ^]¼…xDjjjTT”  à‘#Gp\Ôh Ad°ã£ƒxGÁ|s `ÿMtÂÅÞ½{?~üðáC´ÂÔW®\ ¨¨¨À;î¹{÷îúõë¿ÿŽw ؃‰w}ÿþ}ÕªUèdÚ‡@ „††.Z´èÍ›7Üゥ©éÁƒèœjîôøöí[îô… KKËk×®)**®Y³æÃ‡x‡Ã fffÿüóϸqãBCCÑy‚L ¼KFFfذa¦¦¦h ¼#˜··÷… ¨Tª§§'7»þý÷_!!!t-×:Û°aF»yó&×:å&"‘¸mÛ¶–––ƒNœ8ÑÞÞþåË—êK^^ÞØØXSSóÎ;ê‚aóæÍt:=<<\YYyÏž=---8ƃ!>N ;??¿‘#GfddÌ™3GMMíèÑ£æ7@¡P,--ÛÛÛãããÇ÷çŸrgin°°°yóæUVV£h9-<<<++ËÜÜ|Ú´iiiiÜé”›¬¬¬Ð Z§OŸÖÐа²²zðàæ¡w ^ºt)$$„¹—ÿÏ%K– £‘ÿþû¯··÷„ Ž;ÖÙÙÉýH°ÅljáóçÏöööÿüóÏÎaaaèãW¯^¹¹¹;6<<|À,§åããƒ> Óé[¶l?~üÁƒ™uŠ8äË—/JJJ^^^Ð××_¼x1wf{M™2ÅÆÆðìÙ³… Nž<ùÔ©S\èškºÖBäêÕ«FFFFFFW¯^Åüï´k%‚+VXZZêëëëëëaÛ]½½½™OËËË]]]ÕÔÔ.\¸Ð·ÏË`0|}}õôô |}}–íâããÙo³W;£ø81ÈËË+))͘1CMMíàÁƒÜ9ØdÁ…ƒ”•+Wv­¯òýû÷ÐÐP…Õ«Wã2:-†V/@UTT¬Y³†J¥öùö÷÷700ˆŽŽ^·nÝéÓ§kjj8Ô‹­[·2'Á¼zõÊÁÁAEE%11±­­­o ÚÚÚ:::þìUæ7‚‹‹KßÚï-###´HpW<°²²ÒÐÐ8}ú4†‰¥Áõë×Ñ*I=Љ‰ÁdFƒÁ(**z÷îݧOŸ***jjjY\\]]Y ÛØØèêêöa¤+&&†H$¢wF ÇÆÆö¸§ü\v›N§=ý’’’^^^¯_¿îqOOOOв۪ªªNNNªªªÌu"Ñõ[F­§§§§§§¯¯ÿêÕ«¾5Îô³²Û/^üÙnÞ¼y÷ïßG~YvGhÙmOOOŸíÛ·ïÝ»7!!!99ùìÙ³—.]º}ûvDDDŸNOOYwºe·qÁNÙíåË—wÿ°£Gމ‰illD÷ùmÙm7‹Q£E7‡¾páB+++333ccc}}ý©S§NžtΪSWWÿÙ‘>|ø¨Q£~±$†©©éÓ§OѲÛÎÎοíwÚ´iuuuèㆆô1óG©®®~âÄ 111vèÐ!¤Û·S×=aÙù×Ðìß¾}û¿ï—^ÿ·q@ßÖc8}út×@˜={öåË—;;;»îÖÏÄ ++[VVöñãGtËüQTT4cÆŒ'Ož ’““3kÖ¬¾5΄&ô˜ËØØxÚ´i eìØ±#FŒøõX‡²²²àÕÄПkk뢢"þJ jjj—.]ºpá¹sçNŸ>}âĉcÇŽ>|8>>>66600ðguÜF޹}ûöÚÚZ6Crrò¡C‡bbbЕ銋‹ ííí‘ÿ~#Lš4©   ûAŒªªêÊ•+©Tjllì¯ûb&†>ÿ(¢¢¢>>>è4 þ$–„Ç|ÚõïÑÔÔ´Ïí#ÿK T*u„ ²²²Ã† 2dˆP¯>µ””zàÏNb R©]Ÿ22X¾î»þ°|;±ì‰ôæø€™z1Á­ÏK#1Wâ„%K–ÄÇÇ3/p!róæÍ›7o*))­^½zÅŠÒÒÒýï…L&£—˜˜ch¹¤îuû_.©k€ß"‘HÎÎÎ[·nõõõýíÎ ÃÏÏïÁƒD"Q__çÎÜ[‰‰ikkkþŸ–––æ.jjjÐã¾ß›››‹ï'}ÐÖÖ6oÞ¼>¼±²²200055•ÍbæÜ/FM .\¸ ôsÂÂÂAAA‡fy£€€€‹‹KhhèèÑ£™O1‡y•¤!C†dfföøR[[[[[[kkkCCƒAjüøñ¾¾¾Ë—/?{ö,›=Љ‰Õ××£GBè¡UWÝÿRº;ýlOöõ"1ôyÁ<Ž&;mÚ4–áþ>øúú†……-[¶ =]è:^^^`ž3¢}Ýë8zyyõsp3((ÈÀÀ@\\\LL ý·ººZ[[»û­æææQQQìOÜe_‚ƒƒãââ˜9ÊÃÃãY¶¶¶Ïž=ë¾}êÔ©>>>666AAAœ c$iÞ¼y‚‚‚=iooOLLìñ»¶¶vDD„©©)Fûm/¸£& ,øuT))),o±µµ GKŠaâg•¨Tj÷*I‚&B2™|üøñîYaÊ”)~~~666½­ò½dÉ’ÈÈÈíÛ·¢¢¢Ð‘‘H¤ÓéuuuÕÕÕà¿_ú,ßN,{‚>eˆ^$*•ZXXØ}!$ …¢­­““³oß¾™3g¢»444òóó».®„.«ô[õõõ555µµµµµµ,ºoonnþYSMMMGŽÉÏÏGÇ©ú ­SýìÙ³}ûöuÝΉ:ކ††æææ]·ìÝ»—%+¨««ïÚµ«·‹«¤¦¦2ËôûûûÏš5 M ]d/^ì¾ÂÄowè³'Ožüý÷ß]·sss___“þ´Œ#!!¡ôôôŸ½Ò=+¨©©mݺÕÚÚšýª¼YŒ:66¶ëâêfffÛ·o×ÒÒ¶ÞQ__ϲ(›‰‰‰¿¿¿™™Yß\¿~½ŸŸŸžž‘HÔÓÓcÞ”èáá¡«««££ƒ~û3«ÉÚÛÛ³|;±ìɲs/Baó:P%++ûéÓ§ÆÆFæXV#\èw7™Lîí¥ˆˆº qwcÇŽý믿~_cÀ|EÙõxñ¹¦¦¦ëռѣG'%%±\AAØ»øÌ2|©©©‰>èú#³´´|þü9‚ eeeÌQÚßîð3¿]ó¹ëBBBNNN/_¾ì¾[ß®1 —(ÑËÌá]ô³phõïß^|®««“’’êú+:~üøS§N±ü@Ù¹Æ`hhøùógôñ»wïÌÍÍ_½z¥§§ghhèèèˆn÷ôôœ3gNJJ zAWW½²¸¸Ý¡û_ëϰ³æs}}=óËHWW÷îÝ»=îÖ‡5Ÿ¹Í5Ÿ™)ˆDâüùó³³³{Üý‹Ï}€á·S_®1 ºŸ{b;Â…V*•”””’’:t¨””Ô/ ÿÒét4¤®ÄÄÄüýý}||~–3øÅáÇћµ‡ âçç·qãF11±¾5ÅÎð%Ë ½Ý¡W._¾ŒàJHH¬\¹ÒËË‹y&XŠ¥wõÛáM­ÛzàÀÚÚZôñ˜1cBBBœ™ë)ö £NHH¨©©™4iRDDD¯Î~øTeeåÞ½{ííí7oÞŒ®Ñ20ôú7²ûÛ®ÌÌL##£^…Óu>0@X¼xñ®]»ºg‹>Ãk}Çööö}ûö ¸»»‡……ÉÈÈô§5–áKt²øïL]]½ë lîУFòòòZ¹r%§×Žfކºoš™™±ŒŒ1×mE¿j1ÔÔÔ‘‘ ôððƶ µ¶¶¦¥¥%'';88 ’å3cbb\]]½½½1üªéN|;aPvÛ®Þ%uvv&$$0ŸjhhÄÆÆ˜(Ïž=;eÊ”ÈÈHLFÐáK}}ýºº:MMMôôü÷GÖã ¿Ý¡=zäããcooϹÂÅèº{€µk×vÝÞõv2×mÅ<ôšóöíÛׯ_/..Žyûø¢Óéè oxÂ=¿ž´Á¿z‘мÔýÜ“H$¢«ë¡<==YîbžÏrÂåË—?~ü>|xxx¸»»û@:Z111qppÀª5‰´{÷n@nn®§§gmmí°aÃ@·Y÷&~»C •úßÎ/tJúYë>2Æ\·[‚H¤?Ô¯ôw‰/`5N8P”`,Ô³ÿ~Õ«Wÿù矿˜ȧ˜w`KKK+;;›-ó æð&Ë⬀í7{‹@ °œ¸@ì())qssCײNII)++ë:ôwùòåÔÔTiii“ÐÐÐ;v0Ÿ.\¸½ ’@ $&&R(çÆ  ^ãï€ââbðüùó~Þ4ɺ˜ õ sx“gÅkº"—±ÌÚ[»vmס¿ÒÒÒôôt …‚fúcÇŽ1ŸÎš5«û„>Î0ü}Æ ..Žþ¼±R†®‡,ÌÇ胮Û,#c8èô ^Ó¹ŒeÖËÐ_RRRtttss³£££……E×§=NèãÐ8áÀÃ߉a̘1œh¤@¼§+rˬ=–¡¿ŽŽCCæ¦&--- ---æÓ'ô ¤ Å߉CàA Äûš››™ë’’Éäç”°Óܺu«·;à.66ÖÍÍD")**ž8q‚eè/77·¡¡¡µµuÕªU€Å‹3ŸÎœ9óªƒL =€)ïãµéŠB¡PºÎÚSTTüÅMq—/_îúôú _ƒ‰¡ð â}<5]``bè¬4ƒ£œ***–-[öÏ?ÿà„'–BñÒÒÒååå¡®®î×{v/£AƒÄ€M ÷îÝ[ºtiEEÞpÕ¹sçlmmydæD^^.ÚÌ¡$@׺¿¨€€33³)S¦t?c`ïØ­˜ Fdddhh(Ë:É›ƒƒÃ_ý•––6{öìsçÎIKKãOLLŒƒÁ011éÛ e}†.ÅÄR(ÞÔÔ´¸¸øÓ§OK–,aÙ‡eÏ_ߦ AØ@+ÇX]]mee4¨²ÀÂÂ"33SVVöÎ;:::ÅÅÅxEÒÚÚêêêºqãFƒñçŸÞ¹s‡§ª~>zôˆF£™››3Wë… ˆÅ€:cÈÎζ³³ûôéÞàCGGçéÓ§óçÏö왞žÞ©S§,--¹Ã÷ïßmll>|(..~âÄ ¼ÃÈÈèþýûxGA<‡åúA˜˜6h³jÔ¨Q™™™K—.­««³¶¶Þµk7{ÏÏÏ×ÖÖ~øð¡‚‚ÂÇy0+@ÄŽpÆPWWçêêú÷ßÐ:E@ Î;IDEEO:E¥RCBB6oÞœ““süøq111N÷»{÷îÀÀÀöövCCÿÿþ{äÈ‘œîqÀKLL400`¹W /©©©Ø6øåË!!!lÛÄs¿ÁI€ /¬!S__ß·72$55•H$vË633»}û¶””Tmm-Fò H¥RÑ+Ò÷ïߎŽvppàÐWLIIÉêÕ«Ñ©®®®ñññ¼üÏ|}}Ÿ=MSS311±±±‘£qv5˜‚ ¥¥¥èÒCãÇ/**¶ñî¾~ýŠ–ž•––ÎÎÎætwh#}‚¬^½zøðá]·£OÿüóÏØØXœBû½/_¾p¡CCCCCÃÄÄÄ»wïfdddggþüùëׯ?~üøñãGIII÷·HKKËÈÈŒ?ÞÊÊÊÒÒRNNŽ qBLcÇŽÍÉÉ¡Ñh………šššÛ·o߸q#‡î1;þ¼‡‡GMMͨQ£}jooÿöí[11±½{÷®\¹“f!~…÷Xf^½zE$EDD¾~ýŠw,Æ0¹‰™k0¿ÆÀ¢¢¢ÂÜÜíkþüùÅÅÅýiíóçÏNNNhÆÕÔÔìgkÐÀ0pÎìííOŸ>½nݺ¸¸8¼c0†^vÆ;Šž577«¨¨tttûsÚÛÛoܸqíڵÇ£ë®Y³fïÞ½pÖ:ÌPÒ›7o(Š€€À»wïÐ{û ˆkЃccc.×ÿöíÛž={:ÔÐÐ ‰***ªªªT*URR’L&‹‹‹ ÕÖÖ666ÖÕÕ½~ýº¨¨¨¨¨èÊ•+hiz!!!{{{??¿‰'r-rˆÇ ÄàäätâĉU«V¼Áâk|ŸÊÊÊ&L˜€ Èëׯ•””ð¼jkkÕÔÔ>þ½iÓ&¼Ã ¾ãûãš;v´··;88À¬áKJJêðáÃ!88¸Ç äÄ/øûŒ¡¼¼|ܸqÅÅÅãÇÇ;îîîGŽÑÕÕ}ðàî ì@Pßð÷ÃÎ;ÛÚÚ–.] ³Ä#¢££ÇŒ“½{÷n¼c >âã3†/_¾Œ7®½½½°°PEEïp èÿddd˜™™ åææNš4 ïp ¨×øøŒa×®]---¶¶¶0+@CCà 6´··;;;·¶¶â±…ÏÎjjjëêêžûAP?={öLOOAÌÌLxÊ ñ2@HKKÃ;àííýþýûŸ½_]]M£Ñ`V€øÔÔ©Sýýý#""\\\ž?.&&†wDÔ3€H$²¿†8çhiiåååõxÆÐØØ¨¨¨XUU•‘‘1sæL\ƒ þkkkÓÖÖ~ñâņ öîÝ‹w8Ô3þ¸+)!!¡ªªÊÀÀfˆ¯ %'' ÆÅÅeffâõŒCss3ºæIHHÞ±@Pihh3Œ+V466âõ€ÃáÇ+**tttfÏžw,„€€€)S¦¼ÿÞÏÏïX ¨¼žZZZÐ{ûàé4` &'' ÇÇÇß½{ïp ˆ¯'†£G~ýúUKKkΜ9xÇA˜QSS CÄÕÕµ¡¡ïp è?x:1´µµíܹB ðÜ” ê___mmí²²2Ÿî¯^¼x‘û!AЧCRRRyy¹ººú¼yóðŽ‚0& œœ,""’˜˜xëÖ­®/UVVzxx0 ¼bƒ9ÞM ííí‘‘‘ž.@—ªªjxx8‚ nnnuuuÌí¡¡¡•••ß¾}Ã16h0ãÝÄpâĉ²²2*•ÊkÕœ C7nÔ××///߸q#º¥°°ðÈ‘#€ÒÒR\Cƒ/M ;vì‰<$õ‰DJJJKJJºzõ*ÀÛÛ­D„ýÎ=uêÔû÷ïUTTlmmñŽ‚8k„ Û¶m¬\¹òܹsÌë 01@xÀ;€tvv¢ ]ÁÓh0X¿~}ZZZffæÊ•+™û–>þüúõ놆:N§ÓÛÚÚ¤¤¤Èd²„„„’’’¢¢"¼bý/&†³gϾyófüøñK—.Å;âƒñåË—Ò.šššB×KÐl&Až>}šžžž™™ÙÑÑñ‹‰D¢‘‘ÑäÉ“­­­i4š€/~@¸ã¹_ ƒ $‘Hx‡AØc0Û·oŒŒüu­¤ß&†úúú˜˜˜C‡}ýú•¹QFFfòäÉäÿª­­¥Óé ÅÅÅååå÷ïß¿ÿþ¾}û–/_¾}ûvl>4‰D„L™2€ÎhSRRjooÇ;"â ¯_¿º¸¸üb°”D"µ¶¶öøÞ¶¶¶ˆˆæ¡rrr^^^¿ý«éèèÈÊÊ VSScöâììüùóg|Dˆ_ñ\b7n 11ïp ˆòòòŒ–Þ¾}Ûý-Ož}¢Ñh謯¯ïÏF™ú€Á`ìÛ·˜RUU}þü9V-C|ª‰ý~WUU]¹r%•JE·«ªª:99©ªªfdd ]Ò€ºº:‚ 'Nœ£Ñh]Å{¤¬¬ ‘‘iiiéóç ¾VUUµvíZæÍBþþþèö+W®HHH —Ð?4Ì „„„8ÑÄ/z±æ3•J-,,”““{òäɰaÃttt ÐßÔÇggç»w444òóó™oümû&Lxûö­ŸŸZ" ‚­ââbŸk×®ÙÙÙ¥¦¦ÆÆÆnܸAkkë#GŽ >œCý¶´´lÞ¼yÿþý‚¬^½zÿþýšH´k×.N4‹¹¡C‡º¹¹áNzuÆ@¡PЧè ‚ ãÇGhhh ]Î&OžÜõ¿…%=yò„½”AÜÍ›7W¬X±uëV@ˆ‰‰áN¿×¯_888pâæ@>ª;nÜ8Ì?>_èõ<†îÓ&étzyy9`èС"‘H§Óëêꪫ«ÑtÄŠ=è…5‚LMMoß¾* pôèÑåË—s§_ssó[·nÍ›7/%%…N§§¦¦ cÞ @ؼy3æÍb¥¶¶öСCxG &¸III={ölß¾}]]]4OLLL,--—-[fooßÿî h0`0«W¯>|ø°°°ðéÓ§.\ÈÍÞi4ZFF†……ÅÅ‹çΛ––&..ŽmD"‘—?|ø0˜ý¾+‰Í‘¢ßB‡’0¹‚øZ[[Û²eËbbb7nÜÀ+Œ‚‚YYY€AMM VÍ¢CI$ «9áýû÷`%ÁuÄ[ZZZ-ZtúôiIIÉ›7oΞ=¯H¨TjffæØ±c>|8cÆŒªª*¼"¸ìÿµwïAM\]Àï AñAkÆJÀ)"O‰Z@¡ˆ â«€óçÏ/_¾¼»»{ÇŽ\.Wõ Ab@MmÚ´)--MSSóðáÃDI • ˜˜¸víÚÞÞÞƒÆÆÆÂn ïµÛÁ @ d2™«V­âr¹ÍÍÍéééD± å‘H$û÷ï?zô(†a'NœØ¹s§R‡{OÔ×ן;wŽê(䉵æëë{ýúuŸK—.UTTdddê®±±1((èÞ½{ #99yãÆJè}SWWwèÐ!ª£—$ÔÝ‚ JJJ***£££wîÜ©ðº§/^Ü´iŸÏ744LKK[°`bûfff*+x5}êæævúôib[0''''''ggçêêj¢6›6kÖ¬“'ORùMh¦’PƒM%ɸ|ùòŒ3Èÿ®®®±±±·nÝjjjì#/_¾,**:uê”——¹{(‹Å:uêÔÐ;HS>•äããÓÖÖöâÅ‹•+Wâ8Îápˆ½úúúˆdgKKKâ– Žã¥¥¥‡8Ïb±E"‘•••<#¾çSIpóZZ¶l™ŸŸßõë×/\¸‘‘Q\\\\\L¼Åd2'MšÄd2uuuµ´´ÚÛÛ…B!ŸÏooo'?Žaؼyó¼½½###544(úrimm-++[½z5B¨ªªª³³³©©ÉÞÞ!4àøææfâÝ9sæ·R'L˜`dd„Ró/«& 1@W†y{{{{{§¤¤\»víþýûååå555/^¼ …ýÛkkkÛØØÌ™3ÇÆÆfÅŠ ß{GI.]º½nÝ:„PbbâÕ«WŒŒ>|hgg'‘HˆÜ€K­þ344,--µ··ÿí·ß ‰“°Fï@b€öÆŽëïïïïïO >Ÿ/‰„BaOO¾¾¾®®î¸qã&NœHmœÃ“™™™••E¼^¸páÖ­[y<^pp°†††©©iZZ’Ú&!ÄãñBBB0 c0)))T†N[š!‰DbeeEu$¨¾¾žê ôôôôôô¨ŽBaÈ)2„™™Ù7B¿üò‹t›øøxâQïïÁƒ2ÛÆüñÇÊ uÔøßCUUµq½äççÏœ9ÓÌÌŒê@OSÝRÂôéÓ©ðÎpßæñgÏžmnnîååuàÀY³fQŽ"i²ÙlªcÐ^vvvEEExxø‡~Hu,*Âb±BBBx<^vvö²eËFSz€nðõõ½té’‰‰IhhhMMRÇ222rss³±±),,Tê@oõÁH$’üÑÚÚzÅŠ•••#éP"‘ìÚµËÑÑÑÙÙy×®]ÄšþÈ•Þòx§ÆH ÐÔÔŒ‰‰ù矒““---—.]z÷î]%5~üø»wïæææîß¿Ÿ<9Øo¨R±X,r¹¸BÒ—Ëe0<¸ÿ¾––ǰ$=,]ºÔÍÍ !„ãx^^ž»»»]fffoo¯2†322!6›½qãFooï‹a(qÑ@Ž0=deeíÝ»—x½gÏž .¯ÉG­­­¥K€ „ØlöúõëÙl6qý$ݽY/Dþ0`@aŽ?nooO.7+++ سgODDDppð¸qã8Vee¥BˆÏçïÚµËÂÂÂÃÃËåKÛ"""nß¾=Â!úúú"##ßÚlæÌ™åååÒgˆô@Þ{D±XLþ+1™Ìîîîþm‚‚‚bbbÈ ²ööö¯¿þðõë×{xx ÝXN «+Vhkk¶5XBB–-[B6lPYÍQ;;»Õ«WgddHŸlllŒŒŒ<|øpHHȶmÛ¦N:ÂQ:::ÜÜÜp‹‹Céëë[XX ~Å0x<Þ•+Wìíí;6¼$Illì°ã$ÒCnnnrr²œÑÑÑéìì$rƒH$ÒÖÖ–i€÷Ûá•Édš˜˜ „ø|þÐ-å‰Z"*Q·µµ‰Åbé© ™•p?zôhWWWWW—H$ê’"}(‰üxGGÇwß}—””4ÂHˆ{ ä!YþH¦FDDDDDÄHÒÐÐ rÏÐ233KKKûŸ×ÑÑ Û½{·üsJŸþù·ß~{ôèQ„бcÇV­ZEœg0B¡°££ãõë×èÍ}¡PØÔÔ„š0aBÿ–hx‚ª2~€ÉY]õìÙ³III\.÷âÅ‹8Ž×ÔÔ8;;»¸¸â8ž––¦££3þü¤¤$KKËÊÊJGGGGGG''§ªª*¢ ‹ÐÐP+++7ôXDuÕ‘ïÓ0eÊ”ÄÄD¢Hø»nÔ#¬¥*sXYYéàà@<ÒSSS3ìþñw©®ú×_‘¥jI:::;vìxþü9ÑFþꪽ½½‘‘‘NNN‘‘‘dùØøøxKKË7ÕaÃÃý¼¼ÒÓÓq·°° ²°°(((èßR¦ñÐÈêªP/r&UV¢&ÃäÉ“÷îÝÍårOŸ>žžž}óæÍâââ²²²ššš†††ÖÖÖƒöO ºººøpwpS1ù¹ùÝ€) Ô²Û2ir$ ì64FI%j ÃŽ92t›îîîÄÄDé36l8|ø0‹Å’gz©««#ïñGS¦L¡6ª‘ƒÄý¨m%êôôô/^‡^^^111êP£SI¢££{{{©M d}@‚Äý¨g%jÇÉgxfÏž}üøñ (i,uPWWwùòå;vŒŽ«i õ¬D}ãÆêêjccãèè耀€'µF“úúú††}}}ªQ‰úÉÊÊ*(( ^ïÙ³‡Ãá‰ÁÊÊŠxÕÚÚúêÕ«ÒÓñÄ*³·6P72ë3âããÃÃÃ…B¡††ÆüùóËÊÊAww÷¦M›B+W®$=<bé$èGžªý2ÓñïÚ(\UUUHHÕQ ¥¡¡x‰ú‘©ÚïïïOœ—®ÅÿÉ'ŸHOÇËÙ(Oss3]&µ 1@?Û¶m‹ŠŠrrrêèè°±±ùᇈóaaasçÎ0a‚Ìtü¡C‡äi”ÁÒÒòÌ™3TG!/ccc Áöo…sss+**ºwïž««ë[—••…‡‡ççç|!¼~ýzòäÉ/_¾yo8Ž3 ÞÞÞ‘÷¦$õõõfffæææOž<¡: À4fkkû믿RmFç¢Ã‰À 1x$o€Äà ¼€7À:$I`` ÕQ J(R• 1 ŽÔjU°2*){D+¼[ P/DÍÔÍ›7ß¾}ÛÈȈêp@ @ÿlä0 ËÌÌTHWÊÆd2©P+ õÒÚÚúé§Ÿþþûï&&&æææÓÖÖæååURR2uêÔÛ·oÏœ9“Â`€ÊÀÍgÔ‹Á;w\\\æÍ›GáÞ2---îîî%%%fffÅÅÅÞP;ãÇ¿yóæ¢E‹ž?îææVZZªúçÍ›WQQaiiY\\S`ç€và/èaîܹåååëÖ­‰D!!!§µµuäÝvuuíܹÓÓÓ³¥¥ÅÃÃãÑ£G$hCOOïìÙ³™™™úúú………¦¦¦Û·oojj^o|>ÿÈ‘#Ó¦M‹‹‹3fLLLÌ­[· 3 #˜J€~ø|~TTTJJ ŽãcÆŒqww÷õõ]²d‰±±ñ[?ÛÖÖ–ŸŸŸ““sóæM‘H„244ÌÉɱµµU~à€ 1@W555ÑÑÑ.\ +îikkÏ™3gÖ¬YzzzL&“ÉdŽ;¶½½]( ‚ÚÚÚêêêgÏž‘=p8œ}ûöÍŸ?Ÿ¢oÔ$è­½½=///''çÎ;mmmomÏd2}}}ýüü¦L™¢‚í@b`ôhii©®®~üøqgg§P( …===úúúL&sܸq¦¦¦l6ÛØØÃ0ª#jí?w´w‚ÝZNIEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/preserve_in_nat.rst0000644000000000000000000000013215055603742023055 xustar0030 mtime=1756825570.265068523 30 atime=1764928633.571681248 30 ctime=1764935922.860571635 rsyslog-8.2512.0/doc/source/whitepapers/preserve_in_nat.rst0000664000175000017500000000442415055603742022525 0ustar00rgerrgerPreserving syslog sender over NAT ================================= Question: I have a number of syslog clients behind a NAT device. The receiver receives syslog messages that travelled over the NAT device. This leads the receiver to believe that all messages originated from the same IP address. With stock syslogd, I can not differentiate between the senders. Is there any way to record the correct sender of the message with rsyslog? Answer: OK, I’ve now had some real lab time. The good news in short: if you use rsyslog both on the senders as well as on the receiver, you do NOT have any problems with NAT. To double-check (and out of curiosity), I also tried with stock syslogd. I used the ones that came with RedHat and FreeBSD. Neither of them reports the sending machine correctly, they all report the NAT address. Obviously, this is what made this thread appear, but it is a good verification for the correctness of my lab. Next, I tried rsyslogd on the sender and stock syslogd on the receiver (just RedHat this time). The machine was still incorrectly displayed as the NAT address. However, now the real machine name immediately followed the NAT address, so you could differentiate the different machines – but in a inconsistent way. Finally, I tried to run the stock syslogds against rsyslogd. Again, the host was not properly displayed. Actually, this time the host was not displayed at all (with the default rsyslogd template). Instead, the tag showed up in the host field. So this configuration is basically unusable. The root cause of the NAT issue with stock syslogd obviously is that it does NOT include the HOST header that should be sent as of RFC 3164. This requires the receiver to take the host from the socket, which – in a NATed environment – can only hold the mangled NAT address. Rsyslog instead includes the HOST header, so the actual host name can be taken from that (this is the way rsyslog works with the default templates). I barely remember seeing this in code when I initially forked rsyslog from sysklogd. I have not verified it once again. I have also not tested with syslog-ng, simply because that is not my prime focus and a lab would have required too much time. To make a long story short: If you use rsyslog on both the senders and receivers, NAT is no issue for you.rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue1.png0000644000000000000000000000013215055603742022405 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.532822752 30 ctime=1764935922.843571375 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue1.png0000664000175000017500000000564315055603742022061 0ustar00rgerrger‰PNG  IHDRŒݾhÏsBITÛáOà pHYsêe¤ FIDATxœíÝLUõÇñ×¹ ¨ê ;Šh®™8q¶}ñGΡýnõ5\Φø‡ŽYYmèr+K0WÙ–Nfšß-Kú1ûåWÔ…n-$LóËïÔT² Lhö%Þ{¾\§VzÏïåœsïó1Ƹ»Ÿ{yöäsν\T^^.p¾}ûš7?xðà%K–8=!\Ñ£G›]e˜¦Ù•£@§ùœì"X<ƒ`ð ‚À3Ï Xp+ÓÔ¶m:~Üé9à"ñNüiª¸XË—Ë0TQáô4p‚7 ´e‹ tô¨$mÛ&Ãpz&¸O…;úê+èøq†LScǪ¢‚`ázì°à4¿__|¡eËTY©¸8I þ]²D.È0nðæó]ù1†œP਎öûŸñѨ®îO×wXv„Ι‡®uí`]|mjª23C}à º†)s¿ö—ªôý¤Ÿ*UP`¥V.Ñ'³4ËéY‹:`ª¦Vª²JUÝÔÍéY‹8i »~Õ¯e*›§yÔ N!X°k‹¶˜®éN‚ØÅ!!욢)uª«T¥Óƒ v±Ã‚- j(W9Û+—;yR—/;=D$,زC;üò?©'¡ôé£{îÑêÕºxÑéQ"ƒ`Á–ïõ}²’Ãów%1))ÊÎV^ž†Îlq ¶ŒÔÈT¥îÔN§…†¥¥éÂIêß_/¿¬ùóÕ³§Óc… ;,Xû]¿ŸÐ‰‰šèô °–’¢çŸ—aHÒÙ³ÊËSZZôì¶:¶ÃºxQO=¹aàRg2·U¼ö¯q¯”ö;œåô,°ÖÖ¦ÒRùýW.ú| ¢d·Õ±——1MÕÖFh¸×™Gÿ+éü®FÇOé¨H’a(¸ ^lnVm­ÎŸ÷v°8‡ks5·D%õªwzØòÆzõÕ+†´`^zI¼ÿÊû Ö²”uQ÷iŸÓƒÀZs³RSÕÔ$I=zDOª‚xÅQX«Vu¦2ž¶¬Y£¦¦(LUÂÂe]®UíP uzXknÖ¿ÿ­E‹T]­wÞ‰¶Z‰,Öé˺œ¦4§µÓ§u옒’œž#b,T«Z;,OHOwz‚ãªT%‰Ü€`ÁBµª}ò ѧ¬T«z &Èî×"‡`ÁBjØ^Á%,œ×ùd%;= ,XjUkwuwz @"X°Ô¦6‚—¸ö<¬¢¢¢?þØçó†áóù®~Þ÷î¿Ã.žÓ¾p‘‹µ©Í=gÜ‹‹‹üñÇ«_º ë/†¸*+=úéœþ6vÞµ`µµµµ´´˜¦nö>ÄU}¾æ¤[éã­dtøðáMMM›7o=ž«vX³fͺ|1MÜ׿8+++???Ääׂ•›››››ù¯Õ5¦i†½ƒºÃ¨œ³¶¶öèÑ£–ß&WÃJLL|úé§×¯_õyë/vî*gWÆø§óûý–û'5çjVœ!–Í›7ÏN°\µÃ’äóùâãù•²E,`¡Cç°š››{÷î]XXÑ‘³B1evh‡ešfssskkkD§BÌ"X¥]í¦LW"–,„Ò¦6IîyZbÁ‚5S¼ð?\`!”^êeÈ8¯óNH ¡ùäë¥^-jqz@"X°”¤$‚— X°@°à ܃`ÁÁ‚{,XHRÂ%,$*ñúV«Z阃ó –,üÕ Ø¬Í~ùƒ¯š2?Õ§#4"E)ŽˆØE°ðW#4b­Ö¦*µ@uª 눎LÖäÙš=AœÂë áÖhÍY¦e¯ëõáÞ¬æ eAçY=↉‰‰eeeÆ ëªI[ØaáÒ•þ‚^dÊüE¿0e2Fjä}º/Ä ããã'OžŸÏ0ŒðÞíÕ;7 ÃçãmŒ"X<ãÿs¡@a µIIEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue3.png0000644000000000000000000000013215055603742022407 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.535822811 30 ctime=1764935922.848571452 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue3.png0000664000175000017500000001051615055603742022056 0ustar00rgerrger‰PNG  IHDRŒݾhÏsBITÛáOà pHYsêe¤ñIDATxœíÝyPÔ÷ýÇñ×.‡Ë!2Þàxk…Nò£VÑÓ4Óf¢ÅÆ!‘ƒ±Î”Ick­`’ÆcLƒc­T!Æ`B6âA¸"¢L8"Zð ¸ »ŸßëxUÝ/†å»_öõ†åÃò†…§ßï×Ýï"??DDNã‘G÷á¼zõj¹'$"ºA£ÑÜïC*!DoŽBDJeµâÓO1>îGSËõ…‰H1¬VìÝ‹I“-c­¸Ëøµ‰ÈÙY­Ø¿qq¨®†Zä‡Á"¢{ééX³P© 2cÇÊ;aÑ„@FââðÝwpsƒÅj5**0aÂBÀj½ãn½{ÏËÝÜì‘Á"¢Ûœù@YYYzz:€âââC‡ÈÍÍ-,, ÕjKJJ¤¥¥UUUؽ{÷ùóçlÛ¶íêÕ«>üðC½^àwÞ±Z­V¯^-„ðòòŠBÆÄÄ!‚ƒƒ£¢¢„ãLjˆB„……=ýôÓBˆéÓ§Ï™3GñÄOؾÇgžyfòäÉBˆçž{nôèÑBˆ—_~yÈ!BˆåË—!Þxã OOO!D\\€ÎÎÎ 6xxx´µµ%$$xyy]¹r%))ÉVÆ´´´ÀÀÀªª*­V;hРÒÒÒÜÜÜ   ãÇŸ8qbäÈ‘¹¹¹åååcÇŽÍÎή««›8qbFFÆ]7A¡(ô~£Ä¨sâ\/Üâ=‚Á"çe±XÌf³¢³³Ó`0!:::Z[[­V«ÉdÒét‹Å`0\¾|¹««Ë`0444˜Íf½^öìY“ɤ×ëkjj ƒ^¯¯¨¨hoo7 §OŸ¾víšÑhçb®TîpWC}׋ ªÞ¹PA_+Ñ—pÉÞ^ðÒ@ã ï¡„ a„ Ñ­œç_wnaQo¸„KIHJCÚ·ø€;ܧcúLÌñã0n ¦xÁKîI,r ,ÉHÞ‰(ó1ÿøE8§aš<䞎”‡Á"‡0¸Û7`ÃE\‹±‘ˆ|Ï…ÌOa@JÇcXÔÃÄflŽG|ÚÇã{°gæÈ=õ õ¤jT¿‚WŠP4ÓßÆÛ¿Â¯äžˆúÞÓzÌ6l CX5ªwa×7ø†µ¢Ç-,ê&˜¢õ>û-~û/ük(†Ê=õMwt¯ªªÚ±c‡ÄÏôóó³ôC¢µk×¶··K\=Áö”hµÚ£GJ\%q±N§{÷Ýw%.°nݺ~’Ï›pöìY‰‹Ÿ}öÙ™3gJ\|òäɽ{÷J\)qq||üûï¿/qñ‚ öìÙ#qq]]ÝäÉ“%.ÐÔÔäë+õþÄóæÍûæ›o$.Þ¸qãk¯½&qqrr²ôßÝ)S¦?~\âb>>>wüϲ/L…&1Bx.õtÛçv×âcÇŽIÿû\¶lYRR’ÄÅ111›6m’¸¸¨¨hîܹ{{{ët:‰‹„††ÖÖÖJ\¼{÷‰‹?øàƒ5kÖH\ŒÃ³1[îq¨ïã1,zHX"Y‚’4¤±VÔ;,zHÃßàÀ‡øp>æË= ¹ îÒÃ(@ÁlÌ^„E)H‘{r! u›†0„™a.CYô—{r!¼ã(uÛ¬9ƒ3ÿÆ¿Y+gS[‹®.¹‡p$‹ºç,ÎnÁ–—ñò€†da6#'–§Ë‡Z «µlmuB ±ÑA“³ky:½Ë«½ßÞù;àä¬VP©`Û±½ÛÖ†ÆFèõÊa‘T¿Æ¯«PuçÔ<’àÜÞyÿøÇ·U*ôë‡åËñƤ°§y¾>4‡$iBÓù+þÊZ9¹¶6Üðy/È8ƒE Ý—í»ܨ¡^ŒÅ~ð“q‹,º/T[±Õ¶Kh…512ÏÃ`¹<‹$¡¯á5ãñP„Ê; ƒE Ùñ6Þˆòn·a°ˆ÷Ã";°[‡ßÉ=ƒE Ið{ü^KH Â`ƒEŠÁ`ƒEŠÁ`ƒEŠÁ`ƒEŠÁ`ƒE=Éd2ÅÆÆæää8âÊ,b°¨'utt|ôÑG§NrĕۂE®ŒÁ"Åà1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1X¤ 1XÔ“<==£¢¢BBBqå ñYs¨'yyy%%%9èÊ,â)ƒE )ƒE )ƒE )ƒE )ƒE )ƒE )ƒE )ƒE )‰J¥b°\ƒEJÂ`¹8‹”„Árq ) ƒåâ,RËÅ1XÔ“,Ë÷ßõêU]?ƒåâ,êIׯ_ ݹs§ƒ®ŸÁrq ) ƒåâ,RËÅ1X¤$ –‹c°HI,Ç`‘’0X.ŽÁ"%a°\ƒEJÂ`¹8‹”„Árq ) ƒåâ,RËÅ1X¤$ –‹c°HI,Ç`‘’0X.ŽÁ"%a°\o~×USSÓÒÒ2uêÔž½Z‹Å¢V«mÏpÓ㺺ºÜÜÜtåäü,"RŒÿìM#H²ŽùÃIEND®B`‚rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/index.rst0000644000000000000000000000013215055603742021001 xustar0030 mtime=1756825570.265068523 30 atime=1764928633.542680392 30 ctime=1764935922.857571589 rsyslog-8.2512.0/doc/source/whitepapers/index.rst0000664000175000017500000000067715055603742020457 0ustar00rgerrgerRsyslog Whitepapers =================== These are a collection of white papers written by Rainer Gerhards. They detail logging comparisons and realities based on his experience. They also cover observations regarding the development of rsyslog and the community around syslog messaging White Papers ------------ .. toctree:: :maxdepth: 1 syslog_parsing syslog_protocol queues_analogy preserve_in_nat reliable_logging.rst rsyslog-8.2512.0/doc/source/whitepapers/PaxHeaders/direct_queue2.png0000644000000000000000000000013215055603742022406 xustar0030 mtime=1756825570.265068523 30 atime=1764929145.533822772 30 ctime=1764935922.846571421 rsyslog-8.2512.0/doc/source/whitepapers/direct_queue2.png0000664000175000017500000001002515055603742022050 0ustar00rgerrger‰PNG  IHDRŒ ²ªsBITÛáOà pHYsêe¤¸IDATxœíÝkPTçÇñß.  F4Ž—u¼ÄK½A§/Œ¦ŽRcêdÚL´h:$’kD­/˜Œ¶ŽQPƒ1Æk޵2ÑD#NhÑõ A¼Æ¢D„•;˲°ûôÅfŒRd†åìáù}&Ã,ðìî_ož=.g‘””""—Ñ·o_Ñ÷¡C‡®]»Víñˆˆ~âééÙêÇuBˆNÅÅÝÆmw¸Â(µ!¢§èÕÀ…$#yæ,À‚‘©ö,DÔ’»Ú¸„¤„ ä,ΈAŒ:µ'"¢–d$˜‚”P„žÁtb&¤#µ"rAòî­R‘‚38ã7Àl*Uö?uiûÝö®çÝÉ3Þs\Ý£1Ï&ãÞ*y+±òN=ùAt:è^À ªÍ:óîˆ\Ç` ¾ûm,qo5ËÜ;¸ã7+¬ö»ÁmtGw-vXÿ¿áj{AÇ^ÝÅïÎÅÇãÝie¼è6ɸ·²³ÂzGBzwôÐÛ`ð >Ù„MjFD­·VvöfmÀ†\äè…^…(|/ª=µ$ûó­Üàö.ÞÍBÖaƒ1u¨Û‰jED­}oõ$+¬GqôK|i€Û+"WÃZµ$ âá R{"z kEDÚ ûq+R˾}û>ûì3ÑÑÑaaaŽ;öé§Ÿˆ‹‹Û´i€sçÎÙ/$%%………Y­ÖÔÔÔ­[·666Þ¸qcÇŽõõõ™™™áááÕÕÕwîÜÙ»woEEEaaáþýûËËËKJJ¢¢¢JKKËËË¿þúë’’’ªªªo¿ý¶¸¸¸®®î»ï¾+**jhh8qâĽ{÷šššNŸ>]XXh³Ùâãã \¸pÁ~!%%¥°°Àõë×ínݺuïÞ=¹¹¹ÅÅÅ JJJÜ¿¿´´@YYYYY€ŠŠŠG¨­­­ªª`2™êêêX,³Ù Àjµ677àâ™Z= ‘³L™2EñÁŒ?^ñÑG 2D±råJooo!ÄêÕ«=<<„!!!,Ë矠ªª*<<Àƒ"##äåå}óÍ7ÒÓÓccc¤¦¦ž={@bbâ¥K— †´´4111YYY..®³¿Æµ"×eµZ-‹¢©©Éd2 !«««m6›Ùl6V«Õd2•––677›L¦¢¢"‹ÅR__÷î]³Ù\__Ÿ““c2™êëëoݺU[[k2™nܸQUUÕÐÐpíÚ5£Ñh6›“““KKK-KRRRqqqsssBBB~~¾âÌ™3999BˆS§NݺuKa0®_¿.„8yòdjjªâĉ/^BÄÅÅ?Þ~áäÉ“ö Ç·¯9|ø°ýZ‘‘‘öÛ‰ˆˆBœ>}zÛ¶mBˆ³gÏnܸQ¿víZ›Íöý÷߯^½Úl6'%%×ÖÖ^¹reåÊ•=ºzõjPPPIIIZZÚâÅ‹óóóÓÓÓßÿýììììì쀀€ü1//oþüù©©©EEEsçνpáB§;[‘6ð¸ikEDÚÀZ‘6ÈxrXróø?/xe!Kí¡T°ûyrm%X+êTF/ââ\HBÒMÜ||ºž0 ³ѨîxªàIÇâ¿ Rgx€QˆŠAÌñ_îpŸ†iÓ1},ÆŽÁ˜É˜ì/µg$WÇZ‘YaFô¸ˆ‹b.æþ¿žS1ÕjOGÃZ‘S4 aömÅÖ”ŒÆè¼‹wÛ>ë6QÛxÜŠ:˜€ØÝ!©AÍ«xõùÁOí¡¨+`­¨#e#ûC|˜Œäi˜¶ ›~‡ß©=u|¾u˜½Øë ßldÿ ÿºŒËLu,î­¨˜aDà1ûþðüc0«=uAOeÏÊÊÚ¿¿ÂköîÝÛ~…BCCkkk.^²dɸqã.6 ñññ ûøø*\l4íç`RhóæÍÝ»wW¸8""âîÝ» ¿ýöÛÓ§OW¸ø‡~8räˆÂŃþøã.ðÿ‹Í=Ìÿþðß÷‡ßŸ7ã7~óä§‚ƒƒ‡ ¢ð–=zõêU…‹_{íµyóæ)\œŸŸÿÕW_)\ìáá±eË…‹lÙ²Å~¶%.\èëë«pqBBÂÉ“'.3fÌÒ¥K.®««k×ïúõë½½½.ŽŒŒÌÌÌT¸xΜ9³gÏV¸ø©Z>}ZùwÀ Aƒ”ÿ°1bÄÇ.Ž}ã7. ùâ‹/.ž7oÞ¡C‡.ÎËË›4i’ÂÅÊÊÊzõê¥pñìÙ³/_¾¬pñ¶mÛ–/_®pqtt´òoÜÉ“'§¤¤(\  gÏžOý;r/˜/™ÅpÑí£nnߺµX|åÊå?œË–-‹ŠŠR¸8((hÇŽ '''Ïš5Káâ=zF…‹øøøäææ*\|ðàA…‹·oß¾nÝ:…‹gÍš§p±Ñh6l˜ÂÅrss_~ùe…‹ýýý ƒÂÅëÖ­[³fÂÅ|=¿zÔÏÄ̸qçfb¦ÚãPÇãVôœ¬° i1ˆaª¨°VôœþŽ¿ÿÿÙ‰s1WíYH |$HÏã".ÎÄÌ?ãχqXíYH¬µ› &_øZ`IGú xAíqH|v(µÛ:¬»ƒ;ÿÄ?™*W“›‹æfµ‡pÖŠÚç.î†#|͆ҧÉP§éÓ¿úvíBCƒÚ£8kEí³›õÐoÀµ¡VôïyóŒ#º`³xÜŠÚ!ùc1ö/øËìQ{j]y9†‡É`Í,] ¯.q®Cî­¨¶`‹ú5Púäcê|ýû㯅NF#‚ƒ1|xÙgµooÕЀùó7 ¹4«gýùè—%ÏõÙ¡ô÷cH `ýé”÷Ðëa³u…}Vûž*Š‹4 ¹ºÊ7c›½j»yŸß.Îfö­ˆýÝš£¾^õâq+Rê÷ø}² P ç׆O>ùé²N‡îݱbV­ÂÀªŽõ‹ñ7oH‘2”Çù¿áoL•‹«©Áã3’xzv‘NÙ±V¤ˆlþPz¶RKx8ª«»Z§ìøH D †2”qoåÊjj0q",èj²ãÞŠ‰G¼ü˜*WT„ÌL(>#¤Æ°VäX²JPÂW…p}&¨=3ñ•äØ\ÀSX+r,žðƒ1jBRc­È±t¤Çx7´|‘¢ÎÄZ‘cȘˆ‰jOA²c­È#Œñµ"Õ±Vä@! ŒÄHµ!Ù±Vä@%*¼ˆÕ„d÷óó­¢¢¢¢££õz½N§Óëõ/tì[׿ÁNžSg?‘ «@\¦V±±±iiiÿêìž|·O9c¥FïNí/ãsú¹V‹¥®®Na³Ùžõ¶Oµ÷­Í~ ~IIC_yå•êêêãÇ·=ž½V}Ñ·Sþ28qâDdd¤ÚShžË¶ØÏÏ/$$äYcÿ\«%K–,Y²¤Sþ®~"„èð:é»äœÅÅÅ¿L®óH033óöíÛIIIS§N}üÍ#žðä»Ï÷)uWJ~wV«µíMŒš¿yó8¨*Î ³Å‹+©U*º¡[/¨ÿ»gµµµ—.]ª¬¬twçoŒÉˆ¥ *P¡|cUSSãíí½{÷ngLb?à"xÖY±Vä@*”´BÔÔÔ466:cÖJr¬9P‰JW8hÖJz¬9ЮG‚NÅZI޵"ªQí oµ§X+é±Vä€<šÐ¤ök%=ÖŠð‚—fµ§X+é±Vä€'<à¯JÎZI޵"¼àÅZ‘+`­È>$ÁZ‘|$H.‚µ"¸·"ÁZ‘-öVhÌD¦*“°V’c­¨¥ldÇq+¬öwe‡qxÆõGUc­$ÇZQKã0.Ã0,¡÷qßþH0é30ã=¼7 ÓX+RÏD­G¸/|7`ÃFlÑ hð€° ËÚ¸bÏž=GŽtÊKN°V’ãÞŠZ1Vb%‘‹\! tÐÇøßâ·m\ÑÝÝ}ÆŒC‡uÆT¬•äX+j](Bû£¿zû– €€X*ŽÄZI޵¢ÖõFïíØnÃÏçÉïá=Gb­$ÇZÑ3Ù©»Á €ú…XؽUœ‡µ’kEϤƒnöØ Ú` BÊó°Vrc­¨->ðYŽå^Å«>ðQwÖJr¬9° ›`€ºÇ×íX+ÉñùVä@ôÙƒ=ÄÕ„µ’kEŽý R{€µ’ ’f°V’c­H3X+ɱV¤¬•äX+Ò ÖJr¬ik%9ÖŠ:’ÙlNHHpƳV’c­¨#566îÚµëÚµkθq{­HZ¬i÷V’c­H3X+ɱV¤¬•äX+Ò ÖJr¬ik%9ÖŠ4ƒµ’kEšÁZI޵"Í`­$ÇZ‘f°V’c­H3X+ɱV¤¬•äX+Ò ÖJr¬ik%9ÖŠ:R·nÝ'NœèŒg­$Ç×¼¡Žäååå¤g­$ǽik%9ÖŠ4ƒµ’kEšÁZI޵"Í`­$ÇZ‘f°V’c­H3X+ɱV¤¬•äX+Ò ÖJr¬i‰N§c­¤ÅZ‘–°V2c­HKX+™±V¤%¬•ÌX+ÒÖJf¬u$«ÕzóæÍòòr'Ý>k%3ÖŠ:R]]Ïœtû¬•ÌX+ÒÖJf¬i k%3ÖŠ´„µ’kEZÂZÉŒµ"-a­dÆZ‘–°V2c­HKX+™±V¤%¬•ÌX+ÒÖJf¬i k%3ÖŠ´„µ’kEZÂZÉŒµ"-a­dÆZ‘–°V2ã×^^999•••S¦L騛µZ­z½Þþú4®¹¹ÙÍÍÍI7N.޵""møbòR5k,™IEND®B`‚rsyslog-8.2512.0/doc/source/PaxHeaders/configuration0000644000000000000000000000013015114544360017371 xustar0029 mtime=1764935920.98754296 30 atime=1764935930.261684937 29 ctime=1764935920.98754296 rsyslog-8.2512.0/doc/source/configuration/0000775000175000017500000000000015114544360017114 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/PaxHeaders/parser.rst0000644000000000000000000000013215055603742021502 xustar0030 mtime=1756825570.254068345 30 atime=1764928603.611782937 30 ctime=1764935920.962542577 rsyslog-8.2512.0/doc/source/configuration/parser.rst0000664000175000017500000000547415055603742021160 0ustar00rgerrgerParser ====== .. index:: ! parser .. _cfgobj_input: The ``parser`` object, as its name suggests, describes message parsers. Message parsers have a standard parser name, which can be used by simply loading the parser module. Only when specific parameters need to be set the parser object is needed. In that case, it is used to define a new parser name (aka "parser definition") which configures this name to use the parser module with set parameters. This is important as the ruleset() object does not support to set parser parameters. Instead, if parameters are needed, a proper parser name must be defined using the parser() object. A parser name defined via the parser() object can be used wherever a parser name can occur. Note that not all message parser modules are supported in the parser() object. The reason is that many do not have any user-selectable parameters and as such, there is no point in issuing a parser() object for them. The parser object has different parameters: - those that apply to all parser and are generally available for all of them. These are documented below. - parser-specific parameters. These are specific to a certain parser module. They are documented by the :doc:`parser module ` in question. General Parser Parameters ------------------------- Note: parameter names are case-insensitive. .. function:: name *Mandatory* This names the parser. Names starting with "rsyslog." are reserved for rsyslog use and must not be used. It is suggested to replace "rsyslog." with "custom." and keep the rest of the name descriptive. However, this is not enforced and just good practice. .. function:: type *Mandatory* The ```` is a string identifying the parser module as given it each module's documentation. Do not mistake the parser module name with its default parser name. For example, the :doc:`Cisco IOS message parser module ` parser module name is "pmciscoios", whereas it's default parser name is "rsyslog.pmciscoios". Samples ------- The following example creates a custom parser definition and uses it within a ruleset: :: module(load="pmciscoios") parser(name="custom.pmciscoios.with_origin" type="pmciscoios") ruleset(name="myRuleset" parser="custom.pmciscoios.with_origin") { ... do something here ... } The following example uses multiple parsers within a ruleset without a parser object (the order is important): :: module(load="pmaixforwardedfrom") module(load="pmlastmsg") ruleset(name="myRuleset" parser=["rsyslog.lastline","rsyslog.aixforwardedfrom","rsyslog.rfc5424","rsyslog.rfc3164"]) { ... do something here ... } A more elaborate example can also be found in the :doc:`Cisco IOS message parser module ` documentation. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/filters.rst0000644000000000000000000000013215055603742021656 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.267698648 30 ctime=1764935920.656537892 rsyslog-8.2512.0/doc/source/configuration/filters.rst0000664000175000017500000003371315055603742021331 0ustar00rgerrgerFilter Conditions ================= Rsyslog offers four different types "filter conditions": - "traditional" severity and facility based selectors - property-based filters - expression-based filters - BSD-style blocks (not upward compatible) Selectors --------- **Selectors are the traditional way of filtering syslog messages.** They have been kept in rsyslog with their original syntax, because it is well-known, highly effective and also needed for compatibility with stock syslogd configuration files. If you just need to filter based on priority and facility, you should do this with selector lines. They are **not** second-class citizens in rsyslog and offer the simplest syntax for this job. In versions of rsyslog prior to v7 there were significant performance gains by using selector lines instead of the |FmtAdvancedName| format. There is no longer any difference in performance between the two formats. The selector field itself again consists of two parts, a facility and a priority, separated by a period (".''). Both parts are case insensitive and can also be specified as decimal numbers, but don't do that, you have been warned. Both facilities and priorities are described in syslog(3). The names mentioned below correspond to the similar LOG\_-values in /usr/include/syslog.h. The facility is one of the following keywords: auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, security (same as auth), syslog, user, uucp and local0 through local7. The keyword security should not be used anymore and mark is only for internal use and therefore should not be used in applications. Anyway, you may want to specify and redirect these messages here. The facility specifies the subsystem that produced the message, i.e. all mail programs log with the mail facility (LOG\_MAIL) if they log using syslog. The priority is one of the following keywords, in ascending order: debug, info, notice, warning, warn (same as warning), err, error (same as err), crit, alert, emerg, panic (same as emerg). The keywords error, warn and panic are deprecated and should not be used anymore. The priority defines the severity of the message. The behavior of the original BSD syslogd is that all messages of the specified priority and higher are logged according to the given action. Rsyslogd behaves the same, but has some extensions. In addition to the above mentioned names the rsyslogd(8) understands the following extensions: An asterisk ("\*'') stands for all facilities or all priorities, depending on where it is used (before or after the period). The keyword none stands for no priority of the given facility. You can specify multiple facilities with the same priority pattern in one statement using the comma (",'') operator. You may specify as much facilities as you want. Remember that only the facility part from such a statement is taken, a priority part would be skipped. Multiple selectors may be specified for a single action using the semicolon (";'') separator. Remember that each selector in the selector field is capable to overwrite the preceding ones. Using this behavior you can exclude some priorities from the pattern. Rsyslogd has a syntax extension to the original BSD source, that makes the use of selectors use more intuitively. You may precede every priority with an equals sign ("='') to specify only this single priority and not any of the above. You may also (both is valid, too) precede the priority with an exclamation mark ("!'') to ignore all that priorities, either exact this one or this and any higher priority. If you use both extensions then the exclamation mark must occur before the equals sign, just use it intuitively. However, please note that there are some restrictions over the traditional BSD syslog behaviour. These restrictions stem back to sysklogd, exist probably since at least the 1990's and as such have always been in rsyslog. Namely, in BSD syslogd you can craft a selector like this: \*.debug;local6.err The intent is to log all facilities at debug or higher, except for local6, which should only log at err or higher. Unfortunately, local6.err will permit error severity and higher, but will *not* exclude lower severity messages from facility local6. As an alternative, you can explicitly exclude all severities that you do not want to match. For the above case, this selector is equivalent to the BSD syslog selector: \*.debug;local6.!=info;local6.!=notice;local6.!=warn An easier approach is probably to do if ... then based matching in script. Property-Based Filters ---------------------- Property-based filters are unique to rsyslogd. They allow to filter on any property, like HOSTNAME, syslogtag and msg. A list of all currently-supported properties can be found in the :doc:`rsyslog properties documentation `. With this filter, each property can be checked against a specified value, using a specified compare operation. A property-based filter must start with a colon **in column 1**. This tells rsyslogd that it is the new filter type. The colon must be followed by the property name, a comma, the name of the compare operation to carry out, another comma and then the value to compare against. This value must be quoted. There can be spaces and tabs between the commas. Property names and compare operations are case-sensitive, so "msg" works, while "MSG" is an invalid property name. In brief, the syntax is as follows: ``:property, [!]compare-operation, "value"`` Compare-Operations ~~~~~~~~~~~~~~~~~~ The following **compare-operations** are currently supported: **contains** Checks if the string provided in value is contained in the property. There must be an exact match, wildcards are not supported. **isequal** Compares the "value" string provided and the property contents. These two values must be exactly equal to match. The difference to contains is that contains searches for the value anywhere inside the property value, whereas all characters must be identical for isequal. As such, isequal is most useful for fields like syslogtag or FROMHOST, where you probably know the exact contents. **startswith** Checks if the value is found exactly at the beginning of the property value. For example, if you search for "val" with ``:msg, startswith, "val"`` it will be a match if msg contains "values are in this message" but it won't match if the msg contains "There are values in this message" (in the later case, *"contains"* would match). Please note that "startswith" is by far faster than regular expressions. So even once they are implemented, it can make very much sense (performance-wise) to use "startswith". **endswith** Checks if the value appears exactly at the end of the property value. For example, ``:programname, endswith, "_foo"`` matches if the program name ends with ``_foo``. **regex** Compares the property against the provided POSIX BRE regular expression. **ereregex** Compares the property against the provided POSIX ERE regular expression. You can use the bang-character (!) immediately in front of a compare-operation, the outcome of this operation is negated. For example, if msg contains "This is an informative message", the following sample would not match: ``:msg, contains, "error"`` but this one matches: ``:msg, !contains, "error"`` Using negation can be useful if you would like to do some generic processing but exclude some specific events. You can use the discard action in conjunction with that. A sample would be: :: *.* /var/log/allmsgs-including-informational.log :msg, contains, "informational"  ~ *.* /var/log/allmsgs-but-informational.log Do not overlook the tilde in line 2! In this sample, all messages are written to the file allmsgs-including-informational.log. Then, all messages containing the string "informational" are discarded. That means the config file lines below the "discard line" (number 2 in our sample) will not be applied to this message. Then, all remaining lines will also be written to the file allmsgs-but-informational.log. Value Part ~~~~~~~~~~ **Value** is a quoted string. It supports some escape sequences: \\" - the quote character (e.g. "String with \\"Quotes\\"") \\\\ - the backslash character (e.g. "C:\\\\tmp") Escape sequences always start with a backslash. Additional escape sequences might be added in the future. Backslash characters **must** be escaped. Any other sequence then those outlined above is invalid and may lead to unpredictable results. Probably, "msg" is the most prominent use case of property based filters. It is the actual message text. If you would like to filter based on some message content (e.g. the presence of a specific code), this can be done easily by: ``:msg, contains, "ID-4711"`` This filter will match when the message contains the string "ID-4711". Please note that the comparison is case-sensitive, so it would not match if "id-4711" would be contained in the message. ``:msg, regex, "fatal .* error"`` This filter uses a POSIX regular expression. It matches when the string contains the words "fatal" and "error" with anything in between (e.g. "fatal net error" and "fatal lib error" but not "fatal error" as two spaces are required by the regular expression!). Getting property-based filters right can sometimes be challenging. In order to help you do it with as minimal effort as possible, rsyslogd spits out debug information for all property-based filters during their evaluation. To enable this, run rsyslogd in foreground and specify the "-d" option. Boolean operations inside property based filters (like 'message contains "ID17" or message contains "ID18"') are currently not supported (except for "not" as outlined above). Please note that while it is possible to query facility and severity via property-based filters, it is far more advisable to use classic selectors (see above) for those cases. Expression-Based Filters ------------------------ Expression based filters allow filtering on arbitrary complex expressions, which can include boolean, arithmetic and string operations. Expression filters will evolve into a full configuration scripting language. Unfortunately, their syntax will slightly change during that process. So if you use them now, you need to be prepared to change your configuration files some time later. However, we try to implement the scripting facility as soon as possible (also in respect to stage work needed). So the window of exposure is probably not too long. Expression based filters are indicated by the keyword "if" in column 1 of a new line. They have this format: :: if expr then action-part-of-selector-line "if" and "then" are fixed keywords that must be present. "expr" is a (potentially quite complex) expression. So the :doc:`expression documentation <../rainerscript/expressions>` for details. "action-part-of-selector-line" is an action, just as you know it (e.g. "/var/log/logfile" to write to that file). BSD-style Blocks ---------------- **Note:** rsyslog v7+ no longer supports BSD-style blocks for technical reasons. So it is strongly recommended **not** to use them. Rsyslogd supports BSD-style blocks inside rsyslog.conf. Each block of lines is separated from the previous block by a program or hostname specification. A block will only log messages corresponding to the most recent program and hostname specifications given. Thus, a block which selects ‘ppp’ as the program, directly followed by a block that selects messages from the hostname ‘dialhost’, then the second block will only log messages from the ppp program on dialhost. A program specification is a line beginning with ‘!prog’ and the following blocks will be associated with calls to syslog from that specific program. A program specification for ‘foo’ will also match any message logged by the kernel with the prefix ‘foo: ’. Alternatively, a program specification ‘-foo’ causes the following blocks to be applied to messages from any program but the one specified. A hostname specification of the form ‘+hostname’ and the following blocks will be applied to messages received from the specified hostname. Alternatively, a hostname specification ‘-hostname’ causes the following blocks to be applied to messages from any host but the one specified. If the hostname is given as ‘@’, the local hostname will be used. (NOT YET IMPLEMENTED) A program or hostname specification may be reset by giving the program or hostname as ‘\*’. Please note that the "#!prog", "#+hostname" and "#-hostname" syntax available in BSD syslogd is not supported by rsyslogd. By default, no hostname or program is set. Examples -------- :: *.* /var/log/file1 # the traditional way if $msg contains 'error' then /var/log/errlog # the expression-based way Right now, you need to specify numerical values if you would like to check for facilities and severity. These can be found in :rfc:`5424`. If you don't like that, you can of course also use the textual property - just be sure to use the right one. As expression support is enhanced, this will change. For example, if you would like to filter on message that have facility local0, start with "DEVNAME" and have either "error1" or "error0" in their message content, you could use the following filter: :: if $syslogfacility-text == 'local0' and $msg startswith 'DEVNAME' and ($msg contains 'error1' or $msg contains 'error0') then /var/log/somelog Please note that the above must all be on one line! And if you would like to store all messages except those that contain "error1" or "error0", you just need to add a "not": :: if $syslogfacility-text == 'local0' and $msg startswith 'DEVNAME' and not ($msg contains 'error1' or $msg contains 'error0') then /var/log/somelog If you would like to do case-insensitive comparisons, use "contains\_i" instead of "contains" and "startswith\_i" instead of "startswith". Note that regular expressions are currently NOT supported in expression-based filters. These will be added later when function support is added to the expression engine (the reason is that regular expressions will be a separate loadable module, which requires some more prerequisites before it can be implemented). rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/cryprov_ossl.rst0000644000000000000000000000013215114522477022753 xustar0030 mtime=1764926783.023631563 30 atime=1764926784.231661215 30 ctime=1764935920.647537754 rsyslog-8.2512.0/doc/source/configuration/cryprov_ossl.rst0000664000175000017500000000553615114522477022430 0ustar00rgerrgerlibossl Log Crypto Provider (ossl) ==================================== **Crypto Provider Name:**    ossl **Author:** Attila Lakatos **Supported Since:** since 8.2408.0 **Description**: Provides encryption support to rsyslog. **Configuration Parameters**: Crypto providers are loaded by omfile, when the provider is selected in its "cry.providerName" parameter. Parameters for the provider are given in the omfile action instance line. This provider creates an encryption information file with the same base name but the extension ".encinfo" for each log file (both for fixed-name files as well as dynafiles). Both files together form a set. So you need to archive both in order to prove integrity. The main differences between the ossl and gcry crypto providers are: In ossl, algorithms are not hardcoded. There are concerns about potential side-channel vulnerabilities with ossl, such as the Minerva Attack and the Raccoon Attack, due to their bad handling of well-known side-channel attacks. As a result of the Marvin incident, they have downgraded their threat model. Note for distro maintainers: the libossl crypto provider will be available only if rsyslog is compiled with --enable-openssl option. - **cry.algo** The algorithm and mode to be used for encryption. The default is "AES-128-CBC". The actual availability of algorithms depends on which ones are compiled into openssl. The cipher implementation is retrieved using the EVP_CIPHER_fetch() function. See "ALGORITHM FETCHING" in crypto(7) for further information. Algorithms are not hardcoded, we provide everything that can be fetched using the aforementioned function. Note: Always check carefully when you change the algorithm if it's available. - **cry.key** TESTING AID, NOT FOR PRODUCTION USE. This uses the KEY specified inside rsyslog.conf. This is the actual key, and as such this mode is highly insecure. However, it can be useful for initial testing steps. This option may be removed in the future. - **cry.keyfile** Reads the key from the specified file. The file must contain the key, only, no headers or other meta information. Keyfiles can be generated via the rscrytool utility. **Caveats/Known Bugs:** - currently none known **Samples:** This encrypts a log file. Default parameters are used, the key is provided via a keyfile. :: action(type="omfile" file="/var/log/somelog" cry.provider="ossl" cry.keyfile="/secured/path/to/keyfile") In addition to previous example, this changes the default algorithm: :: action(type="omfile" file="/var/log/somelog" cry.provider="ossl" cry.keyfile="/secured/path/to/keyfile" cry.algo="AES-256-CBC") Note that the keyfile can be generated via the rscrytool utility (see its documentation for how to actually do that). rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/percentile_stats.rst0000644000000000000000000000013215055603742023556 xustar0030 mtime=1756825570.254068345 30 atime=1764928603.640783821 30 ctime=1764935920.964542608 rsyslog-8.2512.0/doc/source/configuration/percentile_stats.rst0000664000175000017500000001412615055603742023226 0ustar00rgerrgerPercentile Stats ================ The Percentile Stats component allows user to configure statistical namespaces (called stats-buckets), which can then be used to record statistical values for publishing periodic percentiles and summaries. Percentile Stats Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Percentile-stats configuration involves a **two part setup**. First, define a ``percentile-stats`` bucket and its attributes. Then, add statistics and observation values to the namespace, by making ``percentile_observation`` calls. percentile_stats(name="", percentiles=[...], windowsize=""...) (object) ----------------------------------------------------------------------------------------------------------- **Defines** the statistics bucket(identified by the bucket-name) and allows user to set some properties that control behavior of the bucket. .. code-block:: percentile_stats(name="bucket_name" percentiles=["95"] windowsize=1000) Parameters: **name** : Bucket name of a set of statistics to sample. **percentiles** : A list of strings, with percentile statistic value between 1, 100 inclusive, user would like to publish to impstats. This list of percentiles would apply for all statistics tracked under this bucket. **windowSize** : A max *sliding* window (FIFO) size - rounded *up* to the nearest power of 2, that is larger than the given window size. Specifies the maximum number of observations stored over an impstats reporting interval. This attribute would apply to all statistics tracked under this bucket. **delimiter** : A single character delimiter used in the published fully qualified statname. This delimiter would apply to all statistics tracked under this bucket. A definition setting all the parameters looks like: .. code-block:: percentile_stats(name="host_statistics" percentiles=["50", "95", "99"] windowsize="1000" delimiter="|") percentile_observe("", "", ) (function) ---------------------------------------------------------------- **Adds** a statistical sample to the statistic set identified by the , and . If the number of values exceed the defined **windowSize**, the earliest recorded value is dropped and the new value is recorded. .. note:: Sums and counts only include values found in the sliding window. Min and Max summary values will include all values seen over an observation interval. See :ref:`Reporting` below for more info on published summary statistics. Parameters: **bucket name** : Name of the statistic bucket **stat name** : Name of the statistic to record (this name will be combined with a percentile and reported by impstats to identify the percentile) **value** : Value to record A ``percentile_observe`` call looks like: .. code-block:: set $.ret = percentile_observe("host_statistics", "msg_per_host", $.mycount); if ($.ret != 0) then { .... } ``$.ret`` captures the error-code. It has value ``0`` when operation is successful and non-zero when it fails. It uses Rsyslog error-codes. .. _Reporting: Reporting ^^^^^^^^^ The following example metrics would be reported by **impstats** Legacy format: .. code-block:: ... global: origin=percentile host_statistics.new_metric_add=1 host_statistics.ops_overflow=0 ... host_statistics: origin=percentile.bucket msg_per_host|p95=1950 msg_per_host|p50=1500 msg_per_host|p99=1990 msg_per_host|window_min=1001 msg_per_host|window_max=2000 msg_per_host|window_sum=1500500 msg_per_host|window_count=1000 ... Json(variants with the same structure are used in other Json based formats such as ``cee`` and ``json-elasticsearch``) format: .. code-block:: ... { "name": "global", "origin": "percentile", "values": { "host_statistics.new_metric_add": 1, "host_statistics.ops_overflow": 0 } } ... { "name": "host_statistics", "origin": "percentile.bucket", "values": { "msg_per_host|p95": 1950, "msg_per_host|p50": 1500, "msg_per_host|p99": 1990, "msg_per_host|window_min": 1001, "msg_per_host|window_max": 2000, "msg_per_host|window_sum": 1500500, "msg_per_host|window_count": 1000 } } ... In this case counters are encapsulated inside an object hanging off top-level-key ``values``. Fields ------ **global: origin=percentile.bucket**: **new_metric_add**: Number of "new" metrics added (new counters created). **ops_overflow**: Number of operations ignored because number-of-counters-tracked has hit configured max-cardinality. **host_statistic: origin=percentile.bucket**: **msg_per_host|**: percentile value, identified by , where pXX is one of the requested ``percentiles`` requested. **msg_per_host|window_min**: minimum recorded value in the statistical population window. Identified by ``window_min`` **msg_per_host|window_max**: maximum recorded value in the statistical population window. Identified by ``window_max`` **msg_per_host|window_sum**: sum of recorded values in the statistical population window. Identified by ``delimiter>window_sum`` **msg_per_host|window_count**: count of recorded values in the statistical population window. Identified by ``window_count`` Implementation Details ---------------------- Percentile stats module uses a sliding window, sized according to the **windowSize** configuration parameter. The percentile values are calculated, once every **impstats** interval. Percentiles are calculated according to the standard “nearest-rank†method: n = CEILING((P/100) x N) where: * n - index to percentile value * P - percentile [1, 100] * N - number of values recorded .. note:: In order to sort the values, a standard implementation of quicksort is used, which performs pretty well on average. However quicksort quickly degrades when there are many repeated elements, thus it is best to avoid repeated values if possible. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/config_param_types.rst0000644000000000000000000000013215055603742024057 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.128697001 30 ctime=1764935920.641537663 rsyslog-8.2512.0/doc/source/configuration/config_param_types.rst0000664000175000017500000000336615055603742023533 0ustar00rgerrgerConfiguration Parameter Types ============================= Configuration parameter values have different data types. Unfortunately, the type currently must be guessed from the description (consider contributing to the doc to help improve it). In general, the following types are used: - **numbers** The traditional integer format. Numbers may include '.' and ',' for readability. So you can for example specify either "1000" or "1,000" with the same result. Please note that rsyslogd simply *ignores* the punctuation. From it's point of view, "1,,0.0.,.,0" also has the value 1000. - **sizes** Used for things like file size, main message queue sizes and the like. These are integers, but support modifier after the number part. For example, 1k means 1024. Supported are k(ilo), m(ega), g(iga), t(era), p(eta) and e(xa). Lower case letters refer to the traditional binary definition (e.g. 1m equals 1,048,576) whereas upper case letters refer to their new 1000-based definition (e.g 1M equals 1,000,000). - **complete line** A string consisting of multiple characters. This is relatively seldom used and sometimes looks confusing (rsyslog v7+ has a much better approach at these types of values). - **single word** This is used when only a single word can be provided. A "single word" is a string without spaces in it. **No** quoting is necessary nor permitted (the quotes would become part of the word). - **character** A single (printable) character. Must **not** be quoted. - **boolean** The traditional boolean type, specified as "on" (1) or "off" (0). Note that some other value types are occasionally used. However, the majority of types is one of those listed above. The list is updated as need arises and time permits. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/ruleset0000644000000000000000000000013115114544360021055 xustar0030 mtime=1764935920.980542853 29 atime=1764935930.36768656 30 ctime=1764935920.980542853 rsyslog-8.2512.0/doc/source/configuration/ruleset/0000775000175000017500000000000015114544360020577 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/ruleset/PaxHeaders/rsconf1_rulesetparser.rst0000644000000000000000000000013215071746523026227 xustar0030 mtime=1760021843.789420213 30 atime=1764928604.112798198 30 ctime=1764935920.980542853 rsyslog-8.2512.0/doc/source/configuration/ruleset/rsconf1_rulesetparser.rst0000664000175000017500000001203415071746523025673 0ustar00rgerrger$RulesetParser -------------- **Type:** ruleset-specific configuration directive **Parameter Values:** string **Available since:** 5.3.4+ **Default:** rsyslog.rfc5424 followed by rsyslog.rfc3164 **Description:** This directive permits to specify which `message parsers <../../concepts/messageparser.html>`_ should be used for the ruleset in question. It no ruleset is explicitly specified, the default ruleset is used. Message parsers are contained in (loadable) parser modules with the most common cases (RFC3164 and RFC5424) being built into rsyslogd. When this directive is specified the first time for a ruleset, it will not only add the parser to the ruleset's parser chain, it will also wipe out the default parser chain. So if you need to have them in addition to the custom parser, you need to specify those as well. Order of directives is important. Parsers are tried one after another, in the order they are specified inside the config. As soon as a parser is able to parse the message, it will do so and no other parsers will be executed. If no matching parser can be found, the message will be discarded and a warning message be issued (but only for the first 1,000 instances of this problem, to prevent message generation loops). Note that the rfc3164 parser will **always** be able to parse a message - it may just not be the format that you like. This has two important implications: 1) always place that parser at the END of the parser list, or the other parsers after it will never be tried and 2) if you would like to make sure no message is lost, placing the rfc3164 parser at the end of the parser list ensures that. Multiple parser modules are very useful if you have various devices that emit messages that are malformed in various ways. The route to take then is - make sure you find a custom parser for that device; if there is no one, you may consider writing one yourself (it is not that hard) or getting one written as part of `Adiscon's professional services for rsyslog `_. - load your custom parsers via $ModLoad - create a ruleset for each malformed format; assign the custom parser to it - create a specific listening port for all devices that emit the same malformed format - bind the listener to the ruleset with the required parser Note that it may be cumbersome to add all rules to all rulesets. To avoid this, you can either use $Include or `omruleset `_ (what probably provides the best solution). More information about rulesets in general can be found in :doc:`multi-ruleset support in rsyslog <../../concepts/multi_ruleset>`. **Caveats:** currently none known **Example:** This example assumes there are two devices emitting malformed messages via UDP. We have two custom parsers for them, named "device1.parser" and "device2.parser". In addition to that, we have a number of other devices sending well-formed messages, also via UDP. The solution is to listen for data from the two devices on two special ports (10514 and 10515 in this example), create a ruleset for each and assign the custom parsers to them. The rest of the messages are received via port 514 using the regular parsers. Processing shall be equal for all messages. So we simply forward the malformed messages to the regular queue once they are parsed (keep in mind that a message is never again parsed once any parser properly processed it). :: $ModLoad imudp $ModLoad pmdevice1 # load parser "device1.parser" for device 1 $ModLoad pmdevice2 # load parser "device2.parser" for device 2 # define ruleset for the first device sending malformed data $Ruleset maldev1 $RulesetCreateMainQueue on # create ruleset-specific queue $RulesetParser "device1.parser" # note: this deactivates the default parsers # forward all messages to default ruleset: $ActionOmrulesetRulesetName RSYSLOG\_DefaultRuleset \*.\* :omruleset: # define ruleset for the second device sending malformed data $Ruleset maldev2 $RulesetCreateMainQueue on # create ruleset-specific queue $RulesetParser "device2.parser" # note: this deactivates the default parsers # forward all messages to default ruleset: $ActionOmrulesetRulesetName RSYSLOG\_DefaultRuleset \*.\* :omruleset: # switch back to default ruleset $Ruleset RSYSLOG\_DefaultRuleset \*.\* /path/to/file auth.info @authlogger.example.net # whatever else you usually do... # now define the inputs and bind them to the rulesets # first the default listener (utilizing the default ruleset) $UDPServerRun 514 # now the one with the parser for device type 1: $InputUDPServerBindRuleset maldev1 $UDPServerRun 10514 # and finally the one for device type 2: $InputUDPServerBindRuleset maldev2 $UDPServerRun 10515 For an example of how multiple parser can be chained (and an actual use case), please see the example section on the `pmlastmsg `_ parser module. Note the positions of the directives. With the current config language, **sequence of statements is very important**. This is ugly, but unfortunately the way it currently works. rsyslog-8.2512.0/doc/source/configuration/ruleset/PaxHeaders/rsconf1_rulesetcreatemainqueue.rst0000644000000000000000000000013215055603742030105 xustar0030 mtime=1756825570.255068361 30 atime=1764928604.083797315 30 ctime=1764935920.978542822 rsyslog-8.2512.0/doc/source/configuration/ruleset/rsconf1_rulesetcreatemainqueue.rst0000664000175000017500000000627715055603742027565 0ustar00rgerrger`rsyslog.conf configuration directive `_ $RulesetCreateMainQueue ----------------------- **Type:** ruleset-specific configuration directive **Parameter Values:** boolean (on/off, yes/no) **Available since:** 5.3.5+ **Default:** off **Description:** Rulesets may use their own "main" message queue for message submission. Specifying this directive, **inside a ruleset definition**, turns this on. This is both a performance enhancement and also permits different rulesets (and thus different inputs within the same rsyslogd instance) to use different types of main message queues. The ruleset queue is created with the parameters that are specified for the main message queue at the time the directive is given. If different queue configurations are desired, different main message queue directives must be used **in front of** the $RulesetCreateMainQueue directive. Note that this directive may only be given once per ruleset. If multiple statements are specified, only the first is used and for the others error messages are emitted. Note that the final set of ruleset configuration directives specifies the parameters for the default main message queue. To learn more about this feature, please be sure to read about `multi-ruleset support in rsyslog `_. **Caveats:** The configuration statement "$RulesetCreateMainQueue off" has no effect at all. The capability to specify this is an artifact of the legacy configuration language. **Example:** This example sets up a tcp server with three listeners. Each of these three listener is bound to a specific ruleset. As a performance optimization, the rulesets all receive their own private queue. The result is that received messages can be independently processed. With only a single main message queue, we would have some lock contention between the messages. This does not happen here. Note that in this example, we use different processing. Of course, all messages could also have been processed in the same way ($IncludeConfig may be useful in that case!). :: $ModLoad imtcp # at first, this is a copy of the unmodified rsyslog.conf #define rulesets first $RuleSet remote10514 $RulesetCreateMainQueue on # create ruleset-specific queue *.* /var/log/remote10514 $RuleSet remote10515 $RulesetCreateMainQueue on # create ruleset-specific queue *.* /var/log/remote10515 $RuleSet remote10516 $RulesetCreateMainQueue on # create ruleset-specific queue mail.* /var/log/mail10516 & ~ # note that the discard-action will prevent this message from # being written to the remote10516 file - as usual... *.* /var/log/remote10516 # and now define listeners bound to the relevant ruleset $InputTCPServerBindRuleset remote10514 $InputTCPServerRun 10514 $InputTCPServerBindRuleset remote10515 $InputTCPServerRun 10515 $InputTCPServerBindRuleset remote10516 $InputTCPServerRun 10516 Note the positions of the directives. With the legacy language, position is very important. It is highly suggested to use the *ruleset()* object in RainerScript config language if you intend to use ruleset queues. The configuration is much more straightforward in that language and less error-prone. rsyslog-8.2512.0/doc/source/configuration/ruleset/PaxHeaders/index.rst0000644000000000000000000000013215055603742023000 xustar0030 mtime=1756825570.255068361 30 atime=1764928604.054796433 30 ctime=1764935920.976542792 rsyslog-8.2512.0/doc/source/configuration/ruleset/index.rst0000664000175000017500000000161015055603742022442 0ustar00rgerrgerRuleset-Specific Legacy Configuration Statements ================================================ These statements can be used to set ruleset parameters. To set these parameters, first use *$Ruleset*, **then** use the other configuration directives. Please keep in mind that each ruleset has a *main* queue. To specify parameter for these ruleset (main) queues, use the main queue configuration directives. .. toctree:: :glob: *rule* - **$Ruleset** *name* - starts a new ruleset or switches back to one already defined. All following actions belong to that new rule set. the *name* does not yet exist, it is created. To switch back to rsyslog's default ruleset, specify "RSYSLOG\_DefaultRuleset") as the name. All following actions belong to that new rule set. It is advised to also read our paper on :doc:`using multiple rule sets in rsyslog <../../concepts/multi_ruleset>`. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/input_directives0000644000000000000000000000013215114544360022753 xustar0030 mtime=1764935920.718538841 30 atime=1764935930.366686544 30 ctime=1764935920.718538841 rsyslog-8.2512.0/doc/source/configuration/input_directives/0000775000175000017500000000000015114544360022474 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_dropmsgswithmaliciousd0000644000000000000000000000031515062756615031227 xustar00115 path=rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_dropmsgswithmaliciousdnsptrrecords.rst 30 mtime=1758190989.172640709 30 atime=1764928593.095460758 30 ctime=1764935920.709538704 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_dropmsgswithmaliciousdnsptrrecord0000664000175000017500000000146715062756615033166 0ustar00rgerrger$DropMsgsWithMaliciousDnsPTRRecords ----------------------------------- **Type:** global configuration parameter **Default:** off **Description:** Rsyslog contains code to detect malicious DNS PTR records (reverse name resolution). An attacker might use specially-crafted DNS entries to make you think that a message might have originated on another IP address. Rsyslog can detect those cases. It will log an error message in any case. If this option here is set to "on", the malicious message will be completely dropped from your logs. If the option is set to "off", the message will be logged, but the original IP will be used instead of the DNS name. Reverse lookup results are cached; see :ref:`reverse_dns_cache` for controlling cache timeout and refresh. **Sample:** ``$DropMsgsWithMaliciousDnsPTRRecords on`` rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_markmessageperiod.rst0000644000000000000000000000013015055603742030721 xustar0029 mtime=1756825570.25006828 29 atime=1764928593.14846239 30 ctime=1764935920.718538841 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_markmessageperiod.rst0000664000175000017500000000125715055603742030374 0ustar00rgerrger$MarkMessagePeriod ------------------ **Type:** specific to immark input module **Default:** 1200 (20 minutes) **Description:** This specifies when mark messages are to be written to output modules. The time specified is in seconds. Specifying 0 is possible and disables mark messages. In that case, however, it is more efficient to NOT load the immark input module. So far, there is only one mark message process and any subsequent $MarkMessagePeriod overwrites the previous. **This parameter is only available after the immark input module has been loaded.** **Sample:** ``$MarkMessagePeriod  600 # mark messages appear every 10 Minutes`` **Available since:** rsyslog 3.0.0 rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_controlcharacterescape0000644000000000000000000000013115055603742031127 xustar0029 mtime=1756825570.25006828 30 atime=1764928593.082460358 30 ctime=1764935920.707538673 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_controlcharacterescapeprefix.rst0000664000175000017500000000137115055603742032623 0ustar00rgerrger$ControlCharacterEscapePrefix ----------------------------- **Type:** global configuration parameter **Default:** \\ **Description:** This option specifies the prefix character to be used for control character escaping (see option $EscapeControlCharactersOnReceive). By default, it is '\\', which is backwards-compatible with sysklogd. Change it to '#' in order to be compliant to the value that is somewhat suggested by Internet-Draft syslog-protocol. **IMPORTANT**: do not use the ' character. This is reserved and will most probably be used in the future as a character delimiter. For the same reason, the syntax of this parameter will probably change in future releases. **Sample:** ``$EscapeControlCharactersOnReceive #  # as of syslog-protocol`` rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_droptrailinglfonrecept0000644000000000000000000000013115055603742031171 xustar0029 mtime=1756825570.25006828 30 atime=1764928593.108461158 30 ctime=1764935920.711538734 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_droptrailinglfonreception.rst0000664000175000017500000000116715055603742032160 0ustar00rgerrger$DropTrailingLFOnReception -------------------------- **Type:** global configuration parameter **Default:** on **Description:** Syslog messages frequently have the line feed character (LF) as the last character of the message. In almost all cases, this LF should not really become part of the message. However, recent IETF syslog standardization recommends against modifying syslog messages (e.g. to keep digital signatures valid). This option allows to specify if trailing LFs should be dropped or not. The default is to drop them, which is consistent with what sysklogd does. **Sample:** ``$DropTrailingLFOnReception on`` rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_escapecontrolcharacter0000644000000000000000000000031115055603742031127 xustar00113 path=rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_escapecontrolcharactersonreceive.rst 29 mtime=1756825570.25006828 29 atime=1764928593.13546199 30 ctime=1764935920.716538811 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_escapecontrolcharactersonreceive.0000664000175000017500000000241515055603742032737 0ustar00rgerrger$EscapeControlCharactersOnReceive --------------------------------- **Type:** global configuration parameter **Default:** on **Description:** This parameter instructs rsyslogd to replace control characters during reception of the message. The intent is to provide a way to stop non-printable messages from entering the syslog system as whole. If this option is turned on, all control-characters are converted to a 3-digit octal number and be prefixed with the $ControlCharacterEscapePrefix character (being '\\' by default). For example, if the BEL character (ctrl-g) is included in the message, it would be converted to "\\007". To be compatible to sysklogd, this option must be turned on. **Warning:** - turning on this option most probably destroys non-western character sets (like Japanese, Chinese and Korean) - turning on this option destroys digital signatures if such exists inside the message - if turned on, the drop-cc, space-cc and escape-cc `property replacer `_ options do not work as expected because control characters are already removed upon message reception. If you intend to use these property replacer options, you must turn off $EscapeControlCharactersOnReceive. **Sample:** ``$EscapeControlCharactersOnReceive on`` rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_allowedsender.rst0000644000000000000000000000013215062756615030057 xustar0030 mtime=1758190989.172640709 30 atime=1764928593.068459926 30 ctime=1764935920.704538627 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_allowedsender.rst0000664000175000017500000000632015062756615027524 0ustar00rgerrger$AllowedSender -------------- **Type:** input configuration parameter **Default:** all allowed **Description:** *Note:* this feature is supported for backward-compatibility, only. The rsyslog team recommends to use proper firewalling instead of this feature. Allowed sender lists can be used to specify which remote systems are allowed to send syslog messages to rsyslogd. With them, further hurdles can be placed between an attacker and rsyslogd. If a message from a system not in the allowed sender list is received, that message is discarded. A diagnostic message is logged, so that the fact is recorded (this message can be turned off with the "-w" rsyslogd command line option). Allowed sender lists can be defined for UDP and TCP senders separately. There can be as many allowed senders as needed. The syntax to specify them is: :: $AllowedSender , ip[/bits], ip[/bits] "$AllowedSender" is the parameter - it must be written exactly as shown and the $ must start at the first column of the line. "" is either "UDP" or "TCP" (or "GSS", if this is enabled during compilation). It must immediately be followed by the comma, else you will receive an error message. "ip[/bits]" is a machine or network ip address as in "192.0.2.0/24" or "127.0.0.1". If the "/bits" part is omitted, a single host is assumed (32 bits or mask 255.255.255.255). "/0" is not allowed, because that would match any sending system. If you intend to do that, just remove all $AllowedSender parameters. If more than 32 bits are requested with IPv4, they are adjusted to 32. For IPv6, the limit is 128 for obvious reasons. Hostnames, with and without wildcards, may also be provided. If so, the result of revers DNS resolution is used for filtering. Multiple allowed senders can be specified in a comma-delimited list. Also, multiple $AllowedSender lines can be given. They are all combined into one UDP and one TCP list. Performance-wise, it is good to specify those allowed senders with high traffic volume before those with lower volume. As soon as a match is found, no further evaluation is necessary and so you can save CPU cycles. Rsyslogd handles allowed sender detection very early in the code, nearly as the first action after receiving a message. This keeps the access to potential vulnerable code in rsyslog at a minimum. However, it is still a good idea to impose allowed sender limitations via firewalling. **WARNING:** by UDP design, rsyslogd can not identify a spoofed sender address in UDP syslog packets. As such, a malicious person could spoof the address of an allowed sender, send such packets to rsyslogd and rsyslogd would accept them as being from the faked sender. To prevent this, use syslog via TCP exclusively. If you need to use UDP-based syslog, make sure that you do proper egress and ingress filtering at the firewall and router level. Rsyslog also detects some kind of malicious reverse DNS entries. In any case, using DNS names adds an extra layer of vulnerability. Reverse lookup results are cached; see :ref:`reverse_dns_cache` for ways to refresh cached names. We recommend to stick with hard-coded IP addresses wherever possible. **Sample:** :: $AllowedSender UDP, 127.0.0.1, 192.0.2.0/24, [::1]/128, *.example.net, somehost.example.com rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/rsconf1_escape8bitcharsonrecei0000644000000000000000000000013015055603742031025 xustar0029 mtime=1756825570.25006828 30 atime=1764928593.121461558 29 ctime=1764935920.71453878 rsyslog-8.2512.0/doc/source/configuration/input_directives/rsconf1_escape8bitcharsonreceive.rst0000664000175000017500000000270215055603742031636 0ustar00rgerrger$Escape8BitCharactersOnReceive ------------------------------ **Type:** global configuration parameter **Default:** off **Available Since:** 5.5.2 **Description:** This parameter instructs rsyslogd to replace non US-ASCII characters (those that have the 8th bit set) during reception of the message. This may be useful for some systems. Please note that this escaping breaks Unicode and many other encodings. Most importantly, it can be assumed that Asian and European characters will be rendered hardly readable by this settings. However, it may still be useful when the logs themselves are primarily in English and only occasionally contain local script. If this option is turned on, all control-characters are converted to a 3-digit octal number and be prefixed with the $ControlCharacterEscapePrefix character (being '#' by default). **Warning:** - turning on this option most probably destroys non-western character sets (like Japanese, Chinese and Korean) as well as European character sets. - turning on this option destroys digital signatures if such exists inside the message - if turned on, the drop-cc, space-cc and escape-cc `property replacer `_ options do not work as expected because control characters are already removed upon message reception. If you intend to use these property replacer options, you must turn off $Escape8BitCharactersOnReceive. **Sample:** ``$Escape8BitCharactersOnReceive on`` rsyslog-8.2512.0/doc/source/configuration/input_directives/PaxHeaders/index.rst0000644000000000000000000000013115055603742024674 xustar0029 mtime=1756825570.25006828 30 atime=1764928593.055459526 30 ctime=1764935920.702538597 rsyslog-8.2512.0/doc/source/configuration/input_directives/index.rst0000664000175000017500000000137015055603742024342 0ustar00rgerrgerLegacy Directives affecting Input Modules ========================================= Legacy Directives affecting multiple Input Modules -------------------------------------------------- While these directives only affect input modules, they are global in the sense that they cannot be overwritten for specific input instances. So they apply globally for all inputs that support these directives. .. toctree:: :glob: rsconf1_allowedsender rsconf1_dropmsgswithmaliciousdnsptrrecords rsconf1_controlcharacterescapeprefix rsconf1_droptrailinglfonreception rsconf1_escape8bitcharsonreceive rsconf1_escapecontrolcharactersonreceive immark-specific Directives -------------------------- .. toctree:: :glob: rsconf1_markmessageperiod rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/droppriv.rst0000644000000000000000000000013015055603742022051 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.195697795 28 ctime=1764935920.6505378 rsyslog-8.2512.0/doc/source/configuration/droppriv.rst0000664000175000017500000000247115055603742021523 0ustar00rgerrgerDropping privileges in rsyslog ============================== **Available since**: 4.1.1 **Description**: Rsyslogd provides the ability to drop privileges by impersonating as another user and/or group after startup. Please note that due to POSIX standards, rsyslogd always needs to start up as root if there is a listener who must bind to a network port below 1024. For example, the UDP listener usually needs to listen to 514 and therefore rsyslogd needs to start up as root. If you do not need this functionality, you can start rsyslog directly as an ordinary user. That is probably the safest way of operations. However, if a startup as root is required, you can use the $PrivDropToGroup and $PrivDropToUser config directives to specify a group and/or user that rsyslogd should drop to after initialization. Once this happens, the daemon runs without high privileges (depending, of course, on the permissions of the user account you specified). A special note for Docker and other container system users: user and group names are usually not fully mirrored into containers. As such, we strongly advise to use numerical IDs instead of user or group names when configuring privilege drop. Privilege drop is configured via the :doc:`global configuration object<../rainerscript/global>` under the "`privilege.`" set of parameters. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/properties.rst0000644000000000000000000000013215071746523022405 xustar0030 mtime=1760021843.789420213 30 atime=1764928603.677784948 30 ctime=1764935920.966542638 rsyslog-8.2512.0/doc/source/configuration/properties.rst0000664000175000017500000003264115071746523022057 0ustar00rgerrgerrsyslog Properties ================== Data items in rsyslog are called "properties". They can have different origin. The most important ones are those that stem from received messages. But there are also others. Whenever you want to access data items, you need to access the respective property. Properties are used in - :doc:`templates ` - conditional statements The property name is case-insensitive (prior to 3.17.0, they were case-sensitive). Note: many users refer to "rsyslog properties" as "rsyslog variables". You can treat them as synonymous. Read how `rsyslog lead author Rainer Gerhards explains the naming difference `_. Message Properties ------------------ These are extracted by rsyslog parsers from the original message. All message properties start with a letter. The following message properties exist: .. note:: Property names are case-insensitive. Use the spelling from headings in prose and examples. .. list-table:: :widths: 30 70 :header-rows: 1 * - Property - Summary * - :ref:`prop-message-msg` - .. include:: ../reference/properties/message-msg.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-rawmsg` - .. include:: ../reference/properties/message-rawmsg.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-rawmsg-after-pri` - .. include:: ../reference/properties/message-rawmsg-after-pri.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-hostname` - .. include:: ../reference/properties/message-hostname.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-source` - .. include:: ../reference/properties/message-source.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-fromhost` - .. include:: ../reference/properties/message-fromhost.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-fromhost-ip` - .. include:: ../reference/properties/message-fromhost-ip.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-fromhost-port` - .. include:: ../reference/properties/message-fromhost-port.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogtag` - .. include:: ../reference/properties/message-syslogtag.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-programname` - .. include:: ../reference/properties/message-programname.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-pri` - .. include:: ../reference/properties/message-pri.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-pri-text` - .. include:: ../reference/properties/message-pri-text.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-iut` - .. include:: ../reference/properties/message-iut.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogfacility` - .. include:: ../reference/properties/message-syslogfacility.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogfacility-text` - .. include:: ../reference/properties/message-syslogfacility-text.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogseverity` - .. include:: ../reference/properties/message-syslogseverity.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogseverity-text` - .. include:: ../reference/properties/message-syslogseverity-text.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogpriority` - .. include:: ../reference/properties/message-syslogpriority.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-syslogpriority-text` - .. include:: ../reference/properties/message-syslogpriority-text.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-timegenerated` - .. include:: ../reference/properties/message-timegenerated.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-timereported` - .. include:: ../reference/properties/message-timereported.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-timestamp` - .. include:: ../reference/properties/message-timestamp.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-protocol-version` - .. include:: ../reference/properties/message-protocol-version.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-structured-data` - .. include:: ../reference/properties/message-structured-data.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-app-name` - .. include:: ../reference/properties/message-app-name.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-procid` - .. include:: ../reference/properties/message-procid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-msgid` - .. include:: ../reference/properties/message-msgid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-inputname` - .. include:: ../reference/properties/message-inputname.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-uuid` - .. include:: ../reference/properties/message-uuid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-message-jsonmesg` - .. include:: ../reference/properties/message-jsonmesg.rst :start-after: .. summary-start :end-before: .. summary-end System Properties ----------------- These properties are provided by the rsyslog core engine. They are **not** related to the message. All system properties start with a dollar-sign. Special care needs to be taken in regard to time-related system variables: * ``timereported`` contains the timestamp that is contained within the message header. Ideally, it resembles the time when the message was created at the original sender. Depending on how long the message was in the relay chain, this can be quite old. * ``timegenerated`` contains the timestamp when the message was received by the local system. Here "received" actually means the point in time when the message was handed over from the OS to rsyslog's reception buffers, but before any actual processing takes place. This also means a message is "received" before it is placed into any queue. Note that depending on the input, some minimal processing like extraction of the actual message content from the receive buffer can happen. If multiple messages are received via the same receive buffer (a common scenario for example with TCP-based syslog), they bear the same ``timegenerated`` stamp because they actually were received at the same time. * ``$now`` is **not** from the message. It is the system time when the message is being **processed**. There is always a small difference between ``timegenerated`` and ``$now`` because processing always happens after reception. If the message is sitting inside a queue on the local system, the time difference between the two can be some seconds (e.g. due to a message burst and in-memory queueing) up to several hours in extreme cases where a message is sitting inside a disk queue (e.g. due to a database outage). The ``timereported`` property is usually older than ``timegenerated``, but may be totally different due to differences in time and time zone configuration between systems. The following system properties exist: .. list-table:: :widths: 30 70 :header-rows: 1 * - Property - Summary * - :ref:`prop-system-bom` - .. include:: ../reference/properties/system-bom.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-myhostname` - .. include:: ../reference/properties/system-myhostname.rst :start-after: .. summary-start :end-before: .. summary-end Time-Related System Properties .............................. All of these system properties exist in a local time variant (e.g. \$now) and a variant that emits UTC (e.g. \$now-utc). The UTC variant is always available by appending "-utc". Note that within a single template, only the localtime or UTC variant should be used. While it is possible to mix both variants within a single template, it is **not** guaranteed that they will provide exactly the same time. The technical reason is that rsyslog needs to re-query system time when the variant is changed. Because of this, we strongly recommend not mixing both variants in the same template. Note that use in different templates will generate a consistent timestamp within each template. However, as $now always provides local system time at time of using it, time may advance and consequently different templates may have different time stamp. To avoid this, use *timegenerated* instead. .. list-table:: :widths: 30 70 :header-rows: 1 * - Property - Summary * - :ref:`prop-system-time-now` - .. include:: ../reference/properties/system-time-now.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-year` - .. include:: ../reference/properties/system-time-year.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-month` - .. include:: ../reference/properties/system-time-month.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-day` - .. include:: ../reference/properties/system-time-day.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-wday` - .. include:: ../reference/properties/system-time-wday.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-hour` - .. include:: ../reference/properties/system-time-hour.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-hhour` - .. include:: ../reference/properties/system-time-hhour.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-qhour` - .. include:: ../reference/properties/system-time-qhour.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-minute` - .. include:: ../reference/properties/system-time-minute.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`prop-system-time-now-unixtimestamp` - .. include:: ../reference/properties/system-time-now-unixtimestamp.rst :start-after: .. summary-start :end-before: .. summary-end .. toctree:: :hidden: ../reference/properties/message-msg ../reference/properties/message-rawmsg ../reference/properties/message-rawmsg-after-pri ../reference/properties/message-hostname ../reference/properties/message-source ../reference/properties/message-fromhost ../reference/properties/message-fromhost-ip ../reference/properties/message-fromhost-port ../reference/properties/message-syslogtag ../reference/properties/message-programname ../reference/properties/message-pri ../reference/properties/message-pri-text ../reference/properties/message-iut ../reference/properties/message-syslogfacility ../reference/properties/message-syslogfacility-text ../reference/properties/message-syslogseverity ../reference/properties/message-syslogseverity-text ../reference/properties/message-syslogpriority ../reference/properties/message-syslogpriority-text ../reference/properties/message-timegenerated ../reference/properties/message-timereported ../reference/properties/message-timestamp ../reference/properties/message-protocol-version ../reference/properties/message-structured-data ../reference/properties/message-app-name ../reference/properties/message-procid ../reference/properties/message-msgid ../reference/properties/message-inputname ../reference/properties/message-uuid ../reference/properties/message-jsonmesg ../reference/properties/system-bom ../reference/properties/system-myhostname ../reference/properties/system-time-now ../reference/properties/system-time-year ../reference/properties/system-time-month ../reference/properties/system-time-day ../reference/properties/system-time-wday ../reference/properties/system-time-hour ../reference/properties/system-time-hhour ../reference/properties/system-time-qhour ../reference/properties/system-time-minute ../reference/properties/system-time-now-unixtimestamp rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/basic_structure.rst0000644000000000000000000000013015055605325023404 xustar0028 mtime=1756826325.6178002 30 atime=1764928348.088696527 30 ctime=1764935920.636537586 rsyslog-8.2512.0/doc/source/configuration/basic_structure.rst0000664000175000017500000001511715055605325023057 0ustar00rgerrgerBasic Structure =============== This page introduces the core concepts and structure of rsyslog configuration. Rsyslog is best thought of as a **highly extensible logging and event processing framework**. While the general message flow is fixed, almost every aspect of its processing pipeline can be customized by configuring rsyslog objects. Message Flow Overview --------------------- At a high level, rsyslog processes messages in three main stages: 1. **Inputs**: Messages are received from input modules (e.g., `imuxsock` for system logs or `imtcp` for TCP-based logging). 2. **Rulesets**: Each message is passed through one or more rulesets. A ruleset contains a sequence of rules, each with a filter and associated actions. 3. **Actions (Outputs)**: When a rule matches, its actions are executed. Actions determine what to do with the message: write to a file, forward to a remote server, insert into a database, or other processing. .. mermaid:: flowchart LR A[Input Modules] --> B[Rulesets] B --> C[Rules: Filter and Action List] C --> D[Actions and Outputs] D --> E[File, DB, Remote,
Custom Destinations] Processing Principles --------------------- Key rules to understand the rsyslog processing model: - **Rulesets as Entry Points**: Inputs submit messages to a ruleset. If no ruleset is explicitly bound, the default ruleset (`RSYSLOG_DefaultRuleset`) is used. Additional, custom rulesets can be defined. - **Rules within Rulesets**: A ruleset contains zero or more rules (though zero rules makes no sense). Rules are evaluated **in order, top to bottom**, within the ruleset. - **Filter and Action Lists**: A rule consists of a **filter** (evaluated as true/false) and an **action list**. When a filter matches, the action list is executed. If a filter does not match, rsyslog continues with the next rule. - **Full Evaluation**: All rules are evaluated unless message processing is explicitly stopped by a ``stop`` command. ``stop`` immediately halts processing for that message. - **Action Lists**: An action list can contain one or multiple actions. Actions are executed sequentially. Actions have no filters inside the same list (filters apply only at the rule level). .. mermaid:: flowchart TD Start([Message Entered]) --> CheckFilter1{Filter 1 Match?} CheckFilter1 -- Yes --> Action1[Execute Action 1] CheckFilter1 -- No --> CheckFilter2{Filter 2 Match?} CheckFilter2 -- Yes --> Action2[Execute Action 2] CheckFilter2 -- No --> End([Processing Ends]) Action1 --> CheckFilter2 Action2 --> End Configuration File ------------------ By default, rsyslog loads its configuration from ``/etc/rsyslog.conf``. This file may include other configuration snippets (commonly under ``/etc/rsyslog.d/``). To specify a different configuration file, use: .. code-block:: bash rsyslogd -f /path/to/your-config.conf Supported Configuration Formats ------------------------------- Rsyslog historically supported three configuration syntaxes: 1. **RainerScript (modern style)** – **recommended and actively maintained** This is the current, fully supported configuration format. It is clean, structured, and best suited for new and complex configurations. 2. **sysklogd style (legacy)** – **deprecated for new configs** This format is widely known and still functional, but **hard to grasp for new users**. It remains an option for experienced admins who know it well or need to maintain older configurations. Example: .. code-block:: none mail.info /var/log/mail.log mail.err @server.example.net 3. **Legacy rsyslog style (dollar-prefix)** – **deprecated** This format, with directives starting with `$` (e.g., `$ActionFileDefaultTemplate`), is fully supported for backward compatibility but **not recommended for any new configuration**. Why Prefer RainerScript? ~~~~~~~~~~~~~~~~~~~~~~~~ RainerScript is easier to read and maintain, avoids side effects with include files, and supports modern features such as structured filters, templates, and complex control flow. **For new configurations, always use RainerScript.** Legacy formats exist only for compatibility with older setups and distributions. Example RainerScript rule: .. code-block:: rsyslog if $syslogfacility-text == 'mail' and $syslogseverity-text == 'err' then { action(type="omfile" file="/var/log/mail-errors.log") } Comments -------- Rsyslog supports: - **# Comments** — start with `#` and extend to the end of the line. - **C-style Comments** — start with `/*` and end with `*/`. These can span multiple lines but cannot be nested. Processing Order ---------------- - Directives are processed **in order from top to bottom** of the configuration. - Once a message is stopped via ``stop`` subsequent statements will not be evaluated for that message. Flow Control ~~~~~~~~~~~~ - Control structures (if/else, etc.) are available in RainerScript. - Filters (e.g., `prifilt()`) provide conditional matching for messages. See :doc:`../rainerscript/control_structures` and :doc:`filters` for details. Data Manipulation ~~~~~~~~~~~~~~~~~ Data can be modified using the `set`, `unset`, and `reset` statements. For details, refer to :doc:`../rainerscript/variable_property_types`. Inputs ------ - Each input requires a dedicated input module. - Inputs are defined using the `input()` object after loading the module. Example: .. code-block:: rsyslog module(load="imtcp") # Load TCP input module input(type="imtcp" port="514") # Listen on TCP port 514 See :doc:`modules/index` for the full list of input modules. Outputs (Actions) ----------------- - Actions are responsible for output, such as writing to files, databases, or forwarding to other systems. - Actions are configured with the `action()` object. Example: .. code-block:: rsyslog action(type="omfile" file="/var/log/messages") # Write to local file Rulesets and Rules ------------------ - A **ruleset** acts like a "program" for message processing. - A ruleset can be bound to specific inputs or used as the default. Example: .. code-block:: rsyslog ruleset(name="fileLogging") { if prifilt("*.info") then { action(type="omfile" file="/var/log/info.log") } } .. mermaid:: graph TD Input1[Input: imtcp] --> Ruleset1 Input2[Input: imudp] --> Ruleset2 Ruleset1 --> Action1[omfile] Ruleset2 --> Action2[omfwd] Ruleset2 --> Action3[omelasticsearch] For details, see :doc:`../concepts/multi_ruleset`. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/timezone.rst0000644000000000000000000000013115055603742022037 xustar0030 mtime=1756825570.255068361 30 atime=1764928604.278803251 29 ctime=1764935920.98754296 rsyslog-8.2512.0/doc/source/configuration/timezone.rst0000664000175000017500000000426015055603742021506 0ustar00rgerrgertimezone ======== .. index:: ! timezone .. _cfgobj_input: The ``timezone`` object, as its name suggests, describes timezones. Currently, they are used by message parser modules to interpret timestamps that contain timezone information via a timezone string (but not an offset, e.g. "CET" but not "-01:00"). The object describes a UTC offset for a given timezone ID. Each timestamp object adds the zone definition to a global table with timezone information. Duplicate IDs are forbidden, but the same offset may be used with multiple IDs. As with other configuration objects, parameters for this object are case-insensitive. Parameters ---------- .. function:: id *Mandatory* This identifies the timezone. Note that this id must match the zone name as reported within the timestamps. Different devices and vendors use different, often non-standard, names and so it is important to use the actual ids that messages contain. For multiple devices, this may mean that you may need to include multiple definitions, each one with a different id, for the same time zone. For example, it is seen that some devices report "CEST" for central European daylight savings time while others report "METDST" for it. .. function:: offset <[+/-]>: *Mandatory* This defines the timezone offset over UTC. It must always be 6 characters and start with a "+" (east of UTC) or "-" (west uf UTC) followed by a two-digit hour offset, a colon and a two-digit minute offset. Hour offsets can be in the range from zero to twelve, minute offsets in the range from zero to 59. Any other format is invalid. Sample ------ The following sample defines UTC time. From rsyslog PoV, it doesn't matter if a plus or minus offset prefix is used. For consistency, plus is suggested. :: timezone(id="UTC" offset="+00:00") The next sample defines some common timezones: :: timezone(id="CET" offset="+01:00") timezone(id="CEST" offset="+02:00") timezone(id="METDST" offset="+02:00") # duplicate to support different formats timezone(id="EST" offset="-05:00") timezone(id="EDT" offset="-04:00") timezone(id="PST" offset="-08:00") timezone(id="PDT" offset="-07:00") rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/output_channels.rst0000644000000000000000000000013215055603742023421 xustar0030 mtime=1756825570.254068345 30 atime=1764928603.585782145 30 ctime=1764935920.959542531 rsyslog-8.2512.0/doc/source/configuration/output_channels.rst0000664000175000017500000000643115055603742023071 0ustar00rgerrgerOutput Channels --------------- Output Channels are a new concept first introduced in rsyslog 0.9.0. **As of this writing, it is most likely that they will be replaced by something different in the future.** So if you use them, be prepared to change you configuration file syntax when you upgrade to a later release. The idea behind output channel definitions is that it shall provide an umbrella for any type of output that the user might want. In essence, this is the "file" part of selector lines (and this is why we are not sure output channel syntax will stay after the next review). There is a difference, though: selector channels both have filter conditions (currently facility and severity) as well as the output destination. they can only be used to write to files - not pipes, ttys or whatever Output channels define the output definition, only. As of this build, else. If we stick with output channels, this will change over time. In concept, an output channel includes everything needed to know about an output actions. In practice, the current implementation only carries a filename, a maximum file size and a command to be issued when this file size is reached. More things might be present in future version, which might also change the syntax of the directive. Output channels are defined via an $outchannel directive. It's syntax is as follows: $outchannel name,file-name,max-size,action-on-max-size name is the name of the output channel (not the file), file-name is the file name to be written to, max-size the maximum allowed size and action-on-max-size a command to be issued when the max size is reached. This command always has exactly one parameter. The binary is that part of action-on-max-size before the first space, its parameter is everything behind that space. Please note that max-size is queried BEFORE writing the log message to the file. So be sure to set this limit reasonably low so that any message might fit. For the current release, setting it 1k lower than you expected is helpful. The max-size must always be specified in bytes - there are no special symbols (like 1k, 1m,...) at this point of development. Keep in mind that $outchannel just defines a channel with "name". It does not activate it. To do so, you must use a selector line (see below). That selector line includes the channel name plus a $ sign in front of it. A sample might be: \*.\* :omfile:$mychannel In its current form, output channels primarily provide the ability to size-limit an output file. To do so, specify a maximum size. When this size is reached, rsyslogd will execute the action-on-max-size command and then reopen the file and retry. The command should be something like a `log rotation script `_ or a similar thing. If there is no action-on-max-size command or the command did not resolve the situation, the file is closed and never reopened by rsyslogd (except, of course, by huping it). This logic was integrated when we first experienced severe issues with files larger 2gb, which could lead to rsyslogd dumping core. In such cases, it is more appropriate to stop writing to a single file. Meanwhile, rsyslogd has been fixed to support files larger 2gb, but obviously only on file systems and operating system versions that do so. So it can still make sense to enforce a 2gb file size limit. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/index_directives.rst0000644000000000000000000000013015055603742023534 xustar0029 mtime=1756825570.25006828 30 atime=1764928592.995457678 29 ctime=1764935920.69753852 rsyslog-8.2512.0/doc/source/configuration/index_directives.rst0000664000175000017500000000143715055603742023207 0ustar00rgerrgerLegacy Configuration Directives =============================== All legacy configuration directives need to be specified on a line by their own and must start with a dollar-sign. Note that legacy configuration directives that set object options (e.g. for inputs or actions) only affect those objects that are defined via legacy constructs. Objects defined via new-style RainerScript objects (e.g. action(), input()) are **not** affected by legacy directives. The reason is that otherwise we would again have the ability to mess up a configuration file with hard to understand constructs. This is avoided by not permitting to mix and match the way object values are set. .. toctree:: :maxdepth: 2 config_param_types global/index input_directives/index action/index ruleset/index rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/ipv6.rst0000644000000000000000000000013015055603742021070 xustar0029 mtime=1756825570.25006828 29 atime=1764928593.16146279 30 ctime=1764935920.720538872 rsyslog-8.2512.0/doc/source/configuration/ipv6.rst0000664000175000017500000000522415055603742020541 0ustar00rgerrgerNotes on IPv6 Handling in Rsyslog ================================= **Rsyslog fully\* supports sending and receiving syslog messages via both IPv4 and IPv6.** IPv6 is natively supported for both UDP and TCP. However, there are some options that control handling of IPv6 operations. I thought it is a good idea to elaborate a little about them, so that you can probably find your way somewhat easier. First of all, you can restrict rsyslog to using IPv4 or IPv6 addresses only by specifying the -4 or -6 command line option (now guess which one does what...). If you do not provide any command line option, rsyslog uses IPv4 and IPv6 addresses concurrently. In practice, that means the listener binds to both addresses (provided they are configured). When sending syslog messages, rsyslog uses IPv4 addresses when the receiver can be reached via IPv4 and IPv6 addresses if it can be reached via IPv6. If it can be reached on either IPv4 and v6, rsyslog leaves the choice to the socket layer. The important point to know is that it uses whatever connectivity is available to reach the destination. **There is one subtle difference between UDP and TCP.** With the new IPv4/v6 ignorant code, rsyslog has potentially different ways to reach destinations. The socket layer returns all of these paths in a sorted array. For TCP, rsyslog loops through this array until a successful TCP connect can be made. If that happens, the other addresses are ignored and messages are sent via the successfully-connected socket. For UDP, there is no such definite success indicator. Sure, the socket layer may detect some errors, but it may not notice other errors (due to the unreliable nature of UDP). By default, the UDP sender also tries one entry after the other in the sorted array of destination addresses. When a send fails, the next address is tried. When the send function finally succeeds, rsyslogd assumes the UDP packet has reached its final destination. However, if rsyslogd is started with the "-A" (capital A!) was given on the command line, rsyslogd will continue to send messages until the end of the destination address array is reached. This may result in duplicate messages, but it also provides some additional reliability in case a message could not be received. You need to be sure about the implications before applying this option. In general, it is NOT recommended to use the -A option. **\***\ rsyslog does not support RFC 3195 over IPv6. The reason is that the RFC 3195 library, `liblogging `_, supports IPv4, only. Currently, there are no plans to update either rsyslog to another RFC 3195 stack or update liblogging. There is simply no demand for 3195 solutions. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/dyn_stats.rst0000644000000000000000000000013215114522477022217 xustar0030 mtime=1764926783.023631563 30 atime=1764926784.231661215 30 ctime=1764935920.652537831 rsyslog-8.2512.0/doc/source/configuration/dyn_stats.rst0000664000175000017500000000755515114522477021677 0ustar00rgerrgerDynamic Stats ============= Rsyslog produces runtime-stats to allow user to study service health, performance, bottlenecks etc. Runtime-stats counters that Rsyslog components publish are statically defined. **Dynamic Stats** (called dyn-stats henceforth) component allows user to configure stats-namespaces (called stats-buckets) and increment counters within these buckets using RainerScript function call. The metric-name in this case can be a message-property or a sub-string extracted from message etc. Dyn-stats configuration ^^^^^^^^^^^^^^^^^^^^^^^ Dyn-stats configuration involves a **two part setup**. dyn_stats(name=""...) (object) -------------------------------------- **Defines** the bucket(identified by the bucket-name) and allows user to set some properties that control behavior of the bucket. :: dyn_stats(name="msg_per_host") Parameters: **name** : Name of the bucket. **resettable** : Whether or not counters should be reset every time they are reported. This works independent of ``resetCounters`` config parameter in :doc:`modules/impstats`. **maxCardinality** : Maximum number of unique counter-names to track. **unusedMetricLife** : Interval between full purges (in seconds). This prevents unused counters from occupying resources forever. A definition setting all the parameters looks like: :: dyn_stats(name="msg_per_host" resettable="on" maxCardinality="3000" unusedMetricLife="600") dyn_inc("", ) (function) -------------------------------------- **Increments** counter identified by value of variable in bucket identified by name. Parameters: **name** : Name of the bucket **expr** : Name of counter (this name will be reported by impstats to identify the counter) A ``dyn_inc`` call looks like: :: set $.inc = dyn_inc("msg_per_host", $hostname); if ($.inc != 0) then { .... } ``$.inc`` captures the error-code. It has value ``0`` when increment operation is successful and non-zero when it fails. It uses Rsyslog error-codes. Reporting ^^^^^^^^^ Legacy format: :: ... global: origin=dynstats msg_per_host.ops_overflow=1 msg_per_host.new_metric_add=3 msg_per_host.no_metric=0 msg_per_host.metrics_purged=0 msg_per_host.ops_ignored=0 ... msg_per_host: origin=dynstats.bucket foo=2 bar=1 baz=1 ... Json(variants with the same structure are used in other Json based formats such as ``cee`` and ``json-elasticsearch``) format: :: ... { "name": "global", "origin": "dynstats", "values": { "msg_per_host.ops_overflow": 1, "msg_per_host.new_metric_add": 3, "msg_per_host.no_metric": 0, "msg_per_host.metrics_purged": 0, "msg_per_host.ops_ignored": 0 } } ... { "name": "msg_per_host", "origin": "dynstats.bucket", "values": { "foo": 2, "bar": 1, "baz": 1 } } ... In this case counters are encapsulated inside an object hanging off top-level-key ``values``. Fields ------ **global: origin=dynstats**: **ops_overflow**: Number of operations ignored because number-of-counters-tracked has hit configured max-cardinality. **new_metric_add**: Number of "new" metrics added (new counters created). **no_metric**: Counter-name given was invalid (length = 0). **metrics_purged**: Number of counters discarded at discard-cycle (controlled by **unusedMetricLife**). **ops_ignored**: Number of operations ignored due to potential performance overhead. Dyn-stats subsystem ignores operations to avoid performance-penalty if it can't get access to counter without delay(lock acquiring latency). **purge_triggered**: Indicates that a discard was performed (1 implies a discard-cycle run). **msg_per_host: origin=dynstats.bucket**: ****: Value of counter identified by . rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/rsyslog-example.conf0000644000000000000000000000013215071746523023461 xustar0030 mtime=1760021843.789420213 30 atime=1764928634.979722777 30 ctime=1764935920.971542715 rsyslog-8.2512.0/doc/source/configuration/rsyslog-example.conf0000664000175000017500000001402715071746523023131 0ustar00rgerrger# A commented quick reference and sample configuration # WARNING: This is not a manual, the full manual of rsyslog configuration is in # rsyslog.conf (5) manpage # # "$" starts lines that contain new directives. The full list of directives # can be found in /usr/share/doc/rsyslog-1.19.6/doc/rsyslog_conf.html or online # at http://www.rsyslog.com/doc if you do not have (or find) a local copy. # # Set syslogd options # Some global directives # ---------------------- # $AllowedSender - specifies which remote systems are allowed to send syslog messages to rsyslogd # -------------- $AllowedSender UDP, 127.0.0.1, 192.0.2.0/24, [::1]/128, *.example.net, somehost.example.com # $UMASK - specifies the rsyslogd processes' umask # ------ $umask 0000 # $FileGroup - Set the group for dynaFiles newly created # ---------- $FileGroup loggroup # $FileOwner - Set the file owner for dynaFiles newly created. # ---------- $FileOwner loguser # $IncludeConfig - include other files into the main configuration file # -------------- $IncludeConfig /etc/some-included-file.conf # one file $IncludeConfig /etc/rsyslog.d/ # whole directory (must contain the final slash) # $ModLoad - Dynamically loads a plug-in and activates it # -------- $ModLoad ommysql # load MySQL functionality $ModLoad /rsyslog/modules/somemodule.so # load a module via absolute path # Templates # --------- # Templates allow to specify any format a user might want. # They MUST be defined BEFORE they are used. # A template consists of a template directive, a name, the actual template text # and optional options. A sample is: # $template MyTemplateName,"\7Text %property% some more text\n", # where: # * $template - tells rsyslog that this line contains a template. # * MyTemplateName - template name. All other config lines refer to this name. # * "\7Text %property% some more text\n" - templage text # The backslash is an escape character, i.e. \7 rings the bell, \n is a new line. # To escape: # % = \% # \ = \\ # Template options are case-insensitive. Currently defined are: # sql format the string suitable for an SQL statement. This will replace single # quotes ("'") by two single quotes ("''") to prevent the SQL injection # (NO_BACKSLASH_ESCAPES turned off) # stdsql - format the string suitable for an SQL statement that is to # be sent to a standards-compliant sql server. # (NO_BACKSLASH_ESCAPES turned on) # Properties inside templates # --------------------------- # Properties can be modified by the property replacer. They are accessed # inside the template by putting them between percent signs. The full syntax is as follows: # %propname:fromChar:toChar:options% # FromChar and toChar are used to build substrings. # If you need to obtain the first 2 characters of the # message text, you can use this syntax: "%msg:1:2%". # If you do not wish to specify from and to, but you want to # specify options, you still need to include the colons. # For example, to convert the full message text to lower case only, use # "%msg:::lowercase%". # The full list of property options can be found in rsyslog.conf(5) manpage # Samples of template definitions # ------------------------------- # A template that resambles traditional syslogd file output: $template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n" # A more verbose template: $template precise,"%syslogpriority%,%syslogfacility%,%timegenerated::fulltime%,%HOSTNAME%,%syslogtag%,%msg%\n" # A template that resembles RFC 3164 on-the-wire format: # (yes, there is NO space between syslogtag and msg! that's important!) $template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%" # a template resembling traditional wallmessage format: $template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r" # The template below emulates winsyslog format, but we need to check the time # stamps used. It is also a good sampleof the property replacer in action. $template WinSyslogFmt,"%HOSTNAME%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%syslogfacility%,%syslogpriority%,%syslogtag%%msg%\n" # A template used for database writing (notice it *is* an actual # sql-statement): $template dbFormat,"insert into SystemEvents (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%',%syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')",sql # Samples of rules # ---------------- # Regular file # ------------ *.* /var/log/traditionalfile.log;TraditionalFormat # log to a file in the traditional format # Forwarding to remote machine # ---------------------------- *.* @172.19.2.16 # udp (standard for syslog) *.* @@172.19.2.17 # tcp # Database action # --------------- # (you must have rsyslog-mysql package installed) # !!! Don't forget to set permission of rsyslog.conf to 600 !!! *.* >hostname,dbname,userid,password # (default Monitorware schema, can be created by /usr/share/doc/rsyslog-mysql-1.19.6/createDB.sql) # And this one uses the template defined above: *.* >hostname,dbname,userid,password;dbFormat # Program to execute # ------------------ *.* ^alsaunmute # set default volume to soundcard # Filter using regex # ------------------ # if the user logges word rulez or rulezz or rulezzz or..., then we will shut down his pc # (note, that + have to be double backslashed...) :msg, regex, "rulez\\+" ^poweroff # A more complex example # ---------------------- $template bla_logged,"%timegenerated% the BLA was logged" :msg, contains, "bla" ^logger;bla_logged # Pipes # ----- # first we need to create pipe by # mkfifo /a_big_pipe *.* |/a_big_pipe # Discarding # ---------- *.* ~ # discards everything rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/global0000644000000000000000000000013215114544360020633 xustar0030 mtime=1764935920.659537938 30 atime=1764935930.366686544 30 ctime=1764935920.659537938 rsyslog-8.2512.0/doc/source/configuration/global/0000775000175000017500000000000015114544360020354 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/global/PaxHeaders/options0000644000000000000000000000013215114544360022326 xustar0030 mtime=1764935920.693538458 30 atime=1764935930.488688412 30 ctime=1764935920.693538458 rsyslog-8.2512.0/doc/source/configuration/global/options/0000775000175000017500000000000015114544360022047 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsyslog_confgraph_complex.png0000644000000000000000000000013215055603742030375 xustar0030 mtime=1756825570.249068264 30 atime=1764929145.519822498 30 ctime=1764935920.690538413 rsyslog-8.2512.0/doc/source/configuration/global/options/rsyslog_confgraph_complex.png0000664000175000017500000042754415055603742030061 0ustar00rgerrger‰PNG  IHDRP—ómûbKGDÿÿÿ ½§“ pHYsHHFÉk> vpAgP XU°€IDATxÚìýw\÷þÿ?v—¥#UŠ(6°cÁ†½w±aÁ‚%±ÆÞMLb4‰-cbŒGÆbï½WPQ¬  "* ½·Ý¹þøó½rò9ç$ꪼîÿxËì2ïç¼goáÉÌìŒJù'„BQb¨ @!„ož‘¡!Ä3¿g~Ïü`¿Ñ~£ýFjjj ª‘ª‘ª‘€‚ÂÛ|œÒ[lA™­ÌVfƒEŠEŠE t×u\×qPubÕ‰U'‚ê¹ê¹ê¹¡Ã ñÿQÉ)!Ä›–=9{röd8ÔýP÷CÝá°ýaûÃöàvÀí€Û¨u¥Ö•ZW@å®rW¹™d’ièÔÿ‡F4¢èëëCL‡˜1 bJÄ”ˆ)Ðâ‹_´ø|³}³}³Áî˜Ý1»c†-J:)Bˆ×Ng¢3Ñ™ÀÕaW‡]Aß}ô=hÖjÖjÖ Aƒ ^#¼FxÍÍÍC§þ\pÁîëîëîë °]`»Àv0#aF è;¯ï¼¾ó µ}kûÖö`²Éd“É&C‡%!Ä«W—ºÔ…˜f1ÍbšA`ëÀÖ­áÉ“&ÐóÇž?öü:÷ïÜ¿s0ûÐìC³!eqÊâ”Åp1ùbòÅdȘ•1+c¨WªWªWòÖ P:(”`z×ô®é]hfÖ̬™”©]¦v™ÚPÔ½¨{Qw¸Pp¡àBlÓnÓnÓ‚Ý&»Mv›`È€!† €_ÕøªÆW úLõ™ê3Co•xßIB¼2YͲše5ƒ}“÷MÞ7N,>±øÄb¨;§îœºsÀïŠß¿+à²Üe¹Ër(š^4½h:œß~ÿùý°½þöúÛëƒæææ¸å¸å¸å¼üoå²rY¹lè­ü#UUUxžö<íy¤ú§ú§úC‡= ³®³®³Ìš/4_iåÒÊ¥•ƒ=c÷ŒÝ3Ο)>S Þ›¼7yo‚þ¾ý}ûûBéoJSúCox_IBüeEnEnEn21dbÈDØÚck­=À"À"À";vì unÔ¹Q稂TAª ¸×è^£{ Ð%Ð%Ð’þ‘ô¤@ß«}¯ö½ ­ú·êߪ?˜¤˜¤˜¤z+ÿ{Å{Š÷ïÐJ¡•B+ÁÖÎ[;oí êáêáêá0H=H=H ^ã¼Æyµ³ÚYí ¶<Úòh > |øž9=szæ½§÷žÞ{:´Éh“Ñ&ÌUæ*s•¡·R¼/¤!þkÊfe³²¢—F/^ åÊ”ƒ§6OmžÚ@oÓÞ¦½M¡½¦½¦½L×™®3]ÉaÉaÉa°Ój§ÕN+¸”{)÷R.´œÔrRËIàëçëçëvãìÆÙƒÜ/r¿Èý”yPæAÈ3Ê3Ê3Õ(Õ(Õ(CÏÂïæc—²KÙÆ?ÿhü#Tʪ”U) l.Û\¶¹ 9Ãs†ç ‡Ce•=T?tþÐy¨Y®f¹šå``ß}ö…r½Ëõ.׊sŠsŠsà’ú’ú’¶®Þºzëj°p·p·pÿŠþý+‚ç Ïž3@}\}\}Üг ÞUR„ÿQzÿôþéýaOõ=Õ÷T‡ÓV§­N[AãøÆñã¡ß'ý>é÷ 898989@¡}¡}¡=œúâÔ§¾€ÝwvßÙ\×»®w]C̆˜ 1ƒ*ÙU²«dƒrU¹ª\…°åaËÖÖá[†o)­SZ§´ë@ë@ë@P"”%Âг¨P¡ÕBÕBÕBÈZµ:k5×7®o\–Xj`)hººéꦫA»V»V»bbb hTШ Qp÷—»¿ÜýºÌè2£Ë èþA÷º–Û,·YnƒÌ#™G2À>Í>Í> œ¨|¢ò‰ÊàuÖë¬×YÐd@“MÀ¥†K —†žñ®‘ „øƒÂ…= {ÀE“‹&M`{æöÌí™`jj ƒž z2è ÔxPãAÀÎpÂï‡ß¿½{ö‚ŒmÛ2¶Aûþöýí¡ydóÈæ‘ =¬=¬= qÇ}÷1l­¼µòÖÊpÇìŽÙ3èäÜɹ“3ttêèÔÑ JÍ,5³ÔLP)‹”E†ž^€‘È;“w&ï \ìp±ÃŰ»öîÚ»kƒë×®#`pÚà´ÁiP¥s•ÎU:ƒî¶î¶î6ÜH¼‘x#¶tÙÒeK(6.6.6¿»~wýîB£'ž4zFmŒÚµÇ¾}ûBе kA×à¡î¡î¡zÔìQ³GMèЧCŸ}ÀbŒÅ‹1†ž$ñ¶“ „@Ñ):EQË¢–E-ƒ€À€À€@xÞýy÷çݡƒú‚¶ß´ý¦í7`¼Éx“ñ&Hì“Ø'±l7Þn¼Ý®Ö¿Zÿj}hÿCûÚÿ½2zeôÊë ë ë Èi’Ó$§ n{¸íá¶ppæÁ™gBõÀêÕaðóÁÏ?‡r_•ûªÜW†ž•¿.¹Mr›ä6°Ã{‡÷o111‡–m[¶mÙúô èv?Ùýd÷äõÏëŸ×Ž… 9ûÌö™í3÷8÷8÷8œ;8wp.T¨R¡J…* ;®;®;WG]uula [£›F7nÂà&ƒ› nõÆÖ,hºhºhºzVÄÛF €%XÊÜ”¹)sa×Ï»~Þõ3\8zá腣ТA‹-€ïVß­¾[Á¾¯}_û¾““'¾>ñõ‰¯ao½uöÖ ]*t©Ð6l •ÊT*S© èÑ£®/½¾ôúRèÐ%  ¨\T.*|lð±ÁÇ þ¶úÛêoÍ!Í!Í!CÏÊ«£ªª ÷ï;Þw„€Þ½z˵/Ö¾X ýû;öw„Ö¶þ°õ‡  ÐhàyìóØç±°íãmoûÂú†õ ë tttÐ3¹grÏd(5ºÔèR£!35353Ž4>ÒøHc8\|¸øp1xÖð¬áYÞxkà-puu5ô¬ˆ·…!JŸŸ8Wç\su`çí·wÞ§>N}œúÀàCƒ >ÕÎU;Wí(éJº’7»Ýìv³v ìØòªæUÍ« Æ ‡ÆFvœvœvµvר]cw (W»\írµaÈÕ!W‡\÷Ûî·Ýoƒþ{ý÷úï!¬eX˰–°:`uÀêðJðJðJ€ ùò'äËXÆ2CφxÓ4_ü“¡ƒ!^¿“åO–?Y*׬\³rMÔgPŸA} h\Ѹ¢q°¿óþÎû;ÃjV³°g;ÏvLº1鯤ÐB×B×BFéFéFéâââ ßýîèwG!±|bùÄò0:`tÀèè9µçÔžSÁº·uoëÞ†Þú·™ÖLk¦¯k^×¼®gˆgˆg_ ¾|v{ïöÞí ZµV­UC¥ó•ÎW:Õ÷TßS}4ñlâÙÄb2b2b2 °|`ùÀòá”á”áîÝ/º_„ŠC+­84·4·4· *-*-* ZÎj9«å,P›«ÍÕæ†ž ñ¦ÉÓ…(A4Õ5Õ5ÕÁx¡ñBã…À&0.^¼xñâEØztëÑ­GaÚøi㧇†ÕVoX4& <ªø¨â£Š49hrÐdxìöØí±ô íÚ3Úïh¿£ý0555ôÖ¾CV±ŠUàÀ§e?-ûiY¸ôüÒóKÏa[Ýmu·Õ…ó{Îï9¿4bШ•V+­VŒë<®ó¸ÎÐÚ¥µKkX~où½å÷@ÓAÓAÓ†2”¡€ö¦ö¦ö&m5Új´ÃÆð¯S ¢d‘ DI’DI ü ü üðrqVLVLV Ôq«ãVÇ ¼ã¼ã¼ã À¬À¬À ¶ßz|ëq86áØ„c Á„L€…çž[xœf9ÍršÌb³ ½‘ï¾ßÎå·¦5­zëë­¯·ö=Ø÷`ßø¦÷7½¿é mÚ6´…á©ÃS‡§BÍû5ï׼͌š53‚”A)ƒRýnÅ1ÄJœ§Ä/xÁ Co­0µ¡! ï·Çîªïªïªï¾\~gÖYwfÁÞ{îÓwMß5}L¨1¡Æ„à´Ëi—Ó.C§ÿY´i=üCýCýCáónŸwû¼œÙxf㙪 U…þþÁÎ8ã ªMªM*yÊ øR„ªà»‚ï ¾ÇŽ@au†Õêöêöêö¯~¼a/Â^„Atqtqt1(þŠ¿âoèYx{¨¨¨€{k÷Öî­¡^ûzí뵇Â*…U «:x×HBü¹V´¢ÿz¾= ¯ñ;CÁŸü)l´yÐæAPÔ·¨oQ_COèëêëêëB¾{¾{¾;/op`(7¸Á Pò•|%ßг#ÞUR„†WH!…Ðv[Ûmm·ÁDωž=ÁèÑ£ ë«ë«ë :‹ÎŠÚµ)jú²ú²ú²ÀyÎst_é¾Ò}ÅaÅaÅaPä\ä\ä ÅÅÅÅÅÅ/‡Ó××ÝGºtÞxã ú†ú†ú† ›¥›¥ûݵ —\zpélûzÛ×Û¾]œ.NÜæ6·A×C×C× ,<ú•ú•ú•†žT!þor Âàô+ô+ô+àtÆéŒÓpÚî´Ýi;Wi\¥q•`õðÕÃW<€‘…‘…‘ÄV‹­[ &L ˜î¸sà\Kº–t- ll°±ÁFˆÛ·)nøîöÝí»ŠÔEê"5üôóO?ÿô3Ì<2óÈÌ#1.c\Æ8X7jݨu£`ôíÑ·G߆ )R6¤@êG©¥~îÏÝŸ»?ënÖݬ»Ážö|´ç#0›f6Íl”ïT¾SùNÐ;§wNy…x›È!„Á©g«g«gƒÛI·“n'án™»eî–Rß—ú¾Ô÷R1¥bJE°µµµµµ???ˆ<y:ò4Üȼ‘y#¬o[ß¶¾ ™¥3Kg–†!‡<òÜκu; ÿ¸÷{ÿ¸.]:»t†Ç<þàñ}=ûzöupoáÞ½DOž=´ÿÐþCû(ëVÖ­¬Ô©]§vÚÐlJ³)ͦÀ¾zûêí«ñ·ãoÇ߆aµ‡ÕV<}<}<}€{Üãž¡gWˆO €â­¡IÔ$jA½L½L½ Ô±êXu,¨²TYª,0úÊè+£¯ÀRo©·Ôƒq3ãfÆÍ wYî²Üe ŽPG¨#Àh…Ñ £`êjêjê fffð¤Ã“O:@q|q|q<¨SÕ©êTP%©’TI >¤>¤>ª`U°*Ô¥Õ¥Õ¥AÝOÝOÝŒ-0Zð2o=Ïzžõ­Ú´jÓª ü°í‡m?lëëë˜å?Ë–?$x&x&xzR…ø÷¤!ÞÙÛ²·eoƒ‚ô‚ô‚tHë–Ö-­ä·Ëo—ßr»ävÉíEŠ:u‚‚Ç CîªÜU¹«@Y¦,S–A~ùüòùå!¾l|Ùø²ömØ·aßBƒ”) RÀÒÌÒÌÒ ´Í´Í´ÍàYýgõŸÕ‡ · · 7(šV4­hä×ɯ“_LT&*Äí‹Û·RN¦œL9 'žœxrâ YYYA{Óö¦íMÁøcã?†â§ÅO‹ŸzV…ø÷ä"@!„Á´-h[ÐÒ§N; ÍmšÛ4·È#Œüjͨ5£Ö °,oYÞ²<ÄùÆùÆùB u6ÔÙV&V&V&‘‘ ªU‚ ŽŒ;2îÈ8°«jWÕ®*t«Ú­j·ª`ínínícŠÇ)†èºÑu£ë‚&H¤ ‚6 Û,l³”1Êe tÏêžÕ= v5ÝÕtWS¸¼òòÊË+Áv¾í|Ûùp±èbÑÅ"Py©¼T^0½ÙôfÓ›A™‚2e =»Bü{R„grÚä´ÉièF7ºݶtÛÒmËË×{Ñ‹^¿ÿ–´¤%|>úóÑŸ~¹xÛm7¶Ý€ §*œªp †Ž:nè8ÐZk­µÖ·G·ÝztûÝW\q…nm»µíÖöï¯Mmjÿ›ü¿Ý.sÌ1ç__Kâm&§„î·sâ¯ù@;æ\Ý\Ý\x¶éÙ¦g› ëJÖ•¬+ðäô“ÓON:Ýkàƒ>r«_ñ÷È!ÄŸRg¨3Ôz2õdêIH¼˜x1ñâËkäÞ¿}[`ÄÚkG¬…ÁUW\l;Ûv¶í ô¦7ïÑãˆ3g,ÎX n=ºõè4 oÞ0ÜЩĻFŽ!PN+§•Ó@#Ñèåòê‹«/®¾<{6öl s§Î:w*J:”t( ò~Èû!<ì+óÛ_ÂöííÛÛ·7770000tº¿¯h|Ñø¢ñpÑõ¢ëEWøÄùçOœÁ®µ]k»ÖPײ®e]Ë—ïW7Q7Q7%T Uä±ÌâOHB`tÎèœÑ9¸oußê¾<òlȳ!`Óܦ¹Ms˜•0+aVøÿâÿ‹ÿ/pÀâ€Å‹—O¥»}÷öÝÛwA¿H¿H¿ÈÐ[óîS6(” ðèÞ£{îÁ"Õ"Õ"l8ºá膣Ð% K@—€—Ë]r]r]r!uNêœÔ9pÇåŽË0±1±1±ùýŠßîS9âÍ’ D ¢_¢_¢_úúú/—7û¼ÙçÍ>ÏIž“<'Á§‹?]üébØn·Ýn»ä7Ìo˜ßZ¶*lUKÛ.m»´-xnõÜê¹–]]vuÙUø!⇈" alÂØ„±†ÞÚwOzZzZzl²Ùd³É¾þ"ø‹`°Í´Í´Í„ESM]4|’}’}’AÝJÝJÝ Ž 8³ÊÎ*;«,X&Y&Y&OªOªOêËõ+U”*JP¦(S”)@6Ùdz«…¡¨”2t!Äë·ÎbÅ: 8Þáx‡ã`Ⴥ>£G=Ž‚îÝ7ºo ¬_X¿°~°¥ý–ö[Úƒî¡î¡î! j;¨í ¶Ð0½azÃtммм€èMÑ›¢7AБ #AGàQ³GÍ5ƒž7{ÞìyÚOi?¥ý°ð´ð´ãüKa\a\a\jq©Å¥°í̶3Û΀mÛ&¶M`PÄ ˆAP3§fNÍ „B "6"6"mmm!-#-#-úŸí¶ÿYh>¨ù æƒÀ¸¯q_ã¾ðÜë¹×s/XÑxEãÁ¦”M)›RðqÃ~ÜT}U}UoÁSÅ›%@ˆ$õJê•Ô+°µxkñÖb¸Üër¯Ë½ 5­i ôZÞky¯å`7Ôn¨ÝPÈ«–W-¯™wdÞ‘y°¿Ïþ>ûû€‡‘‡‘‡ é6¤ÛnP¾zùê嫃n‚n‚n\i|¥ñ•ư¥ü–ò[ʃö²ö²ö2 >døáPwXÝau‡¦£¦£¦£¡gå jG;ÚAT¥¨JQ• À<À<ÀâæÄ͉›}ö=Ú÷(´mÚ¶iÛ¦`RÕ¤ªIUHê’Ô%© lwÜî¸Ý®L¹2åÊh»»íî¶»¡wtïèÞÑ`hh9ù9ù9ùp$äHÈ‘8Øë`¯ƒ½ ZnµÜj¹àç箎®Ž®Ž†ža(R„(ôAú }Ü+u¯Ô½Rp*àTÀ)Hš24e(ôwéïÒßZílµ³ÕNЎ׎׎‡ç}ž÷yÞ¶žÛznë9¸©½©½©…Ï:<ëð z÷4îi VŠ•b¥@fÿÌþ™ýápåÕW†#;ì<²jש]§vðã7Æo ¸vpíàÚáïo×Û*µjjÕÔª°K½K½K çÇž{~,4_Ù|eó•àââNNN_%¿J~8ñʼn/N|{Gíµw¸ítÛ鶆,²pÈB¨S9¦r è;ë;ë;Ãõ×7^ßÓ¦Lîr—»0hì ±ƒÆBýŠõ+Ö¯FµŒjÕ2ô¬C“ „  IA“‚&pnƹçfÀÎ;;ììŽ+W8®€Á&ƒM›@µnÕºUë,g9Ëá–Å-‹[˜˜˜¹r7än¿ñ~ãýƃ÷ïÞ@{L{L{ žV{Zíi5Z´6h-Ükt¯Ñ½FÐíÃnvûºôíÒ·K_°ìmÙÛòþÚ^~~~~~>œßq~Çù°kÍ®5»Ö@饔ƒsçÎ…j«u¬Ö˜Ç<æÁ­ž·zÞê «W®‚\u®:W ~Q~Q~Qàíëíëí ÚMÚMÚMð´áÓ†OBÐÞ ½A{á^Á½‚{Ðmx·á݆C—y]æu™–í,ÛY¶3ô¬ˆ·!ĤÖI­“ZvUÚUiW%8owÞî¼4?Úühó£Ð×¶¯m_[°¿k×þ.ä×ͯ›_N|zâӟž&{šìiåï–¿[þ. 5dÔQP9¡rBåÐ{é½ô^p½úõê׫C@ã€ÆAùPùPùÏÓ|<ãÏ ½u¤4R)@ó¡æC͇Ðq]Çu×A½õõÖ×[êPu¨:¦?L˜ÁÁÁ÷CÜq?@ï*½«ô®mú´éÓ¦˜Í5›k6×Ð[%ÞwR„¯]VpVpV0ìß·ßþ}p<÷xîñ\¨S­Nµ:ÕÀ¯¾_}¿úPÆ»ŒwoC§}uRƒRƒRƒ`Ï{~ØóœÕœÕœÕ@“êMª7©ýõ?Ôÿ8Ä9Ä9¼Åßrï')Bˆ7çŸÏ±ý$úI4 <x ¢2¢2¢2 í…¶Ú^€·jܪq ˜Ît¦9äó7Æ- €P·W·W·šÑŒf Ÿ£Ÿ£ŸØ`ƒÍßXuªS”^J/¥<«û¬î³ºpÌì˜Ù13°oc߯¾ ‰?$ª_®~¹úeP}«úVõ­¡wŠ(©¤! F7V7V7BcBcBc`‡²CÙ¡@þÃü‡ùA® W…ÅSü×ÇQmVmVm†§fOÍžšAÑ‚¢E À½·{o÷Þ Ÿ¯Ÿ¯ÿß.PUPUPUÝÝÝ0jjÔÔ¨)tŸÚ}j÷©Ðʾ•}+{0™l2Ùd²¡g]ˆÿ!Ä[C÷L÷L÷ t: PDE€ ª¿¾^µƒÚAí>ØðÁ† uTê¨ÔQ0Ûj¶Õl+(r.r.rþÁõèѦ˜b šAšAšA ™®™®™Î¿ž ÄÛÄÈЄâ7šršršr Aƒæ5¬ßÈËÈËÈ Œ† 1ªÇªÇªÇ`Œ1Ưr Ãæðš4!þ"µ¡!Ä£  Ç;…¤!„%’!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!D‰¡š©š©š ”¢¥ FÃ’ „xïê u…:H\Ÿ¸>q=¼°xañÂÒï¥ßK¿YyYyYy²1ecÊFH“8&q äµËk—×ÎÐé…x3TÊ?:ˆB¼*wMïšÞ5¿î~ÝýºCF¥ŒJ• §QN£œF OÓ§éÓÀj–Õ,«Y`ee+mWÚ®´…FŒ:z+„x½ä#.„x︪\U®*(g^μœ9„þMø7|_dµ}kûÖö…Zk5®Õø†oøæUˆw‹œB¼wlólóló “k'×N®`ôØè±Ñã?û¾íû¶ï N*'•“ÊÐé…x3ä€â½Õ–¶´\º4tiÏxƳ߽nkk ²:duÈu5u5u5C§âÍ#Bˆ÷–Ç_x|555|½öîÚ»kúºúºzC§âÍ’ „xo™™˜™˜™@ë.Ö]¬A½Z½Z½T¦*S•)´ú±Õ­~çÎ5œk:­o–!Ä{¯‰{÷&îà1Éc’Ç$°ÚhµÑj#t=ÓõL×3†N'„aÈ5Bˆ7¦0®0®0n=½õôÖSH³N³N³Uš*M•¨Pñ /ÂSõUõUõ…Âã…Ç C©U¥V•ZŵŠkׂ¸Œ¸Œ¸ 8UæT™Se@¿S¿S¿ó5løINrLZ›´6i š7hÞ 9˜«ÍÕæòg˜0)Bˆ7&ø@ðà°tçÒKwBÍ{5ïÕ¼ššš@"‰$¾Ââ'~µ§ÚSí îÝ/º_„ì¢ì¢ì"¸5áÖ„[@ÿ‹þý/¼ü^à«b‹-¶ Ú¨Ú¨Úaéaéaé0ìÖ°[ÃnÁ ‰ƒ&šø&÷€/É€„¯]ÖŠ¬Y+`Nòœä9ÉÐIÕIÕI>·|nùܽJ¯Ò«€\rÉ}õã«n«n«nCš>MŸ¦‡LÿLÿL(ï^Þ½¼;({”=Êž×°áZ´hAõ™ê3ÕgÚ<´yhsøéÀO~:_úzÔ×£À5Þ5Þ5þuï!þ_R„¯Ý¶úÛêo«¡ñ¡ñ¡ñðåÚ/×~¹Ì|Ì|Ì| îÍÑÏÔÏÔÏ„¥ÉK“—&ƒiGÓŽ¦aJÄ”ˆ)À—|É—†N)J 9û$„xm⿈ÿ"þ 8b}Äúˆ5 ðà=À»äýâÿúõ7êo`€f€f€nøÝð»áwÝïºßu7t:QÒHB¼6»ï:¼ë0xÄzÄzÄ‚×~¯ý^û Êð*®¯¸¾âzhÕ¡U‡V ¨{P÷ îP¸±pcáFC§%…!Ä+1&bLĸ}=úz4ø­ñ[ã·4:N£3tº·G9=æô˜‰J¢’¨@0Á:”(1¤!^™â-Å[Š·ÀÖò[Ëo-ÍM››67…Êm+·­ÜÖÐéÞ>íÚ;´‡Þ {7ìÝvì(ØQ™Ó3§gN7t:ñ¾“ „xeBrBrBr ^¯×B =.ô¸`èTo¿¶ËÚ.k» Lê™Ô3©ÇN;u씡S‰÷!Äß–µ0kaÖBØæ¸Íq›#ôXßc}õàXѱ¢cEC§{û™ùšùšù³fÌàÈ¥#—Ž\‚„2 eÊ:x_IBümǦ›~l:Í5šk4Újw¨Ý!C§z÷4´mhÛÐ*i*i*i`ÇÒKw,Ô¨åÿÖâU“”â/Kx‘ð"áiq¤Å‘0à耣Ž‚…»…»…|­í¦.§.§.~^~^~^úIè'¡ŸÀ½û÷îß»oètâ}#@ñ¿{Ä#ÁžN{:íéå生S~4®Ý¸vãÚ†÷îsuu…æ™Í3›gÂÖè­Ñ[£¡¸iqÓ⦆N'ÞR„ÿ³ÈŸ"Šü .Ç\޹¿øÅÀ/@ªNU§:Ý{À , ÷²ÞËz/ƒØò±åcËÃå)—§\žbèpâ}!@ñ_+._\¾¸üË¿H½ïzßõ¾ ·=n{Ü6tº÷Oé‘¥G– >w|îøÜƒw Þ1rkçÖΕ#-âo’ „ø¯]=põÀÕðÄø‰ñcèãÛÇ·¯¡S½ÿ:tëЭC7PÍTÍTÍ„£7ŽÞ8zÃЩĻN €â?Êyó çl»}ìö±Ð=¢{D÷p q q 1tºW§(ª(ª( 2¿Ìü2óKPZ)­”V†NÐÿJÿ+ý¯À¢EŠ É+É+ÉËÐéÄ»J €â?:yñäÅ“Aï¬wÖ;C§…vZhèT¯Þ~wúÝé_ø|áó…¤·Jo•þ€ß4œÕpVÃYP~PùAåÁî‘»GîièTâ]%@ñ§^¤¾H}‘ çœp>ô›Ûon¿¹`ÑÝ¢»EwC§{õܸ/p_cöÙ7fXeYeYe:ÕKÚNÚNÚN0°ÖÀZkAHnHnH.D}õMÔ7†N'Þ5F† „x{íé»§ïž¾PƸŒqchr¾Éù&çúÔ§þëW—®Kץá‡:Z>hù %TN­œZ9¢NFŒ: n*7•› LãMãMãáÑ7¾yô t\ÐqAÇà9ßs¾ç|x¸àႇ àä‘“GN}”>Jå”oP¾tÊî”Ý)ï{¼ïñ>8yòäÉ“'¡‡S§Np¾êùªç«‚2X¬ k¬±âcâcâc ¿_¿þ~àÒÑ¥£KÇ׿_ªzWõ®ê ¯4¾Òø lËÞ–½-涘Ûbn P_P_PË-˜Å G„ððÙÃgŸÁÅЋ¡CÁ¯À¯À¯Œ¦M5šúúÇרhl46~$ýHú‰ ‰ ‰ƒÆWh\ŠW¯.^ G¶Ùrd xû{û{ûCQó¢æEÍaCƆŒ /×—u"ëDÖ ¨v Új Qq£âFŰfÑšEkÁc£ÇF ô†ÒJo€ƒ.]º@ö¦ìMÙ›àÁƒ<€‡þýúC‹ -.´¸·gÞžy{&ì»»ïî¾»opu¥+]¡÷„ÞzO€Ç¾}ûBhHhHè{tM†x½¤!þEo£·ÑÛÀ¶Äm‰Û¡á ?høT^ýyõço>i5Ój¦ÕÀt¿é~Óýàbëbëb îöîöîö ›¤›¤›Îõœë9×ƒŠ³+ή8^Œx1âÅ(ÞS¼§xTJ«”V) >søÌá3(Ø\°¹`3dÎÉœ“9²‡gÏ3-fZÌ###0l4Øh0˜L4™h2Ì{š÷4ï Î'œO8ŸçcÎÇœAÒá¤ÃI‡ßüü¸”v)íRº:uuêêAÓƒ¦M‡\×\×\×7ŸG¼[¤!þåÚ¶kÛ®mƒ‡ÕVXúzöõìë RH¡)((@4ÑDÿn¹ *Àlþ¸\µTµTµ 6l,Ø+-WZ®´„í·:Ü žn|ºñéF(jTÔ¨¨¨>U}ªúУGÿorSL1K,±¿[þÏöЂ´0ÀüüS§ÅwZ ÅÅÅp2ðdàÉ@Ãåï)BòÏåŸË?ÛömÛ·mtV:+pé2ÒÅ€W™ëÓôiú4Ð5Ö5Ö5ý3ý3ý3ÐÇéãôq k¢k¢kŠ•b¥Xýnùºu?BÎÚœµ9ká|íóµÏ×ï™Þ3½gB—Ó]Nw9 f­ÍZ›µ†âàâàâ`ЫÿVÿ-èÓõéút(ÖkŠ5 ?¯?¯?:{½Îþwù¬ôVz+Ðyè‚Ù}f÷™Ý†,²xÈbh}²õÉÖ' l3˜EcŠÆjPƒ ¾®¾®¾ú|}¾>ŸzW_S_S_}–>KŸ bƒÀ(Ù(Ù(¨Le*CaÂ:…u@µLµLµ TZ•V¥uOuOuOPf(3” ¯«¯«¯ 8á„I$‘ º©º©º š'š'š' ;§;§;Le*SÁ¨•Q+£V ²TYª, 7}‡#G†%O–/óy™ÏË@åž•{VîiÀý*Þ*R„(Á6žÚxjã)xð݃ï|óÍ[4o˜Ô2©eRËÐéÄ_N8áðýåï/²_d¿È~³Sf§ÌNÍ7šo4r߀ONQEoŒÞ½Î8àütwÐÝAwåÿ{£&5© ¾¾¾ðpÉÃ%—@Øa„}`èpâm!@ˆè\ÿsýÏõ‡ *@õîÕ»WïìWÒ¹ötíéÚ* ©4¤ÒØÛdo“½M J¼-¤Qyžó<çy’û$÷Iî   †N%^µÌ&™M2›@l™Ø2±eÀ[ñV¼å„¯ø')B”@^6^6^6PÕ¹ªsUgرvÇÚkAùXùXùØÐéÄ«rD}D}D ó,æỸöMÛ7mßÔЩÄÛBž D ¤nªnªn æ ˜3`|¾ùóÍŸo†ð‚ð‚ð¨E-äR€wW|™ø2ñeà襣—Ž^‚L>2ùÈÌʘ•1+cètâm!G„(Á*.®¸¸âbhMkZ[£¶Fm‚¢ÉE“‹& Ð<æ1ŠcŠcŠc H)RŠзззå‘òHyúŠúŠúŠ ôWú+ýø€@§Óét:P|_ÅÈ"‹ß=ÍOwCwCwŠë×-® t§;ݺԥ.è u…ºBPî(w”; ¤)iJè’uɺdP®*W•«¿Ë{‚œ€âüâüâ|(Ž(Ž(Žnr“›˜¿žô¤'ì꾫û®îà±Ðc¡ÇB¨]?º~ôß_½x¿h¾ø'CBNùg埕ûÝÿëþ_Áæ[›om¾… ,*X¼þñõëôëôëàXü±øcñ°'aOžˆ54j(ü:ñ׉¿NãAƃŒÁÉïN~wò;8Þõx×ã]¡žªžªž Ö®/\_§ZŸj}ª54ÖlX³apÏúžõ=kؼoó¾Íû $3$3$žL|2ñÉDpNtNtN„Åî‹Ý»ÃócÏ=?å*”«P®|­úZõµ Æ%ŒKµ‡×^{8œ{rîɹ'°«Ç®»z@ð÷Áß¹Cs‡æ…J[*m©´TMUMUoàÐ{Dˆ=`Ç£v<‚¦~4õ£©`_þ†}×?¾x·È!ö-í[Ú·„ž'zžèyví0ÚaÙ£²Gezýãßó¾ç}ÏÖkÖkÖk û³îϺ?ÿfþÍü›AâñÄã‰Ç!õTê©ÔS`û¥í—¶_Bx¿ð~áýÀòSËO-?»™v3ífB¸Y¸Y¸äŽÈ‘;~´þÑúGkp›ë6×m. »:ìê°«°çÙžg{žAܽ¸{q÷@ÕNÕNÕyxäá°s·s·sÅ]qWÜ!ºOtŸè>8!qBâø©×O½~êí~n÷s»Ÿ¡ýÎö;Ûï„TþGåT†¤˜¤˜¤˜×?…ممÙÔ5¨kPWhîÑÜ£¹¸;»;»;¿þñÅ»I €â_Úµ5jk&ÓL¦™Lƒ#wŽÜ9òn%ûÀãÇ0*kTÖ¨,¸ÏvŸí>L²M²M²AóLóLó ÔÔÔ@ÓJÓJÓ T«U«U«RHÍÍÍPG©£ÔQ?1bþDˆØ±/b$,MXš°®}{íÛkßBÖY_d}i™i™i™`ÔΨQ;PPPx™Oc­±ÖXƒæœæœæ¼øâÅ/¾€ÇæÍ›Ãá‡> ‘Ý#»Gv‡Ô¥©KS—BN™œ29oàœû•ÙWf_™ ñÃã‡Ç‡^ù½ò{å¿þqÅ»M.Bü‹Y®Y®Y. x2àÉ€'°fÞšykæAsçæÎÍÁ%Á%Á%áÕ«úDõ‰êPÊ)å”rÀe.s™—OýûÃüs¹^xý›å®¸â ô =À¨³Qg£Î`3ÄfˆÍpÕ¸j\5°`Ò‚I &A–5ZÖh §5§5§5`dmdmdý»õjÑ¢¬°Â TTT@ûLûLû lîÚܵ¹ ŽŽްlÁ²Ë@™Ae•ôúöWööìíÙÛaGÁŽ‚ÐsQÏE=Aé¨ÒQ¥£^߸âý G„Pߨ¾Q}#¨4­Ò´JÓ`×®]»víz}ãyTõ¨êQŠ»w-î a…a…a…ªMÕ¦j¡hTѨ¢QÀö°,V[¬¶X Yg²Îd¤¯“¾Núò&æMÌ›…³ gÎíTíTíT¨ST§¨NäææBy¥¼R^š¹5skæ‚e+ËV–­ÀÒßÒßÒ^l}±õÅVȶ˶˶ƒüGùòA^¿¼~yý t¯Ò½J÷‚Šùó+惮‡®‡®TÞTySåMPcTQ5Fé*ÓU¦«^ß¼;xìృ Ù®Ù®Ù¦v˜ÚaêëO¼_ä"@!ĨK©K©Kk× ® È1È1ȪW® -Z:´|uã9ôrèåÐ àúæë›¯o~ù8Û””ð:àuÀë´ØÞb{‹í1(cPÆ H0N0N0ÅB±P,ÀêœÕ9«sPG©£ÔQÀ«‰W¯&9,rXä0¸ïrßå¾ËËŸw)v)v)×T×T×Tˆû>îû¸ï!½gzÏôž@ºÐ*:Tt¨ œ87p†jí«µ¯ÖÂòÂòÂòà±Õc«ÇVPh]h]h .V.V.V ñÖxk¼_Ý|%^I¼’x~òýÉ÷'_útèÓ¡O¡â¢Š‹*.zÃñÎ’‡ !þ£µ³ÖÎZ; â·Åo‹ßŸ%|–ðYh 4š‚×8°3Î8ÃàòƒË.>Ù>Ù>ÙàîînèY1€¬`¬îµº×ê^¼1ycòF˜»h‹@S¤)Ò:¤xWÈ)!ÄÔ«C¯½:@¬M¬M¬ \¶½l{Ùöõû¤å“–OZBVBVBV¼¨÷¢Þ‹z 7Ó›éÍ =+o^äØÈ±‘c!$"$"$ü¢ü¢ü¢ä¿øk¤!þ#ÇŽ;@÷;Ýït¿[c·Æn…ìMÙ›²7½Æq×9®s\?Õú©ÖOµ`ðÕÁW_Õ:Õ:Õ:CÏÊ›£KÔ%êaÛØmc·…&štjÒ ª¸Vq­âjètâ]%§„ÿµì Ù²/À'µ?©ýImhÝ:»u6ôqíãÚG~½6!Æ!Æ!ư>|}øúpXÔkQ¯E½À1Ü1ܱ$ž ¯„Bü×,[X¶°l~'üNø€CŸúôЧØ/±_b?C§{ÿäæææææÂ¶ÆÛok ÝÚtkÓ­ü⯆!Äÿ¬ñ׿nü5¸Å¸Å¸ÅÀÞø½ñ{ã êýsâ鉧'ž‚n…n…ntØÜas‡Í†N%ÞR„ÿ3Í Í Í ð‹ô‹ô‹„à Á‚'ÀƒVZ=heètᄂI’Àþãûï?ýK÷/Ý¿4Xµ±jcÕÆÐéÄûB €â/«_5¾j<4þ¼ñç?‡ Û Û [(X<°x ¡Ó½»ö}³ï›}߀k€k€kx¯ò^åýo($J&)Bˆ¿­O~Ÿü>ùð¸ÁãÀµö×Ú_koèTïžGíµ{Ô.ú]ô»è~_ú}é÷%h¿Ñ~£ýÆÐéÄûF €âos~æüÌùt íÚ-¶ÏÝ>wû\Èž;Ê„È_"‰ü"ÊD”‰(EÖEÖEÖ/.cþÆü¹>r}äz¸w;ïvÄëãõñzPr•\%÷ÏÇÍõÎõÎõ†¨Q;¢v@⇉&~9s&æLÛ{¶÷lïAóÇÍ7 Fß}gôX.´\h¹´çµçµç¡èdÑÉ¢“àààë=Ö{¬÷€ûû{PÒ•t%ú%ôKè·ëÜ®s»D'F'F'‚îKÝ—º/!öYì³ØgÙ ²AdxRæI™'e Þ*Þ*Þ XÊR–zo‰×ÍÈЄâMь֌֌†ufëÌÖ™½,GvÙq$lŠÞ½)†Z µj,:Yt²€7vÞØò¯ç_Ï¿ÎcœÇ8kß^ûöÚ·0tÇÐCw@‹u.Ö¹øÇq³ïdßɾ¹¹¹€1ÆCÂü„ù ó¡8ª8ª8 fŽ™9fæøáÑ~x妗›^n:I$‘PT©¨RQ%¸q9âr–),SX’¿Kþ.ù;È8˜q0ã ¬;¸î຃P«C­µ:ÀÍR7KÝ,}–÷YÞg9¤þšúk꯰|éò¥Ë— ƒF V'¬NX€×^x 4hÐz§‰×F €¢ÄPõVõVõ«ÎUç ¥}Jû”ö.Å]Š»Ã…M6]Ø7_Ü|qóT?TýPõCpäÊ‘+G®ÀÊ++¯¬¼uuuðäö“ÛOnÃŽQ;Fíu¨C3®cŽcŽcT¸\ár…Ë`>Î|œù8¨W¿^ýzõ!¥FJ” 5ÖkA¿H¿H¿pÄG  hÖ_Ziý%”=[ölÙ³`V`V`Vµ>«õY­Ïà»§ß=ýî)P‹ZÔ‚áû‡ï¾–™,3Yf‡*ªp¨ô?ÓÿLÿ3`œkœkœ =Œzõ0ëkÖ׬¯z¨z¨z¨¡÷–xÝ䀢äУGd‘E@/_V¿P¿P¿}}}}}}Èþ<ûóìÏ¡ ¤ ¤ ̃̓̓_¾ß^m¯¶WC"‰$þ7ãGM4(m•¶JÛóúorÿÙŸÞ*T¨€§<å)(þŠ¿âÿòåDûDûD{ˆ58j0l¨º¡ê†ªðb‹ /&€KKK0‹YÌ#Œ0Lõ¦zS=XN°œ`9T¥T¥T¥ ½³Äë&@QrhÑ¢ÊQŽrÀv°ãw¯»ãŽ;PƒÔ‹\‹\‹\ÐŽÐŽÐŽ€ü&ùMò›¼|{z—ô.é]ÀAå rPýãW¤"AuBuBuâwË ( ˜Ît¦ƒj„j„j/‹Ê$&1 Æ0†;ÙÉNP†(C”!/WcçoçoçUW\e0ø÷?î>]øtáS˜â5ÅkŠè§é§é§jªjªj*à†Þ9âM“ „(1”ÊFe#p—»Ü…¤ ¤ ¤ Hœ>8}0$vJì”Ø ’>Jú(é#°ÿÚþkû¯¡íçm?oû9ì²oȾ!°÷—½¿ìýbÆ>Œ}}êô©Ó§ÎŸ›5.k\Ö8x>äùçCàéæ§›Ÿn†¤åIË“–Ãã”Ç)S c]ƺŒuð°æÃškÂÃ*«<¬þþþðä“'Ÿ<ùœÎ:u: 7«Ý¬v³„……AûYígµŸ9Ýrºåtƒ]UwUÝU‚›7 nI{’ö$í8ã8ã8cH›’6%m ÄæÆæÆæþws(Þ*åŸ D!^·‹6.Ú¸®$]Iº’ãW_=~5¸9¹9¹9Áƒ´iÒ@3P3P3jzÖô¬é E¾E¾E¾µ.j]Ô:(ø¨à£‚À)Õ)Õ)*̯0¿Â|PmQmQmùã¸Ù‹³g/†ðkáׯñ¯¯#z8{8{8C¶]¶]¶ÄŒ3œ>púÀé066†§žvzÚ Êx•ñ*ã6ŸÚ|jó)D4‰hÑ ê媗«^†§öOíŸÚÃóºÏë>¯ æ£ÍG›†r?—û¹ÜÏžžžžž±»cwÇî÷_ÝuÿÊ|Sæ›2ßz/‰7E €¢ÄذzÃê «!uYê²Ôe0#zFôŒhC§Â0䀢ä(¢ˆ"@AAþì%œ!„¢’ „B”@R„BˆH €BQIB!J )B!D $@Qr´ -L01t! K €â½£©© Ù+³Wf¯„ÜÄÜÄÜD(˜]0»`6|UðUÁWPð¤àIÁÈÊËÊËʃ¢iEÓŠ¦:½o†<XñÞyxãá‡7`æ™Cf]Œ.F±mcÛÆ¶…¢E‹ÂeÍeÍe ¨««ÃÌF3ÍlÍiNsCo„¯™!Ä{ÇZ±V¬H^¼:y5„ìÙ²ãï»W|¯ø^1¸åþ•ûWà\ŹŠsÀ?ü ½B¼^r @ñÞqssƒNQ¢:Eg9ËÙ? m m -T0©`RA® %„!Ä{«Ý¶vÛÚmÇ\Ç\Çó¸[ãŸ6þº´èÒ¢K 0Zn´Üh¹¡S ñfÈ)!Ä{«NÝ:uëÔ…Úŵ‹kÃINròw¯W«W=¤5Hkfè´B¼Yr@ñ޲ʳʳʃ®C»í:ô¯7ù¤É'M> öì+Ø:­o–B¼÷Zjq¨Å!(»¹ìæ²›!uqêâÔÅàcâcâcªbU±ªØÐ)…x³¤!^»¤RI¥’JÁóÎÏ;?ï Üä&7l°yï`; ¨TQ©¢RàòƒË.?€º¬º¬º,¨Ôê¸ýøöãÛA  P¼Æh¯k¯k¯ƒå$ËI–“@­ŒVF¿Æ…RêuŽ:,_X¾°|êêêppÅÁW8ÀPâ”8%îõÅQ­V­V­†œ97rn@ŽkŽkŽ+Ly8åᔇÐ4¤iHÓ  MhòçE@¥ü“¡ƒ!Þ·¯Þ¾zû*|ÛÿÛþßö‡vOÚ=i÷|.ú\ô¹F£ŒFe·²[Ùýúó¨ÜTn*7xÞôyÓçM!Õ.Õ.Õj®5ºÖhÐ×Ó×Ó×^ãÿ U5T5T5@ÿµþký×p)øRð¥`¸p)àŒl7²ÝÈvÐfG›mvüýñ„ø¿HBü}ç8Ç9¸v÷ÚÝkwáûŠßWü¾"ôÜÜssÏÍЧEŸ}Z€ê#ÕGª ˜ó)Oy <ä!¶´¥­ó¨P¡‚óåÏ—?_Ö–Z[jm)ð7õ7õ7…NW;]ítÕ€ùÄ{M €âo îÜ7¸/ühú£é¦àgægæg>Û}¶ûl2È ÃÐ)ß~—c/Ç^Ž…nÿpû‡Û0Àq€ãGðiãÓÆ§ ¨²TYª,C§ï ¹@ñ—‰?&~ø9àçš24eh tÜÙqgÇÀ:Ö±ÎÐ)ßÞe½Ëz—­…ÖBk+.¯¸¼â2~QøEáÐǺukPg¨3ÔR¨Äß$G„ÿ5ÅD1QLàXè±Ðc¡˜˜˜®ûp݇ë õúÖë[¯7tÊ÷LJwÞyË;,ï°¼t¸×á^‡{àçàçàçšlM¶&ÛÐ)Å»J €â?RF(#”°Ÿýìv$íHÚ‘ã“Æ'O‚&¡MB›„:åû+²Md›È6°$cIÆ’ h~´ùÑæGÁ–ÿ,ÿY ýEû‹öC§ï¹ âO)s•¹Ê\ØytçÑGa·õnëÝÖ0µÞÔzSëA“ÝMv7yWñ—tUÏT=Sõ |2ç“9ŸÌU!«BVÁÏ·¾ýóm(˜X0±`¢¡SŠwBüAñòâåÅË!(*(*( ÎdŸÉ>“ SO=<õ0x¦y¦yʽó æIä“È'‘°$rIä’H¨ª®ª®ª†ÑcG=ÌbÍbÍb R¼í¤!þ¥èQÑ£¢G°)gSΦÞ¼'xÌšï{ø±ò•¬ á«ÂW…¯‚¹óçΟ;ÿ¯ÿâ/W<®x<Ýýt÷ÓÝpcÍ57Ö@ø’ð%áK b]ĺˆupwÔÝQwGÁ‹/^¼xaèÙxV±ŠU®Mצk!<,<,< Ò'¥OJŸô×Wë¬rV9«àã~÷û¸ä̘?–¦-M[šisÓæ¦Í5ôÆ‹·!J \Ç\Ç\Gø¾ô÷¥¿/ Ñ£G?†¹“çNž;ܼݼݼÿúúõçõçõçáªùUó«æ0:xtðè`U…ªBUðhÊ£)¦À‰èÑ'¢á”ë)×S®†ž•7`›ØiÓ.¦]„Ù³gÂÙÃgŸ=ü÷WoŸoŸoŸ³gÍž5{hnhnhnÀ o,¼ÉÍ’›%Ë)ñOR„(A²Ü²Ü²ÜàÛ*ßVù¶ $5Ij’Ô>ùùÈÏGB™Æe—iü÷Ç177‡*õ«Ô¯RljÛÔ¶© ëw®ß¹>øäøäøä€_Ž_Ž_T¶¬lYÙòåÏ+ã”qÊ8(Î(Î(Î}/}/}/ <ò@IQR”P|ŨG=ê>Z­}¨>T ú}Œ>”Ê@e ¼#¡:PV(+” _¦_¦_Æ¿nÑ«D+ÑJ4GGG‚~Œ~Œ~ÌïrNR&)“@9¡œPN€rE¹¢\¥¦RS© P@°žõ¬Ý*Ý*Ý*(w³ÜÍr7Ár…å ËP<¤xHñW·ŸKå”Ê)•ÓÇN;},Ø.µ]j»¾Îû:ïëÏ|ÅÝ‹»w‡Äs‰çÏÁ”ƒSN9Q_E}õ˜¿0aþJ,=²ôHpâ2Äe”ëV®[¹n0¶ÁØc€³£³£³#üªÿUÿ«œsssáÖœ[snÍ›"›"›"hü}ãï÷•ûÊ}Öu\×q]Gè–Þ-½[: 1xÄàà¼ÁyƒóÐ7Ó7Ó¿ÆCóæÌ7˜o€ k&¬™°ª¬¬²²ÊJø2åË”/S zwôîh¹ŸC‰#@ˆ÷QCÒ~Iþ%ù—dx|éñ¥Ç—`ZËi-§µëÅÖ‹­¿s™Ë\(uºÔéR§¡©OSŸ¦>ÐxQãEŧŸZ|úòí7moÚÞ´…JC* ©4LÏšž5= Õ/T¿Pý$I8’pÒ¾Iû&í0¹drÉä”ý®ìwe¿ƒšík¶¯ÙjN¬9±æDð®ç]Ï»\˜taÒ…IðÐë¡×C/ÈHÉHÉHS™§2OeÂcïÇÞ½¡®¦®¦®4Ã4Ã4ÃÀNg§³ÓÁeíeíe-<;ÿìü³óýUöWÙ_ú;õwêïÀl¶Ùl³ÙP±cÅŽ;BÍñ5Ç×Ï:=ëô¬hii‡ƒ‡ƒ‡˜55kjÖ4 5 5 ÛÜæöëß&[M¶šl…Ñv£íFÛ®¢®¢®",½`ô‚Ñ/¿ "J)B¼B %Ú›µ7kofÍ*šU„£ŽN8:t5t5t5^ å´rZ9 &çLΙœssshP®A¹å _¿6~/߯٥٥ÙzK½¥þw×èƒôAú `³˜ªªª/·S9¬VþÍEt­Û´nÓº Ü©}§öÚììì c§Œ2v \hv¡Ù…fðÐæ¡ÍC¨~¥ú•êWàòÎË;/ï„o3ø›Á`ô£ýÌ1ÇÀ /¼+¬°%X V‚A S”°ßèK_ú‚ªªªàŽ;‚Xb‰%à„Noàs±›Ý솋K/.½¸²wdïÈÞ~‡üùmUmUmÕ7C¼ä!Þcõ¶×Û^o;̰a;Ö&-MZšù=ò{ä÷€!K†,²ŒfÍ6šýêÇÏ Ë Ë ƒUª@™+3Wf®§ÙN³fƒÝ5»kv×^¾ß;Ð;Ð;¢,£,£,!9 9 9®ï¼¾óúN¨T®R¹JåÀ6Ö6Ö6 ®\+¸¹þ¹þ¹þ¿ÖÚZkk­£ÆQãd‘EtîÖ¹[çn°±ÛÆn»Å]‹»wÁt·énÓݨJT%ª sjæÔÌ©à9Às€çxPöAÙe!Ü#Ü#Ürä,ÈYE­ŠZµ‚5úÔè£ÜG¹rÓV¦­L[:¥ø«tÞ:o7ì|ºóéΧphÌ¡1‡ÆÀ´ÃÓO; u¯Ô½R÷Š¡S C“k„(*<ªð¨Â#˜ûáÜç~÷?½ÿéýOaUýUõWÕ‡¼áyÃó†:¥ø_·/n_ÜŸ> |G;ít´ÌIž“<'Y~ñ‹ÿ—BèŸèŸè‹#G.ŽǾŽ}ûÂDÕDÕDXδœi9ÓÐ)ÅŸ)ì[Ø·°/üÒè—F¿4‚ÐÌÐÌÐL˜1rÆÈ#¡j…ªªV0tJñ¶‘ „ø—äŒäŒä Xú`郥Àâ‹O,>Én“Ý&»Íz›õ6ë Rü&¿S~§üN°®ñºÆëCDZDZDÌt˜é0Ó*Í«4¯Òí<|SüMñ7Å úQõ£êG˜n3Ýfº Øýl÷³ÝφNYråÆäÆäÆÀç<ÿãyx¶èÙ¢g‹`vöììÙÙàúÌõ™ë3C§o;)Bˆ?•96slæXø.÷»Üïr!;";";f|<ãャ¯£¯£¯¡S–ÙÙÙ°rÖÊY+gAJLJLJ ÌL™:3\œ\œ\ÞÄýÄ{A €â?ÊNÎNÎN†UšUšUHXš°4a)Ì\2sÉÌ%àªwÕ»ê òý•q1ãbÆEø6üÛðoáàFÁ‚0éLJ¯)½¦ôC§ïù€â?²t°t°t€É¡“C'‡Bùúåë—¯_g~ùu&<­ð´ÂÓ †NùþI=Ÿz>õ<,*»¨ì¢² ·ÕÛêmaŽóç9Îò‹_ü=r@ñ?+h_о =lðÜà¹ÁnÞ¼yóæM˜í:Ûu¶+T ¨P)ÀÐ)ß]Iw’î$Ý%éKÒ—¤ƒÍ¯6¿Úü “GN9y$”j\ªq©WðØfQ²IBüe… €%@ Pàb…‹.V€™a3Ãf†AõáÕ‡Wnè”ïŽç#Ÿ|>–œ^rzÉipqwqwq‡ ê ê j°8jqÔ⨡SŠ÷…!ÄßV|ªøTñ)ØvnÛ¹mçàø•ãWŽ_^3¼fxç"ÏEž‹ òíõÛUü‹ª.ªº¨*xœö8íqÆùŒóç¦L;™v2tJñ¾‘ „xeôõõaw·ÝÝvwƒýßîÿvÿ·0¥þ”úSêƒ×N¯^; òíñhÍ£5ÖÀ’fKš-iu‚ë× †‘åF–YLºšt5éjè”â}%@ñÊ)M”&J8èrÐå  lÌߘ¿1êÇÔ©VŸX}bõ (­•ÖJë7(—\rA¬V¾øâ ú(}”>Š7ö8^ÕϪŸU?CNÙœ²9eáöšÛkn¯ö~íýÚûÁPŸ¡>C}@[E[E[å Ì‹(Ѥ!^¥…ÒBi!î!î!îóòÆBhРyý9ÔžjOµ'\¾|9rŸä>É}íRÛ¥¶K]K]K]Ë70!e)KYÐ7Ñ7Ñ7ò!åCʇ@Ûkm¯µ½F­ŒZÉC˜Ä"@Qbl,ÚX´±Rz§ôNé 3Î88ã ¡S ar!D‰¡¬VV+«p 7t! K €BQIB!J )B!D $@!„(¤!„%!„¢’ „B”@R„BˆH €BQIB!J )B!D $@!„(¤!„%!„xCô}õ}õ}áæ²›Ën.ƒK+/­¼´tYº,]0–±Œ‚ &”J¥(ÁJ° Üâ· ½â}!@!ÞÜÜ\صx×â]‹!ºvtíèÚpóÓ›ŸÞü–|°äƒ%@Zë´Öi­!øjðÕà«0©Â¤ “*Àã!‡<bè­ï )Bˆ’Cƒ  B…êÍ¡ö…ÚjƒéBÓ…¦ aàÔSNç;Îwœï@žuzÖé æµÌk™×‚Ê÷*ß«|Â3Â3Â3 Ó6Ó6ÓSSS!¬IX“°&†žTñ®22t!„xSÔ3Ô3Ô3àVï[½oõ† iÒ.¤;ÙÉNÈË˃f­šµjÖ ,ÛX¶±léÆéÆéÆpËö–í-[ȋɋɋ×®\@Íû5ï×¼ê(u”:ê㦤¦¤¦¤BÄâˆÅ‹A=Q=Q=Ø>°}` &eLʘ”UgUgUgÈwÉwÉw­³ÖYë šGšGšGë–ë–ëÿ8ñÿ8ÏÛ>oû¼-L91åÄ”à‘à‘à‘÷ŠîÝ+‚§ÇŸzl>°ùÀ樿³þÎú;!rjäÔÈ©x<ñxâq°ùÞæ{›ïÁä¡ÉC“‡àéêéêé ÄO¼¡÷šx]䀢ÄÐh 4°ãÆŽ;nÀ¾ü}ùûòÁ|´ùhóÑðk̯1¿ÆÀÁõ×\ù;ówæï„•+#VFÀ#»GvìÀtŒéÓ1°6hmÐÚ 8wëÜ­sÿǹyíííÐj µ…`ÜÀ¸q0ícÚÇ´äyåyåyÁ×s¿žûõ\ˆ111M5M5M5à Oxš¾š¾š¾ð|ÁóÏ€ÞIï¤wó æÌ/Àõ%×—\_«¬n°ºhr5¹š\خڮڮ‚ÓO><â–Å-‹[s3æfÌÍ€ˆ9s"æÀï~õð+ÐM×M×M7ôÞ¯›!DÉQ‰JTqÄì~°ûÁÔWê+P±uÅÖ[Ãá‡> Ïæ?›ÿl>\±¿bÅ:.ãbhýkë_[ÿ •kU®U¹¼zðêÁ«>l©Ã¥—: N¡N¡N¡àö¥Û—n_Bʼn'VœÎë×;¯“Ú&µMjÖXc ä“O>0•©L‹‹‹°o?Þ~<¸e»e»eC¹å”[§Êž*{ª,GGGBó:Íë4¯NþNþNþp6ôlèÙP(=ªô¨Ò£ÀúºõuëëÐåA—]€Ï8Ÿq>ã@“¬IÖ$zg‰×M €¢äУGd‘EpˆCúÝë™d’ xàä·ÏoŸßt³t³t³@k£µÑÚ¼|»Å0‹aà 볬ϲ>û/Æÿç_òJO¥§Òó/äÿíÚ…tÒI $ðwñã3ã3ãáq…ÇW€§vœÚq hE+ZAãqÇ5ô¡}@5Z5Z5Ô+Ô+Ô+ÀÈÁÈÁÈXÄ"zg‰×M®B”¿]h‚ &@YÊRöw¯›bŠ)ЈF4kkk0»mvÛì6¤?Nœþœp xîûÜ÷¹/¸9¸9¸9üã›a†PzÔûÝòߊ‰ .¸¥)Mi@‡ÿ:bñ¯?çs>‡¢šE5‹j¾\M™ü2ùeò!ß4ß4ßü¯ú_õ¿ ê`u°:øåûB¯†^ ½ú»<æ˜cnè#Þ4)BˆCi®4Wšƒ©ÞToª‡äíÉÛ“·C¢*Q•¨‚ó^Ì{1ÌrÌrÌrÀz¾õ|ëùЯ _A¿ØóÉžOö|öÉöÉöÉPQQÃO ?1üÄŸ›œœ Ï[=oõ¼hëkëkëÃSç§ÎOáI§'žt‚|×|×|W¿~?ü>dÌ̘™1 îÜ-¸ QÞQÞQÞP%³Jf•LØûpïýáH#5ŽÔ€®Í»6ïÚÖ\[smÍ5ø±Öµ~¬åΖ;[î,xÅyÅyÅÁ“ÙOf?™ y³òfåÍ‚G6lÙ€=öØz'‰7F¥ü“¡ƒ!Äë¶Ñr£åFKˆÚµ7j/L­4µÒÔJ`¥¶R[©!%%%%%ÔwÕwÕwÁé§_œ~ÅWñU|!isÒæ¤ÍPäUäUäÖݬ»Yw›t›t›t`Cø7ßÓ/ˆ,ˆ,ˆ„¤II“’&ñ¯Sö-í[Ú·„‚eË –AÆŒŒ3Àâ°Åa‹Ã`dndndßf|›ñ-Xݱºcű͋͋!qGâŽÄ`æiæiæ N7œn8Ý€ô-é[Ò·@ú­ô[é·Àx¤ñHã‘`Óʦ•M+ÈÛ“·'od É’5ìžÙ=³{¥ÂJ…• 3ô^oŠ!D‰±aÕ†UVAêòÔå©ËaÆãg<6t*! C.B”¿SBHB!J")B!D $@!„(¤!„%!„¢’ „B”@R„ïŸ/ø‚/@y¦¤û°égÓϦP›ÚÔ6ôFˆ·•!ô§?ýáÚ—×¾¼ö%l>¾ùøæã «« ýªö«Ú¯*4ˆlÙ ̵æZs­¡C—\IIIp7ànÀÝØ1wÇÜs!5=5=56Øh`#h™ß2¿e>h"5‘šHC§o)B”`¹º\]®¶>ßú|ës8÷sÿ8÷ð)çSΧtvïìÞÙ,ÛZ¶µlkè´âÏŒ)S0ÎežË<— [7lݰuxîõÜë¹F”Q~Dy°ijÓÔ¦©¡ÓŠ·…!J Ì[™·2oÁªŽ«:®ê óæ'̇‰™3'f‚Ç,Y³ RüUñcãÇÆ…Ÿ–ÿ´ü§å÷uÞ×y_ÃŒ¼y3òÀy…ó ç†N) Mž D ’W>¯|^yXU¸ªpU!ä¯Ë_—¿æo˜¿aþ†ÿâ9ä€r^9¯œœp ˆ!†˜W°B l`p{ÜÜpà ”o•o•o½ìeïÿ±ž (~æg~æ_w |]2~Ìø1ãG8×ì\³sÍ z^ô¼èy¿{ÃyÎsøˆø”qÊ8e°‚¬tèнºKŸ¥‡éÕ¦W›^ l¯Ú^µ½ú_¬ÇlàfÊÍ”›)0Ùw²ïd_x°ãÁŽ;þ~ÌüÞù½ó{Ãwß~÷íwß•òWÊ_)‰&„{ì]°[¶ lõçëÉËÍËÍË…Ê e…WG]uuÔ«ŸÖâKÅ—Š/Á¯Û~Ýöë¶—WíÇLŽ™3¶tÚÒiK'Øo´ßh¿d–É,“YV»®v]í Ë—;/w½£ÞQïøêóY”¶(mQÆ 7xÜ`pZè´Ði!üìý³÷ÏÞ óÑùè|^ý¸âÝ @ˆàþÊû+﯄0ÿ0ÿ0øhÞGó>šÖU¬«XWùVTDEà¶Øm±Ûbˆø5â׈_!mTÚ¨´Wð V3P3P3jÖ(¬Q¥ƒJ•§%NKœ–@Áˆ‚# òzäõÈëP¬/ÖëárÒå¤ËIåŸåŸåÚµj?„ujÔ©QJ?-ý´ôÓW?¯ÙU³«fW…³gÏž={Z o5¼ÕphYز°e!T¨W¡^…zP®a¹†åB©OK}ZêS°L±L±L›ov¼Ùô[õ[õ[_}¾ßï3Þg¼FÞygäHÚœ´9i3\ît¹ÓåN¯o\ñv“ D pdù‘åG–Cƒ6 Ú4h厖;Zîè__ŸQ£>F}@ç¡óÐy@x™ð2áeàäù“çOž‡° aÂ6@Ö¦¬MY›àÔ¾SûNíƒðRá¥ÂKAöÅì‹Ùá䘓cNŽð&áM›@á£ÂG…À8Æ8Æ8òoçßοý»quF:#¨W«W«WÃå–—[^n __ÿúú××á\™seΕ”­)[S¶‚I˜I˜Iä×ʯ•_ ¢’¢’¢’à°Ýa»Ãv:4thèP8Üæp›Ãm º}tûèöÿyûõóôóôó Ê-Ê-Ê bbbàö¸ÛãnƒÑ/¢_Dƒ¦¹¦¹¦9¿üyíJíJíJPPPÕÕÕÈÙ™³3g'\H¿~!ަM=š у¢EúûŸ›96slæ@§tZ‡Zjy¨%œ-8[pö5}øÄ[K €ï±Ô›©7SoÂýv÷ÛÝoMG7Ýtô+Xq.¹ä?ð?€q¸q¸q8h“´IÚ$Xc½Æz5œÛynç¹°/l_ؾ0Øž½={{6˜|lò±ÉǰÇhÑ#ØÞt{ÓíMÁ¸ºquãê°cÔŽQ;FÁ6ý6ý6ýïÆýç¹r•›ÊMåy½ózçõ†„„„0_a¾Â|˜39fr ¶·ÙÞf{ØYgýõ!Î&Î&Ξ_x~áy(=ó)”êXªc©Ž ¬UÖ*kA{A{A{œœœA™¤LR&¶¿¶¿¶?8¬uXë°H „ß›J*© Þ Þ ÞÎ:Û¶m7BÍ5oÔ¼6>6>6>`Àþ€ýP}§úNõØ/±_b¿̽ͽͽ¡Ú¢j‹ª-‚v9írÚå@LXLXLäŒË—3²ªfUͪ IÛ“¶'m‡•_T~Qtãuãuã¡ü½ò÷Êß›Ã6‡mCMš5=À¶—m/Û^àô©Ó§NŸ‚ê”ê”êÔ§Q5]5]5²¼³¼³¼áØÞc{í¯ ^¼&@³f!ÍBàYì³Øg±iiiÿ÷wŸÍ-›[6·Àô±écÓÇÔ4©i’|=°Ä‘gñS¶)Û”m úEõ‹ê`Cò VüÛÍïr”£€^xãÏx(5¾ÔøRã!ëqÖã¬Ç`ÚÏ´Ÿi?à1yü 7Ð#Œ@ÙªlU¶þný5©IÍó~ 4 œTN*'cãPžò”%P T?üðƒm¶Ûl·Ù­C·Ý:¿ÆÆ´ÓnL;piäÒÈ¥(Ί³â J=¥žRïÈ_Žr”]˜.Li‡Ò¥‚à˜à˜àˆý8öãØ¡n«º­ê¶—-.[\¶½éMï¿>m¿rPuTuTuýAýAýÁW¸_Ä;A €ï1{c{c{cPn+·•Ûv4íhÚQ°ZgµÎjÝ+ Ÿ|ò T ÂËÅ7=ÜôpTëY­gµžÕ<«yVsÈWò•üßßuä·"Q–²”ýÝrSL1Ѐÿfy jPÈ@B±}±}±=èÝônz·ß½ß ,xy|=zô¼¼EîU®r•—§š¨š¨šð¯;#ú‡û‡û‡Ã€Š*¨t¡ ]À¼‚yó á—á—áÇ¿¾Þ‡;î¸ÿn|*Tÿf;~[þÏq7o6Þ e‹Ê•-‚fšuhÖ:Ìï0¿ÃüßýÜ&0áïï¶ ¯ ¯ /È«˜W1¯"8¶qlãØæ|Ä;E €ï±Òö¥íKÛCÅ[Tl—+]®t¹Ò¿¾Vÿ—i‡k‡k‡ƒ»µ»µ»5\\|qñÅÅpgÄwF@‘o‘o‘/ôû¼ßçý>‡Û+n¯¸½‚6mÚ ‡¶Úrh ¤,LY˜²Œsss!¦8¦8¦ž'>O|žœä$'!"5"5"’ÔIê$5¨[¨[¨[€þ¬þ¬þ,ØŽµk;öå×ñº¶éÚ¦kHÜž¸=q;¨»©»©»ÁÕ®W»^í M š4…§ƒŸ~:žœrþÉyȯ’_%¿ <Ÿ÷|Þóyàhåhåh&˜`ò»íWâ”8%¿êþ*È-Ÿ[>·<ÜýÇÝÜý¸Íq›ã6?.~\ éÒ;¥w‚[Kn-¹µbnÅÜŠ¹éáéáéáv-íZÚ5ÔuP×A]áø‘ãGŽ„* Uª@ÙÑeG— &4šÐhX˜Z˜Z˜þõý©ŠTEªÀz…õ ëàlælælfèO«xÓäN€B”7Rn¤ÜHMúMúMz˜;mî´¹Ó ôæÒ›Koþ +lK[ÚBê©ÔS©§ §nNÝœº Û©Û©Û ¶ lØ.ëÍÖ›­7CÑ÷Eß} ³f'Ìõ]õ]õ]`0ƒ êºêºêº`ÕÕª«UWH[œ¶8m1EQPÊ£”G)È Ê Ê â_‡úKw)Ý¥tHßœ¾9}3ävËíöÿcï>㢸úþfwéM¥ƒ‚ˆ *XP,(Vì½÷D51‰Fb,1jŒ±w½ÄØ{ÃÞ°‚ A"Ò{]Ø6ÿwüß¹r_IŒÙ¨ó~¢/v÷Ì÷œÝSÎ)íU~ªòS•Ÿ èvÑí¢Û n7ˆ@±@±@±Êë•×+¯616161 j®j®j… /^Û^¶½l{y#óFæÿiu½YÌbä?ΜÿrÝrÝrÝÀ¬–Y-³Z`•n•n•¹B®+€ªªªTšSiN¥9 LQ¦(S@¥R©T*°mcÛÆ¶ YYYBÆŒ7@å£òQù€i’i’iX?³~fý äáòpyøŸØ_?+••ÊJeðí¬og}; Z5kÕ¬U3èØ­c·ŽÝô}”JþiR ‘¼t}t}t}`Ó O6<üYù³ògÁ”Ð)¡SBÁd­ÉZ“µúN)y]tN:'l¾µùÖæ[1,cXÆ0ø¢Ã¾è†s çÎyõíHÞ,ÒSÉ;@vDvDv†}7ì»aßAa»Âv…íàûÜïs¿ÏeUeUeÕWߎäßEýHýHývÛí¶Ûm}ú<ô&|0რÒÿ»N: ‘¼ƒ2ëeÖˬ˯,¿²ü µ0jaÔ&ö˜Øcbp\â¸Äq‰¾SJþªü%ùKò—À¶Ûnl»1ícÚÇ´‡ A3‚f€{‰{‰{‰¾SJôM*$’wX~ïüÞù½aóªÍ«6¯‚èÈèÈèHþlø³áÏÀ_ç¯ó×ᧆŸ~ªï´’ߣ  P±FÃ6ÇmŽÛ¡J@•€*ðá­o}x V8¬pX¡ï´’ ©H$h«k«k«Ã¥”K)—R`cöާmNÛœ¶Á ¥ƒ–Z µ…ÚBmä“ä“äÃãh’¿F÷ƒîÝØ ±Ab8°ôÀÒK!29292z¬é±¦Çèù^Ï÷z¾FOž=ÕwjÉ¿TH$’ßÈ2È2È2€cŽÇ9¾7úÞè Õƒ«W†.^]¼ºxA=ÿzþõüÁxšñ4ãi¯¾]ÉöË<QžQžQžü øAðˆ9$rÔÿ¡þõ€þ7ûßìª:Tu¨ê‚—à%xé;½äßJ*$Éï;ÃÎ@JAJAJ\ØqaÇ…pÓø¦ñMc0~füÌø4Ó|Ló1Ðäh“£MŽ‚s¡s¡s!………ê»oMGMGMGH]˜º0u!<þ B\C\C\!oqÞâ¼Åà«öUûª¡ÓÌN3;Í„{kì­±„ÍÂfáoX+@òn ‰DòÇ}Á|E{Šöí°Ü°Ü°\¸6áÚ„k ¹mrÛä¶P© RA¥¨Y/²^$Ô¿RÿJý+P]Y]Y] fçÌΙ…•ÂJaEÅŒ€o9 t”hK´%ZxaûÂö…-„«ÃÕájx4ìѰGÃ Ó Ó ÓìzÛõ¶ë -†¶Úb(4§9Í*æUÌ«˜qħï^IÞTR ‘H^™¶½¶½¶=dÍËš—5"kEÖŠ¬÷¿¾ÿõý¯áùÎç;ŸïÎGç–ý-û[öO;O;O;psssss§Ï>wúì­í­í­ÁRc©±Ô€l¸l¸l8¿Nýû¯qŒcqŽ8Gœřřř1-cZÆ4H”þ(ý$öMì›Øâ¢â¢â¢ «RV¥¬J k¨k¨kÕÚVk[­-ÔŸUVýYPÿ^ý{õï}sûæöÍÁ`ªÁTƒ©úî¬äm#‰äµ+kXÖ°¬!ü`ôƒÑFpjý©õ§ÖCàØÀ±c!'5'5'ò¶åmËÛb˜&†Å·ßZ| U|ªøTñË`Ë`Ë`°ö¶ö¶ö[o[o[ïŠ)mM6˜l0ÙË –,E?E?E?V «…Õ ß,ß,ß Ìf6³AW_W_WtëuëuëA;O;O;ÔuÕuÕu¡LY¦,SB¡_¡_¡ä®È]‘»2÷eîËÜ 6l€Ü©¹Ss§BáâÂÅ…‹A(‚Õz«õVëÁÑÞÑÞÑ<7ynòÜ®Ç\¹ƒê;ªï¨¾,÷Yî³Üǯ‹I$ÿéP“H$¯]t@t@tÜï¿ÿýþ0Ãü ó7@Ó°¦aMÃ@}Z}Z}ÊÇ—/™Á™Á™Áb”b”bT±@®e®e®eÅ= U#ªFT…âjÅÕŠ«vŸvŸvˆ/Äâ ;‰ÄNÀr–³ØÈF6‚ØWì+öaˆ0Dæ0‡A¨.Tªßò-ß‚b©b©b)èÎêÎêÎBè†Ð ¡ _P¿ ~AàèèÖqÖqÖqà¼Ùy³ófphíÐÚ¡5dü‘ñG`8ÕpªáT@Däå_·zÒ“žúÞ;’w•t@"‘¼6Iý“ú'õ‡yÙó²çeC·€nÝ ï ¾ƒú¼ñÆû¯·¯MÓ¦iÓ@m¤6RÆUãªq­XŒHÛ@Û@Û bù_]Œ.Fâ2q™¸ äååA¨,T*ƒ\!WÈ )d YÅ©÷ŸíãëC_úú41ibÒÄúíî·»ßn}²Dò×H€D"ùÛN(œP8¾nòu“¯›@õ‹Õ/V¿ZNh9¡%(&*&*&ê;åŸw§ÝvwÚÁ§8ýÃiXä¶Èm‘إ٥٥é;DòçHkH$’¿V­UkÕ°uæÖ™[g‚Aƒ&M`t³ÑÍF7{s¿øÑx_ã}÷AµøjñÕâá¨ßQ¿£~úN%‘ü5R ‘Hþ6§—^vzD¼ñ^Ä{ðц6|´L?6ýØôc}§{ur[¹­Ü¶Øj`+yò0ä!$¶Jl•ØJßé$’?Gº ‘H^Ù#ûGöìaiý¥õ—Ö‡O¯zýÓëà§ôSú)õîï'v»‰Ý`yŸå}–÷ªQj0ÕyªóTg¼oáîmHþ Ò‰Dò—e»d»d»Àúo×»þ[èÒ;¤wø-ð[à·@ßé^á”pJ8ýú;õw‚pppx²éɦ'›ôN"ùc¤@"‘üiº.º.º.°m×¶]Ûvs?ç~Îý W^uzÕ>ã3>ÓwÊׯz×ê]«w…–ñ-ã[ÆÃ¸qâ@×Q×Q×Qßé$’ÿ›TH$’?í¢ ‹.,‚˜b>ˆùÆŽ aaaúN÷Ïë5¿×ü^ó!ùAòƒäú,ôYè3}§’HþoR ‘Hþ°ô¾é}ÓûÂÞa{‡íÃZ k1¬8„9„9¼ƒ_ü¿°¿fÍþtÜqpÇÁ°¿ÕþVû[A™¬LV&ý/+ù—’M‰Dò_‰wÄ;âØýÞî÷v¿Ë<–y,ƒ–n-ÝZºé;Ý¿G§N!B Ø´Ø´ØB¾ ù2äK}§’Hþ3©H$ÿÕÃ+¯<¼)))0<{xöðlPÌUÌUÌÕwºJw+Ý­tzuèÕ¡W8zíèµ£× hGÑŽ¢úN'‘üÿ¤@"‘ü.õ}õ}õ}Ø_yåý•¡ýŽö;Úï€jë ¯6\ßéþ½ÚÎn;»íl¥ÉÒdipåÄ•WNè;•Dòÿ“ ‰Dò»î¯¼¿òþJÈžœ=9{2tžÞyzçéúNõïgnn=½W€IDAT½}zûôöS½Nõ:Õ ( @ßá$’ŸI€D"ù õfõfõf8Þåx—ã] µGkÖ`Óצ¯M_}§{s´xÚâi‹§`>Î|œù88·æÜšskôJ"ùR ‘H~#ºGtèðbÏ‹=/ö@à¤ÀI“ôêÍcôØè±ÑcèÔ'¨OÇÇÇ@Îòœå9ËõNò®“ ‰DòÁ«ƒW¯??????pë0ÖaìßÐpI$)¤òÇ?ölð³ÁÏÕFW]i%‘%‘%‘/½¡ˆ"Š@ÌsÄ u¨ä‘Gž¾G·iܦq°}jûÔö)œI>“|&Yß©þ€rÊ)žð„'@e”ý÷•½_ö~Ùûp+öVì­Xxñ8âqÄKoH&™dà(G9 âââÀ1Žq P¡B¥ïοý¤@"‘üêùÎç;Ÿï„¨&QM¢š@× ]7tÝð74ìˆ#Žð“åO–?Y‘¢#EGŠþ@÷çîÏÝaKŸ-}¶ôèuÑë¢×AüÊø•ñ+añ²ÅË/ƒDm¢6Q ±Q±Q±Qäää!½Bz…ôÒ÷¨‚Q{£öFí¡ÿþ7ú߀K/=¼ôÒ¦=L{¨ït¿/ý›ôoÒ¿…XxRìSìSìÿûçŽÎ::ëè,¸øüâó‹Ï!>*>*> Î=wôÜQØâ¼Åy‹3ûûûÃÁSO<³²feÍÊ‚¢‚¢‚"éf‰×N*$ɯBlClClÁµŸk?×~P½EõÕ[ü d$#¡zIõ’ê%àâãâãâóß?ö8úqôãhHOOOOO‡áý‡÷Þ\šº4ui µ§ÖžZ{*XÔ¶¨mQjÌ©1§ÆH6J6J6‚Ÿ¾øôŧ tT:*áΔ;SîLÍ<Í<ͼ~|ú4ôièÕüªùUóƒÓ§Nüó9þ(“““¨k_×¾®=˜7nú<ý¡Û«Û«Û »\ìr± ÔÙZgk­Ð#¸Gp`p r r ‚šv5íjÚ¹¹¹8&:&:&Bظ°qaã@½Z½Z½bÅŠ=qKâ–Ä-Ñ÷h¼}ú ‘HôOYYYYYnu¹ÕåV¸vàÚk!Û;Û;Û»þîz°Xo±Þb=”û•û•ûGW®]ÁÑÞÑÞÑn׿]ÿv}0›c6ÇlhGhGhG€³»³»³;60l`Ø´×µ×µ×A´-D Š„"á¥3eëËÖ—­‡È'‘O"ŸÀóGÏ=OÒŸ¤?I‡ªêªêªj0-3-3-åUåUåU°ö´ö´öùUùUùUg‰³ÄYpLvLvL‡—^vxµ jÔ |/û^ö½ iKÓ–¦-…èëÑ×£¯ƒ¡ƒ¡ƒ¡4šÛhn£¹o‘o‘oQª(U” l/Û^¶½ +•Æ <šy4óh?xüÁãÀkׯ=`sÝæºÍõŠ~ÉïÈïÈï@ߤ¾I}“`åâ•‹W.†Îý:÷ëÜœ9r>ô×÷£n¡n¡n!„½{ör.ä\ȹ&ãMÆ›Œ¡«ÐUè ~Ûý¶ûm‡ìÙ-²[ÀÓ£O>= ¶ŸØ~bû h7i7i7Co‡Þ½Á4Í4Í4 ÊŽ—/;|Çw|÷Ò†ÛІ6x$ñHâˆ;w$î<ûdì“±ÐØ¦±Mc’„$! „-Âa è~Ôý¨û >6øØàc}*ûTö)dÎ<œy–w_Þ}yw¨q¯Æ½÷`”Ã(‡Q`½Ñz£õFxØæa›‡m wNîœÜ9PuxÕáU‡ƒ§è)zŠVVVô¦7½AÞRÞRÞâââA£‹ÑÅ@æ¥ÌK™— Qt£èFÑ Ÿ(Ÿ(Ÿ¨ï•¯Ÿt@"‘ðhÓ£M6ÖEë¢ußTßTßT(ý±ôÇÒaáü…ó·¤ÑI£“FCn|n|n<,깨碞‘‘G><òá‘a퉵'Öž€øöñíãÛCúÚôµékáÎì;³ï̆UŠUŠU Ðøh|4ÿáL€ì„ì„ì(ÊeŠ2m‘m‘mƒíÛ ¶ƒì¾ì¾ì>¬^¹zåê•pÃ÷†ï ß—øù²ÌCæ!󀜌œŒœ (˜[0·`.˜$™$™$AÊ•”+)W`Ye=–õ€Â‹… /¦7šÞh ›ý6ûmöƒâÅ‹Âì.³»Ìî×b®Å\‹§wžÞyzR>Jù(å#ØÕ~Wû]íá™Ç3g¿?ÞõÞ¯÷~½÷Á³‘g#ÏFptæÑ™GgÙd“ý×÷£l†l†lÜè}£÷Þ°ÁiƒÓ'0p1p1pS·OÝ>uv·ÞÝzwk(T2¨d|©úRõ¥ B"B"B" úTô©èS tV:+aÅÝwWÜ…;†w ïþ‡ Ûb‹-("ŠÕ“Õ“ÕKKK0úÐèC£!>4>4>¾éõM¯ozAñûÅï¿Bª*¤™d’ Âmá¶pA±A±A±MMMáÄû'Þ?ñ>~pøÁá ‹ÓÅéâ`Í©5§Öœ‚'=ùèÉG V/X½`5Ä;w¾âž’PÿPÿP8˜{0÷`.¨ž«ž«žëû_ã?G: ‘H™23d&4 lØ0Ì¿7ÿÞü{Ðiƒ´A`>Å|ŠùðêäÕÉ«ÔßTSýMppÔÁQGÁ³KÏ.=»¶!¶!¶!`.7—›Ëa¨0T*€à"¸.œœ Âcá±ð°Ã»ßæ1ðÙï³ßg?œîºÿéþ|+ùVò-hkÞÖ¼­9ºººÃ¦:›êlªýÝû»÷wóÏÌ?3ÿ Z|×â»ßAÃ9 ç4œâq‡¸–.-\Zf'ÍNšüýñ. —…ËÐwpßÁ}Â; î,¸]kw­Ýµ6¸áƫ̰lÓÔ¦©MS¨Ò¯J¿*ý Eÿý[ô‡ÂF… ÁöšÛkn¯ ]>èòA—À¼­y[ó¶Ð²VËZ-kA½%õ–Ô[ººº`þÌü™ù3ˆÄÿaƒ8ÀpŽuŽuŽ…*ªtªÒ ¼¾ñúÆë°¿nÝþ:8ìpØá°d¶2[™-0éLçׂM)ŽGB展ÇV •ÛUnW¹ÔÚQkG­`Óæ‡M8±üÄòËÁ_ë¯õ×Bë•­W¶^ û½÷{ï÷†EŠÃF‡ÁÞÛÞÛÞŽ8~àx«ˆUÄ* ë¡ë¡ë]’º$uI///}ÿküçHg$’wXÖá¬ÃY‡!Ê>Ê>ÊZ´mѶEÛ—Þ`€@0Á‡8Ä!-‘-‘-y€<@¥—J/•^!LÂ@æ"s‘¹T|ñÿêw¸ó'jР±ƒØAìdA ü‰v´hÑ‚¸^\/®šÓœæPâZâZâ é­Ó[§·†Ã>‡}û@|@|@|´ÜØrcË ÿJþ•ü+ …B¡dé²tY:È2…LòMòMòM`9Ùr²ådgÊ3å™ÿ=V-ÏZžµ<¡Þƒzê=€£ Ž68Úˆ!†˜Wر?KYÊÒŠ·1ncÜ”ÔÔÃ@—¥ËÒe`/Ø ö {!{!{²²² »$»$»¤‘FÚØî/ÇË/w÷O'‰åñQ9rä@8ᄇ9ÌኗóòòòòòàÑüGó͇ý-÷·ÜßªŽ«:®ê8¨y¼æñšÇA7H7H7¨b?ýÒ/ƒO >5øŒ¦M7š^Qàþr¯Ê»B*$’wX„C„C„˜×5¯k^j̨1£ÆŒ—ÞðËãX}èCö û„}PÜ ¸AqP¯T¯T¯û‰öí'‚¸X\,.¡¹Ð\hþ6(C† hK[ÚÆcüüåý=éIOÀSL:tüútMhB“—>÷Ë™o¼ñjS›Ú ™£™£™â|q¾8ª,ª²¨Ê"¨z©ê¥ª—`€ÏŸ>0ùÔäS“OÁ´zÓêM«F#ŒF ¢ðø_¿¢«ÜTn*7ˆ<y8ò0-6(lPØvîݹwç^¨íWÛ¯¶Ô«W¯^½z°¾ßú~ëûÁÁ ƒAƒàɆ'žl€Än‰Ý»òŠòŠò ĚŚŚUäÍ Î Î †EÇ_t"GEŽŠõÇ÷COj|Rãh´¤Ñ’FKàèÄ£N1SÌÿÀ™„ÿM8 @âáÄɇa×Õ]Ww]…>øðÁ‡0üÆðÃo@ÚÙ´³igA§ŒSÆAlÕØª±UOù”O!6)6)6 •…ÊB%Äõ‰ë×Êæ•Í+ûOQ$ìHØ‘° >*ø¨à#ˆ>}>úQlÔ>¨}(?qüÄñ¢˜\-¹Zr5Q,É.É.ÉEõ5õ5õ5QLª”T)©’(&&$&$&ˆbù˜ò1åcDQ]_]_]__ä¾È}‘+ŠÏ|žù<óÅ¢oо)úæ·ÛÕtÑtÑtÅ_\|qQã{Æ÷Œï)Šùòä?Å   Q|6ôÙÐgCEñŇ/>|ñ¡(æuÎëœ×YŸ•=+{V&Š)7Sn¦ÜEålålålQ|ø<ðy (&~™øeâ—¢¨Ù¤Ù¤Ù$ŠÅ“‹'OÅgžuxÖAŸW^ýyuQÌ_‘¿"…(|PðAÁ¢———!Š™]3»fvÅÿ¹¤ йF®‘‹bê™Ô3©gDQ9]9]9ýÏï—Äî‰Ý»‹âû3ߟùþLQŒ¬Y#²ÆŸog—÷.ï]Þ¢8àà€ƒŠb|ÿøþñýE1­FZ´¢¨ ׆kÃE± }Aû‚ö¢&Š™‰™‰™‰¢(Öë‹õE±Ð¥Ð¥ÐEã ã ã E1eBÊ„” ¢¨ Ôj»Ý¢IE“Š&‰b|·ønñÝD19;9;9[KÕ¥êRµ(¦OOŸž>]ãíãíãíE1{vöììÙ¢˜žž.Šñ£ãGÇÅü#ùGòˆbþ½ü{ù÷D1æÓ˜Oc>Åœ¤œ¤œ$QÔÍÐÍÐÍÅôVé­Ò[‰büþøýñûE1Õ=Õ=Õ]KÅR±TÅ”í)ÛS¶‹â³¼gyÏòD±Ô«Ô«Ô«"o¡m¡m¡­(f|™ñeÆ—¢¨Û®Û®Ûþºÿõý{H€Dò ) ) )ÅeË>–‰¢²®²®²îoß—Ô>©}R{Ql‘Ü"¹E²(÷ îÜSßéß~ëCׇ®Åy·æÝšwK5ÆcñÿüÚqkÇ­'Š}Ÿö}Ú÷©(æÊ?”Hß½’üÛH—$’wУ:ê<ªµKj—Ô.ãããˆß¾¯ìnÙݲ»0xÍà5ƒ×€Ñh£ÑF£Aw[w[w[ß½x{õìÒ³KÏ.=þzüuxœ÷8ïñ˜ÒX¨T‚ëû®ï»¾’:%uJ‚¢»Ew‹îê»W’á—J@ßA$Éë÷˵Û/²¾Èú" m´iÐ&ð/÷/÷/×w:Éÿ¶åΖ;[îÀóÄç‰Ïá«V_µúª(Ž G}§“¼é¤3É;$åqÊã”Ç ¼¦¼¦¼ž2O™§þÈMÌMÌM„¸Uq«âV*[•­z… pÞV=:÷èÜ£3üϽðàûß?ø^ß©$o ©HÞ!á«ÂW…¯‡µkÖ‚Í›;6æ¹üW”Ý%»KvØôÓ¦Ÿ6ýû|÷ùîó…¬mYÛ²¶ý÷Ï]-ºZtM<4ñÐDØ¿zÿêý«A×F×F×F_£úúØåÙåÙåA»Äv‰íáp³ÃÍ7ÍQÍQÍQ}§“¼é¤@"y‡DŸ‰>}¼Â½Â½ÂzÔ£Þ?·ý‡‘#FB\Õ¸ªqUáƒÃþà0ØÖ°­a[ã¿Þ"Ñ"Ñ"òîçÝÏ»GGqth{j{j{êkT_¿Î :'@–{–{–;ܹs÷U& ú«†0„!ð¢Á‹/@Á½‚{÷ô=:’¿J*$’w@A½‚zõ ùËä/“¿ssónûºÎºÎºÎW=®z\uȘ“1'c”,=Xzäµäµäµ ýdúÉô“ðDóDóD1{böÄì²Ùe³Ëfïó>ïƒÅ‹;w@vKvKv „mÂ6a}[ômÑ·}-úZô5ˆ‘ÇÈcäPÚ¿´iÿŠz;4ßt|Óñbbòò¢A?OMûËT³ekËÖ–­…ës®Ï¹>¬»Yw³î#Œh0¢Ôµ¨kQ×’,’,’,àtãÓO7†f̘Aß}oô½çzœëq®üÏ„5úÞk¿U9¤rHåèêÐÕ¡«ó?æÌ”®JW¥ë«·ÿßT_^}yõåË!·ÞÑzGëФZ“jMª¬³¬³¬3´nÜ"Æ=÷xÜcðºäuÉë”y—y—yƒI_“¾&}Áõë!×C JV%«’¡àË‚/ ¾„ý;öïØ¿cccá½[ïÝzï=ÄbÒ„4! ¾(ø¢à ¸6äÚkC`ƒnƒnƒ®F^¼ Ú³Ú³Ú³/µóóâââ`nnnnnã§Ÿ>~:œ¬y²æÉš0¥ï”¾SúBĦˆM› ä@É’r(åPÊ!8zêè©£§àÌ…3Î\‡R‡R‡R{È=ä¹—¯]`ïÀÞ½¡ì~Ùý²û2+dVȬ׿]ÁH0Œ€U¬b°}ìžò”§ 7•›ÊMÁ¤‘I#“F`ô™ÑgFŸü‚ü‚üPB %/7øóÚ ƒÄ PTT„”“)'SNÂÅŽ;^ì{ý÷úïõ‡JG+­tŒÂŒÂŒÂô½Þ|Ò%‰ä-¦Û¥Û¥ÛIý’ú%õƒ®»6îÚ˜_¯µþã(P€pA¸ \E¨"T 747474pÄìˆÙ3Øn·Ýn»˜÷4ïiÞ‚7 nôR;?¯'l6 Ag«³ÕÙBÀå€Ë—¡k“®Mº6/ÏyþËó°UÜ*na²ÁdƒÉ`·Ón§ÝNè6¸Ûànƒ¡Æ75¾©ñ ˆ^¢—è¹—¯E„E„EôpîáÜÃŽçÏ?ž- Z´(ÓÏM?7ýüul ,@l(6‚ØDl"6á×ņèF7ºà/ø þT¬jXJ)¥ «¢«¢«òR{†bÂ(a”0 Æ c…1Ø4·inÓÚÚ·µok-,[X¶°„QÇGu Ò Ò Òõ½Þ|R ‘¼Å²§gOÏž¹¹¹à1Ìc˜Ç°>‡vžvžv$oMÞš¼2?Îü8ócH2K2K2‹­[-¶VÌ0xÏýžû=wH]º uAÅ"1é©é©é©¢JQ¥¨ g|Îøœñèšèšè ß;øÞÁ÷ ©wSï¦Þ`<Úx´ñhðøÂã / ÚgÕ>«ö4+lVجŽß=~÷ø]hr¨É¡&‡ÀÁÝÁÝÁjzÕôªéòKòKòKúÞ‹¿¯õÈÖ#[„3–g,ÏX•ãWŽ_9]?ïúy××Pæææ€Y™Y™Yümð·P/½^z½t(t,t,t„¤[I·’nU,ÆXíDµÕN@^Q^Q^„4 iÒR R R  P, E»È]ä.ÐIÖIÖI*_¨|¡2hiiÍ{6ïÙ¼µšÔjR« a„‘¾wÂLš P"y‹…Í ›6vœÜqrÇIX¼mñ¶ÅÛÀÔÇÔÇÔçŸË¡Z«Z«Z C‡>…ü¸ü¸ü8ð:ïuÞë<Øô²éeÓ ÂÛ†· o šÝšÝšÝ`4Ùh²Ñd(Qþ¢ü¸wuïêÞR¤ HæææàuÁë‚×Ho—Þ.½Ü,¸YpŒ§O1žÞVÞVÞV`¶Öl­ÙZÈwÏwÏw‡È!‘C"‡€PY¨,T»©vSí¦‚Ûf·Ín›A>F>F>Fß{ñ¿;w>î|ö9ìsØÛ/¶_l–‰–‰–‰ßvÄÅÅáÉ´'ÓžLƒ´–i-ÓZB•mU¶UٹŹŹÅP͸šq5c¨e]˺–5”e”e”eÀÃúë?¬²(Y”, ä“å“å“¡üaùÃò‡Ð`Iƒ% –½éMox\ü¸øq1¨OªOªO‚u±u±u1¸+Üî 0\b¸Äp‰¾GÿÍ%É[ìðõÃ×_‡ÈN‘";Á—Æ_i B®+äê;äïR:¨tPé ˜á7Ão†´=Øö`ÛƒÐûvïÛ½¥5$¿Cº P"y‹%|ðuÂ×woK_üo'Ó}¦ûL÷Amm-œñ9ãsÆò†å ËÓÃ%É›A*$’·*^¯Š‡ M†&CUÛTmSµ¾SI^7ÿ•þ+ýW‚ÅgŸY|çÇŸ~¼¾SIþ­¤@"y •••AAÍ‚š5Á>Õ>Õ>Uß©$¯›aºaºa:ô½Ù÷fß›pîĹçN@NNNNN޾ÓIþm¤@"y e̘=tF§‡F½z»’7ƒß¿!~CÀ6Ý6Ý6ΤI;“¦ïT’©HÞB   `9×r®å\¨Ü¬r³ÊÍôJòO105050…¾}úÀÅŒ‹3 㓌O2>Ñw:É¿…TH$o¡” )R6€C{‡öíAˆ¢…h}§’üÓ j0¨Á pövövö†SCO =5Tß©$ÿR ‘¼…2b2b2bÀ®¿]»þ¯ÞžäÍd`e`e`ýû÷ïß¿?\ï½ÿõþ2)eRÊ$}§“è›TH$oM¶&[“ ™O3Ÿf>­˜Mònó™ç3ÏgÔð«áWÃN|}âë_W¼žR˜R˜RW¿¹úÍÕo@ÛSÛSÛSß©%¯›4°Dò)¹Ur«äÞ,¼Yx´Z­¾SIôMÞNÞNÞú9÷sîç ‹Æ-·hˆ)bŠ˜»/ì¾°û”Ý-»[v.̽0÷Â\¨D%*é;¼äµ‘ ‰ä-RÒ¿¤IÐåêru¹`þØü±ùc}§’蛺±º±ºqÅZ OO?=ýô4ìß¼óþÍPn^n^nn§ÜN¹‚”)#RF@¥ÈJ‘•"õ^òºH—$’·HQxQxQ8~‚ŸàævævævúN%Ñ—¢ïо+úf¹Îrå C†„ ƒ»SïN½;Ê”(?PñþüjùÕò«A¢u¢u¢µ¾ÓK^7é €Dòɉ͉͉“N&L:™ƒ™ƒ™ƒ¾SIôÅ8È8È8\º>t}b7±›Ø xÈCþöýyóæ „DãDãDc}§—¼nÒ‰ä-’ö4íiÚS¨<¤òÊCÀÈÔÈÔÈTß©$úb 4P(aBà„À °vÊÚ)k§€ÛçnŸ»ý§å‚£‰&CCC@·M·M·Mß½¼.Ò‰ä-’SSSUVYXe!p„#Ñw*‰¾É“åÉòdÔtPÓAM¡ÒJ7*Ý€iÉÓ’§%Cxð:áu€¯øŠ¯ ¡GB„PRZRZR £,FYŒÒw/$7é €Dò)xTð¨àTž]yvåÙúN#ù×¹Ãî@§ÌN™2aÓÁM7„€7nT¼-æF̘Pܯ¸_q?}‡–¼.Ò‰äm Fò=ò=ò= n׺]ëvÒI']ßá$ÿ:N8áMÔMÔMÔ°1zcôÆh4,hܪ~«ú­ê}=ûzöup<áxÂñ”Þ.½]z”Ó”Ó”Ó@}]}]}tž:O'¨WªWªWFaU ªTá™ðLxL¾6ùÚäk0v1v1v™ÌGæB²,$™ÈD}ÒÛO*$’·€6U›ªM…ÂÎ… ;Cå+\ùc}§’è^xAI‡’% ß+ß+ß ò ò ò+îI]–º,uÔºXëb­‹u%êJÔ˜›07an8¦8¦8¦€ÚEí¢vmmmmmmŠŃ ¶[Š-Al$6ÖXc ÂûÂûÂû 8 ΂3 ……ÂB••…‘ÂHaÆŸnü9X„X„X„€•ÖJk¥…J5+Õ¬Tª®z¸êapzâôÄé X5±jbÕ*=¬ô°ÒC0O7O7Ožð„'úô7‡ þLßA$É_W´¯h_Ñ>ºt%è |fõ™ÕgVPkQ­Eµé;äuÑÞÖÞÖÞ†âóÅç‹ÏCƒ„  Ú9Ú9Ún'ÜN¸ )•S*§TÕIÕIÕI××׋Ç-ƒ]¨]¨](ØxÙxÙxEC‹† A¢Q„€c%ÇJŽ•À¢¹Es‹æ`öÜì¹Ùs0jjÔÔ¨)Èd²0Tª U@5ªQ ÔÓÔÓÔÓ@ûö;íwPþ~ùûåïCɃ’% 8±8±8J®•\+¹ï¼WðäÉ“7rÇåŽË™f™f™fP`Z`Z` ºÕºÕºÕ P)T 8Îpœá8Üänr79x÷ï5Ü]Ý]Ý]Á<Ä<Ä<f 3…™¾÷Ú¿‡TH$ot÷t÷tw˜¹kæ®™»`ᜅsÎûóöçíÏë;äUiŸjŸjŸBRpRpR0<ÿhü£ñ>.|\ø8H¿—~/ýÈ’eɲdpâ<Äy¸yºyºyB­/k}YëK°)²)²)‹“'-N‚¹Ò\i®E?E?E?ÀC õÝÛÿÐW­«ÖŠ÷ï-Þ Å-‹[·„ìžÙ=³{BLPLPL9õÉ©OàAñƒâÅ`gg-7¶ÜØr#4ÍmšÛ4l l l @^]^]^¨Nuªë»7ÿÆ{Œ÷ïO<ñ¤âÏ®­º¶êÚ r/ç^ν a7Ân„Ý€kæ×̯™ÃñÇ޶޶޶УA=€ûF÷îAÞDÞDÞDß½ûûHg$’7HÁ–‚-[àƒÍlþ`3\»síε; ë­ë­ë JC¥¡Ò,’,’,’€Câ,hµ Õ‚VðAì±Äê»’E/Š^Á<à‘Û#·GnPw`ÝuB· nAÝ‚ æÐšCkÃ]†» wé;õÛKU¨*TBâƒÄ‰àLÀ™€3ð`ôƒÑFƒ×÷^ß{}cÆ Œ j4¨Ñ@ß©_TH$o 9ò9ò9r˜_w~ÝùuA|,>ÿâ?N]œº8u#qGâŽÄA“˜&1MbôþÝS–R–R–§N%œJ€–',OXByuæÕ™ý ûö7·Jn•Ü*°^X/¬×wêwXšÐ’’“’“’áˆçÏ#žpßò¾å}Kèt¿ÓýN÷¡Wí^µ{Õ³ fÌ.è;ôŸ'ÉèÖù[ço‡n‰Ý»%BÞ¸¼qyã~û¾îNݺ;Á¾žûzîë ¦ëM×›J_,ÿ˜Ì~™ý2ûÁ÷¿ŸøýDȘ’1%c Œöí9ÚMj4©Ñ$µ•µ•µÕwZÉïLjcÄ1aaa›¼6ymòÓ»¦wMïÂ$&1 ¨º¥ê–ª[ôö“f”HÞ@µÜj¹Õrƒ¦›^lzñ·¯+–*–*–BLJv|(}ñÿÓž‡={ .x¸à!˜M1›b6¾]ýíêoWƒß!¿C~‡¤/þ7…°YØ,lŸ•>+}VÂü„ù ó êðªÃ«‡oL¿1ýÆâêÅÕ‹«§ï´œTH$o *5«Ô¬RÚMo7½ÝtM“M“M«xÝa³Ãf‡ÍÐnp»Áíë;í»#Ó&Ó&ÓVŬŠY>W|®ø\OÆ~2ö“±P¹]åv•Ûé;å›§(´(´(â­â­â­@i«´UÚê/Õ"«EV‹`‚áà †ÐÊ·•o+_X6pÙÀe!¹crÇäŽúµÿN*$’7X{ÿöþíýÁé¶Óm§Û?˜0;`6T_P}AõúNùöÓÞÑÞÑÞ]vtÙѪ׬^³zMx_ù¾ò}%}bô‰Ñ' Ÿ´?i‚kó¯Í¿6¶¬Ú²jË*(­SZ§´Î«çÌóËóËóƒ=½÷ôÞÓ²f5Ìjñ3ãgÆÏ„ï‡?üû᥉ÒDi~¿Ü¹7roÀß=¾{|!{eöÊì•ÿ¸–Ü-¹[r¶oÚ¾iû&غ;tw(D>Š|ùï>¼ûðnˆß¿1~#¤‡¦‡¦‡Âæ™›gnž !º]ˆîïÏõ E E E tvÐÙAgÁÏÂÏÂ϶šn5Ýj e§ÊN•z}ÛUR ‘¼Áj÷­Ý·v_ð}äûÈ÷~kø­á·Ð>¼}xûp0kfÖ̬™¾S¾ýîÄ߉¿YYY0òۑߎü < < <ÿx;ò¡ò¡ò¡ ýRû¥öKØ“µ'kO”L(™P2áÕsª»¨»¨»@zŸô>é}@]S]S]l²ýÉö'<*xDEDEDE€ÖNk§µƒ„‚„‚„KÄ±Ô Õ Õ !}Dúˆô >¯>¯~ N%”'”'”ÃÍS7OÝ<Ã<ü1¸ tè6ÒìÒìÒì@ù©òSå§`íiíií a3Ãf†Í„ot¼ñü&.ß+ß+ß ƒG 1x¨‡ª‡ª‡Âõˆë×#^ÿöÿ*©HÞ`&óMæ›Ì‡¦QM£šFMW›®6]¡‘w#ïFÞúN÷öÓi‚4ApnܹqçÆAë¸Öq­ãÀê¨ÕQ«£½]ËË–—-/ƒÆCã¡ñ€¤â¤â¤bˆy/潘÷ ÿ£üò?‚’g%ÏJžAÌõ˜ë1ס¨rQå¢Ê«øÅ¬ˆY³ŠêÕ-ª ¦ï™¾gút¯Ü½r÷Ê`QdQdQæ×̯™_ã{Æ÷Œï2dÈà‹ /.¼€•WW^]yž‡>} ƳŒgÏ‚îuÿ¨ûG`ºÝt»évx‘ö"íEÄËãåñrxð<ày<ÝûtïÓ½PÖ¾¬}YûÿÞ1QL!qGâŽÄò(åQÊ#(Š-Š-ŠÃM†› 7Aç{ïu¾ùùù``e`e`f§ÌN™ÁSð^*À”}”}”} ®E\‹¸«ŒUÆ*A9J9Jù7,wlVŬŠYè0¬Ã°Ãà‚ .,ÕAÕAÕÁ×z(þ%R ‘¼Án½wë½[ïÁ¡ƒ‡:YYYðCì±?ÄB¾s¾s¾³¾S¾½òGæÌ )ÝSº§t‡º=êö¨ÛãÕÛz =…žÆöˆíÛÎ9s:çóGÏ=4DÙFÙFÙÂÔ½S÷NÝ W¼¯x_ñ†‚»w îÂùù9\ùþÊ÷W¾‡‚¢‚¢‚"˜l4Ùh²\™zeê•© s‘¹È\€zÔ£èšëšëšChС= Ü4Ü4ܽ½½!óÓÌO3?…Éq“ã&ÇÁõÃ×_? û¿Üÿåþ/aföÌì™Ù K:/鼤3ì­½·öÞÚÿ½ÿª0U˜* R›¥6KmÊebZÇ´Ži yòõ7êoÔêyÔó¨çNININIо^ûzíë‹§‹§‹'ØlµÙj³Ê{•÷*ïõÛq”u“u“uƒgÕŸUV.¾pøÂaz~èù¡ç¡ÇÚk{¬…Sѧ¢OECvnvnvî«ï?s¹Î\¦ûM÷›î‡Œ3>Ìøð:(ÿ©HþÍ $ §N)œ¿~üõã¯aKÏ-=·ô„{Æ÷Œïƒ0[˜-¼4g¹I¢I¢I"˜~gúéwúîÄÛK~@~@~tÃtÃtÃ@÷©îSݧGÃÈ‘ƒxH<$qÄŒ-6Z Öµ­k[׆ÔüÔüÔ|À[l©˜óög‚¹`.˜vØa÷Rûf˜aö~þ¿©P¡Þã=Þ ( ÿC;Z´h;ÜáÎKÝ9#?#?ÚvÚvÚvPüAñÅÀÂì…Ù ³!(-(-( æ¹Ìs™çEK‹–-ÁEp\€÷yŸ÷‡<äáKù 0Àp §ßÆò„æã—ÚïD':ð‘ð‘ð°‘läׂS˜+Ìæ£Íh3Ä 1H!…@ƒ …ÎBg ƒ„AÀ|ÁÀAòò5oSL1aª0U˜ &¶&¶&¶0¼Êð*뀺“º“º(Ú(Ú(Ú€Å`‹Áƒ©(hB %ð ¯—ÚuÇwv »„]ÀG|ÄG@ jP0Çs033‡ .@÷Ðî¡ÝC¡êüªó«ÎúÑ~`ØÖ°­aÛ—úùe-ÍZšµÊ\Ë\Ë\¡ê”ªSªN6° ¯õüS¤@"ù'e‘EäûåûåûAø©ðSá§àVÜ­¸[qWWW†w ïÞ:fuÌê˜Á˜ªcªŽ© î;Üw¸ï€J•+Vü†c·Ün¹Ýr¨ìPÙ¡²Œž5zÖèY`ll¬ïN¿½,'XN°œ³=f{̆ûŽ÷ï;‚—ÖKë¥ýëí·7noÜŒîÝ7ºwÞix§!yyyy{óöæí!pfàÌÀ™Ù.²]d;u u u÷±îcÝÇBQFQFQäÔÉ©“S’/$_H¾yÃò†å ƒ$Ç$Ç$GH´N´N´†¼°¼°¼0Hþ.ù»äïÀ©®S]§ºR+¥VJ-¸`tÁ肸«ÜUî*È={:÷4ÄŒ? &L,˜¹Gsæ­x\0½<½<½r{äöÈí¥ËK——.×£®G]¾Ôñ"ˆ1WÌsáyæóÌç™{8÷pîax¾íù¶çÛ€e,cdœÌ8™q4W4W4W %(%(%²/g_ξ̯SúZo±Þb½¤5Hk'Fœqbøºøºøº€Ã ‡3Àý®û]÷»¯~&àÎÖ;[ïl—z.õ\ꃙƒ™ƒ™¾Öß’¦–H^‡‘Œd$Ü(¸Qp¢;GwŽî !'BN„œ€èþŒ6 ¾};úv„Æ¡C‡BMûšö5íÁä®É]“»ÿ}s¡kBׄ®]·wÝÞu_]|uñU0I1I1y…ßd$ÌS³§fOÍà»”ïR¾K A‚€ËX—±.cÿ|{åõËë—ׇ'»Ÿì~²”””@wLwLw > > P-¡ZB5(î^ܽ¸;ø6òmäÛ,Ì-Ì-þéqí·Úoµß“€'O u@ê€Ôà‘ç‘ç‘–û-÷[î‡H×H×HWP„*B¡à²ße¿Ë~HÔ&jµ Ÿ!Ÿ!Ÿ F5Õ`(++Ó:Oê<©òRy©¼¼¼¼ zÝêu«×ÙVÙVÙÖ?¿ßÒóÒóÒó`‰Ã‡%0¼öðÚÃkƒïC߇¾õ}”þ–TH$¯â Oxª¶ª¶ª¶÷4îiÜS¸ºøêâ«‹áaÌØ‡1 |%|%| "D4ˆÿ*þUü«€çHÏ‘ž#Áxñã5À 1èÏÇ:.tì\µsÕÎU°Äu‰ëW0É2É2ÉÒ÷ ½;vÖÚYkg-ˆ‹‹ƒ™Wg^y*u¯Ô½Rw}§“¼.ÅÏ‹Ÿ?‡åõ–×[^ì§ÙO³Ÿ㯌¿2þ ç…óÂk˜'áUI—$’?AÜ-îwCòµäkÉ×àŽÓ§;NpËé–Ó-'(ìWد°x™x™x™À˜ucÖY^½z ‹»w-^þ>ƒ 2ôÝ+Éße@ÝuÔ…´¡iCӆ²´eiËÒ`ʇS>œò!X'Y'Y'é;¥äïR0´`hÁPX·pÝÂu Ak¡µÐZÀÐAC Â,a–0Kß)Ÿô€DòŸSL1úúúà ù ù 9Ìš4?æ›;lî0þ<ü9tºØéb§‹°°Å [@ÐÉ “A'Á¯º_u¿êÿá‹ÿïöóMc¿þ) è{ß=&‡M›†½>ôúÐ ¬,­,­,aîÁ¹ç„'ÓŸL2ÄŸÄŸÄŸôVò§-a K .7.7.¾¶ÿÚþk{кiÝ´n0yâ䉓'‚eMËš–5õö¿“.H$€v«v«v+$''ÕW^\ywºßé~§;áB¸Í7;Üì0´ÞÝzwëÝPµ jAÕ‘‘Ñ_þСC7®ջVïZ ‹Ó§-N“\“\“¿á¹fÉ_S>¥|Jù”Š g‚KƒKƒK¡Kv—ì.ÙÐò‡eK°œi9Ór¦¾ÓJ~OéÞÒ½¥{á´æ´æ´Ž Ç„c´.h]к†.ºdè0M4M4MÔwÚ?Nº y'ççç½¼{y÷òàòùËç/Ÿ‡$¯$¯$/p3s3s3ƒ÷V½·ê½Uà]Ï»žw=°xdñÈâP›ÚüÍþ)ò~ò~ò~ /——ËËAì(v߀ÕÈÞvF+V­„¡%CK†–€O3Ÿf>Í`Wý]õwÕ‡;oì¼±zG÷Žî -¾hñE‹/Àì˜Ù1³cúNÿîR–+Ë•åpG{G{G G+>+¼&zMôš-ÂZ„µïÝÞ»½wƒÅp‹áÃAÖKÖKÖëÕ㼭įůů¡hfÑÌ¢™mmm 7ÜpcDŒŠ1 ¬[5¶j K—.©øÅÀÂÊÂÊŠ_çx[H€äVšUšUš¡×B¯…^ƒóÎ_8RW§®N] õ×o\¿1tl×±]ÇvPó`̓5‚Á ƒ/ôþïóÐì¡ÙC3ر1bc,½¶ôÚÒk`ö¾Ùûfïë;äÏ*¿R~¥ü $.K\–¸ BœBœBœ üiøÓð§P~§üNùp=âzÄõÔQoD½PóyÍç5ŸƒËr—å.ËÁdŠÉ“)€X¼jª±ŸoÚ-·.·.·†dËdËdKˆk×(®V>VBüÙø³ñgÁÀÞÀÞÀê¨{ îhÐ8 1¸7qoâÞŒãŒãŒãôÝ©×O*$o”_V_»ñùÏo|gãÏÆŸF£Ñh uTë¨ÖQÐêX«c­ŽãMÇ›Ž7Š·ùŽ—‡æÍšÃ&å&å&%,Ùµd×’]`6Ôl¨Ù[pªRò?ÊN–,; ñ³ãgÇφÈÊ‘•#+Cd‡È‘ £ZFµŒj ''µj9Ô×Ö®­][ƒ{ˆ{ˆ{ØùÚùÚù‚eˆeˆe˜]6»lvL L L @î)÷”{¾zÞ¿J7O7O7”¾J_¥/w,îXÜŠ-(ZYƒ³g †x³x³x3x¾ûùîç»!í»´ïÒ¾õõõ°[h·Ðn!ÔîS»Oí>à½Á{ƒ÷¨ùSÍŸjþ¦¦¦úÞ«ú#’§ `äœÈ9‘s.´½ÐöB[¸tùÒåK—Á8Ö8Ö8ºt)èR-´<Ðò˜Ï3Ÿg>OßáÿyRðnÓŽÒŽÒŽ‚bM±¦X‰7$n€ø±ñcãÇBBqBqB1¼Xÿbý‹õPZPZPZbM±¦XäkåkåkÁj±Õb«ÅP¹såΕ;ƒU«V ÀÌÛÌÛÌÌvší4Û &·Ln™ÜC¡ÆP²ë²ë²ë`0Ë`–Á,ÇÉãäq ê ê êšMŒ&TkTkTk@iª4UšBé´Òi¥Ó D[¢-ÑBGGäÏ;Ÿw ´Ú-h/k/k/W¹ÊU0™`2Ád8…9…9…[°[°[0Ôì[³o;PýVõ[Õoe?Ë~–ý@þBþBþñû»¼Å¿IÞ(%”P/¾øb œË?—.n,»±ìÆ2°›b7Ån ¼÷Ù{Ÿ½÷44hhÐÐL½M½M½o¼ñÖw'ôG,‹ÅbKÅR±8ÊQŽê;•äŸ"ß&ß&ßVXaÔ§>õú?Õÿ©þOÀMnrʋˋˋ¡xTñ¨âQPÔº¨uQk(”Ê åQ'£NFȨŸQ?£>*÷}ÓÿûG…£ÂQÔ‚ZPókA%‘à?þ`„F€Ñ£;FwÀk¬ÿ¯ÏMe*Sÿ×ÓH# È$“LÀgœaÑÕEW]×f®Í\›Áà!ÁC^^”*Ž8þÌ5öŸWýc8îïÁ|{H€äŸñóÝõ)Y)Y)YpìÖ±[ÇnÁJw*Ý©µ'ÕžT{|üEðÁàYìYìY ²²²úÿ律©˜©˜ +…•ŠŠeTÇ2–¿°Dò‡8âˆãK®`+ÀØÙØÙعb"$zЃú+ùߤ@òZ¥ú§ú§úÃÉè“Ñ'£áæ‡7?¼ù!xzzÂôƒÓN?žåžåžå ÷‘ûÈ¥ßðÿ¼}ìcN:éÀZÖ²Vß¡$ï*Ãñ†ã ǃR§Ô)u¯Þžäõ ÉßcÓ˜iiipzØéa§‡AÈŠ!+À½£{G÷޵ïÖ¾[û.ÈåÆrc}‡ ¤’J*¨W¨W¨W€ØFl#¶Ñw(É»ÊÄËÄËÄ òîäÝÉ»£ï4’ß#’¿æ—¸¹µrkåÖ‚“‡N:y.¸tâÒ pmîÚܵ9L¾7ùÞä{àÓÞ§½O{í•í•íÕwø·Pe”v§v§v'ЉNtf0ƒú'y×Xܶ¸mqR¦¤LI™¢ï4’ß#’?¥8¢8¢8.TºPéB%8p*àTØæÚæÚæÂ§?=øéAðžî=Ý{:Ô4¨iP8ÂŽè;ýÛOð<O µ¨¥ï4’w•¹Ü\n.åYåYåYÐÐÐÙYÙYÙY}§“üB*$ÿ§òíåÛË·Ã-Ý-Ý-xhà¡ [ [ [#"GDŽˆ„f×›]ov ;v4”¡ù版ˆ/ý)‘è‘yºyºy:(/*/*/‚æ´æ´æ4bˆ¡¾ÃI~%’ÿh&š‰f•••»“v'íN‚Œ°Œ°Œ0è5²×È^#¡½{ÿöþ`jbjbjt¤#Ò¿þü2Õë/wc ú%yWçç為™º™ºhghghgÛØÆ6}§“üB*$¤þ”úSêOpðãƒüîͽ7÷Þ\° ° °…Ï ?+ü¬¬eÖ2kÒc=ÿ2ò™ò™ò™ < A,ËÄ2}§’¼« 40hºÛºÛºÛ i¤i¤i¤ïT’ÿM*ÞQ¥ãJÇ•ŽƒsCÎ 97Žõ?ÖÿXð¸îqÝã:|¥ùJó•ܹ/r_ÄŸD¢W²š²š²š MÐ&h|ðT¨Pé;ä]cð™ÁgŸî¹î¹î9hnininé;•ä“ €w„ØDl"6G)R¥À®â]ŻС¬~Yý²ú0ÎiœÓ8'hr¤É‘&G@ž.O—§ë;µäª Õ„j@;ÚÑÄ=âq¾SIÞU†] »vZЂ =¬=¬= |ÄG|¤ït’_Èô@òze©²TY*X×v]Ûumae핵WÖßk¾×|¯Á· ß&|›Ík5¯Õ¼–ôÅÿ¦’»ËÝåî .Š Al+¶Ûê;•ä]¥(V+ŠA×B×B×´*­J+‰úבμeÔÛÔÛÔÛàºêºêº ö$ìIؓՖV[Zm)Ì›77ÜÝÝe,c™¾SK^•pD8"m=m=m=*»”¿”èb•b•bˆ·Ä[â-Ð\×\×\×w*Éÿ&oºŸ'€yqòÅÉ'aÇ¥—v\‚øVñ­â[ÁCn ¹múµéצÔ0¨aP¨A jè;¼äï"/È @/Œƃ¨¢ô¯[¢' #…‘ÂDÑF´ÎGç”RJ©¾ÓI~!ýñ†R7V7V7† Á‚/þFûík>¶>¶>¶°°ÓÂN ;}ª}ª}*P…*TÑwjÉë"L& “Aã¦qÓ¸2dÈøíò¨’¿&’H"AtÝD7DADÀ 3ÌôîßGá¯ðWøƒ8H$M²&Y“¬ïTÿbPP1‡/ä ù€+®¸¾¾ÍJ÷¼)®r•«Z%µJjX¼cñŽÅ;àˆ÷ï#Þ0fܘqcÆÁä“wNÞ öeöeöeH_üïY¬@V2™ƒÌÄiâ4qš¾S½ùÄâ q\zýéõ§°¢óŠÎ+:Ó3OÎ<9S±öRñáâÃŇA9C9C9âÓãÓãÓ!«0«0«Pß½øç8àÚµk?Öwªß§j¡j¡jÏ­ž[=·‚ÔC©‡R{ØÃßp3mɘ’1%c %$%$%tótótó*^8îḇã`•Ë*—U.pÛê¶Õm«×ßo©ø—Ӟממ‡óUÏW=_fžyxæa0ŒcÌZ0kÁ,hy¾åù–çA¾E¾E¾Eß©%ÿ4ù ù ù LÁ444ô꟣٨٨Ùb$ý}í¦nNÝœº~üàÇ~üêß«¯þ=GÈ#ä°"kEÖŠ,M M Me±²XY ‹Ú/j¿¨=lk½­õ¶Ö/å\¬Y¬Y â2q™øß{£h¬h¬h еее tV:+õê÷©ÜTn*7Ø:b눭#`aû…í¶q¢8QœøêíßßpÃý °üÈò#Ë@éÒÒ¥¥K¡xHñâ!°Åw‹ï_p‹u‹u‹››67mn¾þ~KÀ¿Tî¹Üs¹ç`ÍÍ57×Ü„½óöÎÛ;Þ¯ñ~÷kÀ”€)SÀöcÛmÿÅ•µäŸ!dBˆ‡ÄCâ!ÐZh-´¯‹¾¢¯è t£ݨ¸4Кִ²È" XÊR–[ØÂË…äArÄ®bW±+ˆ;Ä⎗>÷ó*>á>>æc>~i»½éMïÿ¼B A<%žO8Gœ#Ί)¦˜Ë\æR±¼q $T|¼À§À§À¶ÚnµÝj ™ù™ù™ù/µM4ÑÀ—|É—ÀINr˜À&ƒÌàß׬#YG²Ž@òÆäÉÁûï¼?Ù³=fÔSLYMn5¹ÕäTY[em•µ`W`W`WªpU¸* ;v,ì[Ÿm}¶õdÍ›5ö¥ ýÜ_ñ xP<â"q‘¸ˆ_ïñùuQ§ld#C 1Àp†3\ßGßo)T •B†‹ .e]e]eÝ¿qa„âdq²8¹âO 'H$‘D`"™œãç@üLüLü ıD,©hÎüGóÍ—h—h—h(³(³(³ÑD4M€›Üä&ÇÑÏíDAT,¾¥D‰ò·q}ý|ý|ýàs«Ï­>·³‹fÍ.Báܹ…s!Ö1Ö1Ö<'zNôœ5»ÖìZ³ë?°Ÿ^ÿ&$„ø¹ø¹ø9<²~dýÈ6>Øø`ã°ûÊî+»¯`þ²ùËæ/''' ‡rôZòo¡°TX*,Aå¥òRyÁ⹋ç.ž 111à|Þù¼óy(]Yº²t% m0´ÁÐðXóXóXçÖŸ[n=ÔÛ_o½ý`|Êø”ñ)èÙ%²K$œ?|þðùÃr#åFÊ P?V?V?††‰ &Bã³Ï6> k­=¶ö”*K•¥Jpöröröe2HC͆š 5»»»íÚ-´„ 9rtWtWtWÀÏÚÏÚÏjd×È®‘ ßµú®Õw­ fÝšukÖÝÝÝ(1*1*1‚]Mv5ÙÕtgugugAQ¨(TÂýÈû‘÷#a‚÷ï Þ`gegeg;Gî¹s$´Ö´Ö´Ö@SšÒô¥ñ,;Pv ìÜ^}{õíÕP?¡~B}8}"úD4´Ñ¶Ñ¶ÑÂþo÷»ÿ[ð|æùÌó `<ðÀtOuOuO!¸,¸,¸ 6´ßÐ~C{€þ7úßèž.xºàé¸iqÓâ¦EÅ:MO6=Ùô$¸p=àzÖE®‹\ µ¢kE׊]¨.T íÆ·ßn<WWWƒO7Ÿn>Ý }¿öýÚ÷ÓÃñè¥ðRxÁƒ%K ô‡ÒJxõvµ×´×´×àbÝ‹u/Ö…˜Ø˜Ø˜XÐÓÓh³ýÍö7awûÝíw·‡¤o“¾Mú¼“½“½“áa¯‡½ö‚¾ñ}ãûÆC£ÑF7 Ô¡u€œà\)»Rv¥ öÞÝ{wï]î7Üo¸ÔŸ[ný¹°«Î®:»ê€G”G”Gt2édÒɤ"¯øX|,>†‡=zÀ±-ǶÛúðЇ‡à‘æ‘æ‘G'ŽN]QŸV]it¥Ñà´Õi«ÓÖ×·Ÿ¤3z¦j«j«j {Oí=µ÷,k´¬Ñ²FÐvwÛÝmwÃŒof|3ãpÚæ´ÍIšC[ò{F1ŠQ`nenen¹.¹.¹.PæSæSæC[m9´%dª2U™*Ø›½7{o6ØØØÀµ×V\[Î}û:÷RRR¸réÊ¥+— 8"8"8ú'öOìŸí¶Øn ¬ÿtý§ë?…4¿4¿4?(½Vz­ô”÷/ï_Þ†Œ2fÈHÛ”¶)mìÕíÕíÕAŽyŽyŽ9¬>µúÔêSÐdz“éM¦C@Ç€ŽaݲuËÖ-ã×3ñ#âGÄ€œs9çrÎA“ M&4™žÏ=Ÿ{>‡J#*¨4º„w ïÍ5oÔ¼DäDäDä€.@  aŠ0E˜S ¦L…µjÔªñVM4`<Àx4¨Û nƒºà˜í˜í˜ Äb< = = ¡Ð±Ð±Ð"="="=^jà/xŠjŠjŠjàVÓ­¦[M¨´µÒÖJ[¡ÓG>êô(W)W)WÁšëk®¯¹þ{ý÷úï…æ½š÷jÞ ÖM\7qÝDûÈ}ä>»0vaìBÈ÷È÷È÷€F¥J•‚áxÃñ†ãÁæ‰Í›'`þØü±ùcýŽò=ò=ò=`nnʡʡʡ¯ÞnxëðÖá­a÷ÒÝKw/…n3»Íì6zì=²÷HØscÏ=7 <*<*< D;ÑN´ƒçKŸ/}¾ºî뺯ë>0»fvÍììÙ²gËž—Ïtý|æ@è&tº—»—»—;$&'&'&Cɺ’u%ëÀÀ×À×À4Aš Mx–y–yþ‡©·ÁG𪚪šª¸{ôîÑ»GA¹V¹V¹Z6´lh öþöþöþN»v;í~ýûI*ô$#:#:#–”-)[R7Žß8~ã8|øEà0`Ñ€EÑ£=FÒŒn’ÿB¾C¾C¾ä)òy ȳåÙòl0¼kx×ð.XDYDYDA­ãµŽ×:‘}#ûFöyGyGyG0?c~Æü xyyAýÚõkׯ >„*ŽU«8‚}eûÊö•Á³À³À³t™ºL]&¿øü"T›VmZµi`kkkkkûûãjǪ̂™Q3PÜWÜWÜÓOL?1ý¤âuÅrÅrÅr­”­”­|éƒ4høõRˆÁ"ƒE‹@¥ˆRDÙ³ f ûtöéìÓðldzÏv@†o†o†/¤þúCên–n–n¥{J÷”Fsæ‚ëc×Ç®¡arÃä†ÉPÕ£ªGU~{øíá·¡éܦs›ÎÕ÷Q † ¥Z©Vª_½½'gŸœ}rOOOÁ%Õ%Õ%ªÇV­ VÍ­š[5‡u„:B F+ŒV­ƒï ¾3øÌ›56k öí;Ûw†‚Ž ^^ÄL50†1ŒÇ8Ç8Ç8èØ!°C \޽{9’Ì’Ì’ÌÀ*À*À*܌܌܌~?·ÁçŸ|òEòEòE ;,;,; FFF X¬X¬X ¦íLÛ™¶Ê)§üõï©ø‡=r}äúÈæ„Í › B£ÐÀ¼çóžÏ{>‚à#Pq­I"ùdr™\&äÈ‘ƒÚMí¦vÁOðü*Þ§¤¤2s™¹Ìœ_OUÿzîñ9Ïy^ñ~!GÈr@œ+Îç¾´Á<࿞*e?ûÙOÅsÞ`Pñv]]]9ÊeŽ Æ‰qb‡„CÂ!M–M–M»Oí>µû¾îõu¯¯{3Î8º*º*º*À)Nqê¥&˜`¯ÿaÿr×¾¼ª¼ª¼*tìÞ±{Çîpkõ­Õ·VCÈœ9!sÀ¯¯__¿¾b€×߬²øËÏ+Q‰J/ïŸô +@‹mÅ< xâ‰'pžóœÙMÙMÙMüÁo:Þt¼ _¯ýzí×kÁ±¾c}Çú ö{Š=`‚ ~i{¿¬ù/cxÅðŠáPå¨rTÃ%Ká¾p_¸ç8Ç©8^¾Eœ%Îg*„ ¡@ %”ðÛÇ5(P]èB——7ðóþ ‚ˆŠÇñÚ´7ho±«bWÅ®‚ã-·<Þ|úô=$“ÌyÌñ—ÆcLÅs¿G¿7ÿ©xÍ455áøãCŽe¥ËJ—•B‡>útèSã¦ÆMëöÖí­Ûë;­äM%L¦ Ó@HR…ÔŠÇË¿/ÿ¾ü{ÈŸŸ??><-|Zø´=iô¤ÑÐ\Ò\Ò\uœ:Nå-Ë[–·¬h×w¿ï~ßýšš iSÓ¦¦M…¨…Q £‚¼º¼º¼:xxx€vŽvŽv”RþIù'ß)¿S~'xzüéñ§ÇÁ_|»FvìAõ°êaÕÃÀ,Û,Û,72nd -:µèÔ¢SÅõlõlõl(S”)Ê^ºsI>K>K> ”Ê@e dŒÏŸ1´Úmø÷?îÊÍÊÍÊÍ ³[f·ÌnP5 j@Õ€ÿ>®åVåVåV š š šeš2M™¦âuÕPÕPÕP(__¾¾|=ˆ¡b¨ ª«ª«ª«P¾µ|kùV~½¶\]] éõÒë¥×ƒJ³*ͪ4 \» v ÐhT£QFÿuÿëþ×Áà ƒ/ ¾ÕNÕNÕN(ËÄ2±"GYRYRYlÿxûÇÛ?†[é·Òoý ¦ô6ênÔݨ;”'”'”'¼z{urêäÔÉõ9õ9õ9Hü<ñóÄÏ!þTü©øSPغ°uakðñ÷ñ÷ñ‡²Œ²Œ² PY¨,T N'ˆ@=Z=Z=Ô=Ô=Ô=@×U×U×Tö*{•=”ï,ßY¾TóTóTóÀ'À'À'¬s­s­s!jEÔŠ¨P£¨FQ¢?pe–g–g‚º¥º¥º%”=*{TöÊ–,?êTuª:”­”­”­þ¹ý#Ÿû³n“ˆ’ˆ’زj˪-«àêÌ«3¯Î„O">‰ø$Ú·nߺ}k/–/–/ÖwZÉ›N£Óè4:¸xìⱋǠئئØÒz¥õJëª*ª*ª*`Ó̦™M3è¿·ÿÞþ{!>->-> ² ² ²  Æ®»jìª8E^-¨ZPµ ²„,! nO¿=ýötH,H,H,€=z@Ó¦ LárË=.÷€ÇÓO<T6*• ؅؅؅@¿õýÖ÷[Ö3¬gXÏ€j[ªm©¶n»Ýv»í±Ç~û1(((]éJWˆ½{-öXåXåXå€ÏG>ù|fß™}göä ¹B®Ï<ðlxL÷˜î1lfÛ̶™ Ùk³×f¯_C_C_CðÜê¹Õóÿ¸¹J³W³W³×â^ È/É/É/çSΧœOì¾ì¾ì>D­‹Zµ®âRåTË©–S!) ) )Œ¡^ïz½ëõ†òŽåË;³Üg¹Ïr¡¡sCç†ÎP›ÚÔn)o)o)!Î-Î-Πʋʋʋ@¼/ÞïClnlnl.Tº[én¥»P×½®{]w`! Y!!!!!!`ýÜú¹õspëîÖÝ­»þŽËÐèÐèÐhP„*B¡à;Ìw˜ï°¿ÞžÝ»v#Àò¶åmËÛp+þVü­xˆ™3#f´QµQµQA“†M6iÔÔÔ ,–KÀcÇ Aû0öaìCN §…ÓPíLµ3ÕÎ@üœø9ñs@|$>W W W Tq¨âPÅJÊKÊKÊ¡ª®ª®ªšŽm:¶éØßϫ֪µj-<Úøhã£õ ëAÖ°_l¿Ø~1,:Xt2r2r2rÀ6Æ6Æ6Ü» v C…¡Âð5î Qò·J–>,}˜(Îrå:ËU§)¦)¦)D1iaÒ¤…úN'y[•þXúcé¢8)uRê¤TQì?¯ÿ¼þóDñËõ_®ÿrýKo<'žω¢¨Õ¢Zÿç±;QŸ‰ÏÄg¢ø?ϧ‹¢¨µ¢ö¥Ï%ˆ b‚(ê”:¥N)Šbg±³Øù·9æ,›³lÎ2QœÝuv×Ù]_zá‚xA¼ðt`¤8R)ŠºKºKºK¢(¶[Š-EQü^ü^ü^Åóâyñ¼(Š[Å­âVQŸŠOŧ/}>ULSEQ·N·N·Nó{æ÷Ìï)Š9ßå|—ó(îè¿£ÿŽþ¢˜µ,kYÖ²?0 ™b¦˜)Šâ8qœ8Nÿç’…(þÏãf/Ó:q¸NÅ`1X Eq€8@ Šâfq³¸ù¥Ü¿¼þKÎR]©®TÅ‹âEñâKÛ"‡ˆ¢î²î²î²(þÏ¢N/mç’xI¼$Šâ&q“¸é¥\ÿRë²Öe­ËÅõ ëÖ'ü çˆ9bŽ(ж¢­h+Šbu±ºX]¬8®“Åd1YÅÅâbq±(бb¬ûÒ¸-—ˆKDQLÅDQüŸK\¢(Îç‹ó+6SàPàPà ŠE׋®]Å“Lþ1Y[$¶Hlñrf‹Ùb¶(Š£ÄQâ(QcÄ1FÿçR…øëþ£Ä(1JÅ)âqÊK¹^3á—¿¼Æã+'®œ¸r"Ôú¾Ö÷µ¾‡± Æ.»,šY4³h¦ï”’·•ÆKã¥ñ‚W~¸òÕî¥î¥î¥°äÓ%Ÿ.ù¬+YW²®ô÷o¿´yióÒæðY¿Ïú}ÖÔÕÕaiêÒÔ¥©P¥s•ÎU:ÿa=ö°|ÙòeË—AùöòíåÛÁÿÿü€65ÛÔlSóÈ!`ã6U†*C•“&Mš4i’¾Sýq[?ÜúáÖ!ùjòÕä««¨v?×ý\÷s †Côò¯“ €WtëÀ­·À¦I›&mšÊ:”u(ƒþ»úïê¿ zô4è©ï”’·x\<.‡eÊ>”A»¹íæ¶› ~þ~þ~þàø“ãOŽ?Q¶Q¶Qöß¿}õQõQõQHù,å³”Ï@w@w@wœ—:/u^ F{öíýçÆ#y_ò¾ä} z¤z¤z®m\Û¸¶EGEGEÇWn^òmóÛæ·Í â â âarîäÜɹúNõÇe8e8e8AA³‚fÍÀÕßÕßÕŒ‚Œ‚ŒþÆ'õE*þ$]ª.U— Á;ƒwï„ýyûóöçÁ°ãÃŽ;~ø“„IÂTéJÞp}éK_˜ü|òóÉÏ¡ß÷ý¾ï÷=4 hÐôÕ›—HþŠ]»"vE@zrzrz2|Þåó.Ÿwyõv%i&À?H3T3T3ö¥îKÝ— çýÎû÷ƒI'užÔ/n¼¸±t3ŸD_ZÒ’– ˆWÄ+âA]K]K]ëÕ›•H^…ÁrƒåËAc¢1јðÛÇî$z%=ø_¨òTyª<ض|ÛòmËáºÑu£ëF0k÷¬Ý³vCãöÛ7–ß“è[sšÓqŠ8Eh>Ó|¦ùLß¡$ï:Å"Å"Å"ÐÖÖÖwýSQQGmx´ntºÑéF'PG©£ÔQ½]1RŒ#!eRʤ”IpqèÅ¡‡Bæ€Ì™~ÿsRð;”˔˔Ë`ãÌ37΄ðKá—Â/Á¬u³ÖÍZ©©©úN)‘üì—ÀZa­°õgêÏÔop ^¡^¡^« V¬æ×õÒ%oƒÍ› 6ƒúõê¿a-€7<@ €è:Ñu¢ëÀ7Ý¿éþMw(Ñ•èJt¯ÐðÏ˾k{i{i{Áâ‹O,>÷Ýï»ßwÿýIÀÿRêQêQêß¹|çò Ä÷ïßfÎ œÕ<ªyTóxõíH$¯ƒÂEá¢pÍ6Í6Í›¸vD!„ÀÅ7^Ü»fïš½k6”~PúAéPÒ§¤OI(¯Q^£¼”®+]WºJ_”¾(}%MKš–4ŸÎOçªÆªÆªÆPbRbRbºÑºÑºÑ›S/S/S/ƒ‚ü‚ü‚|P.T.T.³é’Þ+355…²Ø²Ø²X(®W\¯¸*:Tt´Ú m”U*«TV Jw”î(Ýb (‚rµrµr5”n-ÝZºðÁÍD3Ñ Š2Š2Š2 ð‹Â/ ¿ÍÍÍP+Ô µŠeŲb%%%@aRaRah§k§k§ÿ6¯*S•©Ê„‚'O ž@Y½²zeõ€Ílf3”Û”Û”Û@qJqJq ”l.Ù\² C C C@k¯µ×Úÿ¶ÝòåË7B¹¶\[®…*¦UL«˜‚l‘l‘lPjT«xYµ²jeÕ  ¬ ¬ T·T·T·~Û®®µ®µ®5/_<,FYŒ²ÆcŒÇ.r‘‹¿¿¤{~V*+••Ê`Ýüuó×͇ܒܒܘi2Ód¦ ØÚÛÚÛÚ¿úv$’×IñXñXñÔÕÕõæÏ+Ú\´¹h3ìY°gÁž×9¯s^gp?æ~Ìýœ~þùùç`8Ìp˜á0pŠuŠuŠƒÓ§ Nõ1ׯ\³—Ì^2{ ”Ô+©WR–å-Ë[–sWÏ]=wuÅâ>[3·fnͱ¦XS¬ …í Û¶ƒÁ™ƒ3gBí/jQû }ʛ˸̸̸ ®_¾ k¾\óåš/A8#œÎ@„ = òRä¥ÈKpîÇs?žû–*—*—*!x{ðöàíp±ëÅ®»ÂÊ¢•E+‹à’Å%‹KpÏþžý={0³7³7³‡æC›m>Ìæ™Í3›_ŸøúÄ×' CË-;´„üÜüÜü\pÒ8iœ4ðþñ÷¿rçäÎÉ;vìØ±cȼeÞ2o(ú¢è‹¢/`„ÿÿþ~7ünø]Ø×g_Ÿ}} ß¤~“úM‚;wïBuÖ£ÊG•*‡ÄQ‰£GÁnÃ݆» Áº—u/ë^\š\š\ º…º…º… //Ñ÷¢ïE߃6lØ€Ée“Ë&—AW_W_WÆN;iì$0{nöÜì9ìž´{ÒîI^7½nz]°¹osßæ>d—e—e—ÐJh%ü3 ¾ógJG•Ž*ßýý×ß ùyùyùy0­Ù´fÓšmÛ¶=ôR"ùcäéòty:h¾Ð|¡y¿¸,¶[l·Ø® ® ® ÐàLƒ3 Î@—¡]†v fáfáfáP¶°laÙBè¥ÿ•þW mö Û6„œ;9wrî€ò¡ò¡ò!Ô «V+ rkçÖέ å¥å¥å¥pÆåŒËH8p áLž3yÎä9`qÚâ´ÅiøIñ“â'é×£WfXÓ°¦aMÈMËMËMƒÞ ¼xè’Q%£J ZZµ´jiP½kõ®Õ»Â‹e/–½XŠDE¢"Üû¸÷qï)gSΦœ•N¥Sé`o½=ööÛ5¶kl×À>˜ðÁ¨¥©¥©¥ª%UKª–@qIqIq ´ÛÔnS»Mð~»÷۽ߎE‹8±§bOÅž‚ŸžøôħÑ8£qFc˜ÒkJ¯)½@öPöPöm=´õÐVpã8Æq øøøB§ÜN¹r¡ãÔŽS;N…ã#Ž8> ³ ³ ³`‹Ù³-f`°Ú`µÁj˜ØgbŸ‰} k·®ÝºvÙ²d?Tœºß:j먭£ÀîžÝ=»{ðé„O'|:¢ò¢ò¢òàú{×ß»þ„Î :N+N+N+àƒ ø`Œ 42¨bÙkq˜8Lü?f^|g €²€²€²øa÷»Ø =3zfô„©6Sm¦Ú@•ÚUjW©­ï”ÉŸc`e`e`ê/Ô_¨ßÀà a†0„}Â>aßK?o+´ÚB%ËJ–•,Áé¬ÓY§³`Öþ¬ýY –XbAø^ø^ø˜Ît¦ƒ&„ a ‹•ÅÊb!Î3Î3ÎRV¦¬LY GÝŽºuƒ”å)ËS–CqŸâ>Å}ô= o>í†[ ·‚B©P*”°êÇU?®ú6uÝÔuSW(P: t΂³à B±P,#ÁV+„‹òÈmå¶r[è4¬Ó°NÃàX±„c °Èe‘Ë"È”3(gABB¡ŠP+ÁJ°F #…‘}9ûröeˆk×8®1¤K9–r Ž <2:et‚bm±¶X L`@¨*Tª‚ì‘ì‘ì˜6l>T'U'U'AÝ_Ý_ÝbÖĬ‰Y^ݽº{½<%ó/‹Zbˆ!hkhkhkÀÓNO;=íñÆñÆñÆpl䱑ÇFBÉä’É%“+–Ž·ˆ·ˆ·€Jç*«tl"l"l"€‰Ld"ÐntT¨Pýþþyç U *P›7%nJ„”ð”ð”pøÜþsûÏíÁzºõtë鯼‰D/äåòry9hvivivé;Í+0Çs~ûØØ/Ëì¦BÊK?ÿeµ_Veûåõ_V[k@T¼ndidid ‰‰‰Ð¸Zãj«Á'Û>ÙöÉ6˜<#xFðÌ*ù}7¹ÉMð_å¿Ê,ÈZµ ‡‡?ìýaï{A˜)ÌfOx ˆ"ЍØè@‡ŠÕ{ïソ÷~øáô§8 º‘º‘º‘ðíøoÇ;Ôaê0uÝ„nB7z ½„^ ½«½«½ ÚõÚõÚõ`tÏèžÑ=0r7r7rÇcŽÇAã76ÞAãƒÆ‡)_MùjÊW ‹×ÅëâÁ f0àˆ#ŽüºŒ°°_Ø/ì¯è·bbb ¨}Õ¾jß—ÆE‡ЛÞô®è¿é2Óe¦Ë FíµkÔ†¦«›®nº—,.Y\=?êùQÏ@øHøHø4-4-4-€žô¤'«NÖj µ6´¡Íïïžw¦ÐžÒžÒž‚]ówÍß5bZÆ´Œi Ÿ›}nö¹ØÙÛÙÛI×ø%o8sssPTTÔwš¿Î¼y;óvp%áJÂxfýÌú™5–––@þÒü¥ùKA}V}V}  4¦Q¦Q¦QÝ#ºGtH“§ÉÓäPæQæQæQqÓX³ðfáÍ¡|iùÒò¥ý(ûQö#P|¯ø^ñ=˜Í0›a6Cߣðæ“Ëä2¹ ÊN–,; f7Ìn˜ÝÏ®ž]=»‚±¹±¹±9˜u7ënÖ´-´-´-àé¹§çžžƒìÙ³BÙó²çeÏ¡xgñÎâ°ÞþyûçA¹u¹u¹5x}çõ×w`QÉ¢’E%` jGµ£Ú’…d!Y€«^W½®zÓh§ÑN£Á}‹û÷-ÐlH³!͆@‘Q‘Q‘äzçþ?öî3.Šsÿûøg KïÒTŠX°#Fƒ{ï=ökb/±%±ÄKìF=±E,X£ÆŠ‚Tªˆ´¥Ãî^÷ƒCîsþ9'‰e™÷“äå3ß¹fa;s•ê™ÕÁ Ð Ð LË™–3-ê½ê½ê½PðEÁ_@n@n@n¨W©W©WAþ©üSù§ ärÉå’ËÐ( Q@£€²ccïÅÞ‹½iîiîiîPx¾ð|áy(ñ+ñ+ñƒ——HP$(Px´ðháQ0Œ3Œ3ŒÕ^Õ^Õ^¨y¼æñšÇ¡È¿È¿È.n»¸íâ6H8–p,áäßÌ¿™ríríríþËõyïWôÇ82ôÈÐ#CáböÅì‹Ù03jfÔÌ(pä2Èe¾CJ$¯Ç­·vÞÚ Zc­±Öü>ôûÐïÃWßïÛæXѱ¢cŲ?ùwòïäßë¬?°þ?rüÈñ#¨t¥Ò•JWÀ2Ð2Ð2\æ¹Ìs™Ï;>ïø¼#ÈkÊkÊk‚“¥“¥“%x¬òXå± êµ¬×²^K°¶²¶²¶‚˜ó1çcÎCŽOŽOŽXl¶Øl±,{[ö¶ì­ïÖøûʸ”q)ã:t̆˜ 1å]Ë»–w…n³ºÍê6 œ69mrÚVQVQVQ®MצkÁèK£/¾×X×X×XðZäµÈkˆZ¢–¨1³cfÇÌÕ÷ªïUßC_u_u_5÷5îkÜv?Øý`÷p¸ãpÇᤤ¤B‡= üòwÊßwCwCwC0ÿÖü[óoá‘í#ÛG¶{"÷Dî 044„<§<§<'°Þe½ËzT¬[±nźPèYèYè 666à½Î{÷:ø`ÉK>XŇŠ‚¤ÝI»“vƒj j j ¸7roäÞ< = = ¡Aå•T.{Dý$ïIÞ“<( * * ‚r.å\ʹ€{5÷jîÕÀµ·ko×Þe«.\8\ \ \ ÊúV¸-u[ê¶d­e­e­sÞüzCúuúÀé§1¨dPÉ !î=½÷ôÞS}§’HÞŒÍY›³6g ±ºduÉê}§‘üÓÝ1»cvÇLˆ1ÆcŒÇ ‘¿+Wþ®7ÜT×T×TW!šWm^µyU!¢vFíŒÚ©ïÖx÷¼·Â… {£öFí‚ÑõG×]ªºUu«ê¦ïtÉ›aàmàmà š)š)š÷`±Éß›ÜQî(w„-{ B#4Bóæw#îFÜ 0ªnTݨ:Ä,‹Y³ xÈCê»UÞï]°3agÂNøfú7Ó¿™= ÉûB»K»K» bRcRcR¡ÀºÀºÀ^tyÑåEx1鍓à¶ÏmŸÛ>`]ǺŽu°TX*,à¡ñÐxh@v[v[&Özkd/'Ðwÿåâõ‹×/^‡]wuÞÕ6\ØpaCp9ìrØå°¾ÓI$oWܸ!qC ÷ÀÞ{„yŠ Éû¢xañÂâ…0ÅŠÿøÞú{ëï­ùµÓŸZ£Ö¨5`ñÂâ…Å )ÿRþ% 04>ßôù¦Ï7éû,þyÞù;é½Ó{§÷†Ý‹v/Ú½zMî5¹×dp™î2Ýåo¼Ú™Dò*»8vqì^ /…—›†7 oúŸÛ½\SÅþKû/í¿„ê?Wÿ¹úÏúN/yß~fø™ágP3©fRÍ$øÆüóoÌAg¥³ÒY•mWH!…€é Ó¦7À¹ÿr©O€Þ¼³uÏtÏtÏ`Oñžâ=ÅPÞ·¼oy_h6¡Ù„fôN"Ñ/ÓΦM;CËî-»·ìF³fÍþýí[_o}½õu°km×Ú®õ?ŽDòg4Êi”Ó(<£<£<£~»*Ϫ<«ò üúûõ÷ëÿÇ÷/y½ÞÙàú¡ë‡®‚ˆM›"6Áàùƒçž*c•±ÊXßé$’wC¯&^M¼ üò7ÊßøÏ×-²-²-²¡…e Ë– ?(?(—žýKÞ/ / / ð{â÷ÄïÉïo×rRËI-'ý9ûsöçôúŸë+òÖç­Ï[{•{•{•Ðåj—«]®‚ÛL·™nÒòœÉÿÇm±Ûb·ÅÿŸ¯×ø©ÆO5~‚ÚvµíjÛýùýK$†²¼²¼²Ï}POQOQO¡ïpÉ[vƒÜ€Ò€Ò€Ò(xPð àw)îRÜJJJ ¤SI§’N Ù£Ù£Ù¥.¥.¥.àìì ÚkÚkÚkPâZâZâ "D>ˆö°‡= ðWø+üÁ šA5ƒj Z­Z­Z ªUŽ*Œºu5ê Æ:c±”^J/¥P›ÚÔÖw#IÞ6ííí(U8ªp-.Z\´J®”\)¹%ÝKº—t‡RãRãRc-EKÑÜ"Ü"Ü"Àº¶umëÚ`?Ý~ºýtxhôÐè¡èt º„²5[”½”½”½@µFµFµTÇTÇTÇÀpšá4Ãi`l`l`l†+ W®.q‰Kún¿/½qÇ}÷1ÜŒ»w3æ.œ»pîBP4R4R4Òw:‰äՈꢺ¨źb]±rúäôÉé‰!‰!‰!Ü6¹mr[H K K ƒôaéÃÒ‡Af~f~f>‚˜'æ‰y€:ÀSLêT§:ÈêÈêÈê€Á×_| ö‹ìÙ/‚}>û|öù€¸%n‰[@8á„S¶hP6Ùd5©IMà)Oy ²Ú²Ú²Ú`~Þü¼ùy°imÓÚ¦5Ø÷µïkßœœœÀ5Ü5Ü5\“\“\“ÀôŽéÓ;```ð›ýKÞ ýèG?(X2°d \/¸^p½l‰Äá‰Ã‡CêÊÔ•©+!mvÚì´ÙÙ*³Uf+P‡©ÃÔa 3Ôê >ô¡O<ñüú~Ä_|¡0¡0¡0ªR•ªÀµ”k)×R ¬NX°:ÀArÈ#<às>çs 2•© d ;ì°###°q·q·q‡rËu.×{9örì.w]îºÜ7™›ÌMVC¬†X £UF«ŒV|£|£|£¾/»Cïm¾aø†á vW»«ÝaZä´Èi‘¿™ÒT"y—QDäeæeæeÂcícíc-<ªþ¨ú£êicÒÆ¤ü‡ùó‚aeÃʆ•Áv¡íBÛ…àpÔá¨ÃQ°k`×À®888€Í|›ù6óÁ¨“Q'£N º§º§ºª`U°*”S•S•SA9W9W9 'N(œEW‹®]…r Ë5,×´‘ÚHm$ˆ‹â¢¸ÚXm¬6JÓJÓJÓ ä“’OJ>’j%ÕJªAáˆÂ…# ½$½$½žõ}Ö÷Y_xîñÜã¹6}lúXHï‘Þ#½˜˜˜I?“~&ýÀ®Ð®Ð®¼R¼R¼RÀ;Ù;Ù;<x4ðh–-[>pÀAßWïíÑ[ð"óEæ‹L˜^<½xz1L œ81jÜ«q¯Æ=}7ËûKý¹úsõ瑟‘Ÿ‘Î :/CCC}§{w 7á&Ü }Wú®ô]ðð»‡ß=ü®_¼~ñúExüôñÓÇOA6C6C6œ›87qn•ÛTnS¹MÙ7—/\¾pùì?·ÿÜþs0P¨ þŽË£žãç ¨oQߢ¾šœšœš Éw’ï$ß'yOòžäAÌ¥˜K1—àùÞç{ŸïU7U7U7¨Ü½r÷ÊÝÁÿ¾ÿ}ÿûàêê V¶V¶V¶ü:µ±äwL0ä^ͽš{+++àÆÝwoÜ…ûù÷óïçC~J~J~ ذ`;¼¶xmñÚ•2+eVÊ—ñ.ã]ƃÓ§#NGÀÔÏÔÏÔØÌf6ëû$ÿ<ÍÍÍxQú¢ôE)¤ÌN™2–$,IXÑÍ¢›E7ƒ¤EI‹’A©g©g©'”/-_Z¾üÎû÷;Õ'WŸ\}28Lq˜â0——ï᣽§ÖZwjœ+ôûÐï!lYز°e i i i•å•å•åP÷“ºŸÔýª6¨Ú j°ò³ò³òå.å.å.þ±}9DUQUT…Â>…} û@b½Äz‰õàÖŠ[+n­€ÛgnŸ¹}2b3b3b¡ÂÔ S+L…f÷šÝkvjo«½­ö60mjÚÔ´©¾ÏæÕ½õ@[W[W[Ì[0oÁ<¨9¿æüšó¡û­î·ºßÒwsèæKÍ—š/!ùVò­ä[àrßå¾Ë}PÞWÞWÞõý_S]S]SÁ†ÝvoØ _|üÅÇ_| Ê8eœ2ö}¼ïã}C‡vtØ®³\g¹Î‚áAÆA“NM:5é#ŒF0‚„ 7n€K'—N.@9J9J9Jß­ø×å-Ê[”·®˜_1¿b§'Ÿž|z2,/X^°êÞ©{§îh¼¸ñâÆ‹Á}¥ûJ÷•`¼Âx…ñ }§ÿú”Oùr›ä6Émî=º÷è\8uáÔ…Sp¯å½–÷Z‚Ë— . ýÚökÛ¯…:ñuâëăjªjªjª¾OâÍÑkµÆ5?j~Ô|8¹íä¶“Ûà‘É#“G&PiM¥5•Ö@ó-Í·4ßUݪºUu«@«@«@ Íh¦ï³øû)µ.µ.µ†Ä–‰-[ÂÃ+†W áZ»kí®µÙ Ù Ù h±¾Åúë¡IA“‚&`3Ñf¢ÍD}§ÿóÞzðòâ¬#³ŽÌ:3ëά;³.x”z”z”–mWª(U”* quâêÄÕ@A®µ®µ®5˜/4_h¾ì­í­í­!­BZ…´ Pú´ôiéSP ¦FL˜`ö™ÙgfŸë×®;þs»¢ÇE‹ÃÜÊs+Ï­ v[í¶Úm…Z½jõªÕ Â,Ã,Ã,aܘqcÆë®o¸¾öºîuÝë ®tºÒé Ø}c÷Ý7PkZ­iµ¦ÁwAß}ž <x.€äÉÉ““'C¹Är‰å¡{•îUºWÙ[go½œ|||¡5¨„-[¶Æ?düpŸà>Á}lHܸ!ðÃ?Èû  |dùÈò‘ðaƒ|Ø>Ö|¬ùXÍ›77CCCȨšQ5£*„U«Vb®Å\‹¹1ŸÇ|ó9GGGÖá[†oÚvÚvÚv°áîÂH›‘6#mÀ|~ÓŽ…õ ëÖ‡ä>É}’û@fÌ:™uàA¯½ôåYåYåY˜á:Ãu†+´Ý~tûÑ0hï ½ƒöòkï[±El[ übøÅð‹6'lN؈]»,vØ.³]f» ¾úíÐo‡‚¢®¢®¢.äÈrd92ðâ1ÄcÔ/W¿\ýr0.l\ظ0\¸&p ˜>2}dúš?lþ°ùCXÑaE‡ ßž~{úíÀnÝ_Còaʇ)¶çÛžo{;=v‚®©]S»¦B‹-6¶Ø&…&…&…oû·Còò΀#Ž8ý3úgôÏ€¶uÚÖi[~ þ1øÇ`Xî¾Ü}¹;|àþûî0`Ø€a†ù6ómæ£Î…Ï ž<‡c×]?vNN<9ñäDðwöwöw†ÅsÏY<[:¶tl DEÔ+Vò'™œ79oršÓœæ@#ÑH4píɵ'מÀþVû[ío+_¬|±2Œ0a8Â<z>ô|T¤"õ}ÿñ–mˆÙ³!FˆµK×.]»ôo?váØ…c ±&xMðšà²Ÿ1vÆØc…Xyyåå•—…ݺ?t¿mú´éÓ¦©#RG¤ŽB-SËÔ2!o\¼qñF!Ä,ˆYS¶Ÿøñ#âGÑÁ¡ƒC!b^ļˆy!ÄÇ]>îòq!Ö»¯w_ï^¶ý´±ÓÆN+ĪäUÉ«’…ˆ"BÑéD§N‘––&ĵA×]T¶ßäëÉד¯ Ñnv»Ùíf 4?h~Ð|! ­ ­ ­…8Þéx§ã„èúi×O»~*DáG…~$Dœkœkœ«í·_Ü~±wÞxw w†Þzg¨{òöäíÉB¥ÒFý~;ž :t*Hˆn»5îÖXˆüýùûó÷—½>|èð¡Ã‡ ±iƦ›füæßM†› 7â[×o]¿u"xIð’à%Bt¯Ù½f÷šB«‹ÕÅj!n˜ß0¿a.D—¡]†v*Dfvfvf¶—Ž_:~é¸útêÓ©)þ)þ)þB´>ÕúTëSBœÖÖÖ ¡nªnªn*Dþøüñùã…ˆvvv"»]v»ìv¯ð†.†‹áBÜȾ‘}#[ˆa®Ã\‡¹ ±Â|…ù s!ÒRÓRÓR…i"M¤½ßÉ+¹+BÄ®Ž]»Zˆ™>3}fú1É}’û$w!þõ Zß!ÿ·´/Ó¾LûRˆ9½çôžÓ[ˆñÕÇW_]ˆ;ï ¼3PíIíIíI}§”üQYNYNYNBlŽÚµ9Jˆü?òÿÈ_ˆ3çÏœ?s^ˆ ãÕwÊÿôöîÌe.s!Á.Á.ÁŒŒþÈ¢>/LJîg?ûV´¢X?²~dýžñü‹ç_ÛÙÎvPíRíRí³ŸÍ~6ûÌtf:3$·Jn•Ü ¼M½M½M/¼ðKKKÐ*µJ­²µÙÚl-È!Ä~±_ì/‹cµÌj™Õ2Hßœ¾9}3äDäDäD@RpRpR0¼uðÖÁ[?"Dþ(7§Üœrs@¶L¶L¶ ä#ä#ä#Àä²Ée“Ë`”i”i”Y6ŒFDŠH º]º]º]PÉ©’S%'¨º¡ê†ª èVЭ [P¹_å~•ûAåÈÊ‘•#AÞ@Þ@þßfÖúå„Ä`1X æ×ñÞ¿2à 3À<þ@á8FŒc@î"w‘»@VaVaV!$VH¬XŒ<0òÀHÈÙ•³+gØõ²ëe× XÇ:ÖâKÅ—Š/Átœé8Óq`kk[¶ï5Þk¼_Ãá¡GC†…íý¶÷ÛÞúŒì3²ÏHhÕ:«u(Ž Ç×ðþ–¼¿Œ/÷ðõðõð…¹6smæÚÀž{îK —.5„‰ê‰ê‰j¨fXͰš¡¾C—Iü"ñ‹Ä/`Y«e­–µ‚Š™3+f”îSºOé–=-{Zö|õãHÞ.«««¾aø†á šc5Çjް¥Ê–*[ª@·9æ|ÝÖt[Óm È'È'ÈßUmßÚTÀÙå³Ëg—‡Ï_<ñ<¯x^ñ¼ò~ð—_øŸ@=J=J= ¬7Xo°Þœà'øufÁ—·®_²žh=Ñz"äW˯–_­ìߋ֭+Z4¢Àt¥éJÓ• >Ÿ‰Ï@¶_¶_ö› wCî†Ü `-¬…µ#w#w#wpœï8ßq>tÚÙig§0~ÖøYãgÁÆ{lìVu¬êXÕ†2”¡@ ZÐâ7çùòÚGøkıH!…hÛ¬m³¶Í 4"4"4„?Õ2«eVËüí(ý(ûQö#¿>ëþÕ/½‚eßȾ‘}ó›¯E-j+YÉJ~í%/¼…·ðQCÔ5ÊfŒsjáÔ©tëÖ9 &ÚM´›hëG¯½~4X·8nqÄV±UlšÒ”¦¿‰9KÌ³Ê ±ÒV¥­J[ýù÷[øóðçáÏá»3ßùî ŒVVVA»Þíz·ë ЕЕЕÿ¥¹¢E´ˆ†ÂÝ…» wCQ—¢.E]€lä5L$¢ûD÷‰î(Š)Š)Š1JŒ£ ¤aIÃ’†;ÿvþmеӵӵû/û®®EQEQEQ žŠ§âéÏñ‡5  |Iø’ð%°·poáÞBÈ<‘y"ó'''î´î´î4”ƕƕÆAþ‚üù @³_³_³ÿÕcü»—S…Ý?tÿÐýЪY«f­šÁºªëª®« ‰×¯'^íñ'e=Ëz–õ Vy­òZå¾½}{ûö†qûhÜGüƒ_WWWWWò‹ó‹ó‹¡$³$³äüþÿA/G”Ô-©[RÄD1QL„Bu¡ºP … 6 0à¿ ÖTÑTÑT’ê%ÕKªW¸Âù{ÿ'‡‡‡ÂÙîg»ŸíÇçŸ|>”¨KÔ%j(ö*ö*ö±T,K¡xJñ”â)PàVàV຺º¯/ÏË>d 6<Úð(L}0õÁÔpúðéçÃù3çÏœ‡F³¼½ ;;;;›_;ÍY…X…XýÎ+b’˜$&A\j\j\*¯ ^¼2Úe´Ëh-í[Ú·´/›É*ëRÖ¥¬KV”V”VT¶ŸöÛ7nßÒ|Ò|Ò|àLè™Ð3¡p$ôHè‘P¨ß²~Ëú-¡Ri¥ÒJ¥ Qj”%Ä}÷QÜGp:ïtÞé<Èj›Õ6«-´ÜÛro˽àìì Þ—½/{_† þAýƒúí鷦ߚ©mRÛ¤¶ô¾é}ÓûBv³ìfÙÍ é|Òù¤óeù¬|­|­|!»OvŸì>p6õlêÙT(t.t.t†ºßÕý®îw`‘d‘d‘nSܦ¸M£vFíŒþË„h&š‰f41ibÒDx±èÅ¢‹ ñEâ‹Ä^-½Zz5ȘŸ1?c>$?J~”ü’û&÷Mî[ÖY2Ù/Ù/ÙT-U-U-!«vVí¬ÚpzËé-§·€›‘›‘›x¬ñX㱂<ƒ<ƒ<á–ú–ú–ž9|øÀ¼‰ó&Λé¡é¡é¡pûèí£·Âð¥Ã—_ ÷.Ý»tᅩ?¾ßá~‡û`Þ¤y“æM‚ÌÄÌÄÌÄWÏ÷ï¢ûD÷‰î{›ím¶·ì3Øg°’Ö$­IZŸy}æõ™ÄZÆZÆZÂÓVO[=mçœÿq>œÝqvÇÙ¯?×Kò>ò>ò>Ð-²[d·Hðëî×ݯ;ì²Ýe»ËŠ ‹ ‹õѧ㗂ÿÀŠ+¬—±.c]ÆÂ`»Ávƒí@å«òUùþñÝeÎ=æLœ3qÎDØ‘»#wÇk\,-H¤RÃÚfk›­mùC󇿅#Ž4:ÒÆM7mÜ4Ⱦ’}%û¿| />^|¼ÖnY»eíÐÔÔÔÔÔ|ýÍ{vÛÙmg·Áe×Ë®—]A¾L¾L¾ n6¿ÙüfsX¸eá–…[ kZÖ´¬iðóÏ?ÿüóÏ0lÀ°Ã”ÍŸð¦Tm^µyÕæ0ÆxŒñc8zñèÅ£á©ùSó§æoî¸Ô[{ ž§ž§žªïUß«¾Ã†= {ü´Æk %-i &æ&æ&æ0Ñ|¢ùDsðêëÕ׫/())Á¬àYÁ³‚Á(Ò(Ò(²l7õ[×o]¿5X·µnkÝ’‡'OµzÔêQ«T›Wm^µy`4Üh¸Ñp¹"Wäòko$SSS˜”1)cRxòä=dŸÈ>‘}3ªÏ¨>£:ܯ¿þýú ë¯ë¯ë¢›è&ºj»j»j;ÌVÍVÍVãeÇËŽ—AWCWCWj©q¤ÆX([([(mKmKmK ˜bŠÁ°ža=Ãz¨Tª¡á' ?iøÉÿn>Í*Í*Í*¨=²öÈÚ#Á¹šs5çj`xÜð¸áqÐÕÔÕÔÕ„±qcãÆÆqœqœqhNhNhNÀØÇc} ¦L˜oGoGoGXðdÁ“O@ç§óÓùƒÒAé „g4žÑî—»_î~9ÐÝÑÝÑÝñ¡øP|†¹†¹†¹0g朙sf‚s˜s˜s/á%¼ÀBg¡³ÐÁÐ>Cû í†W^a8P Tøßçûcê©?¦‚{#÷Fî Ð7Ð7ðOü}É Û Û œ®;]wº!“B&…LÝ÷ºïuß¿úïƒë<×y®ó wýÞõ{׫VV­¬ZA•§UžVy ™¶™¶™¶P0¤`HÁHl—Ø.±DýAô87pnà\pµuµuµ…Þ^½½z{ùróåæËù_=çK1þ1þ1þ±*cUÆ*è0§Ãœs€³œå,ô:Üëp¯Ãàt×é®Ó]0¯f^ͼ”š•š•šAæžÌ=™{^_žß#O–'Ë“¡×Ù^g{…Eb‘X$àêý«÷¯Þ‡¦u›ÖmZ÷Íçx)jpÔà¨Áð0ñaâÃD˜uiÖ¥Y—@UEUEUåÏïÏf„Í›`¨4T*áùØçcŸ¥ìè+ªëPס®x{z{z{‚YM³šf5Á³ŽgÏ:°óãïü´K´K´Kàæ…›n^ƒŸ ~2ø j¨u¢Ö ¨R7¤nT6«lVÙ ö´§ýëkßÇn»q Ì/™_2¿í[µoÕ¾¼Hz‘ô" L˜40i–“-'[N†*±Ub«ÄBÚ–´-i[ (º(º(š_ïp½)u;×í\·3ÜKº—t/ 7:Üèp#˜”2)eR ÈœeÎ2ç7wüßóÖ €‚ùó æƒ²²²²²2<6xlðø¿üÀ.v± 455Ás”ç(ÏQp-àZÀµÿÜÜ÷¨ïQߣ¿>1ø²Ÿe?Ë~.ûøëÁ¿5õË£í<í<í<(?»üìò³!`VÀ¬€Y¿×!Ê!Ê!ê¿Ì$ùË~ÛІ6ÿÇËF-ŒZµ€Æ4¦1 ‰×Äkâ!bhÄЈ¡PúséÏ¥?ƒUºUºU:ThZ¡i…¦”Í™ý; jÔ2¨uoÔ½Q÷Æo^˜ÉLfþ&ÿ¿çîD':;î¸Ld"¿çú2ç¯6° e½·_þ÷÷ÚÁ 'œšÐ„&À#ñT¨PþøãÏ—U>«|Vy¸t#èFŒí7¶ßØ~ ·—ÛËíÿÄŽþ¼³¼³¼3¤ÏJŸ•> NL91åÄÈËËËË˃:ª:ª:*0ò5ò5ò…ó¾ç}ÏûB»vì ÿ«ü¯ò¿‚ ¾|/øBÇÕWw\ Õ ªT‡[Q·¢nE㇎:~ …d+d+d+ ¿~ÿüþ°áð†ÃClilil)X(, 0;kvÖì,Üš{kî­¹`•a•a•áׯ…_ƒÒ’Ò’Ò0¿e~ËüVÙ0ÔŽöí;Úƒ½»½»½ûïŸ^H^H^„{†{†{£óÎ?:÷]Üwqxß÷¾ï}î<¾óøÎc0Þn¼Ýx;T «V5 dÍdÍdÍ@ÖFÖFÖ°Å[ˆôôô‡ˆ*U"ª€ò åÊ/ Yf=šõÇ«ŽW¯þõëfÖÒ¬¥YKh\¡q…Æ ¤RH¥JÐøÓÆŸ6þäíåíå¯ñƒè÷„L ™2j^ªy©æ%°7´7´}~m·õ}ê ÝÜ»¹ws‡'¾O|ŸøÂÓÊO+?­ ^Î^Î^Î ûJö•ì+Ÿ”Ÿ”Ÿ„¤¥IK“–ÂÒ K',Ï<žy<“Ù&³MfóÙÏf?› I½’z%õ³D³D³D^¼>x=8w8îp &L.˜ ÊéÊéÊéÐñnÇ»ï‚a[ö†mÿô“Û'·OnQùQùQù`ÜÁ¸ƒq/^>¼<(ý”~J?¸p+àV¸}êö©Û§ ›#›#›²ë²ë²ë ‹“ÅÉâ@‹` ¯]¼vñ<ÝñtÇÓ`Óɦ“M'h1¾ÅøãÁd€É“ý²fffÀÂ¥ —.\ É^É^É^àšïšïšÿæßÿî­=(6,6,6åååPÎTÎTÎüýíÓ;¦wLïå¾+÷]¹ïʾçç翹œé é é `÷Ýwv߯Cã¡ñõõõŽ·ÕZ Ü…»p‡ÐâÐâÐb6(l4qjâÔÄ •••_ý8ï‹Ô ©R+€ÖJk¥µ‚òËo,ÿžÕ¿ì«`æeæeæ5ª×¨^£:؅څڅ²šËj.« é Ó¦7„ïµßk¿×BB„: uÀr†å ËpðöÁÛoC°„a ÃÀüˆùó#°×j¯Õ^«²©Jåqò8y°–µ¬ã>Æ}ŒûS™ÊT°mgÛζT\UqUÅUeì{ëí­··¤N?œ~îL½3õÎT¸ñãoü¾Ç|ùƒ«?_ýùêÏpèÆ¡‡nüïó7íiÚÓ´'8Ç;Ç;ǃM›þ6ý¡rÏÊ=+÷„rË=,÷N(O(O(á¶ÿmÿÛÿGå&·‘ÛÈm álÂÙ„³ðuÎ×9_ç@ÅÛoW¼ Y¡Y¡Y¡°®ûºî뺃¶²¶²ö5¼¿k/¯½¼örH©–R-¥<Ïžÿü-ü¡-¨\P¹ 2Äuë×|?õýÔ÷Ó×·YMYMYM(·­Ü¶rÛ ®¬®¬® ²²²`uÉê’Õ%Ý<»yvsغ;uw*”4/i^Ò´»´»´»à» ßUø®”¶)mSÚJ®–\-¹ ;»ïì¾³;äÏÈŸ‘?d!²Yˆqbœ#-FZŒ„¢ÁEƒ‹CE³ŠfÍÀuë×5Pt¿è~Ñ}Ø‘º#uG*L2Ép|Éñ%Ç—@æÎÌ™;ÁÇßÇßÇvíܵs×NoÞ:¼õÿ>›i6Ól¦­ÖVk«-›¬ÂŽ ;*ì#c#c#cعcçŽ; íQÚ£´G ß*ß*ßZ¶Ÿ—wŒB:†t éß÷ý¾ï÷}¡ö‚Ú j/€Ð¸Ð¸Ð88bÄþÈ+|‘xÉq‰ãÇ%`»Èv‘í"¸wøÞá{‡_ë[ïOyk€ÖNk§µ¥Ò@ ò¶ò¶òÿRáÙ±;bw¾¬úeÕ/«ÂTÏ©žS=Áò¼åyËóü¸–ÝgvŸÙ}‹k-®µ¸LI˜’0%,--Þboq…Â@SÚOi?¥=Œ?~üøñàxÉñ’ã{8'õ«Jߘ¾1}#˜Æ›Æ›Æƒ‰»‰»‰û«ï÷å-î—•¿n¸ƒ<ñÄbbbÀHf$3’L.“Ëä`Ù˲—e/PuVuVuY®,W– j µ…Tþ*•?pŠSœ2É$8ÎqŽƒÊIå¤róJæ•Ì+ÒFi£» vì&€¥°– nÜ2¸2™¬l)ÓOM?5ý*\¨p¡ÂpKqKqKäÛÉ·“o—Í…~/ã^ƽ ¸«»«»«ƒGµÕzT d² YØö²íeÛ ÌW˜¯0_._»|íò5X\²¸dq Œ…±0 {${${ôŸÍ¨U„*Báþ¤û“îO‚gâ™x&À±Ø±Ø±lkÙÖ²­·ÜZpk¹¹½†ëgZ×´®i]P,Q,Q,»»»WßïÿRr¨äPÉ!(j]Ôº¨5XtµèjÑõ5à—éVÝ­º[u÷ZîµÜkAÏžµú×ê_«?¨Uª@xñÙ‹Ï^|¹›r7ån‚HûHûH{¸»íî¶»Û i{Òö¤í`Üĸ‰q°¬gYϲ”Ë.—].l½m½m½Á²ƒeË`gg÷›ÎÜ9äSÖŒ²Á²Á²ÁpiÄ¥—F€Aƒ ÀvŸí>Û}`tÍèšÑ5¸Yp³àfÁ«_6y y y °x`ñÀâd6ÏlžÙüÍ¿Ï[{ðò߯½¨ÿW¯Ð—½åß¶Œ`ī捻°¤°¤4­5­5­Á$Á$Á$xžü‰½þ(ù¯LMMËzý–î-Ý[º”(_íMþËè qFœg€ñŒg<(3•™ÊL-ÿZþ5h:h:h:€,\. Ù:Ù:Ù:~5ñÊäÈ‘å(G¹?°ý/}G¸Ë]îRöÌÅC AV_V_Vr,s,s,áPíCµՆ… ‚ãxÇñŽãaBð„à Á” ýåέiÍø¦ö’l¼l¼l<”4(iPÒr:ætÌé7ß<~ó8hzizizAÿaý‡õªªª¯ÞlZs­¹Ö´½µ½µ½ÁÐÕÐÕЕ7>U®¢¢¢(‚AŠ (ù¸äã’ùÏÑ?U.¹äþæ}ù ÕmÕmÕm·Åmq´3µ3µ3v´£e ]ã×þâ±ËcŒ)ë«õ{^Ž«~Á ^±Äò›a¿Øc}Ù#»ÇvíÛÁ¾ƒûî;b›Ø&¶Ÿ±Ÿ±Ÿ1¸uê:H#´²Oÿ,YYY(ü¡ð‡ÂàyÁó‚çpõÜÕsWÏAÅ›oV¼ îGܸºÐ….½¹D±(ÅPÜ¡¸Cq0 1 1 áOÿ>½.o¯x.{.{¥~¥~¥~ »§»§» ¼ÁN˜o]Öò¬åYËañþâýÅð¯ n`ŒÇ1`ÿåçsãsãsã!r^ä¼Èy`ÑÍ¢›E7¨Þµz×ê¯óÄ{ÆQã¨qÔ@IQIQId,ËX–± \wºîtÝù ;þåƒ÷×?´¿tNx\ø¸ðq!×)®S\ª-¬¶°ÚB8¼åð–Ã[ È£È£È„¹0æ œ…³p¡j¡æ×W´-EK‡ÅaqÄ'âñ ˆKâ’¸â”8%Nì¼ì¼ì<¼(xQðtž:O'ˆ©bª˜ Â^Ø û²áN/ÿ Šeb™XƯ`ÄP1T mž6O›å:”ëP®ÌN:;•_ïÈÊÊ–5ƒh#Úˆ6e£Å^ÎÃ@2Än±[ìÝeÝeÝeÉ"Y$ƒˆñ"tN:'TjT©Q¥FPº­t[é6èÒ­K·.Ý@Y ,P}éKßW¿lEEEîŸîŸî½*zUôzóïÇßóÖ UmUmUmÐÆiã´q } } }nnnúk€×-4?4?4âuñºxŒté<Ò +V4üSA*§(§(§À±ùÇæ›%á%á%á°ŠU¬Ò÷ɽÜ>wúÜéspûÈí#·àÆÐCo W\q}…ýV¸^áz…ëàâëâëâ » wî*„LU¦*S½ì{Ù÷²‡zÕû¨ÞGX?°~`}8p&àLd÷Íî›Ý,W[®¶\ éÑéÑéцM ›6…‡Ë.¸´Úm•7*oTbbb Æ±ÇjƒÝ#vØ=öÛ?nÿ8p©ìRÙ¥2­4Zi´Â&„M›Ï}Ÿû>÷e¾2_™É#’G$€\Ó\Ó\S tÒ!W“«ÉÕ€ùóæþóü‹lŠlŠlʆ-½5 j@Ô0¾k|×ø.ˆF¢‘h‰Y‰Y‰YpkÈ­!·†_ð_@bnbnb.N œ8 Z}Öê³VŸÁ&—M.›\À}©ûR÷¥P#»Fvl¨Õ½V÷ZÝAVOVOö ñ…øB|\\pqÔû¹ÞÏõ~“Z&µLj½ù÷£²·²·²74Ûhl£±pÅëŠ×/ܸ'p¨ú«ú«úÿõý×I¯“^'nÙÞ²½e [ý·úoõ‡´®i]Ӻ¨®£ºŽê •ÆV[i,T¯T½RõJ°oð¾ÁûƒyŒyŒy X=±zbõžœxrâÉ xxöáÙ‡gÁ0Ü0Ü0ÂcÂcÂcàÙžg{ží£<£<£<ˆ_¿"~|¨ùPó¡B†‡ ¶¶¶ò]Êw)ßá|Ãù†óá” S.Lá×ÎÄ/†¾úb(Ä.]»d‰²DY"dTɨ’Q´´´@q[q[qû?ÏÿYè³Ðg¡›—›—›º*º*º*ðäÚ“kO®AìúØõ±ëÁx·ñnãÝp/ô^è½P°±±“Y&³LfAL˘–1-¡£OGŸŽ>ðbý‹õ/ÖÃê뫯¯¾å{–ïY¾'øòä?*t¨Ð¡B‡¿~Ý„Ƈ33³7ÿ~ü]okÊÁð»áwÃï 1~ÄøãG‘;+wVî,}O„øú}uù«Ë_]bì¼±óÆÎ¢àQÁ£‚GBˆþ¢¿è/DáñÂã…Ç…Èž3˜ôÁ¤Êþ½ô|éùÒóB¨k¨k¨k‘W/¯^^=!t:CÙvÚ0m˜6LˆÜª¹Us« ‘7 o@Þ!tStStSôÝJoNÔ¬¨YQ³„ï6Þm¼› ½z'ôþëûӭЭЭ¢àXÁ±‚cBäÜ̹™sSˆÜ‘¹#sG ¡½ª½ª½Z¶}é¦ÒM¥›„ȹ”s)ç’ù5òkä×"73737Sˆ¢EE‹Š Q4¬hXÑ0!ÔWÔWÔW„ÈÍÍ¢HV$+’ ¡ÎRg©³„(¸Up«à–Z/­—ÖKõõõ!rÏæžÍ=û›ícÔ1ê!òÖå­Ë['Dî”Ü)¹S„ÈÛ“·'o¥;Jw”î({ä]λœwYm¶6[›ý_΀n€n€ùæùæùæB¨×©×©× Qܰ¸aqC!JìKìKì…ÈuËuËu+Ûï¿&Ø"wTî¨ÜQBä×ϯŸ__]{]{]{!41šMŒ9wsîæÜBÝPÝPÝPˆ¢Œ¢Œ¢ !þ5#æ_¿n×÷\ßs}Ä1A‘ŸŸÿ–ߌBˆ¼ayÃò† 1cÜŒq3Æ qjÅ©§V¼ú~5©šTMªy1y1y1Bä É’3Dˆü”ü”ü!D;ÑNüf í¢öEí‹Ú ‘“™“™“)DþôüéùӅȳʳʳ¢Ä¸Ä¸ÄXˆ‚îÝ º ¡>§>§>'DáÌ™…3…øWo}!Ô±êXu¬ÅTü‘¥—~\ú±ÙÁÙÁÙÁe?_У GA!ÔÕՅȋʋʋB­ÎVg Q^^.DÉý’û%÷…È5Ë5Ë5¢PU¨*T !ºŠ®¢ë9ÿÖšÖšÖBävÊí”ÛIˆÜɹ“s' QêQêQê!Da\a\aœêÃêÃêÃB +V0LˆÂÕ…« W ¡ŽPG¨#„(œW8¯pžb»Ø.¶ Qü øAñ!²ó²ó²ó„Èý(÷£Ü„(V:¬tØ_¿^s2ædÌâÓíŸnÿt»¡³Bg…¾Ÿo­ˆ&šh„U8ªpT¡Ó2¦eLÓ÷é¿>i¶i¶i¶B ¹7äÞ{Bü«Ž§/Ÿ¾|ú²ÆÆÆB¬µrÔÊQB¬¶jتaBL2yÈä!B\éx¥ã•ŽeûûµÈ™”3)Gˆ‚ ±ºùêæ«› ±8pqàâ@!oZ¼iñ&!âìãìãì…Ðøj|5¾BìÙºgëž­B,öZìµØKˆù‡æšHˆÓÕOW?]]qPõÝjoÀ1D âÛ-ßnùv‹Ó¢§EO‹"c@Æ€Œú'yÓb£c£c£…]ytåÑ•…8åü•óWôJˆˆví"Ú 1lÁ°Ãîîî£ïT’7­ \A¹‚rB|!ûBö…LˆÝVt[ÑMˆ’oK¾-ùVßéÞb:$uHê!†UVeX!’ÔIê$µ¾Oÿõ[eºÊt•©jL¨1¡†º(]”.JˆÒy¥óJç V¶ýâé‹§/ž.Äô^Ó{MïUöï/ €O|>ñùÄGˆ§§'!>ðÁ€ñSÂO ?%‘ôCÒI?¡¶P[¨-„ˆÜ¹!rƒÝ ºt7"¥0¥0¥PˆÐ¡C ÑË«—W//!Ô=Ô=Ô=ôÝZoN¡A¡A¡_•ÿªüWå…˜VeZ•iU„HŠLŠLz…o–’wÌqq\â^À½€{BŒh=¢õˆÖBìÞ¼;XÑEt]ôRQ*JE©§ãNÇŽbÐ…A]âç.?wùù]È'y­²¿Îþ:ûk!- Z$Ĭ泚Ïj.DV\V\Vœ¾Ó•ykí’­’­’ÁÈÖÈÖÈÒÓÓÞÇEX^ö®ýe”ƒ¬š¬š¬”jKµ¥ZÈLÉLÉLïC¾ù>î}¸÷á^(^_¼¾xýîî_8ÀFa£°Q@Ã1 Ç4_îürç—;aÿäý“÷OÍ"Í"Í"H»‘v#í$^H¼xBN„œ9·nÝ6‚By¡¼Pš4?h~Ðwc½9F%F%F%0Öf¬ÍXpvqvqvµÔ^PÂv‡íÛ b­X+Öê;­äÏÒ<Õ<Õ<…“óOÎ?9,XË—.ƒ>gûœís8ÂŽè;-¿Giýeë/[ “& L‚oF3ú›Ñ°/|_ø¾pø×-w}‡•üi;ØÁxèõÐë¡ÌýxîÇs?Ý:Ý:Ý:˜:5tj(XU²ªdUéUöú¼µN€FÁFÁFÁà`à`à`ñAñAñA¿v:}ü2,F6\6\6œ_{¹žH:‘t" ‚F  s.Ϲ<ç2ÜYygå•ÿSþOù?ÝèF7À#Œ@ì{Å^0J2J2J‚iݦu›Ö ž4~ÒøIcX0dÁCÀ`‰Áƒ%PGWGWGVÑVÑVÑPí†[ 70»gvÏìt+ìVØ­,?°üÀò}7Ö›gaacŒy0æœr:åtÊ Öú¯õ_ëþ]ý»úw…nÚnÚnZpT8*ß§a)ï‹_¦j¯_7¾.ìMØ›°7‚‚‚`Læ˜Ì1™Ð ²AdƒH%ÿJþ•¾Cÿ¶²•­e£íSíSíSaóÍÍ77ß„ˆ&M"šÀ€v ؾC}‡útèÐé;¼äßeOÏžž=އ= g‡žzv(´8Úâh‹£ÐKÙKÙK ÆZc­±VßiÿÓÛ[øå”?Pþ$œJ8•p ½|Ý^{QQQì´ì´ì´²‰@ò&çMΛ ÿêlS6Á„â™â™â$$$CQ\Q\QäžÎ={òä5ÈkO—>]út)œ9pæÀ™ÐêT«S­N§‰§‰§ (z*z*zB¥é•¦WšNQNQNQ HP$(À·À·À·,®X\±¸òhy´>øø Ü5¹kr×âžÄ=‰{Å{‹÷ï…Š… +‚ß¿3~g ¶Sm§ÚN`]ɺ’õ;ÔYê]“×"¯E^ ¸;é“àºúºúºbT1ª(Ž)Ž)ŽAÅJ+U¬¾æ¾æ¾æàyÕóªçU°Yk³Öf-X|eñ•ÅW _-_-_­ï³z.r‘‹P´£hGÑȪ—U/«¤Z¤Z¤Z@dxdxd8D_Œ¾}Ò»¤wIïR6scÝ)u§Ô~ƒüù ···…ÊBe¡ú>¹×ç­/íܲsËÎ-’’“÷MÞ7yŸ¾›C"ùc^αžÕ4«iVS87ôÜÐsCae½•õVÖ׎®];‚}¤}¤}$´5hkÐ\]]]]]ÁÕÊÕÊÕ œk;×v® ®«]W»®»-v[ì¶€ê–ê–ê(›+›+›ƒb–b–b(F(F(Fw¸Ã×p"¿L±*¢E´ˆÝ0Ý0Ý0Ð4Ö4Ö4MŠ&E“E]‹ºu…gGžyv’Ï%ŸK>)Q)Q)QØ1±cbGH]™º2ueÙÜû– K…¥¼;zwôîÕ½ª{U÷Ÿ(Ÿ(Ÿ(°øÔâS‹OAî+÷•û¾úéüS‰(%¢ Ï$Ï$Ïä×Õµ‰4‰4‰4‡AƒAæðÌá™ÃAž*O•§‚ýXû±öcÁí¼Ûy·óà4ßi¾Ó|péçÒÏ¥8×s®ç\Œ2>J;¥Ò”ϔϔÏ@¢Q„€lšlšleëy¿ªÉLf2èÎèÎè΀f·f·f7h²4Y𬲵>2/f^̼I“'=†”Î)S:CòÕä«ÉW!áQ£„GPpºàtÁi0Üf¸ÍpTÔUÔUÔAµgÕžU{¾|ø>{/{/{/PF)£”Qú¾ªožÞ €;#3¶¶ÚÚjk+XâºÄu‰+˜60m`Ú@ßÍ"‘ü1ÖÖÖ°)|Sø¦p¨ä\ɹ’3 \>pùÀå ]¯]¯]©­R[¥¶‚h]´.Zəəəð|ÛómÏ·zŒzŒz h?Ö~¬ýŒ<Œ<Œ<ÀÄÀÄÀÄŒ4:†} ûösss0«lVÙ¬2ùùù‚ÂEá¢pÃ}†û ÷n•n•n”X–X–X‚ÆNc§±ƒâÖÅ­‹[ÿfJ+ûFY²®d]É:(\8¸ppYçÔ’ %J&€Aƒ>}ÀÊÇÊÇÊì¯Ø_±¿î'ÝOºŸ¯Æ^½ƒÝ@»vÁv·ínÛÝ Z¡Z¡Z¡ï«õÏ¥1Õ˜jL!smæÚ̵ðâð‹Ã/Cì´Øi±ÓàI«'­ž´‚´eiËÒ–Af‡Ì™ ¤sIç’Î`ðÁ7߀ÉI““&'Á¸Ä¸Ä¸ 7n0ܦN¦N¦N`žjžjž F±F±F±`0Ò`¤ÁHPE¨"T HS¤)Ò ¸mqÛâ¶e‹@[[[@þóüçùÏ!÷aîÃ܇PdXdXdE_}QôÎ)œS8 s s sA–)Ë”e‚Ù:³ufëÀ~¤ýHû‘àlàlàlÞxã 8pà<lÛ>¶} f×Í®›]ç×á{ÿTz+Š,‹,‹,aFÇgt„þû?ìÿüÂüÂüÂôÝ,Éÿ­dVɬ’YÔ5¨kPW8,‹ÃºÎï:¿ë|èÕ)ªS$$$üïý‰ùb¾˜ÿšÚ2µ™ÚL-äTÉ©’SrLrLrL ïEÞ‹¼Pж mA[È]—».wäÉ;“wŠÌŠÌŠÌ@g¯³×ÙC±w±w±7Ⱦ–}-ûT ªU(Rþ¤ü ŒÎ1:æÎæÎæÎ`¶Ûl·Ùn0Ùa²Ãd˜™™å Ë–7ÀÒÆÒÆÒloÚÞ´½ &-MZš´6±‰Mú¾*’׿ 9E?ýXô#d,ÊX”±rå Ê9n9n9n ^¬^¬^ ŽŽŽW’W’Wy#óFæ„«…W ¯‚ö¡ö¡ö!D÷îÝböÅì‹Ù­´>Ðú¨t*J†™†™†™`šgšgšæýÌû™÷Óê¦ÕM«ƒé.Ó]¦»Àršå4ËieØ­G[¶ –-[>ù ù ù }7âß‡Þ €—¶šm5ÛjÅŠ?‚>vúØIßÍ"‘üÿ2§gNÏœ›¯m¾¶ùÄ;Ä;Ä;ÀØø±ñcã¡VX­°ZïBáúË*qÔ¦6µ&4¡ e«üý²°Dò6]´¼hyÑÎŒ?3þÌxX´ hA(#”Ê}§ûçzk3þžTlP:?t~è Ù‡²eÒw*‰ä_î÷¼ßó~Oø,골Ϣ 8¬8¬8 4^ÐxAãwèƒÿ¥—ãà‹)¦8ÃÎ }ðKôë—å~™Â¦ ïP½Þ¼+xWããÆÇÃí;·ïÜ~›$’¿@ë®u׺ÃIï“Þ'½aIÌ’˜%1Ðàhƒ£ ŽÂŒ~3úÍèNãœÆ9ÓwZ‰äo¢”RJ<òÈÓwÉKz/TÇUÇUÇáà nøpœ¯q¾Æù i¦i¦i¦ït’ µ½Ú^mk£×F¯†ïݾwûÞ Æ&M›ýÕýÕýÕ`¸Åp‹á}§•H$’W§÷ॆ .l¸2Š ›}6(¡„}§“¼/^ŽO?ûüíó·aþ£ùæ?‚jŽÕ«9ÂÜNs;Íí®>®>®>úN+‘H$oÎ;S¼¸5pkàVˆéÓ9¦3$}šôiÒ§úN%ù»+Ø[°·`/li¹¥å––°+{Wö®l¦¦¦†!û†ì²LBLBLBôV"‘HÞ¼w®pïçÞϽx^ð¼ày‚·o ÞªïT’¿«DÏDÏDOX˜¿0a><²{d÷Èæ­˜·bÞ hêÜÔ¹©3ÈUr•üuÌ`&‘H$ï\Ànv³ÚŸi¦ý¸VñZÅk!éIÒ“¤'ú'yçýÒÛøFíµoÔ†ùæw˜ßœ¼œ¼œ¼`þÄùçO„JA•‚*é;¬D"‘èRß~ÏTŸ©>SÁûCï½?„ã1ÇcŽÇÀ˜ c*Œ© ït’wMÉ ’A%ƒàhç£v†cãŽ;6úú÷õïëmk·­Ý¶6(J¥ŠR}§•H$ý{÷îüB¦”)eJèâ×ů‹„>žÜ}r÷É]}§“¼+2K2K2K`eÎÊœ•9pþÅùç_Àt£éFÓ CõÕ;T—>ø%‰äß½³w^òÌòÌòÌ_µ¯ÚW Ç–[vlL,?±üÄòÀb³Xß)%oÍT¦2¢££aÝ…uÖ]€rŸ—û¼Üç°Ðj¡ÕB+p¨éPÓ¡¦¾ÃJ$É»ë½ð’ÌIæ$s‚.á]»„ÃÅwßY ‘ޑޑŽúN'y[t×u×u×á¬ËY—³.°è“EŸ,úê=¬÷°ÞC˜qwÆÝw¥~‰D"ù£Þùà%wwwhѸEãaoøÞð½áPœ\œ\œ¬ït’7¥À§À§À¶5ÙÖd[Øc³Çf Œœ?rþÈù0°ÅÀ[€áxÃñ†ãõV"‘Hþ>ÞùGÿ®Cz‡ôépµùÕæW›Ã…µÖ^X m–´YÒf‰¾ÓI^—de²2Y ëo®¿¹þ&:::¼¦óšÎk £+FWŒÖwJ‰D"ùûúÛÜxÉ2Ï2Ï2zžìy²çI8Üýp÷ÃÝáÅ®»^ìÒw:É« O O Oƒ¹‘s#çFB9ûröåìaþ—ó¿œÿ¥ôÁ/‘H$¯Ëß®x©¡CC‡†àzÔõ¨ëQØŸ»?w.°mlÓw:ÉUš\š\š ?DÿýC4¬Þ¾zûêíÐ9²sdçH˜à1Ác‚X®µ\k¹Vßi%‰äýñ·- Ö¬5X ƒüÓàŸà–Ë-—[.p½ñõÆ×ë;äÉÊÉÊÉÊÕíV·[ÝÎ,<³ðÌBø¤î'u?© {uîÕ¹(‹”EÊ"}§•H$’÷Ïß¶xÉí’Û%·KÐùçÎ?wþv}»ëÛ]ßBN…œ 9ôNòïâ¢â¢â¢`~üüøùñ öP{¨=`Q›EmµÚ­j·ªÝJß)%‰äý÷·/^jÝ­u·ÖÝÀfÍ:›u°ßf¿Í~cÄ1Fßéþ¹Äz±^¬‡K-.µ¸ÔF/Œ^ ¾¾¾0Ë~–ý,{pè0Ða ¾ÓJ$’7¢)Mi ²%²%²%€è;”D&~¡ï ¯KÜå¸Ëq—aᣅ>‚1SÇL3¼hð¢Á }§ûç(:Rt¤èÚ}h÷¡Ýpzïé½§÷ ”A)ƒR ™M3›f6 °TX*,õV"‘¼¥Á¥Á¥ÁQ-£ZF5?‘?‘?Ë·/ß¾|.6½ØôbS˜¢›¢›¢ÅÅÅ0[h¶Ðl!XD[D[DÎ8ã¬ï³yÿ½wÀK'U'U'UptÀÑG”ÝbvèåÐË¡—¾Ó½¿2ÎfœÍ8 ߸}ãö¤vIí’Ú&¤NH >Ù>Ù>ÙúN)‘HÞ„´Ùi³ÓfÃxÿñþãý!®J\•¸*PP¯ ^A=Èù"狜/À%Û%Û%tëuëuëajÈÔ©!ЧJŸ*}ªèû,þ9Þ›Gÿ®Õ­~lõ#xÔõ¨ëQ¶¯Þ¾zûjÐLÑLÑLÑwº÷OôêèÕÑ«a^§yæu æÎœ(}ðK$ÿå²Êe•Ëc c c ¸å}Ëû–7R|¤øH†{ ÷îÕwZ‰D¢ukÕ­U·Tö­ì[Ù÷?_WnRnRn‚æÍ#šG€y¢y¢y¢¾Sÿó¼÷ÀK~Ÿû}î÷9tèÕ¡W‡^°¡â†Š*Búžô=é{ôîÝ—î‘î‘îKK—–.-…Û[no¹½>ûÙØÏÆBÓòMË7-²ÏdŸÉ>ÓwZ‰D¢OnÕܪ¹UƒÆ3Ïh<ã?_·7±7±7À'Oè;í?×?¦ ˆ ‚ [t·ènÑP~Xùaå‡Á¦]›vmÚÅŠ?ÒwÈwϽ½÷öÞÛ sMæšÌ5U¶*[• j-¨µ xUòªäU 0ÄC}§•H$ïùSùSùShÕµU×V]Á²£eGËŽe¯øôç>…Šöí+Úë;í?×{; àÉeÈ2d0÷ë¹_Ïý–4,iXý‹û÷/ÙlÙlÙl}§|ût§t§t§àÜgç>;÷ì<¼óðÎÃÐ>±}bûDè1¶ÇØcA¡ŠPEè;­D"y—¥ßN¿~ÚýÔî§v?A„g„g„'lœ·qÞÆy0,lXذ0}§üçúÛ­øºØ [a+`üüñóÇχÅO?Yüœ9r>Íg7ŸÝüTì)ØS°vOß=}÷t¸|5øj0Œ0vÀØÐÈ©‘S#' ‚"ôV"ùg*\^¸¼p9dµËj—ÕDÑF´¬±ÆZßé~£ÝèÚGÚGÚGPç§:?Õù R?Hý õ¨8±âÄŠ!¥0¥0¥„¿ðþ€ 2}‡4hÐÏyÎs0J5J5J•ÊF2L'{úýcïü»ŸFý4ê§Q°­â¶ŠÛ*´ÚÓjO« ÕZWk]­µ¾Ó½9©•R+¥V‚o ¿1üÆòŒóŒóŒaüˆñ#Æ€Jc*©$ͤ(‘¼‚ƒƒa›Ë6—m.`¥±ÒXi@4ÍD3}§û_>Èå#å#å#!qâþÄýÔ;©wRoðké×Ò¯%ÈËËù䓯ïпQ—ºÔ…’>%}Jú€}Š}Š} Ì_7Ýüu`5ÈjÕ }‡|uRðoöUÝWu_UÍ Í Í„ùËæ/›¿ œ>rúÈé#}§{ H î~p÷ƒ»À:Ÿu>ë|Àk„ׯ0²ÁÈ#€eË –ôV"‘üÖæ”Í)›S ý|úùôó0áᄇBiõÒê¥Õõî?ÉÎÉÎÉÎAîéÜÓ¹§Aí©öT{‚Ó*§UN«@öHöHöСãúF-«#«#«)ûRö¥ìƒÅ7ZÜVXy`å°ßj¿Õ~«¾S¾ºì#€ßÓ}T÷QÝGAÊÉ”“)'a•r•r•æÌ ˜—,.Y\ÒwÊ?O©‰ÔDBp·ànÁÝ`諒—ö^‚.¹]r»äBçÐΡCAUAUAUAßi%ÉÿEÖGÖGÖLƘŒ1æ_˜aþ…¾Sý}éKßÿò„¢u¨£ï¿¯p_á¾Â} ˆTD*"V´â=Z¬ìŸ3 àRMTMTM„Ñ¡£CG‡‚¡·¡·¡7¬ËZ—µ. ŠjÕ(ª¡ï”\^h^h^(l:¹é䦓pÈïß!?˜Øhb£‰ ‡cÇŽeç-‘H$’©ø¦Å¦Å¦Å0éÇI?Núžïy¾çùؾ}ûöíÛAÛPÛPÛð?N³_³_³tßé¾Ó}§¿üÉñÉñÉñ°°ÉÂ& ›À“ÛOn?¹ ó;Ïï<¿3ÔO­ŸZ?d2™ƒþrJ$‰D?¤à°]h»Ðv!LÖNÖNÖBÄöˆíÛa¿|¿|¿„³pÎ:+uVê,˜g:Ïtž)DUˆªUáõåÈËÌËÌ˄؎±c;òëòšÿ.\®WÀ¼ó^Ì{.U]ªºT…¹s æ€[o·Þn½õݪ‰D"Ñ7©øƒÜë¸×q¯“U“U“Up^}^}^ ;Âv„íƒY³ fÀ’3KÎ,9ûŠ÷ï+qDG^áÀg9ËYر'bO 4,<xºªºªºªp$äHÈ‘X½sõÎÕ;¡Ã½÷:܃qÝÇu×,¾³øÎBw$$‰Dòn‘:þIUVWY]e5ôë߯¿þ0bÀˆ#@‚U‚U‚èŽèŽèŽÀÑíG·ÝE}õQT¡ e•Ë;?Üùáΰjܪq«ÆA4ÑD ’$/H†ºñuãëÆÃƒrÊ=(“£&GMŽ‚:]ët­Ó†è»Õ$‰Dò®‘ €?)µVj­ÔZ°O»O»O ɺd]²tttʶ‹þ1úÇèáPÌ¡˜C10»ÕìV³[ýfØËÿ»9wsîfX¾~ùúåë!Ú Ú Ú ìõC¡‡B…‹¹/澘 [3·fnÍ„ *L¨0Aß­$‘H$’wôàÒ”Ó”Ó”ƒ­.[]¶ºÀžÏ÷|¾çs(½_z¿ôþn/E „ý“÷OÞ?â«ÅW‹¯ö¿#6‰Mbì•í•í•Áᇇ~øäy¬y¬y F>ù`$ܯx¿âýŠún%‰D"‘ü]HÀ¤<¥<¥<ý¦õ›Öo,˜²`Ê‚)Pëv­Ûµnƒ²Ÿ²Ÿ²à„Ne?]7ºnt]øÁùçœÿ÷q"®G\¸«ìWÙ¯²‡ßßßßß>¥CJ‡”°Äm‰Û7HZœ´8i±¾[K"‘¼Ë´•´•´•à6·¹ l-ØZ°µ^x¿ð~á ‰mÛ$¶£ŽG:B‘c‘c‘£¾Sÿqâ¬8+ÎBìϱ?Çþ [“·&oM†Ø5±kb×è;Ý»C*þ(?üð&M<šÀ´øiñÓâáÈ´#ÓŽLƒ¯ž|õä«'àŸæŸæŸ……… Ù­Ù­Ù J”(…'ñOâŸÄÿçîsäÈ9_5ýªéWM!ºKt—è.¿ÙÀwÜÁæšÍ5›kÐHÛHÛH SÛLm3µ Ìm6·ÙÜf`ó±ÍÇ6ë»±$É»LÑUÑUÑÌ›6 ße}—õ]¤L˜:ò£ó£ó£á±ö±ö±4Ã5Ã5Ãõú“%Êe‰`ooG§~t:Üw¿ï~ß]ßéÞR€¿H¦•ieZ¨@*“MZ4iô ìØ3‚rƒrƒraWæ®Ì]™p·ÜÝrwËÁžÇ{ïy 'œ8p"ÈzÊzÊzÂÁàƒÁƒáÇøãŒÇ*ŽU«€ÏŸ->[ e£–Z6‚¶°ýƒíà›ê›ê› å”[Pn¾[C"‘ü¨W«W«WCFqFqF1¨}Ô>jeɲdY „ƒp—d—d—dèÚ²kË®-A©ŠTE‚ÎFg£³”€”€”(ú²èË¢/Á¦­M[›¶`³Éf“Í&~]D'3(3(3²ÏeŸË>º5º5º5à0×a®Ã\0bþÄü 9ùääðî3Üg8X˜X˜X˜@Ï>ž}<áA¥•T‚}“öMÚ7 ¼"¼"¼" åVÊ­”[PÙ¢²Ee èNwº»÷íÞ·{˜_7¿n~î4¿ÓüNsÈÈȆJ¢’¨$`Ú·Ó¾ö-tJì”Ø) à à áKR—¤.I°Ûd·ÉnÙÉìdvP¾¤|IùPWWÙzÙzÙz}_w‡T¼)¿,'i=ö@çt߸~ãú+Ä/_¿8Æ1Ž£«£«£+Œrå:ʬ¿³þÎú;`Ó˜¦ï“‘H$gǯ¿rü d]̺˜u´YÐfAÈÚ™µ3k'쫳¯Î¾: ³YÈ,À£šG5j "D„ˆ]w]w]w¸¾ùúæë›!{öþìýйSçN;Q=£zFõ@+‹•ÅÂÎØ±;c¡ü€òÊ€ÁîƒÝ»ÃóóÏÏ??C3†f -Ë×9»svçlð8çqÎãl Ú´%.X_°¾` W4^Ñxˆú¢¾¨~lôc£¡êªwªÞËc.¹<nn¼¹ñæFØ:ëü­óÁ¬§YO³žð½ï÷¾ßû‚N¡Sèú¾ï©À[¢ì¦ì¦ì&L&˜üÃôL{˜ö0íÊpe¸2\ßi%ÉûäéÇO?~ú18¤9¤9¤â”â”âˆÕbµXýüÀËÕù<ðÀt‘ºH]$t{ÔíQ·G {¬{¬{ ãÖŒ[3n =zôJ»–v-í ‰‰‰àúƒë®?”íÖ~¨ýPû¡PeR•IU&ANßœ¾9}áZܵ¸kq°åô–Ó[NÃÏ?{üìºiºiºi f‰Yb(((€iwÓî¦ÝÁl€Ù³¶3mgÚN0ogÞμ˜'˜'˜'Ÿó9Ÿë»õß]Rð–”ëV®[¹nЫ_¯~½úgÏžÀû’÷%ïK8.p\à80/1/1/ÑwZ‰Dò>1ílÚÙ´3äËòeù²ß¼ @d#d#d#@ÖUÖUÖÈ%—\`"™ô¤'=Ái¡ÓB§…ðMÖ7YßdAmm-|sè›Cß‚´‚´‚´°j5Ôj(dÅeÅeÅý~®óKÏ/=¿´¬ïSÏôžé=Ó¡þÝúwëß®r•«€9æ˜øâËoFG™ššB±g±g±'h‡i‡i‡†b4§9Í)Laо¯Æ»C*Þ2]]]ø´ç§=?í k»¯í¾¶;Ä-[·2údôÉè£ï”‰ä}Ø+°W`/x^ëy­çµ È È È"U‘ªHäÝÌ»™wž{=÷zî S¦$Lµ¿Ú_í)ÚmŠŽ/:¾èø"8õìÔ³SÏ pzáôÂéPÅ¿Š0w7w7w‡®Çºëz Â’Â’Â’àT‹S-Nµ€›#nޏ9^ô}Ñ÷E_0ýÐôCÓ¡ôQé£ÒGðàÒƒK.AÆÍŒ›7!7?7?7ž< xêGêGêG\>¹|rù²óó›â7Åo ëŒuÆ:8xèࡃ‡ |Iø’ð% .R©‹ ccÆÆŒú¾ï©À[R2¤dHÉHˆIˆIˆ^›zmêµ ~Óð›†ßÀO«~ZõÓ*8zðèÁ£aæïЉä½àWÓ¯¦_M0b2Äd¤vJí”Ú L›.6] óÒç¥ÏK‡òOË?-ÿD(0wÀÜs€Ë*—U.« ÒµJ×*]ƒÇ9sç€ÌWæ+ó…ù…ó ç‚u¢u¢u"^ ¼x\|]|]|!ezÊô”éPšSšSš¥GJ”ƪƪÆ*0.5.5.…Ò“¥'KOB`ÏÀž=¡ñµÆ×_‹‹‹øÌé3§ÏœÀõë×À.p*l®°¹Âf˜õÁ¬f}±þ±þ±þ 3Õ™êLaꆩ¦n§H§H§HЭҭҭùdùdùd}_=’·"1'1'1Gˆ¡ ý`èB¤I’:¤ìõÈÐÈÐÈP!®¸vàZ!âââôZ"‘¼K6lØ Äʽ+÷®Ü«ï4ï¿dïdïdo!>êöQ·º ‘¶1mcÚF}§z}¤GoIL¯˜^1½ÀJi¥´R‚……EÙëÕÛVo[½-Ôɨ“Q'öwÜßqGІiôaúN/‘H$’÷T¼%?üp0TJ©”R)«««³A@Ï[=oõ¼Ñ·£oG߆ÛA·ƒné;½D"‘HÞ7Rð†­/Z_´ýôè§G?ïPß¡¾C{—c.Ç\ŽAëÂÖ…­ aàþÀýP¬,VK=6$‰DòšHÀ–Ù7³of_P—ªKÕ¥à¾Ñ}£ûè…Ú¾iû¦í›BATATA„œ9rBßg#‘H$’÷…ôò ‹Û·9n3˜1c6k8Öp¬ñ¿Îb½Åz‹õн {A÷8píÀµ× mÛ¶`aa-Íe-‘H$’¿Hºð†EÞ¼y<Ò<Ò<ÒÀp¼áxÃñüç?”}(ûP¶m;Úv„c-޵8ÖBßg%‘H$’¿;©xC´>Z­ĉ8' Úºj몭ûóû146464†¾ô¥/²3dgÈNxòõ“¯Ÿ|­ï³”H$Éß•T¼!©±©±©±Ý"»Ev ¨ò´ÊÓ*Oÿúþ|‹}‹}‹¡æƒšj>€ƒŠƒŠƒ ŸˆOÄ'ú>[‰D"‘üÝH}Þ„ 3f€iÓ¦Àú[ëo­¿ýëû“id™zm赡ט;sî̹3!"$"$"jS›Úú>i‰Dòfý²HObbbbb"Ü^{{ííµ IÕ¤jRõîÿM ˆ’ – E–|¼|<”¬×~¤ý¸Å3ž²W<Îk&3È mpÚà´ÁP¬.V«RHÑwº×G*Þû÷îß»<*{Tö¨ Æ9Æ9Æ9¯¾ßòcÊ)?ƒƒƒ`ŸÓ>§}NPµ¨jQÕ"042424Ò÷ÙK$’7¡¢SE§ŠNp¹Åå—[ÀÕÕ0“™ÌÔwºÿ$ÎÉÜeîà0&=1=›¥¤@dÊ]*w±M>A>Pþkùôw†^xAéîÒÝ¥»ÁÛÍÛÍÛ ŒÜŒÜŒÜôîõ‘½œPßAÞ­F«Ñ¬Ÿfý4ë'háÒÂ¥… ´öníÝÚûõ'K—¥ËÒÁÌë3¯Ï¼]Óº¦uMƒÖ]ZwiÝEß­ ‘HÞ$'âDÜË©ÜSL1ÕwªÿC‘ÜIî²U×ò¯åƒlÝ•W^€.k‚çO @ñBñø×Thï-Z´ «'«'«²ƒ²ƒ²ƒ@cÓXßá^éÀk–3/g^Î<ȼ˜y1ó"xUôªèUØÅ.v½¾ãXË­åÖrèÞ¶{ÛîmáÙ²dP?³~fýL°j=Ôzè«G"‘¼{d2™ȽkwÏÿokþµkj]­uä–Xb ¿üß»çÙ/(ÞSR'À×,&8&8&ŒŒŒÀÕÅÕÅÕåÍ/à|Àù€ó`bbA©A©Aïâ³@‰Dò¦ˆUÄÙÙКÖúÎ$‘î¼f·>Üúp+¸á† ª©ª©ªùæŽgTר®Q]è÷E¿/ú}«3Vg¬Î€&FMŒš[‘[‘[‘¾[E"‘H$ïéÀk¢©¯©¯©Ñ3£gFÏßM¾›|7½½ã× ªT+ª-©¶¤Ú8u0ê`ˆf¢™h¦ïÖ‘H$É»F*^“¬¯²¾Êú ^¬|±òÅJ¨4ªÒ¨J£Þb€«\å*ôÌè™Ñ3¢ªEU‹ªw»Þíz·«¾[G"‘ü³e$f$<Ì{˜ vˆúÎ$‘ €×$).).) ‚þչũԩԩôíç¨àTÁ©‚4—7—7—ÃÞV{[ímEQEQEQún%‰DòÏt?å~ Àþ°ýaÚ"­ôhRï¤à5‰ŒŒŒ·Qn£ÜFy=ózæõô—§ãŽŽ;:î€LËLËLK¸¼éò¦Ëoñ‘„D"‘”ñ¾ã} sÃÎ ÁŠ`}g’HÀ«zÈC£•V>Z >—}.û\Öw(°îmÝÛº7t¿ÐýB÷ pxßá}‡÷AÎМ¡9Òð@‰DòV9Œt P[U[ ;";¢ïL©xEõ2êeÔƒÔìÔìÔl¨Þ¸zãêïÐDÍŒ›733S3S3S8|"ø„TyK$É?žT¼¢D—D—D0˜c0Ç`8:;:;:ë;Uî†] »Bï½ô~Á‚/_€¤“I'“Nê;D"‘HôE*^QLó˜æ1ÍÁå;—ï\¾³efËÌ–é;Õª}²öÉÚ'¡ŠeË*–p°üÁò˃è%z‰^úN'‘HÞo¥ÊR%@Þ´¼i¬a¾3I¤à/*¡*¸v?ì~T­YµfÕš %%{›Ãÿþ yyyèãÒÇ¥ Dˆ! raäÂÈ…úN'‘HÞo‘7"o|7ø»ÁÚ;Ú;úÎ$‘ €¿¨`iÁÒ‚¥z8õpêaðí9Ús´¾Sýo444Ðì`³ƒÍÂþšûkî¯ ¥¥¥úN'‘HÞO†‘†‘–,;ðŸé;“D*þ¢§¹OsŸæ‚X%V‰UP1¼bxÅp}§úãºìí²·Ë^Ȱΰΰ†Ÿ–ý´ì§wðÑÅ{C À!qÈ%—\}‡’HÞŸ^>½z,è±@‘ªÖ,Ñ;©ø‹bæÆÌ™ jµƒÌlÍlÍlõ곎·Ž·Ž‡.‰]»$Â?xüàj™Z¦þ[,/ö'ýòœµ,kYÖ2Èú$듬O€<òÈ{ó‡555…õ Ö/X¿B¢C¢C¢!gÎþœý-Ë–eË@ÓGÓGÓRî¦ÜM¹ ©—R/¥^‘%²D–¾Q"ù«Æ cÕ@Õ@Ð@ß™$RðÅ;<<<<<<@ö‰ìÙ'úNõç5MošÞ4LƒMƒMƒ!È$È$ÈDߩހ4ÒHƒýÁûƒ÷þÚûjï« |Ï÷|ÿ'ö³–µ¬ííí tÒóÒ¥=J{À¶Ôm©ÛRÁòk˯-¿»svçìÎÁž–{Zîi >:ðÑ ô\é¹Òs°?räþH˜?;~v<”Î/_:„¿ðþ »§»§»§ïF•H$gRð'å‡ä‡ä‡ÀÓ½O÷>Ý UVXe ¾SýuÆÎÆÎÆÎÐ÷iß§}ŸBð§ÁŸ ‰÷ï%¾Í˜Ãæ0°„%,ù/Û½\Ÿ{8ì`+øõžÜàÆÿñs…R=Œ{÷0†^“zMê5 ðÆoÊnÉË·|ËïQS£¦FM…C·Ý:t pÆg@ƒÍn_|¤øHñ¸ïwßï¾x|îñ¹Ççà;Ãw†ï è!ï!ï!‡îÝ=º{€ñ ãÆ/ b¿Šý*öƒ‚K— .¦¹¦¹¦9üpþ‡ó?œ‡û“ïO¾?ùÿ8Ï$’HÖ±Žu@>ùäÿ¦ÝÂ#ì-^W‰DòÎ’–þ“²eÊTö‡Ù9Þ9Þ9pÅW}§ûëjM¯5½Öt¨ººêꪫá‡Þ?ôþ¡7LΘœ19H%•7ðÌ.jKÔ–¨-<8xpð`È äPDZŽcGhò¬É³&ÏàŘc^ŒOO<=ñ à à à Ç8Ç8ÇŠŠŠ!üVø­ð[ÀzÖ³ÌsÍsÍs¡jXÕ°ªa»:vuìjHß’¾%} Î œ8 ¶ïÛ¾oû>ðœä9ÉsG¶G¶G64Ðd@“°1mcÚÆ4x2ëɬ'³ÀaˆÃ‡!Ð4 i@S_–_–_í!í!í!¸9ðæÀ›!þLü™ø3pjë©­§¶‚õbëÅÖ‹!Ì+Ì+Ì 2FeŒÊ™ÈD@ÖJÖJÖ d¥²RY)Üm|·ñÝÆ°êÒªK«.AËo[~Ûò[°üÁòË€Œ`ÙÙÙAqûâöÅí¡bŠ=*ö€ÆAƒÁ·U¾­òm0¬iXÓ°&˜ô7éoÒêÖ®[»nmˆsˆsˆs€¼ªyUóªÂíí-È d²}¿K%_OƒžÄŸ? ФK“.òfriµR½‘îüIýû?ö³;fwÌî€Ã‡ôêÕ)  è­ì­ì­„ïïoˆôŒôŒô|sÇݺqëÆ­¡`fÁÌ‚™Ðõ^×{]ïõë)ÖS@»X»X»6Þ4zÓhH+L+L+„~súÍé7üÛú·õo Ê…Ê…Ê…»=w{îv;v.ìT_W}]õuPηœo9_0ô1ô1ôK/]¼tlNÙœ²9w«Ý­v·x®ð\á¹ÚVl[±mEø®ùwÍ¿k òy‚;,vX ž½<{yö‚úíë·¯ßä]ä]ä]~Óž– K…%T?RýHõ#à sÐ9è ±wcïÆÞà3Óg¦ÏL0ð0ð0ð€+í¯´¿ÒtÁº`]0`‹-¶ މc┿PþBù `2ÍdšÉ4h¼¾ñúÆëÁÁÄÁÄÁÖëÖëÖë@µMµMµ ºEt‹èû£÷GvOížÚAήœ]9»àV—[]nuߎ¾};‚±»±»±;ZZZÑ7Fß}8à€ƒ¾ß’¿¿Ä+‰W.…^ Ð%ë’õI"Ýø“îgÜϸŸ'UœTq¨òUùª|}§z}*L®0¹ÂdhæÞ̽™;ìÍÙ›³7Ú,´Yh™™™¯ïx•¾­ôm¥oáè•£WŽ^ëÖ¬@—»üØåG(iVÒ¬¤Üì}³÷ÍÞ0!{Bö„l°¸`qÁâ4ªÙ¨f£š ìªìªì ö\Øsa8Vq¬âXê9×s®ç œà'àÞÇ÷>¾÷1ȵr­\ ÎÎΠܠܠܦM›>ïÞ+¼W€Aƒ:uàiå§•ŸV£F+ŒV€Q®Q®Q.w6îlÜùÿ8±@ £Ï>7ú”6J¥ ˜M2›d6©l3Æ €OŸú>ú>ú> f‹Ùb6hJ4%šˆ÷÷÷S7S7S7¨<­ò´ÊÓ@Ö_Ö_ÖrBrBrB ¨{Q÷¢î€/¾¼¤ Ô‹zQ/‚á¡á¡á!hNhNh~¶“~·~·~7èóõùú|Ð × × }Ž>GŸzk½µÞŒ®FW£+•F¥Q ™3f>F0‚PMYMYM 6Ø|`ó4^ÛxmãµÐÆØÆØÆ®½\{¹ö—ÎKçº"]‘®pÁà‡8§RN¥œJƒ>:øÄ01L 3÷Ñ(‘Hþ Rð+¥†¦†¦†‚E„E„E¸ qâ6ÄÜ©þ|-η8ßâ<(w(w(wÀ‘ýGöÙÿêÚ×xj<5ž°µÞÖz[ëÁ½Ýû×½Áè°Ña£ÃÀYtEøðø‡Ç?<ÊÆÊÆÊÆ°©Æ¦›jÀ·nÜ ªOTŸ¨> ¨¨vìØ€¬‡Y³B‰K‰K‰ änÈÝ»*l«°­Â6H—8.qhkkÙ¹gæž™ ‡px :?èü ót2èdÐIhÕ"ªEXí·ÚoµަM;š†å†å†å¥ý5¢FÔ@lýØú±õÁwŽïß9\˜\˜\NNN×"¯E^ ðªêUÕ«*Ü]~wùÝåPP£ FA ¨p¸Âá ‡!gzÎôœéУe–=Z•¡W†^ ±§bOÅž‚Q¦Q¦Q¦ÒþmHÙ²!N49ÑäDH«–V-­X´i5¬}¬}¬} kjÖÔ¬©@':Ñ rå4Êi™µ3kgÖq±¸X\lî£P"‘ü)Dɯ²?þþ|Qœž5=kz–(›››™;Õ_çö“ÛOn?Åwn¼s㢘d™d™dù Þ n7ˆ¢ñ}ãûÆ÷EѨ5jZQ¢Q4¾dû1D Ec;c;c;Q4n7n7nÅ7ω¢Éd2™L¢hÒ˜4&(ŠƒÅÁâ`QW‹«ÅÕ¢h:n:n:.ŠâXq¬8V Ož(™›%d YÐ{xï὇Ãý”û)÷S ªCT‡¨¿Á| ž1ž1ž1P>´|hùPhÚ´iÓ¦M¡}›ömÚ·µÚFmò»ò»ò»Ðãh£=ŽB½óõÎ×;‰Q‰Q‰Q ºŠ®¢+nܸ’ܓܓÜA®ׇÃöÛlƒÁ`0ÀØÈ±‘c#!ýlúÙô³p¸âኇ+š{oH$¯ZÍìšÙƒ|ùțɛ™;“D*~ÁÓÞO{?í ®V¸Zá*ØL±™bó7œèæ¯æ»Òw¥ïJh]к uì(¿£üŽò ë©ë©ëiîtÿ›ðXx,<a°GØSúsE%E%E%pëèÖÑ­#x›¼MÞ&p™ê2Õe* GŽø’/ù„`!XÁOðüøiµ½è~Ñý¢ûAÊÑ”£)GápÜá¸ÃqïžïžïùùùÒò»’«æVÍk:¾øæ?—¹æÎ$‘.ü‚d‡d‡dðÞê½Õ{«¹ÓüýtÝet—Ñp-àZÀµ¸°öÂÚ káMÞäMs‡ûo*R‘Š ôz=€cãˆbXœâ§øÏÅJ(¡УG˜0aЀ@yÊS¬*ZU´ª^ ^ ^ Pkz­éµ¦CpApAp¸îsÝçºï7§–H$’ßLø à à à cBÆ„Œ àwÉï’ß%s§úûqºïtßé>t¿Ýýv÷Û°çæž›{nB²@Y 4wº_f½Âz…õ ˆñŒñŒñ„äJÉ•’+ºžºžºL+˜V0­t{›6;mv‚°SØ)ì„g¹ÏrŸåBŽ,G–#m’6I›F£Ñ@SUSUSäTÍ©šS   Ài™Ó2§eàpÏážÃ=sï‰DRHÀÿ“ãžãžãEˆ ¿¹~sý¤¡ªß­ù¶æÛšo‡3fÀÁo~sðs§úeﺽëö®8éü¥ó—pëØ­c·ŽAÓˆ¦M# Ü¼róÊÍõxõxõx¨Ð¢B‹ -à£-mùh ÄÆÄÆÄÆ@ARARAô¸ÓãN;`J0%˜ ‡U«VÐrCË -7Àå›—o^¾ ·çÜžs{ä+ó•ù¯q$‘ü>Ùõ³ë<ýp4€8KœeîLi5Àÿ'꣨¢>ÅÔ¨?P‹bþ§ùŸæjîTwÞYxg¡(òä?È_§$NIœbîT‰ä¯q©Â¥ ¢(Š3GÍ%Š¢¨ß¨ßhîLiàÿÉø:ã댯Áþ¡ýCû‡`›o›o›oîT!÷Cî‡Ü‡î5Ük¸CøúðõáëA¼ ^/˜;D"ùsååt[Úm)€ü¶ü¶¹3I¤Å€þŸuOÖ=Y÷´ñÚxm<Œj?ªý¨öæNõÏ‘XœXœX 3¾ŸñýŒïaÜúqëÇ­‡ë!×C®›;D"‘”ÒÀL·L·L· Õ*Õ*Õ |ßñ}Ç÷s§úçñUú*}•ÐzPëA­ÁŽG;íxº¡º¡º2¸Ì²D"‘˜‹Tü@¿W¿W¿²]²]²]Àk¹×r¯åæNõÏÕ©o§¾úB~×ü®ù]áüÜósÏK7[J$É_F*~›”›”›š0M˜& *4©Ð¤Bs§úçrÞí¼Ûy7tìÙ=öøïñßãùŠ|E¾4;…DòcúÒô%€>N@QæÎ$‘þÔþ iPÒ ¤A`ãdãdãnsÜæ¸ÍÖ±ŽuæN÷ÏÕ¼Mó6ÍÛÀiñ´xZ„C^‡¼yÁ@2ÐÜá$É+r§òÊ×][0"jD€ü²ü²¹³•]ÒÀÒê¤ÕI«î­Ü[¹·EEEs§úç³^j½Ôz)ôóèçÑÏÎÎÎ ñlâÙijæN'‘H^ ›6\º4`3›ÍI"?xþéóOŸ î5Ýkº×!TBͪ쨽¾öúÚ롆¼†¼†vÕÙUgW0L“âtqº8l½³õÎÖ; ^¯^¯^oîÔ‰äß©¨<Ž| p¿ÒýJú#ú#Á™Á™‡=pß÷¾/@úgéŸp©ðÿË”ùK¦K¦K¦Kê”ê”ê>hôA£̪ Š#Ž8x[ö¶ìmÌHž‘<#æºÏuŸë{Ûîm»·-)S<ZšZšZšÀg˜Ï0Ÿaæ/‘H^(nVÜ `Ò²IË"s"säå(¢€B „îBw€ "Þžõ¶4Cà_¦Ì¨ƒ€Û·þË¡êêê7#nFÜ s§—H$/WK]K ’’ð²ß[ݳºж^ÛzÖ“¬'™;sÙSæïÈØ’±%c ععع€ýöoØ¿aîTe‡ì;Ùw²ï =íi¸½­ÞVo «V9¬‚)G§rôwôwôwà ÷AïƒÞµ0jaÔB° ¶ ¶ ý—ú/õ_‚éˆéˆéˆÓÄiâ4@5˜,M–&K“Åd1°ÄK••á°pX8 ä“O>„GÂ#5’5’5Y¾,_–r'¹“Ü ^ /…Èmä6r+åJ¹òÅüfòË`!·[ÈÁ"Ã"Ã",>°øÀân 7…›€ ™T†K^¦^¦^â^q/€´ú”••Á.Ü.Ü.”ß)¿S~à˜ã˜ã˜ŽÏŸ;>'£“ÑÉ.^.^.^àô™ÓgNŸ¥µ¥µ¥5(J%ŠPLTLTLrƒæ>J$¯±‘Œ0 0 }/û@¶TöÒÇjó?Ïÿà›sßœð\á¹ WÝ^uäEò¢{ÁÏùŸJ?•••r(ä@û í+xVóü·»þSv§ìX&,ºEt‹}?ô¥€æKÍ—çúŸë LT&4y»ÉÛòy‚¹wõë¯Ì*µJ­RƒÊ 2¨ à¶Ëm—Û.s§2ƒYÌb”$•$•$A¶W¶W¶d·Ìn™Ý²Ä,1K„TMª&UÏeÏeÏePø´ðiáS(©SR§¤¨j£ÚB€ €……… (]”.J°³³åyåyåyPWW‡rËÊ-+· Á1Ø1Ø1ìFÚ´ qqq`QÛ¢¶EmP¤+Òé¼ø36t¶:[-8r:åt dMdMdM@^S^S^³ôüOßôd²õ’õ’õzÑ‹^`’™d&˜››å(G9+‹•ÅÊ`ÔµF-˜œLN&'0\1\1\c#c#c#0ô5ô5ôC¬!Ö †­†­†­ ½¡½¡½%‡K—†‚'O ž@Á€‚ XY¬,VBöÑì£ÙG!¾y|óøæP\\\ºõuôuôu%J”`÷/»Ùý ”¢RTŠàÐÍ¡›C7ðœè9Ñs"x½åõ–×[à†n€›£›£›#¸Íu›ë6¬—Y/³^T¤"Í}Jþ:OÖ?Y°óà΃×w\Pz/Ý޲в a§†Ê¯-¿@ö­ìÛ—¾ÀG€®]»vèP©C%ù7òoBo…Þ°heÑ €K\¨è^Ñ`ªvªÀ~“ý&6°á¥ï³œå} úä?Ì`ªoª GþÒ—ÅŨ>U} ô(è€åBË…æþlþz‚øsù«eÍ<šy&§LN™œ³Sf§ÌNïÙÞ³½g›;ݧÓét:Ì)˜S0r;ævÌíq¾q¾q¾ççç©…©…©…{<÷xîq0 `›b›b›öÍì›Ù7ƒòKÊ/)¿Êo(¿¡üp q q çsÎçœÏs[ç¶ÎmÁÙÊÙÊÙ ”ÙÊle6țɛɛà(8 ŽÀ¦0ÅÜ{ç5¤C‡Îp†—ŽLè·è·è·@QvQvQ6äåæåæåBÞ„¼ y ¯^^½¼z»5wkîVH‹I‹I‹,§,§,'(®]\»¸6¨ë¨ë¨ë€eË&–MÀí¶Ûm·Ûà£òQù¨ `wÀî€ÝàëãëãëÎöÎöÎöàøØñ±ãcË‹åÅæÞI’ÿ¤R¨™V™VîÝ;Ø}o÷ý˶O_‘¾àq½Çõj6¬ÙÀ]î.ÿ5ï÷ÚùqfÁÛ¼x|¸9Í~éÒÚ¡7½ pó½›ïŒx6â€ç4ÏiæîÊ_¯ÌñOãŸÆ?…yÌû`Þ0ÿÊü+󯀛ÆMã¦1wºÿ⇙óô¹ú\}.äœÎ9sbâbâbâ æTÌ©˜Sð´ÒÓJO+AþäüÉù“ùé­ë)×S®§ âÁŠ+„Š[+n­¸|×ø®ñ]<:xt›t›t›t°jnÕܪ9(ÒiŠ4Ào¼Í½$¿h›Øúæúæúæ }¦}¦}ªªªf“f“fIg’Î$ÄÆ‰C²²²?ä7ÍošßäÃåÃåÃÁõ#×\?‚ÀyóçAÐ¥ KA— ðaàÃÀ‡à´Êi•Ó*???0wçË¢ÓOO?8¼ùðf€1ãÇŒ¨äRÉå4ûeìiì  m¯m`}Þú<¼x ùeÛ? yP¸¢p@íwj¿/Æ&ÍÝ—?®ÌÒ¤?H‡U™«2WeÂüÕóWÏ_ Žk×8®1wºRùÝó»çw‡g Ÿ-|¶ôyÐçAx4ùÑäG“!Lþ˜ü1`?ß~¾ý|ðËñËñËê7«ß¬~*~Vñ³ŠŸëb×Å®‹ÁñãÇ ».».»nîÞI^†-†-†-••9á9á9ágggË=.÷¸$®O\Ÿ¸4Aš M¸·poáުϭ>·ú\¨î\ݹº3øò?ä”ã•ã•ãÍÝ»¿¥-lJWÍû…Er —.ÐÆhcÜÂÝ„L!ÓÜ]ø'¸¼üòr€#ïyà›l|EßÀY³Ì7ÎÞ8{ã,ìè´£ÓŽN0ïü¼óó΃mÛ¶ þ ‰$’ý úô‡è6Ñm¢ÛÀ•5WÖ\YOÝžº=uÅÅÅð/ð/ð/€¸¸8ºt+è”Ï,ŸY>ä£ä£ä£p0÷^–ücüðT„~Œ~Œ~ ¤,OYž²žÄ=‰{÷zßë}¯7$ÖL¬™X„^B/¡Ô8^ãxãÐtWÓ]Mwÿ}ÿûþ÷AYEYEYÅÜzeîÈܰ§ÞžzÍC›‡TO©žbîleÒO…i“µÉББò(y”¹£ýqe¶8£;£;£ƒ N,8±æŽ;vîX°PZ(-”Þûšô&½I‰S§$N3ò3ò3r¸UÿVý[õA$’A-«ZVµ¬ ©eS˦–àßÕ¿«W°™b3Åf ½…ÞBosïE‰äÓMÓMÓM(™Q2£d»4wiîRpÚä´ÉiXT¶¨lQèK_ú¾º÷1í4í4í„ÇÅ‹Ã~ÇýŽû!6*6*6 ãããa¨õPë¡ÖÜ;¸wpoPÞWÞWÞªP…*À]îr×Ü{M"y9YCYCYC°?nÜþ8Ô§>õúsëÏ­?ò*çUΫ QU¢ªDUS§NÀ©¾§úžê !C:†t„ÎÓ:Oë< *eWÊ®” t§;ÝÍÝ»¿RuêÕÕÕÕ|ŽtâÿùÈ|ÒÆ¥ˆNŠNøÐãCùsùssgüOev`eñÊâ•Å ¨¯¨¯¨ïG¿ý~ô«k?ùJò•ä+°³æÎš;kƒº>º> «« Ø`ƒ¹ÃýŒ'žx‚f‘f‘f”¼[ònÉ» mªmªm „Nø¾L^]^]^‚݃݃Ýa쌱3ÆÎ€É™“3'gBbdbdb$L1}ÄôpG¼#Þù[Mɽœ{`éÂ¥ âóãó{+?.­9®9®9†u†u†u¯.¥q¡q¡q!Ü n7/‹—ÅË “éd:h“´IÚ$ Œ0ÂþK;3Œ3Œ3Àà`p08xÄ£W¿Wu™ºL]&œ»îþ¹ûpìÆ±Çn€ÁÖ`k°}7}7}7SÄ1ôžzO½'heZ™Vâ q†øJW•]•]PvUv^ÓÿOÄ2Æ8Æ8Æ8FgXͰša%ЇòåÊÿýí½8EqKì–Ø-±¢øNÊ;)龜â9å9å9¥(êô ús÷ºÔ¹£çŽž;*ŠŸ7ú¼ÑçDQí®vW»›;•äÿÓŽÓŽÓŽŽå÷–ß[^‡ì²sÈNQÌœ9!s‚¹Ó•ŠËŠËŠËÅù æ7˜ß@W8­pZá$Šs®Î¹:çª(^¯ˆW~G»êXu¬:V÷<ÚóhÏ#Q(Š¢x¼õñÖÇ[‹¢é]Ó»¦wÍÝûßâÉì'³EQ74ÝÐTE±È£Èã··’Ó!§CNQ:>t|¨(n¸´áÒ†K¯.å~q¿¸_ť喖[ZN‹N(:!ŠÛ4Û4Û4¢8¼hxÑð"QÌÿWþ¿òÿõËíì3î3î3ŠâÒw—¾»ô]Q4Øì v¯~¯õ9êsÔG§ë¦ë¦ëDqÿÐýC÷Å+=¯ô¼ÒS§_~uúUQÌmšÛ4·©(žíq¶ÇÙ¢8àÒ€K.‰blNlNlΫÏõËÔŸª?EQT¥ªRÿÊ÷}¹27` 5…šBA³Z³Z³ìªÚUµ«úûÛ;æ}Ìû˜7\­zµêÕª0}êô©Ó§BË¢–E-‹@á«ðUøš»×¥ªÜ©r§ÊxkÌ[cÞ–³,gY΂‡3fÀ ý ý಺b¦˜)f•®Wº^é Ïv?Ûýl·¹Sý2Ë/-¿´ü÷î Ü 5j&ÔÝÝÝ€W¸_œEgÑJn•Ü*¹¦ë¦ë¦ßðx¨æºæºæú‹ÙWšå}”÷QT_R}Iõ%°²áʆ+‚æ ̶͚߰µ¿µ¿µ?t¯Ú½j÷ª0:ptàè@Ø%ß%ß%‡ë®¸þ ÷߯Š];€÷z¿×@™¡Ìøí­¸v9ìr)ŠE ¤N>úÕ¥ ù äƒ ´Wh¯Ð^ l«l«l gΜ…xM¼&^†w ïÞ…;º;º;:¸¿äþ’ûK~ÖŽ"†ˆ:4thèP͓͓Í{õ{õÚÅk¯]ûÛö·íoC—ð.á]¡r§Ê*w‚NC; í4ì·Ùo³ßÁ¾Á¾Á¾z'õNêP_U_U_}õ¹þKâã׎,ê·¨€!Úð /=ÿVeî&@SgSgSgЖӖӖ›Ý6»m~lj ¹yróäæp¢ß‰~'úÁÈé#§œþþþ¿?ßC÷‡îÝáü§ç?=ÿ)4¬Û°núPYýeõ—v±v±v1XºZºZºBü¤øIñ“àVŸ[}nõýýý°:guÎê8=szæô œª8UqªòŠòŠòŠóȧ1‚˧.Ÿº| K{-íµ´X °`5k;Öv¬ +V¬„ËŸ_þüòç^+½Vz-(—P.¡\´¨Ó¢N‹:`‘`‘`‘ðëûùTþTþT·Êß*«<ð Ÿð 4nÛ¸mã¶q%ãJƸ»õîÖ»[_Ìú>x´ôhéÑÎÌ=3÷Ì\Ì Ì Ì„r­Ëµ.×.Ö¿Xÿb}ÐËô2½ j=«õ¬Ö3°zßê}«÷aÞ¦y›æm‚æš_h~ÞúÎÐw†‚ÝWv_Ù}çûŸï¾?ª Õ…jjÔ.¨Ô¨R£J*p¢Ï‰>'ú€fšfšfØ{Ù{Ù{Az`z`z TЍQ)T§T§T§ ×"×"×Úßh£ý (׸\ãrý~’} û@ö‘B¤YºX‘q•q•q\µ¾j}ÕÒ†¥ K–-;[v†¦ò¦ò¦r(÷´ÜÓrOAã¢qѸÀÅ‚‹ '3'3'òæ7Ìo>×|®ù\ƒv}Úõi×çׯQ40h`Ð@~šhêGî)î)î)P (P(Ààdp28ýþÿ.ê?­ÿ´þS4{ÐìA³!Ü&Ü&ܪž©z¦êpjíÔÚ©õïoÿ/0Žq¯°µÖ|ˆ‹‹‹…ƒ£Ž:8 4O4O4Oà_£ÿ5ú_£!arÂä„Éžž>éôI§O ò@äÈêêê¿éøMÇo mLÚ˜´1Ú<µyjs¨Ú«j¯ª½@–(K”%‚¼‡¼‡¼¤Nœ:ô[ÐoA?ðïâßÅ¿ Ø6·mnÛ2keÖʬiiiàÜȹ‘s#8»í춳۠ܦr›Êm‚’%-JZ€¥‡¥‡¥´÷oïßÞ,ß´|Óò¿¬ò™¶-m[Ú6xxÿáý‡÷Áv·ínÛÝ9'rNäP4S4S4ƒè®Ñ]£»Be¿Ê~•ý@v^v^v„d!YHáð@xœä$'áòÒËK//…¤öIí“Úƒ‹ÜEî"‡–1-cZÆ€uœuœõš¨Ò¹Jçžå<Ë0ºÝf9—¹±³ØYì švšvšv`;ÝvºíôßÞÎù›çož¿ B€ @uÿêþÕÿÀ‰ÿG¶cmÇÚŽ…2d@š2M™¦„ŸŸøüöç·?¿ 1bă 0( Ⴤ>ÕBÕBÕBX1gÅœs@õ‘ê#ÕGPdQdQdÆùÆùÆù°ÆuëWЌՌՌµÚNmç<Îyœƒò5Ê×(_ŽN::éè$8p0à`@é¼ûZíkµ¯œìw²ßÉ~¿¾º÷tïéÞƒùMç7ßÔÅêbu1¸+Ý•îJ(Ì-Ì-ÌÅÅÅø¦ø›âoŠ!ÿPþ¡üC ˆb<ÞñxÇã`Ùβe;XsyÍå5—áшG#? ? ? È»›w7ï.Ø~iû¥í—Püañ‡Å‚ïtßé¾ÓK×$Ø8j㨣àQñ£âGÅP)¼Rx¥pX±jŪ« naܸ…p»ÓíN·;ÁÅöÛ_lU«8Vq„ËC.¹<N«O«O«!x@ð€àp¹á冗Bx¥ðJá•þøñ!ë!ë!ëGÆ ‡CÓM?4ª»Vw­î y{óöæí…Å9‹s瀺¶º¶º6VVVÁjª¨U—W]^u9ÜØuc×]{#÷Fî °p·p·ø ËbËòdy²<=‘=‘ýìf¶T§T§T'¨ÒµJ×*]Áº­u[ë¶¼ÿM¾nòu“¯Ázõë5p{Üíq·_å‰õï"ðÅ*|.=]zºô„ê ª7¨ÞÒ–§-O[Ë–, €¬ŠY³*¦›lZÚÖÚÖÚÖ ¤¤lx°áh»k»k»CÉÜ’¹%sa]þºüuùPò¤äIÉ“ÒÕ+ÅÏÅÏÅÏA™¬LV&Cñ½â{Å÷À{©÷Rï¥à±Óc§ÇN(üªð«Â¯`ÝŽu;ÖíÓÓÓØ3lϰ=à ý«ô¯Ò¿¿[~·ünÁ†FmhwòîäÝÉûßÝwúÊé+§¯À9Á9Á9< x/÷^î½777aý¼õóÖσôyéóÒçìˆìˆìHi;²g²g²gp¾õùÖç[ÃŽ¯w|½ãkÊ Ê Ê‚“O^t9€U±•§Ø.s€~‚~‚~èCõ¡úP°­i[Ó¶æoh Õ¨q»âvÅí‚···W—¯Ò”JS*M6Û4nÓ¢¦EM‹šI““&'M†Ó‡O>}ΩΩΩ {böÄì‰Plý±õÇB¥}•öUÚ.3]fºÌ„6OÛ3}fŸ§>O}žÂ§ã?ÿéxر)bSXæ[æ[æCë¹­ç¶ž —¶^Úzi+\m~µùÕæPË£–G-ÒvGî¹gähSЦ M,µlÔ²Q0¯É¼&óš€ÎZg­³¡³ÐYèÌ‹ÅÂä .—‹Ë¡duÉê’ÕÝ2ºetK¸ºùêæ«›!”PBàÁ ‚€é3Óg¦Ï€‹\äç'Ì÷ß(d@¼‚ã;¾ã;PÇ©ãÔq`YͲšåÏ–UU„(B! n·‹ÛA_S_S_ÚÎk;¯í<ȱϱϱ‡oR¿Iý&µô’B«Þ­z·úKØØØÂž•{VîY ¡ÏBŸ…>ƒzMê5©×äôûGïò.ïBq§âNÅÀ¾};ûv¯°ýWFÕIÕ `Iì’X€§¶Om_aóPâ>qŸø³‰f¬fZÍ´š ¦tSº)½tÙn¶³í€?þøSz¼þQ&L˜ø¿ÿáÇ嵟óœçüçSN8á²Éþ%û<»úì곫°)|Sø¦pذkî »àÒ—Þ¸ôó{I~\æ{®8WœûÛã ¡B¨ ªzªzªz¶1mcÚF8ïrÞå¼ x=ôzèõÚ^m{µí+¹WàÅßgØÓvO[€;^w¼^E»¿O™+УУУøé´3Ù™ìL¿½Fë­o´¢â£â£â¡øtñéâÓ¯.gí:µë郞 c1¢§GOž½“{'÷N†Ì™2@VRVRV”ë]®w¹Þ öûŠ}A¬&V«7¸ÁŸ5\ôÃêYéLgà'8¼É›¼ êêêêê꥛W:Pé@¥PqDÅG@ï½Oô>ÍÿhþGó¡•±•±•ñ×÷K÷H÷H÷²dÈÓ†L2mtVuVuVÁÕÉW'_ \æ2—¡ùèæ£›†âuÅëŠ×AÄ•ˆ+W xQð¢àE¥íÆ×¯_†›†›†›`ä[#ßùD$E$E$:O§Î+]¾WS_S_Sä:¹N®ƒJ•*@µäjÉÕ’¡Oã>û4†1-Æ´Ó*+++++ÁØÀØÀØÄJb%ñgCúâcñ±ø¸tùàŸ<æ1öyüV?~cùáó® ×…ë¨ Tª íLÚ™´3¥›§uNëœÖìÚ/´_Î={:÷SkSkSk¨™S3§fÔ\QsEÍð¡ï‡¾úBÝNu;ÕíôÛãô}±ëw ß%|—>®>®>®Ðp}Ãõ ׃zŠzŠz 0šÑ¼‚›ÕÒ«¤WI¯)Å)Å)ÅPgf™ufþñv_=‹zõª7«Þ Àf–ͬWØüSžò¨E-j•þ8ªZTµ¨jà1Ãc†Ç ðŠðŠðŠ]º.]—Æ)Æ)Æ)@9䀨Xl,6qˆC”þ}hLcƒ.†‹áü´ÙOÛÿpB757575/} ô'Z´hAl$6»ÙÍn`#ÙbG±£ØñgÛÿðsãXãXãXÙ²!dÌí<·óÜÎ0?|~øüpè>¼ûðîÃK_öâ1 2•ùùw?öã=Þ㽟=î÷C® IÓÓÓð[æ·ÌoTH¯^!z ê1¨Ç øpÿ‡û?ÜaýÃú‡½’y(„ï„ïÚ?jÿ öíÚ·_áqñ•¹›K:”t(éòuòuòu`ý±õÇÖÿövîm¸·á^8·åÜ–s[`›Ï6Ÿm>ðžë{®ï¹‚"G‘£Èùý9m»Ûv·í;v ÛY¶³lgA…7+¼YáMèb×Å®‹øMò›ä7‰Ÿ¾$WL®˜\L‡M‡M‡!®{\÷¸î|%øJðx0÷ÁÜsAqFqFq¢+GWŽ® 6Ø` œïü{ç߃Ó×O_?}úTëS­O5øÆæ›ol`yÇå—wŸ!>C|†ÀçÞ8÷Æ9ðJðJðJøßýµ¢VÔÂù¦ç›žo wÂï„ß ‡çCžy>Þ^øö·òÓ7׆® ]B³øfñÍâÁ¥·Ko—Þ`·ßn¿ÝþÒvï¿wüÞq¸:æê˜«c ¤wIï’ÞÐob¿‰ý&‚k×&®M Á”SL½ù{ó÷æ—.f3¬`XÁ°Ø?hÿ ýƒ Ï.Ï.Ï|³|³|³ ¶}mûÚöggg ªªªïï﹇sç­­ÖVk ñAñAñA””úýúýúýP0³`fÁLpLpLpü/ûK?T?T?¢/G_޾ ý,úYôƒ˜ƒ1cBŸV}Zõi;ê쨳£¬j¸ªáª†3*gTÎ(–6,mXxŒðá1îõ½×÷^_8_ó|Íó5!ncÜÆ¸ k¡k¡k~çýÎû‡÷ƒß~?”J¥ÿST»¨vQíàÈ£#Ž<‚Ê«*¯ª¼ N §„SxuõêêÕÆÕW{\íÒ¡Þߪ¤MI›’6°©å¦–›ZBõ°êaÕà heÐÊ •ÀR–ò[.Eýé,Ã,Ãú–ô- u^]ë!³Cf‡Ì†;µïÔ¾S6^ØxaãH»v!í =tôÐѸ:puàjN N Nm¶=Øö”••ÁÞÏÞÏÞâ¯Ç_¿Ñë£×G¯ÙSÙSÙS¸ÓáN‡; ý\ú¹ôs Ï•çÊs!îhÜѸ£Ð8¦qLã8õñ©O} åœÊ9•s‚TÿTÿTPÌVÌV̆³ûÎî;» 5 5 5 sræäÌÉ›››¦`S°)2¯f^ͼ &k“µÉ,4‹—¬Îú¼ñóÆÏCþ¢üEù‹À0Â0Â0&LO§?þt:(†+†+†CT—¨.Q]ÀuªëTש`1Àb€ÅˆéÓ'¦tŠéÓ)6žØxbã X^ny¹ååÀg£ÏFŸÐhQ£Eo´o´ï»kÿÅH µ©ý…ÿK™› ðÚ…k®]€ù;òwäÃ’°%aKÂ@a¡°PXüööRû¥öKíó´ó´ó´¼5xkðV¼cðŽÁ;Àþ=û÷ìßûýy >2|âDq¢8,ü,ü,ü@Ÿ¨OÔ'‚p_¸/ÜE±¢XQ %ãKÆ—Œ½“ÞIï¶É¶É¶É`©²TYª $£$£$tqº8]X7±nbݤô¦™¢õEë‹ÖƒÕU««VWÁî„Ý » Þ©Þ©ÞY:ô¬ÈVd+²AV]V]V®G]º :tADágG•è%z‰^PîT¹SåNAõ‘ÕGV ÄC Èäò°¯h_ѾbéÍF?Î1¿û»Ýßíþ´nкAk¨|§òÊwJÛ×ÌÔÌÔÌ•µÊZe ²õ²õ²õ`/Ú‹ö"Èãäqò8ÐVÑVÑVâÁŃ‹ƒrrrX}`õÕP¼¯x_ñ>ÐÓÓ‹ví,ÚuEëŠÖA=F=F=¦tÈÑf¾Í|›ù ¹¬¹¬¹ â)ñ”xêÅ÷=›Y )ÖkŠÁxÂxÂx¢öGíÚYÓ²¦eM¡›ÐMèö³ýôÃ7&ûnöÝì»AHnHnH.X]³ºfu ¬tV:+Ø8Ø8Ø8€f®f®f.¨º«º«ºƒ"@ ûûûª Õ„j°6}múÚt000€·Þx î~¸ûán?cüŒñ3à³ ŸMøl¨ê¨ê¨ê”N<ó“,²ÈY‰¬DVÁí‚Û·÷î;Üw€±¯±¯±/°šÕ¬…ÂGáΓœ'9OÁ^°ìýñŸ5(kPÖ X5tÕÐUCA§Óét:ø$ü“ðOÂÁa­ÃZ‡µ¯ìÏÃ߆a§a§a'¨BT!ª0¶3¶3¶‹Š-*‚ò†ò†òDI ŠWÅ«âA›ªMÕ¦‚â ÅŠ7ÀtÚtÚt¬åÖrk9è;ë;ë;ƒÞAï w«YV³¬f¸R\)®½‹ÞEïÖßYgýÈÒdi²4(ªYT³¨&X‡Y‡Y‡x]¼.^CSCSCS»È]ä.`t6:Á¢‚E‹ `ñ¦Å›o‚ê‚ê‚êX´²heÑ ìfØÍ°›Üç>÷_ÒÿO Ÿ>âÅ#ŠG”åÛæÚæÚæÂ‹ùW@«ÕjµZ°¬bYŲ ó„yÂ<ÐÍÐÍÐÍË>–},û€­ÂVa«M?M?M?PTT¹£ÜQî¶wmïÚÞ‹mÛ,¶™ûÓuÊ\pfÑ™EgÁÉïO~ò{˜¯Ÿ¯Ÿ¯Ù=Ù=Ù½ßßnò…ä É`徕ûVîí¿´ÿÒþ Þëô^§÷:Aõ¼êyÕó@ð<„_ñÍêïÂØÄØÄØ’|’|’|@›¢MѦәÎÏŸ®øášÝ9»svçÀë[¯o½¾y_y_ùKÖ^ØÞd{“íM@ÛWÛWÛ”¹Ê\e.ô°éaÓÃd“d“d“ÌÝû_OüJüJü RW¤®H]EQEQEQ œÎ ç~¶ár–³¼ô„_áD…N”Þ;ñ{ÍÚ=k÷¬Ý k¥k¥k]žuyÖå<øâÁ¾€‡ýö{ØFÍ5kÔ,Ðn×n×n1MLÓ~ÖP %”€pA¸ \“‡ÉÃN+œV8­øãûéÇâÆä“oL†o;øÛÁPéJ¥+•®ÀûÞŸðþp^å¼Êy•™>L‰äW3)MJ“£É@‘ªx…7ƒþQe®8rñÈÅ#áF„ 0k³æ‚ðDx"¼‚9¹U_©¾R}{Çì³w œÜ~rûÉíP§Cu:@wßî¾Ý}¡¢[E·Šn <ž OͽW^?×]t}ä~šûiî§ÐÌÐÌÐÌ5j:ü–§6$äìÌÙ™³îV¸[án0­3­3­Ë©–S-§BÍG5Õ|.Ý]º»ü…‹ï‡‡‡@LŘŠ1!üãðÃ?†¸Ëq—ã.CO‡ž= ÝúvëÛ­‹ï,¾³øÎÜ{ó0¤RöïÚ¿ ÀgªÏT€FªF*sg“¼:ª-ª-åå!ï…¼Ð\Ó\óGÚ}µÊ\°/x_ð¾`ˆºu?ê>LO™ž2=Á_xÏñÿH\ .@üÖø­ñ[awÝ5v×€‡Š‡Š‡ чèCôжQÛFmAP“ &AMÀ¢±Ec‹ß0QŒDòw¢}Sû¦öM¸»ïî¾»ûà¤ËI—“.ð,ìYس0hÞ8¼q8tóîæÝÍÊ·.ߺ|kJïbÿûû¡'§ŸœW9®2À°”a)ò‡ò‡æŽ(ùã22ŽZµ«V ÜùrçÍ­T™+v^Úyiç%Hl›Ø6±-|²ù“ÍŸlÞæmÞþóÞ×xÁxÁxž5zÖèY#8µåÔ–S[àîÔ»SïN×q®ã\ÇAÓ M/4½µ»×î^»;xÇ{Ç{ǃl¾l¾l¾¹÷žDòëzzzAüàøÁñƒávÞí¼ÛypÝæºÍuÐL×L×L‡Æo4~£ñz?ô~è}ðiàÓÀ§«„UÂ?zˆ_œ NÐE뢬ܭ^LÀ$-ÎõÏ âňNº°‡=8à`îh¥Ê\°¥ú–ê[ªCÖ̬™Y3a|¯ñ½Æ÷2Cn~Ëú$듬OàFñâÅp=ázÂõÈpÍpÍpÏÙž³=gC½.õºÔë57ÕÜTs”ïV¾[ùn`gmgmgmî½*)s6³™ÍP´´hiÑRHÍNÍN͆»–w-ïZBäìÈÙ‘³!§^N½œzàìì M*4©Ð¤ÔßUWý]àø/Ç9þËÜyeMÌš ^ ^à•ï• pQ¸˜;[YT¸¿p?À“ož|PuQÕEÊ*Ê*æÎöÛ•¹`ý¦õ›ÖoM”&J£–ŽZ:ê5z|Èl6CF—Œ.] âVÄ­ˆ[p÷‹»_ÜýÒ+¤WH¯¶ŸÚ~jû)lذ‚š5 jAõ‚êÕƒòËo,¿,ß±|Çò²ðJò*™všvšv‚öíÚ %<%<%ž|ýäë'_ÓOj<© ‰ ‰ ‰`ØdØdؾn¾n¾nP{DíµG@]»ºvuíÀu¨ëPס ÷’{ÉÍ8ñÉßÏÕçWŸìX´cÀ(×Q®U>­ò©¹³•EG3f\x÷»’'$¸ßsÿ7‘›K™+VèVèVèÀâ‹O,>÷—¾¿ôýרø%¦ý¦ý¦ý]=»zvuHHH€ûïW¼_b'ÅNŠ9×r®å\›$›$›$(ߤ|“òM à«€¯¾‚Š+N¬8Êo(¿¡üðððððð›{6÷lþ†°ä7ºÃî@ñÔâ©ÅS!ãbÆÅŒ‹Q7£nF]HpKpKpƒ¸¸¸x>àù€çÀkÈ5ä‚Ç2eË ð|àùÀóPsWÍ]5wïw¾ßù~΂³à,ðÓc€’?ÊxÙx Ã.ÃÀ¹ƒsÛ4Û´—m¯©®y1‘×<æXw±îbî>¼Î^L9×s®8õrê`áoñÒ{Š+W²…l;•ÝßøæÍ2W,þtñ§‹?‡ÆC—\:ðoPü¢Ëû‹ýÅþóQÎG9Aü—ñ_Æ Ž Ž Ž[+¶Vl-x^çyçu dTɨ’Q h¤h¤hT:QŽÇuë×Ák¿×~¯ýà'÷“ûÉÁµ®k]׺`sÆæŒÍ°l;Ùvriá ß+ß+ß Øa‡¹wÊ?XD€>H¤µ\-WËA=G=G=T‡T‡T‡àyäóÈç‘x6ñlâYHMM…ço?ûùÛ÷}Þ÷y߃8Oœ'Îûö=ì{€g¬g¬g,Ô¨PüÞö{Ûïm¨Ô©R§JÀÑÊÑÊÑ ˆ%–Xsï É:›~6à芣+F,±À_í¯þ#íþS <p¸ÑáFò'äøö9lîl¾2WÌ­2·ÊÜ*´(hQÐ"èÙ¥g—že BˆÄ Qj”%¨>T}¨úR¥4JiIÑIÑIÑœœ éƒÓ§†¬>Y}²ú€îMÝ›º7Af-³–Y—.*bßÚ¾µ}kp÷s÷s÷×O\?qý>wøÜáspôwôwô§IN“œ&ó]ç»ÎwÁÉÑÉÑɬ.X]°º2­L+Ó‚ÌOæ'ó+H¦”)eJ† Ã…á  ABЉNüŽ©kÿ4KXŠŇ`úØô±éc0å™òLy`J5¥šRÁoŠ7Ńé–é–é¨>V}¬úòšå5Ëkùóòçåσ‚zõ êAÁÞ‚½{¡À©À©À rss!ëDÖ‰¬PÒ¹¤sIg0:Ž Îg‰³Àú´õiëÓàñ±Çǃ§§§§§'xúxúxú€oC߆¾ Ás›ç6Ïm¥¨XeYeYeQ:E´äo¦äƒ’¢ý£ýáÅ$×.=\z¼lûçªç*€‹½/ö¨s¬Î1€ÊÆÊ/Ÿâ;žxñ²x@ø^ø€Ã¼Úæmnˆ«Å#I/Ö0@˜"Lyéöá„\lr± @f§ÌN,:XØÜ°¹ñ²—¥%§%èëx·ðn Ÿ!ŸñJûóZ*3S›f›f›fƒz±z±zqéjRtùé.Í4¡‹ÐEè6Ø`ØÄØÄØÄ€+®¸!„òóD¨³ÕÙêl(lPØ °Ÿ)>S|ŠfÍ*šY1Y1Y1Z/µ^j=Èž7P®T®T®/w/w/whP®A¹åÀm©ÛR·¥ ¼§¼§¼ÊÏ”Ÿ)?‡.]º€Õ`«ÁVƒ¡ eèKŒF4âL0$yݼXÝêQïWmoL4&¤·Ooà³Ëgðÿ¦Ö/¥uѺ@é= òyòyýmúÛÈÔ²—Ž4$%<| P'³N&€«Ÿ«ß˶ÏÊÏÊØQ´£ x~ð|€7‡¼9@ð<ÿíŸó9@Î…œ ú} €PK¨ÅáåãåÀÎPæ”™CKCKCKø´ý§í?mNv8Ùá$´<Ûòl˳æN÷¢G˜À&”.’c¬i¬i¬ %·Jn•Ü‚¢”¢”¢(9Yr²ä$¨««ƒzƒzƒz¨Ž«Ž«ŽƒÚBm¡¶Ý1Ý1Ý1ÐÓÓmymymyPŸPŸPŸÍZÍZÍZ0l3l3l½^¯×ë!kFÖŒ¬pÁpÁpÁ-Z8´pÛ¶;mw‚X]¬.Vù—ò/å_‚E‰E‰E J*© è¦è¦è-&ZL   °ncÝÆº ØÌ´™i3,çZεœ –C-‡Z«T«T«T°icÓÆ¦ ؄ڄڄ‚mÛ6¶mÀ¦³Mg›Î`;ÅvŠípXæ°ÌaØZÛZÛZ—Ž´ÁB° Œ`¯`9a‰äÜáÅÔÚ:^¬îÙ˜—ÎGbØkØ pµÓÕNbU±*À¿Âÿ «#{éš;²vd¬m¼¶1À†¤ I•õ•õ/Û¾ðXá1€ë箟ðîìÝ ÚÇÕ>à·þí?®nøããw¶¼X}ñÅ*„’—*3€®‡®‡®L´˜h1ÑzÓû›Þß@S›¦6MmÌNòÊü¸,© ˆôŽôŽô†uÖXw.Z¸há"PUU-]œHØ%ìv%d Y?k¯?ýéÿ³%Éïð°ÕÃV‘]#»ô]Õw€ü‰üÌÀ*ù}ÊÌ%1YL“Ax,<ƒ|‰|‰| 0•©L5w:É+óÉÿGñµãkÇ×PPP°/°/°/(ýýË”Ót0wx‰äŸ*xrðd€À?o”o4w&‰ÌÜþ*¦1¦1¦1`¼a¼a¼²²2é&§¼··7ðòôòôòüãíI$’ßCÞNÞÀò±åcšÑÌÜ™$e¦OŠ'Å“ ,– Ë@¶D¶D¶ÄÜ©$¶Œqã2ÆW]¯º^uÍF"‘H^e§Ø#î÷€i­i­i-ÈöËöËö›;•äÏ¢ª¨ª¨ª¹Ñ¹Ñ¹ÑP±uÅÖ[›;•D"‘¼>ÊL`šhšhšÌb³@6G6G6ÇÜ©$–ÌØÌØÌXÐêõà¥öR{I¡H$f’´*iÀ…öÚ˜"M‘æÎ$)3€øT|*>å§ELdÏdÏdÏÌJògÉ=:{4Øî¶Ým»lFØŒ°‘£“HÌ$黤ïÎ;? ÀtÏ$M=nveæ)ÓÓÓ0µ0µ0µy]y]y] B ÍNòªeÞμyŽ GXhý¡õ‡ÀZÖ²ÖÜé$’²¦ö°ÚÃÞ x@¡T(Ì`sg+»ÊL Æ‹ñb<‡„CÂ!õ—õ—IÏuÿc%´Lh™Ð¼ßò~Ëû-·’·’·2w*‰¤¬RQùù¿’×AÙ¹0[œ-Σ§ÑÓè B+¡• þqŒÑÆhc4¤_L¿˜~¼y7ò–¦º•H$’ÿPv €t1]L/]ýŒ (øÃÍJ^3úÙúÙúÙß5¿k~Wð˜è1Ñc¢¹SI$Éë§Ì‚L 2À ,ÌFòg)ÙP²¡d¨¬UÖ*k('/'/'7w*‰¤¬ÓtÔtȽœ{®ý¿ÊL€øÃb8àXcµ¹CI^µôö/V5S8(àÞ˽—{/s§’HʺÛooXýñê ïÞ1w&I™)Ä(1JŒE_E_E_È dÒ%€œÔoS¿Mýœ:;uvê 6J¥ÒÜ©$’²Î³™g3€ºWê^“3w&I™)xÆ3žüˆüˆüȾ’}%ûÊÜ¡þ:†C¡ÒW¤¯H_ùkó׿ÿ‡Ë¨•Q+£¸ãŽ; Ôêuþp³‰äñêÿà-«·¬d³e³ÍIRv €©Q£¦tÝú¿Ø­Ž·:ÞêW¢¯D_‰B %ôÏßsžç<ÏyÂÖ°8ÝòtËÓ-áöíÛ·o߆k“®Mº6 TóUóUóáÔ¤S“NM‚ýWö_Ù à à Ãÿúýõ[¥L™><çxÎñ”fz”H$’_Tö 3Kn›Ü6¹-$$'$'$ƒ¸Z\-®þõ¯×¨4* Òj¥ÕJ«´¢ÿåqFÝÝÝ_¾(|4šÑhF£ÐzZëi­§Aâ–Ä-‰[ ¡mBÛ„¶`3Ëf–Í,Èl“Ù&³ |»üÛåß.Ý{º÷tïANýœú9õ!_ÌóEsïÍRÚ.Ú.Ú. ~?ƒŸÁÜ©$‰äõUf&úõ¨G=oŠ7Å›Þ%½KzÐ××—î.Ý]ºƒC¬C¬C,0ỹÜ~¹ýrûAÑÇE} âNq§¸\÷¸îqÝ%”|PòÈÈÈ€©©©ض·moÛšÞjz«é-0›ŠMÅ JV%«’!§CN‡œ //ÆcŽ1\Žºu9 Ê}Ê}Ê}püäñ“ÇO­ž·zÞê c¢ÇD‰·ûn÷ÝîƒPK¨%ÔÚІ6³4giÎRˆ;w.ªªªª‚õiëÓÖ§¡™¾™¾™Lz“Þ¤A#h ¸Ä¸Ä¸Ä€¬ž¬ž¬Á*ù*ù*9ÔíU·WÝ^V-¬ZX5°Üj¹Õr+d®Í\›¹Ô>jµ¸œq9ãrì‚í‚í‚áùÏßxþXܶ¸mqLßš¾5} ö5íkÚ׃ڠ6¨Áeˆ2D‹¯‹¯‹/0ŸùÌÿ峨±Ø±ØTsTsTsÀ-×-×-×Ü™D"yÁ„éÅ¿wMwv ; 4w¶²«ì?Üý/;/;/;‡ìÙ²ƒ [.l¹°|‹}‹}‹Ák¦×L¯™Ð³jϪ=«BäÕÈ«‘WaOážÂ=…P9¾r|åxH´M´M´…:ß×ù¾Î÷‘‘‘ Éß$“ü Ô^ox½á¼"xEð Hذ;a7\¼|ñòÅËðÉŒOf|2Æí·oÜ>hóe›/Û| •,*YT‚Üþ¹ýsûÈ3#ÎŒ8g£ÏFŸ†˜1-bZÀ“EO=Y.^.^.^ _,_,_ ¦¶¦¶¦¶è’è’è9-rZä´€¨žQ=£zBíÚ!µCàÔÑSGO…k+¯­¼¶6MÙ4eÓ…D!„]Â.a¤^M½šzŽß;~ïø=PÔWÔWÔ‡úƒêª?ââââââàDË-O´„òÃË/?²S³S³SaxÎðœá9ðUׯº~Õr–ç,ÏY!Y!Y!YP{oí½µ÷Âãk¯=¾ÉÆdc²fœ9pæ@P ø¯k±¶X[¬±™ØLlŽFG££H%•TstIY÷´ÞÓzF<Ðmn·¹²8Yœ¹³•]e§°ÄK—‰ËÄe€-¶ØÂ…E]XÚ/µ_j¿„> û4ìÓ …B¡ÃdÃdÃdØ8uãÔS¡î³ºÏê>ƒÁ÷ß|RÆ¥ŒKúúú OÐ'è!sbæÄ̉0ðÐÀCE‹€E,bq=âzÄÊ)?¤ü°i5Òj$4ŒiÓ0Ñø‹Æ_À`§ÁNƒàñ'?yü T¾RùJå+ h¥h¥hÍŠš5+úÏîÊ&É&É&AH¯^!½Àk‡×¯•³*gU΂gÍž5{Ö N}pêƒS€h#Úˆ6@ $€8H$¿H¿H¿H(÷¼ÜórÏ!´ehËЖPa~…ùæÃg ?[øÙBèà×Á¯ƒtÜypçÁ0(zPô hx|âñ‰Ç' üíò·Ë߆¯¯/xgí;kßY âuñºx*¨t ÒÐxj<5ž o(o(oø¿?Þì³?Ìþ,¶[l·Ø¡¡Á½‰ä×(²*²H½Ÿz@tÍIRv €BÃÃÃ0F#ŒÐË£—G/X¼rñÊÅ+aäᑇG†¾î}ÝûºCûík´¯)>)>)>Ð¥S—N]:•6ë½Ä{‰÷’Òÿozjzjz 6mÛ4§·œÞrz‹#`&~º=]Ø$l6ËYÎr~™/‰—ÄK`]Ùº²ue°‰·‰·‰‡,ë,ë,kµ“µ“µqš8Mœö+úýãÄGÇ9Îqà׸Ìe.s)!Œ0€ÛÜæöÿnG<$±‘±‘±$^L¼˜xnl¼±ñÆF(Ì,Ì,Ì!LÂ@þ©üSù§ 4š ÍÀömÛ·mßÇ›Ž7o–¾S7§nNÝ~ûÇ›à™à™à åüËù—óÛDÛDÛD³q‰ä'5ËÕ,Pybå‰r¹\š ËìÊL \® WAØ*l¶‚ñ{ã÷Æï!0(0(06 Ù4dÓ¿~+ü,‹^½,ÞØüÆæ76ƒò]å»Êw¡PW¨+Ôý—7úa¤v´£ÝK~ÿã w%+YIéój=éIO&„ `êdêdêÚ m†6ìOÙŸ²?™2d³˜Å@ozÓû¿äÑ¡CÂa€0ˆ'žø—ìŸÕÂja5Ѓô ´`YÆ2–Dìb»€L2Éa†0C˜ÎíÛ;·‡†£Žj8 Âv†í Û ={&öLûÇöíÃ-ñ–xKs˜Ãÿ™C¢ ц€©’©’©Øl·Ùn³ŸFl~IúÝô»éw¡¼oyßò¾f9Ä$É/²ÚoµÀ «?XÂ’?Мä•(3OÈ>•}*û„ B¡ˆÞ¢·è ûî컳ï\œqqÆÅ «)«)« UrªäTÉå)å)å)èZܵ¸k1\H¹r!ÎÆŸ?‘±‘±‘±ù óAæÈ>™}2û$dŸÊ>•} c c cÀÔÞÔÞÔR3R3R3 Cþ†ü Y1³bfEÐûëýõþÝ1ºctG88÷à܃sÁù ç/œ¿€zwëÝ­wœ>rúÈé#ˆ½{7ö.Ü(¾Q|£ŒmŒmŒm~ÖáCâS}J¥ƒÒ&.˜¸`âðxÓãM7!ìNذ;à8Òq¤ãHÐkô½xÎsžÿ¬¿yÌclÁÆåË—ž.ž.ž. Þ©Þ©Þ U×V][u-Œ >*Œ;;;¡ÚØjc«…Q_ŽúrÔ—`3Ãf†Í ˜æ>Í}š;ÄLˆ™3 û û û` ï@ß¾q-âZÄ5(*)*)*«3Vg¬Î€ÖVk«µ…ö¾í}Ûû‚&\® Ãdž —Ænº§éž¦{ ¤CI‡’ ?*?*?úË«f™f™fä¨sÔ9jð™ã3ÇGzþ_"‘Hþ'Aü¹ƒüÙ ?)ü¤ð˜ºcꎩ;`¸ípÛá¶P3ºftÍhóå*©WR¯¤ô|»çÛ=߆ñúñúñzh3µÍÔ6Sͽ×^)}Sú¦ô…ëg¬Ÿ±æ?šÿhþ#ðhèÑÐãWÜ<(‘Hþ 9696™þ™þÁ‡ ›;[ÙUf.k…µÂZ0ùš|M¾`R˜¦×`ü#Ù6Ù6Ù*XU°ª`i Ò¤5ÃJÃJÃJs§{ýe É’5lŽØ±9vvvÒÉkæqÓÇMv­ÞµÀèl”ž0»²SÌæs@^,/–ƒé¤é¤é¤¹SAÐÌ ™A3aý±õÇÖƒ]vØ!ŠEˆ¹Ó½þ²’³’³’Á¾»}wûî`=Ýzºõts§’H$ÿ®Jd•H€. º4—7w&Ékðø¯ñã„6¦|S¾)L‘¦HS$à…^fÌÕZh-´ZÓšÖæÞK?I±I±I±àõÔë©×SP\W\W\7w*‰DòïÊå”Ë(G¹?ØÁsg’”`¼0^ò•ò•ò• ˆâë0T<žñŒ‡øòñåãËCž6O›§…ZGj©u×××ÌòõcJ6%›’!õZêµÔkr7änÈ]à(G9úG[—H$’¾²s X‚Á´ß´ß´ŒaÆ0c˜¹SAôèèÑÑ£á›YßÌúf\­}µöÕÚ B…êW¼>{xöðìáðU÷¯ºÕ¶lØ`î^ýùô³õ³õ³!÷«Ü¯r¿bbbs§’H$’¿2SȲdY²,EÉ¢dQ`zßô¾é}s§‚kS®M¹6Ô½Ô½Ô½`°Ã`‡Á ¡¡ñ¿_ï¶ÎmÛ:(¹Sr§äÜly³åÍ–æîÕŸïÇÇ.K• *Ï=ž{<ÿãíJ$’?ƒ©ÈT/æb †sg’”@&“Éd¥7×éºéºé~Ç”³¯Šj¹j¹j9<^ðxÁã\\\i)i)i) †‹áb8<òäÿÈ.'\N¸œÃ"†E u#u#u£Òö¬|¬|¬|@vEvEv¥ôç)ÇSާ‡++®¬¸²"zEôŠè%'JN”œ(Ý.Gž#Ï‘ÃõÐë¡×Cá¦ú¦ú¦ŠÅŠâ×ðBQZ½´ziõ@¶V¶V¶Êm)·¥Üs§’H$/ùYägkÚ¯i`üØø±¹3IÊN K%€¥`)X  ]£]£]c¾<†Q†Q†Q ËÔeê2AwCwCwÔ#Ô#Ô#@»N»N»Ž·:Þêx+È;!wl<·ñÜÆsÞ&¼Mx›ÿlWh%´ZA®³ùÌb®Å\‹¹‘§#OGž†ô+éWÒ¯@Á„‚ `±j±j± †> } gcÎÆœµóÖÎ[;ŒþF£¿ùö×ÿ—23efÊLp~Ëù-ç·À.Ó.Ó.ÓÜ©$ÉËY¾kù.€Ã ‡ALd¢¹3IÊN/‹—Ń¥h)ZŠ Ù¦Ù¦Ùf¾<2™ƒ |}}Áw†ï ß’’’ÖyÖyÖyÐçAŸ}@Ç®»vì •ÄJb%îº;èî —4¼”¥,ÕÕÕxØôaÓ‡M\p®[»níºìììáa«‡­¶‚{ìy°º ì2°Ë@hÚ,´Y(œªwªÞ©zP¸¡pCáóí¯ÿ/mSÚ¦´Mà~Ãý†û : „N¼]‰Dòg¨>½út€¾}-äNr'sg’¼†ƒ»aª0U˜ ––– ½®½®½Néâ7æ’K.¹ Öë‹õKœ¼5ykòVØ•¾+}W:8Ìt˜é0noº½éö&ð™à3Ág?Íùÿ#qŽ8Gœž=7zn„ ·&Üšp v÷ÛÝow?84þh>ûø,¼ÿìýgï?ƒF_4ú¢Ñ &‰IbÒÏÚ±Ç{n7„ m¨m¨mu—Ô]Rw l~¸ùáæ‡àpÉá’Ã%8øÖÁ·¾N{ö:í… ©R+¤B¯£½Žö: ãúë?®?|‘ôEÒI ŒTF*_ƒ¿ÚEí¢vô–é-Ó[‚ŒŒ¿t3‘D"‘üfefàG?®Ö«}¤}¤}Ô¤&5ÿú%gKΖœ…¤Ô¤Ô¤TH•§ÊSå””¾u|ëøÖóÏÏ??ÿŽÜÍÁ&Î&Î&âóâóâó€ŠT¤"ÈkÉkÉk_ó5_ƒ»µ»µ»5¸wvïìÞ… ÌX6FM4°Ä‰ÿX¸ pA 8Ÿp>á|â7/‘Hþ)ò9@B«„VM¶7Ù +'+gîleW™+6ÜÙpgÃPŪbU±0º×è^£{™;•ä×:~,üX8\8záè…£0ï£yÍûdõeõeõÿxû‰äÏpuÉÕ%çMçM“ZLj h h`îleWÙ»cc…Ó §NzÑ ©øÛH(J(J(o…·Â[!ø%’¿‡;jìð¾í}@ž#Ï1w&IÙ» ðŒÕ«3 ›®›®›¬f5«ÍJòk¥mNÛœ¶¼W{¯ö–>7‰äoÂ!Â! ¢©¢ @p¤å€Í®ìvVvVv  Ó†iÃ@ôýD?s§’ü/Å·Šo߂̭™[3·B@ý€úÒ7‰D"ùÝÊ\`}Ðú õA0  Ök‰µÌJò¿d,ÎXœ±ŒÇÇǡ¢ ‹*˜áæM‰D"ù§(s€åW–_Y~º]‰®¨K]êš;•äI·K·K·û¡öC퇂]»vÒcÉßDÉÆ’Ï«<1ÿJ-¤/^fWæ «`«`«`ÐöÒöÒöÑWô}ÍJò¿Ä5Œk×¼›x7ñnV:+•ÎÜ©$ɯsÐýA›‡n `8f8fîL’2WX°`=ô½F¯±®XW”FÌï‡üM-M-M-/¼ðÓÓӈ߿+~T^QyEåæ+‘H~›òóËϨV' @vPvÐÜ™$eî1@«»Vw­î‚Þ]ï®wSSSs§’ŸŸŸÂ¦üMù›ò!õpêáÔÔ””1-bZÄ´€FµÕnTŒAÞYÞYÞÙÜé%É %ÕKªDΊœ Z¨Z +’Èä gΟ9 :ˆ>>•*àƒ¹ûòÏWæ ëëÖ×­¯ƒÉßäoò­ÖGëS:E°ÄOŸ§ÏÓUÓUÓUà!y¶ù¶ù¶ù ¼¦¼¦¼®]ºßS¾§|OçUÏ«žW¡ü½ò÷ÊßÏ‘ž#=G‚ínÛݶ»†4¤¡¹? ‰äÏ"îwX~gù€ÍE›‹/Û>'>'`e••Uü ~€þ–ý-äZ¹öß^PH!À¡§‡žÄôéP;°v Àã 7|øö‡oÈÏËÏÄëãõkŽ®9 öiا-µxé½>ªîªî»–îZ `ÿ™ýg].w¹  x¦xfî}ýú+s÷-„B °Üe¹Ër¨+©+©+™;ÕŸOÌsÅ\(®Z\µ¸*dÔȨ‘Q¢NFŒ: Ñ!Ñ!Ñ!Ú.µ]j;ЯүүåUåUåUp™á2Ãeø¤ù¤ù¤Aµ¡Õ†V N›œ69m'''pNvNvNå`å`å`°ªmUÛª6]„.Bv »…Ý@?úѨHE*‚ÐUè*tñxH<yyy`gogogò&ò&ò& n7ŠAWOWOWŠ7(nyyyPм yAsÈ7 o<{ö< b¾ù6æ[¸Ztµèj”Ü,¹YräoÊß”¿ ž O…§ªÖ¬Z³jM¨q¹Æå—Á3Ë3Ë3 î:Üu¸ BO¡§ÐÓÜŸ¦Dò{E‰°¡Ó†N}?èûÀ¼ñÒííÙ/x;àíÇZ޵ä'ä'^ú:µíÔ@|(>0T0ThTÔèÅŒ€½ä½~þ²JC* ˜Ÿ9?@øHøè¿õC1Q1 ’g%OC-ËŅÒIÿo¯»r3  £  Ù¡f‡lÚ”Á¿Ìüh¥×J¯•^`1Ñb¢ÅD>vøØáÿ„çPW°‚PìPìPìj=¨õ D" xòÍ“ož|†C„!<¿õüÖó[¨Ú¢j‹ª- JA•‚*àý¹÷çÞŸƒrrrX9X9X9€pG¸#Ü1w';qž8OœÚrÚrÚrPbWbWb©bª˜*BÌØ˜±1c!ºFtè‘‘2™‹Ì[¶ l R¤6H…šÖü°æ‡àpÃá†Ã ` X`î^JÊžœé9Ó­|´ ú‚ê \†¹ {ÙöyEyE¹ýrûTØTa€µ»µ»¹ûòW¸PéB%€ˆüˆ|€m´(^>ÜÜÙþze¶ø®ïw}¿ë ÏO>?ùü$ŒÏŸ3>ÇÜ©~;S?S?S?ˆõõõ‡‹\üàâpË÷–ï-_Pø)ü~P}EõÕW@á ‡6 ¾ù~äû¸|ïò½Ë÷ Üî ÷ÌÝó‰ÇÄcÿMþ7ùß@âèÄщ£!"'"'"¢ÞŒz3êMÐ^Ó^Ó^ƒº·êÞª{ š5jUTYPeȯɯɯ™»7’¾ÓgNŸ¸øùÅÏÞ|? BA…sg{‰ßŠßï ï`Äø²ínö¸Ù ýNú€Öï·~@9Y9ÙÜ}øãÊlpÄûˆ÷o¸1âÆˆ#`f§™fvYMYMYMs§ûe†Ñ†Ñ†Ñð¨Õ£VZÁÁ÷¾ð}ˆ;?v>TVuXÕaвzËê-«CÍ5Ô\6ímÚÛ´dÈÊÞ­Ÿ¯Žæ‡{œF?Œ~ Æ_a<c=ìuÛë¶× ®·¼ÞòzKèÛ!¶C,t íÚ%¬ ­ ­ ÍVòúˆ_¿àéŧÞøäOìkÚ¿Æ#“ƒ£Á`·çnO¿¿€Fg ¯áM†e¶¸wõÞÕ{Waì ³6Ì‚yOç=÷ìãìãì͸*UþìüÙù³a]Áº‚u»(vQì"viØ¥a— žXO¬'‚ÐRh)´4÷^”üOKX¸¿éþ¦û›`nn< = = áà Nøp¸Mp›à&ÍG!‘üM//œxr @æ´ÌiÏ< Û&ÛfîŒÿ©Ì^ ¶­Ek — — —Á`c°1ؘ/OþðüáùÃañòÅË/‡âÅ‹7œªsªÎ© õ[ÔoQ¿…tâÿ­L L L @;A;A;Ä‹âEñâo÷WÇ8ÆA­µÔz³·ÏÞ>{;ȪʪʪÂÛ¶ l!Û!Û!ÛÁÜ{KòçË¿‘@÷¦îMsgù0a†þ†þ†þ ‹ÐEè"€Hø+ƒÈ›Ë›´¿Üþ2@ÿ¯û ¯ë‰ÿGe¶° ³ ³ CCCóº9º9º9°®ýºöëÚƒm;Ûv¶í`⬉³&Î÷'îOÜŸüïvŒ###!:(:(:îÕºWë^-0ùš|M¯àÚa±g±g±'DµŠjÕ 455!MŸ¦OÓõÍ×6_Û ù±ù±ù±¿ÜNÑÝ¢»Ew!ªNT¨: }¤}¤ýõÑ~¬ýXû1쪼«ò®Ê°ø»Åß-þâ†Ç »<ìò° Õ.ª]Tr«æVÍ­ ×ß½þîõw!}Wú®ô]¯>—K}—ú.õaìÙ±gÇž/¥—ÒK «¬Z°j¨k¨k¨k¼ú÷•˜[Êê”ÕŸWû¼@ÜŒ¸¿½UgUgUgˆÐDh"4Ð2¡eBËW—2mHÚ´!ðÔö©íS[Ðí×í×í‡'›Ÿl~²n¸=âöÐ_Ô_Ôÿ—B:Í6Í6ÍžZ>µ|jùâʸø'Ü4—1>c|ÆxX³wÍÞ5{aýùõçן‡Ìa™Ã2‡ÁÃj«=¬Z£Ö¨5BâÑÄ£‰Gáúþëû¯ï‡’+%WJ®¼ÊD‚à ¸¯¸ÿêûûªý_{÷Eµ÷qü3»Én’MϦJB º€éU^A¥ ˆ‘"ˆå"E¥H“* Ò!ô"Uz/¡†$„@éÙlʶìîó‡záQ¹Š{¹9ïx½6“9¿sfÂ~wgæœRbbbÀüŠùó+`}|úøô@C !ЎÇ9Ö²–µpÆýŒûwX¼2xe0’ I†$]º(tL¸?áþ„ûàââ&“ƒÉŒ?4~ú$}’>éçÈ ›Žt¤ã_ÔüÔüÔ|ÈÛ·;o7× ®\‚ׯ ^ã_ÿúø×!âZĵˆkà³Âg…Ï poäÞȽX:X:X:<ÜŸ5Ök}]}]}]0¬1¬1¬bˆ!æïŸÎ;ìü1¼ñào<€Ã£:< |pðÁÁçp" ÏI`¯À^­Þoõ>€½ÙÞüä{qºítÛé6¨•j¥Z Æ·oßccc0l4l4l^åU^ÓVÓVÓV0Õ7Õ7ÕkµÀZ¦ö¦ö¦ö`zÅôŠé å(-Ç·ßr< ,;°ìÀ²àÐÛ¡·Coñ ñ ñÉ_ò—üÁ¼Ë¼Ë¼ ÖE¬‹X¿=øíÁoÁºÎºÎºZi5¦Õ˜Ÿg%x$GÉQrc}c}c}0Ž7Ž7޽J¯Ò«ÀTh*4>ùxĈ?#Œ0oÞ,¼ÔªZ«j­ª0¦`LÁ˜pè6Ðm '''ýDû‰öùùýGîÒ7¯4¯4¯|¸Jl‰ªDU¢J(¡äiœ§sOçL•O•”|QòÅS<ÍžP©› øWNr'¹“':Ntœ9Ós¦çL~íŸ3œ3œ3€ª¢ª¢ª"DÞˆ¼yã)ìxÛØY5³jfÕ„­Ã·ß:¿úþj(Û¶lÛ²m¡ZrµäjÉ0Û~¶ýl{Ñ}D÷ÝÁþ{ûïí¿‡/{ÙûËÞ0j¨ £&€}Sû¦öMáË_ŽørŒœ6rÚÈiPij¥©•¦‚”)eJ™P8¡pBáصo×¾]û þõø×ã_‡ R©‚5ðö·AsSsSs¢VF­ŒZ 'Ê(w¢ômÞ·yßæP‡:ÔùÝ/h]к 5\]]ARó¤æIÍaOù=å÷”‡¨³Qg£ÎÂìe³—Í^¯¾Zøj!´£íÙ4@ k¸5Üvlرa$WJ®”\ Œ¹Æ\c.¼2õ•©¯L…F4¢Ñ?8l“#&GLßßß8ÕàTƒS  èô|NIábee·Žß:~ë8¬ö\í¹Ún¿~ûõÛ¯CÓð¦áMÃ!ghÎМ¡°ÑþEûÁ¿öükÏ¿öÀùù9Ú|hó¡Í0¹ýäö“ÛÃóÎ8‡:ê|¨3|üeð—Á ¹In’ÛÃS¥4JiKG,±tD6‰lÙ###àÆ¿nüëÆ¿àH¥#•ŽT‚¡aCƆÁŒÈ‘3"!*"*"*¨Le*CjßÔ¾©}a´ÇhÑà½Ä{‰÷’Ç÷?ùXò±äcÿjü«ñ¯‚b¥b¥b%¿|üòñË`-¶[‹aÙÌe3—Í„OZÒú“ÖàÔØ©±Sc ‘DA:#‘΀f¯f¯f/¬¼¾òúÊë`lglglÆÎÆÎÆÎðF·7º½Ñ ‚cƒcƒcÿÉ‘«1»ÆlS¦)À2Ë2ËvçQ©ý@~J~J~ T%ªU ä•É+“WæùµMsMsMÓ"¦EL»•v+íV>…7§9ÍÁÇÕÇÕǺé»é»é¡÷ë½_ïý:lß¼}óöÍýSöOÙ?AvAvAvhWiWiWAÄ•ˆ+W ó­Ì·2ß‚üåùËó—C¹oÊ}SîÈè™Ñ3£'hÛhÛhÛ<ü²¶µ¶µ¶·¦nMÝšB°1Øl„Èj‘Õ"«AÓM{4íå_.ÿrù—!Ý;Ý;ÝÌÞfo³7Øo±ßb¿J®—\/¹½Jz•ô*<Àí펿ð¸œË—=.{ æÑšGk…°„°„°xuÁ« ^]ëT¬S±èÒtiº4Ȩ‘Q#£ÆœGäGäGàÚ›×Þ¼ö&l Û¶1 úå÷Ëï—u^©óJW`ñ«‹_]ü*ýy}#s”9Ê¡Â>¨ð\7\7\7üýý ÿÛ¤áÒpi8TŒ®]1úéw¤ßh°ªÁª«`‰y‰y‰8 p·­·­·­': „¤±Ic“Æ‚,[–-ˆ…! CB¢O¢O¢˜f˜f˜fmiK[°¦XS¬)Þxã 4Éh’Ñ$ªÖ¬Z³jMrrr€„c ÇŽçÏ9žs@§‰ÓÄsÿæþÍ¡ŸK?—~.psí͵7×Â…‚  þ¼ÿ¡ C†6„ò£Ë.?ê(ê(ê( zbôÄ艱0baÄB¸~7ün8kŠ5Å6H¤G¦ü•©d*™ ¶þkë¿¶þ îÔ¼SóNM9e䔑SÀxÁxÁxÖÝYwgݧqä¼ý½ýÚUoW@á¯ð·ÝyTjÀ¯\2]2]2¡à‚7 žã„ ; vì×®\üóýýÛ/SÕIAR²BY¡¬‚{÷ î îÉîÉîÉŸŸ²YŒ,¤[Ò-éH“¤IÒ$õ“õ“õéªtUº ²Ñ²Ñ²Ñ {Sö¦ìM~¾ru‰Ÿ×þÒ @Z!­V€4Eš"MY†,C–ÒYé¬tdkdkdk.ª#k(k(kR ©…Ôd!²YH“¥ÉÒdpþÒùKç/Þ§«« K..¹¸ä"Ìí4·ÓÜNðCÇ:þЬQÖ(kȇɇɇ4L& yyy 3é ÒHi¤4$wÉ]rÿý0JIR’”i÷Òî¥Ýƒ´OÓ>MûŽ•9VæX¸9ÿæü›óAÓAÓAÓJz—ô.ù—n~Ë-Û-Û- Ë–-, ¼Ë»¼ûlÏEáY0757¸5ëÖ,€â¦ÅMŸâî]^tG– K%<|¹ú¬ê³ªÏ‚¼áyÃó†CVë¬ÖY­A~F~F~¤•ÒJi%ÈNÈNÈN€Ô^j/µ–°„% í“öIû@ê u:<¼´ˆ#F B .ª&U’*I•@~@~@~àa²]²]²] 5‘šHM@j.5—š?ü»—w’w’wçƒÎ‚Ýq»ãvÇÁ8Ì8Ì8 §&NMœ s?œûáÜaN¯9½æô‚éÒ¤?ÒÎ"Ù"Ù"555xøº´MÚ&m{ØÞ¯ý¦ˆ" êR–”%eÁn|pãÈLÎLÎL†½.{]öº@vvvvv6dÏÏžŸ=ÿ©¹C8S÷L]€øyñóžâyñ„DøÑåG—AÛBÛBûËqÚì´Ùi3Î)œS8ç4@À8Æ1ŒõŒõŒõ ävÉí’ÛàÒÒ¥¥KKà~à@ÿžy@ äß×1aÂÄÏŽF€TEª"UyøºTN*'•ãß_éဠ‘†HC–eµX-V Pžò”ªP…*€=öØMiÊ£ÿQºãŽûÃÕíœíœíœÁ?Ø?Ø?Êö(Û£lðK÷K÷KdMƒl²É©µÔZj 8ãŒó#ûýõ£KðȨQ£~8räÈ—•.+]VBX·°naÝ Uv«ìVÙ0#jFÔŒ(p6:ÿü°î*ÜU¸ œÞszÏé=`‹Xô ÎáÓÑXrhÉ!€Ä’ħr ùvØaÇÿó_Ž,Y8ñŠxE<8h4à3>ã3NnÅŠ¨Nuªn¸áÆ¿Ï{©¡ÔPjxá…ÿ~ÜŽú¿,øëö¿þýv¡ ]©ï×í£‰&ðÀ ,e) Ô¦6µÙ¾1i Üà7Ài Ó@§PöÕ²¯–}Ê.(» ìðœä9ÉsÒ#¿÷KRK©¥Ôò‘×ý,Š(¢ø÷=ÿþì׺ùÀdßо¡}CðªáUëD„E„E„Áàƒ #rFäŒx*kÅXMVÀá‡$¼ðöSäùÂÓ¦¼©¼ Ю^»z>}žâMö}íûÚ÷…¢ÊE•‹*ÃÀaÿàýƒ÷†¨ÝQ»£vCùºåë–¯ Fo£·Ñî̽3÷Î\Ðh4`|Ëø–ñ-(ªVT­¨hkhkhk€®’®’®h 5…šBÐŽÓŽÓŽÝ@Ý@Ý@(’É‹ä`_ξœ}9Hž04îw;äœÿqþÇ`¨n¨n¨ùÕò«åWƒº?Ôý¡î +£+£+lb›À'Ù'Ù'Ônj7µÛÓ8rÒOÒOݼ»yÔßZëóN© øWG_;úÚÑ× Ö7Ö7Ö¦wšÞiz'°kcׯ®Í³o㢋6.‚«®vºÚ b,1– ¨|U¾*_[Žð¬éêꬹ³æÎš þeýËú—…>3úÌè3¨D%*ÙºJAþ•úK^#½Fz„¢¢¢ÐéŠtÿànî'Õ¶¤mIÛàc>æcø®Üwå¾+†&†&†&¶áY1éL:“~8÷ùÎæ¶æ¶æ6tÐq@Lj7þÿ]Ó™`TU–æ–æ¶.IxvŠºu(*SôŸ2û«J}pŽwŽwŽóióióiЩt*êùµï4ÄiˆÓTkP­Aµ qKâ–Ä-0gᜅsBÁ·ß|këQž–â ÅŠ'À¢r‹Ê-*/]¼tñ 9·¤[Ò- ø†oøÆÖ£&<©Ûñ·ãoÇÃg²ÏdŸÉàέ;·îÜ‚1•ÇTS¿ ü*ð+[W)<{r“ÜP5¦j €®†®€y‘Y<íñ?Dî'÷ˆ¾} öKµ_²uM¿'€›ÂMávj;µt7t7tOcF¾¿Éo‘ß"¿E0.|\ø¸p¨âUÅ«ŠüËù_Îÿr†3VÌX1r·æn͵áݣ¦‰ÕÄjbaÍŽ5;Öì€O?ýôÓO?…‡‡˜¸i⦉› pEàŠÀ¶®Vxþj_¨} ûáî‡äSäSl]“ðô¸Ut«Тf‹šðóe¶®é÷D0)L ÈÎËÎË΃î–î–î–­«UwUwUw跢ߊ~+ Æ!Æ!Æ®Ÿ¼~òúI›46ill*ÞT¼©òÆçÏÏ¿§ž“8âˆmOmOmOغ=t{(ŒÝ0vÃØ pnƹçfÀ{9ïå¼—ï^}÷ê»WÁµ¯k_Wqwiöó¼°‚ŸàÏÏÉÿNò¸äqgÎ$ÀÏëóÙºôÒìÛ7€MÇ7Ș7ÐÖ5ý}¥v-€_)’IŠ$PtStStƒ¢~EýŠúÙºª‡$¤‘4P•ªT>U}ªúTg<Îxœñ€í—·_Þ~önÜ»qïF¨ëQ×£®DŒ>}ÊÍ,7³ÜL°Ûn·Ýn»­{óâ3eþÊü$7HnÜŽ÷:Þëx/8"þD<8p:átºevËì–ùpÞ§žN=zÚºzáÅ“?'ÀÆÓO¸Öw­P±cÅŽ¶®­4ºÒçJ€ÛSoOh6¶ÙX[×ô÷•úðë"7¿>÷ž«ÊUå>Ç›Ÿ”C‘C‘CÑÃÅgê­w¶ÞYˆsŠsŠs‚Cñ‡âÅÃôÄé‰ÓAí¡öP{@­:µêÔªµSk§ÖN?o?o?opòsòsò~äG~´uïþ |Îç|º£º£º£á•á•á營~~8œ¿qþÆù^7½nz]ˆèÑ=¢;ô[ßo}¿õP£{î5ºƒƒƒƒƒƒƒ­;#¼øªß¯~ ‚K»ÆvÿÓöù­ò[è4: €ºšº€Ýb»ç¸Úé‹ãç§¿ mTÚ(€ÀÄÀDÇ9Žÿ†ÖB š½×ì=€=Zô^–^¶uþ¾R?À¯f}6ë³YŸë@×®¡¿oßþ/àsø–8Kœ%²œ³œ³œáÂÌ 3/Ì„³ûÏî?»R‡¥KŽï:¾ëø.”K)—R.*¹Vr­ä ោþ øÕñ«ãW”¾J_¥/È^‘½"{P¡â¿8 =Ö/SƒZb-±–X0~jüÔø)d4Ìh˜Ñ§$NIœ7Þ\xs!$êõ‰z(º\t¹è2”ñ,ãYÆj{Õöªíµ«Õ®V»ø.õ]ê»deebù^ÁæŸ:| `Ó‚M †·Þ  üëå_ÿÃ_˜Ílk k ©²TÙÖ}øG~yÌÒÒÐÒ@–,KøÿËþ>´ûÌî3{ûïíc±\ ¸fë®<{"ü⻽ßíýn/h&j&j&¨3£ÎŒ:c몞Ë`Ë`Ë`ÈZŸµ>k=¤ÌO™Ÿ2®œ¹ræÊHèÐ!¡äÎÏŸ;yŠÁ}À§•O+ŸV o)o)oùO;!ÏŠáÃ;™Ç3xMðšàôºÓ€{Ÿßû`?/’ר»±7@ÍA5ýaƒ `:h: ÿXþ1€ì ÙÓ]Lm8ÃŒ½?/²õË…JñóPBÿßö£ °)hS@º}º=@¿%ý–¨.¨þð1Km[m[€’µ%k˜|M¾&_°Ýþuû×AY ,P€Ë&—M.›.&RsÍý5÷CàÔÀ©S!haР…à1ÇcŽÇU’U’U²È"ËÖGMž”r±r1ðËZ^N•¬J6@iVšÿÓöúú ®,¸ —‡ ýhèGòÉòÉô{—ú\êpüÊñ+¯9½æPöxÙã´ýƒw¼° Â‚ Q‰Q‰·wÞ ½'½÷ÿ~!‰$?³Ÿ@ÝHÝÀ~Ÿý¾ÿÔ×]®»þÿ ¸>åCò_L€_¸×r¯å^ V¬(X–.–.–.WƒûŸõë²¢&™If‚‹ã/Ž¿8âNÆŒ; Ÿ…~úY(¼Tþ¥ò/•óÛæ·Íoƒ!ÇcÈckckck0Š EÛ/·_n?È Ê Ê ‚ÂÖ…­ [Cq¿â~Åý@¿@¿@¿Jn•Ü*¹æíæíæí`þÑü£ùGÛËíåö Ÿ!Ÿ!ŸvûìöÙíe%e%e%pÊuÊuÊç=Î{œ÷€Ç;ïx¼žöžöžö ,¯,¯,Š E"èa‘'Êå‰<\Åì>÷¹ÿÈ8´§=ím}0áyó\æ¹  #ÿÒöУУm7·Ý `J0%ÈîÈîü§ß³7Ù›8Á éséóÿ´½ûP÷¡Ý¢ºEx;{;ÃÏ ÿá/la À˼À—äŸ;q à—{_î}¹7,¨¹ æ‚šðÍžoö|³?*~T”‚›ãŽn=ºõèVX¹ rA$ n?¸ýàö}#úF´ çEAžR?À¯¼ü¼ü¼ü äZɵ’k =¯=¯=o몞½SêSêSjøvË·[¾Ýoû¿íÿ¶?D‰>}ÄÖÕ ‚ ÏŠ¿poíÞÚ½5C 1'Ï“çý÷~Ïù=ç÷ÀœŸæü4ç'ès®Ï¹>ç éõ¦×›^¼ñÆÛÖU ‚ ÏŠ¿PlSlSlG‹£ÅÑš*š*š*¶®êé»Üår—Ë]`ÖüYóg͇ž=#zF@«f­šµjÔ¦6µm]¥ ‚ð¬‰ð ùUùUùUpÎrÎrÎMš&M“f몞žGn¹qf¤ÎH‘ :têЩ´Kk—Ö. ˜Å,fÙºJAáyà¿Näâlv6;›Aó“æ'ÍO¶®êŸ»»ã;`Æç3>Ÿñ9´¼ÙòfË›ÐiI§%–€,T*+Ï» ‚ ÿŸ¿÷Ñî£ÝGCÞñ¼ãyÇÿñnm&Ý%Ý%ݦ{ún¨µ¦ÖšZk û©î§ºŸé”tJ:eë*A[à7|—û.÷]™3g6zÓ›Þ¶®ê¯Ë+ŸW>¯<̰›a7š5 jýÜû¹÷sûJö•ì+ÙºJAÁÖDø õõõÈ?’$ÿ˜N™N™^€OÊEó‹æ͇Y/ÏzyÖËà¸Êq•ã*zf虡gÀÁÎÁÎALû$‚ üB€ßp‰u‰u‰C5C5C50ƒŒOcûgÄf3„Á¼éó¦Ï›:‹Î¢³À¨ £.Œºª©ª©ª©¶®RAøo#Ào8ëü­ó·`eeÆ{Æ{Æ{¶®ê÷LMMañžÅ{ïyx³ß>ø|àîÝ'ºO´u•‚ Â+ñ¥ðo¸^s½æz LɦdS2è.é.é.xغ8Àz×z×zV½úëÕ_C\J\J\ Ll7±ÝÄvà³Øg±X÷[Aø"ü†Û}·ûn÷A™®LW¦C–>KŸ¥•¿Ê_e»º¬C¬C¬C 6!6!6~ þ)ø§`»}ìö±Û!P¨TÛzôA„…¿á4Ûi¶Ólpí2Úe4<0<0<0@QDÙ°®}íöµÛ×bÝbÝbÝà}ãûÆ÷P^]^]^¼ñ ‚ OHÜðžË=—{.‡ì·³ßÎ~Ûvuœ¬~²úÉê°2ceÆÊ ˜20e` ÔhZ£i¦¶%AáE%¾x õRõRõRÈVd+²Ï¿ý+þWü¯øÃ‚á †/½›ônÒ» 4 lØ0ÐÖ£#‚ ¼èDx ïºÞu½ëÂóóóók7aÂþ„ýðµõkë×Vèð~‡÷;¼­•­•­•¶Aá…¸ðe>,óa™!onÞܼ¹ Oÿžþ½g×ÞÝ#wÜ=Ó¦M›6m4oÞ8:]ît¹Óe[† ‚ð¿F€Çð>â}ÄûèƒôAú ((SP¦ ÌÓoçþ¼ûóîσ©û§îŸºj­=´öPx#öØ7bA^W^W^×Ö£!‚ ü¯à1œv9írÚòòòPðrÁË/?½ýg¼ñvÆÛ0¥Æ”Sj@Å£V< ý×ö_Û-Ø«íÕöâî~Aᑬ¿°u!ÿm4r\#‡±²±²±2h©n©n©åååÈÑçèsôÐá«_uø Ü/¹_r¿E9E9E9À4¦1 TÓUÓUÓî7·anÃ܆0Y?Y?Y¾|7øn€á>Ã}†û€£ÊQåhÃùA„ÒA€_ܺ~ëú­ë°gž {&À%÷Kî—Üa_¥}•öUK-K-K-(t-t-t…J©•R+¥Â¦ðMá›Â! J@•€*°jϪ=«öÀŽ“;Nî8 Ó‹¦M/7½›ÞMS›Om>µ9¨^V½¬zFùŽòå *‹Ê¢²ØzA„ÒB<ð‹ÔC©‡RÁ”ÎS:Oé éo¦¿™þæã·X° `xtòèäÑ Š,>;‡í¶s¬KZ—´. ´ µ µ ¡úçÕ?¯þ98¼éð¦Ã›ðžã{Žï9Š7~AÁ6Ä=¿xEþŠü9¼±èEo,úóí}Ûù¶ómNV'«“®~ýóëŸÃ¡)‡¦šòp»ÝºÝºÝ:Xzýéõ§¡~›úmê·WgWgWg[÷ZA(­Dø…|||¼ÓéNït‚jöÕì«ÙÿÁ†§8Å)ðÏðÏðÏxøòõõ5dÆgÆgÆ?²ýHF2’’’`䀑F€­Ÿlýdë'`ɵäZrmÝ{A¡´à7*Œª0ªÂ(8fà˜cÀAí vxän|•·Ê[å a«ÃV‡­†ûƒîº?~<òã‘€u¢u¢õ–áíE/zAÞŠ¼y+ Ñ-Ñ-Ñ ,Í-Í-ÍmÝkA¡´à1zDöˆì M¶4ÙÒdËÃ׎9s8%%%plî±¹ÇæÂå¶—Û^nûÈÜpà \ǸŽqo´{£Ýí`ãW¿Úø¼÷ò{/¿÷2Ø]°»`wÁÖ½AJqàcxõôêéÕF„g÷ŸÝv?(++ƒç<Ïyžó`ÎÔ9SçLãwÆïŒß£³£³£3¼¼úåÕ/¯†a]‡uÖš7-nZ .¸àbëÎ ‚ ¥ž¢ÉŠ&+š¬€v[Ûmm·Ž=rôÈQ¸´ôÒÒKKád¥“•NV‚jUªU©V¥J”݆uÖm¨‹ÕÅêb[÷BAþ?1ÀŸ¸YöfÙ›ea𗃿ü%œò;åwÊB7‡nÝ MÓš¦5Mƒ÷»¾ßõý®Ö7¬oX_À„ “­«A„?&îxœªT¥*¬²~Èú!pøõï~ôMõMõMávÉí’Û%ÐîT»SíNAØëa¯‡½ŽxãA^"<Îæ0ìííÿc;/;/;/GË£åѶ.VAžŒ¸àqÓ˜ÆÐã\s=ÎÁ¥J—*]ªÇ Ç Ç Ð§_Ÿ~}úÁKá/…¿nëbAáɈ{þ¢sŽçÏ9¢7½¹èMø‚/øP/R/Rÿ…™AΈøà/rôsôsôUeUeUePtUtUtµuU‚ ‚ð÷ˆðYÏYÏYÏÕ`5X @9äe)KY[W'‚ OFÜ(‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ð¢ËXÆBÊî”Ý)»á²ù²ù²Jv”ì(ÙaëâA„…/˜[Ën-¨¥p÷.KIDAT»µ –6_Ú|is8’}$ûH6ÄoŽß¿ôXÐcAÈNÈNÈN€8Ç8Ç8Gø´þ§õ?­·æßšk¾­{!‚ ØšOJŽ9 !!=ÿæ·8Þâx Ð×Ô×Ôׄ·Ö¾µö­µàæêæêæ N“œ&9M;;; ‚•OT>Qîº?èþ (Ž,Ž,Ž„ëæëæëfÀGm=¸‚ Âó"À_$5‘šHMÀ¼Ä¼Ä¼®æ^ͽš w]Üuq\u¼êxÕδ9ÓæL(2™ŠL_Ÿ¢OѧÀ•”+)WRàtáéÂÓ…¸>q}âz°¼fyÍòÚãÛ×uÑuÑu›UoV½YR‡¦M K2–d,û(û(û(ˆÔFj#µ “ÎIçÀÑßÑßÑì7Ùo²ßæææ°î•u¯¬{æ š7hÞ Hú*髤¯Àêmõ¶zÃý1÷Çܧ矞z>\Ñ\Ñ\Ñ€±ØXl,†{Y÷²îeÁ§ Nœ áÄ>„ĉ€5Äb ±õQAÇÎÖ¼0üðÃdQ²(Y¬ë°®Ãºÿnþ»ùïB»þvýí`Ùée§—†&G›mrÞÔ¾©}S +]Vº¬tívívív(ÿVù·Ê¿ë—­_¶~¼zêÕS¯ž‚&4¡É4oüÔø©ñSÐ-Ô-Ô-ÝÝÝÈ?:ÿ4”l)ÙR²>lðaƒÀ' ?YøÉB¨·¾ÞúzëV´¢XZZÂõ¸ëq×ãà¾Ó}§ûNPì[ì[ì ·¿¿ýýíïa^y=æõ€Zµ2jeÀ%å%å%%ÔïX¿cýŽ n¦n¦n1>1>1>зRßJ}+Ê_å¯ò‡À€%J[;AáwÄ7‘uuu (¿S~§üÔáêpu8¸Ww¯î^4*hTQŸF}õ)ĵ‹k×2ó2ó2ó`ÇÑGw…V Z5hÕ:Duˆê‘ŠHE¤Öç­Ï[ŸÖýÖýÖý¿oß­Š[·*20d`È@ ƒšN5j:APvPvP68f8f8f€u¶u¶u6ÿþjßú™õ3ëgà´Êi•Ó*È È È‚°ýaûÃöCÕŒªU3à¨óQç£ÎPP¥ JAèáÐá‡Tz§Ò;•ÞÑ;£wFƒ_ ¿~-ÀñÇwß–A-ƒZA©‡ÔCEEE[5AáqDxRf̘=zôÀ*V±êá¥FR#©XNZNZN‚>SŸ©Ï„bm±¶X Nݺ;u¸½ûf÷Íî›!¯R^¥¼J`mkmkmûÚÏ!‡°Ö²Ö²ÖúýÈ'Ÿ| ?ýéÿðå¼y-òZ@rTrTr,[·<î¿7þÞx¨P! BA ''ö~ö~ö~àPÑ¡¢CEVJ+¥•¶>X‚ ÂãˆKOJ† àŠ+®Àְ摟{àH ¥†RCp<ïxÞñ<8rä< îÜ/¸øã?dk³µÙZðŽõŽõŽY5Y5YµÿÐþ¯û_*-•–½èE/À€H½¤^R/`£RH!H]¥®RW"¥H)èNwºƒ¹›¹›¹ÛÃÝ{FyFyFAØõ°ëaסO`ŸÀ> ¸¡¸¡¸ñ°½Dy¢Á}‚û€©©© ¤*R© p›ï6ßm>¨T*x`|`|`÷D÷D÷DP;©ÔNT1©bREpüÆñÇo "!"!"²eÊ÷Çß<(UJ•R¾|;ùvÃ%Ã%Ã%¸¿âþŠû+Àÿÿ!ÿCPFWFWFgë£%‚ üþ¢«9Ws®æÀÓÓ|–õYÖgYàZÕµªkU[W'‚ OF\xR,Xl]„ ‚ ü3"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"üER{©½Ô$³d–Ì@ÊPÆÖU ‚ Âß#ÖøUª@óZÏk=¯5ÄÿQüGŸ–Ÿ–ŸñÚxm¼²·foÍÞ vkìÖØ­–mZ¶iÙzlë±­Ç6‘‘±uoAá‰ðNŸ9}æô$:$:$:ÀòZËk-tÕ½*T¡ \ç:×y[y[y[hx¶áÙ†gÅ¿ ‚ðb—~C>Z>Z>:èp Ãp~ßù}ç÷¿}ùäòÉå“¡QÝFuÕµuõ‚ ‚ð׈µãéé Ú»¶wmï çõçõçõ¿ß®ßõ~×û]‡¥­—¶^Úd)²YŠ­«A„ÿL|𾡾¡¾¡Ð|UóUÍWýþ犗/)^‚ví"ÚEˆ7~AáÅ"ÀcÈRe©²ThòZ“ך¼^2/™×#£UqzÅé§Cí-µ·ÔÞbëjAáɈð'êΩ;§î¨Ð¥B— ]¾Þhr£É&CзAß}kë*AáɈ§~µ‘lëyëyëy°ÚYí¬và¶ÇmÛhÖºYëf­áZĵˆkЬQ³FÍì#ÙG²À²Ï²Ï²$wÉ]rI-©%5J(¡¶îœ ‚ üÿ3Àl ¶ƒ6H¤ ‚¼¢¼¢¼"Ð&i“´IP[[ š“š“š“œœ ùó+æW‹ÎEçFÉ(%(YR²¤d ð Ÿð Ül}³õÍÖ`Îþœý9Ø_e•ýUàÂù ç/œÙW²¯d_}Š}Š} (f+f+fƒj¸j¸j8¸[Ü-îP‡«ÃÕáà–ê–ê– ÎùÎùÎùàVÝ­º[uð\ã¹Æs 8}äô‘ÓGÀP†2ÔÖ£+‚ ü¯ù¯ À°Ì°Ì° òßÏ?ÿ}xÐâA‹- áX±„cŸŸAAA ™©™©™ $“L2(¿S~§üì?·ÿÜþsPUTUTUÏž <€K´K´K48UqªâTÊ;”w(Š]Š]Š] /‘—ÈKÀàcð1ø@VxVxV8 0XÌbƒ¹•¹•¹C¡ÆPÐètPt£èFÑ ÐžÑžÑžÜ͹›s7ƒ~´~´~4kkk€a²a²a2(ª*ª*ª‚G:uÀÿ´ÿiÿÓá–pK¸¼»zwõîú0HȳåÙòl[-AáEaó`íkíkí š›š›š›pÝåºËu¸žw=ïzÜê«ÿ­þ ¦¦vövövöà÷™ßg~ŸAЦ MA›  s@ç€Îäää ÑÑÑ ôQú(}@aQXP¬T¬T¬Ù@Ù@Ù@À<þB¡é¤“œá g€–´¤%à€á÷äG~óóó0Œ`TUFèVéVéVAæ¥ÌK™—àÞü{óï͇Ôz©õRëÁ]Ã]Ã]dgegegì{Ù÷²ïÁ;Ø;Ø;*&TL¨˜‘ªHU¤ "ÖD¬‰XNóæ;ÍV³šÕ¶:Ê‚ ›ç\pÁ2»evËì—¢.E]Š‚3µÏÔ>Sî¼7òÞHpã4Æi „>ªfWÍ®š AÊ e¼Çzõûð«udÈJíŒÖ¥Ö¥Ö¥¿6mþZÈX”±(c$•K*—T®.¹ºäêH™–2-eHU¥ªRU_¾4|)ÔÛToS½MÙ6²md[pñsñsñ³u¯A[yfÀXÝXÝXnn»¹íæ6ø1óÇÌ3áfß›}oö­‡ÖC u:ÖéX§#TWUWUWAèêÐÕ¡«Á~‹ýû-@MjRÓÖÃô˜ÊT¦BQrQrQ2Ül{³íͶpAvAvA—†^zi(XG[G[GC­ µ*ÔªÍï7¿ßü>Nœ8dI²$Y’­;#‚ #ûŒì3^Þóòž—÷€ìCÙ‡²m]´ ‚ðwýå é¨é¨ésÍ4wdÈ8qÞÕ¿«WUõUõUõüû±8áÅV2¢dDÉØ×{_ï}½aÍ»kÞ]ó.´Ò·Ò·ÒC÷sÝÏu?ö*{•½ÊÖÕ ‚ OêO@þ[ùoå¿ÓÚLk3­ 8ìuØë°†í¶gØðLóLóL³u7^<æ¹æ¹æ¹äšäšä ÖvÖvÖvPa]…uÖCÂ[W QDÜŠ¾}+fš9hæ ¨=¸öàÚƒ¡_r¿ä~É ’Ƀl]¬ ‚ðW=öºk‰µÄ ‹‡/¾x8¨T*•JD}õAÔ“¿ñgÎÉœ“9¾¼þåõ/¯ÃÁï~ðû§×‘ý1ûcöÇÀ–k[®m¹E‹:u†»6îÚ¸ ¾™üÍäo&ƒ¡¦¡¦á?‚ ³õØpdú‘éG¦CæñÌã™Çah­¡µ†Ö§÷œÞszïÉR_Q_Q_„š 5j•cWŽ]9öô:b?Å~ŠýPvRvRvÕfÕfÕfp˜î0Ýa:ìÛ°oþ `ºmºmº wÛÞm{·-<¨õ ÖƒZ÷£˜¯˜¯˜Š­Š­Š­<³Ç÷®Ù»fïð›à7ÁoôêÑ«G¯ Ë”eÊ2Ÿ^;ª}ª}ª} tR:)`ßÔ}S÷M…’Å%‹KþÆ¥š² eÊ&ÀÐC; í{çì³w¤´Ki—Òîé“ ‚ðlü.EEEÁΑ;Gî ¯^3¼fw?w?÷0qŒl‘l‘lØÏµŸk?2×f®Í\ —k\®q¹Ä9Æ9Æ9‚ÞSï©÷„c‚1ÁW†_~e8WWWÀ­š·jÞª Wf_™}e6ïïï@À[o¼A#‚FxØ®Óm§ÛN·A¶X¶X¶²ò³ò³òazÎôœé9°}ÝöuÛ×Aβœe9Ë  f@Í€š|0ø`ðAÈKÍKÍK…³ýÏö?Ûnt¸ÑáF8·îܺsëàÖ«·^½õ*àƒ>>¹“s'çN†[n ¸5RÝRÝRÝ ½Wz¯ô^pîö¹ÛçnÃåj—«]®úKúKúKì`ÛØ†E†E†Ep-æZ̵¸ãvÇ페n˜n˜n@Âü„ù óáR—K].uÔZ©µRkìììЋ^ôúûÇ3r\ä¸ÈqP½yõæÕ›Ãö˜í1ÛcžîÉ)‚ <;¿ ñoÆ¿ÿ&˜BM¡¦PˆêÕ#ªÇSlñ{¾ç{(Š+Š+Šƒ¬È¬È¬HX•°*aU¬l¿²ýÊöpLwLwL‚'Oý!ý!ý!8QåD•U`‚Ç  wÐ;èàXçcu†ñ•ÇW_ô)ú} °œå,jQ‹ZÎEÅEÅEhFjFjF‚Áßàoð‡£ÙG³fÃGE|Ù²d€± Æ6ÛŽ}wì»cßÁ­n}p똰yÂæ ›ávÈíÛ!Þ}ÝÝÝÐÿ ÿAÿHRù³ógçφVTXQæ†Í ›–K‰¥Ž.;ºìè2ØSeO•=UÀzÕzÕz6ÝÜtsÓMHšŸ4?i>üXþÇò?–‡tXÐîW¼_ñ~EÈß¿;7C9€+Oaú§Æ>}ûÀµ©×¦^› y²«™*˜*˜*€] »v5žA‹w¹Ë]`6³™ýðeŸ²>e}ÊBQbQbQ"èVèVèV€tN:'œp‰þÉUX7[7[73™ÉÌÿ°½9rà*W¹ lg;ÛAê#õ‘ú7¹ÉMý ûAö?üüñóðáâ¸b¤)F‚1;bv<ò¹õ¤õ¤õ$X[Z[Z[>|½jZÕ´ªi@_úÒv¶ÙÙfgú:èë ¯¡xUñªâU°Ç´Ç´ÇÞ ¼x7•§ÊSå ¹s'æNïsÞç¼Ï=Ò_îæÚ¤0)L Yª,U– ¦Ž¦Ž¦ŽO¿Aáéú]ðOóOóOƒœWr^Éy̳ͳͳÿήà /¼x¸šÞ/’“““““ÁËÎËÎËÜîFw#”L+™V2 ¬/Y_²¾(Q¢ééé @3fÌÀ V°ˆ ‚ˆG^_ÈBõ¨G=°î¶î¶îK}K}KýGêû%`H+¥•ÒÊGößntÆ0†1<œ"w0ƒ £Åh1B{uîÕ¹ÍúhÖG³`‚ÿÿ þмGó͹”"Õ–jKµAZ/­—Ö?|ÝãsÏ=>‡º“êNª; ÖÎ_;í|¨Õ³VÏZ=¡f»šíj¶ƒXßXßX_®\/¸(†*†*†‚K+—V.­ ¯A^ƒ¼ôë—U ¥yÒ$}”$—$—$ƒóç1Îc ´FhÐÀ|Á4(iPÒ Ð[ô½||| 8¦8¦8›6 l¹³sgçΆüåùËó—C™ì2Ùe²A§Ð)t ÐLÑLÑLà’à’à0Þ4Þ4Þ„Ô¥©KS—B™OÊ|Ræ0X ƒòÝòÝòÝÀ5È5È5´=µ=µ=A½T½T½\’\’\’ yJò”ä)à=Ù{²÷d”¥@ ¤ R©Âïû_P¡ BAH I I »ùvóíæCXrXrX2¨š«š«šƒ©±©±©1d~ùuæ×°4`iÀRÐËô2½ òìóìóì¡Ìƒ2Ê<Ö²–µ`Z`Z`ZIõ“ê'Õãaãaãa°¯j_Õ¾*KŒ%ÆKKK—a.Ã\†=ùqÌ=Ÿ{>÷š|4.^¼xñâEÊ e…ðŠêÕ+*hZ¡i…¦@=P=P=ÐÖAžµ§~Ë:É:É: rëäÖÉ­çcÎÇœ£n<ºÒÇ¥Kµ†0„!¶îœ ‚ð¼<óð8æqæqæq~:ýtúi¸™q3ãf\¨s¡Î…:Ò)¥SJ'(ÙT²©døûûCðÜà¹Ás!bqÄâˆÅà7ÅoŠßðlíÙÚ³õÙôìÚ´;hëá}yä‘úïôß鿃¼Nyò:Aκœu9ë Mž&O“CÂO ?%ü÷‚ïß †¼Ì¼Ì¼Lpvvvvv†ð¯Ã¿ÿjׯ]¿v}(7´ÜÐrCÁ³¶gmÏÚ 5H þy¹‚ ‹Ífà±:әΠWéUz¤ø¤ø¤ø@âáÄɇ!iBÒ„¤ po꽩÷¦BÁÉ‚“'¡d{Éö’íà|Öù¬óYPWWWWW¯ê^Õ½ªƒÇhÑ£ÁsˆçÏ! ÎRg©³Àm„Û· ,T* A¾\¾\¾äÊ?”R#©‘Ôd'e'e'A:/—΃eŒeŒe X/[/[/ƒ¥¡¥¡¥!˜˜˜@‰¥ÄRbÝÝÝÐ8iœ4N}*ûTö)ÈUä*r ±j¬+dÇdÇdÇ@NpNpN0è_Ó¿¦ ”””À½Ž{÷:º#tGès s sƒˆmÛ"¶A™žez–é vƒìÙ ºÐ….¶>˜‚ «ÿ¾ðg>á>C+C+C+(ò*ò*ò‚‚áà †Cª*U•ª‚´Vi­ÒZAöÛÙog¿ o·Æ4w5w5w¡èZѵ¢k`hlhlh ÖUÖUÖU ##’BRH &I“¤I`èaèaèÚ•Ú•Ú•àµÉk“×&]‘]‘]Ë6Ë6Ë6°.³.³.ËËË““Ç•Ž+W‚sŒsŒs ¸¹¹Ç1cÇÀ»wï>h 4ÁÏËÏËÏ œ—9/s^ª»ª»ª»`7Þn¼ÝxÀgœm}0A„Õ‹þ!k'k'k'Ð÷Õ÷Õ÷ÃÃÃ0L4L4LS9S9S9022i·´[Ú ×¢®E]‹‚u××]_wÞ_òþ’÷—€ëb×Å®‹AVAVAVìß°Ãþ PtPtPtåååPÎVÎVÎåDåDåD –Xbm=‚ BiUêÀßu­úµêתÒo–|³äø´Â§>­®¾®¾®¾¶®NAžŒ˜¼÷/²°°«Áj°€L2É|ñEAá#ûç»AáE#€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$Àoe“M6Fi_–¤0) ¤÷¤÷¤÷*Tü^ $zôèmÝ AAøÏ$ë/l]È‹b»b»b;Øí»Ûw·/dh3´Z¸ï~ßý¾;œH=‘z"ÚMh7¡ÝPöQöQöª?Tý¡ê-EKÑÈ&É&É&Ùº7‚ ‚ðÇDø c?c?c?è?¨ÿ þƒà‡ú?Ôÿ¡>°—½ì¶³íÀ+¼Â+ ;&;&;³[În9»% k;¬í°¶¶î… ‚ ügâÀo(–+–+–CK]K]K8;;­hE+`.s™ t£Ý ¨jPÕ ªÐplñ ÇÚºzAAøkDxŒhÏhÏhOjÔ,¨Ùã·«q§Æw rbåÄʉ¶®ZAþ#`nÀÜ€¹ÐüBó Í/üþçvÕìªÙUƒW­¯Z_µ‚¢XQ¬(¶uÕ‚ ‚ð׈ðŠÅŠÅŠÅÐħ‰OPQQyøó ø ø xh0£ÁŒ3l]­ ‚ <þDƒ 4hC#†F }øzÃà 7< ¡ýBû…ö³u•‚ ‚ðdìl]À»2õËÔ/Sš:6ulê   Ð*¿U~«|PÎWÎWηu•‚ ‚ðdž{¸k¼k¼k„ý¡ûC÷‡‚1ŘbL©—ÔKêeëáx„„„²Ã²Ã²Ã ¹¤¹¤¹v'ìNØ€[Ëo-¿µ-^´xÑb°JVÉ*Ùºèß³¬´¬´¬¯W½^õzÚèÚèÚèÀå„Ë —¶®NA°•ç>Àކ;îhßzëý­7´­Þ¶zÛê`ýÎúõ;[Çø‰Ÿø Š¿(þ¢ø HIIàQÁ£‚GÜ,7ËÍÀu®sÝÖÅ>ÂwÜA_[_[_t8Ðá@ø¦Á7 ¾iáêpu¸ÚÖE ‚ ¶òÜ¿°¼ayÃòTÝUuWÕ]0dÒIC&“˜ÄñÌy–w-ïZÞS¡©ÐTJ‹Ò¢´»ØÅ.[W÷xEYEYEYpåê•«W®‚5ÝšnMÔ¨@¡Ô÷üE²Z²Z²Z D‰`';ÙiëªAáïO‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B"‚ B)$€ ‚ ”B/l°¦ZS­©¹8sqæb¸àuÁë‚äÏÈŸ‘?t t t àfÓ›Mo6ÃjÃjÃj[Wýä4ÿÒüKó/¸}1úb4¤I?’~ÄÖU ‚ /º60ŠQŒQcÔáÃ}îûp\èp¡Ã…>+}Vú,˜7vÞØyc!gLΘœ1¶.úÉŽŽŽÁK¿XúÅRØþýöï·oëªA„Ý ¬·¬·¬·À´Î´Î´bbbÀQã¨qÔ€ù˜ù˜ùM š4 >vøØácðYí³Úç‘o̘?0AgÐù{ó÷æï=zô´WÆZÆZŒcccÁènt7ºƒåˆåˆå‘Oâ–ÖÖÃ`ô3úýÀ4Õ4Õ4˜Â¦€e‡e‡e˜CÍ¡æP°ô±ô±ôK‰¥Ä¬`+€ù˜Á4×4×4ÔoªßT¿ î¹î¹î¹`~Ãü†ù [AáE÷ÂÌhz×ô®é]زyËæ-›!¹qrãäÆàºÔu©ëRÈÞœ½9{3H_J_J_BbNbNb|=çë9_ÏÁ!ƒC‡€z”z”z¬,\Y¸²”½”½”½@}B}B}zÕéU§W0Ž3Ž3Žƒu6ÖÙX´•´•´• xLñ˜â1öZØka¯A¼y=ò`}ùõå×—‡Ô¦©MS›BþæüÍù›áå/·x¹„î ݺ¾nøuïBÍ÷k¾_ó}°¬¶¬¶¬†n»Mì6âfÄ͈›gLgLgLàÝØ»±wc¸q;ãvÔñ¬ãYÇÓÖGCAxѽ0ßœ>qúÄé°±pcáÆBè5¥×”^S wãÞ{7õ~õ~õ~°N·N·N‡PïPïPo¸Ÿr?å~ ä‡ç‡ç‡ÃâÅŠ!nGÜŽ¸Ðç‹>_ôùêm­·µÞVo—o—o‡Í 67ØÜ.Lº0éÂ$èÿzÿ×û¿}ä}ä}äà¶Ìm™Û²‡õï Þ¼_|eð¨1²ÆÈ#aÅÇ+>^ñ1¨·ª·ª·BÊK)/¥¼Î&g“³ Z,m±´ÅRH›š65m*Ì›7?Z·*nU ýÇõׄº†º†º‚¥ÐRh)´õÑA^t/L¸ÞçzŸë}À#Ä#Ä#Êf—Í.› öÉöÉöÉ µ”ZJ-<àÈ_’¿$ dñ²xYÌ6wÚÜiP©C¥•:Àøã;Œï cÆ&Œå<å<å<(©]R»¤ö#uô–zK½Áî»wìÞk×®ÀäÚ“kO® ªxU¼*¼'zOôž,e)KÖñïeƒÏr–³ì7NŠ“â€A b°ˆE,zdœqƨD%*Ùúh‚ /º&T-ªZTµ4:N£ƒKÕ.U»T ²‹²‹²‹ÀpËpËp Š»w+î…µ kÖý6ý6ý6(îZܵ¸+¹väÚ‘k¹ sAæh’Ý$»I6¸^s½æz LËMËMˡѵF×]ƒëšëšë¸1ãÆŒ3 Ë1Ë1Ëô3õ3õ3!ÿëü¯ó¿†¼!yCò†@ðõàëÁ×A}X}X}Œ)Æc ô)èSÐ 2ƒÌ ƒÂe…Ë ¹„Ò$¤IHpÀàÔW§¾:õä\ιœstMuMuMAwNwNwÎÖGCAxѽ07Ö)©SR§ú¥ôKé—Ç'Ÿp|” .\&Ýjt«Ñ-P,V,V,†äÓɧ“OC½µõÖÖ[ ¦–¦–¦–à<Ðy ó@8×õ\×s]A'‹“ÅÁЃC=Ök„Âß 'üí’í’í‚ïxçÀ;àeõ²zY¡rDåˆÊPe]•uUÖA×Ϻ~Öõ38xþàùƒçÁéªÓU§«Ð4¦iLÓHé•Ò+¥Ô­[?JÚ”´)if…YaV@Ⱥu!ë`”ý(ûQöpöÒÙKg/¦¢¦¢¦"T{©ÚKÕ^¿Ù~³ýfƒ¡º¡º¡:(£”QÊ([AáE#Yñ¼ܶ`Û‚m à䮓»Nî‚)Û§lŸ²ÝÖÃð¿«(«(«( †^zuèUøÈû#ï¼!¢JD•ˆ*¶®NA°•æ€ ‚ O‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P ‰ ‚ ¥‚ ‚P =ÿGq@EÙºû¥€ 2 4Ò€d’I¶uQ‚ ‚­=÷©€´Z-\Œ¹s1Æ{xìa Íhfëáø¢B… ' ' ' oTÞ¨¼Q`ï`ï`ï´§=ím]¤ ‚`+Ï}*àœ-9[r¶Àå —'\žú]ú]ú] u•ºJ]m=ÿC¬X±‚µ³µ³µ3xä{ä{äC5vÔØW®:\µu‘‚ ‚­<÷ ‚ ‚퉛A¡ú?aî #˰.zTXtcreate-datexÚ320°Ô50Õ54 14·2°´26Ò60²20Aë4¼yð.zTXtmodify-datexÚ320°Ô50Õ54 14·2°´26Ò60²20AëV„ŽIEND®B`‚rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_maxopenfiles.rst0000644000000000000000000000013215055603742027266 xustar0030 mtime=1756825570.248068247 30 atime=1764928592.917455273 30 ctime=1764935920.679538244 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_maxopenfiles.rst0000664000175000017500000000210415055603742026727 0ustar00rgerrger$MaxOpenFiles ------------- **Available Since:** 4.3.0 **Type:** global configuration parameter **Default:** *operating system default* **Description:** Set the maximum number of files that the rsyslog process can have open at any given time. Note that this includes open tcp sockets, so this setting is the upper limit for the number of open TCP connections as well. If you expect a large number of concurrent connections, it is suggested that the number is set to the max number connected plus 1000. Please note that each dynafile also requires up to 100 open file handles. The setting is similar to running "ulimit -n number-of-files". Please note that depending on permissions and operating system configuration, the setrlimit() request issued by rsyslog may fail, in which case the previous limit is kept in effect. Rsyslog will emit a warning message in this case. **Sample:** ``$MaxOpenFiles 2000`` **Bugs:** For some reason, this settings seems not to work on all platforms. If you experience problems, please let us know so that we can (hopefully) narrow down the issue. rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_mainmsgqueuesize.rst0000644000000000000000000000013215055603742030167 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.407700306 30 ctime=1764935920.677538214 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_mainmsgqueuesize.rst0000664000175000017500000000306515055603742027637 0ustar00rgerrger$MainMsgQueueSize ----------------- **Type:** global configuration parameter **Default:** 50000 (v8.30.0) - may change **Description:** This allows to specify the maximum size of the message queue. This parameter is only available when rsyslogd has been compiled with multithreading support. In this mode, receiver and output modules are de-coupled via an in-memory queue. This queue buffers messages when the output modules are not capable to process them as fast as they are received. Once the queue size is exhausted, messages will be dropped. The slower the output (e.g. MariaDB/MySQL), the larger the queue should be. Buffer space for the actual queue entries is allocated on an as-needed basis. Please keep in mind that a very large queue may exhaust available system memory and swap space. Keep this in mind when configuring the max size. The actual size of a message depends largely on its content and the originator. As a rule of thumb, typically messages should not take up more then roughly 1k (this is the memory structure, not what you see in a network dump!). For typical linux messages, 512 bytes should be a good bet. Please also note that there is a minimal amount of memory taken for each queue entry, no matter if it is used or not. This is one pointer value, so on 32bit systems, it should typically be 4 bytes and on 64bit systems it should typically be 8 bytes. For example, the default queue size of 10,000 entries needs roughly 40k fixed overhead on a 32 bit system. **Sample:** ``$MainMsgQueueSize 100000 # 100,000 may be a value to handle burst traffic`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_moddir.rst0000644000000000000000000000013215055603742026052 xustar0030 mtime=1756825570.248068247 30 atime=1764928592.929455643 30 ctime=1764935920.681538275 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_moddir.rst0000664000175000017500000000106615055603742025521 0ustar00rgerrger$ModDir ------- **Type:** global configuration parameter **Default:** system default for user libraries, e.g. /usr/local/lib/rsyslog/ **Description:** Provides the default directory in which loadable modules reside. This may be used to specify an alternate location that is not based on the system default. If the system default is used, there is no need to specify this parameter. Please note that it is vitally important to end the path name with a slash, else module loads will fail. **Sample:** ``$ModDir /usr/rsyslog/libs/  # note the trailing slash!`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_includeconfig.rst0000644000000000000000000000013115055603742027404 xustar0030 mtime=1756825570.248068247 29 atime=1764928348.39370014 30 ctime=1764935920.674538168 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_includeconfig.rst0000664000175000017500000000563315055603742027060 0ustar00rgerrger$IncludeConfig -------------- .. warning:: This legacy directive has been superseded by the rsyslog :doc:`include() <../../../rainerscript/include>` configuration object. While it is save to use the legacy statement, we highly recommend to use it's modern counterpart. Among others, the `include()` object provides enhanced functionality. **Type:** global configuration parameter **Default:** **Description:** This parameter allows to include other files into the main configuration file. As soon as an IncludeConfig parameter is found, the contents of the new file is processed. IncludeConfigs can be nested. Please note that from a logical point of view the files are merged. Thus, if the include modifies some parameters (e.g. $DynaFileCacheSize), these new parameters are in place for the "calling" configuration file when the include is completed. To avoid any side effects, do a $ResetConfigVariables after the $IncludeConfig. It may also be a good idea to do a $ResetConfigVariables right at the start of the include, so that the module knows exactly what it does. Of course, one might specifically NOT do this to inherit parameters from the main file. As always, use it as it best fits... Note: if multiple files are included, they are processed in ascending sort order of the file name. We use the "glob()" C library function for obtaining the sorted list. On most platforms, especially Linux, this means the sort order is the same as for bash. If all regular files in the /etc/rsyslog.d directory are included, then files starting with "." are ignored - so you can use them to place comments into the dir (e.g. "/etc/rsyslog.d/.mycomment" will be ignored). `Michael Biebl had the idea to this functionality `_. Let me quote him: Say you can add an option ``$IncludeConfig /etc/rsyslog.d/`` (which probably would make a good default) to ``/etc/rsyslog.conf``, which would then merge and include all ``*.conf`` files in ``/etc/rsyslog.d/``. This way, a distribution can modify its packages easily to drop a simple config file into this directory upon installation. As an example, the network-manager package could install a simple config file ``/etc/rsyslog.d/network-manager.conf`` which would contain. ``:programname, contains, "NetworkManager" -/var/log/NetworkManager.log`` Upon uninstallation, the file could be easily removed again. This approach would be much cleaner and less error prone, than having to munge around with the ``/etc/rsyslog.conf`` file directly. **Sample:** ``$IncludeConfig /etc/some-included-file.conf`` Directories can also be included. To do so, the name must end on a slash: ``$IncludeConfig /etc/rsyslog.d/`` **And finally, only specific files matching a wildcard my be included from a directory:** ``$IncludeConfig /etc/rsyslog.d/*.conf`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_debugprintcfsyslinehandl0000644000000000000000000000013215055603742031057 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.323699311 30 ctime=1764935920.663537999 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_debugprintcfsyslinehandlerlist.rst0000664000175000017500000000052415055603742032556 0ustar00rgerrger$DebugPrintCFSyslineHandlerList ------------------------------- **Type:** global configuration parameter **Default:** on **Description:** Specifies whether or not the configuration file sysline handler list should be written to the debug log. Possible values: on/off. Default is on. Does not affect operation if debugging is disabled. rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_generateconfiggraph.rst0000644000000000000000000000013215055603742030576 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.375699927 30 ctime=1764935920.672538137 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_generateconfiggraph.rst0000664000175000017500000001623315055603742030247 0ustar00rgerrger$GenerateConfigGraph -------------------- **Type:** global configuration parameter **Default:** **Available Since:** 4.3.1 **CURRENTLY NOT AVAILABLE** **Description:** **This parameter is currently not supported. We had to disable it when we improved the rule engine. It is considerable effort to re-enable it. On the other hand, we are about to add a new config system, which will make yet another config graph method necessary. As such we have decided to currently disable this functionality and re-introduce it when the new config system has been instantiated.** This parameter permits to create (hopefully) good-looking visualizations of rsyslogd's configuration. It does not affect rsyslog operation. If the parameter is specified multiple times, all but the last are ignored. If it is specified, a graph is created. This happens both during a regular startup as well a config check run. It is recommended to include this parameter only for documentation purposes and remove it from a production configuration. The graph is not drawn by rsyslog itself. Instead, it uses the great open source tool `Graphviz `_ to do the actual drawing. This has at least two advantages: - the graph drawing support code in rsyslog is extremely slim and without overhead - the user may change or further annotate the generated file, thus potentially improving his documentation The drawback, of course, is that you need to run Graphviz once you have generated the control file with rsyslog. Fortunately, the process to do so is rather easy: #. add "$GenerateConfigGraph /path/to/file.dot" to rsyslog.conf (from now on, I will call the file just file.dot). Optionally, add "$ActionName" statement **in front of** those actions that you like to use friendly names with. If you do this, keep the names short. #. run rsyslog at least once (either in regular or configuration check mode) #. remember to remove the $GenerateConfigGraph parameter when you no longer need it (or comment it out) #. change your working directory to where you place the dot file #. if you would like to edit the rsyslog-generated file, now is the time to do so #. do "dot -Tpng file.dot > file.png" #. remember that you can use "convert -resize 50% file.png resized.png" if dot's output is too large (likely) or too small. Resizing can be especially useful if you intend to get a rough overview over your configuration. After completing these steps, you should have a nice graph of your configuration. Details are missing, but that is exactly the point. At the start of the graph is always (at least in this version, could be improved) a node called "inputs" in a triple hexagon shape. This represents all inputs active in the system (assuming you have defined some, what the current version does not check). Next comes the main queue. It is given in a hexagon shape. That shape indicates that a queue is present and used to de-couple the inbound from the outbound part of the graph. In technical terms, here is a threading boundary. Action with "real" queues (other than in direct mode) also utilize this shape. For actions, notice that a "hexagon action" creates a deep copy of the message. As such, a "discard hexagon action" actually does nothing, because it duplicates the message and then discards **the duplicate**. At the end of the diagram, you always see a "discard" action. This indicates that rsyslog discards messages which have been run through all available rules. Edges are labeled with information about when they are taken. For filters, the type of filter, but not any specifics, are given. It is also indicated if no filter is applied in the configuration file (by using a "\*.\*" selector). Edges without labels are unconditionally taken. The actions themselves are labeled with the name of the output module that handles them. If provided, the name given via "ActionName" is used instead. No further details are provided. If there is anything in red, this should draw your attention. In this case, rsyslogd has detected something that does not look quite right. A typical example is a discard action which is followed by some other actions in an action unit. Even though something may be red, it can be valid - rsyslogd's graph generator does not yet check each and every specialty, so the configuration may just cover a very uncommon case. Now let's look at some examples. The graph below was generated on a fairly standard Fedora rsyslog.conf file. It had only the usually commented-out last forwarding action activated: .. figure:: rsyslog_confgraph_std.png :align: center :alt: rsyslog configuration graph for a default fedora rsyslog.conf rsyslog configuration graph for a default fedora rsyslog.conf This is the typical structure for a simple rsyslog configuration. There are a couple of actions, each guarded by a filter. Messages run from top to bottom and control branches whenever a filter evaluates to true. As there is no discard action, all messages will run through all filters and discarded in the system default discard action right after all configured actions. A more complex example can be seen in the next graph. This is a configuration I created for testing the graph-creation features, so it contains a little bit of everything. However, real-world configurations can look quite complex, too (and I wouldn't say this one is very complex): .. figure:: rsyslog_confgraph_complex.png :align: center :alt: Here, we have a user-defined discard action. You can immediately see this because processing branches after the first "builtin-file" action. Those messages where the filter evaluates to true for will never run through the left-hand action branch. However, there is also a configuration error present: there are two more actions (now shown red) after the discard action. As the message is discarded, these will never be executed. Note that the discard branch contains no further filters. This is because these actions are all part of the same action unit, which is guarded only by an entry filter. The same is present a bit further down at the node labeled "write\_system\_log\_2". This note has one more special feature, that is label was set via "ActionName", thus is does not have standard form (the same happened to the node named "Forward" right at the top of the diagram. Inside this diagram, the "Forward" node is executed asynchronously on its own queue. All others are executed synchronously. Configuration graphs are useful for documenting a setup, but are also a great `troubleshooting `_ resource. It is important to remember that **these graphs are generated from rsyslogd's in-memory action processing structures**. You can not get closer to understanding on how rsyslog interpreted its configuration files. So if the graph does not look what you intended to do, there is probably something wrong in rsyslog.conf. If something is not working as expected, but you do not spot the error immediately, I recommend to generate a graph and zoom it so that you see all of it in one great picture. You may not be able to read anything, but the structure should look good to you and so you can zoom into those areas that draw your attention. **Sample:** ``$DirOwner /path/to/graphfile-file.dot`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_failonchownfailure.rst0000644000000000000000000000013215055603742030453 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.361699761 30 ctime=1764935920.670538106 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_failonchownfailure.rst0000664000175000017500000000117115055603742030117 0ustar00rgerrger$FailOnChownFailure ------------------- **Type:** global configuration parameter **Default:** on **Description:** This option modifies behaviour of dynaFile creation. If different owners or groups are specified for new files or directories and rsyslogd fails to set these new owners or groups, it will log an error and NOT write to the file in question if that option is set to "on". If it is set to "off", the error will be ignored and processing continues. Keep in mind, that the files in this case may be (in)accessible by people who should not have permission. The default is "on". **Sample:** ``$FailOnChownFailure off`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_umask.rst0000644000000000000000000000013215055603742025714 xustar0030 mtime=1756825570.248068247 30 atime=1764928592.967456815 30 ctime=1764935920.688538382 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_umask.rst0000664000175000017500000000107115055603742025357 0ustar00rgerrger$UMASK ------ **Type:** global configuration parameter **Default:** **Description:** The $umask parameter allows to specify the rsyslogd processes' umask. If not specified, the system-provided default is used. The value given must always be a 4-digit octal number, with the initial digit being zero. If $umask is specified multiple times in the configuration file, results may be somewhat unpredictable. It is recommended to specify it only once. **Sample:** ``$umask 0000`` This sample removes all restrictions. [`rsyslog site `_\ ] rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsyslog_confgraph_std.png0000644000000000000000000000013215055603742027520 xustar0030 mtime=1756825570.249068264 30 atime=1764929145.517822459 30 ctime=1764935920.693538458 rsyslog-8.2512.0/doc/source/configuration/global/options/rsyslog_confgraph_std.png0000664000175000017500000050751415055603742027200 0ustar00rgerrger‰PNG  IHDRØM`TRMbKGDÿÿÿ ½§“ pHYsHHFÉk> vpAgØM©aºß€IDATxÚìÝe|Tgþÿÿ×™‰‡8„  Ü)®A*hq+EZ(RJ‹ $!¸»O  NÜ]'3™9ÿßí»ým·$ t¯ç>2r÷çšÙýpΜsIþAá¢ÐwAAø+ ôàÏÒfh3´}$úHôH²H²H²´hÑ ŸD;öÇ0k:×t.T;VíXµc`>ß|¾ù|}‡AøtHû!ÄäÉ;’w@ O O ÜRÝRÝRuKë–Ö-AYFYFYˆ&šh}§ý0€é•é•é¶6¶6¶6à³Íg›Ï6hÚ0´a(HG¥£ÒQ}‡Aøx}t{`ùr¾œ/Ã…Œ 2àð³ÃÏ?'S'S'S˜?jþ¨ù£ ò«Ê¯*¿©¾T_ª`ðñUóŽßö[Ò’–};ûvöm8›r6ål lh±¡Å†PW[W[W ž-=[z¶„Š×+^¯x]ßáA>>zßÓuÓuÓuƒðÀðÀð@Ø“º'uO*¨z¨z¨zÀàƒ >Íã›Ç7emememÈ:›u6ë,¨BT!ª µ¨(Q¢Ô÷´þxÄ#PnUnUnë†Ö ­‚á5Ãk†× ftÌè˜Ñ°7aoÂÞxÒõI×']¡‡}ûöÐãzë=®ƒù:óuæëô]Œ ‚þé­%|“ðMÂ7àoæoæoaê0u˜:»tvéì½B{…ö «5Vk¬Ö@î÷¹ßç~Ç:þÓñŸàøÇ8þƒ2I™¤LÞð†7úžÖß“÷È{ä=™™ µ†ÖZk(xó:æu ªUªV©Z%ЮҮҮ‚{Mï5½×ü‚ü‚ü‚@§Ð)t ðêãÕÇ«4îѸGã 4T* õ] ‡÷ÁXžUžUžœ¾wúÞé{p|îñ¹ÇçBõEÕU_^ ¼x5§_œ~qú4>ÜtgÐAàŸàŸàŸFõêÕ‡þ÷úßë*W ® R²”,% $ ïiý7ÝNj'µƒŸŸ8·ñÜÆs!Ä-Ä-Ä ÚÍn7»Ýlð¨íQÛ£6ØÔ³©gSòZçµÎk §{œîqº/}¼ôñÒP}xõáÕ‡ƒW¯2^eÀ©ŠS§*À]îrWßÕ ‚ ”¼k`Z7­›Ö îͼ7óÞLð{ì÷Øï1ènênên‚WM¯š^5¡I@“€& X£X£Xoν9÷æø%ø%ø%À«¯z¼ê›<6yl‚ÎU:Wé\LϘž1=ê)ê)ê)PdXdXdXb‰% !!é{zrÈ©ªTUª &~&~&~ÀŽp"œ"œ"œ`—ÿ.ÿ]þá›á›á ƒ|ù òÖÓZOk= ŒŒŒ aQ¢„EàŸèŸèŸaUª„UÎc;í<z}Óë›^߀Õz«õVëõ]¼ BÉ)ös æ@ÌØ{zïé½§á‰ú‰ú‰ztëÑ­G7è¡ì¡ì¡óæÍBÖ’¬%YKàpÃà 7„ S/L½0kt®Ñ9ðÜí¹Ûs7”›SnN¹9 öV{«½áòˆË#.€Î'œO8ƒÖZk­µÅ0Å0Å0 ƒ 2ô=½À@2 GŽ(õFÔQo Œ;0ʆ” )…ý ûöƒK.¸tŒ?0þÀx°ïkß×¾/øæùæùæA M M èŽêŽêŽBøìðÙá³aOìžØ=± š¦š¦šC"†D ‰€fAÍ‚šAoƒÞ½õ=‚ Åç½X¶K¶K¶ œÜwrßÉ}pÚé´Ói'¨;¢îˆº#À3Ã3Ã3ãíÙt[­Æ®½~ôúQ\¸$p XT°¨`Q¼½¼½¼½ Ž_¿:~ Õ•êJuáIŸ'}žô¿r~åüÊAÚ£´Gi Gxðáàø£ãŽ?‚,ËÁ@yäé{zA'“ÆAÁØ‚±cáüŠó+ί€(ß(ß(_ès²ÏÉ>'¡“q'ãNÆ`º×t¯é^H[š¶4m)hy å–píѵG×AË!-‡´ýüúùõóƒ2“ÊL*3 ò3ò3ò3àÂý ÷/܇Ç:|œv;ívÚ ^s¼æxÍjÓ«M¯6]ß³"‚ðþþëVäTäTäw¤;Ò ö¦ìMÙ›†§ OžŸ“>'}NBÔ†) S@ò—ü%xÑáE‡`·ÇnÝgggý#úGô€Ïæ~6÷³¹`\ʸ”q)H^œ¼8y1EEEÂÍ 7+Ü¬íÆ·ßn<ôKí—Ú/ljÛÔ¶©­ïiü󊲋²‹²áÖü[óo͇½5÷ÖÜ[L™62m>v>v>và¶Óm§ÛNPTWTWT‡g?=ûéÙOàׯ…_ ˆ¯_;¾6 è< ó€ÎЮ[»níºI˜I˜I$¯O^Ÿ¼>|wÜYpg´¿ÓþNû;àÑÉ£“G'°±´±´±Ô÷¬‚ ü÷þsË'Ÿ|xãþÆý;øöí7^µÕþU{ðØæ±ÍctÑqDÇ`Þȼ‘y#Hß—¾/}¼zðêÁ«p5æjÌÕhÞ¸yãæa`äÀÈ‘Pú×Ò¿–þ ­ ­ ­áü¨ó£Î‚ƒyóæã ÇŽ/À»œw9ïrP-§ZNµœ¿Ï…¾969696p4òhäÑH8[ál…³ Þâz‹ë-†!“†L2 ”J%¨sÕ¹ê\¸öÓµŸ®ýGŽ›X›X›Xð)ïSÞ§<Ôq®ã\Çtststs ¢aDȆ°Ûy·óngHß“¾'} 9xäà‘Ð&¯M^›<0ˆ4ˆ4ˆÔ÷¬‚ ügØÀ²|³|³|áȰ#ÃŽ ƒ ‡/¾pù5òkäUUUP¾ |Aù(lZØ´°)\wuÜÕq°?uêþT(Ó·Lß2}Á;Ù;Ù;j}[ëÛZß‚&‡Éaþ*üUø+ØÛoo¿½ý W«ÎUƒçÏž; Eë­[´Ã†/ _è{ºJP@Ôâ¨ÅQ‹aŸjŸjŸ ž={öìÙ3è9¥ç”žS óúÎë;¯ ,°Òw¤ïHßÇ"ŽE‹€‹ .@ãvÛ5nG 1pØgÙgÙgê¹ê¹ê9\peÀ•p`Í5Ö€}œ}œ}x—ñ.ã]j\­qµÆUVH+¤úžA„ßû]{Úãi§=`­f­f­¬V +ø÷î;êdÔɨ“ò0y˜< "R#R#RaãÇ=Ž–•–•–ƒÆ;h,´ nÜ6    ±Jb•Ä*à?Ïžÿ<¸÷üÞó{ϡӨN£:‚>ûtìÓ,£,£,£ô==ú£[­[­[ !‘!‘!‘à·Ìo™ß2à7¸>J¥~Ö𳆟¼Ò¼Ò¼ÒÀÍÍ D}õmÔ·à‘ï‘ï‘›tnÒ¹ ˜xšxšxBÚ„´ iàÀóÏ<‡‹©S/¦B¯f½šõjÞí¼Ûy·ãŸ'£‚ |4ä±ëÑ®G»Éò¤Ó“NO:-Ë*{•½Êþíó)›S6§l–åMõ7ÕßT_–}†û ÷.Ë[}¶úlõ‘å4‡4‡4‡·¯Ï_ž¿<¹,ìu°×Á^²<Ü~¸ýp{Y^’±$cI†,¿qxãðÆA–åãòqù¸,üœ.9]rºÈr`d`d`¤,›0l° ²ümæ·™ßfÊrÔ¨!QCÞ¾^=U=U=U–ƒs‚s‚sdù+ƒ¯ ¾2å)¦\˜rA–Ã,Ã,Ã,eY·U·U·õíûdÙg©ÏRŸ¥²¬Y®Y®Y®ïêA~ïw«*R)ŠpjáÔ©'''Âëô×é¯ÓaYÀ²€ePñvÅÛoÃüÖó[Ïo ... ­©­©­ ¡“C'‡N†½{#öF€æ„æ„æŒ]4vÑØEÐØ¿±c0ˆ3ˆ3ˆÓwÿø•:]êt©Óow„š57jnðç7žßxB×]Ot==#zFôŒ€V¥Z•jU êfÕͪ›'Æwb,ß¶|Ûòm0Àg€Ï4jШA£ ò¶ÊÛ*oË!–C,‡€üD~"?Ñwõ‚ ¿÷ûåoKSšÒüó7F3šÑðÚäµÉk0žb<Åx Ìy:ç霧`|Ûø¶ñmˆ+W.®ì5Øk°×?2~d ݃»w†ó{Ìï1J-/µ¼Ôr}—ý髸]Åï*~_ÿúõ¯_ÿ ásÃç†Ï…=i{Òö¤Áµ]×v]Û^^^ÐôZÓkM¯×¯^¿zý ÚåÚåÚåƒÄ @ž(O”'W¹ÊUÀ 3Ìô]­ Âïýù;ha cÀÔÝÔÝÔŒë×3®s3æfÌ…é™Ó3§gBA@A@A,«³¬Î²:à9Ás‚çѸJŠb„b„b4ˆoß –¬Z²jÉ*è2­Ë´.Ó`ƒÕ« VpºÛén§»½}Ÿ]¡]¡]!˜&˜&˜~„Ko ‚ ü'¾bˆ!à‡~oε̵̵e'e'e'ø¢â¿¨}+úVôV²’•ú.ó‡Ù$³If“ wLï˜Þ1ÐúrëË­/ÃËu/×½|g{y¨1¿Ý®Eš!Ífè; BñyÿfŠ)¦ •ÇÊc­lek þÇ¢¿ŠZŠZŠZ@5ªQíƒÍ×JsMsMs…WÚWÚWZ}§Aøû{ÿöèVêVêVBÅ‹/V¼...¥ÎRg©áÞ…{î]€g5ŸÕ|Vž„= {/F¾ùb$iŠ4EˆÈŽÈŽÈ†»Çî»{ Âë…× ¯Ož8=ŸL“FK£¥ÑpÍæšÍ5˜ygæ™w 9'9'9f½˜õbÖ ¸Xt±èbDXEXEXÁ¼àyÁó‚áõW¯¿zýì´ÐþAðí o};bVŬŠY?õø©ÇO=à¤æ¤æ¤¢ì£ì£ìaòˆÉ#&€˜±1ccÆBô„è Ñ`Ò¯“~ô+¼>ðúÀëÖ3¬gXOHè™Ð3¡'äÌÌ™™3`kí ·6„ˆyó"æÁ²7ÊÞ( ÚëÚëÚëúž]A„OϧÓÀì$;Éœg:Ïtž º]Œ.lllÀÜÊÜÊÜ *_®|¹òeðôöôöô†Âv…í ÛA\µ¸jqÕ ü¤ò“ÊO‚²ÃÊ+; zvíÙµgWhy·åÝ–wáHБ #APþ|ùóåσòŠòŠò HI#iÀ¹–s-çZ ´SÚ)íÀú¾õ}ëûP>±|bùD¨Ý¾vûÚíÁ¥¹Ks—æðøèã£BjÔ©5 åg-?kùt½ÖõZ×k Ü­Ü­Ü­ïÙAøô|2 ìÿQA@A´QÚ(mŒ1Æä9òyÿ\DP^"/‘—¼Ʋ–e-ËZ=({Pö Ð¥éÒti 9IN’o¯“‘‘ÿÍöŸñŒgÀXÆ2öíÓÃÎ ;7ìX*,– ˜8wâ܉saçðÃwÍ8Í8Í8}O¢ §çÓk`:tè@Ú-í–vóö$<ði´@Zd“M6ÿ¼›-la  D‰¤ËÒeéòÛaÓv¥íJÛv ;…”:¥N©ÝrÝrÝr—ËËååü³‘Ic¥±ÒX +]é ò4yš< tñºx]üÛqÍüÌüÌü`íÒµK×.…/†1ü‹á°gÕžU{VAÚ—i_¦}©ïIAøô|2 LÓ@Ó@Ó^5}ÕôUSÈ,È,È,€¹!sCæBÆ÷ßg|ñÓã§ÇO‡¸ï⾋û2ªeT˨‰þ‰þ‰þ ]©]©] ÑnÑnÑnptÌÑ1GÇ@X°:au`Àƒ<ëÞÖ½­{ƒÃD‡‰áŒíÛ3¶p¿êýª÷«BÁ¸‚qã 55555*=®ô¸Òc¸Ux«ðV!Üv¼íxÛN];uíÔµ··¡yóå›/ß| Íž6{Úì)”Xj`)±H® ÂÍàý‡ø@þ±‡ÕjS«M­6Aíŵ×^ Ö®Ö®Ö®°ê—U¿¬úÊt+Ó­L70?e~Êü¬N\¸:*ØW°¯`GYtd˜‡š‡š‡‚c3ÇfŽÍà‹å_,ÿb9TTuPÕA ŒRF)£àÛ£ßýö(¤,MYš²,Í-Í-Ía½ëz×õ®à´×i¯Ó^¨~»úíê·¡Åüó[̇2eË”-Sz{ööìí C†$ i¸4\^¼*xU€R—J]*uIß“+‚ðéyÿ¦E‹hLcI$‘TüA .0\. \¸,xç‰QŒbÔ;ÿËoTMhB€Ýìf7¨´*­J fãÍÆ›‡Úwkß­}ŒF2\âï4”JT¢Ò;ÿý½ìeïÛ?›ÑŒfKXÂ;¿±9|çðÃwÅ?/‚ ÿ«Þÿâ?–GW—R—R—‚¢šE5‹j껬ßS-U-U-«t«t«tpYã²Æe $/L^˜¼PßéJ޶½¶½¶=ȇåÃòa}§A(>¾%“Lòï—$2+mVÚ¬4äÊ•7 6glÎØœ±cÆ&3™Éú.Læ™Ì3™£ÊŒ*3ª Ìqã:Ç*~YñËŠ£“(òÉÿ%ÿ8ê|Ôù¨3\êw©ß¥~PeW•]Uv½}Ô^j/µÊSžòúN-‚ðßûÓ‡¥,)KÊ‚üÐüÐüP(t/t/t»P»P»PX×g]Ÿu}`oøÞð½á07enÊÜè¶¶ÛÚnk¡{n÷Üî¹`Yʲ”e)}—ý÷¡UiUZ„ç…ç…ç_ˆ_ˆ_¨Ö©Ö©ÖÁ$·In“Ü Y|³øfÑ&£MFPŸPŸPŸÐw‚ ÿ½ßïývúy[ÚÒöíÕ;TîP¹ì)ØS°–?[þlù3x9õåÔ—S¡‚cÇ Ž0uÖÔYSgÁ„fšMh·WÝ^u{Ìí2·ËÜ.pËî–Ý-;ÐÓÓÓwùŸ®øöñíãÛÃÚçkŸ¯}?øáÀ Ñ–F[mÖ+¬WXCKç–Î-!¿k~×ü®àwÌï˜ß18®>®>®†ºuê¼W:.—Žóöòƒ (Ðwµ‚ ¿÷»=0ù˜|L>ñã/Æ_„B‹B‹B ¨r¾Êù*ça•¼J^%CÐù óAçaqÅÅW„¶§Ûžn{<®y\ó¸îµÝk»×†šOk>­ùÎ^:{éì%øyøÏÃö_Øa? y>äùçP¥z•êUªë{:>^9?åü”óœÉ<“y&N†œ 95kÖ„%C— ]2œp (šV4­h\kr­Éµ&°/s_æ¾L0ÝlºÙt3ÌX;c팵àVË­–[- ‹,² æaÌØ‡7%oJÞ¢¥h)q[A>:’ü¿=ð¼ÆóÏkÀÇ~8öÃ1(5¹ÔäR“Á÷’ï%ßKP§cŽu:‚¤•´’žä=É{’{Nì9±ç¤nKÝ–º å Ê”­O´>Ñú_7¾n|%6Jlþ7ýoúß„{a÷Âî…A'ÛN¶lßÞÇʪƒU«úžý)ºUt«èÜ5¾k|×ü~ôûÑïG¶KÛ¥íàÝл¡wCpŸç>Ï}(2Š xÕùUçWaõë=Ö5:jtÔhðèëÑ×£/tvèìÐÙLZ™´2i©_¤~‘ú¼qðÆÁp©Ê¥*—ª@¯ç½ž÷z^›¼6ymÚÑŽvúžA„·~×À(¢ˆ"ÈZ“µ&k ùõȯG~…óÏw>ß=mô´ÑSð<äyÈó”3+gVÎ ÔžjOµ'\¹~åú•ëèèèeUeUeUà#ùH>ÔUsTÍQ Û¢Û¢Û[>lù°%ìþv÷·»¿…¼‰yó&Âàƒ{ î­¼ZyµòeŽ2G™£ïé*yQQQQQQ°¯Û¾nûºÁÓõO×?]½æ÷šßk>tÖeX—aPêóRŸ—ú2eÊ<‡·Þzx+\Ì»˜w1š\kr­É5ÔjP«A­ ìå²—Ë^uCuCuC¸})úR4UªTìÏÙŸ³?>±>±>±Pc@5€ôTz*=Õ÷¬‚ üÞïØ¿úŒÏø ^}=öõXØÛxoã½áµÙk³×fÐghŸ¡}†BGÏŽž=Á|”ù(óQŸŸG~<òã‘áê«®€æ¦ÍM››B¿Ký.õ»e­ËZ—µ†‚)S ¦ÀÅ¡‡^ ‡lٲǖŽ-[‚W¯&^M šO5Ÿj> õ•úJ}õ=}ï/û|öùìóp¼èxÑñ"8ÓüLó3ÍÁm“Û&·M0hè ¡ƒ†BÅ +T¬êöêöêöpm˵-×¶@à…À Àºuë>àääu²ëd×É$$$xÜïq¿ÇýÀÏÒÏÒÏòí %ƒ: ê4¨´ZÛjm«µ`kk«ïYAøäÿRQlQlQ¬,_K¼–x-Q–Çý8îÇq?Êòän“»Mî&Ë¡¡¡²\´±hcÑFY–5²FÖÈòs÷çîÏÝeù›Eß,úf‘,²e3ÊF–Oxžð<á)˪ ª ª o·“<6ylòXYþÑøGãeÙgžÏ<Ÿy²¼õþÖû[ïËrúÜô¹éseY~&?“Ÿý·Uèf™f™f™,›››Ëò—ª/U_ªdyʦ)›¦l’å°úaõÃê˲N¡S責ë¢ë¢ë"ËO­žZ=µ’åyCæ ™7D–G¥J•&˧ž:xê ,«²TYª¬·ÛIÚ˜´1i£,opÛà¶ÁM–}'úNô(ËÛ_o½ýµ,gxgxgxë{6Aþºÿ¼öä¸å¸å¸Á ûö'ìáT×S]Ou…º&uMêšÀànƒ» î+W¬\±2¨?W®þnæÝÌ»™þWü¯ø_‹Ö­-Zƒ››Ôu¬ëX×ñío>Oz=éõ¤ì¹°çž ’’Ûun×¹8=vzìô˜·KfdA†¾ÿy¬g=ë!ïQÞ£¼Gp¹Üår—ËAtXtXtôùºÏ×}¾†Nqâ:ÅY³*fU ½Zzµôj´3hgÐNÞ¼)x´êÓªO«>Ðÿûþß÷ÿJß.}»ômPÝUÝUÝ…sÎ 87 =4ôÐPpŠpŠpŠŸÞ>½}zCÕŸ«þ\õg ˜`‚õ=9‚ Ý{7°mmmþ+ýWú¯„'Ûžl{² zØõ°ëaÝFvÙm$”\jp©Áééé G=xô \¹r!­n´ºÑjÔlP³AÍ Ü—å¾,÷%j µ…Z¸|þòùËçáøÍã7ßùKùKùK ¥B©È#<}O/HÝ¥îRwP›«ÍÕæPçZku®ÁÀï~?ð{°_b¿Ä~ úúúÃ%‡K—à`·ƒÝvû{ö÷ìï÷NïÞ;¡ÆÀk ]]]x y y ¿»~wýî‚j´j´j4x¦{¦{¦C³kÍ®5»†m Û¶Ñ÷l‚ Ÿbo`¿ÑÙêlu¶p÷ÉÝ'wŸ€ß×~_û} :¥N©S‚ׯ^ ñîÆ»ïåååxù&òM$øðá7^%¾J|•}¾ëó]Ÿï óäΓ;O³f/Ì^€®¿®¿®?èŒuÆ:cþù›Ï?ÿ«o*T¨€}ìc|eð•ÁW –GË£áÉó'ÏŸ<‡Ý»=v{@º:]®†Á#<Z[¶¶lm †[ ·n…øïã¿ÿü+ûWö¯ ÷î'ÜO€Îã;ï<zô.è]–V–V–Vú.^¡ä”XûWyÊ6…R¥F©Q¾ý-Ê+Á+Á+ª­6¶ÚXЕҕҕ‚Ð_C ýöÕØWc_ ÐuÖuÖu†!…C ‡‚»³»³»3l2Ød°IßÅ ‚ |x¾ý ¹—ÜKîáQáQáQ°G³G³GùWò¯ä_!†<òš}ÞìófŸƒáÆ óeæËÌ—['·Nn\$É0ÄC}Oë¿©ó+œüv(Ðn˜Ý0»a`PÛ ¶AmˆiÓ.¦ìMÞ›¼7ž|ÿäû'ßCÏ=7öÜ=.õ¸Ôã˜å›å›åë»AýÓ{ûWªT?¨~€sºsºs:8TïP½CõÀiŽÓ§9àíãíã핃*UF2’‘¼ý­é¯R£FÍ?ï/&Í”fJ3Av—ÝewÞ® øW[3À #éymóÚæµ…a'ÂN„ÁiŸÓ>§} îgu?«û úö9H’ƒàõϯ~ý3$4Jh”Ф Òéo÷ þ"¥¯ÒWé ¡UC«†V…«G®¹z¾êûU߯ú‚aªaªa*ÿ¼®ë/×±GÞ#ïÓoL¿1ýj«æ.0³4³4³Ô÷, ‚ |:>™ö¡\9xåà•ƒpäË#_ùVÎ^9{ål0œl8Ùp²¾Ó ‚ ¿ùówdþ_ñ“@dKÙR¶D¬X!‚ð‘ LAø$‰&‚ |’DA>I¢ ‚ Ÿ$ÑÀA„O’h`‚ Â'I40Aá“$˜ ‚ðI LAø$‰&‚ |’DA>I¢ ‚ Ÿ$ÑÀA„O’h`‚ Â'I40Aá“$˜ ‚ðI LAø$‰ö¯ddd µ¨˜c޹¾C ‚ ÿê¶É;åòNÐ\Ñ\Ñ\:Ò‘ŽPÔ¨¨QQ#ÐþªýUû+h 5†C(šT4©hh3µ™ÚLà9Ïy®ï*Aþwè;€¾$/N^œ¼6_Þ|yóeÈpÎpÎp†ØV±­b[Á«v¯Ú½j3¶ÍØ6cHW¥«ÒUèß³Ïþ=¡Ýµv×Ú]Ów‚ ÿ»þg˜q9ãrÆåàæÓ›Oo>…3ÛÎl;³íì`;àþŽû;îïÛ­¶[m·Bï¼Þy½óô^AøŸ=„h}Ýúºõuèx¿ãýŽ÷Á`§ÁNƒüú:k묭³šÔnR»Im}§AþgØo:=èô Ó(ãPÆ¡ŒÃ¿yÁ ^ð:¯ê¼ªó*°ÚcµÇj¾S ‚ ÿó ¬Úžj{ªí‰-[$þþùÒ.¥]J»Àgc?ûÙX}§A~ó?ßÀÌesÙ\†Îë:¯ë¼”ç•ç•çß>ß$µIj“T¨iXÓ°¦¡¾Ó ‚ ¿ùŸo`¿iMkZ•ëU®W¹HÁR° ퟶÚþ)X½±zcõFß)A„ß||g!†FdwÌî˜Ý jÔ.¨ T§:Õ ©·÷q-Y4²h5ZÔhQ£d¸d¸d¸@ýÐú¡õC!¥JJ•”* «£«£«S9^ò’— ¼­¼­¼ ¶:[­*…J¡ú Ÿ€ Â'á£k`)ÇRŽ¥ƒÅ‰‹'Bæ¢ÌE™‹À¨ºQu£ê@8á„ãc‰%¤)AJ€Ì¯2¿Êü ÌGš4 »æíš·kŽ4i8ØÃJâ$3Ì0ƒBÏBÏBO–5,kXt¢>ÌÔ ‚ |R>žvƒ„®\¸‚ÅY‹³gaÆôÓgLÅNÅNÅNÀ;ìŠó¿í龎}ûRT)ªÔ¯^¿zýê ß”oÊ7KpûñŠxE<„¾ }ú–,X F7Ý`4”ÞZzké­%ý!‚ |:>šö¼Âó Ï+ÀÍ/n~qó ˜½iö¦Ù›ÀÑÊÑÊÑ ˜ÈD&–|Žr.å\ʹ€|T>*E”"Jõ&`s˜]Ët-Óµ Ü.u»ÔíRpÄùˆógÅ(F}€‚ Ÿ ½ŸÄQXXþ³ýgûφ¦Õ›VoZ\»6vmüáóH/¤Ò‹ظþ…aŠaŠa ©6¤ÚjpuðÕÁWÃëÏ^öú³ŸGác¥÷Ò9¤sHgxsøÍá7‡¡ÿ•þWú_ 0øxö?¼ÚšÚšÚhhÖЬ¡4 hдaÚ0m˜¾Ó ‚ èŸÞXss3¦¦¦AzаO´O´O|ßÑÿ\pÁ´Ðv@[x¶üÙògË!l^ؼ°yú'‚ zk`çÊ+w®h›h›h›@Wî†]Ņ¿SáE…^@×Q]GuûÚïk¿¯=XXXë; ‚þ|ð–:$uHê8w4îh Ø?`ÿ€ýPÊ´”i)S}OÇÇ«{N÷œî9?8pþ`¸<÷òÜËsõJA>x;ÔàPƒC À¡¬CY‡²Ð|uóÕÍWë{>~–‡,Y‚ãŽ8=<ôðPH™þ2ý¥¾Ó ‚ |x¬½*ûªì«²\)¸Rp%¼rðÊÁ+Áð”á)ÃSúž†OGëá­‡·v‡íÛ†£ë®?º^ß©A>¼o`ò7ò7ò7Ð: u@kp¿â~Åý Ô´®i]ÓZßåz ûö5ì ƒ/¾8ø"\ºuéÖ¥[åååðþã ‚ |*J¼…Œ 2^®y¹æå0`À€@r—Ü%w}—ÿéªkQ×¢®¸Ýu»ëvúô è º}º}º}úN'‚PòJ¬¬+XW°üíýíýí¡kó®Í»6‡Ï>sä¾7i«´UÚ Ï <7ð<^ðxÁã>9|rød}§A(y%ÖÀ.V»Xíb5P=T=T=„.»lì²Qßåþý8vpìàØ:õéÔ§SðÿÖÿ[ÿoA½@½@½@ßéAJN±7°Ôë©×S¯Ãá7‡ß~Ï <3ð Xõ³êgÕOßåþ}õüµç¯=…ìjÙÕ²«Áåê—«_®®ïT‚ %§ØØÑ”£)GS ¬AYƒ²ÐrRËI-'é»Ì¿?kWkWkWè7°ßÀ~á@…T€ÌÙ‡3ë; Bñ+¶éééWw_Ý}u7 Y>dùå`dndnd®ï2‹OL@L@L\²¾d}É4¶[­¾S½ÕÚ·µok_°*´*´*„㳎Ï:>Kß©AŠß{70mž6O›þÇýû‡úŠúŠú ¨X'°N ¾Ë+~ q q qp3ífÚÍ4P¿V¿V¿Öwª·L¾3ùÎä;òtÈÓ!Oá¼ò¼ò¼¢/G_޾¬ït‚ Åç½×{¿?øþàûƒáé§7žÞ€¥qKã–Æ&˜`RrÁå>r¹dæfæfæBQÅ¢ŠEAº"]‘®@Q¿¢~EýÀÔÂÔÂÔÔ½Õ½Õ½Aw@w@wì:Øu°ë :t„½…{ ÷B†}†}†=È5är °*²*²*³Rf¥ÌJk×®  RL¥˜J1`ð•ÁW_Aª2U™ªÉH2’Œ@;K;K; OOOÀîšÝ5»k m‘¶H[JþƒuËsËs˃Z7kݬu‚ S6LÙ0ep€(ù‚ %å/ï©*…JþøãtnÙ¹eç–PѤ¢IÅl\¿ÑÐЀÍêÍêÍj˜7#nF\>sùÌå30£âŒŠ3*Â÷?}ÿÓ÷?Á•AW]s¯Î½:÷*/s¼Ìñ2oÇ nÜ*¸lOÞž¼=¶µÚÖj[+Xýfõ›Õo wTî¨ÜQpoý½õ÷ÖÃØScO=OW<]ñtÌ˘—1/Ö_{|íq8»ïì¾³û`jé §6„û ÷î'|€Oôsss`ÐóAÏ=‡É’$ßüôà§—C¡¤üåvÅéŠÓ'Èm–Û,·ôxÔãQG.¸²HY¤,›4›4›40ñ1ñ1ñ5ÔP6 liÏÒž¥=ƒ¯¼ð ê™×3¯gK],u±ÔÛñ\ʹ”s)_¨¿P¡Ÿi>Ó|¦Áµñׯ_IÛ’¶%mƒN5œj8AnRnRn˜[›[›[ƒi¨i¨i(ØEØEØE€ÏŸ5>kÀ,Å,Å,nD߈¾ýáæç7ÎîÎîÎîоlû²í˾¡û†î j'µ“ÚéÃçA(.ÿuËØ’±%c <|ððÁÃ0à쀳΂Õk«×Vúø-È#Œ€ît§ûÛ‡óóóA÷T÷T÷ô—ÇÅÅ‚&C“¡É]]]]]]Hž<;y6thСAp(òPä¡HÈ}‘û"÷è u†:C :Õ©Œb£@j#µ‘Ú¥)Mi •¨ôv{†³ gÎõBõBõB=ÌÏ?ôJé•Ò+Ò<Ò<Ò< xNðœà9úË#‚ð¾þëvÌÿ˜ÿ1°a;Âv´yÐæA›z¬ÀSLAZ)­”V¾ó¸9昃$IAmÚƒË.?¸üágÔͨ›QÂV„­[áuÂë„×ûµï×¾_R?Oý<õsx²õÉÖ'[á•î•î•ÔŸ©?SÒ¥=JƒW^]xuáí¸ªªªð¸ÆãkÀ½Ú÷jß« iõÓê§Õ‡‚«W ®Â}é¾t_‚„Í ›6CÞ‘¼#yG lSئ°MP7¡nBÝ·ãf÷Ìî™ÝîܸámÂÛ„·Üé¹Ós§øùSVV†}Áû‚÷Cç©§vž*®ÿáÓó§Oâ¨V)¬R|¶ú³ÕŸ­ÿ:þuüë€ÆFc£±)ù ©©©°ªþªú«êíò·Êß*1‹bÅ,‚YÊYÊYJéÒ?¤?ÚÚÚÃ~ôà MeSÙöåïËß—?¬úaÕ« (¹(¹(vßÝ}w÷]84ïмCó Ä7Ä7ÄV?^ýxõcHÙž²=e;¬>²úÈê#äää ºµºµºµ°ªÒªJ«*ÁèÑ¢AU]U]UÖ­_·~Ýzö ö ö„ÓŸŸþüôç°¹psáæBÐ|£ùFó͇ûÀ/ ½4ôÒPȘ70o tÖ}X÷anû‚ Åå¿> ±×à^ƒ{ †ô_ÓMÿ®Ö»Zïj½’z½ãõŽ×;BÔ’¨%QK`¸ûp÷áîÐåE—]^€‰‡‰‡‰1c<*XW°®` E›Š6mããÆÇƒc/Ç^޽@÷B÷B÷2¾Ïø>ã{8ºþèú£ë¡“¦“¦“ú§õOëŸ÷OÞ?yÿ$¤jSµ©Z°c?Æ~ µ*jUÔ ,.[\¶¸ e~,óc™Aö•}e_x1åÅ”SàÖ²[Ën-ƒ³Î8 :¹wrïägœpv¤·Lo™Þ²äç/½azÃô†pèÉ¡'‡žÀ€“N8 VQVQVQ%¿}A„âö_70›16clÆ@?~ý< ¨sPç ÎU%«JV•’ št*éTÒ)°ìeÙ˲˜29dr8ÍiNÿÛÊ(@ª%Õ’jý›ç{Ñ‹^ >©>©> ‰Q‰Q‰QpvýÙõg×CA•´•´•´`^ϼžy=»ÉÝän ÕjH5~?¬ôBz!½€\ó\ó\sˆŽŽ†ýÛ÷oß¿®¬º²êÊ*¨®®®®®Ã†3 g”ܼýæX™ceŽ•»Ãv‡íCëå­—·^^òÛA()ùŽÌm£ÚFµ‚ó·Îß: NÔ9QçDð ¯jó­Í·6ßBΚœ59k@3R3R3¤¾R_©ï;/, €&J¥‰ í£í£íóÎóÿX½žÎt¦3v7ìnØì÷Úïµß ,;Yv²„f«›­n¶ä$9IN©«ÔUê Ú¯´_i¿­‡ÖCëñθ•©Le` [Øæ™æ™æ™àð™ÃgŸAßúþÐ÷¨¸§âžŠ{€>ô¡p—»Ü-±Ï—ÈÐÈÐÈP¸”|)ùR2L93åÌ”3`TÖ¨¬QÙ’Û® BIûË2›èLt&:Ì`g¯Ÿ½~ö:ĪbU±ªâÚ¢v‹Ú-jƒuMëšÖ5a냭¶>€+W®@îóÜç¹ÏA¶—íe{¨ZXµ°j!¤¤¤À…o/|{á[ˆ7p½àzÁõȈΈΈ†”ý)ûSöƒc®c®c.¸'»'»'ÃÞW{_í}§¥ÓÒi žô}Ò÷I_Ðyêr¹¼Ð¼Ð¼Ð@Ñ¡¢CE‡ÀÚÝÚÝÚ;6vl Í š4‡í_´ÑÌvší4Û ê®ê®ê®`œaœaœÕæV›[m.äúäúäúÀ롯‡¾ ŠúŠúŠúPºZéj¥«ÃQ‡£GA —Â¥ðâ›§°uaëÂÖÁº_Öý²îXüãâÿ•ÚUjW©]ñmGA_Þ»ý&Ò1Ò1Ò6YØda˜2-dZÔ‰®]'ºä ÈÌÌ„‘#FÂXÝXÝXôíзCßn"?ªiªiªi0¿ÓüNó;A½Iõ&Õ›>O}žú<}ÿñA>Ŷ¢sŒsŒs ´ñmãÛÆöÍÙ7gßPç©óÔy%<žxâ!~hüÐø¡ÐxYãe—é5Ók¦×@— KÐ%|À™üHïÞ¼²Œ³Œ³Œ¡çŠž+z®Ðw*A„âWl{`¿I½žz=õ:Ì›6; ¼²½²½²¡ýœösÚÏÑw¹_™O3Ÿf>…Ùɳ“g'Cߘ¾1}c ³wgïÎÞúN'‚PüŠ}5úÒ-K·,Ý<*{Tö¨ û»ìﲿ dÌ:˜uPßåþ}q|Äñ`ùÒò¥åKh÷¼ÝóvÏõJ¡ä”ØíT:¼ìð²ÃK0©kRפ.œfü™ñú.÷ï'æbÌŘ‹pîȹ#çŽÀàÙƒgž F‹Œ-Òw:A„’Sb Ìt’é$ÓI08ipÒà$8}óôÍÓ7!þBü…ø ï?þÿ:y´Á;‚wï€444è=±÷ÄÞõJáÃû` ì7}Ãú†õ ƒøäøäød¸9ýæô›z¸/Ö§&»ovßì¾°ÿÇý?îÿ^'-NZœ´333h·¬Ý²vËôJA>xûM§ÄN‰AyGyGyNkNkNkô=Ÿ8—8—88½íô¶ÓÛ`È¥!—†\ÓLÓLÓL}§Aн50ÓHÓHÓHd7Ènœà'€¤rIå’Êé{Z>/xÁ ºt%è Ô˜ScN9Ð`iƒ¥ –ê;œ ‚þé­ý¦ñÙÆgŸ…Ê•=*{À¶Úh QD‘¾ÓéÏcãÇÆá^ö½ì{ÙàyÏóžç=P6P6P6Ðw:AýÓ{3d0È` þv𷃿…ÛÏo?¿ýž†< y¢ïtž:^¯Ž‡}åö•ÛWÚ¶1lcU.T¹PE\.‚ðOùŽÌÅ­z\õ¸êqÐ|vóÙÍgîô]é»Òáˬ/³¾ÌÅnÅnÅn ¥B©ØÌf6ƒÜ_î/÷,±ÄRßUüuŠ[Š[Š[pçì³wÎÂõ×;\ï¾G}úÕw:A„O±¯Fÿ¾R§,NY ‹g/ž½x6d.È\¹Œ–-5Z QFQFQF ,¥,¥,Žsç8Î9]N—Ó >Å“A,°À m m m  uAë‚ÖÐ5¸kp×`3i̤1“ôRáãñÑìý¦L¯2½Êô‚eå–•[V Ú´)hšíšíší°ø³ÅŸ-þ :†w ï¢:Duˆm‘¶H[èСÓwAa„ÁTƒ©S!Ù0Ù0ÙV­ZM7Üd0¸Ù»Ù»Ùë;¬ ‚þ}t{`ä列#^Ž€9+rVäÀ·Ï¾}öí3(ó°ÌÃ2õ®äøûûCèÞн¡{ai»¥í–¶sOsOsO}§AнŸÄñg…L ™2*zVô¬è ¥¿+ý]éïôªäõŽïß;tttàXà±ÀcúN%‚ }+¼^x½ð:ÜwþÝùмróÊÍ+ƒÔEê"uÑwº’gáiáiá î»:ì*œÌ:™u2 ^¶}Ùöe[}§AП¾Å+âñ HÛ’¶%m Ô™Zgj©úNõá5HnÜ šÕjV«Y-ØiºÓt§)hkkë; ‡÷ÑÄñ¯îô»ÓïN?plãØÆ± T®\!Xß©><©ÔFjž•<+yV‚9æ<šóÎYŸ³>g ÝéNw}‡Aø€>Ú=°¢íEÛ‹¶Ch@h@h4 hÐ$€O÷,Ãbbçlçlç Þ‡½{†ý÷?Þÿâ7ÆoŒß¨ït‚ ÎGÛÀ¢\¢\¢\ U‘ªHU@£-¶4Ú¢ïT–g[žmyj쩱§ÆØÝqwÇÝAûöí7úN'‚Pò>Úö ñƒÆƒƒµƒµƒ5”QvFÙúNõñPF+£•Ñà;Ôw¨ïPˆð‹ð‹ðƒÃn »1LßéAJÞG×ÀdgÙYv†{-×74nh Ê e†2Cßé>>ÆTSa PPPÃÞž{{îí æææúN'‚Pr>º–² eAʈ¿)þÔÏ­Ÿ[?Wß©>~gvžÙy&ØÙÛÙÛÙC@¹€rå@N’“ä$}§A(~]{4æÑ˜GcÀÂÜÂÜÂ*•«T®’¸?Øddkdkd ò‡eˆë6×m®ÛÀCÕCÕC•¾Ó ‚ ¿®Ýë{¯ï½¾PϤžI=0,oXÞ°¼¾S}:\Â\Â\ S¥N•:U‚]a»Âv…Aþ²üeùËôN¡ø|4 ,»Uv«ìVðbË‹-/¶@ƒ² Ê6(«ïTŸ®¾UûVí[ œ œ œáôîÓ»OïÖw*A„âóÑ4°Ø³±gcÏ‚®HW¤+§N;œvè;Õ§ËbµÅj‹ÕàææGƒŽ ‚Ø1±cbÇè; Âûûhؽ {A÷‚Àék§¯¾Ûζm;ë;Õ§¯é‘¦Gš:SêL©3öœÙsfÏÐ×××wºð†7¼x£x£x#x´ðÑÂG AóLóLóLßáA(Nzo`²•l%[ÁãW_=~õÜê¹ÕsÓwª¿é°tX: ^?zýèõ#<ûtìÓ±p³ÉÍ&7›è;ÝÓ&k“µÉ°?dÈþ¸þàúƒëþóû"7DnˆÜ[[[p®è\ѹ"xáýÂû…7lqÛâ¶Å RÜRÜRÜàIÖ“¬'Y°|ÓòMË7A„y„y„¸ü@> zo` .$\€ä_’Iþê}]ïëz_ë;Õ߃‹ƒ‹ƒ ô‹êÕ/ üø5ðkðöŽ×ÉAr@a¬0Vƒâ”â”âÔ~ß­a·†Ýéiéiéi0²ËÈ.#»€U€U€UH›¤MÒ&P( P±cÅŽ;ÂõÀë×!2/2/2 ›6+lO?=üô0È­äVr+}ÏŠ ïÒ{‹TGª#Õ`îeîeîe–]Xv¡¾Sý}užÜyrçÉ`9Ør°å`8´êЪC«Šoü¤WI¯’^Á¤;Iw’àææîMº7éÞ$HHHÕ8Õ8Õ8?~>ü<¼6mþÚžÞ}z÷é]ÈË˃ÚÍk7¯ÝÊm)·¥Üà'8ñû톆†Á³ègÑÏ¢!Þ4Þ4ÞR¦.L]ÆÞÆÞÆÞànånån±±±`öÊì•Ù+0\`¸ÀpÈõäzr=8’{$÷H.¬K[—¶. ^õyÕçUÐíÕíÕí…äìäìäl¸w7în<~þøùãç ž¢ž¢ž‰{÷$îð±ácÃÇÂã7ÆoŒáµëk××®———ý#úGô‡¼©ySóþï² ïCï«Ñ?hò Éƒ&àèèfKÌ–˜-Ñwª¿/“Ú&µMjðýÃöÛ+~XñÊ yQó¢æEàjàjàúߊè‡Ñ£„ .L¸ãÚŽk;®-¤Y§Y§YÃÏ|~àsßl|³ñÍ`õ¼ÕóVÏ«ÙV³­fCÚujש g4žÑx+}Àë¯o¼¾RF¥ŒJ{s÷æîÍauÁê‚Õ0íõ´×Ó^ƒnˆ#è‚ðçèmL;M;M; ^Ž}9öåXpmâÚÄõ#þMæï¦V“ZMj5Ö­-Z[À®Ò»Jï* êºêºêº}Üò¥Ê—*_ JÝ+u¯Ô=hÚ<´y(øøøÀý÷gÜŸ)]Sº¦t…2FeŒÊSm§ÚNµaTæ¨ÌQ™Ð°~Ãú ëCùíå·—ßZV§Õ4h~¿]K+K+K+¨6¢Úˆj#Ày¹órçåÐäç&?7ùœª;UwªæVæVæV {¢{¢{Xa…°…-l³ñfãÍÆƒ£»£»£;T¾Wù^å{àÞÕ½«{W¸í}Ûû¶7$š%š%š÷(ïQÞ£ þòúËë/‡£§Žž:z Êî-»·ì^0јhL4Ð~jû©í§‚×~¯ý^û¡F=jô€UVTYQjF׌®­ïo… |Zô¶–¼4yiòRÈÈÊÈÊÈ×××}OÇÿžþÕúWë_ f_™}eö8çvÎíœô =þÊ€†br€ Ž8âÆÆÆ µ—ÚKí!¯z^õ¼ê yJž’'M4šh4ŒbŒbŒb€‘Œd$PŸúÔºÒ•®bû9ärc¹±Üøíßÿµ<òȼñÆÈ$“LHš>4}(DíŽÚµv”ßQ~GyH M M —Þ.½]zƒ4T* ÅÏŠŸ?ƒ±™±™±˜šš¾ÝL*Páƒ~â‚ð÷¡·=°§·žÞzz ,“,“,“ ü‹ò/Ê¿Ð÷tüï±n;Ýv:x·ðnáÝ‚²‚²‚² !%!%!å/ ¨B… ¤åÒri9à?þPàZàZà òxy¼<¬v[í¶Ú ru¹º\˜Ï|æÿ›ñÌ1ǤƒÒAéàÛ¿ÿP)JQ ¤KÒ%éÒÛ¿ÿ¹çÖ~ôi´@ZÀÛ×›Þôf3›ÙÀcó´—µ—µ—ßo}Íúšõ5pŠpŠpŠŸ5>k|ÖÀ<£yFóŒ`¡z¡z¡”½”½”½@-–FíhG»·ãh5‰šDˆ ˆ ˆ µ³ÚYí¬ïoƒ |ZôÖÀžÕyVçY¨’_%¿J>|mðµ8ûPoZµjUGVYuäÛÅ€¹Ë]îþùq¤5Òi äææÂÕ «AWƒ`oÀÞ€½ТN‹:-ê@éñ¥Ç—I]’º$u››(XW°®`äÌ;˜w¢F7ŒnI–I–I–ä“ä“äóûíª®©®©®AÔ¦¨MQ› ! ! !¢²¢²¢²àîî2r2r2ràå×_>„gžxv2keÖʬo6¾Ùøf#ص´ki×¢.F]Œº'{ìu²¸çþûw`»Ûv·ínØ5w×Ü]sá|ãóÏ7†(¯(¯(/ˆ­[)¶d5ÎjœÕÞL|3ñÍÄ·y£ý¢ý¢ý`FíµgÔ†'Wž\yrEßßAø´|ðCˆêêêêêêðòØËc/A°a=€f4£™¾§ã—A7ƒnÝÀ÷˜ï1ßc° ý‚ö ÚChdhdh$¸7roäÞèO B!`ÐÒ ¥AK(Ó¼Ló2Í¡Éá&‡›ç Μ7€¡‹¡‹¡ Lo1½Åô l¡l¡lŠE„"¸ÈE.µCÖYûöì>Óf¦ÍLÿÍ÷D:!N€—“—“—¨¶¨¶¨¶@©R!¥B@g¡³ÐYÀjõjõj5X&X&X&€Õ6«mVÛ`µÕj«ÕV`Ýʺ•u+°ß`¿Á~8Y9Y9YqsãæÆÍÁ©©SS§¦0û‹Ù_ÌþbbbÀ8Ü8Ü8̶šm5Û ÎÎΰ1scæÆLpØá°ÃaÇÛ¼R*¤TH¹Ïç>Ÿûœ~púÁéà*W¹ªïoƒ |$ù>ÔS’S’S’aÎ…9æ\€™»fîš¹ ªªvªÚŸ¸ÎGø0ÍÍÍáúºë뮯ƒå7–ßX~Ì·›o7ßþÇï{1àÅ€`Dþˆüù°ñÕÆW_AýgõŸÕ+a‚PŒ>ø!ĸ~qýâúAUƒªU¡ÜþrûËí×÷4ÿª»Awƒî ûÈ>²œX{b퉵ÿù}­3Zg´†Vþ­ü[ùCºoºoº/p’“œÔwU‚ ü|ð=0¿8¿8¿8ˆêÕ'ªÌ :'TßÓ ü‘=!{BöÀÆol¼‹k/®½¸68sç4NßéAø_öÁ÷À^õÕÿU¨6­Ú´jÓô]¾ðŸ4²idÓÈê-¨· ÞØë·×o¯è¶é¶é¶é; ÿË>XË}œû8÷1$''ƒki×Ò®¥õ]¾ðŸ(z(z(zÀóCÎ9Ï×>_û|-ÜÚ}k÷-q1Aôèƒ5°ä²Ée“Ë‚v¹v¹v9”[~lù±ú._ø³¼¼¼Áã…Ç °gÏž={ö@ÖÙ¬³YgõN„ÿE¬%=OzžôÌîšÝ5» ¥:”êPªƒ¾Ëþ[7uÞÔy˜w2ïdÞ ŽL;2íÈ<üúî뻯ïB¨*…Jï?ž Ÿ®vØ«:¯ê¼ª`jbjbj¢ïò…ÿ–é Ó¦7Àׯׯ×VX=bõh‘Ü"¹E2T+[­lµ²Å¿Ýì¸ì¸ì8Xï²Þe½ h¶h¶h¶€l*›Ê¦¿)~Sü&°ûÖî[»oAí«öUû‚ò„ò„ò¤5Kk–Ö :„wïñ1ñ1ñ1‘‘‘Ou<ÕñX6·lnÙB#B#B# ¶clÇØŽ`·Ën—Ý.h>¢ùˆæ#Àð©áSçúþ4á[‰ïÉOå§òSˆìÙ-²T ­ZEœuøÉ«{³îͺ7¡Y“fMš5=Wö\ÙsŠF.]üÛ3o<Þx<¤OHŸ>̾1ûÆì(]6ºl4\rpÉÁ%°oʾ)û¦¼½mK‹„ /`Ç:u´;iwÒn(ZT´¨hüÐç‡>?ôäËÉ—“/CðÐà¡ÁCagÁ΂Pz}éõ¥×CÐë ×A¯áäÖ“[OnÕ÷ì ‚ --ZZ´’'$OHžŽ®Ž®Ž®ú.[x_’«ä*¹Â vƒÚ j±Ýc»Çv‡«/¯¾¼ú²ø·g|Èøñ!°¶¶¶¶¶† ³+Ì®0œÊ8•q*VùVùVùPí«j_Uû ì°wÀ^h~¤ù‘æGÀ ·AoƒÞ Ø¡Ø¡ØeÒˤ—IÃ9†s ç€âÅ7Šoà|öùìóÙPʱ”c)G¨7±ÞÄzÁ2Ð2Ð2®ýtí§k?é{öA€ÐÀ2¿Ïü>ó{È¿“'ÿTÈ©Sᯬ.|”Ê”+S®L93 g@ø›û›û›Cú±ôcéÇJ`ƒ¹ä’ Üã÷Þy¼ h¨Q£~û°²PY¨,*S™Êï¼N‹í;ïoMkZCΜœ99s Ê)Ê)Ê Ž-9¶äذq³q³qƒ–u[Ömù·›¡ø”øo`qÚ8mœŒ®]5º eüÊø•ñ’I&Yßå Å¥ýÕöWÛ_…àÍÁ›ƒ7CÐà ÁAƒalÒØ¤±IÀhFS ‡åqò8y¨=Ôjwžˆ$’Hà2—¹ t¤#Ar“Ü$7Ð%ë’uÉ õÖzk½y»æàu®sdoÙ[ö†Jo*½©ôLMMÁ«®W]¯º ¬¬¬ïYá]%¾–°'aO°j;Ôv(ö4ìiØSße ÅÍxñ ãAàkékék ÁñÁñÁñð$íIÚ“´âÛNà o4¼w÷ßÝw?ì[¾où¾å¹4siæRˆ_¿ ~äZåZåZÍa›Ã6‡¡ÁÄL„ƒùóæÃuƒë× Àè+£¯Œ¾‚¤ä¤ä¤dèëÒ×¥¯ p‹[Ü‚ ÷6ÜÛp®<¸òàJˆù%æ—˜_ô=Û‚ —°m³¶ÍÚ6K–ØùÃÎv–ôÖ½{"?‘ŸÈòV«­V[­dyÖ¡Y‡f’å … 7¼ÿð… +V”åøÎñã;ËrÒÓ¤§IOe9©]R»¤v²œ|>ù|òyY.r/r/rû¾œ£9GsŽÊrBï„Þ ½e9->->-^–ãããd9o]Þº¼u²,‡È!rˆ,g'e'e'Érü¸øqñãd9Å0Å0ÅP–U›T›T›ô=É‚ Ȳ,—ØZˆòLy¦<Y|dñ¨?¡þ„ú Ï¸>ãúˆ5ôþö2m3m3maö¸Ùãfƒ^1½bzÅ@÷Ýwtß¡ït‚ ü”Ø!Ä‚¯ ¾.øÒg§ÏNŸ åÃˇ—×w¹Â‡bnnž¾ž¾ž¾dddɮɮÉâ,TAŠA‰50•©ÊTeúö––6–6–6ú.WøÐZ¶4liNkœÖ8­ÿÒþ¥ýKƒ|V>+‹%¨Ax%×Àf¨f¨f€¦HS¤)Ëo-¿µüVßå šaeÃʆ•Á÷¹ïsßç:!tBè¸_é~¥û•ôN„OY‰5°´riåÒÊáqÃã†ÇÁj¦ÕL«™ú.WЗ*5ªÔ¨RºœîrºËiسpÏÂ= ¡à—‚_ ÄY}‚ ü%ÖÀâÚÆµk V:+•ÌW›¯6_­ïr}ë=µ÷ÔÞSA­ÎVgÃ)×S®§Äob‚ ü%ÖÀR"R"R"Àv¡íBÛ…ú.SøXXÔ±¨cQ¼5Þo ½tôÒÑK›››«ït‚ |JJ¬e}›õmÖ·`ígígí§ï2…Mã=÷4Þ5[×l]³5ì¼wðÞÁ k¤k¤kôöuš¯5_k¾ÍaÍaÍa}§ácRb ,;/;/;,{[ö¶ì­ï2…Ò^i¯´ï Þ¼/@D§ˆN äiÈÓ§ð¼ÓóNÏ;Á7+¿YùÍJ8wçÜswôZ„IÉ50ŸlŸl°îcÝǺ¾Ë>V—U\Vq4íÝ´wÓÞ0Cž!Ï¡oï¾½ûö†ÕmV·YÝnþxóÇ›?xÄ#}§ácPì‹ùÎ,œY8òjåÕÊ«v¦v¦v¦ú.SøØdÖϬŸYúô9è;3wfîÌ„;[îl¹³t>:ÏÛ×GlرtýuýuýAñLñLñLßU‚ OÅÞÀòMóMóM¡ µ µ lÛ.¶]¬ï2…ÍÝcwÝ= k,¬±°ÄÄÄüñëc²b²b² 73737,±ÄRßE‚ WÅ~QuYuYuä±òXy,˜ššê»LácÓz}ëõ­×ÃÒuK×-]N³œf9Íúã×gdd@ìúØõ±ëõ^„A±70õ<õ<õuFêŒÔííí ïô‚ | Šý¢¦›¦›¦HÁR° J­R«Ô¾ÿ¸Âß“tGº#Ýnt£`9×r®å\ø:öëØ¯c!¤yHóæ1 c@ƈ¹s%抾S ‚ð1(þ=° u:”fJ3¥43hfÐLße ŸŠ–ËZ.k¹ ¶­Ù¶fÛèÚ·kß®}ß>ÿ¦Ö›Zoj.]—®K×wZAô©ø÷À5‰šDP^T^T^¥¤””’¾Ë>5u¿¯û}Ýïa홵gÖžîp‡;pS}S}S Ûù€9æg[ÈBBöôìéÙÓÁ°·aoÃÞ`zÁô‚é…?~[QÓ¢¦EMá¢ýEû‹öÓ&¦MLè¿¶ÿÚþk#áX|cñÅ7Pا°OaÈÍÉÍÉÍ«V¬€qeãÊÆ•‹}ö>¯xÅ+(°/°/°‡WC^ y5n*o*o*á‘î‘î‘ ó ó ó œU9«rVP«\­rµÊAWË®–]-Á9Ô9Ô9,]-]-]AyRyRyø‚/ø¨Nuªÿ›í§’Jê¨Ó +¬@yHyHy,°À°pµpµxwý[ÜâÖ;§“N:ȵåÚrmPTT„8ÿ8ÿ8x}âõ‰×'à‰Ç'°sÇÎ;w@á¾Â}…ûÀÙÅÙÅÙšîiº§ép«íVÛ­6Ø^²½d{ ¤õÒzI\N ü+þ&!!ñÏFVRŠŒ‹Œ‹ŒacÔÆ¨QPý^õ{ÕïÁ0àÿñ¾;ë﬿³Î.:»èì"貸Ëâ.‹!²Vd­ÈZ°}áö…ÛÂ4Ãi†Ó !G‘£ÈQÀ¼»óîλ “÷NÞ;y/´ kÖ6 äŸåŸåŸAò<$À{ìK®n}K9r:å4\~uúÕépmÁµ×@ÞÕ¼«yWÁuŽë×90Èuë WpµvµvµëëëP~¡üBù…¾«øl±Å¤)AJSL1ªQj@µ•ÕVV[ ¢:EuŠ‚üÑù£óGCìîØÝ±»áΚ;kî¬ã뎯;¾îíbÇnQnQnQðYÏj|VjŒ¯1¾ÆxPNPNPNÐwÑ‚ðaû@”]”]”]À{„÷ï`6ÇlŽÙœÿü¾§ÇŸz Û¶)lv8Øá ¨}Õ¾j_¿cüŽñ;À>Õ>Õ>Ê+¬ü1ãåx9T«U«U«!ö§ØŸb‚Û«n¯º½ úNï;½ïtPd+²Ùúžâ¿,~Yü28åuÊë”ÜpsÀÍP¦S™Ne:A÷öÝÛwo Ë5,×°ØÍ´›i÷ïn\Ú–¶´Õw5ÉIr’œÀüœù9ósPƒÔj¬ª±ªÆ*è:Ðu +¼|ø".Õ¿TÿR}øþî÷w¿¿ C*†T Þô¦7à¶ßm¿Û~0h0Ð` ¾«„’Uü ì·C†¿ýW‰åÛ§ÃN„;[\#\#\#@Ú'í“öAÃ{ ï5¼GräÉ…ÞF½z“‘“‘“QÉ}!~;{ïÄwNÜ“—N^:y œK;—v. ㎌;2îÔ›_o~½ù ´SÚ)í€gþùx˜¿xþâù‹áZêµÔk©ðåø/Ç9æ˜{`îhðYƒÏ|ÊëÊëÊë%—GøÍhF3(ß |ƒò `؆a†m€å¶Ëm—ÛB©ª¥ª–ª ú,è³ +:Vt¬ŠÆ)£ïð‚P¼Š}쟇.æ1y ›®›®›´¤%-Á¤¬IY“²`ÔÞ¨½Q{°›l7Ùn2ØÏ·Ÿo?²7foÌÞ‰ªDU¢ Ì0ÿÁü¨TX©°R!´)Û¦l›²@QD½½G:%’NñvÏï_å,g¡”{)÷Rî`žažaž6Wl®Ø\"Ÿ"Ÿ"0ô5ô5ôÉN²“ìx{²@$‘D‚ÒPi¨4SoSoSo0÷5÷5÷«WV¯¬^Á#ßG¾|!{aöÂì… î î îŠÑŠÑŠÑðøÑãGAˆAˆA˜+Ìæ p³p³p³€ê¹Õs«çòÏ“^fÏ=wö\NH'¤Åÿ¸juÕêªl¯¸½âöŠÐfi›¥m– äAɃ’¡Ô²RËJ-+þí ÅËÁÊÁÊÁ &™xdâ¸sûÎí;·aÛ©m§¶‚7Ÿ¿ùüÍç0Êy”ó(g044ÔwjAx?žf´Öh­ÑZЖ֖֖í1í1í±ÿßÿïäŽbˆ’I&˜À&8ÀÓåt9þú-?’Éÿî>Pyä‘÷_,¢ˆ"oÊ7å›oÿþ¯bˆ!Ї>¼s¿³¢QE£ŠFÊWå«ò…˜Í1›c6ƒã:ÇuŽëàËA_úr¸¸¸±Ä r²œ,'¿3¾7ÞxƒôPz(=*Q‰JÅ÷9]ȸq!¶]ÚviÛ%¹o侑û`ä‚‘ F.€R«J­*µªø¶÷wWÔ»¨wQoHÉNÉNɆ‚°‚°‚°ŸCJ–’¥dhú éƒ¦`ñÄÅO„ËËKX?rýÈõ#!Xþ°üaúž5Ax?ÅÞÀ wî2ܺٺٺ٠Uj•Úw~ûmÏB¶—íe{Ð´Ñ´Ñ´ÈÆ‘#ƒI{“ö&í¡|\ù¸òqPô¦èMÑ(’Ф¢³¢‡¶¶¶ÁÛëtt¯u¯u¯ÿ8Ÿ¶ª¶ª¶*hëhëh뀮…®…®ÅÛqt¿è~ÑýEaEaEa =¡=¡=ºãºãºãP”\”\” ŠpE¸"²ëe×Ë®ªªªàlèlèl6Y6Y6YÐØ³±gcOð8èqÐã tPwPwPƒÜZn-·ÝçºÏuŸƒvšvšvÚÛœé“Ò'¥O‚€J•*ABvBvB1œÞ.¼]x;Ø×c_}=`üÅñÇ_„6õÚÔkSÿøy¥¼R^ ©©©p ú@ôhÈZ™µ2kåûç+T8¨p\èr¡Ë….0>a|ÂxHNLNLN„Cç;t-~´øÑâÿbœê Õªÿù–î¶î¶î6Ÿw|Þñy°ñÔÆSOÁÍy7çÝœ÷ö¬×g­žµzÖ r¦åLË™gÊž){¦,\[rmɵ%Àw|ÇwÅŸ¯ÜrÊ€9š9š9È•9*søEøEøEkXÚâß® |ÅßÀ:v2ìºB]¡®´–ZKí;7n’¥@)r.å\ʹ‡S§NSƧŒOÃØØ±±ccÁ,Ñ,Ñ,”·”·”· UþªüU=5{jöTHž><}8díÊÚ•µ W®2\ÑÍ¢›Eÿ›µ³Ìþ1ûGÈ|™ù2ó%(Ö+Ö+ÖÃÓ«O¯>½ &&&`ÓÕ¦«MWˆ;6v,Ü«p¯Â½ `wßî¾Ý}ˆó‹ó‹óƒÚMj7©ÝL‡™3ûÆì³o ¸·roåÞ :ûuöëì[o}¼õ1켸óâ΋ðHóHóHÑý£ûG÷û#öGì@dFdFdÆÛ¼yyypçüówÎCÖì¬ÙY³ÿúç’“œ“œ“ ûúíë·¯ôOíŸÚ?Ok<­ñ´??Ž4Sš)ÍõõõXWm]µuÕ Ñ!Ñ!±V‰/V8¬pÜycä‘|/ù^ò=(ÕªT«R­àpÙÃe—…sÎu8×áíû’'=Nz ÚmÚmÚmPøKá/…¿¼3N|r|rüûçûWã2ÆeŒƒ « « +èêØÕ±«#ÔM®›\7Bë‡Ö­¯¼Zðj˜ÅšÅšÅBh^h^hø-õ[ê·ävr;¹]ñçûÍ~›ý6ûák§¯¾v‚' Ož$@èôÐé¡ÓKn»‚P¢äbÓ?¦LY0*`T€,'ÔI¨“Pçç¯Æ\¹*Ëí/´¿Ðþ‚,?þåñ/‘eíxíxíxY–—ÈKä%²¬» » » Ëšušušu²¬ùNóæ;YÖitF–u»u»u»ßy~ŒfŒfŒ,k³´YÚ¬ßçÒ%èt ²¬Y¢Y¢Y"Ëššš²¬í¥í¥í%ËZs­¹Ö\–5ã4ã4ãdYsZsZsZ–‹Ö­-Z+Ëšešeše²¬‘5²F–eÙ[ö–½eY³_³_³_–ÕÕÕeYþUþUþU–u—u—u—e¹ðháÑ£²\˜P˜P˜ ËZW­«ÖU–µe´e´edY3J3J3J–‹–-+Z&Ëÿ·Ô’,Ëkä5òYÖ~©ýRû¥,˾²¯ìû×?—ã]w=ÞU–çËóåù²,ª U…ª÷øœ#c"c"e¹íçm?oû¹,ßüîæw7¿“å$Ï$Ï$OYέ”[)·ÒÛÏ'énÒݤ»²œggg Ëêîêîê´1icÒFYγȳȳeuCuCuCYNP$(²œs!çBÎ…·Ûà1Ác‚‡,ÿP÷‡º?Ô•åˆÐˆÐˆPYž:yêä©“eùåæ—›_n–å‚9s æÈrBÇ„Ž e9gSΦœM²œ¥ËÒeéd9i[Ò¶¤m²œú:õuêkYNh—Ð.¡,«f¨f¨fü‰ x#¿‘ßÈò“sOÎ=9'˭ǵ×zœ,ßPßPßPËr¡w¡w¡·,'ÝOºŸt_–3L2L2LÞ¾ý'·ŸÜ~r“å/’¾Hú"I–u:N§“eí×Ú¯µ_Ërʃ”)d9aiÂÒ„¥²ü+›¼×ÿ4ÿNkOkOkeyŽjŽjŽJ–U¨PûÿBÉ*ö“8L¢M¢M¢A.-—–KƒÚUíª~gÅ‚ÿû?>ÈŸ=>{Ã* «0¬\=õüÕóàbïbïb_îýrï—{A£ˆQÄü¾~MYMYMYx6çÙœgs ¥GJ”p»Ãí·;€ýJû•ö+a§ûN÷î )­)­) ËYÎòw籡ÔPjøö‹pªõ©Ö§ZCÈÍ›!7Áì;³ï̾Ãë†× ¯Ãçû?ßÿùþ÷_š­±Ec‹ÆpøÄá‡O@dÝȺ‘uß^‡&Ÿ‚b?„hÞü‡y0yhòÐä!¤Ù¥Ù¥Ù½}ÞùWç_…k7®Ý¸jv¬Ù±fG @Ä›‹]n‹Ü¹- Ù:Ù:Ùª}[íÛjß¾ÿ¸òy¼ÌÊš•5+ \:¹trqQã¢ÆEÖEë¢uà†Á ƒ‚ÅQ‹£G!kNÖœ¬9`·Çnݰ4·4·4‡¬IY“²&½]*Ér’å$ËI=0{`ö»äþãìSÃã†Ç C‹5.Ö¸]+ºVt…nÉÝ’»%CåÈÊ‘•#ÁbœÅ8‹qW'¯N^(ߥ|—ò]àÿöt KR—¤.IÐcL1=ÆÀ¹»çîž» yîyîyî\¿¡™¡™¡¸rå> f9Ìr˜ÝßtÓý TiQ¥E•P¾jùªå«¾]-ÿwþqvkÆÖŒ­[aÇÐCw …Nu;ÕíTFÚ´is.æ\Ìç'ŸŸ|~òý??Û<Û<Û<(íWÚ¯´<ýlô³ÑÅúÕ„Wì{`¦ L˜.‹¦M-šBRaRaRáÛçË_,±üE(OyÊ¿ûƪT¥ª¾§ãï'Iþ’ü% Êr ˜—3/g^®þm3—\rA^!¯W¼}ØÙÆÙÆÙ^­µþÕzÐÕÒÕÒÕi‰´DZ,f1‹gœqæ3ŸùïŒÿGÿQŽ“œä$Fi¿GZ -ðö¬Óa cH›¥ÍÒf0É1É1É¢~EýŠúAÑ¡¢CE‡`ûôíÓ·O‡×–¯-_[‚¯¯/ŒRRRƒ²­²­²-È7äò íd;ù°a‚ &À·|Ë¿ù‡ƒ4Eš"M‚؂؂Xˆ Š Š ‚àGÁ‚ADDDDD(âqŠ8йéÜtnÀ@R +m˜U4«hVòfåÍÊ›Ld"‹áû!@‰­Vh}ÇúŽõH—>.}\É"W—«ËÕ¡hBÑ„¢ üóÂãÿug,ÎXœE{E{E{È Ë Ë,ŽÓ»µhÑ‚TGª#Õiˆ4Dòöé Ï Ï O(ûSÙŸÊþR;©Ôþï·ÃwÆqÀÆJc¥±ï<^™ÊTi¡´PZøÎãN8áÌf6³:t¼m\4h~?Îo‹?ÿÖÀ¤EÒ"ioå?Þ'…IaR(f*f*fBË-_´|½÷Ü{0ô¼ÖóZÏk`çjçjç ²¿ì/ûƒ4Iš$M©«ÔUêúÎöÿqˆ´RZ)½{–æoí‡Â•9ÊeXZZB³sÍÎ5;ýgöŸÙ&l3Þf¼ÍêéêéêéŠïû‘íŸíŸí6ö6ö6ã5<…¿§[ ÑZe­²VAÆíŒÛ·K®€¼Íy›ó6ÃÁI'œ‰#G$Ž€1wÇÜs¬±Æúÿñþ‚M› 6Ák¿×~¯ýÀd…É “Pµ°jaÕB #éXrùKÚogs::8:8:À“éO¦?™®¸âúãô1ècÐŒ?6~ Ï;>ïø¼#$žH<‘xâ+ÄWˆ¯_ ûbØÃàôÝÓwOß…O_<}ñ^•zUêU)È–=,{dgfgfgBÖã¬ÇY!swæîÌÝâââiª4Uš ²öeíËÚ)S¦ EiEiEiÈ9“s&ç Üx~ãùçÐ`yƒå –CfÕ̪™Uß ˆ‘b¤ ršæ4Íi ƒ2e ‚´‰iÓ&BŽiŽiŽ)älÈÙ³j”®QºFéw wÁþ¹øàÓ¡O‡> Ùó‡g‡ø¾ñ}ãû‚ÓC§‡N!åjÊÕ”«a–a–a)Q)Q)Qfœfœf >>> ¥¥-¯´¼Òò „ô éÒ lÆÙŒ³V­.Z]ëÉÖ“­'¿ÿ÷"~züôøéá‘á‘á5Õ5Õ5Õzü¢ Â_Pb{`¶ƒlÙ‚Œ]»2v•\ן\rý Üky¯å½–Щ¨SQ§"0Š1Š1ŠùÏï×uÐuÐu€}Îûœ÷9ÃÚÆk¯m rM¹¦\³är(Ò&i“´ :ôëЯC?¸v+ìVä:ç:ç:ÿõqíºØu±ës2çdÎÉE5E5E5Èê›Õ7«/Œ_2~Éø%Po]½uõÖo¦o¦o&txÖáY‡gw%îJÜègÞϼŸ9´1mcÚÆ²~Ìú1ëGèÙ;³w&4?ÖüXócÞ ½Azè3¿Ïü>ó¡™w3ïfÞPE®"W‘azé饧—†‚;w î@Ö¥¬KY— qã>ÆÐÔµ©kSW°[g·ÎnŒÝ2vËØ- Û¥Û¥ÛeÊ8”±‹Ç.»”””þ¸~¹Ü@n_|ið%Œÿzü×ã¿Ó$Ó$Ó$È3:g4¸OwŸî>úìw°ßAȨ’Q%£ ¸Ww¯î^úMê7©ß¤·K¯Mj?©ý¤öPKUKUKщщщÚ.µ]j;Ðh ´ÅðÏÎààààà`¨lRÙ¤² TÜ[qoŽô«)ﯤNo¼zéꥫ—dyòáɇ'–eJ£Ò¼ÇiÛä'ߟ|ò•å/V|±â‹²\QQ!ËòOòOòO²¬µÒZi­d¹Ð¥Ð¥ÐE–5¿j~Õü*Ër˜&‡½3οžÖœ¡ËÐeȲîªîªîª,ÆÆÆÊ²ú¸ú¸ú¸,ËÝänr·w‚Œ—ÇËãeY=T=T=T–Õ/Ô/Ô/dùÿV)©Yþó _¾.|-ËK~^òó’Ÿey{Íí5·×”e­©ÖTkªït‡ò8çqÎãYþ2ì˰/ÃdùE»í^´Ów*AøkJlÌq‚ãÇ ;"wDîÈ É É )¾ñSÂRÂR ìǰÃ~„ÇöíÛùçvžÛ m Ú´…-…[ ·ÂÑ?Fÿ óûÏï?¿?„Ì ™òon¿"—ÆKãA³X³X³vWÝ]uwUXÓeM—5]`íÓµO×>…—e_–}Yöí’W§*žªxª"¬Ù±fÇš°Ú~µýj{¸ètÑé¢0‹YÌ*©ÙþÏŒ*U6ª CÏ =7ôÜ©r§Ê*plÛ±mǶü¹ü¹ü¹þò %ëu×=^÷€õáëÃׇCWÛ®¶]m¡Ú¥j—ª]Òw:AøkJ¬Y8Y8Y8b…b…b¤—M/›^¶øÆ/Ó Lƒ2  ^£zê5‚š«k®®¹:ê|¨ó!0´5´5´…Z÷kݯu&ÔœPsBM°c;Æv ”(Pú÷ãJ*I%© miÚÒ´¥°­Ò¶JÛ*A³a͆5» ì6°X7¶nlÝÞ¼~óúÍkØ.o—·ËЯ{¿îýºC¿6~müàgŸ=~ö€ŒE‹2•Ôlÿy•öWÚ_i?Lè9¡ç„žptÎÑ9Gç€ß¿'~O@µPµPµPß)…â~ ü@øX&/“—ÉÐât‹Ó-NC÷WÝ_u¥ït‚ð~J¬™'›'›'ƒÙV³­f[!Å9Å9Źø·£4Sš)Í@qIqIq ó ó óAΕså\0ºntÝè:œ;|îð¹Ãy-òZä5Èš?4èïÇ“GË£åÑ`1Áb‚ŨgYϲž%|þûóߟ‡sŽçÏ9‚Q´Q´Q4$VM¬šXbÎÆœ9 á‡Ã‡†§¥Ÿ–~ZÒãÒãÒã Ð¡Ð¡°–Z*.µ¾¨õE­/`æú™ëg®‡[7nݸu–÷^Þ{yoˆ;*v”¾S ÿ-•›ÊMåñññðãwŽß9B¯î½º÷êÞ¥½K{—ƒöí Úë;­ ¼Ÿk`&wLî˜Ü +<®ð^}=ôõÐ÷÷wþ±†ÔDj"5¢‰&.Æ\Œ¹›R6¥lJ²Ên(»¬›Z7µnÊï—ðøíÆ›ÿ¸^Çl·Ùn³Ý0wùÜås—ÃÄ_'þ:ñW8´ÿÐþCûaûšík¶¯ƒG É“&# \ûrí˵‡Æ]wiÜÖ8®q\ãvËí–Û-ÿk%–¤ê½ª÷ªÞ I‹¤Eؽ´{i÷¾9ôÍ¡oA@n@n@.dFeFeFé;­ð¯Š‹‹áî7w¿¹û Ì3œg8Ï®7¼ÞðzC˜ªšªšªñã=ƃr’r’r’¾S Bñ(±ö›Ê-+·¬ÜÞX¿±~c òQù¨|´øÆÏÛ”·)oäÕÏ«ŸW455!9<9<9TÓUÓUÓ¡²yeóÊæ`}ÝúºõuP©ŒTF IÓ¤iÒ EþŠüP0°``Á@ˆ_¿,~œis¦Í™6àfìfìf õ:ÕëT¯äùçùçùƒã÷Žß;~7UÜTq¨vªvªv‚ã\ǹŽs¡êøªã«ŽÃxÃxÃXL¶¸ØÙÙÁÿÇÞ}ÆEqõÿÿí.méAQ±bWì½+ÖØc‰=šØ5ö‚hì½D±‹{/ØÁŠ"¢ ]štvþ7þ——y\ùæ—¢fEÏóÎu ³gÞsfãÇ3sæÌXó±æcÍaTÕQUGU… › › ˜b=ÅzŠ5‰?$ÒΧO;O‰Ì ¤)èRÐ¥  „x†x†xÂü¸ùqóã`MÏ5=×ô„Çj«q ¶_Ø~a{¨æUÍ«š—¦S §ñé X§*NU qLâ˜Ä1PXXøáí¾{÷6 U†*C¸Ú¹Ú¹ÚÁË[/o½¼ÍÍÍPpýÁõÇ3gÀ¢¥EK‹–PSYSYS ±õbëÅÖ“Û&·MnC…ï*|Wá;ÈÍÍ…â>Å}ŠûÀ¯üʯ€‹‡‹‡‹ |=ðõÀ×Pêh©£¥ŽÂ‡ àYŸg}žõSŧŠOC¨M¨M¨ ¿)~SüæÓŸÐ%o!o!oµ®ÔºRë ÌOœŸ8?úLï3½Ït¸mwÛî¶L>?ùüäó°Qg£ÎFxzïé½§÷ ¨JQ•¢*üw$,ü3Òyé¼t’’’àx¯ã½Ž÷‚Mg4Ñ6ÆnŒÝ ŽÞŽÞŽÞ°Øv±íb[è›Ù7³o&m3Úf´MÓG!Ÿ–ìÝtÄOµƒtuº:] “¤IÒ$ ¦î™ºgêpà2ÀåS\R>©‚Ê• *Ó½Oö>Ù ‰‰‰–––Æ1Æ1Æ1PíVµ[ÕnAõÔê©ÕSÁ¡—C/‡^`œoœoœÏû•4¾r…s çÎøñ3âg@øÂð…á !¨(¨(¨b~ù5æW°PY¨,Tà5ÅkŠ×¨ý öƒÚÀ²ºeuËêÀ†0DÓG#ÿ®O^ÀÞ½0rú¨é£¦¯e^˼–A»í´{ éÃ>X3šÑ R—§.O]û?ìÿ°?Ïž<^U}UõUÕ÷…Ïn“Ý&»MPõÛªßVýÊg–Ï,Ÿ ¶ƒlÙƒ €Þ-½[z·@6P6PV’Þ¼ŸýìÕcÕcÕcÈÕÎÕÎÕ†ôé#ÒG@¤A¤A¤D´ˆhÑ"ÎEœ‹8Ù›³7go‹9s,æ@u·ênÕݠ曚oj¾²áeȃ––Ö¬B/_’O^ÀÞÙqzÇé§!%(%(%&Í™4gÒM¾ð©HR ÷jÜ«q¯,9¸äà’ƒ`mgmgm¥F–Yj$Ä­Š[·êýb¿úôé7Ë–+,W@ÿ2þeüÁª¯U_«¾`VÙ¬²Ye0Ë5Ë5˳ fÌ*€aŠaŠa h'j'j'‚¼ƒ¼ƒ¼EQ ** ¬cë@VSVSV¤Òip˜Ã©‹ÔEêòîÿ÷—ß=W˜i”i”iiÒ¥5‚ôé=Ò{@ª{ª{ª;Ä[Å[Å[A|a|a|!dffBш¢E#Àô€éÓà4Úi´Óhðˆðˆðˆ×ú®õ]냙£™£™#èŒÐ¡#žË„ÿ§­€ÇÇÇö³ÛÎn; K£–F-£…F jº„¥8­8­8 .¥\J¹”ûê쫳¯4hß }ƒöÐûlﳽςá#ÃG† ëMÖ›¬7<\Ô®¨]Q»÷…¬¨|Qù¢òP¨S¨S¨ÉÉÉ ]“®I×3Ì0]¥®RW FIFIFI`|ÕøªñU(5«Ô¬R³ ìº²ëÊ®ëÖ ¬€Í›56kÀ|…ù 󠤤¤é³%%Û¿VÀÞ¤¿I“Sƒ§O †‰¯'¾žø*®8¸â`Mwƒð¡2êfÔͨ ;oí¼µóÜ÷¿ï߆d É’š7jÞ¨9ÈœdN2§¿Ñð.É©“ÔIê$PVV†BY¡¬P™d’ d-ËZ–µ rwåîÊÝyµójçÕ†ÂÇ… Cñ÷ÅßE‹.])H ’‚@«V­6 øNñâ;Ð:£uFëÌûK˜úåôËé—ÃN† ;ñVã­Æ[A¿²~eýÊ ¸¦¸¦¸ббሄÄ'ÿ¯Iø Ø; Ë/,¿°<”Y^fy™å0°ãÀŽ;jº„*|Xø°ða°®õºÖëZƒádÃɆ“aä©‘§Fž{w{wû/`QdA>?Ÿ|ýÿªù¤æ“šOà‘Ç#GPÔ°¨aQCMwƒðW©Ú¨Ú¨ÚÀ‰k'®¸ ¬X/°ÏÑž£=GÃÌæ3›Ïl. — ŸÞ'{Ø©¶µÚÖj[á@êÔ©mmmòþ5KÂç)mAÚ‚´°õ›­ßlýÂ+†W ¯cÖŒY3f Ô~Zûií§ ³YÈ,>|‚ æ_Ù¶9ls\ë¹Ös­7šÝhv£™¦»Aø#Ž?:þè8Ì\5sÕÌUk’k’k .0„:þuüëø‹Â%¿ï_/`²‹²‹²‹Ðlh³¡Í†ÂwzÜéÙ]³»fwÕtw…“ 'N†#Ž<:ò|ƒ|ƒ|ƒÀËÇËÇ˦EM‹š¥ôJé•ÒÓtZA¾fÿz{§Zåj•«Umkmkmk42h¤¦»ãë•j”j”jËm–Û,·3‡Ï>s&ÞœxsâMè}³÷ÍÞ7Aw‚îÝ šN+‚ YˆÿëÈË#/¼„;ßßùþÎ÷0oƼóf€n-ÝZºµ4Ý=_¾GO=yôäýªývÁvÁvÁ0lô°ÑÃFƒ­ÒVi«ÔtQr€IDATJA„ßÓØìÆaÇA†*C•¡‚ûA÷ƒîi:Õ—Kõ­ê[Õ·ð«Ã¯¿:€ï[ß·¾o¡Ib“Ä&‰0Y9Y9Y) — Ÿ?0‹¶m-ÚB“½Mö6Ù Ç Ž7Õ0Õ0Õ0M§ûr¤LO™ž2–ç/Ï_ž§#NGœŽ€ &<˜ðz÷îÝ»woЭ;Zw´¦Ó ‚ ü¹}ýi5¹ÕäV“áÒ½K÷.݃»Éw“ï&C}êS_ÓáJ¢ ‚‚е¡kC×Â:õ:õ:5ØV·­n[–]XvaY°N´N´NÔtXA„¿Oã#°w,6Yl²Øí·Ün0Ê;”w(ò&åMÊ›¤ét%GáºÂu…ëàH…#ŽTWWWh2¦É˜&c`J÷)ݧt…K„’ï³)`ï´jѪE« §§—*_ª|©²¦S}þÒrÓrÓráç?ïüy'œ68mpÚ¾ü>ðû@èõ°×Ã^AÏIÏIïï¬E(‚ð™Òø,Ä?ð&àMÀØeºËt—),y¸äá’‡`UÓª¦UMM§û|}:ß^|{ñm¨[¿nýºõaÚˆi#¦…K„/ßg;{'*,*,* ævŸÛ}nwø!뇬² jlÕØª±šN÷ïy[æm™·e`Ç­·vÜ‚ûÖ÷­ï[È #6ŒØuúÔéS§Èle¶2[M§Aøô>›YˆÄÙÝÙÝÙZ÷lݳuOØa´Ãh‡,(µ Ô‚R``` é”ŸN´y´y´9¬®µºÖêZ [A·‚n˜»c;Àa‚ñ2† _¡ÏöâÿêbÖŬ‹È&Ê&Ê&‘ô#éGÒ8âˆÓtºGýVýVý¼¼¼aî½¹÷æÞ÷¾î}ÝûÂÌ£3Î< =z:ôÔtZAÍùì/!þ¯Ð¡C7‚O°O°O0L}0õÁÔP)¸Rp¥`M§ûçråÊ{=÷zîõ„k+®­¸¶6Ø|`shfÝ̺™5ÈÈÈh:­ ‚數öŽß ¿~7 Ä:Ä:ÄæGΜ ÆíŒÛ·Ótº¿.þAüƒø°nÒºIë&AöÌì™Ù3a¬j¬j¬ \Z¸´pi¡é”‚ ŸŸs ñyóç=tOëžÖ= û}÷ûî÷îsŸûšN÷ÿЕ®t…û£ï¾?~ ù)ä§°t±t±ty÷æÝ›wO.A„?Sb ˜þ=ý{ú÷`„Ó§NpSvSvS[·n}¿º…º…ºDߊ¾} â â 4pϬȧȧÈŽ?8þàøXÖkY¯e½ ýÙögÛŸ…±÷ÇÞ{L&˜L0“2AþT‰-`ï8wvîìܼͼͼÍ`[Ÿm}¶õ$¿$¿$?8QùDå•¡|ÿøþñ¢ Q…¨>ÂŽSH!xË[ÞþñfÙ²d€uÃ× _7ŽY³:f6MØ4atmÔµQ×F ¨¨õ?ß&‚ðw}öÓèÿª6oÛ¼móžÉžÉžÉàÇm?nûq\o{½íõ¶ðªÇ«¯zÀÑ*G«­õëÖ ™R¦”ý׆¼à/ `XÀ°€a`4ÝhºÑt¨Ù¼fóšÍßoããã k\ûãÚAæ-ó–yÃìC³Í>šî5A„’«ÄÀÞ)¬YX³°&äý˜÷cÞpl걩Ǧ«i¯¦½šö~»óYç³ÎgÁË»/ï¾¼û÷÷)”GÊaR¹Iå&•ƒií§µŸÖâ†Ç Áƒ?„¹§çžž{Ê(Ë(Ë(aÖôYÓgM…Kác)ñ#°Ì˜Ì˜ÌXðhÁ£`ÍÆ5×l„‚jÕ ªý~û§5žÖxZ®W»^íz5p‰¿²¶m~­üZùµ`õÑÕGW…ÇÇGPìSìSìƒ±ÍÆ6Û " " "¡g|ÏøžñÐöVÛ[moÖ@­Z5Ý[‚ _Ž;þ¬ºYu³êÂR—¥.K]`gØÎ°að:÷uîë\žIϤg¿ÿ\ÇÑGw ûÇï¿<è»ê»ê»þñ~ü ý ý ax“áM†7ŒS§2N½ÿ½¢²¢²¢2Ì0›a6à fçÎÎ ò`y°¼?Ÿ&‚ð¹*ñìbŸbŸbv v vƒêêj8þíño iiiï··¹nsÝæ:´:huÐ ¼Ü¼Ü¼Ü~ßnTŨŠQ¡OnŸÜ>¹p÷ÕÝWw_ýqøEûí_´¡azÃô†éšîA„/ÏsL1E1E1êt©Ó¥NXÿëú_×ÿ ¿Ìþeö/³¡õ¶ÖÛZo]]]Hj”Ô(©œÙuf×™]PìWìWì÷¾½ççgX¹på• !¸mpÛà¶ÿÇŽ;Ð {){){ i>i>i>peWö‚ººº=X-‚PR|1#°?óæÛ7ß¾ùŽÆ= ë|Öù¬ó¬ëY׳®Ãj¯Õ^«½ R¹Jå*•ƒ›wnÞ¹yFUUaTÈtÈtÈt­}Zû´öýû=ö{ âÈŠ#+Ž„VÏZ=kõ ê-©·¤Þp®â\Ź ˜×4¯i^ðÁM÷‚ —ã«)`ÿëJõ+Õ¯T‡ž{nì¹²«eWË®å÷•ßW~ä×ɯ“_òòòòòòÀk‘×"¯EàµÎk×:¨ëV×­®¸é¹é¹én¢n¢n¢¦JáëQâg!þS©¹©¹©¹Ù/³_f?PEª"U‘ðˆG<ºUíVµ[UX¤X¤X¤‡E‹ÒFi£´2È CÓG!‚ðõúbîý]fþfþfþ`àhàhàøþçZw´îhÝfß7û¾Ù÷àââÊÖÊÖÊÖšN-‚ ¼óÕ^B̘˜11c" ^2xÉà%Ý&»Mv¨b]źŠ5( ”ÊøFçotÀý€û÷šN-‚ ¼óÕŽÀ²Êg•Ï*fÍš„õ³×Ï^?–<^òxÉc¨x«â­Š·Àg¤ÏHŸ‘v=ìzØuM§AÞùj X4ÑDF­ŒZµ‚2eÊ8€öí'ÚO w½Þõz׃– Z6hÙ|û÷=a§ÂN…úàÝ ‚ è«-`'?œüp2T˜PaB…  tR:)³¦”ü¨ü¨ü(ômÔ·QßFТ\‹r-ÊÏbŸÅ>‹!Ì4Ì4ÌTÓG!‚ðõúêf!ªÂUáªpˆÜ¹5r+tÕîªÝUû·—ÊeÐ+¨WP¯ ÀC aIÅ%—T„)=§ôœÒ*¬x°âAM Â×ã«%H R‚Ùƒ³g† îÜ+¸ÿùçµµµ¡wbïÄÞ‰Ð&²Md›Hðuõuõu…'ùOòŸäkúèA¾_]‹Ø±3b'˜ì7Ùo²¬zXõ°êñ×?/Ÿ$Ÿ$Ÿ½{;÷v†Öµ[×n]–®^ºzéjx"{"{"ÓôQ ‚ |ù¾ºù"òEä pÄG@ñXñXñøï·#ó”yÊ<¡ç=èù´íÖ¶[Ûn°tÜÒqKÇAè ÐA¡ƒ4}´‚ _®¯¦€–/,_X"NEœŠ8•ZUjU©Õ‡·+”GÊ#¡gxÏðžáЮ_»~íúÁòÃË/? µk=þêî4 ‚ |z_MËìžÙ=³;d˜d˜d˜@Y“²&eM>^ûòöòöòöгJÏ*=«@{‹öí-À×É×É× ,x°àÁM÷‚ —ã«)`±GcÆí¦ÚMµ›B©*¥ª”ªòñ÷#Ó•éÊt¡Û‘nGº.9]rºäÀò:Ëë,¯÷ÊÞ+{¯¬¦{C¡äûj XèýÐû¡÷Á!Ú!Ú! ‚ ‚ ‚>Ýþä5ä5ä5 ký®õ»ÖïÞ½Â*—U.«\à®ê®ê®JÓ½"‚Pr}5,R+R+R \—¸.q]òïíWvHvHv:ÇwŽï=L{˜ö0…Uþ«üWùòwÊÞ#2A„¿í‹/`™w2ïdÞĨĨÄ(p_ã¾Æ}æò´ïÒ¾Kû.Ðw]ßu}×Ášåk–¯Y·Þzx롦{K¡äøâ XRNRNRHk¤5Ò°™i3Óf¦æòÈúËúËúCÛÓmO·= ýýúûõ÷ƒ vì6ØÁ ×®7\-la‹¦{OáóõÅOðŽOŒOŒOãõÆë׃Q£:Fu€*TáLâø«d&2™ ´>Þúxëã è¢è¢è=6zlô€â]Å»ŠwAcÓ`æéÞAø||ñìù€çžGCGCGCÐí¯Û_·¿¦Sý^ ÇŽ-A®”+åJØúùh(r(r(r€›ÓnN»9 ’z$õHúkh ‚ðñ}±—&L<EQEQEQ`ßß¾¿ýgxéðÏ4¼ÐðBà ?"?"?민þ1‡‡‡C»Jí*µ«¤é”,§ANƒœp¡å…–Z‚lll ÈëÉëÉëiOÓž¦=¡nHݺ!p¿ÒýJ÷+A²k²k²+˜&›&›&ƒè=×{®÷Ò¦¤MI›¹ž¹ž¹ž`‚ ¿]X¥x`ñÀâð¸ÖãZkÁ«v¯Ú½jAÊ eLΛœ79Yí³Úgµ‡"""pÅW@qVqVqär¹\.‡ýôÐx/ð^à =¿íùmÏo¡›N7n:€=öØÃí·wÜÞùãòÇåƒÊÝ+w¯ÜlJÙ”²)—[_n}¹5XT·¨nQ gÎ*œ*U4‚—ý^ö{ÙtGëŽÖ Õ7Wß\}³¦Ï¢ |ž¾ØXLý˜ú1õÁøµñkã×`lmlml­éTÿ\ýªõ«Ö¯ cÓÆ¦Mƒý!ûCö‡À‰€'@Z*-•–j:åïéøèøèøÀÑ€£G Ð(Ð(ЬkYײ®;ƒwï †«+®®¸º:%tJè‹®.ººè*Ĉ;wòòò!oHÞ¼!°üþòûËïCâ‰Ä‰'~¿_y˜F¿ýbô ”?UþTùS`˜m˜m˜ Õ,ªYTƒ×ç_Ÿ}°Æk ›l² `X”³(gQŒ®]1ºåmÊÛ”·ÕzÕzÕz¸p%à ̰ža=ÃaU“UMV5äœäœä0{köÖì-ØO¶Ÿl?z÷(îQ êyêyêyàÖÇ­[M‘M‘MÑôÙ„ÏÛ—7K"‰$x¹ûåî—»Á)Å)Å)…ßÌGÿ2ÔjR«I­&0áÜ„sÎÁ¯í~m÷k;8|òðÉÃ'Aº+Ý•îj:åo$’H"H;¤ÒŽ÷?Ö9§sNçäiåiåiñßk²YŠ,d¡²PY(ȶȶȶ-hA‹¿±_]tÑ}?B•NJ'¥“ÿ ¿ œpÂùoá,[<¶x,dêeêeêÁmw¶ÝÙ× ¯^7„fk›­m¶JýRê—R¿€z¶z¶z6ÿá½#Ï‘çÈs@§P§P§´çkÏמ¯é“&Ÿ·/n–·,oYÞ2HÙ˜²1e#47hnÐÜ€ÿþú¥©áTé†L²šd5É ~¶úÙêg+P…«ÂUáÐû»Þßõþä!òyˆƒša†È6Ë6Ë6£Å(HT&*•à<ÆyŒó`4£ ¸à‚ A¿iç]!¹Ï}îÿf»ÿLÿ9rä@(¡„å(G9À 7Ü€"Š(.r‘‹@_úÒ÷7??ÍiNƒ,C–!Ë€¢ÊE•‹*CÑÖ¢­E[A/Q/Q/ìÛÛ··oõºÖëZ¯+xyxyxyü>Žºžºžº`‡vü· K—¤KÒ%+++tttpùÆå—o4xÞá3öÅ°Ü Ü Ü È«“W'¯˜/2_d¾HÓ©>=³g=ÎÂdÏÉž“=aiÚÒ´¥i j©j©j ßLúfÒ7“@ËWËWË÷ßϧ¶WÛ«í!Ø-Ø-Ø 6uÚÔiS'P®W®W®‡Ž3;Îì8®\¾rùÊe(œP8¡pD]ºuªT)¨ROÚŸ(IC\‡¸q•¤­ ·6ÜÚP’T‹U‹U‹ÿý,}Xú0I*(SP¦ Œ$¥4NiœÒX’/$^H¼ IY‹³g-–¤”—)/S^JR’Y’Y’™$å7Ëo–ßL’2]2]2]$)Î<Î<Î\’òòóòóò%©xuñêâÕ’”â•â•â%I Íš'4—¤ôéÓ7JR~F~F~†$%mHÚ´A’’/&_L¾(IEu‹êÕ•$éôFz#Io¿yûÍÛo$)»Vv­ìZšþ ÂçMöîÿhº~,vvvp<øxðñ`ð½à{Á÷(((h:Ý¿/Ú*Ú*Ú –X-±ZbÕMª›T7!C<†x€ÎfÍ:ŸpšvÁÜ‚¹saXô°èaÑ`_`_`_súÎé;§/hwÔî¨ÝQÓ½$BIôÅMâˆ9s<æ8Øv³ífÛíë-\ï¼›Ä2Ãi†Ó 'xÐãA=`ãšk6®‚ví Ú}ºýç7Èoß:[u¶êlõÂê…Õ ƒe²@©éÞ¡$ûâF`¾Ñ¾Ñ¾ÑïW°gÀž{4êóñ:õuêëTX¼hñ¢Å‹Ày±óbçÅ0R=R=R J=¥žROÓ)AþÜ—3ÛÊV¶Â›ð7áoÂÁ6Æ6Æ6FÓ¡>?e,ÊX”±€Y>³|fù@̺˜u1ë`õÆÕWo„l—l—lM§Aøs_LËz–õ,ëdèfèfèB™oÊ|SFL?þC¶Z¶Z¶Z0£þŒú3êCÊÞ”½){áçr?—û¹dŽÍ›9VÓ)AþØSÀÞMƒVQQó±æcÍÅ_ÀʪŽU«:0}ðôÁÓC¾q¾q¾1ø–ñ-ã[Ò;¤wHï é”LµVµVµÂN„; &LÐt*Aþ Š9ÿ¡é *¶{l÷Øîr'äNÈhݯu¿Öý@¯´^i½ÒšN÷ùSÖRÖRÖO{O{O{Ž Ž ŽËêËêËj¨V%¬J60l`Ø@Óiß»uáÖ…[`¥ÁJƒ•ààêàêà 9ksÖæ¬…$u’:I YM²šd57foÌÞ˜AŒqŒqŒ1pƒyœV:­tZiº7áëòÅŒÀþÿç‡@ÏGÏGÏ”k”k”k4ªä1©gRϤüpù‡Ë?\ó¦æMÍ›Â"ÃE†‹ !îNܸÏhMÉèžÑ=£{³ÉÏ&?› ÁÁÁpÝûº÷uo•4*iT\º~éú¥ëp­ôµÒ×Jƒ¿¿?ªp¨Â¡  ^¡^¡^K–:,u€Ã1‡cÇ@~ùüòùåaÕêU«W­†ë½®÷ºÞ ÎŽ8;âìØX°±`c¨f©f©fiº7áëòŰävÉí’ÛéjÓÕ¦«A÷‚îÝ šNUrœ58kpÆY޳g N“&;M†EgYtb•±ÊØÏ`¼ã$ÇIŽ“À¶œm9ÛrШJ£*ª€Û~·ýnûAÙUÙUÙº^ïz½ëuèÿ ÿƒþÀÊÍÊÍÊ Š5,jFFF`µÎjÕ:úKý¥þ11bbÄD\¸0p!ô˜Úcj©ÐÒ³¥gKO8ï}Þû¼7¤5HköLákðŰ„ý ûöƒUªUªU*GqšNUòé7Óo¦ß Fºté[=¶zl…ù æ/˜¿"ã"ã"5ÙÏÿYQ. —†ó~±ÝRH­“Z'µN‚îlÝÙº³AwªîTÝ© Û-Û-Û 27™›Ìí÷ÍÊ"d²È6È6È6€ø˜ø˜øðßî¿Ý;\]zuéÕ¥P¾°|aùBО¬=Y{²ûA¾B%¿€yã7dÚeÚeÚy‚y‚y‚¦C}ytƒuƒuƒá[ûoí¿µ‡º}êö©ÛîY¸gá;v&쌂)Q¢u¼:^ÒTiª4ÐB -Í–Í–ÍqÄñ7ŸûÏâÂÅ]Š»wùÍÏp ¸Ìe.ƒÁZƒµk¡t­ÒµJׂ®Wº^éz&XO°ž` k;¯í¼¶3˜4?h~PsçG¾F%¾€ï)ÞS¼²zeõÊêf§ÍN›Ötª/—ömíÛÚ·a€åË–в~Ëú-ëÃ’K,Y?<þðø¿—Ç|œù8óqP[[ þßùçÿ²²²ÐzEë­W€r¼r¼r?%¾€åÏÊŸ•? ”NJ'¥“¦Óÿ”I I I Lš?iþ¤ùPêI©'¥žÀüqóÇÍQQQšN)Âç¤Ä°Ü¹s‚þxýñúã5FøPå Ê”‡±WÇ^{ªU+ªV‹üù/ò‡Ç»ï~¼[Ó)Aø”Ø&JR ä7Ëo–ß 6l4بéTÂÇ¢ã¡ã¡ãCN99ä$´ßz|ëñ°4kiÖÒ,¸½óöÎÛ;ÿ9u'u'u'ˆÙ³5f+¨§«§«§kúhAøJlSÏUÏUÏ…¼“y'óN‚þ>ý}úû4JøØáŠpE8xö>ì}úMî7¹ßdX·mݶuÛà‚Ñ£ F ÎTgª3áØcCŽ ËG,±Bå¡òÐû-áÿ¥Ä.%U¼¨xQñ"(´)´)´½êzÕõªk:•ð©È§É§É§AkûÖö­íÁø‘ñ#ãG°©Í¦6›ÚÀ­ Z´àȽ#÷ŽÜƒ¨gQÏ¢žg+ÏVž­ ÒóJÏ+=EyEyEyM C‰ý·©z°z°z0¨Pÿ þ´»jwÕîªéTÂ'×~ôƒzKë-­·jÔ¨«ë¬®³ºDÅFÅFžßÜÿGÿý„HËHËHKM‡ác*±#0õIõIõI(Ö.Ö.ÖY5Y5Y5M§>5õeõeõe8¦wL¾²úÊê+PPTPTP<á OÞo$H„ŸÖÿ´þ§õÀLf2SÓG#‡(±#°woâÅSLl²ÉÖt(áSË? \”_”_”CbÛ͉m]tÑýýöjµÚü×ú¯õ_ ‘#;FvÔôQ‚ð1”Üö2=™žLÐFmM§>5} } } XtzÑéE§á€ýûöЫn¯º½ê‚y5ójæÕ~ÿ¹§¥ž–zZ ŽÚµ?jÿvôš×¼©·Ô[ê EéEéEé ª¬ª¬ª yyyðæÅ›o^@ìϱ?Çþ /޽8öâD–‰,YÂÖ…­ [Ï®<»òì D]ˆºu^j½Ôz©ñ·ãoÇ߆Ìþ™ý3ûCA@A@A¨ªªBqfqfq&P™ÊTÖtï Âç¥Ä¾Ð2÷bîÅÜ‹0ãÐŒC3Aߎ};öíµÚ×j_«½¦Ó ÿ¶ìýÙû³÷C‹}‰1‰1‰1ðvÊÛ)o§@VtVtV4äÊre¹2(´+´+´¼ñÆÈ"‹,À;ì€bˆ<ðÀ¸Ï}îóþŠÁ;餓è£>È‹åÅòbÐóÖóÖóÃlÃlÃl0Úk´×h/˜Î6m:ì]ì]ì]ÀÖÍÖÍÖ Ì™?2–-[6ã3þ8Á Nhúì§Qbï½û²|¹|¹|9Ȼɻɻíi(`_ê†U «BƒÝ v7Ø öëí×Û¯‡ÒZ¥µJkÁꪨ/´^h½Ð‚±ÇvÛ<¬=¬=¬AÿŠþý+`=Âz„õ°¹lsÙæ2”ëR®K¹.`ºÑt£éF0ziôÒè% 1b0 œ œ œ@YQYQY´µµµµµAî#÷‘û€vvvH¥‡ÒCP«ŒUÆP|¦øLñ(,_X¾°<älÈÙ³rÜrÜrÜ G7G7G2å™òL9d´Éh“ÑÒ¶¦mMÛ A5ƒjÕ„ŒŒŒ(XW°®`ÈwËwËwƒÍ› 6Àq‰ãÇ%PiS¥M•6“¾“¾“>˜Œ5k2´¿ÓþNû;MŸ=AøgJîÌ:×:×f\™qeÆè÷S¿Ÿúý5×<\óð'ØáÎpÔgÔgÔg@¾Y¾Y¾È'Ÿü?þ˜êŽêŽêÜÝwwßÝ} ¤¤|ù6òå¿—†ä¯å¯å¯¡Ø¹Ø¹Ø¸Ãî€ÂHa¤0¶²•­šîõÏÀ#ñ²Ûe·Ën¡ÏCŸ‡>‡¨¨(ˆ°‹°‹°ƒ¼qyãòÆõë Ö ÜÒrKË-xÓóMÏ7=Áû†÷ ï`¹ÏrŸå>еѵѵRH!EÓûÇÔUÔUÔU ¯K^—¼.Û8·qncHœ28e0<7ynòÜ^ôÑÿExÙêe«—­ p{áöÂí`¹Ýr»åv¨š[5·j.ÔPÔPÔP@Ùne»•íZ´hÐôQ Âÿ[Ébˆ!¨—«—«—ƒz«z«úþÿ¶èmÑÛ"XõdÕ“UO cxÇðŽáPjTû|îbÅ‹/V„Àš5k‚Çxñã!°N`À:puöÕÙWgÃÈ´‘i#Ó 87878~ðûƒßì³vÌÚöØóWnÝ|i ‚ ‚ ‚àyÄóˆçpmеA×ÁãÍ7?Þ Ú´h?€J­*µªÔ ú\és¥Ï(;¥ì”²SÀÚÚÚÚÚäyòþþttt ÑÀF [-[-Û¿Ð{7,oXÞ°k;k;k;èök·_»ý ñzñzñzÐÀªU+0Œ4Œ4Œ„òß—ÿ¾ü÷¡ŽPG¨!Ož'Ï“Ã+ãWƯŒ!¥GJ”à)yJž%nÜüçrÛç¶ÏmA)A)A)pºÑéF§AšYšYšT©U¥V•Z0¢Æˆ#j€ûF÷îA/P/P/ßOvÈ#¼ßïGa£°QØ·¹ÍWðFheeepnãÜÆ¹ 8ãŒ3Ð&°M`›@H}šú4õ)Ü-w·ÜÝrp­ÒµJ×*ÁñÿxüG¨Z½jõªÕ¡C×];t§&NMœš€|¼|¼\¬A*hH‰-`ŠåŠåŠå ÐRh)´ ¨EQ‹¢¿ß.x\ð¸àqð|Úóiϧù6ómæÛ PU¨*TA}y}y}9/(^P¼nÄ܈¹vÎvÎvÎ_5¿j~Up¶u¶u¶…,ï,ï,oHÕKÕKÕ[l±ý?ò% K–0 ž¾zúêé+H~•ü*ùÝy,zRô¤è %%%ÂÁJ+¬ .\€.-\Z¸@ãùç7žC-†Z YUYUYU`Ø éocÉ%ó“ùÉüÀK,¶´¥-Ф…I x!{!{!ƒ“ßüîäw0Ïožß Ê$”I(“¥~-õk©_¡øjñÕâ« ]N»œv9@t€rÈi‚4Aš 4SgSgSg(#/#/#kkkXµxÕâU‹ÁÐÞÐÞЪt¬Ò±JG8Wñ\Åsáæò›Ëo.‡×:\ëp ̬̬̬  mhÞ7¼oxÈ ƒ ¨Q¿FýõAé«ôUúiLãpÂüñÇîøÞñ½ã ›gmžµy¸rä>–è.Ñ]¢ ÖßXcý <´4BöZöZöúý¥Ç).S\¦¸ÀÝÜ»¹wsa[ùmå·•‡Ðæ¡ÍC›Ãws¿›ûÝ\°\i¹Òr¥¦Ó _ª;“---½yzóôæAnhnhnèÿµ!2dÀv°XÃÖ€¶¹¶¹¶9¹¹¹BñáâÃŇŸù™ŸAöTöTöôÿh/Š(¢þFÐç<ç9H£¤QÒ¨8àwÏÝã÷Þÿ8{zöôìéðªì«²¯Ê‰ù'柘fUͪšU…•TnP¤³ÒYé,ÈRd)²…ÊBe¡ïg9*ìö {PVPVPV¶±máDEI$\üá‵G×]{¼u¼u¼uàûu߯û~XÇ[Ç[Ç„ý ÿ Y¤,R µãkÇ׎‡E1‹bÅ€Ì^f/³‡Å]wYܽ½½4VøR•ØöŽÞE½‹z!¯Q^£¼FÿÇÐŒf4:Ò‘Ž8!qBâ0ïiÞÓ¼'888ßò-ß!„ò´÷Ÿ‘ W¹ÊÕ¿ð-oyËï' (P àý®/yÉKÞ¯(L0Á@i¤4N'ƒÂË…— /¿oÆ>Ä>Ä>:t<}›÷mÞ·9ü0ï‡y?̃V¬:XÚNm§¶ à7Çñoö¾Ùûf/ÜÝuw×Ý]P°¨`QÁG˜ ssþÍù7çÃÞS{Oí=c‡Ž:v(´Õn«ÝV´zkõÖêýI¾_´Ô°Ô°Ô0x¤ýHû‘6äXçXçXk.ÅD‹‰a⡉‡&çVέœ[ÁÊ•…+ !}~úüôùšî5áKSâ ˜A˜A˜Ad9e9e9ýþ÷²‡²‡²‡8.q\â8ؽe÷–Ý[à’ö%íKÚ0Ävˆí[ÈÊÊÊÊÊ‚‚܂܂\ˆ’¢¤( Šò‹ò‹ò!v]ìºØunœnœn q—ã.Ç]†ô„ô„ô„ßï7±tbéÄÒ:5ujêTx•÷*ïU¼®ðºÂë ïלU§«ÓÕéð¨Û£nºÁã±Ç> Ò=éžtž[>·|n UÎT9Så Ÿ>|Î:wèÜ!èæ×ͯ›H °æÞš{kîÁ‘_ŽüräˆÝ»=v;¼jþªù«æPhPhPhQ¢:EuzŸ7ì›°o¾õÚëµ×kCúé?¤ÿðÏÏK©„S §`¯Ç^½0hö ÙƒfCíÓµO×>ÍûPü‰¢E#ŠFÀ©A§k¦¬™²f ä;ä;ä;|ø÷'1(1(16ר\cs H©šR5¥*<Í|šù4­_´~Ñz333ø íl6Øloÿæþ‡çû_Ï3žg<‡­µ¶ÖÚZ N‡ž= á+ÃW†¯„Þ;¼wxCDˆ= ®g\ϸž°Ü¹ÿr¸RõJÕ+U?~®wÞÍvâ4Äiˆ˜l1Ùb²öߨcÿ .H¤ ŸnÿÂ×¥ÄÞ{ǨžQ=£zÖ,­YZ3 /}é `@ €E¢E¢E"´°laÙÂLCLCLCÀ,Ó,Ó,T›U›U›a»ïvßí¾ c£c£cŠ5Š5Š5`½ÏzŸõ>Xæ¿Ì™?ÈÊÊ‚ÑX£±FcCâÐû\æ ̘7€Ÿoþ|óç› +'+'+&Ú&Ú&ÚPïf½›õnÂþiû§íŸz~z~z~ o(o(oû.í»´ïèÒ?¤t÷ëî×Ýmë´­Ó¶èÍ×›¯7̜͜͜az¯é½¦÷‚ìyÙó²çöíÚ;ÀHf$3’A'·NnÜ ¥aKÖ†`¬k¬kü›Åoë,©³¤Î’÷³ÐMv™ì2Ù e(Cÿúù"¤)Žõ=Ö÷X_¨Ö°ZÃj Á«¯W_¯¾ÿüjmÒÚ¤µ '''àLÚ™´3i0`ç€v‚zè}À÷çÝ,<ùpùpùpÿ,ÿYþ3”iQ¦E™pÓà¦ÁM¨žS=§z”«[®n¹º=5zjôT¨°£ÂŽ ;@VFVFVä ä ä @vEvEv¨Nu>â{ê¢fGÍŽš ¼x=ð‚eO—=]öô[ë·Öo ®=ºöèÈbd1²°íoÛß¶?„;‡;‡;ƒlŒlŒlÌoé~2zázázá0$xHð`Xä½È{‘7„……GK–-?aáë •pÇ“'O–¤ŸÆþ4ö§±’TœSœSœóþ÷‡»î~¸»$5:Ùèd£“’ôbô‹Ñ/Fk:õ—+þQü£øG’ôݵï®}wM’^¬x±âÅŠo÷êÁ«¯”¤¦‘M#›FJRà/¿þ"I!ãBÆ…Œ“¤”ê)ÕSªKRúŠôé+$)¤QH£F’”¾!}CúIJ½‘z#õ†$…„„HRúŽôé;$)-&-&-F’îﺿëþ.IÊPf(3”’¤2S™©Ì$©óåΗ;_–¤S§e|ÊxIz { { “¤Ôn©ÝR»IRøàðÁáƒ%éa݇uÖ•¤§'Ÿž|zR’‚‚‚$);;;;;ûÏ¿¸Bq…â ’´o侑ûFJR£Š*6ª(IwºûÓÝŸ$)mlÚØ´±’ôðÎÃ;ïHR‚i‚i‚éûÏm3¶ÍØ6’ô³êgÕϪ÷?ÏlŸÙ>³½$Ýßÿýý’ô ÑƒFIRÖY?fýøñ¾~~~’´üÅòË_H’tGº#Ýùxí _§ Ñø¼ñyãó37gnÎ\l$ɤªRU©*”ö.í]Ú†µÖfXP«ÕjµZÓ©¿\a¡a¡a¡`àbàbàeee¡áÿŒdT?¨~Pý)R:¥t‚ ºAuƒêÂüÐù¡óCá¹ës×ç®0U6U6UA5‚jÕ€¿¿?˜>9|r85 jÔrúæôÍé “fNš9i&Ü9vçØc ?.?.?¸à‚ ¨ªªBè÷¡ß‡~/;¿ìü²3¤ë¥ë¥ëAFãŒÆáÇ£?ýñ(ÜÝywçÝpÈóç!Oð1ö1ö1†D§D§D'X×k]¯u½à@Ë-ü…‘H‘u‘u‘5¼õ{ë÷Öò ó ó !emÊÚ”µžž>M}šú4¹¿Üÿÿø¯[–+Ë•åB~üù5`ÕêU«W­†ë½®÷ºÞ ÎŽ8;âìØX°±`c¨f©f©f}øé«²³ÊÎ*;!ânÄ݈»1ÿbþÅúÕ¾B%¾€™™™ANéœÒ9¥ß¿öâݽ¯º½ëö®Ûú+ú+ú+Ày½ózçõšNýåJjžÔ<©9˜_4¿h~äcåcåc?BÓ˜Ä$0Ùa²Ãd4®Ð¸Bã 0°ÝÀvÛAæšÌ5™kàù¥ç—ž_£F7Œn€ú¶ú¶ú6رc7 7n2Üê£ê£ê£Pz}éõ¥×ƒÁƒ@ýTýTý0Á` [ØúcôÇè{O{O{Op p p Ïöží=ÛCÙUeW•]ÁÁÁ ]I»’v%°ªaUê˜H&’‰M+6­Ø´"xºyºyºAÈ–-![@ª)Õ”jB¡e¡e¡%T/¨^PýýŸu®ê\Õ¹ ºTèR¡ ØêÙêÙêAÏž <¡ô¹ÒçJŸ / / /(J*J*Jú}7*¦+¦+¦CÄðˆáÃ!paàÂÀ…Ðcj©=¦BKÏ–ž-=á¼÷yïóÞÖ ­AZƒ?}ÖK¬—X/ÕyÕyÕyx»òíÊ·+ÿ½ï¥ðe*ñÌ\Û\Û\TÕUÕUÕ!»OvŸì>šNõõÒ¡3Bg¨bU±ªØØð»µ W³šÕ 9H’(M”&J0Zj´Ôh)¤4Ki–Ò Å(F8à¨Qó1FÞÿyNoø†o€\rÉýl¯B… ¤ÝÒni÷o'P(éô@zo¾}øö!,”/”/”ä6“ÚLjóþϹ>¹>¹> —…ËÂAj&5“šxÀƒ¿_!‹E@¶A¶A¶ÄÇÄÇÄÇ€ÿvÿíþÛáêÒ«K¯.…ò…å Ë‚ödíÉÚ“?¼Û õ õ õøïbÌÚÞÚÞÚÞá|_µ?‰Ã|²ùdóÉ Û%Û%ÛoŒß¿1 ,°ø˜;úÏ_ w‚ïß †ûÃî»? :$vHìeâÊÄ•‰û㫇©‡©‡AfÛ̶™mAÝMÝMÝ Ì§šO5Ÿ ²%²%²%šîÍç|ÆùŒó¸2øÊà+ƒ!;+;+; > áwC´£í@vOvOv²2²2²2 ³bfÅÌŠà˜æ˜æ˜ן_~ýùû72ã…^¼Ÿ½P‡:Ôò‡@7ºÑ dMdMdM€ZÔ¢ЉNtJSšÒüwúhq@q@qAü·P½kGq´ÐB dGdGdG€ïøŽï#Œ0â¿ï3lmØÚ°5Œ¾0úÂè P¼µxkñVPd*2™ ?EŠþÒ¥t)d'd'd'xÿ¾±wÜqÇýýä†0„!€n¸G8Â0Xk°Ö`-”n^ºyéæÐueו]WB™Ýev—Ù t¦3ùãÇIþ¦—Ç_yLϘž1=FîFîFîŸøË(|ñJüL·žn=Ýz`˜j˜j˜ o6¿ÙüfóÇßÏ+›W6¯l`÷O»Úý”6(mPÚà7o„þ…£ GŽ‚#‘G"DÂ÷ß;|ïÙnÙnÙnšîÅÇe¥ËJ—• ;Tw¨îP=z>ôü‡·kèoèoèz]ôºèu‹o.¾¹øö Û7lß0prsrsrƒ&Û o2\o»Þv½ ×ú^ë{­/ÜÞu{×í]SœSœS )³Sf§Ì†ÈüÈüÈü÷GD>Ž|ù‡? 3*fT„èµÑk£×‚E‹ àUô«èWÑp2âdÄÉþ,üd,ÊX”±Â&†M ›/ú¼èó¢¤Ú§Ú§ÚÛWo^½yñÉñÉñÉÖ5­kZWÈš=4{(XZZB©”R)¥RÞÿùÝ[ÞÍBLÍIÍI͈;"v@âÓħ‰O!©QR£¤FÑU£«FW…»»;xuãÕW7Àê†Õ «àYƳŒgص7joœ•••ÁÓ®O»>í ê^ê^ê^ÿü¼©oªoªoBàÁÀƒÁsºçtÏé U]«ºÖGœ)|JüL!SÈ20n6Ül8¤4Ji”ÒèÃÛý_qÝãºÇu‡8eœ2N ^k¼Öx­ÓlÓlÓì?ÿ¼^u½êzÕÁu±ëb×Åðkܯq¿Æº·º·ú z×ð;Ãï ¿ƒÖZ?hýNt?ÑýDw¨4³ÒÌJ3ÁhÑ£¿ÝJW*]©töYØgaÈß“¿'”Ó.§]NœÌœÌœÌÀ8ß8ß8~œÿãüçë)¯¦¼š&Î&Î&ÎàcçcçcVVV 7Ao‚ÞðÝî»Ýw;É6“m&ÛÀ×Ä×Ä×Lš64m6klÖØ¬².e]ʺ€Ž½Ž½Ž=˜_0¿`~|[ù¶òm*• TUUAò–¼%oÐñÔñÔñ„Þ^½½z{AáëÂ×…¯A'F'F'æÿÝ%Ó†ãŽk8Ü—»/w_¶Ö¶Ö¶Ö ©© S6OÙô|ׯ_m<,5_j¾ÔöÖÛ[oo=ˆ>}*úܸyãæ› {${${”””à‘é‘é‘ /·¾Üúr+\|qðÅÁP¸±pcáFðxåñÊã4¬Ý°vÃÚ ó–yË4xA5V5V5|Í|Í|Í@é¤tR:Á¨”Q)£R@w²îdÝpoEøöûØïa¯ÿ^ÿ½þ¾;|wønÒlH³!͠ᆹ¹Ü\n®éЗê‹)`V?YýdõèÄéÄéÄÁëí¯·¿Þþñ^+Uœ_œ_œÅ7‹oßõ@õ@õ@ˆë×?®?<Ÿþ|úóé°0paàÂ@xdøÈð‘!\ɼ’y%ó7Ÿÿµø×â_¡X§X§XòÝóÝóÝáÞø{ãÚ=µ{jƒúºúºú:œv:ítÚ ”ÚJm¥68?s~æü ÊŒ,3²ÌHh;»íì¶³>ô¡p‘‹|Æ+ï5Þk¼F¦ŒL™ÕfU›Um컸ï⾋p¹Éå&—›@×f]›umunÖ¹Yç&èèèh:ýWè?Ïm%æ$æ$æÀ™ŸÎütæ'˜0!`T¶®l]Ù”ZPjA)(}¬ô±ÒÇ}ôÑ×txáK÷Å0e²2Y™ v‰v‰v‰nnnžxâùíªÊ©Ê©ÊÁ«€W¯ÀÌÍÌÍÌ G=Žz.J¥‹\op½ÁuØ›±7coèVÒ­¤[ œú8õqê/Ÿ¿|þò9¼>öúØëc`õÌê™Õ3xµûÕîW»áÅÅ_\„g<ãý2ûeöK. —†K`¾Ç|ù3o̼1óàœû9÷sî[+¶Vl-(S.¦\ 4¼ÓðNÃ; _G¿Ž~MŸ•?¦°RX)¬ áІ+®€ªMª6©Ú.¼¼ðòÂKØûlï³½ÏàÈè#£Œ†–ò–ò–rð¼èyÑó"Øt±ébÓ…÷¯«> Õ<Õ<Õ<ˆ¬Y1²"¸¸¸Ã]ƒ»w  Œ{÷2î0A5A5A±±± Ø¥Ø¥Ø¥éôÂ׿‹™…øÎÞ ½A{ƒàʼn'^œ€™ógΟù!ï!šÅ,fAÑø¢ñEãyÿ íî})Ú*Ú*Ú¾‘)S4ä¶r[¹-È–Ê–Ê–‚¬’¬’¬H~’ŸäR©¿Ôäáòpy8GyP”X”X”² Y,´×i¯Ó^üÀüÀßãU4¥hJÑPgª3Õ™ïï1h=Óz¦õ ØË^öjúlüsY=³zfõ„^7¼nxÁår—Ë].éÓÓ§§O·ónçÝÎCƒ &4˜î·Üo¹ß]]]?“?“?ÓôQ|¾ ¶l)ØI[“¶&m…à3Ág‚ÏÀ¦wšÞi o:½éô¦¸»º»º»Bë«­¯¶¾ •b*ÅTŠùù¹x-Š a_\»Ÿv?í~l ݺ)|køÖð­F†F†F†šN'üS“ &L‚}_ô}Ñn˜Ý0»a¡cCÇ†Ž…ü¼ü¼ü<(;µìÔ²S¡òÞÊ{+ï…ò+˯,¿; v zkôÖè­yiyiyiMÕ'0›Ù̆â³Åg‹ÏBzÿôþéý!¢ADƒˆðlƳÏfÀÓ†O>m?güœñ3ØFÛFÛFC6uÚÔiµ}jûÔöKÉR²”@ÞHÞHþ ž¯„ñÅ\B|ÇáŠÃ‡+PÔ¢¨EQ ˆ;w,îTø¦Â7¾Ñt:áŸÒõÕõÕõýïJIÿýß¼„¼„¼xµåÕ–W[àb…‹.V€e–UXV¦:Lu˜ F›Œ6m«V;­v‚CŒCŒC 85vjìÔ¬²­²­²Áì®Ù]³»`|Ïøžñ=0hoÐÞ =hMך®5]>‡9Ì|e¾2_ Y#²Fd€Ì ™27@z•ô*éU ~vüìøÙµ.j]Ô:ˆ7Ž7Ž7†ÌüÌüÌ|0ìaØÃ°8>v|ìøÚe´Ëh—åë–¯[¾.”ò/å_Êä7å7å75}¶á¯ùâ ˜I®I®I.XW±®b]¢jGÕŽª- Ø—J¯—^/½^½8{qöbx4õÑÔGS¡sBç„Î Ð{zïé½§Cf½Ìz™õàÅ…^\€èmÑÛ¢·Áy÷óîçÝ!g`ÎÀœP0±`bÁD`2“™ †K —.ãdãdãä÷“P ¦L3˜ú½ô{é÷=¥žRO ÚeµËj—}?ûN;Y;Y;Ô Ô Ô  È¬È¬È ŠŸ?-~ …g Ïž¼syçòÎAnanan!dß;›}2õ3õ3õ!ëfÖͬ›¿8qþbÐ2Ö2Ö2ÝRº¥tK¹‡¹‡¹899AÍ€š5À©†S §P*¹Tr©äß\’þ‘ù(E)Jiú, Â?óÅ0­þZýµúCńРà¾î}ÝûºÐ¾SûNí;Ç9ÎqM§>TþìüÙù³á`áÁƒ…p¾íù¶çÛBÏž!=C Ý«v¯Ú½­öZíµÚƒ]„]„]T¤"á¿‹Õª´UÚ*mÈóÈóÈó€\÷\÷\wÈj›Õ6«-$E'E'ECò”ä)ÉS ëLÖ™¬3™™ ɇ’%‚üSù§òOJ¦’©dïß¦š¡š¡š2{™½Ì´iÒò‹ò‹ò‹ {]÷ºîuP.T.T.ý6úmôÛ€ƒ“ƒ“ƒ˜¾1}cúl´l´l´Àê±Õc«Ç Rÿ¤þIП¥?KèµÑk£×æ7Ï[à'~Óas™Ë\MŸ5Aø¸¾¸{`ï„:V­*ZUËdËdËdï׸J¦ØÞ±½c{æc›Žm:oß&¾M„‘º#uGê‚û0÷aîÀ]ìBÌŠ„/Ú7{Ç¥›K7—n c¡c¡c¡¡¡Ѐ|„÷ó ÿõ õ õ ¸iuÓê¦lÓߦ¿MªëV×­® “zLê1©˜œ79orQ¸á+òÅ,%õ¿Þ]Rq_å¾Ê}Üó¿çÏ_Ó©„¿*g\θœq°µÆÖ[kÀ–¡[†n }ë÷­ß·>Œ)S8¦ð7…K„¯Î;{§Aà 4„õÖWX_ÒRÒRÒRÀÜÊÜÊÜJÓé„ÿµ!jCÔØØ|cóÍAÝHÝHÝ~2ÿÉü'sp)t)t)†2”¡šN+‚&}±#°wÜ»»wwï† ;v„»Ãï¿;\Ó©„wÔUÕUÕUáÒ•KW.]y[æm™·œ£œ£œ£`îsœûão — Â|±“8þ×áÇ> w3ïfÞÍ„òòrФ5Hk¦Ó}}²u²u²u`—å.Ë]–ømà·ßÂ`ËÁ–ƒ-Ák©×R¯¥ “ÇÉã4V„ÏÑ?{§ÑÁF„”Ê)•S*ÃÓÃO?=¬éT_‘x≇§_œ~qfœ=röHˆ^½6z-̽7÷ÞÜ{Ðd|“ñMÆ‹Â%ŸûjF`ïlÕÙª³U’÷%ïKÞÓ”Ó”Ó” k'k'k§ét_µ£ÚQíWV^Yye%ø ÷î7êï©¿§þè—Ý/»_6t5èjÐUÓiA(I¾šØ;mšµiÖ¦D}õ}Ô÷~<üx¸x°ù£Ë~˜ý0û!l|ºñ鯧à7Ùo²ßdtiÐ¥A—`ØŽa;†í…K„î«+`eΖ9[æ,Ôt¯é^Ó~õë¨_GÚAí vÐtº’ïEâ‹Ä‰0·÷ÜÞs{CtNtNtÌ5šk4ךz4õhêò=ò=ò=šN+BIöÕ°w:ßí|·ó]ß¾%| œ*@  €£“ŽN:: Ž+å)OA=B=B=âýŸÿmRy©¼T®´»ÒîJ;XÐsAÏ=¡^µzÕêUƒÉ''Ÿœ|¬­¬­¬Å‹=A(Ä=°¿)Ú%Ú%ÚædÏÉž“ý~ʼn†Q £FÁÙÒgKŸ- Ï]Ÿ»>w…Ñ]FwÝ>}¾üuùëò×Á^ݽº{uá갫îƒÁwß|k5Öj¬²j²j²jšîMA„N°èìö³ÛÏn‡êêj¨´¿ÒþJûÁ§†O Ÿ 7NoœÞ88e|Êø”1¸»»ÿýý×/®_\âÂãÂã¡T¹RåJ•í»Úwµï¾ß.å\ʹ”s°.e]ʺH­•Z+µŒ[ö&ëMÖ›¬ÿóýdšfšfšÂpõpõp5Ì:˜u0 š,j²¨É"ÔeP—A]àÊÆ+¯l„–Z6jÙ¼+{Wö® ºt+èVÐto ‚ |:bö7÷ îÜü¬ý¬ý¬áí³·ÏÞ>ûãí ü)ð'nÜ.ø/¼ñYr’œ$'ð[â·Äo œp<áxÂñýï¦L˜‹’%-J‚þ ýú'À7ÅßS, — _QÀþ&¯^½6ÂîàÝÁ»ƒ¡gïž½{öÃQ†£ Gý~ûôRé¥ÒKÁ±ÎÇ:ë êêêêêêÜ~ðˆàÁ#`õžÕ{Vï¼Çyóÿ~»ÏÏOˆ¬Y)²Hý¥þRM÷Ž ¿G\Bü@YÖYÖYÖpÆçŒÏØ Ú Ú ‚[¥n•ºU ;v*ì¢+DWˆ†cáÇÂ…CùÖå[—ÿÍêíé]Ò»¤waúÃô‡éÃá}‡÷Þ÷çûw¬ëX×±.øò?ä<í<í<í4Ý+‚ Ÿž} £d£d£dè9¸çàžƒá@饔ßJ¾•|+A¥âJÅ•Š!jJÔ”¨)pæí™·gÞB¾W¾W¾HAR~süæøÍ«N¬:ñÛ¤Ѐ ¬¬ e—=\ö0ôµêkÕ× ~0ûÁì3°f9Ìr˜¦{Cáß#F`Ÿˆú¾ú¾ú>D5‰jÕæ.ž»xîb¸Üár‡Ë ™W3¯f^àäçäçä»ûìî³»¼Ö­ÿZÜn 7ÔVkX­aÐÄ·‰o_¨¿§þžú{ Ì·e¾-ó-())Æó¦é ‚ ”T_ý -?yuyuyupÔqÔqÔ+m+m+mH(›P6¡,ìa{®r•«ÐíD·ÝNÀ i…´Buë<Öà ‡7@;Q;Q;ñ7;xÉK^jú(A4G°OLå¥òRyAÒˤ—I/ÿ{Ë–',OÀŒ3f̘5ä5ä5äÀv¶³]ÓéA>_¢€}bú‡õë†öí=Ú{Àí Ú´A5PwPÝAuAŽ,G–#ÓtZA„’C°‰e¼e¼e A„χ(`ŸXöÁìƒÙ!òräåÈË0hñ Åƒÿ~»&×›\orýý*ñ[oy¼å1`ˆ!†ÐŒf4ÓôÁ‚ |FDûÄ’’’ `@Á€‚à°ÏaŸÃÿõ€r ZÐG4Žh2?™ŸÌ¶æoÍßšÒPi¨4š§4OižãÇ4}t‚ š#dþÄBû…ö í6æ6æ6æ`“e“e“õÿøÀHF2¼n{Ýöº Cï ½3ôürû—ۿ܆‹µ/Ö¾X†húèA4G°OìÙ¾gûží;;;5’5’5úëŸ÷zåõÊ댨0¢Âˆ °c׎];vÁEÙEÙE1kQ„¯˜(`ŸHÞ¬¼Yy³à•í+ÛW¶P)§RN¥œÐ+®¸B£o}ÓèøNñâ;øÝ÷»ïw.Ô¸PãB À 7Ü4}Ô‚ ÿqìIP%¨Tÿmþ·ùß‚Óc§ÇN? Ánt£4ìÖ°[Ãnï¼!{Cö†lP_V_V_†Öú­õ[ë¹ä’«é^AøtDûD^ïy½çõ0®`\Á¸¯0^a¼âãµßPÝPÝP 2=™žL6ÜÝpwÃ]PTT„¶´¥í‡ïFá³% Ø'ò¤î“ºOê‚ójçÕΫA¯”^)½RqräÈ¡Á³Ï<…Â@a럯¾þ9¯(^Q¼Úkµ×j¯²±²±²±šîA„G°¬ø—â_ŠU_T}QZÎl9³åL`ÛØö vX‘ŠT„ºëV¬[î w…;¬NY²:Š·o+ÞjvªÙ©&ÈBd!²M÷’ ‡“8>²Œ)S2¦@ZVZVZ¸Ìs™ç2ïßÛ­°ZaµÂàûÙßÏþ~6z}èõ¡×p´ÅÑG[[ÙÊVM÷’ ‡ì#‹Úµ+jè9è9è9€Ýv»ívXU¾æØšckŽ…‰ý'öŸØŽ8vàØ8dyÈò%¨3Õ™êLM÷– Â?' ØGö2çeÎ˰=n{Üö8èŒÒ¥3JsyªW7®n +N¬8±"79nrÜüòÿÉÿ'P;©ÔNšî5A„¿O°,ê^Ô½¨{àÜй¡sCYÈ,dšNUNW9]å4LöŸì?ÙN[ž¶õ õ õ ;v"ìL(˜P0AÓ½!ŸQÀ>’Ȇ‘ #‚m¡m¡m!(C”!Êô¼•kškškÌ3cÌŒ1pkÿ­ý·öÃŽ ;6ìØE½ŠzõÒtÊ?÷öèÛ£oBð¡àCÁ‡àQÕGUU…ØØXˆw‹w‹wƒbýbýb}kÖ,¬<7|nøÜž=7znIû’ö%íûÎöí;ƒë×3®g@ÝXÝXÝø÷ûU»«ÝÕîaaaq¯â^Ž‚„ s™Ë\¨1¤ÆCÀð¶ámÃÛ è£è£èz¾z¾z¾ [.[.[III°(iQÒ¢$xèñÐ㡨ö¨ö¨öÀÛ·!oCàÁ€‡M6}زó³ó³ó!sCæ†Ì ð ôƒÒJCôóèçÑÏ!üRø¥ðKëžëžëÏç>Ÿû|.¤.H]º@ÓgOþQÀ>’eŒ2F öæöæöæšNóÏ9ç9ç9çÁ´¶ÓÚNk ¯_¾†mS·MÝ6TÎ*g•³¦Sþ±œu9ërÖÁäÜɹ“sá|™óeΗÇ À"íEÚ‹´áuù×å_—‡K,9°¦&LM˜š÷î܇GçtnºÝt»é“'Ož=ôЪP…*Ý3ºgtOxöý³ïŸ}éËÒ—¥/ƒ )CÊ`uøêðÕáp½×õ^×{ÁÙ‘gGž ›šmj¶©¤=I{’ö~XøÃ®‚]» à²õeëËÖ= z@ôX¸"pE Üè}£÷Þš>{‚ð÷ˆöŠ=(zñÕã«ÇW§|§|§|M§úpåš•kV®Ìè=£÷ŒÞâââ [o}¼õ1¨Ú«Ú«Úk:åïYæYæYæ±¥±¥±%xœö8íqÎ8sàLÈŽÌŽÌŽ„û•îWº_ ÊÜ,s³ÌM°l1Øb0 ˜=`ö€ÙÐxMã5×€ƒÂAá éô@zÀûk¬ÿCçªÎU«P¡E…Z€­ž­ž­4ðlàÙÀJŸ+}®ô9°ð²ð²ð‚¢¤¢¤¢¤ß4H"‰ å§å§åŽ“'9NÛš¶5mkBÃå —7\ñR¼/ÁíK·/ݾ=¦ö˜Úc*´¬Ú²j˪pnɹ%ç–€öí=Ú{À(Æ(Æ(ª)ª)ª)àÛ*ßVù¶ ¸´uiëÒ~2øÉà'h.5—šKš>{‚ð÷ˆöRcScScám©·¥Þ–§'NOœžh:ÕÇã¸Ýq»ãv˜ywæÝ™wáQÑ£¢GE°qÊÆ)§@þµükù×4ò7´ÐB $@VJ+¥• [/[/[zõê „ y†/ó“ùÉü~óówïsÛÌf6:è êxu¼:¤SÒ)él3Øf° J×*]«t-èz¥ë•®W`‚õë Ö°¶óÚÎk;ƒÅ^‹½{Aò<$}+ûVöío+L¦ƒ„¹ sæBŽ,G–#^*”0¢€} Ô-©[R·€þcýÇúA?O?O?OÓ©>;?;?;?˜Ùfÿ™ýáå/|ù#¬Ù¿fÿšýÛ<·yns üžïùTÇTÇTÇ ¸(¸(¸üŽùó;¶»lwÙî‚êªo¨¾bý5öWHêÔ!©¼ùþÍ÷o¾‡¢îEÝ‹ºCT­¨ZQµ =.=.=^uxÕáU‡ßïV½\½\½¢öEí‹Ú©9©9©9±#bGÄH|šø4ñ)$5Jj”Ôbbb ºjtÕèªb—b—b¯u_ë¾Ö­0­0­0(Ü\¸¹p3ø—ñ/ã_,]-]-]¡ÖúZëk­‡½Q{£öFÁY³:gu Ì5Ì5Ìâ—Ç/_Ë2–e,ƒh÷h÷hwžHO¤'ðöÉÛ'oŸÀlïÙÞ³½á⨋£.jpÅAø'dÒh:HIµkö®Ù»fCâÜʼnsa“˜¤éPÿ¢”Ù)³SfÃ’¶KÚ.i æ6æ6æ60Öj¬ÕX+064646ü÷ò¨æªæªæB7©›ÔM‚væíÌÛ™Cƒý ö7Ø¥¢KE—Šs…¹Â\áU«„W¼¶ymóÚBùÄò‰åAyUyUy¢_E¿Š~i÷Óî§ÝÇŽ'O€M#›F6øï´úbÿbÿbxqþÅùç!µkj×Ô®`ß¾…} п¥KÿDûDûDû€Öh­ÑZ£ÁÚÀÚÀÚ.%\J¸Ú«´Wi¯‚²ºeuËê«‘¯F¾ — .\†J¶•l+ÙBáãÂÇ…!J¥ˆR€ÜSî)÷«V¬€RW©«Ô…H‹H‹H 0©hRѤ"¸¨]Ô.jÌ%sÉ"ëDÖ‰¬–»-w[î‹»w-îjú[%(`ÿÔT¦2W_\}qupzáôÂéôžÖ{Zïiš÷ï{w/Ðç’Ï%ŸK _^¿¼~y˜Ð{Bï ½Á$Æ$Æ$æÓçÈZ—µ.kôLí™Ú3†­¶nØ:è–Ô-©[Ò‡·/ÂçC\Bü‡ŠæÍ+šoº¾éú¦+غٺٺi:•æXØ[Ø[ØÃ´-Ó¶LÛ…5 kÖ€e²e²e2HOOÿô9R†¥ KµªÕªV«¨.ª.ª.‚J©Rª”ܼ Ÿ1û‡²ÏfŸÍ> t&èLгÌþ1Ü:¹urë¤étš—y"óDæ Xa¸Âp…!äääÀ?þVã¬ÆYÓtJAJ21û‡RV¦¬LYùþ¦¸³³Ígü€ï¿Í¤£IG“Žð£ÿþ?úƒ¡‘¡‘¡,™²dÊ’)8+qVâ,M§¡$ìJ¶J¶J¶}S}S}S0H0H0HÐtªÏázÃõ†ëaÂØ c'Œ›<›<›r|äxPä)òy°Ôn©ÝR;HX•°*a•¦{C>¢€ýMÅÅÅPؤ°Ia0ò4ò4òÔtª’OÑJÑJÑ z¬è±¢Ç èªìªìªßæ¾Í}›CPHPH߯önµz£££pì:Ùu28 sæ0 ­ ­ ­ ¡}Cû†öàÝÖ»­w[°k?Ö~,`…V ¯¯–-'ZNùeùeùeHÏKÏKσ«1Wc®Æ@å•T•ªUªV©D‡D‡D‡ÀËZ/k½¬¥é³%ŸQÀþ¦÷÷wPÙ©ìTvbïM>Z>Z>ºhwÑî¢ ýœú9õs‚Uú«ôWéç7žÞx \àþÍ`È‘á„$@O>ùÀas¸ÈE.¾ÿ˜¬XV,+Ù7²odßüíV¦2•¡xLñ˜â1©—©—©w¶ÝÙvg\7¼nxÝš­m¶¶ÙZ(µ«Ô®R»4w~ás¢¥é%MA©‚R¥ ¸mqÛâ¶`tÎèœÑ9`4£­ét_YCYCYCh«n«n«GGGØpcà 7 ÿjþÕü«Ð|Kó-Í·€ì ì ìà'̳H¶H¶ŠlŠlŠl H¯H¯H¤Òip“›ÜJSšÒ@E*RäMäMäM Ð Ð Ðà7 ªP¡©µÔZj z]õºêu{¹½Ü^õºÖëZ¯+xyxyxyü£È‚ðÅìoJS¥©ÒT ³Jg•Î*0ú>ú>šNõõhèÑУ¡(g(g(gÀêú«ë¯®¹urëäÖ«z¬ê± ÍÍÍ>Þ~ƒŒƒŒƒ`yøòðåáã’ã’ã:gtÎèœVsZÍi5ôËè—Ñ/äCxšxšxšÀŠû+Òjiµ´š×h^£y ÎJg¥³`¬e¬e¬,;Xv°„úùõóëçCÑ¥¢KE—@/X/X/t[é¶Òm¥é³ Ÿ±âß´¿ùþæû›CÔѨ£QGa†Ñ £FšNõõ ݺ3t'¬hµ¢ÕŠVP¯¸^q½b0ÀüóAg“Î&MšN)§ &qüMYR–”%ñBã…Æ 5F¨<°òÀÊaºùtóéæ<7xnð\Øxgãw ÿçüŸóÖtJA>QÀþ¦ìÄìÄìD0n8Üp¸¦Óï8ë:ë:ë¬K³.ͺQƒ¢E ‚•æ+ÍWšCŽwŽwŽ·¦S ‚ð1‰ö7euÏêžÕŒ¾5úÖè[M§þ—Ý »v/`†Ï Ÿ>¶4miÚRX:éü¥ó!ã—Œ_2~ÑtJA>QÀþ¦œ9 r€ñã;Æw4Fø#Ö Ö Ö 0=~züôxºH]¤.°¸ìⲋË›ùoæ¿™¯é”‚ |QÀþ¢‚9s æ@îœÜ9¹sÀô•é+ÓWšN%üÓ Ó Ó ˜¼vòÚÉkÁÄËÄËÄ ækÏמ¯ ¯[¼nñº…¦S ‚ðOˆöåææBþùüóùçÁ¼²yeóÊšN%üU†- [¶„‰nÝ&ºK°K°K0Ìo8¿áü†ðlí³µÏÖj:¥ ‡(`Q¡ºP]¨†b—b—bÐë ×A¯ƒ¦S —^”^”^Œ|3òÍÈ7ÐÀ®];XÒyIç%á^å{•B‰ Ø_¤š­š­š òúòúòú Ø¥Ø¥kÒ•XZZZÐïT¿SýNA×>]ûtíË}—û.÷…kf×Ì®™ç9ÏyM§áÿ" Ø_¤Z­Z­Z ²lY¶,ä×ä×ä×4JøPò£ò£ò£Ð©~§úêÃÐÈ¡‘C#aSò¦äMÉp2ádÂɼ%oéÿ˜†/EKÑR4-(ZP´àÿcï>㢸úÿÿ¿v—¥,½#UQ,ØÐ¨ÄÞ»±ÆÞK¬±÷Ø±×Ø5*–Ø+ö.bˆˆôÞX¶ÌÿÆ/^ø¿’\ßÍ¢™ç.³gÞgÎÊÇ™=sFß½‰þ]Ä¥¤þ u/u/u/yɼd^ K%ÈôJô±H–H–H–@C¡¡ÐP O O OX=kõ¬Õ³ ç]λœwÐeX—a]†,W–+Ë…ÃA‡ƒAzô:éu`È»!<ðÀCß½‰¾lbûƒÔNj'µH…D²Å²Å²Å@#ñ×Üé™ ¨U=ªzL5j:Õ–ÍZ6kÙ,ÈÍÌÍÌÍ« « « ˜Ð|Bó ÍÁæ;›ïl¾ƒ5[ÔlQܓܓܓôÝ‘èË&^BüƒÔ~j?µÈÌdf23©d*™Jß©DŸšÒGé£,º1:¨^P½ z0lȰ!Æ@ôÁèƒÑ!Ô6Ô6ÔŽ8 ïÔ"Ñ¿ƒXÀþ ÝÝÝ0(cPÆ  HÕRµT­ïT¢OM·E·E·Bk†Ö ­ Ï»=ïö¼¤ÏNŸ>»h;mememeض'lOÄçÆçÆçê;½Hôe ؤm¡m¡mšPM¨&˜ÉLfê;•èS»?ãþŒû3`lðØà±Á™™™ýûÛ?Nœþ8N™2;e¦ïô"Ñ—M,`ÔqŽs˜Ìd&2dÈôJô©y¾ñ|ãùfdÎÈœ‘ ß4~Óø ˜M6›l6ù×Û«¶«¶«¶Ãî ÝA»ƒ ylòØä±úî…Hôe'qüQräÈõBôO³7³7³7ƒ `бtÇÒKÃ9«sVç¬`gß}wö…³³3È^—½.{Ü»xï⽋p&òLä™HèK_úùÊ|e¾òÛç·ÏoÊÕÊÕÊÕæšæšæ I“.&]„ô2éeÒË€²¹²¹²9(¯)¯)¯AþìüÙù³AõXõXõ´åµåµåAÓYÓYÓt+t+t+@6N6N6dQ²(YH $0i4Òh$˜ú˜ú˜ú€¢¾¢¾¢>˜M1›b6ìØ °Nwî:Ý«®V]­º‚â±â±â1(âqŠ80\`¸Àp0†1ŒÑ÷(‰þ­Ä&ý V‚•`%@7ºÑ h¡m¡m¡…óþçýÏûÃ:å:å:%„x‡x‡xÃêàÕÁ«ƒ!ªDT‰¨¹>!OÈò ªyTó¨æpþüùóçÏÃZj=¨Š×Š×Š×àçç_uÿªûWÝÁ5Ë5Ë5 L‚L‚L‚;ì°ÓwoŠ!p€œ93rf@¤E¤E¤ÜšvkÚ­iðxÊã)§€AmƒÚµák߯}¿ö…FM5iÔv;ìvظ²‰è7‰g`ü¦ü¦ü&‚`º]€.¸ÈE>â5~YsYsYsèÙ¿gÿžýA1M1M1íÿ~ßË“/O¾< ªzªzªzÐèH£#Ž@aïÂÞ…½a䎑;FîÇTÇTÇT(T"¨DñB¼K –,…Ø ±b7À%w–ÜYßLüfâ7Aš-Í–fÿß9Š;a‹°EØoZ¿iý¦5›{lî±¹ð|Êó)ϧ@¹§åž–{ ÃŒ† 3‰ÄG&Ö&Ö&ÖÀYÎrVß½øŒ$“L2˜cŽ9P™ÊT*·®ÜºrkÈú1ëǬáÉO~|ò#œ›rnʹ)pÁë‚×/¨mXÛ°¶!´³lgÙÎ’’’øtW@DŸ±€ýA5 jÔÝcÝcÝcÐÎÕÎÕÎ-úù£SN=:G‚Ž /S/S/SÈIÈIÈI???({µìÕ²W!Ð2Ð2ÐÁA!X‚¡²Me›Ê6ð äƒ’J‚ñCã‡Æ¡[›nmºµNr’“EûM[›¶6m-<øéÁO~‚‹^,z±.Ý»tïÒ=pmîÚܵ9YYY@»ýíö·ÛÞ7½ozß®r•«P0¥`JÁØÖs[Ïm=áÆ¬³nÌ˲–e-ËBÝNu;Õí7ûÞì{³/¼<ðòÀË Ï’gɳ ÕƒVZ=€„€„€„8owÞî¼” +V. ${%{%{¡ÚÃj«=„ã¹ÇsçB;Ãv†í ÁÃÐÃÐÃðÓ_VtVtV4ô?èЂ˗ . ÕFW]m4Ì|4óÑÌGàÙÛ³·goܕܕÜÕ÷§î f=ö`9×r®å\¨G=êu²ëd×Ɇç¾Ï}ŸûÂѦG›m SB§„N …û:ìë°šo~¼ùq0:jtÔ訾;#Òñ>°?HþXþXþsÁ\0Ý"Ý"Ý¢¢Ÿ¿Ÿ=v¥Í•6WÚ@ÙgeŸ•}FUUa¬þfõ7«¿œ9'rN@ئ°Ma›àžîžîžÜòÝòÝòÁ¼¾y}óúááá W¯„_ a’0I˜ôë\¶'lOØžÏÛž·=oƒ»›»›»øíòÛå· \Ž»w9ÁîÁîÁîõ4êiÔS,—,—,v°ƒ Ø­Ø­Ø V›­6[m'''¨ñ¸Æã!t`èÀÐèèè65ÚÔh(G(G(GÀæK›/m¾k,ÖX¬cã?64å4å4åÀæ¢ÍE›‹ Þ¬Þ¬Þ 9—s.ç\ÍrÍrÍòO7n¡¹¡¹¡¹0£úŒê3ªC„i„i„)L}8õáÔ‡0æî˜»cîB©¥f”š‰‡D¼T¥7Pyl展Ç Ïž3`œgœgœ\àôýéýƒ ƒ ƒ øš¯ù¨0 Â€  pkàÖÀ­0gÌœ1sÆÀ˜cvŽÙ åû”ïS¾¾S‹þ)âØ$¿*¿*¿ Âa‰°tctctÞÀ)EŠˆ!†þsíÿýôds˜Ã ¤ éB:`‚ & <ž Ï~c‡J”(ÿD@ 4 Ün ·Šþþç;úË ÛíiOûš¨¨½ zô†˜1c6‚Ûj·Õn«á»®ßuý®+”3(gPˆ%–X’…d!ùƒö{Ò“ž •„JBwÜqÿxãtÅæŠÍŒŒŒ†!M†4ÒºÇuë÷Aáý)ÊÎÊÎÊÎÚ;µwjoÐÝÒÝÒÝúçsXo³Þf½ FžyräIhÜ$¸I0,k±¬Å²ðòöËÛ/oëûh‰þ)bûƒä-å-å-Aç¬sÖ9ƒF«Ñj´lðË™…à(8 Ž ®§®§®Q5¢jDÕã†Æ B‰¸q%â@óVóVó4D#ùõþ´UµUµUAÛOÛOÛt‘ºH]äïçÓ–Ö–Ö–mEmEmEÐÕÑÕÑÕ)jG·Y·Y·444@{J{J{ t'u'u'A“¬IÖ$ƒô‰ô‰ô dûfûfûBAÿ‚þý¡¤¼¤¼¤¬³¬³¬³ F·ÝjtƒG:ép6*lTB]¡®PtCuCuCA;A;A;¡(gú˜ô1éc`¿û~÷ýîð&‡¼ªÿªþ«ú°÷Û½ßîý†ÝvkØ-ð·õ·õ·å?—Jÿ/ù!ù!ù!pa÷…ÝvCÈèÑ!£e,cÙßϳ?fÌ~¸2ôÊÐ+C!¿j~ÕüªÚ"´Eh 8|8øp0d-ÏZžµü´cuÅꊨmÔ6j›¿Ÿï¿¥®O]Ÿº6ÿ¼ùçÍ?Ãææ››onQý¢úEõƒ‹ò‹ò‹rÈ–dK²%U5ªjTU8dwÈîÄîÝ»ÿãç2¨cPÇ t^ÛymçµÐú‡Ö?´þ6FlŒØiÇÒŽ¥ûøû/bûƒLº™t3é†c ÇŽ…œ–9-sZý\r@r@rr®ä\ɹÇRŽ¥K3FgŒÎÁØ!±CbA‘¨HT$‚ì¶ì¶ì6ä-É[’·²ÇgÏéýÒû¥÷ƒ¬Y;³v‚|‰|‰| D׊®]ë×¹Þ/]”‘‘Ò5Ò5Ò5ð2øeðË`333ëÖ-¬[@ìØ!±Cà¡ËC—‡.`ûØö±Ö6ºê€IDATícˆÛ·'nT¨Y¡f…š`Òפ¯I_Ø;xïགྷÁïk¿¯ý¾†f{šíi¶¶>ßú|ës¼x9ð2ÂsßâââàöÃÛo?íííÐj 5…°Êv•í*[Hì‘Ø#±¨Ö©Ö©ÖAêýÔû©÷Ýέ´[i·Ò 0²0²0ò¯çú=!>!>!>ííí }êö©Û§.hçkçkçÃõC×]?¹‡sçãŠÆ+ÂË-–[,áÙºgëž­ûø¹Þ“øH|$>Ð~Yûeí—guÏêžÕáØ¡c‡ŽBœ~ÿ…¿ûƒŒ¯_7¾ƾƾƾ¾3}gú΢Ÿ m…¶B[°P[¨-ÔÐaP‡AA¹Yåf•›RG©£Ô„:B¡,]¸táÒ…€5ê¹}ìƒIÕ&U›T XÃÖ€t™t™ô7ÎÌ;™w2ï“3&gLΖ°„% u•ºJ]Ë\æ2üÔï§~?õrÈ!$i’4Il™¿eþ–ù@G:Ò zô2è~ü:øu(šv.ß.ß.ß}<ûxöñu¶:[ Xb‰%øøøi¤‘µÚÕjW«H*I*I*í×­¥[K·–°tÕÒUKW4Wš+ýy8þáø‡ã!ënÖݬ»Ðìq³ÇÍ-hA‹?ßž$\. ›®6]mºBD…ˆ  ùPò¡äC@Yd-¶Øªªª×8¯q^c°îiÝÓº'ä·Ëo—ß ºt-è Ö­'ZOŸé>Ó}¦ƒû÷ î@qGqGq: ÃöÛ?l?Øœµ9ks¤]¤]¤]ÀÄÓÄÓÄ“¢õ‹‚6m Ú@fffff&Èíävr;°nmÝÚº5HKKÿùq303030ƒo„o„oX¨X¨X¨€f‘Í"›E­C ú¢?ešû4÷iî‚Ô<¨yPó¢×oî¼¹óæNA¨nQÝ¢º… œÙxfã™úNû‹¢…hAXn¸Üp¹¡ ì|¸óá·¯ù Á‚7 B«Ñ­F·-{—ï]¾w¹ ̨0£ÂŒ ‚°¹psáæBA¸dxÉð’¡ ´yÒæI›'‚Ñ%¢KDA¸ríʵ+סÍö6ÛÛl„ˆ#~ŒøQ®¾½úöê[Ah³¡Í†6!2/2/2Oâ[Ä·ˆo!444‚p3èfÐÍ AèT§SNu¡ûµî׺_„{y÷òîå Âe£ËF—¡íú¶ëÛ®„ÇO?yüD†úõê/Ó §N7„]cwÝ5Vú<íó´ÏSAxØúa뇭ÿïþ§nIÝ’ºE†×^gxAh°¦Ášká\À¹€s‚êêê.í#ÛG¶„«õ®Ö»ZOþß%cAh?³ýÌö3áló Ï6„ÜŹ‹s Â’óKÎ/9/Ë.o¸¼¡ LÉœ’9%S.{ùÛËß~„K„A˜Ûrn˹-ápÈáÃ!Ÿè3(Ò;ñâŸdùÎòå;ȼ›y7óƒû„Jn/¹½ävX»ríʵ+Á§‰OŸ&Àp@ß©¿<ïç¨Äwˆïß<ªyTó¨öw0šÑŒ÷î+ÜWÀ·ã¾÷í8ès½Ïõ>×áôºÓëN¯uuuÈ?“&ÿ èÒuéºt(ûºì벯A¥ŒRFî˜î˜îx_ò¾ä} ”‰ÊDe"hÚjÚjÚòŸI3ïo,wé0Òa$¸åºåºåBÍù5çל_t?a™Ëe.—¹ ¹I¹I¹I`jejej&÷Mî›ÜÛ0Û0Û0赢׊^+@‘¢HQ¤ÀÍè›Ñ7£ÿïîÛ²d;*V*¬T>?ûüìó34íÓ´OÓ>PÖ»¬wYoþ³Ì~~z~z~:0 ,jGæ!óy@Èóç!Ï!Ô:Ô:ÔF.¹däðµôµôµ„Ýßïþ~÷÷ }ª}ª}ú7ÆÍ 'œÀÍÃÍÃÍÞÖ~[ûmíûÙâ%Ä?ÉZ°¬ÈÐeè2tE¯—¸\âr‰Ë¬÷^iJSZß©¿@íhG;Ð\×\×\ùkùkùëØþûE›3È ;ÁN°·l·l·l.”.”.„„2 eÊ€ô¼ô¼ô<Є&4¡è¶‡÷¿Ð 0Àà¼þË¥ä_ùå’¬ð@x <øàõ÷ÛÿÒŽ¤®¤®¤.EKZý×ìNùùùÐ\Ð\Ð\€¸q âÀ–[vlÙš]š]š]à™é™é™ —\>pyÑ~„SÂ)áÔùßï¿ h@Ñ¥Âÿê‡dƒdƒdÄ=‰{÷b~Œù1æGؾ?|8¼®ýºöëÚ`pÉà’Á%N'„øäßÊ¿• êêêügKÑ—E<û“¬Ï[Ÿ·>¦¦¦ŸpG]éJWx:þéø§ãál©³¥Î–‚÷÷‚?0í\Ø'ìöæ’æ’æèÖéÖéÖñû¿(?3ÒkÒkÒk`9Îrœå8H­šZ5µêGÜÁ/…å}a¼–¼–¼†¬Y-²Zoxð6´6´6üàøþr»$H@òäÉ7€~øùä“’Á’Á’Á­.ÿþõ~’~’~@}êS¿èõ÷…ì? )¤ðƒvÞW\qÉlÉlÉì¶¿ÿ_ž$nãeãeãmBÚ„´ vß¶û¶Ý·àééÿád E…èýßÿs ü>ÿ`3˜¢÷~i0“& L€³©³©³)4»ÓìN³;0:rtäèHXb±Äb‰\7¸npýï_êŒÔ©3À~•ý*ûUñs!*VÄö'9å9å9åAúôé7@3V3Vó ž¸Ú(´Qh#øyÚÏÓ~žÉÉÉP (P(þï÷gdededÁ²øeñËâaÕ•UWV]|ðÁGßGñï“ZH-¤Påx•ãUŽÃ“QOF=:s¹Îüï·¯(£(£(y5òjäÕ€'러²N\=qõÄU(³üÍò7¡Z‡jªuÅAÅAÅAxpøÁá‡áݽw÷Þ݃¼cyÇòŽAFéŒÒ¥!Ñ$Ñ$ÑrvåìÊÙñ¹ñ¹ñ¹x,ñXâ1ÈuÌuÌu„d§d§d'°²²‚g+ž­x¶^¹¼ryå‰Ù‰Ù‰Ù+Ë•åÊàí¼·óÞ΃ôZéµÒkAÆáŒÃ‡!ïyÞó¼çÙ#³Gf¢Ÿ¹¹¹‚_/¿^~½ f™šej–rGË-w´g´g´g ¥rJå”ÊEÓÒSߤ¾I}ÉÇ’%ƒœr~Èù—$.I\ §N%œ‚Üæ¹Ís›CÂÝ„» w¡rÕÊU+Wã—Æ/_Âýˆû÷# épÒá¤Ã ^«^«^ ô¢½þú¸e¯È^‘½Þ¼)xSÕ:VëX­£¾?­¢OE6ûúò¹ÐöÕöÕö…K}.õ¹ÔêZ×µ®k O…§â#>†äÜžs{ÎíwïÞ9ÀØÁc ¦¥LK™–IUIUÉÿ8ã0ñ3ñ3ñƒ'矜rÂaŠ0´žÖzZëi q•¸J\õ}4ÿ>'''8—y.ó\&¸]p»àv':Ntœø×Ûu´q´q´»4»4»4ȪšU5«*Xݵºku:ÇtŽé޾޾޾à•ì•ì• yGóŽæS#S#S#(X>°| xôðèáÑtº@] ”TrPÉAà4Âi„Ó0èlÐÙ 3”t+éVÒ \K¸–p-5 kÖ0ƒ3g ΀QG£ŽFÁø‰ñã'P²qÉÆ%ƒÍQ›£6GÁå;—ï\¾ï5Þk¼×-á¥T*¡Ìˆ2#ÊŒ7[7[7[0(cPƠ̯ûŸ<ÿxþq(´-´-´…R?”ú¡ÔàtÂé„Ó (|Qø¢ð8ìqØã°\×»®w]† C…¡JD•ˆ*îÇܹßž¾=}{B¹fåš•kIý“ú'õ•¿Ê_åæß˜cþ X ³f5Œ¢K«ÒE‡‹ í«´¯Ò¾‚ŽÞ½;zƒ•••¾?­¢Nß³H>7É’;$w„Á©ƒS§ ›ko®½¹öñÚÏŠÊŠÊŠ„ñgÇŸVZ6nÙ¸ecA¸½èö¢Û‹¡°aÿÂþ‚r6älÈYA8";";"„ãÁǃ Bª*U•ª*joCå •7T„ïäßÉ¿“ ‚®µ®µ®µ „M›6YŽŒ:2êÈ(Ar r r„Ôá©ÃS‡½?æLÌ™˜3‚p¢Á‰'‰'vœØ! ïÞ%¼Ó÷h9YòdÉ“%a¬0V+BêÓÔ§©OõJôOyÕóUÏW=aXûa퇵„'Ûžl{²Mß©DŸšx ñO2 0 0 £¦FMšBÆÕŒ«W?^ûFFFFFF`~Ìü˜ù10õ2õ2õ[k[k[kЩt* žÛ<·yn%&•˜Tb\;~íøµãØ8°q`ã_·+ÑJ´-¤ÏIŸ“>æäÌÉ™“jgµ³ÚTUU!ýEú‹ô1(cPÆ Xš¾4}i:888CRrRrR2¬H_‘¾"ò_å¿Ê¥ïQf=šõhÖÜϸŸq?+\W¸®p…ôUé«ÒWé;èSy³öÍÚ7kaÕËU/W½„&‹š,j²|ûûö÷í¯ït¢OM,`’ÂBa¡°›¯l¾²ù â6ÆmŒÛøñÚ7r2r2rÇ'ŽOŸ€}iûÒö¥¡t‡ÒJwÃ݆» wC›+m®´¹å•[Tn8Žuë8"²"²"²~£á’”¤$è2u™ºLH‘¥ÈRd6?l~Ø|ð}âûÄ÷ xÅzÅzÅBÄðˆáÃáEÔ‹¨QPõBÕ U/@Ù¦e›–m ÷,ïYÞ³„L£L£L#} ÈÈÈÀ …ƒZööö0×®ÿ\xÛÿmÿ·ýÇ<æ±¾ÓŠþ*á¼p^8÷4÷4÷4°àÞ‚{ îAí„Ú µ ]Z»´vi?¢ÏƒXÀþ$©‹ÔEêî~î~î~ù4òiäß¹oå÷ü2›Kè+ôú‚ÄAâ q€ðÜðÜð\X[{míµµápàáÀÃðÜü¹ùssØKì%ö¿nNÈr…\°±±yÊyÊyJH™>2}$ wî8ÜÎm;·íÜ6ÐÔÒÔÒÔ‚tEº"]—Z_j}©5¼ {ö2 Zg¶Îl ¦·Mo›£ÅS͂͂͂atÜè¸ÑqPa`…Â쓳OÎ> §ìOÙŸ²‡B]¡®P÷÷÷'úgäLÈ™3vXí°ÚakTkTkTÐ)­SZ§4èiÙÓ²§%Èýåþr}§ýSÄûÀþ"×ó®ç]ÏÕÉW&_™ ÚÚÚ s9È>ÂÞOS¾Îu®èD'¸1áÆ„ zFôŒèP7 n@](ÜR¸¥p <íñ´ÇÓ¿ÑNYÊR”ϔϔÏÀä‘É#“G°2heÐÊ ˜è8Ñq¢#\éu¥×•^ÐPÿAýKC—†. ¡y¹æåš—ƒ’-J¶(ùáMU©ÊÇœ¾þ‘˜8š8š8ÂÀý÷Üåg–ŸY~&잺{êî©’’’ ÝFwÝm4TÔUÔUÔAƒ6mô^T0£`FÁ ¸izÓô¦)’’’€Ù(³Qf£`Ú–i[¦mŸ“>'}Nþýý‰>Obû‹JV+Y­d5HKHKHKe}e}e}°³³ûëíæ®É]“»¢5Ñšh ¤UL«˜VÞX¾±|c †W^a8ûûûÀžˆ={" Þ2Þ2Þ²hí·oß¾}ûâÎÅ‹;ٱٱٱð¦Õ›VoZÁ¡¡‡† wûÝíw·H¼%ÞohÞµy׿]¡´giÏҞкc뎭;ÂöRÛKm/eú”éS¦xyyAõÕwVß ²u²u²O¸hë_%õ‘úH}Àÿÿ!ÿCEÏ“:îuÜ븬ºµêÖª[à±Ôc©ÇRhÛ°mö ¡Â~¨ð˜Ô6©m"®äðéÜç>÷!;3;3;î~÷û»ßÃiËÓ–§-AÙWÙWÙÚ×o_¿}}h¤n¤n¤.Z“Tôï&y?›CßA>7y²`úÒô¥éKÈMÌMÌMŸÎOç%-JZ”„¼ô¼ô¼tPe«²UÙ`hh6'lNØœÉ*É*É*PPP€tïtïto „B@¡P( 0¿n~Ýü:@ ú•?Ál Ñ.Ñ.ÑÎU?Wý\u¸QòFÉ%AqHqHqꬨ³¢Î ¨]ºvéÚ¥ÁÙÅÙÅÙd–2KÙ_XíþßN=\=\="##!¤KH—.pÖýY÷g££#4éߤ“þP?¢~Dý°b5Äjˆ¾Ó‹Š±€ýEï'CÌ2kȬ!à7Èoß h߬}³öÍôNôW¥G§G§GãèGÑ¢áZ™ke®•øÛñ·ãoƒÃp‡áẮº®ºÊï*¿«ü.p5s5s5óXóXóX 3é¬ïÞüó„GÂ#á¤oOßž¾¢GFŒ OK>-ù´$<¹üäò“ËÛ-·[n7ðR{©½ÔPKý-õ·@ÅòËW,¦UM«šÃKÓ¢âE,`Ónùnùn9ÄnˆÝ»¦ š2hÊ }§},ººº8#qFâ x4ûÑìG³á±ú±ú±^½xõâÕ PURURU‚Êû+ﯼJÕ,U³TMðŽôŽôŽç¹Îsç‚éPÓ¡¦CÁ¤¡IC“†`ÐÌ ™A3ŠÖ0,nö°‡=Pؼ°yasÈï“ß'¿äÏ=ž{Þ­y·æÝ—…ËÂeðöÛ·ß¾ý’Ü’Ü’Ü@¾X¾X¾Jî+¹¯ä>¨þ¬ú³êÏÀw¿ï~ßý`ÝØº±uc($ ÉXaF$úøØßäóÏw>ßÁ¾7úÞè 9«sVç¬ó1æcÌÇè;èï’úKý¥þà|ÅùŠópÆgÀ#ß#ß#·^Üzqkp—¸KÜ%à9Âs„çx{úíé·§!d`ÈÀPèPèP膡†¡†¡`>×|®ù\(áRÂ¥„ Ø]³»fw ¬úXõ±êVVV`ÖØ¬±YcPLQLQLÓ¦L€Ñ$£IF“À Ý Ý  ž<1x2 ™…Ì4 šMhohoho€ÚWí«ö…££#P¾Q¾Q¾¼½y{óöB®*W•«‚Œ2@FvFvF6¤¸§¸§¸Câ™Ä3‰g ¯t^é¼ÒPx¡ðBá0íaÚô¸mqÛⶪª«ª«ª¡â©Š§*žÇšŽ5k‚™`&˜ ¹+¹+¹û·‡E$Ä3°¿-ù›äo’¿©¥§–žZ¦O5žj ^ó½æ{Í×w:ÑÇ¢.P¨ àÌÍ37ÏÜ„C•U>Tšæ7ÍošçvžÛy.˜l6Ùl²xÈCB~Ïüžù=!¥]J»”v>>}|úxHY—².eDï‰Þ½§h²NŽ"G‘£€œ…9 sB¾{¾{¾;h»k»k»S´¨o(¡„¨@à OxT¦2•ùÏ"ºÿY•>tÒ ,°Æ2–± —Ê¥r)(f(f(f€yœyœy˜/6_l¾ìÙ7²oîîî`§´SÚ)Á&Â&Â&ìîÛÝ·»_ôªHôO ØßµšÕ¬†üðÿÁ*DWˆ® Ý:vëØM\Dô³—êêê ÛØÆ6 <2<2<†xñâ 5·×Ü^s;ð_ñÕߨQ€N«Óê´ ;­;­;]4ù¦ðJá•Â+ \¯\¯\ªªª é é éšMŠ&´5µ5µ5Á   dÃdÃdÃ@~N~N~ŒË—3.ŠaŠaŠa Ï“çÉó@z@z@z¤½¥½¥½AzCzCzƒ¢UåE¢bH,`É‹#G,àÁÜsÌ…ùòùòùrŒŒŒÐw:Ѷ“ì„ÐÑ¡£CGÃúë¬N—.;]†¡—‡^zœlœlœlôV$úwWâøHª9Usªæ %<‚„ó çÎë;•èR%©’TIpðÎÁ;ïÀ’’KJ.) C†4 É{&G,\"Qq"NâøHœ~túÑéG°î`ÝÁº<Ëy–ó,§èKQñ” ›;n#ĥǥǥÃxÏñžã=¡Êü*ó«Ì§è»&‘HTlˆg`‰qsãæÆÍá«…_-üj!?~ü„ªBUA¼Ÿ¥øøåFï{ïî½»÷f 1tÆP?”?”?„ùç_œª\ªr©Ê% 6µW≊%±€}duRë¤ÖI…„A ƒAÔØ¨±QŸà‰Í¢?§ ]A»‚v°·ÃÞ{;ÀšŸÖü´æ'h=¹õäÖ“a܃qÆ=»Rv¥ìJé;­H$ú#ÄI™.¤ é0/w^î¼\(ù]ÉïJ~}Nõ9Õ甾Óýû$&&†“Nn8 )¦)¦)¦0²õÈÖ#[Cù˜ò1åc€” „¾ÓŠD¢?C<ûÈ$6‰ 4Ó4Ó4ÓÀ ¿~7ü «vVí,ñRÔ?æáÆ0#aFÂŒPÔSÔSÔƒ¹ç>žûÊkÊkÊk —Hô Ø'Råa•‡U‚Ùf³Íf›áºåuËëâ⯟LÁë‚ׯáç3?Ÿùù ¬vZí´Ú ÚviÛ¥mg0Î`œØM¶›l7YßiE"ÑÇ °Oĸ³qgãÎÐìM³7ÍÞÀ¯ ^¼@­ŒVFë;Ý—#Ñ'Ñ'ÑÇ.Ž] ×\pýLršä4É Úßm·ý][É­äVúN+‰>&ñ;°O,·^n½Üz0õÖÔ[SoA»¼vyíò ©¼©¼©\ßé>Cu¨CxPõAÕUacÜÆ¸qàÕÕ««WWÔqPÇAÁÖØÖØÖXßaE"ѧ$ž}bïqÿþRVPFPFP(»(»(»è;ÝçCµVµVµö.Ü»pïBX¼*xU0´Žk×:Æõ×g\±p‰Dÿ&bû‡Ô «V/ äžrO¹'\êt©Ó¥NúNUü%&&Ââš‹k.® ×O^?yý$LNŸœ>9:Üëp¯Ã=kä¹FßiE"Ñ?I¼„ø „v4ÚÑn_¸}áv°ÿÁþûô®øxRþIù'åa}çõ×w†’‡J*y†*‡*‡*ÁæÍ;›wúN)‰ôI,`ÿ°÷åX8qáÄ…Áþýûðì;Ùw2à:×¹®ï”z8.‹Ô‹Ô‹àTÄ©ˆSpx÷á݇wCÛ¨¶Qm£ Ãè£;ŒÃ† è;­H$*ÄKˆÿ0¹±ÜXn =z÷èÝ£7Ü6¼mxÛžõyÖçY}§ûçe”Ë(—QVy®ò\å 'Çœsr Œ 86º.躠ë±p‰D¢_ ˜žxÕôªéU—o\¾qyØá³Ãg‡äõÌë™×Sßé>½p‡p‡p˜<3xf0äÌÊ™•3 æªçªçª¡Z·jݪu~äG~ÔwZ‘HT‰LÏ:ÖêX«c-ÐÍÑÍÑÍ£m޶9ÚFß©>>]]]8wáÜ…s`||ü´~Z?-Lõ™ê3Õœ«9Ws®¦ï´"‘ès 0=3ëcÖǬô¯×¿^ÿzpvïÙ½g÷³ÖÏZ?k­ït_Μ!9C`À 6 €½·öÞÚ{ [¶l ýÖõ[×o˜59jrTßiE"ÑçDœÄQÌìi¾§ùžæpKqKqKóÎ;8ï XXXFOo‹©S%¦ ¬Y³fÍš5 |-|-| £‚F öí=Úë;¥H$úœ‰g`ÅL§EuZ6‚`#À“&;L@»R»R»Rßé~Ÿ°SØ)ì„»îv¸Ûf©f©f© ¤¬¤¬¤ f¥ÍJ›•&.‘Hôñˆ¬˜1®j\Õ¸* ]=tõÐÕðìೃÏÂÉC'¯z¢z¢z"2=dzÈV÷]Ýwu_èø¤ã“ŽO`Øa†s{s{s{}]‘Hô%ùŒ.Jý»¸x¸x¸xÀðñÃǫϯ>¿ú<äíÏÛŸ·‚N: çt~س;fw ÚÑŽvc¿‚¯à+ø{ØÃT’T’TúõvY9Y9Y9°%~Kü–xß¾%| Lz>éù¤çPÙ²²eeK`5«Y­ï£)‰¾H‚¨XS•Q•Q•„i㦛6Nl m m AZ_Z_Zÿýw—‚ð}íïk_[„ !Húëû;·ÿÜþsûa›í6Ûm¶‚ qÔ8j‹~þ¦Ö›Zoj ÂØúcë­/Ór§åNË„¸ä¸ä¸d}-‘Hôo"žSk2Öd¬5;×ì\³¶æoÍßšé†é†é†¿ÞþΚ;kî¬ø×ñ¯ã_ƒ3Î8ÿ‰ýň;æ™?fþxð*àU8ÉœdN2°úÖê[«oaÓŽM;6í€Z!µBj…@Ÿð>á}ÂAQUQUQUßGM$ý›ˆ¬˜zëôÖé­• *T’í’í’í~ûб¡cCÇÂË/¼\ðÇ ˜ÚTmª6… U6TÙPnÕ¹UçVÐäiò4yð}Ÿïû|ß*lª°©Â&æ>Ì}˜;4^ÖxYãe «*«* —H$ÒqG1UíUµWÕ^A G G ô;ÕïT¿S`ñÜâ¹Åó_oŸÛ5·knW¸Úêj««­€0Âû¿÷sÁå‚ËØ2iˤ-“Š ×{á;Ãw†ïM²&Y“ 5_Ô|QóÈËËëû(‰D¢3ñ>°Ï„ò¾ò¾ò>:rèÈ¡#°´ÅÒK[À‹ò/Ê¿(‚½`/ØÃ×w¾¾óõ8Yp²àdXÖ³¬gYï×íŚĚĚ@Ïn=»õìÁÁÁ€ @@àƒO…aGÃŽ†á‡Ê?Tþ¡2Li<¥ñ”Æ ó—ùËô0ûQ$‰Ä3°Ï„©Ÿ©Ÿ©ôéÙ§gŸž°oÕ¾UûVAï½Oô>Æ!Æ!Æ!O<ðtÀ¯ÛQ¯V¯V¯†uo×½]÷näÜȹ‘óÁï W=êQäÏäÏäÏÀs¥çJÏ•cšcšc ʡʡʡú>*"‘èßL<ûÌe¿Ì~™ý… = Ëî.»»ì.´Übp‹Áðµ××^_{u'ëNÖ ¡uBë„Ö0F;F;F[t?™…ÎBg¡ƒR5KÕ,UjUªU©V%h:§éœ¦sÀ÷²ïeßËà^ʽ”{)0¬kX×°®¾{/‰þÍÄö…9—w.ï\ i5¤ÕVÛ&¶Ml0?n~Üü8˜Ž6m:T*4×4×4×€¿‡¿‡¿T7©nRÝJ4,ѰDCäKò%ùúî•H$ýš8 ñ csÁæ‚ÍÈz•õ*ëè®é®é®AYd5,kXÖ°„-·tÞÒܲܲܲ@ÖPÖPÖðƒ†òÉG,\"‘¨¿ûÂ8>u|êø|žû<÷ù`¶¢ÁvƒíÛ¡Êé*§«œ†.%\J¸€lŒlŒlŒ¾S‹D"ÑŸ'^BüBMQNQNQ›5oÖ¼Y ìØ7°‡ø¬ø¬ø,(ÿ¶üÛòoáÛ»ßÞýö.ÈîÊîÊîê;µH$ýqâ%Ä/LV^V^Vd¤e¤e¤ÁôeÓ—M_UÒª¤UIƒ°Ä°Ä°DXì´Øi±è  gDψž õ’zI½ôÝ ‘H$ú¿‰—¿01ãbÆÅŒÝ6Ý6Ý6ðøÉã'ŸŠ~îãäãäãS¯O½>õ:\­rµÊÕ*°§öžÚ{jƒN¡Sèúî…H$ýßÄö…yáôÂé…¸Îrå: ¬V[­¶úÕàËÖ-[·l]˜ünò»ÉïàòôËÓ/O‡]Ñ»¢wEƒF¥QiTúîH$ý>±€}!„jB5¡„Ú‡Ú‡ÚC¥¯*}Ué+\‘\‘\ùý÷ygzgzgÂÔ–S[Nm ׯ9^s„Ÿ}öýÙtmtmtmôÝ;‘H$ú5±€}!r´9Ú-$nLܘ¸Ê-w´ÜÑ?þ~ï²Þe½ËÂÔSgLÁ²`Y° v™ï2ßeÚ Ú Ú úî¥H$'q|!"*GTލ 2_™¯Ì*"‘èß@,`Ÿ¹P!TÀù¦óMç›`sÔæ¨ÍŸ˜}øWyºyºyºÁÌ­3·ÎÜ O–?Yþd9l¹¶åÚ–kPX¹°rae}‘Hô% Øg.Ü8Ü8ܼS¼S¼Sþùý»Ÿq?ã~¦ùOóŸæO+<­ð´lÊÝ”»)TKUKUâwd"‘èóýL)7*7*7 <`pçÁw†jÊjÊjJýåŠ}û.ö„„„CÙ¡e‡– à † 3£p£p£p}=‘Hô%ÏÀ>S‰åË'–õnõnõnp=ïzÞµ|÷äêáêáê3OÍ<5óDŒ1Ö=Y÷dÝÈŸ–?-š¾SŠD¢/XÀ>Sñëâ×ů³5fkÌրŋôªH‰U%V•XÓ¦'LO€¨fQÍ¢šÁZùZùZ9ä=È{÷@ß)?švšvšv’’’ ùòå?Òw*‘èŸ!^BüLmi¶¥Ù–fç“ç“çcVY=fõßo÷SIê™Ô3©'l ذ œÍœÍœÍ`Ô¸QãFÅ Å Å }§ÔŸ˜ý1ûcöCÄЈ¡Cáké×Ò¯¥ O—§ËÓ½½îŽîŽîœœœÀ£·Þ>z õwÖßY'˜57knÖ,X°<εœk9ׂ›;oî¼¹LG™Ž2_›|mòµ 0 |‚Û/D¢OI<ûÌèöêöêö»‹ï.¾»¥·—Þ^z»¾Sýß÷8îqÜ3^Ìx1ã$ÏLž™<VkWkWk!·fnÍÜšúN©? q q qp+íVÚ­4(Œ,Œ,Œüýí3FdŒÈ‡,Y²„n-ÜZ¸A¥äJÉ•’á~•ûUîW7³ÞÌz3 ±ŠXE,ÜWÞWÞWžu{ÖíYÂáˆpR¤H=ùËó—ç/×÷щþÙì_è;ˆèÉÏχ#­´>ÒšölÚ³iOp,ãXƱŒ¾ÓýßL]L]L]À¯_¿6pÞã¼ÇyxìôØé±T}SõMÕ7`TǨŽQ1^¢J[F[F[Ò6¤mHÛÊgÊgÊg••Z¹V®•ƒ‘‘‘‘‘d×ή]ònæÝÌ» ªëªëªë .«.«. vvvP1¤bH۰µ°µ°©­ÔVjûÁŽ£ˆ" ÞU{Wí]5سsÏÎ=;¡é€¦šÏÏÏ(Õ¨T£R dã’K6ÅcÅcÅcxqüÅñÇ!yxòðäáà×À¯_X±cÅŽ;À*Ï*Ï*œcœcœc€B )„´ì´ì´lÈÞš½5{+Ȼɻɻn¸ái1i1i1 m«m«m Ê0e˜2 d­d­d­ ïQÞ£¼G ™­™­™ †m Û¶Õ÷(Š>wâØg&> > >´´´Àý¶ûm÷ÛúNõçÙæÙæÙæÁÔ˜©1Sc »tvéìÒ°Òv¥íJ[ÈVe«²‹ñóÈò\ó\ó\arÕÉU'W…€Ô€Ô€T8^ëx­ãµ`^Çyçu„ÈÓ‘§#OCУ GA`À¤“L‚=göœÙs‚š5j÷ï9Þs„Áƒ @ôŠèÑ¿qIUí vP;À«m¯¶½Ú)µSj§Ô†;î4ºÓb‡ÇëüÖù­óƒ%VK¬–X}ÐÀ/kYâ…^ð¢ï‹¾/úÂÉi'§œwãïÆß‡ÔQ©£RGÁÙð³ágÃaí­µ·ÖÞ‚Ëv.Û¹ 64ØÐ`CHNN†)¹Sr§äÂü“óOÎ? Õ«VƒgUžUyVÖX¯±^c Ûb·Ån‹Õ÷艾bûÌD]ˆºu¬æ[Í·šæïÌß™¿Ówª¿Î6Ø6Ø6¦†N  £ FŒ†eW”]Q2gfÎÌ,†«Þ›_1¿b~Ìž™=3{ =z,„¡~Cý†úAuƒêÕáäð“ÃOÏ!žC<‡@nfnfn&´nѺEëдuÓÖM[ƒw†w†w(•‰ÊDP·U·UÿÆŠ\!WÈà7Ðo ß@pžâ<Åy ´zÛêm«·PªN©:¥ê@‰Ò%J—( ­2Ze´ú DIÉuÉuÉu(³¹Ìæ2›Á±—c/Ç^Ð*¡UB«09`rÀälwÝîºÝšVjZ©i%`;Àv€-\н{)Òf¦ÍL› æ¹æ¹æ¹`>Ç|ŽùèSªO©>¥ ÔRCJ Ž ;6ìØZÚ´´ii£ïÑ})Äö™‰~ý0ú!¸Tv©ìRd²@Y ¾Sý}Ö¬X€I‡'žtÔ¥Ô¥Ô¥`Ù¾eû–íƒôuéëÒ×é;åopÅW 4¥)]ô²ý<ûyöó vyìòØå€5ÖXƒ±‹±‹± Ø\¶¹lsìWد°_$H2@Ðàì× @¸)Ün‚.„ Þ_gŒ1ÆÀB²ð´#C†¬¨ÚÒ–¶¿9sþfˆjÕ4ª)\7½nzÝŽ… ;Ò]Ò]Ò] ë ë ëÒÒÒ`®1טkÀ¶¡mCÛ†`5Âj„Õð‰ò‰ò‰¯]^»¼vé{ÐD_ ±€}&tststs jvÔì¨Ùàååååå¥ïTŸUS«¦VMa’÷$ïIÞ ; ; ;K:,é°¤CÑÿø‹ O<ñÉÉÉ‚¢—•YÊ,e˜w4ïhÞˆ%–Ø¢íÿS`Þûå»&É`É`É`4”4”4üû}¿ýÉÉ´´´øàç&˜`’ŒŒżþ~¿ó˜Ç¼¢íÈ"‹,à1y ²TYª,¬X°:µ.ÔºPëtšÜir§Éð“ÑOF?¯ÎWç«ÍuÍuÍõú÷ßq+V*¬êÓêÓêÓú4Ñ—B,`Ÿ‰¼ yò.@zDzDz¸8¹8¹8é;Õ§c¹Ñr£åF˜>!|B8˜‡˜‡˜‡ÀBåBåB%$¾H|‘øBß)AÈ2„ ˆOOO‡Ûn·Ýn»A|Óø¦ñM¡ñƒÆ?€”);Rv@ö­ì[Ù· mpÚà´ÁÀ[Þò’F%J9Ãs†ç ‡¤×I¯“^ÿƳÉ&’×%¯K^Ù}²ûd÷øëñ×㯃*Tª …”à”à”`ÈX“±&c ¤tNéœÒҌҌҌ #1#1# b b b@zIzIz n\¿qýÆuооо€¯G=úëÑp¯Ì½2÷Ê@t@t@t({+{+{CÞ¨¼Qy£ kPÖ ¬A™™ G£Æ´´´`ׯ5^°Ýk»×ö/ð?^"ý ØgBi 4P€*V«ŠÛ.¶]l»è;Õ§gÞͼ›y7;sì̱3Á!Ð!Ð!n_¸}ávˆÿ&þ›øoô—OX.,–C–a–a–!¤¹¤¹¤¹ÀÀÕW\ _}eô•”••ÁÇCy Be¡²P´…ÚBm!ÈnÈnÈnÀHF20ÝhºÑt#èrt9ºœöWU¨*Tƒï ¾3øFŽ9väX0I2I2I‚œA9ƒrßD¿‰~¡ã‘ŽG:ŒR¥2JŸ·Ÿ·Ÿ7tTwTwTƒiÓ ¦`¦ÿLÿ™þ`´Êh•Ñ*¼/Á Æ 3hÌ (¯,¯,¯„èÄèÄèDH]žº'}NÂüˆùó#àmüÛø·ñŸ>GjTjTj$$$A¶<[ž-‡Ì”Ì”L=<@$ú7 Øg"V«ŒU‚³«³«³«¾ÓèŸq[ã¶ÆmapÅÁW„ªÙU³«fC€K€K€ D\ޏqùÓíßöŠíÛ+°|ÿòýË÷ÃŒF3Íh–––ú>:"Ñ¿ƒx ñ3ñìfý0 ª¯®¾ºújhŸÙ>³}¦¾Sê5ê5ê5°{õîÕ»WCHlHlH,L¾6ùÚäkà]Ë»–w-}§‰D“xVÌåÇæÇæÇBššš?¸îsÝçºOß©Šùhùhùh轪÷ªÞ« á½†÷Þƒ€'NÀ³¶ÏÚ>—.‰¾(b+æ2…L!SÕFÕFÕFpúÉé'§Ÿôªø2hkÐÖ -tÏîžÝ=Z´ h‹V.Z¹h%<ÜúpëíúN)‰>±€sYõ³êgÕyyyP\R\R\ÒwªâOöµìkÙ×Ð¥C—]:@×9]çt+®¬¸²â Ü©v§ÚjúNùûÔkÕkÕk!,(,(,TcUcUcõJ$*^ ô@ô¿eäfäfä‚QI£’F%ÁÄÄÄÄÄDß©>’c’c’cÐ.¨]P» 0,iXÒ°$¬‰Y³&†¨†¨†¨ ~ÇúëwNqŠSúN ·³ngÝ΂͹›s7çÂÈ#ŒlV#­FZM M M 0b<Äxhçkçk烲¾²¾²>8]pºàt,JX”°(áqáqáqà´ÁiƒÓ(Z"´D(d·Én“Ý"{GöŽì ’u’u’uPú«Ò_•þ Ì–š-5[ªï£!ý6ñ ¬˜KðMðMðÛ8Û8Û80®n\ݸº¾S}†~Y㯅Y ³f0èü óƒÎÃ&õ&õ&5\p½àzÁÇ8Æé;,¼íú¶ëÛ®ðrÒËI/'AæýÌû™÷ázçë¯w†áIÓ†'Á¥ë—®_ºÁÎÁÎÁΰøà⃋¡r‡Ê*º•º•º•°Ä}‰ûw8}8úp4xxxÃê5«×¬^×»]ïv½œzvèÙ¡°QµQµQê™ê™êâ´t—Hôñ ¬˜‹?$þ8žu<ëx8Á Nè;Õgì—µúÎk8¯á<0ò2ò2ò‚õË×/_¿TÙªlU6´n׺]ëv 9!9!ÑÃñ.9±äÄ’Á©”S)§RP×·®o]_x°ïÁ¾ûÀ$À$À$¾9ñ͉oN€E¢E¢E"<)û¤ì“² ùZóµæk0¿j~Õü*Ø·´oiß„ÞBo¡7¼®øºâëŠp{Áí·ÀOö?ÙÿdñýãûÇ÷‡)nSܦ¸Aï¼Þy½óÀGõ=v"ÑÏÀŠ)!SÈ2!klÖØ¬±`Sݦºxæõñ˜cŽ9ÔI¬“X'ƼójÌ+8`|Àø€1ÖÖÖ¶±¶±¶±ò½_%~ˆ0D¼â¯€RHƒ“' N‚Ñ,£YF³ÀhŠÑ£) Ù-Ù-Ù ’²’²’²¿nVòZòZòrMsMsM!>:>:>n;¸íà6¸¶äÚ’kKÀ»Ð»Ð»ä“ä“ä“ôá|$O$O$Oô="ÑÿŸXÀŠ©ðá ÂÀÒà¥ÁKƒa«X˜ž3=gzNßéþ}âÛÆ·o Kl—Ø.±‡gÏžÁèÖ£[n fsÌæ˜‰gÈ"Ñ?J¼„XL½Ÿ¼aÔ¨…Q 0¬bXŰоSý{999ÁŒ3VÌXÙÆÙÆÙÆ°¸â⊋+BFFFFF†¾SŠDÿ.b+¦r7çnÎÝ ŠŠŠŠŠŠ } } } ïT";;;˜²vÊÚ)kA$ ’A€ t=ézÒu}§‰þÄVLåÎÊ•; ÷÷÷@zGzGzGß©DïYU±ªbU&:NtœèvžvžvžÐ6 m@[ˆ½{+öŸœµ(ý ‰¬˜Ê™š35g*())ä†ä†ä†¾S‰þ›éRÓ¥¦KaLȘ1!PúVé[¥oÁ<ßy¾ó|áÍ„7ÞLÐwJ‘èË$°b*'/'/'L/˜^0½øâ‹¯¾S‰~q%ãJÆ•`ضaÛ†mƒškk®­¹š4 h ¡þ¡þ¡þúN)}YÄVLeÌ:™ulVÚ¬´Y©ï4¢?Êp©áRåЯy¿æýšC3—f.Í\`©ßR¿¥~pûêí«·¯‘D©ï´"ÑçM\ ±˜Ñèt“˜“˜“Ç,ŽYÓw*ÑŸ%«"«"«]{uíÕµX>´|hùÖ|·æ»5ßAŽ,G–#ƒ&IM’š$ÄQâ(‰þñ ¬˜ÑÖÖ†üù#òG€évÓí¦ÛõJôW½_›°EA‹‚0bÿˆý#öC`f`f`&}{ôíÑ· “éd:™¾ÓŠDŸñ ¬˜ÑÖÖmmm0\a¸Âp0‹YÌÒw:Ñ_öË%CüñÌ¿1ÿÆüX‘³"gEd¯Ì^™½zÌè1£Ç 0œo8ßp¾¾C‹DÅ›xVÌhM´&ZЖՖՖù;ù;ù;}§}l¾G}ú…é˧/Ÿ¾n¼9ðæ@Øà³Ágƒä)ó”yÊ¢íu{u{u{áqîãÜǹ––¦ï^ˆDú%°bF[_[_[„GÂ#áÈ[Ë[Ë[ë;•èS)S¹Lå2•á‡9?Ìùa¼Ûÿnÿ»ý°bÿŠý+öCÆÝŒ»wá䔓SNNî»Oì>ŽÆ;§ïô"‘~‰¬˜ÑÖÐÖÐÖÝAÝAÝAߕߕßÕw*ѧæºÄu‰ë˜1kƬ³ PS¨)ÔÀ6CÚ ißOý~ê÷Sá寗_n„ý÷?ÞÿÒeé²tñ»3Ñ¿”øX1£Û¯Û¯ÛÚÚÚ ó“ùÉüôJôOyÿàRŸpŸpŸpX“´&iMdI³¤YüwóvÍÛ5oׄóuÏ×=_¾å[¾Õwx‘è&ž7ÛÙÎv …B¡$Í%Í%ÍõJô© éBº'†vbLWOWOWÿºp½§¬¯¬¯¬»Zîj¹«%d(2 }÷B$úg‰¬¸Ñ A’m’m’m@/zÑKß¡DŸšn§n§n'(Q¢,ÖX¬±Xò£ò£ò£¿ÿ¾kU®U¹V®É¯É¯ÉõÝ ‘èŸ%°bF¸*\®‚Á,ƒY³@– K%è;•èS“}/û^ö=tëÛ­o·¾dddK‡/¾t8ÔRÔRÔR€|–|–üƒÛ)”-”-”-`gË-w¶åAåAåÁߨASšÒ´IÚ$m¨Tÿ¨þ²³²³²³ æ^̽˜{ >„Mo4½Ñ®:^u¼ê—ë]®w¹œ[yn幕p.í\Ú¹4¸\úréË¥áŠpE¸"À.7ºÜè%%%–––1«bVŬ‚lu¶:[ êñêñêñ ÖFk£¯…Šþñ;°â&—\rAò\ò\òXÌbë;”èŸ"­-­-­ n7Ün¸Ý€1îcÜǸC—e]–uYg–œYrf ìŠÜ¹+î÷ºßë~/¸:þêø«ãaŸÍ>›}6àó•ÏW>_AdPdPdÄÕ«W2å™òL9ä´Ìi™Ó B B Bô HÒ$i’40laØÂ°Î4œi8ä«å«å«AÒQÒQÒ ¦L1˜lf3›Aó£æGÍ 4 A“£ÉÑ䀪¡ª¡ª!¨¬TV*+`ã`€€y¢y¢y"X›Y›Y›ó2çeÎËÀã¶ÇmÛ`ßɾ“}'p(áP¡X÷³îgÝ$Q’(I”¾GM¤/b+n$Hyä‘RH¡¾C‰ôE3Q3Q3Ld&2T¹UåV•[9}äô‘Ó`gg]úué×¥Ôp¬áXÃÌFš4 Œd$#õý)üüò%ž´­´­´-xààáìáìá b:Ätˆ»w=îzÀÉè“Ñ'£áŒùó3æÐq_Ç}÷A£4†y†y†yúî”迉Óè‹™¡ÌPfR¤HõRõRõÒ_oÛ=¶{lwØì¾Ù}³;XU¶ªlU^›¿6m«=W{®öm)m)m)Xo¼Þx½1\9åü•ó‡Æެ=²öÈZ8äü‘óG~?Ÿ¢µ¢µ¢5˜º™º™ºe´e´e4X×±®c]T¦*S•),´üÑòG””Ò«Ò«Ò«ÀqŽsŒF4 é#ÓG¦ÅÅŰ.g]κ_¾|óóóÁnÝ»5p(ìPØ¡0¸ÐöBÛ m!±bÿÄþp-àZÀ5ˆ»w-î$´Mh›Ð¢–E-‹Z§gŸž}z6ä–Î-[úÓßÛ•oW¾] ó"çE΋„£ÍŽ6;Ú ºFwî ¬X/°††nl¸̬̬̬ôú‘ûwéNwºƒé-Ó[¦· á¾†ûîƒN œ8A·VÝZukÇŽ€y?ÌûaÞðÎúõ;k}‡ý7±€32™‰Ìddd@£ÎQçüz;›¥6Km–]¢«t¯Ò½J÷ ™E3‹fp¯ÿ½þ÷úƒv¹v¹v9X̶˜m1ªäWɯ’ÝvkØ­!x®ò\å¹ Ì«›W7¯ô§?ý?ŸeË–Àf¸Íp›áàšàšàš%Ž–8Zâ(ذ;`wäƒåƒåƒ~ô£ÿ¹CW+ŒÆ‚éKÓ—¦/ÁÊÚÊÚÊ\¥®RW)8,vXì°.z]ôºèfnfnfnà;Úw´ïh°Øn±Ýb;ÜX~cùå`;ÕvªíT°v°v°v€´ ÐôQÓGMA­¦µšÖj ‹Ï,>³ø 8ìtØé°ó#ØÖ°n¹qäÆ˜›:7un*”ø±Ä%~„Eg]t«««Á(Á(ÁH¼¯¯Ø1¾l|Ùø24~ÖøYãg°°âŠ +‚ãÇ-Ž[`–Å,‹Ypë»[ßÝúNßiE˜‘-’-’-ÙvÙvÙvPy©¼T¿õÝ×ûÙ‰;ØÁàG~äGÛÈmä6 )£)£)ÚÃÚÃÚÃügÖ˜ä…ä…äÅo´÷†7¼ùAà '„áÂpaøßèp9äyÈâ—s§åNËï<Þy¼ó€ yAó‚æueëÊÖ•Á¿¢EÿŠ œÎ gA’"I‘¤€ä™ä™äYÑ,G™›ÌMæ&åLÊ™”~â'>â쳋Y³.fÁ¦¹›ænš ½ {ö2„ïâ¿‹ÿ.¬šX5±jòñö÷Å3ÁДҔҔ 1ÄðŸaõ³ÕÏV?Ãð^Ã{ ï½Ü{¹÷r‡ 7 Ü0.m¹´åÒ`=ëY¯ïƒöï%°bF" ‘…€"V«ˆ…ܺ¹usëþƆЈF4ÚÒ–¶86qlâX°éjÓÕ¦+˜–6-mZÈ@òŸûx~%“L2k\ãÚúËý>Üâ·>ìÀ/7=â€(¢ˆ¢hõ}îsH'tF £…ÑPx¹ðráå¢fܸ=p{%”á¼ ¤=I{’öDtKtKtK¡ jAÕ‚ª‚‘‘!ÉË’—%/u'u'u§_ïWÕYÕYÕY''NNœ,I›’6%m„‚Š * BÖ¢¬EY‹!A’ IBÆ®Œ]»!«AVƒ¬‚P;¡vBmAȺŸu?ë¾ L(˜P0Aâââ!}Iú’ô%‚ ¬Ök!;););IâGĈ!)¦)¦)¦‚P`V`V`&™Õ3«gV„„ú õê ‚²£²£²ãy©© BúÞô½é{A»E»E»å¯Ëî»kì®!Ë}–û,÷m²6Y›ü×Û»ÖçZŸk}¡U­VµZÕ„”À”À”@A(|Sø¦ð èêê ‚N®“ëä‚ ~§~§~'º]‚.A´´´A¡ŽPG‚à,8 ΂ š§š§š'ÿoÅAPWW„ÂI…“ ' Bû€öíá¬ê¬ê¬Jžõ~ÖûYoAX¼.x]° Ì)˜S0GT.*•‹ $ÏNž<[ A³P³P³P4F#‘ ‚ÚGí£öa«°UØúÇÕ°+aW¡­¢­¢­BR"R"R"AÓMÓMÓM’ã’ã’ã!ÿZþµükEïÕbT‹Q-a…z…z…úƒG #…‘‚Pا°OaA(|]øºðµ Ï„g³¿>^ïiŽiŽiŽ Â’‰K&.™({t{t{t¿]ÑŸ#°bê`…ƒV„& L˜‚PB(!”(úùáN‡;î$uOÖ=Y÷¤ DŽˆ9Bß©¿\YÙYÙYÙ‚0jѨE£ ÂÃõ×?\ÿ÷Û 6 6 6„¯¤_I¿’ ÂÖ[l  ¿[øÝÂï!ðzàõÀë‚Z;´vhmARyHå!•á®ù]󻿂ð2åeÊËAÜgpŸÁ}ánù»åï–„ðváíÂÛ ÂSCN 9%w}ïúÞõ„ÿwæ- ;v0„£YG³Žf ÂTË©–S-¡Á•W\„3ýÎô;ÓOžZ?µ~j-Cg 1t† ÜH¹‘r#E~œóãœçÂDˉ–-aoúÞô½é‚ðýØïÇ~?Vn.¹¹äæ’ÿ»ÿÊjÊjÊj‚°¤ó’ÎK: B…›nV¸);.︼㲠¼ZõjÕ«U‚0¾Ïø>ãûÂÁOm|2ëgÖϬÿÏ>ÿ­Ä3°bʶ»mwÛî ¡¡¹crÇäŽÑwª/³ ³ ³ (¼Ux«ð¨Ž©Ž©Ž}ÄØ`ƒ Ðntm”6Jê ê ê `ºÈt‘é"Šfuºà‚  E‹öƒ÷»âŠë¯;âˆ#E«æþòÀTpÀðÄOþ3KT2E2E20ÆcŠf»þw;¿ÜÆ!©*©*©úA?Þ/^øË¬WI/I/I/0Ûn¶Ýl;˜»˜»˜»ý]ÒYÒYÒH!… :Õ©˜cŽù‡€f ©$©$©ôÁ릘bZô§d“d“d÷7îoÜœ:5tj5š×h^£9¬p[á¶Â lll?ÂlT­Z«ÖªAUKUKU L÷›î7Ýÿ?¢ÿI<+¦ìÙ²;’Ÿ%?K~†ä‚ä‚ä‚¢ÅL?¶œøœøœx8×â\‹s-@»_»_»º„t éÒÁÒÁÒÁ¿ÿ~ÕJÕJÕJÈê‘Õ#«˜F™F™FéW¦_™~¥ï£ù÷9”v(íPdwewew!~^ü¼øy`‰%–£]i_i_i_Ð Ô Ô „”ý)ûSöC˜O˜O˜¨ìTv*;ðïâßÅ¿ \9tåЕCs:ætÌiHÒ…t - - -¡ KA—‚. ì¯ì¯ì_4û4Ç%Ç%Çræ.Ì]ª^ª^ª^³2geÎJ0ìiØÓ°'$ýœôsÒÏ[/¶^l=0µ6µ6µU–*K•Yª,U– ””” ¿C~‡ü ¢¢ù…ù…ù…——òòòÐö~ÛûmïÿþqP( ”ŸŸŸ9Ïržå<EYEYEYÈ?’$ÿäææBáС…C¡ DA‰‚s&çLÎpJvJvJ×'®O\Ÿ@A`A`A ”Ÿ^~zùé`<Òx¤ñH???øÃÃô»Þ®z»êí*è$:‰Ü]Ü]Ü]þá翘lö/ôDôÿ'ÍfH3àú¡ë‡®·Ü~pûšŸÉ×&_›| ïÖ½[÷nÄ¿ˆÿªÕ«V¯Z½¿Þ®ñVã­Æ[Aâ&q“¸AÜœ¸9qs ~Cü†ø Ðái‡§ž‚ï#ßG¾ÀÖÓÖÓÖÞv}ÛõmW(Œ+Œ+ŒÃ\Ã\Ã\p¯ì^Ù½2¨»«»«»CöÔì©ÙSÁ6Æ6Æ6hG;Úò¶ò¶ò68Lq˜â0ª©r¤ÊÈx“ñ&ã d·Ën—Ýd9²Y(=”J0ó1ó1óm-m-m-°ö·ö·ö‡’%3Jf@|J|J| ˜‡˜‡˜‡@yûòöåíÁ¤¯I_“¾¿î¿Zª–ª¥ð|ÿóýÏ÷ƒt“t“t8»8»8»€Ö^k¯µ‡÷÷w°jgÕΪ(º*º*ºBfnfnf.XÞ²¼ey ªyUóªæ>+}Vú¬„Gûí{´¢££Aç¯ó×ùƒÓ-§[N·@ÚZÚZÚú¯ßá¨ÃQ‡£ÀaµÃj‡ÕPwtÝÑu?Á¿OÑo“¼ŸÍ¡ï ¢ÿòË%“cŒY0¼ky×ò®]ÚviÛ¥íÇßݤZ“jMª.U\ª¸T1Çl³‘¢:þóà¦ÿm´ÏhŸÑ>àÙų‹g;wìܱsõ}0?žØÞ±½c{Ãâ ‹+,®ƒÜ¹r‡Ê=*÷¨ÜCßéDÿ”ÇÝwÜ~jÿSûŸÚä*“ªLªnåÜʹ•Ówºñbq•K.¹P¢G‰%z@\ݸºquÿ~³ÿííÏo~û3ßø|ãs˜²zÊê)«ÁãŽÇ;úË'ú´";GvŽì ¶lزa t|ÛñmÇ·báÒqG1Wªq©Æ¥CìæØÍ±›¡°Ra¥ÂJ¿Ý÷\¾uùÖå[p±u±u±…rÊu*× *\©p¥ÂP/T/T/«êVÕ­ªCû™íg¶Ÿ ·NÞ:yë$œ|zðéßønL–"K‘¥À‹ƒ/¾8›í6Ûm¶ƒºu3êf-¥+Ðè àÑ­G·Ý‚Àümj´©Ñ&PNVNVN†Í6?Úü„,!KÈúóýüØš¯n¾ºùj¨=«ö¬Ú³`AÇt„°a=ÂÄ3±/ÎûÇ-t_è¾Ð¾nóu›¯Û@ÓvMÛ5m÷÷Ûý5b+æœ!§TN©œRÛ6·mîG¼„h(5”JÁÄÝÄÝÄ,žZ<µx ŠMŠMŠM`vÄìˆÙ(P. \¤õMë›Ö Ó Ó Ó M“¦IÓüº]¡‰ÐDh¦;Lw˜îµÚFm{ºïé¾§;(… À*Ö*Ö*žî}º÷é^Èî—Ý/»Î+œW8¤>R©<¿òüÊó+ m«m«ý—Pÿ,YuYuYuèy±çÅž¡ÉŒ&3šÌ€Åï¿[üN<9ðä@P»¨]Ôâ—úŸÂ½…{ ÷BP½ zAõ`Ñ•EW]æáÍÛ‡C÷mÝ·ußÒXi¬4Vßiÿ½ÄVÌÙϲŸe? ´Ý´Ý´Ý m~Úü´ùŸ`G¿,Î+Üî ÷Š^>fpÌà˜l^»yíæµÊÊÊÊÊÊ •„JBÝœn„n„nx¹z¹z¹Âò]Ëw-ßæ/Í_š¿„q­Æµ× n5¾ÕøVcà;¾ã;(è]л 7ÄlŒÙ³ÜV»­v[ úë:¬+ȼeÞ2o}JÙIÙIÙIè:´ëЮCaظaㆃ1'bNÄÀ¼Šó*Ϋ¯:¿êüª3ü¿% ôZôß„‰ÂDa"„÷ ïÞæ˜?bþ:t<è8ŒPPPA§ñÆwe Ê”Õwj‘XÀŠ9kkk°´´,úEø±iûhûhû€æ æ æ`Ñë·›Ýnv»Xö·ìoÙZh= õpIrIrIu7u7õ‹¿jwjwjw‚®¬®¬®,D]Žºu   Â`üüñóÇχ²²2x{ííµ·× ÔR7JÝë(ë(ë(¨Ñ­F·Ý Ãá‡;†&]›tmÒ$[%[%[õ=*¿a-kY µ:ÕêT«‚sEçŠÎaA·Ýtƒ5ÖTXS"êDÔ‰¨B¡ÐGßáÿ}„ýÂ~a?¼Ž|ù:V¹¯r_åóïÏ¿?ÿ>8ïtÞé¼nZ¸iá&øjèWC¿ ’†’†’†úN/zOœÄQÌIªIªIªA)I)I) ¼²}eûÊÚІ6¡ý¸cqÇ⎤¼¤¼¤/}HëHëHë@‰%”8>Ó|¦ùLŸ®>]}º‚‡ÒCé¡óëæ×ͯå(‡xŸÖGüì3aØÏ°Ÿa?¨V!¬B<ðhÀ£Ðìi³§Íž¾øò1VG º9º9º9ððÛ‡ß>üŽ\j<Ä]Š»w B… =×^;xí Ž-[8 A'“Ɖ‰‰¿0~aüL²L²L²Àd²Éd“É`˜c˜c˜ÒÒÒ _(_(_$’H"¨G©G©GnŠnŠn +yý½ï:½ñÆ[×iáà îûȘڛڛڃk®k®k.<Ùõdד]ºN%üQO§Æ.”¾PúBi˜µqÖÆYÁ=É=É= |oúÞô½ ®—]/»^F.Aø¢€}lÊP†2PóLÍ35ÏÀ«'VO¬ ¿m~Ûü¿ãÆ0áõÓ¶—. \ ;µ;µ;µ0hí µƒÖ mƒ¶ Ú¦M'šNÔuZAø°‰ö‘ªx³âÍŠ7!«DV‰¬19brÄd]§~ܹ͋/ra¦v¦v¦âªÆU« ¾õ|ëùÖƒ{ìi°ä•ä•ä•tV>¢€}¤   ¡B§ *t‚+ŽW¯8ê:•ð“Âö…í ÛÃiÙiÙiøëûëûëCU¿ª~Uý`æÐ™Cg…’;Kî,¹S×iáã$ ØG®‘º‘º‘Û>¶}l iYiYiYºNõùJÏMÏMÏ…ƒV Z1ö±}Àðkï ¿ßœùæÌ7gÀh§ÑN#Q¸á/ì#WÁº‚uk0v4v4v„ kAׂ®é:Õgd˜a¥ÃJ‡•†Yþ³ügùCÚ›´7ioÀo‚ß¿ àÕÔ«©WSí’í’‰‹náo! ØGÎ(Î(Î(švoÚ½iw8Ûüló³Í¡àxÁñ‚ãºN÷éÒ|¡ùBóœìu²×É^àWÒ¯¤_I¨6¦Ú˜jc`švšvšŠ/,¾°øB]§„O“(`ŸˆŸžtœ™™ –=Zöh™®S}z2:dtÈè+»¯ì¾²;|pðÁÁ0üÈð#Ã@MM Ž1c8F×iáÓ& Ø'ÂâˆÅ‹#ÐpNÃ9 çÀ‰œ9'r@=\=\=\×é>~aeÂÊ„•µfÔšQ ’Ú&µMj ~UüªøUº–u-ëZ‚ÜAî wÐuZAø<ˆö‰i®ß\¿¹>$tIè’Ðî¼?òþH]§úøN)œR8N7:Ýèt#˜“;'wN.ÔȪ‘U# ¦/Ÿ¾|úrpötötöÔuZAø<‰¥¤>Qzèy 'Ü[|oñ½Åð½Á÷߀¡µ¡µ¡µ®Ó}¸2r2r2r`Ó°MÃ6 ƒgûŸí¶™ 2dubëÄÖ‰™¾L_&VG`Ÿ¨fvÍìšÙAvbvbv"\×\×\×è:Õ‡ë•ù+óWæà[×·®o]H4 iÌž;{îì¹à•è•è•( — |HÄØ'î© §.œ‚6lØ€ÿ*þUÀÚÈÚÈÚH×étG»A»A»®ø]ñ»â[B·„n … "D@Ïo{~Ûó[0º`tÁè‚®Ó ‚ðKÄØ'®¡¼¡¼¡ìºÙu³ë‡»îv¸›®SéNNxNxN8l˜¼aò†É°eÄ–[FÀ€J (ýô?Òÿˆ(\‚ð1'C>qŠ–Š–Š–Ð£sÎ=:ÃüÕóWÏ_ u4u4u4PQ¯¢^E=]§üçEGEGEGAà÷ß~êÒêÒêÒàìì ®É®É®ÉºN)Â!N!~f¶ylóØæOz<éñ¤|¿áû ßo“h“h“h]§ûûH¥¥ÒRi¸½øöâÛ‹aýÛõo׿…êÛªo«¾ úë{¬ï10s1s1sÑuZAþ q ñ3Ó©q§Æƒ¦…¦…¦q?â~Ä]שþ>ªU„*v¦ìLÙ™«W;¯v†.Ý»tïÒ†W^exQ¸áS ŽÀ>SÁÁÁ°Ðw¡ïB_[ll±±Å êĪ«~„Ï¡Šß¿1~#¬ë´®ÓºN´,iYÒ2qmĵ× |ÓòMË7¦1iºN+ÂßA}¦*YT²¨dí\Ú¹´sµ¯Ö¾Zû ’&L¨ët¿_ðžà=Á{`fÇ™gvƒ7 nÀ÷¦ß›~o å/—¿\þ2¢p Â'H°Ï\{Ûö¶ímÁÙÈÙÈÙÖ-]·tÝRP]Q]Q])Ú.竜¯r¾‚Èï"¿‹ü¤×Òkéõ¿ŸWÛNÛNÛÎ69Ûäl˜ï3ßg¾4éÚ¤k“®0¶á؆c‚õë Öt=»‚ ü“Ä)D€DãDãDcðÅ_À;Æ;Æ;ên«»­î6˜—8/q^"¤E¤E¤EÀÏž;¨ ®®®pì豣ǎBÅ-·TÜòÇû‘NH'¤ððäÓOBéÄÒ‰¥Áú õAëƒEÛÅIqRœ«üVù­òƒÜ!¹Cr‡Àhåhåh%”¶,mYÚR׳&‚.ˆûÀ²B³B³BášÞ5½kzððÕÃW_A‚C‚CÂ{««G5ŽjÕî™Ý3»g©HÅ?Ñ_ÈС!CaXæ°Ìa™Ð®V»ZíjÁäèÉÑ“£!dfÈÌ™°ªóªÎ«:ƒGY²eaRú¤ôIé`îaîaî¡ëYA—DûÌiêkêkêÃJŸ•>+}`nÔܨ¹Q»;wwîîŸo_hYhYh ×ê]«w­tŸÑ}F÷`xÛð¶áíÿÝ_ÎÙœ³9gañÛÅo¿… E"HQ£:Gu†Â… 7Bd§ÈN‘ mÿ¶ýÛö‡ö!íCÚ‡€­­­®gM„¸ˆã3§w]ïºÞuhw¦Ý™vg kÓ®M»6óåæËÍ—ÿúû®÷¼ÞózOˆ Œ Œ üÍd&3aŸjŸjŸ ö¯Þ¿zÿê¢' Ož0V´ZÑjE+h–Ð,¡YtIì’Ø%Q.A~N0€Ê÷*ß«|Vy­òZåË/?¾ü8”Ï*ŸU> H „¢íãGĈwæß™gþÿn?84848–¸.q]â Ùßf›ýíÏ·ËhÑ £œ¨z¢ê‰ª‘‘¡ëÙáC$ ˜ð_LÜLÜLÜà›/¿ùò›/aßè}£÷†¾ }ú&€IžIžIähs´9Z¸<óòÌË3A¦ Ó„ý¼½¬‰Y³&BÀ©€S§ xuðêàÕ¿Þ¿T Hp.æ\̹8z:ôt¨®gE„‘øLøE²á²á²áP‰JTV[ulÕ1¨Ÿ]?»~6,*¹¨ä¢’p3ófæÍLxzüéñ§Ç¡Dƒ J4Ó¯L¿2ý ö­Ý·vßZØÿxÿãý2”¡ ÈË˃E/‹^½Àm‹Û·-Ðø~ãûïCÝõu××]5û×ì_³¿®gC„‘¸Œ^øC¤:R©<­ù´æÓš0}ÛômÓ·AÌ×1_Ç| ªªªªªªPµwÕÞU{CPfPfPfÑ"«ûW÷¯îuNÖ9Yç$4Ød`“P™ÊT¬¯Y_³¾ú_ë­ÿµ®G+‡L0á/™o7ßn¾LIž’<åýÇ‘a„ô¸Øãb‹0Âx„ñc(;°ìÀ²Áf†Í › k/k/k¯ëQ‚ð1§…¿D¯·^o½ÞÀ.pxÆ3žáK׆/¡›g7ÏnžP7¾n|Ýx ˆ ‚tZ„O¸ˆCøKZUmUµUU¨\¹råÊ•¡J|•ø*ñðe— _&À›Ão¿9 ©Î©Î©ÎºN+§D0á/ю׎׎‡š7jÞ¨yŒ90æÀXZii¥¥• {Möšì5à«ï«ï«áÃ;‡wÖujA>¢€ Éó.Ï»<稜•ZVj”¹Zæj™«à tP:(alÆØŒ±ðEþù_äÃl‹Ù³-àvøíðÛáˆÇœ‚ð§‰&ü)šÉšÉšÉð¼ÒóJÏ+A•×U^Wy ÄKlÑv†G …~}ûõí×z”ïQ¾Gy¼x7ð.´=h{Ð Ÿ>)|¢ëQ ‚ð1LøSÒ§§OOŸñYñYñYP¶MÙ6eÛüúöòòòÐrBË -'Àøžã{Žï g®ž¹zæ*¬2Ye²Ê²»ewËî¦ëÑ ‚ð1LøS"‹E‹,ú}ôûè÷~%üJøýþ÷W•ªJU%ðµóµóµƒØZ±µbkÁ·9nsÜ ®~\ý¸úº¥ 2QÀ„?å鸧㞎ƒR­Jµ*Õ Lw›î6ÝýÇÛq^ï¼Þy=̬3³ÎÌ:`×Ë®—]/˜yaæ…™àY¹gåž•ÓõhAø‰&ü1Ž8â/í_Ú¿´‡òžå=Ë{þõfMO™ž2=£¬GY²†¦‰M›&ÂB§…N à\á¹Âs… yJžÒßП ?QÀ„?$qXâ°Äa•*Wª\©òß×¾ƒƒtµèjÑÕ†žzvèYØÑfG›m`{ÿíý·÷UUU]φ º$Vâþw‡ÞzwóóóÀÎÂÎÂÎâïïGf.3—™ƒ7Þx¶Ûl·Ùnƒ¥Ï–>[ú âœãœãœa˜á0Ãa†`žožož¯ëÙáß$ŽÀ„?$dtÈèÑàRÙ¥²Ke055ÿwâáàáàá¾Ë}—û.‡¬åY˳–ƒŸ­Ÿ­Ÿ-ÄÖŒ­[S׳#¿I0áwÑækóµùðb‹ /&@…-¶TØ `þ½ŽÇ;‡)½¦ôšÒ ŠŸ-~¶øY˜é<Óy¦3oÞ¼H!…]Ïš ÿ$QÀ„ß%»cvÇìŽeg”Qv†îò˜ô7éoÒF4ÑxDchêØÔ±©#,Ø´`Ó‚Mp¹Ûån—»÷¸Ç=]Ïž ÿQÀ„ßåõæ×›_o½êzÕõªCiEiEi…®S~‚~‚~|mòµÉ×&0 Ø€bŠÁ–Ü-¹[ra÷ÛÝow¿u¸:\®ë´‚ üÄEÂï~0ü`øA(v¬Ø±bÇÀð€áúNUD¶X¶X¶шF€]ª]ª]*,«µ¬Ö²ZP˜P˜P³fÌÓdÓdÓä¿Ú« º$ŽÀ„ß¶ˆE,‚—™/3_f‚G„G„GÈ:È:È:è:ܯ«h]Ѻ¢5Ìž2{Êì)ó(æQÌ#ðññ„ .è:¥ …(`ÂoÊj’Õ$« ¼3zgôÎÊ +3¬Ì0]§úýœ8 p3;Íì4³X³:fu fÕ™UgV«V1¬¢®S~º´Ó´Ó´Ó ¢~DýˆúðrçË/w¨@]§>v¢€ ¿)íTÚ©´Sß6¿m~[pÚì´Ùi³®Sýqæ—Í/›_†oC¿ ý6¼OxŸð>sœç8Ïq†›¯n¾ºù ˜Ìd&ë:í‡'çtÎéœÓ°qÁÆÀKõKõKõÿ~_PdPdP$l9¶åØ–cpµ×Õ^W{Á“åO–?Y[·n „¬ñYã³ÆÃ=7öÜØó6ÌÛ0o$VL¬˜(þÀ~…øLøMá3Âg„ÏË Ë Ë °Ûa·Ãn‡®SýyÐkx¯á½†ƒãsÇçŽÏaÍ¥5—Ö\‚ĵ‰k×Bû‚öí @o‰Þ½%ºN­{²/e_ʾy”¨ú *ĵk×2ßf¾Í| O}*ú@YeYeY%œØub׉]`jhjhj=ôlгØDÚDÚDÂ9Å9Å9”hU¢U‰V`\̸˜q1ørý—ë¿\mV·YÝf5Ô^V{Yíeà¿Ù³ÿf°«jWÕ®ª®÷žð¿ˆSˆÂ/J—0.a`Ž9æ`?Å~Šý`ó˜§ëtÿ¨HE*÷šÞkz¯)l4ßh¾Ñn^¸yáfplíØÚ±µ®w¢ðkdÒtDø0HÛ¥íÒvø¾Í÷m¾o•vTÚQitÝytçѺN÷áyiþÒü¥9,­»´îÒºàÖÞ­½[{\rpÉÁ%Á¼yó6ºËwíܵs×ÎÁÌœ™93s`î˹/ç¾Ëa–Ã,‡û2÷eîË ÿZþµükv.ì\Ø9°lkÙÖ²-¸GºGºGBVͬšY5!üføÍð› ßW¿¯~_(S®L¹2åÀ¨³Qg£÷.òÉÚŸµ?›(|`€IDATk?¼<øòà˃ ×L¯™^3(}½ôõÒ×!óPæ¡ÌCkkkvÁvÁvÁ ¿Nþ:ˆ“ÇÉãäàääÆýû÷‡W^=xõìííÁuë:×uÕ1ªcTGHªšT5©*—2.e\ œ;7vn ©õSë§Ö‡Ä…‰ ‚kE׊®‹–Ëè˜Ñ1£#ÄzÄzÄz€û÷î;@ñNñNñN—Ÿ0á·ˆ&üµ«ÚUí ck­=¶6ôôíéÛÓêxÔñ¨ã¡ët®„ 'NÀ²:Ëê,«šsšsšs0öØØccãÇ=Ž{þý\gžxf ,_¾8vìß±Ç~p°u°u°Õõ¬ Â_#¾þKÊΔ);!÷\î¹ÜsP®„] ;]§úð9´uhëЦ¶žÚzjkpˆtˆtˆ„YÁ³‚gCغ°uaëþ½<’™d&™Aahaha(Ô:[ël­³°)aSÂ&]Ï– ü=Ęð_î·ºßê~+ØÜds“ÍM`éú¥ë—®ƒ0ƒ0ƒ0]§ûx¨ ÔjØ»j諾«à⃋.>€ÁÏ?ü¼{ö: ²R²R²RºN+'q‡ð_âÄ-ˆ[6 lØ4ý«úWõ¯ê:ÕÇÇ@a 0P@ï=½÷ôÞö•í+ÛW†Õn«ÝV»ABÙ„² e¡}³öÍÚ7½“z'õNê:µ |\Ä)Dá¿$M8špl5¶[ È¿!÷Ãüyw¹Ë]hQºEé¥a¬|¬|¬Žzõ:êÎo8¿á<ä_È¿/ï"ˆ(`ÒHi¤4b¾Œù2æKpYï²Þe½®S}B¦1iP}_õ}Õ÷¯‰¯‰¯ '''C€Q€Q€¤œO9Ÿr^×aÿ7uououoH4L4L4)QJ”uJøÜˆ&ç˜ç˜ç©‡S§§H§H§È¿Þ®ðËJ*uªÔ)˜m5Ûj¶¨ÝÔnj7ðÃ? ò`äÁȃºNù òÉ'®Î½:÷ê\”Êe\>¹|ryHž•<+y¤ïHß‘¾Ò§5Nk i¾i¾i¾¸:quâjPÅ©âTqWWW‰Þ‰Þ‰Þ ŠQŨbÞëîÇÇøÄ׋¯_R:¦tLéÚõÚõZñÖgO0€¼½y{óö‚J¦’©d`µÀjÕ]§úôYk¬5Ö˜¨¨¨…².e]ʺÀ÷[¿ßúýVx¦|¦|¦ÔuÊ"¾¾¾pÖó¬çYO¸þîú»ëïà~Àý€û°ìÀ²ËÀ¸þãúë;üvøíðƒ=–{,÷XÂÐ=C÷ Ýw†ß~g8¼+÷®Ü»r08fpÌà¸c}ÇúŽ5äTÊ©”S V~»òÛ•ßÂ.ƒ]» `kÀÖ€­põÒÕKW/éz6]L Û'Û'Û4k5k5kÁò¢åEË‹ºNõù0q2q2q‚Á?üZk[k[kaÁ•W\K/m¼´´»µ»µ:\ÿ§FÜJº•t+ åÚ”kS® ´êת_«~P<¥xJñ(ô/ô/ô‡î »7ìÞ:”ëP®C9ÐŽÔŽÔŽ„¼×y¯ó^ƒëy×ó®ç’”¤$Â:7êܨϬžY=³‚‘ G.¹ªXT±¨b;Æì³c hžjžjžêzï º"®BH¤ ŒË—7.M-šZ4RH!E×é>úÝõ»ëw‡Î~ý:ûÝ\»¹vsa½v½v½Ö$¬IX]îv¹Ûå.(j+j+jë ¨5jNJ'¥÷¯žü±™\3¹fr l¢m¢m¢¡°{a÷Âî€>øCÊP ‡r€F4¢È äòˆ=(zD¯Œ^½ö¾ÜûrïKxåõÊë•è_Ô¿¨¤cÒ1阮÷š +¢€ Ä¿‹ÿ,<,<,<Àà¼Áyƒàb‚OV!„@аinÓܦ9,¿·üÞò{Ø+±Wb/˜30g`˜è›è›ü›¿ÍDI€=öØS´z¼n¸½÷ÿ`à€8∮qk€'žxw¸Ã0Zj´Ôh)89;9;9Có»Íï6¿ ­Z9´r…¹Â\aú×õ¯ë_ç?…Sø¼ˆSˆÉ>É>É>`ll¬ë4ÂÿUñ\ÅsÏÁÌ»3ïμ 1110/}^ú¼tH I I ù÷òXšXšXš@”G”G”ÜwÿÝýwÐ7¡oB_H;’v$íd}õuÖ× ÷½Þ÷z߃ÝC»‡váɘ'cžŒW%^•xUrn8¨:¨:¨:À»gïž½{Ù³;fwä?WE Ÿ'±””À÷)îSÜ¡Á“Oè—Ð/¡_CCCuJø»”Yfd™‘0+bVĬÈ®˜]1»"ø}ï÷½ß÷ççç¤ë”‚ðçˆö™Ë•;+wè¿Ô©ÿ½½â²äOŽCŠCŠC LY?eý”õà\×¹®s]˜ydæ‘™Gà…û ÷îºN)Œ(`Ÿ¹¼õyëóÖƒ~ˆ~ˆ~´7hoÐ^ש„ŠÉX“±&ca#4²ldÙÈü/ú_ô¿×__|}±®S Âï# Øg.#5#5#ŒÇ5 ŠXE¬"Vש„š¢º¢º¢:ôÔcPAðMËoZ~ÓÖ×]_w}]8v0ì`h–k–k–ë:­ ü2±”Ôg.£CF‡Œ`fofofòhy´ò|ä©ëQŸ:QÀ>sê+ê+ê+`¸Úpµáj]§>4Vï¬ÞY½ƒ Ö¬'XƒÇråËÁ7Ý7Ý77~Üøqc™2#dŒrå2ÊfŒ›1nÆ8Èè”Ñ)£“®G!|ªÄZˆŸ«…,d!Ì9ÿåü—PŠR”ºmè¶¡Û]‡>T…Ñ…Ñ…Ñpb艡'†Â £F'Œ â@ĈpYvYvY¦æ¦æ¦æ°úÞê{«ïAoÞ½=t^øÔˆ#°Ï””+åJ¹P° `AÁPÎRÎRÎÒu*áC÷Ó ïõêÔ€”);Sv•²WÊ^)[´]vfvfv&¬‘­‘­‘AÌÁ˜ƒ1âµð7ì3%Õ–jKµAm¢6Q›€B®+ħAørœrœrœÀ¿›7ÿnpÚþ´ýi{^I¯¤W?ß>heÐÊ •°½áö†Û‚ôVz+½Õõ(„O…ø'ësL0Á U*H@6S6S6Sס„]ê€Ô© )-)-) L:˜t0éT¡ U~¾}áªÂU…«`k™­e¶–çkž¯y¾F×£>¢€}®~zÔ»#Ž8*T¨tJøÐ•ð+áWÂV[®¶\m Ǧ›zl*Ll9±åÄ–ðÅ‘/Ž|q”K•K•K‹Þ–––\6¸lp–…- [þ ~|’gáÆÂ…!ohÞм¡u$ëHÖȬ˜Y1³"dxexexAŠ&E“¢”{)÷RîAÚƒ´i Ó#Ó#Ó2wdîÈÜ999999P +È@š)Í”Äxq#³ ˜éSÓ§¦OÁo¼ïeÞ˼—ÁèÚ£k® —×]^wyu=êzÔ®ø^ñ½â »£vG펂FéÒ¥ƒ×¯7^o yPò äAïïï éWÒ¯¤_¬ˆ¬ˆ¬Èl›Ù6³-dggC^í¼Úyµ!dþÈü‘ ~¬~¬~ êPu¨: ã ã ãARKjI Ò é…ô +<d’I&ÈÃåáòpÐËÖËÖË"‰$ô ô ô @á¬pV8ƒÁaƒÃ‡Á`©ÁRƒ¥`8Ýpºát016161³†f Í‚ù—æ_š æéæéæé`wÆîŒÝ°³³ãçÆÏŸƒávÃí†ÛÁp‚áà  ðPx(<€ºÔ¥®®÷îÇC0Aþ¸ÉLf2h¶h¶h¶@úÜô¹és!9 9 9lSlSlS ®²®²®TTT ( ( (æfÍÍš›•FW]i4(·+·+·ƒ©ÒTiª³f Ì€™«™«™+˜ß3¿g~ì«ØW±¯F«ŒV­£¡FC†‚É“&Àx ñ@ã l¬l¬l úçôÏéŸÙ,Ù,Ù,P¶U¶U¶Y†,C–êZêZêZPX¥°JaÐ~§ýNût+èVÐ òç7Îo ÙAÙAÙAû ÷AîÈŸ?;6äææBÖɬ“Y'!¢mDÛˆ¶Õ «AVÈŸ=>{<äſſłžBO¡§Å"Å"Å"0Ùe²Ëd8=vzìôœG8pŽwï:Þ—ª.U]ª‚C?‡~ýÀ ¤AIƒ’ ë*ë*ëªëî‰Ëè?SÚm€6fîž¹{ænðªèUÑ«"´ÙÖf[›mºN÷ss æÌpûpûp{0ébÒŤ ¸X»X»ˆçZýýs˜Ã}#ûFö x7îݸwã Â3Â3ÂB‹‡-±oc߯¾…ô€ô€ô0hhÐР!Øì¶Ùm³ì§ØO±Ÿ¥]J»”v‡Þ½zƒ¾§¾§¾'Ø>´}hû,õ,õ,õÀä€É“ {&{&{¦ëIø rÈ!TSUSUS!siæÒÌ¥u#ëFÖ Èœ58k0¤ôOéŸÒÞ6{Ûìm3ˆSÄ)â"K‘¥È knÖܬ¹ \§\§\aaaàÖÙ­³[g(W±\År¡¸qÿâþ`kgkgkrg¹³ÜYדðÏì3¥]­]­] 3]fºÌt¯-^[¼¶@›m´9ðÏõ/þ^ü=8æsÌç˜tºÑéF§`[Ͷšmµ_ß‘à#ÁG‚áqùÇå—‡Š+>®ø:,tX©KS—¦.…fç›ovÎ[·:oÑÑÑ0hÉ %ƒ–€a”a”a”®gÿᾯ¾¯¾©sRç¤ÎgóŸÍ6ny¸åáˆL‰L‰LÍÍͰëb×Å® ¸wuïêÞJ½-õ¶Ô[(5®Ô¸RãÀq€ãÇ ðSø)ü@n!·[Î8óüƒúWI¯¥×ÒkÐlÒlÒl‚ Ï Ï OxëôÖé­DÆDÆDÆ@øÉð“á'!Ú$Ú$Úò—æ/Í_ v'ìNØ€J•*UªT <==Á9È9È9Œ]Œ]Œ]€Ýìf·®Gû׉SˆŸ)Ù|Ù|Ù|Юÿ\ÿ9hÒ5éšô¡ßm²m²m Ÿ#Ÿ#Ÿ²Ë²Ë²Ë@5ªñ ¬0²0²0N~òû“ßC»Þíz·ë Íž7{Þì9eeeƒüªüªü*˜hL4&PÊ•r¥N?}üôqèÚ'´O(¤x¤x¤x€,T* '™“ÌI¦ë½ñÏ“¥D)’¿Nþ:ùk¸»öîÚ»káî⻋ï.†øåñËã—ƒe¤e¤e$TN¬œX9ZŒj1ªÅ((1¯Ä¼óÀ|†ù ó _O¿ž~½_èè ÷{ýi2w™»ÌôýõýõýÁl(úo jP‚¥`)rœsœsœ!¹OrŸä>ð¼ÇóÏ{Àcé±ôX‚Ë“.Oº< ŒªU7ªUæT™Sex—ô.é]Ü[»·vo úkô×è„W‡Šö¹zÍk^ƒb©b©b)þ|3­£ÖQëaÇ=†Ü Ü Ü П¦?M(‰ŠD(Ó£L2= ¥tJé”Òð,áYÂ30ßg¾Ï|hohoho€E–E–Ex6õlêÙôkë×Ö¯ Œe,cßëØ 'œ ®}\û¸ö>3|føLx7òÝÈw#!÷uîëÜ×P¢~‰ú%êƒÝ*»Uv«€›Üä&˜¬4Yi²ägågåg!uFêŒÔ°"cEÆŠ (çXαœ#|}ñë‹__³³fgÍÎBÄʈ•+!csÆæŒÍà˜æ˜æ˜ŽÕ«9VƒW^ x5ôîéÝÓ»R¤)E‚Í6?ØüšŠšŠšŠÝ;»wvop5u5u5Ù;Ù;Ù»o÷l.Ø\°B2C2C2áü„óÎO€°.a]º€Íi›Ó6§¡®y]óºæPÅ·Šo_(^»xíâµA±I±I±é½å A7d¾2_™/˜bŠ)`:Èté ¢uZm}´õQHY² e¼J{•ö* n”¸QâF XÜ~qûÅíÁ¢‡E‹ÐxVãYg—“—“—Xõ°êaÕ0à 3]ö׉ö™úé;Å*Å*Å*(Ø_°¿`ÿ/l" ‘…ÀÞ¥{—î] ÁÁÁÐ÷pßÃ}ÃÙ}g÷ÝMMšš45bÎÅœ‹9ÃhÕhÕhôø¾Ç÷=¾“/L¾0ùê”®SºNi˜0vÂØ caÂÑ G'…æ4çýEÎ¥Ò ideeeeeAþàüÁùƒ!Å-Å-Å rnäÜȹ7ÜpcìËÙ—³/öžÝ{vïY]—]—]ÙAÙAÙAÈÞš½5{+Í š4l6Ùl²Ù¹!¹!¹!p»æíš·kÂåg—Ÿ]~•“*'UN‚m“¶MÚ6 Fžy~äyØ÷zßë}¯áIÜ“¸'qÐòtËÓ-Oƒ[·:nu ¶Ul«ØVðè»Gß=úü­ü­ü­ÀC ÿÁý©>¬>¬> ÷/Ý¿tÿM?š~4’œ“œ“œ¡Ö”ZSjM‰u&Ö™X§¨°êÑ£?FןFáï&ë ë ë¶l;Øv[l±¼&yMòšÉS“§&O…»ýïö¿ÛÎW<_ñ|E8²ñÈÆ#¡QT£¨FQвl˲-Ë‚õ7ÖßX£ëQýœ(`Ÿ«ÏE(  P=S=S=êP‡:E›É¬eÖ2kp<ïxÞñ<$~“øMâ7жeÛ–m[BöÔì©ÙSáèú£ë®‡YKf-™µ Ág„ÏŸà>Ü}¸ûp=•=•=“&L€6K›¥ÍšÑŒfïõ;L6L6 ÊÔ-S·L]°ßa¿Ã~ÔlY³eÍ–àRèRèR%;—ì\²3HU¤*R € -Z´ ùH>’SlL±1`·Øn±Ýb¨¹°æÂš Áé¥ÓK§—0Ãi†Ó 'ð1ò1ò1‚î{»ïí¾.´¾ÐúBkxlõØê±8';';'CL¿˜~1ý ²²´Ë´Ë´Ë@¨TBó˜æ1ÍcÀÐÏÐÏИÈD&þûï)Oy ¯ê¼ªóªl¼ýñöÇãããÍ-š[4·€&‡šjrìVÚ­´[ Ìf6³uýátf XPTÐÚœnsºÍih|³ñÍÆ7áIæ“Ì'™p8öpìáX¸òìʳ+Ïà˯¿üú˯¡É‰&'šœƒ.] ºèz0¢€}öL#M#M#!»mvÛì¶¿±a>ùäƒä'ùIï=Ðм‚yó Ù5³kfWÐ*µJ­äÛåÛåÛAi¬4Vƒ‘ÊHe¤õXõXõX  h@ÑÉý_c€À¶°¤ÒiÄŸ¨ àÇ8Ò)FÞFÞFÞPÇ»Žwo¨&«&«&ƒ[Ån»U ödìÉØ“A3ƒfÍ„UTPœÝÝÝu—[¬Äñ™³hnÑÜ¢9dÎ5ú76üñd»ìŠìŠìJÑË)ÛR¶¥l…ÂFòòò ((4¢ÞkG5ЉNt*º?çWýtDÕ“žôY€,@ðÞÏ<Ò’m—m—mÊSžòEýÈ~ý ûÿÜ *¥H)R HÝ¥îRwu‘u‘uûVö­ì[Am‡Úµ`@ð€àÁ°rÁÊ+@ã ÆAƒ Ð³Ð³Ð˜Ï|æFaT'ãpÆáŒÃ’’Âßvî0çE΋œ°*jUÔª(¸htÑ袌i>¦ù˜æ0¤ÙfCš}Oûžö=O<Ïãþ$¥¤””øÄúÄúÄ‚˜˜˜L1™b2æt›ÓmN7ý>ôûÐïu—S°ÏœåsËç–Ï!Ë8Ë8Ë4Í5Í5¿ôÄݾô¥/D©¢TQ*86èØ cƒà‘×#¯G^ÐŨ‹Q#HèšÐ5¡+dǪ̂™QÞ,}³ôÍ{K ½éò¦Ë›.v5íjÚUˆ°‹°‹°ƒÂR…¥ K½×ßK^ò¢¾ú6ê[HmžÚ<µ9¼,ý²ôËÒq"ãDÆ ?~ ü¤uNëœÖB÷„î Ýó#æĠtÓtÓtӢ列69mrÚ§+ž®xº"„Î ::Ïë<¯ó<¸×á^‡{àÐéC§†Ûãn»=ÒâÓâÓâ!vJì”Ø)Ð6¡mB[HR'©“ÔE±ô<ÒóHO˜Ÿ9?s~&äÊ•?êÏ@*`ׯ5^”‘”‘”³{Ïî=»7T;^íxµãÀ5®qí7zË[Þ»ïÞ}÷î;8pðÀÁ!fcÌÆ˜ýs¤MÐ&hà–ö–ö–Âê…Õ «Yã³Æg‡³ögíÏÚà ¿~7ü€øßí„^½zá¯çþ›6 lÀ· ß&|›¾hôE£/`É•%W–\ðAáƒÂýû¹DûÌ™=5{jöò4yš< Ì,˜YðKk¾EA˜D›D›DC‰:%ꔨC/½8ô"4ÎlœÙ8\. ¬ê½ª÷ªÞPþiù§åŸùX¦Y¦Y¦Á"“E&‹L ñ„ÆOÚÓžöïûÿW?Y<·xnñ-Y´dÑhú¢é‹¦/@î#÷‘û@½‘õFÖ K.,¹°äØWµ¯j_¼ûx÷ñî‹g.ž¹x&8z8z8zÀtõtõt5tÒýI÷'EWE¶ªÕªV«Z0âØˆc#ŽAÉ’!%CÀv·ínÛÝ ¦¦ݔݔݔ0õØÔcSQk£ÖF­‹b·xÞây‹ç0âüˆó#ÎÝ€úg›tlÒ±I““ïL¼3ñØ7·onßü4d‚ &`°Ü`¹ÁrXŸ´>i}Ÿ >|ê¯ޤrR9©+|Vø,0Ž1Ž1Žû9÷sîçÀÎÀ;A:$’Aò¾ä}Éû /3/3/¤ÇÒcéqQ;?=gLø0èׯ?¾ªÿUý¯êƒOœOœOlx·á݆w¹9ssææ/¸‘ù3÷,õYê³TXûÍÚoÖ~þ.þ.þ.`hhX´Ý’'Kž,yϦ=›öl¬ Z´.   t=ŠOOŒŒŒ?Ìo7¿Ýüv0òû‘ßüÊí/·¿Üþ?ß®º»º»º;t1èbÐÅzF÷Œî >Õ|ªùTEMEMEM0×3×3׃´‘i#ÓF‚þ)ýSú§Àôžé=Ó{f”f”fŠêŠêŠê`ff)!)!)!`0ß`¾Á|°Ì³Ì³ÌƒµµÖÖZ[ žö|ÚóiO˜i;Óv¦-,Û¶lÛ²mСA‡@Ó5N×8 ékÓצ¯ƒo ¾5ø Ú´1hÙÓ³§gOýþúýõû]=k¦5ÓšiÁ$É$É$é×ǯ=¨=¨=i}Òú¤õýkú×ô¯ý¸Ìæ s°èdÑÉ¢ä?ΜÿÒ¦Lòîòîòî`UÛª¶UmÈ]œ»8w1hÌ4f3777bˆ! Ïž/<ô§?ýA›¤MÒ&8ÀPöPöPöÕÕÕw”w”w›d›d›ä÷®¦]”½({dÎ:œu *T6¨ V£¬FYy%y%y%Èk˜×0¯!dxgxgxƒ¶¦¶¦¶&$D%D%DA©»¥î–º V»¬vYíú Ÿ§fêfêf0¯Ü¼róÊA¥Á•W *wªÜ©ò?ÿ{".âøÌ™ššBá‰Â…'  ~Aý‚úE?ÏŸ“?'X ±b1Ê” (‰—/'^†â§¸®ñ ºsãÎ;7ÀÉÆÉÆÉ<êxÔñ¨ó×Û¥íh…Í ›6‡çWŸ_}~²Kd—È.ÏŸ;>w„Îzõ:ëÁ¹¬sYç² àuÁë‚×0ÍlšÙ43Xæ¶Ìm™hC´!Ú˜¾gúžé{`eç•Wv¥ÆRc þøã`5Ö€;î¸CH‡!àÄÅO\„báÅ‹…ƒS¨S¨S(l´Ûh·Ñ435353¡}óöÍÛ7‡Y»gížµzOï=½÷t?~>ü<ä™ç™ç™Ãt×é®Ó]Á$Â$Â$âçÃ/|Zø´ð),¸|àòPø¤ðIá“_—Z«Öªaúùéç§Ÿ‡åK—/]¾dËdËdË€¬`´¯Ò¾Jû*ðè꣫®Âþkû¯í¿ÍTÍTÍT ï¬ï¬ï ÷ß?~ÿ8Ø.³]f» *¬ª°ªÂ*8êqÔã¨Ô?Xÿ`ýƒ`ÕÛª·Uo¸Øïb¿‹ý`Lç1Çtggg02`$8w*îT ‡- }´}´}´ \¤\¤\oß¾###ˆ˜1;b6˜_4¿h~f™Ì2™eò×?NŠóŠóŠóÐxwãÝwÃá…‡^íbÚÅ´‹ÅeÅeÅåî÷D°ÏœùjóÕæ«A3T3T3rÆçŒÏvØaGѪÛ?^\Wôƒr”£œ®Ó‚–±ŒeðÚÿµÿkpÝçºÏuÈüeþ2ÿ¿¡ýø@©ˆTD‚—£—£—#´¬Õ²VËZ°Îsç:O8Xì`±ƒÅÀ%Û%Û%BóBóBóÀÄÄÄÄÄŠ—+^®x9xâýÄû‰71>b|œË9—s.OZ?iýä½S«ÄO|Ñýye~(óC™À¡—C/‡^ÐJj%µ’ drÉä’ÉàTΩœS9xz÷éݧwÁiµÓj§ÕPXXµZ×j]«5x×ö®í]† qãÆ üOüƒÙ³ fµÿ$ûIö“l0Ùh²ÑdcѸžnºýévȈ̈̈„7OÜ;úì€; î,¸³ hÅ”®5\k¸ÂõÀë×a]Úº´ui`ŸjŸjŸ VfVfVfp§þúwêCÐwAß};Ïí<·ó\Ñì^x}à5Èýä~r¿ßù™ù\‹»w-¡¡¡f‘f‘föØcÿþºˆïÀ>s»,vYì*:‹333ÕuªÏØ·+Ⱦ’}%û dKeKeKÿz³¿ÖYd‘UôrYã²Æe!zTô¨èQ òSù©ü@–,K–%¿÷þŸ®®œÇ<æýŽ×ÿ/=ôÐé–tKºÒKé¥ôòçíÈæÉæÉæú裴¡ mK,±åååÐÞÖÞÖÞ©²TYª §¼OyŸò†iIÓ’¦%Áô—Ó_NYtºÞk½×z¯Å,fñ/äßË^ö‚•‡•‡•ttíèÚÑV˜¬0Ya‹º.꺨+$H‘4dkekekÁÐÙÐÙЬ/Y_²¾6ñ6ñ6ñ s–9ËœùÙšŠŠŠ Ù¥Ù¥yïTžþ!ýCú‡ŠþéÌG푵GÖ “§Nž:y*l ܸ%rå4Êivì*ØUÆ 7Bh‹Ð¡- n]ܺ¸u`;Ðv í@?“?“ÿ‹%›cŽ9ðŒg<iŒ4Fó|nÿQÀ>sЇЇЇ`5ÆjŒÕˆsŒsŒsü;ìJWºÂÓqOÇ=g\ϸžq…|—|—|—ÿývi´GÚ… /^m 6PHÑåù»Sâfçfçfá½Â{…÷É_ò—þŽ#°o; %(T¦2ï}W‘T3©fRM°l;Ùv2(ª)ª)ªd.™Kæïµ£D‰d£d£dï_eùãm²²²ï½þSaðÿ¢íÈ ƒ —\r¡…²…²…ü§àÉÉÉ>øàÞëõÓ›Rk©µÔª„W ¯Žu8Öá´/Ó¾Lû2PÊ­”[)7жҶҶ:Ò‘Ž?×OóóÓ’aßìÿfÿ7ûaõãÕW?†¨²Qe£ÊÂf‡Í›@^(/”¥)Mi~~ûįÿ´ÔüxÛ‡l‹l‹lË{¯ÿ´èáß¡/7^n¼¦ Ÿ6|Úp˜ûrî˹/áì˳/Ͼ„3¯Î¼:ó ʾ.ûºìkðöòöòö‚;Oî<¹óÌG˜0FO=a4ÈûÈûÈûü}Ûˆk×"®E‹&MÀ:Ð:Ð:ð¯·û¿ˆ&à˜å˜å˜q;ãvÆíüçúyÖøYãga×Ô]SwM…Ä´Ä´Ä4È7Î7Î7þßïOËHËHË€€Ø€Ø€XXvyÙåe—)ºÿëáää±>±>±>êêêñ×Û•!C˜Ž5k:¢:EuŠê­Z?´†{Þ÷¼ïyC»v!íB tréäÒÉh”h”h!=Cz†ô„äëÉד¯C¶u¶u¶5dšfšfšB2É$i+ÒV¤­€¤.I]’º@Š2E™¢,º!?:?:?äååáVâ­Ä[‰X*±Tb)HÞ’¼%y ¤öJí•Ú Þ$¼Ix“Ùòly¶R=S=S=!…R€¬}Yû²öAºuºuº5/_<j ¨5 Ö¨%«%«%‹\‹\‹\°³³ƒÄ‰7þ|\9[s¶æl…¸ùqóãæÃ6«mVÛ¬ =(=(=œf;Ívš v—í.Û]†äzÉõ’ëAæíÌÛ™·!ådÊÉ”“ öP{¨=ŠnçH1M1M1…¬SY§²NAº{º{º;¤X¦X¦X¾÷ºEºEº¤oOßž¾BŒCŒCŒaßê}«÷­Í!Í!Í!(1©Ä¤“À*È*È*¢ƒ£ƒ£ƒáeÍ—5_Ö«ÇV­ƒ¡ÚPm¨†(³(³(3Èo“ß&¿Í_ÿ<|[ðmÁ·pÉ÷’ï%_¨S?¦~ (N+N+Nÿó¿'â;0(Z÷vþíüÛù@zÐãïïçQØ£°Gašš __þúò×—Áà¡ÁCƒ‡ÿûýÖC¬‡X³Ef‹ÌÁ³2ÏÊ<+Òxi¼4¾èè³ÚYí¬†&ÞM¼›xÆÃo8 SSS`£¶QÛü‰#N}'}'}'×~\ûqí!öëØ¯c¿†w>ï|Þù@Wó®æ]Í¡FtèÑs=çzÎuÇÉãäqÛ ¶Al¨µ¸ÖâZ‹¡êȪ#«Ž„Ì¡™C3‡B m m -xÄxÄxÄ@Úõ´ëi×ÁÓÊÓÊÓ <Ôj5˜T4©hRfØÎ°a qã:Æu„”Ã)‡SƒçQÏ£žG¡ÜörÛËmi´@Z#-GZŽ´óæÍ7‚|¾|¾|>Œ 0*,ÆXŒ±ó¿ç¡IÏ&=›ô=¹ž\Oþ ãZRuIÕ%`lblbl_û¢ØÅ 2/2/2Z,j±¨Å"¨s Î: ¬dXɰ’0¸éঃ›¾øâ ùyùyùyСb‡Š*‚I¢I¢I"dnËÜ–¹ :Œê0ªÃ¨¢¥Õþóz»í:´óýæûÍ÷ƒƒƒƒƒƒ¸¬pYá²¢;FwŒîåååàõÔë©×Sˆ;w&î hhh@Ú½´{i÷@-‹–EúFë­k£/¾4úRÑÙ?JûTûTûö§íOÛŸ¹ rä6€&·›Ünrû_üE‘A’¤à#ÁG‚HÒGC y$I™W2¯d^ùûÚÏx›ñ6ã­$;3î̸3’ÔªI«&­šHÒùwæß™/Iý úô“¤gnœ¹qF’éÒ;¤'IG¯½vôš$%«’Uɪ¢öÖ|±æ‹5_HÒ0Å0Å0…$iÛhÛhÛHÒ‹I/&½˜$I‡Fuh”$/~¼øñâ’”<}Z’Ž5:ÖèX#I:¶åØ–c[$).2.2.R×{£ˆª‹ª‹ª‹$-6[l¶ØL’&YL²˜d!I ­Z'´Öu:áC³7hoÐÞ Iä>È}»$©ej™Z&IécÓǦ•¤îí»·ïÞ^’¹r9äòÇÛ/¼[x·ð®$í:¾ëø®ã’ôÿW¬‘¤ðá5Âküûã§ èɹ‹Æ’%=Jzô÷µ¯T*•J%˜1;bvLÜMÜMÜÁÆÊÆÊÆ ´*­J«‚çÖÏ­Ÿ[C±‰Å&›W^=zõ(lm²µÉÖ&?oW¦‘idH:;u6ÌΚ5; ÔNj'µ¨.¨.¨.@jHjHj¤ L˜6¥.J]” ùNùNùN˜˜KR—¤.I…¼°¼°¼0]ï0Øo°ß`? ÑÑÑ‚cÇ:Žu`ÖÙYgg…‡Ë.{¸ ´©ÚTmª®Ó ºVsLÍ15Ç€‹ÒE预5«Ö¬Z³ ¶¤mIÛ’­Ûµn׺4kܬq³Æ¿¿Ý$£$£$#XvfÙ™egàZÿký¯õ‡ ò ò rp½ïzßõþ¿?^QÀL¯›^7½^tŠ#®k\׸®_ûJG¥£Òž84½ÙôfÓ›°´ûÒîK»Ã~ðÃH\ž¸²ùÈæ#Áúµõkë׺Nÿs¢€ ÿÅÃÁÃÁÃŽ?>þøxÈLÉLÉLËF–,ýùv³Wd¯È^Q…Q…Q…R)¥RJ%···€ŠÃ+¯8®•¿VþZyØùzçë¯!Ö"Ö"Ö¤õÒzi=¼yóæÍ›7ðî컳ïÎBfLfLf „·oÞ 90äÀ¸×÷^ß{}AVVVVVZtmѵEWp+íVÚ­4´éÔ¦S›N°Ùu³ëfW(Ó§LŸ2} ìñ²ÇˇÛjl«± ôõõþ…ûYþ*EgEgEg¨­©­©­ÏÁžƒ=Cp»àvÁíàÜÝswÏÝ…€Ý»vƒÕs«çVÏÁk§×N¯à™æ™æ™kÖ:¬e°2X¬ëQ –ÖKë¥õ‚´i'ÒN@XzXzX:\/~½øõâðòÕËW/_õ$ëIÖ“ ™u3ëfÖPov½Ùõfƒyˆyˆyˆ®Gñ¿‰Å|…ÿ’¿8qþb[bl‰±% ß ~ƒú ‚š53jfüùv5U4U4U õnêÝÔ» yªyªy ‡-[e[e[e[HuHuHu­‡ÖCëzwõîêÝúЇ>`jj ÙñÙñÙñ õÔzj=Á¼”y)óR›š›š› ªLU¦* ¶l5Ø ÖǬY+ZËNÝ_Ý_ÝR˦–M- Üà7ÀØØØØØÌ®›]7»ÄGœ®÷Ê_§¦¦)·Sn§Ü† †A ƒÂíã·ß>ñ[ã·ÆoË+–W,¯@eŸÊ>•} ÂŠ +*¬÷Eî‹Ü¹Â\a®¹‰ÜDnÂ{OîþUMhBP½Q½Q½¨¨¨s s s'š'š'ˆªU3ª&({*{*{ÂÉ_$‘ õ]ë»Öw…’¶%mKÚ‚Ò[é­ôþë±þm¢€ ÿíÇçF-Ì]˜»0ìÇÛ·}Oõ=Õ÷oxì†ðaÑÖÖ†x§x§x'»v/ì< yò0"ËG–,ÿÿr~pØè°Ña#”QzDéPv`Ùe‚ãÇŽÀ~»ývûí`cc23™™ÌL×£üø¨®¨®¨®@rùäòÉå!qkâÖÄ­ð6÷mîÛ\xú*ôU(ÄÈcä1rP Q Q ‡Í›6C妕›Vn •ÛUnW¹”t-éZÒŒRŒRŒRt=º¿(`Â/ºd~Éü’9Ï8žq<æ½™÷fÞ0t5t5tÕu:á÷ãÒGªQªQªQ}>ú|ôy‹ ‹ ‹ƒ×o^¿yý¢ZDµˆj¹!¹!¹! 2V«ŒAùZùZùÊ”5(k.\¹4‚K\,qlllÁØÞØÞØ”«”«”«@¢ Q†€¢PQ¨(y7y7y7þ³”Ô‡NŠ"¤(Ô/Ô/Ô‡‚‹ .‚ê[Õ·ªo!ÿ«ü¯ò¿‚Ôj©ÕR«At»èvÑí vQì¢ØE;+vVì,HÔOÔOÔ‡ü ü ü ¢5í«ÙW³¯îjwµ»ÊhËhËh¡L“2MÊ4óûæ÷Íïƒ,S–)ËÔõlüóD~QÌ×1_Ç| 3‡Í6søv÷íîÛ\â\â\>SjÂßC½Q½Q½Õ|TóQMˆ ˆ ˆ½‘z#õF‚W°W°W0dxdxdx@’w’w’7ä¾Ë}—ûôõõA±_±_±¿è¹_&sMæšÌ+7+7+7°lnÙܲ9˜62mdÚ ×®3\†; wîåPåPåP0ìjØÕ°+è?×®ÿôë=Ö{ 2­L+Ó‚¾©¾©¾)È¿‘#ÿ Ož,< Ú¶Ú¶Ú¶ Ù¯Ù¯Ù… .õ#õ#õ#È7Í7Í7…üêùÕó«ƒj§j§j'ädçdçdC¦C¦C¦¤J=”z2ÏgžÏ<*;•ÊÔêu¨Õ‰êDÐ?®\ÿ8XXX€ã5ÇkŽ×Àé¡ÓC§‡àÒߥ¿K(ѳDÏ=Á\e®2Wq q q ÈÊÊêzï랸ˆCøEN›6;m»p»p»px¸îẇëÀ~Çš»Â'N3L3L3 ®ª®ª®ª`çÐCw…ÆsÏi<z¶ëÙ®g;035353ÞñŽw  W…«Â!ëHÖ‘¬#––™i™i™iížížíéÁéÁéÁìžìžìi9i9i9Ð+¡WB/P=R=R=‚‚ì‚ì‚lP»©ÝÔnP`\`\` …ß~[ø-üÿZ@ÒJZI …« W®â?kŽÉÊÊ‚ž§ž§ž'ÈËË]¼£¸¦¸¦¸å Ê”ƒÃ‡ ƒ³³3Ž1c8Ìš4?½*zUô«‰V­&‚Y9³rfåÀü•ù+óW`æjæjæ fififi`²Éd“ɦ÷VÝïF7º½7ÑxÀ]ïí—8~Ó®r»Êí*¯6¼Úðj̪7«Þ¬zºN%èJÚδi;a«ÓV§­Nð¤ÿ“þOúC¿ýô[õlêÙÔ³yyy“¿Þßä‘GОö´é±ôXz ÚmŒ6$•¤’T ¥KéR:0Œa ÉWò•|PB †2”¡ …IaRÈË˵+k#k#kì`;@vSvSvd®2W™+Èd29ÊeŽ +%+%+…x²«Žˆ&ü¦°#aGÂŽÀ­ ·.Ü þ{ý÷úï]§þqÏyÎsx|ûñíǷᇖ?´ü¡%Xß±¾c}†d É’%”Pb€®Ã Ÿq QøM...`–a–a–Á‚'O‡åË–ë:ðOÉ~žý<û9z}èõ¡×pÁú‚õkh{¢í‰¶' ]»víÚµ#g#g#ç¿ÞŸ ü¢€ ¿É¨¼Qy£òàçç—3/g^Î…ÂGrµ\-ÿ$)ðªõ«Ö¯Zúªëª®« … >€)ò)ò)r(ºüéòÿÂsžá÷§…ß%þIü“ø'0Íušë4W÷rÜËq/¡B 5*ÔÐu:áÏRª U…pjÇ©§vÀ¡æ‡šj sæ6Ì…®Å»ïZÌ Í Í ÿz‚ðw‹ù ¿‹ãŽ_8~UÎU9Wå\è|¡ó…κN%üYúúúà'ó“ùÉàœÇ9s0úøèã£Ã0Q¸„›(`ÂÒ"¼Ex‹pxäøÈñ‘#DGDGD‹UÎ?xùùùpdü‘ñGƃo”o”o{TìQ±Gàoäoäo5‡ÔRsÈÜeî2w]§„ß&N! ˆTYª,U†…F Ér“å&Ëa¤×H¯‘^ºN'ü_o*¿©ü¦2lðÞà½ÁRV§¬NY ýçöŸÛ.x>ô|èùä‡å‡å‡uVþq&ü!²g²g²gÐ9½szçtx°àÁ‚ àuðëà×bõrËo˜ß0¿!{xìá±à{Â÷„ï (žW<¯xøó/æ_ jͨ5£Ö Q¸„›8þo¼ñ†•6+mVÚ@nznzn:L|2ñÉÄ' ËeÈþÂêõÂQ3¢fDMØÐgCŸ } ­lZÙ´²Ðzÿéý§ƒçIÏ“ž'‹ *ŸQÀ„¿ä]Ü»¸wq0ãÅŒ3^ÀàÀÁƒ¡ÎÁ:ëÔuºO—ÊYå¬r†“-N¶8ÙŽ1>b ^Ö^Ö^ÖÐýP÷CÝe°e°¥82>Qâ¢ð—8s.æ\ :Øu°ë`;Êì(³£ dZgZgZë:ݧçuõ×Õ_W‡Ù›foš½ ._4¾h £ºê>ª; =4Z.áó ŽÀ„¿EÞÆ¼yaVÏY=gõ„ §+œ®pú~Ù÷˾_ê:ÝÇ+·OnŸÜ>pJ}J}J Çškz¬)Ô5­kZ׺÷îÞ»{o°(°(°(ÐuZAøw‰#0áoa4Àh€Ñè;©ï¤¾“àbÚÅ´‹iEkè LèÁЃ¡Á·¹osßæp%üJø•pøöÄ·'¾=ƒÌ`Dá>oâLøGì°wÂÞ p#ýFútðëç×ϯXÖµ¬kYW×é>¸¶íÚ¶kÛ åš–kZ®öaíÃÚ‡éÓ¦ tV>l¢€ ÿŠkϯ=¿ö6mÚÓ#§GN„²³ÊÎ*;K×éþ9’™d&™Áý^÷{Ýï[/n½¸õ"˜®5]kºúõé×§_ðˆñˆñˆÑuZAø¸ˆSˆÂ¿¢þªú«ê¯‚†¦ MšÂêÅ«¯^ i}Òú¤õÑuº¿_ªSªSªÎœ8VíYµgÕð ö ö .Z‹P.AøóĘð¯Ê+Ì+Ì+„LX0÷÷÷`‚4Aš Á-ƒ[·tò“ÚIí¤vpûÍí7·ßÀ–‡[ny/^8¼€þÊþÊþJ(]®t¹ÒåtV> âLøWéééÃÈÓ#O< qµãjÇÕ†Cv Ù1´]´]´]tò÷KJIJIJ•²•²•2XŸ²>e} t°ï`ßÁ¦[M·šn% — üĘ S¯l_Ù¾²¿Ç~ýC¯ò½Ê÷*ͳšg5Ï‚ŒÍ›36éb§Š*Ì™52ƒbÞż‹yÿûy544à®ù]󻿰Åm‹Û7(ö}±ï‹}Ê (7 ¸Lq™â2E׳+Ÿ6}]>oe’Ë$—I†!‡‡rÖç¯Ï_Ÿ÷ î܇#Ž<8ò¶ïÚ¾kû.XUlU±UÅ ûóîÏ»?ÿëýçNΜ;iŠ4E(Ö)Ö)Öý|»ÔZ©µRkÁŽ´i;ÒàÁÎ;섯Œ¾2úÊš%5Kj–Ê­Ê­Ê­ºžUAø<ˆSˆÂÁûKï/½¿„Æ /l¼ÆÚŒµkk®¯¹¾æ:¤¦¥¦¥¦Áñ‘ÇG ¹ssçæÎýóý¥ÞK½—zÆ^{uìU8=ðôÀÓ‹~®§§·Rn¥ÜJ)w§ÜrRÓSÓSÓaö™ÙgfŸ¶NmÚ:ò”ò”ò”®gQ>/¢€ º5‰IL‚Ç/¿|üv Ý5t×PxtóÑÍG7¡àiÁÓ‚§E›_~vùÙågõÇ»“^I¯¤W°óôÎÓ;Oæ[›nmºóäóäóäpÏúžõ=kXm´Úhµ¬[³nͺ5Ð6·mnÛ\˜zzêé©§¡ÔÌR3KÍÔõä ÂçM0A§&6LlS\¦¸Lq³›În:» èMozÿÂö$€cúÇôý‰à÷Ÿß~ÿ9¬HX‘°"Ôrµ\-‡{·ïݾwzwêÝ©w'ˆ­[-¶ø=ñ{â÷Ú™´3igžžžºž5A@0AÇ,šY4³hSÆM7eô(èQУ,š[4·hþóíµIÚ$mœ‰?&¢ó£ó£óÿw?éëÒ×¥¯ƒ…Å[X ^¯y½æõš÷Ú¥¥‘ñ‘ñ‘ñ`™m™m™ Î;œw8ïÐõ, ‚ðKDtJ©P*” hØ °A ¬X±>6uØÔaSh:¡é„¦ÀðáÃEï{òüÉó'Ïáæ”›SnþÆÕ~’L’I2ع-r[$œ°8aqÂâ×·WTT„ÅM7]Ü.&_L¾˜¬ëYá—ˆ&|PŒW¯4^ ’;%wJ†]÷vÝÛuöì ØU:VéX¥#„„„ÁN8ª/T_¨¾rÉ%·¨½ ¯‚¾ ú VD®ˆ\ ùåóË痯ÙÌd&xxxA¥E•UZM´M´M´ ‹—ÅËâu=+‚ üq˜ðQ&I“¤I¾%|KøØðfÛ oàü€ó΀fÉÍ’›%ƒ2@  @@@Øã¹Çs'r|Èñ!`élélé ®–®–®–PûXícµAórÍË5/U:UéT¥T|PñA`ÐÄ ‰A]^„_" ˜ðQÒ¶Ô¶Ô¶„Ùýf÷›ÝæT˜SaN¥@)äÕåÕåÕÁm›Û6·mÐ)£SF§ ¨gSϦž Ôð«áWÃ&9Lr˜²[²[²p +Aøœ‰™…’|²|²|2hêjêjê‚ö¦ö¦ö&°Žu¬i”4Jc—]>v9 ©1¤Æ¿ÐÐ-n! — |”Äw`ÂÇ©hÞ¹Þ¹Þ¹`—c—c—²m²m²mPΰœa9C(Y«d­’µtV„‚(`ÂGÍÍØÍØÍ|,|,|,`íÓµO×>…m´YÐgÎ8œ—v]Úui°šÕ¬ÖujAþâ¢ðQ{sûÍí7·¡äW%¿*ùôSõSõSbšbšb˜º˜º˜ºÀ†bŠm(VtU¡ÏpŸá>Ãu^„¿B0áãôãwWª?ªþ¨:TôªèUÑ GGG‹6k4®Ñ¸Fã@)‹”EÂÆÔ©SAj%µ’ZAc³ÆfÍ€}ìcŸ®%Â!N! ¥¼y;òv@dÅÈŠ‘¡Âº ë*üÂ*òLcÓ á hø ,X8°6½ÛônÓ;¸˜v1íb0‘‰LÔõ¨Aø#ĘðQŠ10b ¶(lQØÊ—5.kü¿ß×`VƒY f7¸Á ø!ð‡ÀRH&4AÜö%q&|”Â…- [Å.»\ì2˜w1ïbþ{žä\jTƒF ŒÁ*Cª ©[ÙÊVàBÍ 5/ÔjS›Úº¥ ¿E —þô§?¼P½P½PAyÊS““ûí d ¡þÀúëYIYIYIXk¶Öl­HRTÍZ6kÙ¬%p†3œÑõàAxŸ(`ÂG%³}fûÌöííí­µnÔº°Œe,ûóíÖ{QïE½ÀqŽsÖ´YÓfM¶J[¥­Ðœæ4ÿóÍ ‚ðLø¨$)’I PßSßSßçE΋œý cŒ1Ô³¨gQÏd×e×e×a]üºøuñ ÉÕäjr¡elËØ–± s—¹ËÜu=‚ðyLø¨<_÷|Ýóuàêê vgìÎØý§öZÒ’–à7Þ€^O½žz=a•z•z•4]4]4] Í‚6 Ú,Ù$Ù$Ù$]ÏŠ |žD>*¡OBŸ„>÷†î Ý‚ÌUæ*sýçú«“Z'µN*ÈÈÈÀŠ +*¬¨ZS­©ÖÚkÚkÚk=ôÐÓõìÂçE\…(|rMsMsMáí±·ÇÞƒÊM*7©ü/^ï^kR­Iµ&Áw¿kü]c8¸åà–ƒ[àð­Ã·ß©‚TAª ëY„Ï‹(`ÂG!¶olߨ¾ *§*§*¥ŒJ•2ú÷sÔ¸SãN;0&kLÖ˜,8TóPÍC5áàñƒÇíZíZíZ]Ï– |D> ±ûb÷Åî + + +0h>Ð| îòT ¬X-Æ¿ÿfü8võØÕcWá@âĉ ½^H/t=k‚ðiLø(¼Hz‘ô" JW(]¡tPf*3•™ºN_”ÿ¢üåaâʉ+'®„Ó×N_;} öxìñØãÚéÚéÚéºN)Ÿ&QÀ„š¶’¶’¶¼¹÷æÞ›{àvÏížÛ=]§ú¹J*=ªô&dMÈšg½Îzõ‚]Íw5ßÕ4_j¾Ô|©ë”¿Âö…í ÛCRfRfR&ä=Ê{”÷Hש]Lø e7ÎnœÝR|S|S|Áu¼ëx×ñºNõë*Ü­p·Â]˜\ir¥É•àb»‹í.¶ƒSwNÝ9´M´M´b±E¢÷FïÞ —-/[^¶µµÚZmýëÛkïjïjï‰é'¦Ÿ˜«N¯:½ê4Üž~{úíépoŽ÷V@X½°zaõ k|Öø¬ñpÖþ¬ýY{¸áwÃï†@º½ðwLø E­Zµär¹\.‡SJL)1Eשþ·rËm,·¦œ›rnÊ9¸Ö÷Zßk}a[ñmÅ·«ÆUó^þÿ¡‹{÷.îÜN¹r; " " "~}û´i#ÒFÀ‹, e‰–%Z–€Ê‰•+'Âýª÷«Þ¯ á³Âg…Ïãã㸟s?ç~ì ܸ3¤CÒ!é$ïKÞ—¼òç-Î[¬ëÙþ,=ßé:ˆ ü’ œ œ H9›r6å,4ÏnžÝ<dÍdÍdÍtî³)nSܦ8T8\áp…ðÓu§ëNWH>˜|0ù TލQ9ôlõlõluö×iÊhÊhÊ@Êš”5)k '8'8'²Þf½Íz …F¡Q€R©T*•é•é•é¹·roåÞÕuÕuÕuP{¨=Ô`«o«o«•nTºQé˜Û˜Û˜Û€ÜFn#·y¯ã·¼å-DV¬YvnÛ¹mç6hÖ¿Yÿfý¡ôÒ7Jßׯ®]C©&¥š”jÆ?†£!GCŽBâðÄá‰ÃÁ³‘g#ÏF°dË’-K¶€e®e®e.8E;E;EP)™)™)™¹!sCæP|­øZñ5P‚”€”è”è”hдӴӴƒœ9/r^€^k½Öz­!÷Qî£ÜGPè[è[è í Ú´Óõ^üôˆ#0კ™™λœw9ï*º¡øcã~Áý‚û˜f;Ívš-ܹsçÎ;°Å{‹÷o(ü²ðËÂø;²Üâ¹Ås‹Ã¤j“ªMªþÉþÉþÉp´ÎÑ:Gë€_'¿N~ âTÄ©ˆSpüÑñGÇAÿ‰ý'öŸ;Oï<½ó4oq¼Åñäääƒòåʇ¨%QK¢–ü¼_µ½Ú^ma›Â6…m‚$¯$¯$/¸Ûønã»!fxÌð˜áèèè -Z.´|¯k¬±ÜqÇB¾ ù&ä81õÄÔSá^ì½Ø{±<*yTò(8óòÌË3/aÕíU·W݆mÛ¶ÀšFk­i‰×¯%^ƒÉÙ“³'gÜsNÌ9[«o­¾µ:W ®\VX­°Za›b6ÅlŠÑõÞût‰&|ÔNj'µ¼þfø›áPÖ³¬gYO]§úë\§¸NqÓƒ§O†ûîO¸?6TÙPeC(ˆ*ˆ*ˆÒuÊŸ3»lvÙì2˜››CÉy%畜C<‡xñýú5ôkÀ‰á'†Ÿ¥—\z0d§g§g§C›–mZ¶i ÍÚ4kÓ¬ ”M+›V6 râsâsâAÝNÝNý G( c…±Â<xðN“&;M†ÖoZ¿iý\ëºÖu­ ÅÜŠ¹sƒ´Öi­ÓZ¿×@<ñÄ­mYæ‡2?”ùz9ôrè­ãZǵŽ£}FûŒöÁæâ›‹o.Í*7«Ü¬2ô·éoÓß.Æ\Œ¹)3Rf¤Ì³l³l³l0›m6Ûl6ôqíãÚÇ\»v |:ùtòVÖ­¬[YÿÞYþ(QÀ„Rvfvfv&dNÉœ’9œòœòœòtêïSjT©Q¥FÁ´éÓ¦O›º?êþ¨;¬sZç´Î TsTsTstò§8Å7Üp+zÙÎÏÎÏÎbÇ,ŽY Xa…:::ƒõ%ëKÖ—Àn‰Ý»% C† `4¢~£_}ôÑé–tKºÒKé¥ôò½Ÿbˆ!0yÌûv~\òë§vhG;ÚAÞy?äýo›½mö¶\7¹nrÝ޼8òâÈ o—o—omGmGmG³B³B³B°ñ±ñ±ñË–#,G@ù·åß– îÛÝ·»o×õNût‰&|2jdÔȨšëšëšë`7Ûn¶Ýl]§úû¹¨]Ô.j˜1ÆüóáEÔ‹¨Q°ºçêž«{B¾_¾_¾Ÿ®S¾§4¥) ²¹²¹²¹E/çdädäd€Y'³Nf€bˆ)Úþ?æ'?~×$$$2™Ìç7úýiûoeßʾYKYKYË÷~n„F [ [ {ÿóOýúá‡_ÑvdAð˜Ç<½d½d½d°Üg¹ÏrÔ9_ç|óÐyRçI'ÁFåFåF%TÑVÑVÑBáõÂë…×ßßÿ[¹ rAePŸRŸRŸÒõNût‰&|ÞöyÛçm0ïoÞß¼?XŸ´>i}Rשþ9Å·ßR| Ì;sì̱ðöÅÛo_Àʨ•Q+£ Ç/Ç/ç(dRš”&¥Aljljl*Ü)q§ÄÛ,¶Yl3hò Éƒ& iKÒ–¤-y;óvæmH”2(eð†7¼„Q £FAÖð¬áYÃ!áU«„W¿Ða&™dBb`b`b döÉì“Ùb¯Ç^½ªgªgªgt-éZÒ5H[‘¶"m$uIê’ÔR”)Ê%¤Å§Å§ÅC~t~t~4È/Ê/Ê/ÂÍë7¯ß¼šMˆ&ê®7ºÞh*T&¨ DùGùGùCNïœÞ9½!wTî¨ÜQ10c`Æ@HŠHŠHŠ€B‡B‡BÐtÖtÖt†î+ÜW¸Ãf÷Íî›Åcwþ1¢€ ¤È;‘w"ï€ã ÇŽ3@/\/\/\שþyŽG8io§½öbÝbÝbÝ`ùÒåK—/…¬à¬à¬`Ýå“K‹¥Åaaa)Î)Î)Î0`ù€å–Cmemem%Ó+¦WL?üxðc¾¾¾M¦@Sz7õnêÝ„‘Œd$`²Öd­ÉZÐfi³´YïõWMª&UýaúÃô‡ÁÈïF~7ò;0J0J0J€¬Y³‚çÏ ž Ó¡N‡:‚4×4×4Wð,ëYÖ³,tRwRwRƒIE“Š&a†÷ ïÞ \¦\¦\’»ä.¹Ã·¿øí@¨S!§BDÅGÅGÅCòâäÅÉ‹!w}îúÜõÐau‡ÕVCÝGuÕ}ªÑªÑªÑ wWï®Þ]ðV{«½Õà™î™î™®ËOÔ§M&ýH×Aá}þÇüùƒ’õKÖ/YzZõ´êi¥ëTÿ¾äùÉó“ç ,hf;Ìv˜í€1寔SÌG›6ýïå‘>"}D:¸5rkäÖÆ>ûxìc]Ï’ð¹G`Â¥àhÁÑ‚£ß&¾M|(=½ôôÒŸñZ‚¶“m'ÛN†©ë§®ŸºT7U7U7!`RÀ¤€Iz*õTê¿ðKòÛä·ÉoA?A?A?2™ŠL¤'¥'¥'éz–„Ï•(`Â%µZjµÔj;0w`î@(áQ£„‡®SéžÕf«ÍV›aRì¤ØI±À NpÚ.´]h ÉË’—%/ûçú·¹lsÙæ2,Þ»xïâ½0½ñôÆÓƒE¾E¾E¾®gGø\‰SˆÂ%ôBè…Ð °¡ûæá—ˆ&|PâÅ-Š[6n6n6n`4Ûh¶Ñ'xÿ×ßÅ$Õ$Õ$FÍ5gÔ(ݯt¿Òý`îws¿›û¼=ðöÀÛºN)ÿ QÀ„J´o´o´/8UrªäT ¸ÊU®ê:ՇϨšQ5£j0T9T9T _¬þbõ«anôÜè¹Ñ~(üPø!]§üu1¥cJÇ”†X)VŠ_h¿“(`ÂAûLûLû RüSüSüÁa Ã@‡ºNõñQ.V.V.†óÌ0¼c¼c¼c`›æn‚_½øêÅWºNY$µ_j¿Ô~PPPÇ7ßp|¼ûvìÛ±ðxçãw›ø7ñoâ!´qhãÐÆðÂð…á Cxžø<ñy"<-xZð^ç¿ÎÏÛ>oû¼-hii¦¦¦¼*õªÔ«RpÿòýË÷/C̸˜q1ã€RHÑõl”(`ÂAƒ þ"ýEú °kn×Ü®¹®S}¼SSS¡÷½èý4kÚ¬i³¦à¿Çÿx2ýÉô'Àí Ùò‡eƒûñ÷ãïÇCòƒäÉ !*!*! Æ}=îëq_Ãv¶³¸\örÙËeáX¥c•ŽU‚©¡SC§†Bn±Üb¹Åà¶Åm‹Û0ù›ÉßLþrïçÞϽçöžÛ{n/¬¶þÙúgð¢ä‹’/J‚! †,áááy8¿L0ჟŸŸŸŸy'óNæ¹ÜF|:ÿ2½,½,½,øú˯¿üúKørß—û¾ÜpÿÎý;÷ïè._±1ÅÆ¶¯l_Ù¾ÏKž—ÇŽ'O€ÂQá¨p„SÏN=;õ 2·gnÏܹ9¹9¹9=={zötè”×)¯SœÛnÿ¹ý`|Úø´ñip¨îPÝ¡:T_y|åñ`Ž9æºÞ7Âï&Vâ>ûò÷åïˇ׷^ßz} ¦N˜:aêàx ëtŸ{÷ î@`½Àzõ õÁÖ[„Î;oì¼ô}õ}õ}ÿþ~c«ÇV­‘í"ÛE¶‹‰-&BÎ…œ 9ÀbÅ:‹uàžãžãž\ç:×áÕ½W÷^݃d´Éh“ÑlŽÛ·9®ëTÂOÜW»¯v_ S{Oí=µ7¼T¿T¿TÃòfË›-o9!9!9!ºN)|®DtJí¡öP{]4`zÀô€©X»ïƒã²ÎeË:˜6pÚÀi!qVâ¬ÄY0/`^À<È È È ÐuJás# ˜ Sê8uœ: K–*,F©F©F©ºN%ü‡Î:ôóÓÎO;ê¯Õ_«¿†ysæÍ™7’ã’ã’ãtRø\ˆ&è”:X¬ÍlÍlÍl0niÜÒX\ðÁ³2·2·2‡Iç'ŸtLÕÿ½»ŽâÚÿ?þš•lˆ{  @Ð Á‚•Bp-R¼Å¡ÅÝݵ¸C!h±âî,ƒ$„¸ëJvw~ünox|ÛÞÛ[Ú.-óü§²³ç¼gNàÓ™9sƪЪæ‡Î ñÎñÎñΦN)ù§“ ˜Ä¤ Õ…êB5èëèëèë€y„y„y„©SI~+ëÕÖ«­WØ c.Œ¹¥ÍK›—6‡yyóòæåAdzdz¤´H®äO"0‰Iéêê‚ñ+ãWƯ@uNuNuÎÔ©$ÿ«bÅŠÀðχ>üs¨íXÛ±¶#,踠ゎðäõ“×O^›:¥äŸF*`“ÒÓÓ1ELS@™ªLU¦š:•ä÷Ræ)ó”yðåÍ/o~yÚÆµkË-´|ܬv³ÚÍj¦N)ù§–’’˜T¾&_“¯¥ƒÒAéÊfÊfÊf¦N%ùPŠ2Š2Š2ÐñPÇCm¬m¬m,lpÛà¶Á r—æ.Í] Ÿó9ŸÂxa¼0þ½´hÑ›ÙÌfàk¾æk@… •©÷Nò±ÎÀ$&¥>¥>¥>ÊËÊËÊË l¢l¢lbêT’?ŠPK¨%Ô‚f›unÖF¹Žrå û‚öí ‚ƒC=8ôôôо÷¦ñ›ÆoC°_°_°vvv›zo$©€ILªÀ¥À¥À”k”k”k@¹M¹M¹ÍÔ©$–:åꔫS&/›¼lò28÷âÜ‹s/`—j—j— Âç„Ï ŸcüÇøñ‡©¾S}§ú«S¯N½:eêô’TÀ$&Up³àfÁMPŽPŽPŽùcùcùcS§’üÙ*m¯´½Òv˜)ÎgŠp{ÑíE·A·õÝÖw[§lNÙœ²×Ï_?ýµ;ÔîP;0Œ¦N/ùXHLbR††† ª£ª£ªcê4’¿š|…|…|¤´Li™Òž¥xùàex­{­{­3ujÉÇB*`“ÒŸÖŸÖŸÁUp\MFòWI­Z!µ Ïž3<N?=üôð_ß>R©‹ÔAðñàãÁÇóœç¼©÷BbjR“˜”Á×àkðQ+jE­©ÓHþ*²$Y’, 84phàÕ}«ûV÷³³³_¸Dh8l8l8 ‡úê¨?¼®üºòëÊ¦Þ ‰©IÔ1ûcöÇìá±ì±ì± æ¦ÏMŸ+­ÜðÉ0 ŒÐ!¡CB8zâ艣'àÀ¶ÛlƒGß<úæÑ7 Óëô:=È^Ê^Ê^ÂÒKO,=c&Ž™8f"p{Üã ã ã зַַ†üãùÇóCz‰ôé% 3)3)3 ò<ó<ó<‹Þܬ¯¯š8Mœ& ¥ ¥ ¥Àð¹ásÃç ß£ß£ßò¡ò¡ò¡ Ÿ(Ÿ(Ÿòûòûòû ŠUŪb¡Xb=Šõ‹,€eoËÞ–½Áþ û/쿇³g΂ÍF›6A1D1D1ä{ä{ä{€ L`‚©GåïCzL"‘˜ŒÌBf!³€’çKž/yF}6ê³QŸA7Y7Y7œés¦Ï™>°m¶ Û&ÀƒÒ˜Ä¤ŽÙ³9f07cnÆ\i5úO޾—¾—¾d$e$e$AT‹¨Q-à™ö™ö™î¹Üs¹ç/Z¼hñ¢¤†¤†¤†@ÕµU×V] í·kÜ®1¸utëèÖ\·ºnuÝ Ž.Ž.Ž.àïïæ5Ìk˜×ÙVÙVÙV† Äa   <ä!o¼ñþ Á3È èAz€ñ ñ ñ ˆ;ÄâçˆsÄ9 “ëä:9d~–ùYæg~>ý|úyHMM…ä†É “BÜWq_Å}I“& õ>õ>õ>0Ÿk>×|.”Õ•Õ•ÕA¥•T:¾å}Ëû–/*äf1f1f1€vØ™zTÿ|R“˜Ô±æÇškC‡<ùó/!ŠÝÅîbw׋ëÅõ +&+&+Xb‰å¯ïMÚ›´7ið²ÛËn/»AÝúuë×­Ž_9~åø•…ÊBe0f³ŒY`Â=Ã=Ã=!="="=æ;Ìw˜ÕU;Tíø;ø;ø;@¹%å–”[²U²U²U¦Þ»?žt QbRfWÌ®˜]ý!ý!ý¡?¿¿œpþÁÒJ¤•H+· Ü6pÈúÈúÈúü|ûd—d—dØ2aË„-À³ƒgÏðnó»Íï6æƛoj mj¶©Ù¦&8à€°²áʆ+BÀÒ€¥K¡ ]èbêƒm?Ý[z~ýùõç×áâš‹k.®×Ç^{} Ї)µ×Ô^S{ Tù¼ÊçU>÷ ÷ ÷ P©T*• ØÅ.výBiLcSïåG¨(T*‚Åj‹Õ«Á ,×¾®}]ûB-jQ‹¢7™'žN³ùÌæ3!)4)4)n©n©n©àDÿýOô‡#£ŽŒ:2 šn~¸ùahnhnhnÛî¶Ým»›z¯þwÒ4z‰IYlµØj±tƒuƒuƒ¡ð^á½Â{EŸ§lLÙ˜²‚͂͂Íàô±ÓÇNƒjüPã‡ðÔñ©ãSGÐ=Ô=Ô=„‹õ.Ö»X.Æ]Œ»Wî†] ƒðÇáÃCn‰Ü¹% MHÒÐ;éôN?Ï¥ ÐèàÉã'Ÿ<†³³3¸¯¸¯¸¯€ô‚ô‚ôȽ‘{#÷¤ËÒeéïým’u—u—uÚÓžöp~äù‘çGÂb§ÅN‹àêü«ó¯ÎMSMSMSˆŸ?+~œlr²ÉÉ&prßÉ}'÷AòÑä£ÉG!I—¤KÒÁ‘ä#ÉG’á®Å]‹»pµÌÕ2WË@ú“ô'éOà’Ï%ŸK>ð¦ÿ›þoúÿùã'ÎgŠ3!dbÈĉ0-jZÔ´(84õÐÔCS!P¨TÀâ”Å)‹S ÿÚþkû¯…rÃË /7\*\4¡ŒPF(%‚J•‚.~]üºøÁ¢¾‹ú.ê _,úbÑ‹àö·¿¸ýLÚ>iû¤íp¥ç•žWz‚þ¸þ¸þ¸©÷â·“ ˜Ä¤,C-C-C¡p@á€ÂP¸ªpU᪢ÏWWWa«b«b«âßÅ¿‹VϬžY=ƒ•ÕVV[Y ^¿}ýöõ[xxëá­‡·`mÎÚœµ9>-}Zú4HÓÄ4Þõz×ë]/Xm¾Ú|µ9\-¸Zpõç¹Z…V¡Û™¶3mg‚¹§¹§¹'8Ÿp>á|¬š[5·jG¾9òÍ‘oàüÑóGÏ}¯ 4 o"o"oƒÁòªæUÍ« Åwß]|7d•Î*U–î_ºé~иiÜ4nœœœœœ +¾_ñýŠï¡0ª0ª0 6”ÛPnC9¸rþÊù+ç!¥_J¿”~¶?mÚ~8_ü|ñóÅ!òzäõÈëÞ¸åžÉ=“{¶Ùo³ßf«î®º»ê.Ô˜Wc^y°(tQè¢PhwªÝ©v§À{ì–²”¥¦þ­û„¸à‚ Xt³èfÑ _i|¥ñ˜·wÞÞy{¡Ý÷í¾o÷=ìÛ¸oã¾°Ìj™Õ2+HÚœ´9i³©ÃÿwR“˜”E€E€Ev*ìTØ ý ý ýŠ>·Ž·Ž·Ž˽–{-÷‚G+V­ ¹¾¹¾¹äoäoäoàÙgwžÝ'œpJØ–°-a ëw¬ß±>Ô¯Y¿fýšà´Åi‹Óu”u”u¡ÐFhóó\²G²G²Gà¦vS»©Án«ÝV»­àSϧžO=°=c{Æö Ø4³ifÓ èOÞ?ãÉ"‹,}!ûBö899ÝY»³vg¡ÂË /+¼„w5ÞÕxWBû†ö í Õ/T¿Pý”oZ¾iù¦péý¥÷—‚ØIì$vë‰Ö­'B5u5u55t›ÕmV·Yà]Ï»žw=˜m6Ûl¶4ŸÐ|Bó?áy¢äÞɽ“{ n,¸á[÷†o…é›§ož¾zžìy²çI°ëm×Û®·©»$¿¦Øž(ö´rlåØÊ.\ÆZÆZÆZ0ëóYŸÏúÂÎ… ûˆ_0+0‰I©VªVªV‚ñ¢ñ¢ñ"†††¿·9rà Oxœæ4§‹>VÌRÌRÌÍ1Í1Í1– K…¥ ˜ f‚…ŽBÇ÷ÚË$“Ìÿ!  2‡‰ÃÄa@DüþýCÄ1ø–où´Ú@m dXdXdXÀ¥ KA—‚ ìUØ«°W”””W-®Z\žò”§ ¼^ /ß‹ÙAÖAÖÌ/š_4¿òÁòÁòÁÜ8%K–< œXpbÁ pîãÜǹÌè6£ÛŒnàUÞ«¼Wù?®¿OF1ŠQ ôåôåôå3Ì0ûëc¸®:Øö´íiÛD ÑB´ñˆGEÝj 5…x\þqùÇå!ñbâÅÄ‹>>Ï ž<‡ O7<Ýð¼Ëy—ó.#FŽ9b$Xϰža=ã¿·cìgìgìo¾yøæ!„Ž: Ó Ó Ó><§zƒzƒz„e†e†e‚¦›¦›¦¤f¦f¦fÂãÝw?Þ Y‹²e-ú íD†E†E‚¶¢¶¢¶â‡çû¿ô§ô§ô§àäô“ÓON‡%–4ZÒÂtaº0DÝŠºu rå Ê9›s6çl†'ž4zÒË$–I,óÇç2a6Âl|ñú‹×_¼†vªvªv*X¿yýæõ›!©JR•¤*|¿¿—TÀ$&¥LU¦*SA1C1C1ÔMÕMÕMßÛ`‹Xºµºµºµpiÿ¥ý—öÃÆÚko¬ Õª;Uw‚ªNUª:A|ëøÖñ­!{{ööìí HP$(@;[;[;Â߆¿  :G£Î"ÆFŒûó\ú®ú®ú®þMø7á߀ú ú ú SdZ™V¦…sÌ0Ì.˜]0»ðÛÛš Í…æpçÛ;ßÞù&4vÒXÈÈÈÿ€3ÚŸ$NMœš8Ö·Yßf}H©–R-¥älÏÙž³&VžXybe¸_ÿ~ýûõ‹¾§î®î®îþ í4Yßd}HÙ›²7eï‡çû¿^}=öõXø¡á hÍÆ4Ól (.(.(.À†‡nxaaaPX¢°Da X2uÉÔ%SápÂá„à |®W¡ŠPÚNh;¡í¨ìXÙ±²#ëƒõÁz064646üóúÿÍD‰Ä„²m²m²mDqx‹á-†·ÅgvÏìžÙ}®ë©ë©ë)Šíš´kÒ®‰(Xx`á…¢˜:'uNêQTOSOSOE£³ÑÙè,ŠimÓÚ¦µŤ½I{“öŠ¢¶¶¶(VVV‹b†K†K†‹(&6Il’ØDó6çmÎÛ,ŠbŠ˜"¦õklilil)Š¢˜°?aÂ~Q̹Ÿs?ç¾(ªû¨û¨ûˆbRfRfR¦(þÿèD1÷uîëÜ×¢˜¼0yaòBQL L L Em¤6R)Ši÷Òî¥ÝÅ„û ÷î‹bá±Âc…ÇDQwVwVwV“&-LZ(ŠIm’Ú$µÅœM9›r6‰¢ÚWí«öÅĉˆbúÓô§éOEѸڸڸZ+Œ+Œ+D1saæÂÌ…¢¨~¡~¡~ñûÇ%µIj“Ô&¢8Âi„Ó'Q Õ„jB5>Þ×ú\ës­(¶®Ûºn뺢˜º+uWê.QÔ½Ö½Ö½EãcãcãcQ4*J£R c c cEјhL4&Š¢aƒaƒaƒ(þÿI-¢(º‰n¢›(jçjçjçŠbʸ”q)ãD±pXá°Âa¢¨› › › Ší´_Ð~(žÕžÕžÕŠâ‹/_|ùâKQ\}ýõõ×EQ3[3[3[µîZw­»(¦ÌJ™•2KuF§EýBýBýBQÔ«ô*½Ju t t D±°baÅŠ¢(n·Š[ûq¸òêÊ«+¯D±­E[‹¶¢˜••%ŠúîúîúŸŸ/ŠêkêkêkEßùùÈÏG~.Š+ W®(|¯Áâq„(êúèúèúˆ¢.R©‹Eñ…øBü€ßƒÿ>¼N}úZGdŒÈ‘!ŠÏw=ßõ|ׇ·û¡¤çÀ$&¥ V+ƒA±]±]± ‹>Ïœ58k0äÏŸ7´3µ3µ3ÁéŠÓ§+@s™Ë\pÄÇ÷;èE/zýÑ~”ý(ûQÿ=—pV8+œ}oöÜÿõ¯kÍ1Çüú±šd5Éj0‰IL*úùÏòùãÑ][º¶tmù ý}Í×| Å)Nñ÷î‡ïMzù£Vzx÷á݇wÁæÍ›P>¿|~ù|@… ÕïoW8"Ž@º:]®†ã¾Ç}ûBêÝÔ»©wÁ­§[O·žP£VZ5jÁÚvkÛ­mƒÞ z3è Ø¼±ycó–]>vùXøÊî+»¯ìÀîÝ»°lð²ÁËàɃ&š 5î׸_ã>6‚`êáêáêá°ïľûNÀwÜå¢ËE—‹÷÷÷X¯_¯_¯‡>¹}rûäÂcÝcÝc¼5kþÖj ©1¤Æ¸—z/õ^*tËè–Ñ-êQzÿaÿ jÔ,¨ Ê=(÷ ¼¹øæâ›‹púíé·§ßB½zõêÕ«›'ož¼y2ÔíR·KÝ.?^øLøLø ¸Ìe.Ù’gJž) Ï&<›ðlò y†<¨+Ôê ÐtRÓIM'ñï+ÿ+§rNåœÊAåî•»Wî7ÇÞ{s,T¦2¦|)€t QbRªöªöªö`uÓê¦ÕMÈž1<ã½÷BFFFÀ€ 8¥íKÛ—¶};};};S§ÿç ¯^5¼*”M,›X6är¹Ã‡·+v»ˆ]ÀQî(w”CÇÄŽ‰¡ç’žKz.“º“º“:ˆoß"¾$OLž˜<Òf§ÍN› ž{=÷zî…$ß$ß$_Hû:íë´¯¡lç²Ëv†Ä°Ä°Ä0Hë›Ö7­/ÉB² â,q–8 ¬{[÷¶î ¥«–®Zº*ø ñâ3šššÀ{½÷zïõà‘à‘àQ´¯2P¨ „le¶2[ ]övÙÛe/¸ôvéíÒŽ|vä³#ŸËXƲ_ß‹G,AÍ…5Ö\g=Îzœ… À À @ðí3Úg4hNhNhNÀ[ÞòöÚ‘5‘5‘5ØÒ±¥cKÃvq»¸]„N­;µîÔík´¯Ñ>ØÔaS‡M svæìÌÙ>~^Ó½¦{M‡èMÑ›¢7a¢a¢aâŸñøÛHLbR?Ý[q©íRÛ¥6$4NhœðÞÒ@nƒÜ¹ ‚^e{•íU'5NjœŠ4Eš"ÍÔéÿ¹ FŒ. –÷-ï[ÞÿÎ%—\f3„ P+Ô 5xXyXyXëv×í®Û!lGØŽ° ?&?&?V´2‹¬™¬™¬Èòeù²ü¢96²ê²ê²ê Ë’eɲ@ rAd“M6 F„§ÂSá)ÈæÉæÉæìºìºì:(æ(æ(æ€|“|“|Èâdq²8-—-—-™ dÈBe¡²PPŒTŒTŒû>ö}ìû@Áð‚áÃ!ß5ß5ßöoÝ¿uÿVØê·Õo«_ÑŸ +V*¬ …ƒÂd2™L&³âfÅÍÞ;µ–Õ•Õ•Õ¡•ÐJhõóÃ(û^ö½ì{H*–T,©Ä;wžþðô‡§?@˜S˜S˜dÄgÄgăÖMë¦ý·ð´ð´ðÍ(Í(ͨ¢5EME*`’‚S}§úNõ!½szçôÎü{ºøŸ%ýUú«ôWðLùLùL ù.ù.ù.¦> [ÁV° kUÖª¬UB?-ÙîtCŒ!Æ…ã ÇŽËE–‹,1ĸãŽ;`À€á½ïÿ´–ÒO?wÅWÀO<)š…ú¯zšÍŠ%J& “„I] ¡UJ¡ºP]¨þÞ~ütIu Bo¡·Ð¬vXí°ÚÖîÖîÖîEº]„.@*©¤5©IMÀk¬ßk× +¬Š&SüÛO‹Nÿë¿Â&a“° Ìû›÷7ïÅ›oR¼ ø·ôoéßV”ZQjE)p\à¸ÀqÁ‡[v¿ì~ÙýÀêÕ« «)«)3áâÉÒ=0ÉGÁ©¯S_§¾E³ü ŽGƒcÑc`”¬ˆ¬ˆ¬Øê¿Õ«?óŒyÆ<è¤î¤î¤†ò”ç?=Îôÿ'À¹‚sç Î#Î#ξZñÕŠ¯V€ù[ó·æosœVÿ*þUüáx‹ã-Ž·m€6@ªÛªÛªÛ¿¿]Y_Y_Y_044„ÔàÔàÔ`xUñUÅWAë¤uÒ:Aý®õ»Öï W_9|å0Äý÷cÜ!fˆ"èlu¶:[ÐtÕtÕt…üþùýóûƒ¶@[ -€\÷\÷\wÈ[˜·0o!h{k{k{CîÊÜ•¹+Á¬—Y/³^ü}ò÷ÉßûFï½k–ö–ö–ö ÍÖfk³![›­ÍÖB~çüÎùAÝAÝAÝ “ “ “@­SëÔ:PÇ«ãÕñ ôWú+ý¡íöÛ>üõã¯ÈWä+@¨NT'Bî‹Ü¹/À¢¼Ey‹ò >ª>ª> y»òvåí*ZjMSBSBS¢h%”â)ÅSЧ@ɧ%Ÿ–| š]š]š]à;ÕwªïT0a>Â|())ýæaú¹PB …—?¼üáåPñfÅ›o‚,^/‹7Ñ/) Ÿõ/¦‹ ‘@Þá¼Ãy‡á¦æ¦æ¦> ø,à³PÌTÌTÌüãú :"t-~´øÑâ0®æ¸šãjBIyIyI9Èmä6r›_ÿ¾²©²©²)D_޾}ö]ÝwußUè0¾ÃøãÁÜÏÜÏÜï7Çùh94uhêЮE^‹¼ ö{ì÷ØïRÅK/Uü÷·k¾Õ|«ùVJ ¥„R?;~vülHذ!atxÖáY‡gàââŽeË:–…ènÑÝ¢».^¯‹³<³<³<ð¨êQÕ£*ö(ìQØr&çLΙ ŽqŽqŽq@;ÚÑòïæßÍ¿ .“\&¹L‚jG«­v2_g¾Î| 9írÚå´y®}ûômènÓݦ» Ø×µ¯k_ׄ¿¨¦ž)‘ˆ¢(&ßK¾—|OVX}`uQŒ¯_'¾Î×¾¡‚¡‚¡‚(îºèþ¡¢ØÐ·¡oC_Q|àøÀñ£(ê¾Ò}¥ûJã£ã£ã£EñAÞƒ¼y¢øhΣ9æˆbfFfFfFQ{׺\ër­‹(Í š4K³weïÊÞ%Š999999¢ø8ûqöãlQ|äôÈé‘“(¦OLŸ˜>±èûê[ê[ê[¢øÂç…Ï Q|äûÈ÷‘¯(¦îNݺÛÔ£QäŠß¿+~¢øí™oÏ|{F“£’£’£LJòWÉÎÎÅ9žs<çxŠânïÝÞ»½Mªˆt QòQ°«mWÛ®6˜{™{™{Á»­ï¶¾Û n¸ñG,V®wÑ»è] gwÎîœÝ ®¤®¤®)))`ˆ6D¢áüŒó3ÎÏÙEÙEÙEˆ²²²y;y;y;˜7#nF0“™ÌŽp„#`L7¦Óá»ñßÿn<< (^®x¹âå ÷xîñÜãаIÃ& ›Àžˆ={" yZò´äiàïïÁ‹‚/‚I²I²I2°ïeß˾ׇîýï×(¬QX£0Í Í Í„UçV[uÆu×q\Gp(áP¡ć÷#ù¸h7h7h7À¶ÛlkšéšéšéÐѦ£MG›oÿ"Mâ|”ã•ã•ãÁù¥óKç—ðÎæÍ»?ð/ŠÙ5³kf× Bó Í+4‡âæÅÍ‹›Cƒ· Þ6x æÌ/˜_€Ï~Öð³†Ð³AÏ=­ ÷°ðaáÃBP[«­ÕÖ L¦ S‹ÚÿÿàBˆWˆWˆWÑšŽA“‚&M‚:)uRê¤@FDFDFœXsb͉5Т°Ea‹BèœÞ9½s:<]õtÕÓUµ"jEÔ SJÑ,Ѿ-ú¶èÛ¬úXõ±êó×Í_7¼{øîệÞäã="{DöX9`倕 zYô²èe0²pdáÈB°êhÕѪã‡÷óG‘ ˜ä£ðÓ"¼Û1¶cìŸñå_³BĦbS±)…‡ÂCÈ’?$œmv¶ÙÙf°adžvÀ™ïÎ|wæ;0d2 ™ÀZÖ²–Ïbû‰bˆbˆbŒüvä·#¿…hM´&ZCË -7´œ{q«§«§«I±I±I±p~Íù5ç×Àasð0x< `égégùÝK³r²r²r‚oªSý›êàiãiãi3÷ÌUiýå€IDATÜ3s\mqµÅÕ ¢¢b괒߬u¨Ïj=«õ¬L[3mÍ´5 ~¤~¤~“ëM®7¹T|PñA¦ûsÒ%DÉGÅk­×Z¯µp´ÂÑ G+€æ¦æ¦æ&˜70o`Þàèà_Ó­…“ÂIá$ÈåÎrgx±êŪ«`ÿàýƒ÷†}†}†}ݺ)t„ههÙSôdék^ó„ÍÂfa3××ׇ»‡»‡;l»}ìö±°6mþÚ|صe×–][ v`íÀÚàÚõ‡khaÓ¦… Ô]ZwiÝ¥ &‹Éb2BP`êÑø9‹H‹H‹HRcH!5à²þ²þ²v[í¶Úm7ÎÜ8sã ô¼ØóbÏ‹PnB¹ å&€`Œ‚ÑÔé%?-å’x5ñjâU8²ëÈ®#»àþøûãï‡Vlµ:FtŒèæ«ÌW™¯2uè_'0ÉGÅí”Û)·S;/w^î<ÈõÌõÌõó«æWͯþþvËËËáõþ×û_ï‡ôé5Òk@D»ˆvíŠf‘Y¶:lu®j¯j¯j!óYæ³Ìg «¬«¬« ñYñYñY='zNôÈj™Õ2«%ÄLŠ™3 ~¼ðã…/€÷7Þßx9>9>9>P·kÝ®u»‚S-§ZNµ ¨kP× ®práÉ…'BZBZBZ·+nWܪ<¯ò¼ÊsPuRuRu2õ¨üœì±ì±ì14mÛ<ªøTñ©âk¬y°&̉›7'ªÝ¬v³ÚMÚ´;h7x•ñ*ãUdddL½Ÿ€=’08apÂ`8ûòì˳/áºáºáºÊ9—s.ç 3JÏ(=£4x{{óó·+|¤„Ÿfs˜:ˆDPP¡ BA·lܲqË`@ì€Ø±Pkx­áµ†ÿþv ‡ ‡ ‡àÍù7çßœ‡ôŽéÓ;‚G7nÝÀåk—¯]¾†7Îoœß8Cþ½ü{ù÷ÀÂha´0‚z¬z¬z,”,Y²dÉ’UUU·2neÜ‚2—Ê\*s ò®ç]Ï»ÁÁÁ ¦¦žÇ={+o+o+oÐxj<5ž98rpä`ÐÓÓ»ZvµìjA©K¥.•ºŠ—Š—Š—¿¿ÿj¢¿è/úCäÊÈ•‘+áÇÙ?Îþq6< xð,<î{Ü÷¸_~ø5øùúùúù‚Ç#G€)LaŠ©÷âïë§•@^Ž}9öåX¸t5èj¼zùêå«—Pfq™ÅeCÛFmµmU ªT)ÅFÅFÅFS§ÿßILòQZd¹Èr‘%_Q|EñÐop¿ÁýþÀ4Jþ"ÿZ1"~füÌø™p½Ìõ2×ËÀ¦wšÞi šKšKšKà£÷Ñûè¡nߺ}ëöŸhŸhŸh°³¶³¶³3;3;3;SïŒééãõñúxÈmŸÛ>·=¼Ùõf×›]p·ÔÝRwKÁËô—é/ÓÁØÂØÂØjøÖð­á óç7ί¯¯ݑݑÝ1õÞ|8é¢ä£ä;Ðw ï@¸SâN‰;%@ Å@® W…«¦N'ùÍòÉ'¿h%¨©=R{¤Bûí_´ѾѾѾp×å®Ë]8x4ðh €Õ«V# òóÊÏ+?‡r5ËÕ,WÊ>)û¤ìp w w ÅIÅIÅI¥ËÒeé@*PÁÔ;ÿä‘GˆKÄ%âÐ7×7×7‡Œ#G2Ž@t‹èÑ- ºrtåèÊ& “…É ¥iJÓ”¦ 7È r”Ï-Ÿ[>ú}Õï«~_AùoÊSþ°yeóÊæ°žõ˜pÍÂ?‹t&ù(Å ˆ3æ´šÓjN+˜×n^»yíÀMå¦rû€×yH>niÑiÑiѰªÎª:«êÀ«V¬ ð@àÀ®LW¦+!;<;<;T^*/•8vsìæØ œÎFg#xÌò˜å1 œO:Ÿt> V3­fZÍ+K+K+K(vªØ©b§@¨ T‚ʨ2ªŒ 4Wš+ÍAî(w”;‚l´l´l4°Ÿýì¶±m n7Š‹Þ(]ت°Ua+йëÜuî 5jZ#¨OªOªOB~Ÿü>ù} Ï<Ï<ÏÒ§/N_ o÷¿Ýÿv?$ïNÞ¼2¾Îø:ãë÷.a÷¶èmÑÜ´nZ7-TJ¬”X)¼Ö{­÷Z%•j·:Üêp«ìµÿÕþW°Î|œ ¾øâkêp’_eèeèeèÅ‹âEö6ØÛ`ohôºÑëF¯¡×Â^ {-‹5,j˜:­äïJº„(ù[¸æwÍïšVVVÁbíbíb-X<³xfñÌÔé$?É–g˳å°c÷ŽÝ;vó‘ÏF> j¨= 6ܸpd² Y†©ÓJþî¤Kˆ’¿¿4¿4¿4ÐVÒVÒV‚p‹p‹p S§’0‹YÌ‚ð’á%ÃK´sÓÎM;iáiáiá0·îܺsëBƒ³ Î68+.ÉK*`’¿ûûûðûÚïk¿¯áJ•„+ ¦Nõé2Äb ±pºòéʧ+ÃÜ7sßÌ}µÎÖ:[ë,LµŸj?ÕÜtÿÑýGS§•üSILò·Òâz‹ë-®Ã‹¯^|õâ+ˆ···7uªOGæúÌõ™ëa퓵OÖ>£ùGóæÃ°Eà [}žõyÖçû¶Ø·Å¾5uZÉ?4‰Cò·âeçeçe¥›—n^º9\ztéÑ¥GЇ>ô1u¸°°ÇaÃÃúòë˯/6É6É6É0wèÜ¡s‡‚[[ÛGøúÉ?›t&ù[‘‘‘Vç[ounM¼5ñÖDȪ‘U#KšÍö‡1Œ1Œ1Œ³ÂYá¬ó‡Ì2Ô´©iSÓ¦®˜ºbê ©pILK:“ü-UϪžU= ìËÚ—µ/ v^Øya't¥+]Mîo,«]V»¬v°cÊŽ);¦À ^ðºl財ˠ^B½„z < LVò©“ÎÀ$KÊ)Ê)Ê)ÐqLÇ1ÇÀ…úê_¨_ô¢JÉoI$‘¾6|møZ˜63lf¤&§&§&ÜÝsvÏÙ ²Y€ „’BI¡¤©CK$ÿŸTÀ$k5êÖ¨[£.¸Vq­âZ~Ü÷ã¾÷™:ÕÇϰааÎêÏêÏêažfžfžª÷¯Þ¿z˜ñÍŒof|îiîiîi¦N+‘ü2©€IþÖ”£”£”£ Ëø.㻌‡ËV—­.[ÁÛÀ·oMîã““—“—“Zmhµ¡_ ¾|†nºmè6ècÕǪ˜G›G›G›:­DòŸI÷À$ÿUü«øWñ‡*û«ì¯²‚c‚c‚c`\»qíÆµá„pB8aꔦ k]Öº¬uå~å~å~˜ódΓ9O TX©°Ra¦N)‘üo¤¥¤$ÿ(ñ ãÆ/„éÆéÆéFºh袡‹À?×?×?×ÔéþB (àÚêk«¯­†íQÛ£¶GA½üzùõò¡w`ïÀÞ`ÕÓª§UOS‡•H~©€Iþ‘Ž>;úìè3¸ìzÙõ²+Ìo2¿Éü&`ûÒö¥íKS§ûó *T0ô<Ðó@O¸VöZÙkeáËU_®úr4 jÔ4dŸÉ>“}fê´ɇ‘îIþ‘Zlu²ÕI°Â + ¸pÿàþ@Aü_Çïïïókͯ5¿<™ödÚ“i0½âôŠÓ+BóÕÍW7_-.É?‹TÀ$ÿHŦ›Zl* \>pùÀåpsãÍ77ÂÃ!‡<bêt€€‡m¶}Øfœ™qfÆp¼êxÕñ*Ìi0§Áœà¥ñÒxiLV"ùsHLòæ½Ä{‰÷èгCÏ=akÍ­5·Ö„Ôõ©ëS×›:ÝÿNWUWUWô;Ðï@?XýzõëÕ¯¡½s{çöÎ0ê£î‚Ý»%vKLV"ùsI÷À$Ÿ„¼¼Â.Òòû’O(‘|Âv^ÜyqçEQ¬Ø¤b“ŠMDÑÒÎÒÎÒî§Kê¢Øù]çw߉¢.I—¤KúýýÄjcµ±ZQüÁ민DQk§µÓÚ}®Þ«Þ«Þ+Š{ö$ìIÅÞ½{÷îÝ[/n½¸õâVQ4è :ƒÎÔGK"ù¸Hg`’OŠAcÐ4pyÑåE—ÁÎY;gíœáÂ…?‚ü¬ü¬ü¬¢íŸ¯z¾êù*xÓåM—7]~Gþƒ?l4Ûh¶Ñ ¾ÞûõÞ¯÷™îgºŸé™U2«dVe6Ël–ÙÀ­·zÜêSÚOi?¥=4Øl`³ SÊ”2¥©žDòq‘ ˜ä“¿*~Uü*X¸`á‚… àj—«]®vcŽ1ǘóóíc41š Ü ¼x/ðïïBÞ…¼ y°]³]³])uSê¦Ô…i‹¦-š¶F6ÙpdCr…\!f—Ÿ]~vy¨Ø¥b—Š¿£`J$Ÿ©€I>)%{–ìY²',,\X¸°ºýÐí‡n?€EK‹–-¾½nnnܸpã  õÑúh}þ{?q;âvÄ퀅UV]X’‹%K~ï^Ú ûö/ì!ì밯þ†~…ý û‚Ë&—M.›L}”$’¿©€I>)2™‡Ìj©k©k©aóÍÍ77ß„E3ÍX4ʩʩʩ~þ½ëý®÷»Þ’û%÷Kî÷ëíë¢tQº(ø®Áw ¾k·úßê«ÿ¯oÿ¢ÿ‹þ/úÃfÕfÕfè†ë†ë†›ú(I$¦¾ '‘| ^/ƒ—(Þ»xï⽋¢Øåz—ë]®‹¢ª“ª“ª“(ZDXDXDˆbp\p\pܯ·sÊþ”ý){Qt®ç\Ϲ^Ñd_û¯ÜFn#Åé-Ò[¤‹bTí¨ÚQµM}4$’¿éu* ‹”EÊ"¡6µ© luØê°ÕvµÞÕzWkX¡_¡_¡‡³Ég“Ï&ƒïQߣ¾GA~E~E~dÝeÝeÝaÑùEç‡TÿTÿTO’O’O›m~´ù|Úù´óiM.5¹Ôä 8pj-­µ´ÖRp½çzÏõž©†Dò÷ ­Ä!‘üÆPc¨1®Í¾6ûÚlzüéñ§áݬw³ÞÍ333p¾á|ÃùÄœ9sªÏ«>¯ú<¨û îƒº YR³¤fIPE^E^Ev_Û}m÷5(š*š*ššz/%’¿'é L"ùd•d•d• rJå”Ê) -§-§-É’'$O(ÚNh$4ÁÖ[7nÝmÛ¶{{{ †bL½7É?‹4‰C"ù ÌÒÍÒÍÒÁ]ç®s×ýüsß§¾O}ŸB§N œÀÞho´7".‰äO$0‰ä7°}nûÜö9tÞÚykç­à·Ëo—ß.èû¤ï“¾O j­ªµªÖ‚+AW‚®qµqµqµ©SK$ÿlR“H~‹:Ô¡¤K-–Z Æ 3lÌ0ؾûþíû¡çþûw†³¯Ï¾>û¾Ÿôý¤ï'ÑÛèmô6ux‰äŸIº&‘üÙ Ù Ù E«Ø·±lcÙÆd‹d‹d‹þ½/Ml4±,j¿¨ý¢ö`ìlìlì ½Êö*Û«,È£åÑòhSïDòÏ I$¿Á»ë﮿»â#ñ‘øJµ.ÕºTëŸoWþzùëå¯Ãäk“¯M¾Wî]¹wåì[¹o徕`œeœeœe꽑Hþ¤&‘ü!Ž!Ž!ŽàÑã‡G°ßa¿Ã~ǯoï“è“è““§Ož>y:\³¾f}Íö^Þ{yïe0¼1¼1¼1õ^I$oR“Hþ“<à„- [¶*­®´ºÒÿ09ÃÇÖÇÖÇ&M šW¯:_u†={2öd€þ„þ„þ„©wR"ù{’ ˜Dò¤Y§Y§YCÒñ¤ãIÇ¡r½Êõ*×ûßÛñÖxk¼50¹ë䮓»Âõ×\{îm¸·!’ ɆdSï­Dò÷"0‰ä?ˆOˆOˆOù!ù!ù!p}áúÂõÅïoÏû ï/¼¿€)›§lž²n†Ü ¹{÷î CCCSïµDò÷ 0‰ä?¯^5¼*¸‡¸‡¸‡€ME›Š6?¼]¯¯¯˜´rÒÊI+á†Ý »v°óóŸïüô‚^Ð ¦Þ{‰äã&M£—H~xN<'žƒW‡^zu|ùó=Bº.¤ÿqýxô:éu¦¼žòzÊkXØea—…]@4ÍEs跬߲~Ë@1N1N1ÎÔGE"ù¸Hg`É/( „ê'ÔO¨>Ž>Ž>Ž^žžžžžž0íå´—Ó^ƒÚj?¨ ÛvoÛ½m7Ö)¬SXÇÔGE"ù¸HL"ùÑ;¢wDïq´8Z å–;XîàŸßomm-L)>¥ø”âðØõ±ëcWØRuKÕ-UA×Z×Z×úÃû‘Hþ ¤&‘ü‚ȶ‘m#ÛBñ‚âÅ ÀªU«>]ÿ¥ƒK—†©g¦ž™zž>+|V›£7GoŽ]G]G]GS%‰Ä´¤&‘ü‚ˆÒ¥#Jƒ÷NïÞ;Ax&<žýõ9< L7Ÿn>ÝÂ"Ã"Ã"aô Ó6LÍ<Í<Í×|×|×|S§ú¹3JÌ(1¦1ý‹é_À;Ïwžï¶úØjH¾ž|=ù:ÄFÄFÄF@a¥ÂJ…• jPÔ ¨A:-tZè40L3L3L3õÞÿóIL"yOÄ܈¹s¡Ô¡R‡JÕDÕDÕDS§úu.'\N¸œ€©-§¶œÚ%6JlkV­YµfäÅåÅåÅ™:¥é$NMœš8Ö7Yßd}HÙ›²7eï¯ooüÑø£ñGØýl÷³ÝÏÀ5×5×5üT~*?\¸p!ï>¼ûðn0¾6¾6¾†[]ou½Õ&Mž4yÒdÈ7Ï7Ï7½›ÞMïºAºAºA¦>ÿµúä­È[‘·ÂÔ)ƒ…,daÑ¥;ýhýhýhÐÐЃ¿Áßà_´¹ÑÅèbtCˆ!ÄÆÒÆÒÆÒ`H4$¡dÓ’MK6…½gôžÑJl/±½Äö_è7Ž8â@7W7W7Â߆¿  ö)ö)ö)àÝÈ»‘w#h×®]»ví`àùçž•F¥Qi ìÁ²Ëq›¸M܆††ììì·ÖÞZ{kíÏ»5L6L6LÝxÝxÝxˆÄÀT¦2 rƒÜ ãyãyãy08œ N ö{Š=A<"€1ÖkŒÒH#ÍÔƒø×‘VâH€¼[y·ònAâ›Ä7‰o ýÕöWÛ_5uªÿ³“³“³L¹6åÚ”k°äØ’cKŽÁÊw+ß­|£¿=¬Y²"²›e7Ënfê”?§V+‚AµEµEµtɺd]2ôËì—Ù/lWÚ®´] Û÷oß¿}?¸ßu¿ë~^Žx9âå(m^Ú¼´9Ô‹­[/<==!a{Âö„íÖ7­oZߟ÷+< ¡jvÕìªÙE…¦Ùºfëš­ƒ*ùUò«äC‰üù%ò!tvèìÐÙ ÷Ð{è=€zÔ£ˆÖ¢µh ¥–>Zú(8Tt¨èPšUnV¹YeðîéÝÓ»'lqÜâ¸Å,&XL°˜Cï½;ô.Üñ¹ãsÇÛ>¶}l VVVðúÄë¯O@Ó+M¯4½¥^•zUê”’•’•’Amm-ÈÊÊþ‚î?Ò˜D¤–L-™Z,[ ¶ VXaeêPûåöËí—ÃÄL\Kß-}·ô,ûvٷ˾…±cÆ€Ým»Ûv·M¶ˆ¼­¼­¼-È/É/É/™£™£™#x{{{{{íŒ[·2À¸Ö¸Ö¸Š/v¼Øqðpõpõp///(´)´)´ÙjÙjÙjGá—–+MiJƒ¼¢¼¢¼"ÈRe©²TPÌQÌQ¼7 U~J~J~ doeoeožô¤'N8á@&™d‚¬¤¬¤¬$ÈnÉnÉnbšbšbˆŽ¢£è/_$¾HE{E{E{¸±ýÆöÛ!O§ÎSCš,M–&ÅeÅeÅepðtðtðïmÞÛ¼·P\(.‡2”¡ PƒÔ(G9Ê™zôþ:Ò˜D¼±}cûÆÜî¸Ýq»£-F[üîý7öSì§ØO‰§&žšx d2™,^¾xùâåV-­ZZ5S§|9rª Õ„÷réŽêŽêŽ‚r°r°r0÷…ûÂ}àw¸DIä{툈ˆ€+®¸žxâùú5bÄ” %€ò”§ü/lç‡~€%–X¾÷½JT¢ B… ¨K]ê_ð_ðŒRF)£ÀáÃ!‡CPêi©§¥žÂÔJS+M­­ýZûµö½­ÞVo ç8ÇB )|/G3šÑ Ä(1JŒ2õ ýõ¤&ù´me+[!6/6/6<ö{ì÷ØoêPÛ½¶{m÷Âønã»ï* •… ù/ò_äÉ’$?0uJþ}FT°¾`}ÁzHtNtNt†§Ýžv{Ú ê¦ÕM«›ú[ú[ú[ ‰×Äkâ!o^Þ¼¼÷V&É_™¿2%hiiAÞ ¼Ay¿4ð_Ï}¬,XY°454545 §tNéœÒïµw2ÿdþIÐè4:r×ç®Ï]ùB¾/€Æ_ã¯ñõVõVõVϖϖφ7¯Þ¼zó òÆåËþËý—û/‡ìçÙϳŸƒSG§ŽNÁk¤×H¯‘`û•íW¶_AAnAnA.888‚ÎKç¥ó*ÊsnÒ¹Iç&ÁÅÅèÎéÎéΙzðþ:R“|Òôõõ!µWj¯Ô^à–ã–ã–cêT>«0«0«0øVøVøV§µNkÖ¢΋:/ê I7“n&Ý4aÀa c¼K}—ú.ÎÖ8[ãl (·©Ü¦r›àKÅ—Š/mžmžmŽ6:Úè(äÌÏ™Ÿ3Ä@1P „8×8×8Wðì?Ø0®®®ƒf‚f‚fÂ{ýEE$˜'˜'˜C-óZæµÌAg­³ÖYCR÷¤îIÝA}D}D}ê¬w°ÞAxÓéM§7@ã¨qÔ8B@§€N «BV…¬ Ðoa¿…ýBªsªsª3D*#•‘Jä6Èm”Ú]jw©ÝpÜý¸ûqw¸©¼©¼©„Ä«‰W¯‚ýEû‹ö¡üòÊ€´-i[Ò¶Å6¿`~ÁüXÞ¶¼my„·Â[á­ Çí/&ˆÿbê ‰)dïÍÞ›½ÆÖl=˜4`Ò€IÀëš×5¯k¦N÷×)))7VÜX¢»Ew‹î'N„RcJ)5æ¯Ë³±æÆšk³7ÏÞ<{럭¶þYÑl?‰¤30É'.¾X|±øb ‹EÈ" DŸ}Jü…«Î,,ª[T·¨Ãn»=ì6øøùøùøÁü”ù)óS æ`ÌÁ˜¿`v›®º®º®:$¸'¸'¸CfÌ™5 þËø/ã¿4õQ’|l¤&ù¤%,NXœ°ìûÛ÷·ïæ:s¹ÎÔ©LǼ©ySó¦ðu·¯»}Ý ª}Uí«j_Á‚“ N.8 Ñu£ëF×ýóúW Q Q ѧGŸ}Vy®ò\å Îûœ÷9ï3õÑ‘|l¤Kˆ’OÚÞ‹{/šDM¢Æ·ßf|S§úx¶+lWØö4ÞÓxOc¸%»%»%ƒ‰ &€ÏTŸ©>SMRò©’ ˜ä“¶$vIì’XpÿÌý3÷Ï Wx¯ð^á¦NõñÑWÒWÒW‚ý®û]÷»Â¥Ç—_z ãÕãÕãÕPI[I[Ikê”’Ot QòIÒõ×õ×õ‡”)=Rz@©7¥Þ”zcêT/E¨"T =õ<Öó´ kÖ* ;,vXìOn?¹ýä#zZòi ˜ä“¤öQû¨}@Ý]Ý]ÝìŸÙ?³7Á—ÿnä¶r[¹-tëÔ­S·NÐéÇN?vú–•XVbY ¸·ñÞÆ{Mò?Å(FAÚÁ´ƒiA½\½\½ÜÔ¡$¿—TÀ$Ÿ$õbõbõbÐúj}µ¾`gcgcgcêTÂmá¶pÚ§¶OmŸ ½Žô:Òë¬ö]í»Únô¿ÑÿFS§ü¹änÉÝ’»Á²ÝËv/Û ObŸÄ>‰…ìÙ3²g@Úå´Ëi—!»0»0»2ÎdœÉ8©ù©ù©ùý6ûmö[0l0l0l€´i;ÓvBö‘ì#ÙGŠú1Ž1Ž1Ž´çiÏÓžCÒü¤ùIóAª Õ„šú(üsHk!J>Ié!é!é! /È Àî¼Ýy»ó@úóþÃû±>>>ƒVZ]huTUUaãºë6®Ý4Ý4Ý4h¶²ÙÊf+|ò1á B_ö{Ùïe?8uôÔÑSGÁ-Ð-Ð-BBBa›z›z›>?ÿùùÏσñsãçÆÏ!®G\¸`^`^`^S¾˜òÅ”/ŠfIÃü•óWÎ_ gJŸ)}¦4<¸óà΃;`±Ìb™Å2PÞRÞRÞ‚Á‡|,,-,->·ü]Hg`’ORÂí„Û ·ÁvŽíÛ9`}ßú¾õ}S§ú[ÊR–BÓÔ¦©MSahÈС!°£øŽâ;ŠÃé6§ÛœnÆÆÆ¦‹é½É{“÷&p r r ‚VlµÒÒÒ ×1×1×ê´¨Ó¢N èß7¾o<”Pf@™Ñ9£sFg°ìmÙÛ²7”ì_²Éþå•å•å™ã3Çgއ}vöÙÙZTiQ¥Eà8Àq€#\νœ{9"~Œø1âGSÚߟt&ù$¥¥¥¥¥¥½Ü^n/6° ¦NõÏÑ`QƒE ª¹ª¹ª9¬)XS°¦4Ý5Ý5ݡ㚎k:®Ù(Ù(Ù¨¿0˜ o‹·ÅÛÀ.v± ˆ'žx0Ûn¶Ýl;Økì5ö°´´e{e{e{à W¸ò^{æ˜c‚NÐ :PïRïRÃ1‡cÃ7^Üx¯^½zõêÈâeñ²x0V5V5VºÒ•®¦­¿/é LòIÊxžñ<ã98¤9¤9|Bo°ý«ù_ô¿èÆÅ‹'Ïž<{ò,°<`yÀ ?~0üð€l²ÉÔ¨QS´j½n¸öØcÿÞ÷þµØ/è@‡÷~þÓªó-iIKçÈsä9`wÐî ÝA¨{¡î…º óÄÎ;O„mªmªm*ð3úýŒ¦›©€I>I×2®e\‡;vš:Í?_ÕØª±UcaÂæ ›'l†Ëf—Í.›ÁŽå;–ïX:¿ÎÿÃûùoTíTíTí@6\6\6nõ¼ÕóVOˆH‹H‹Hƒ¼iyÓò¦AJFJFJFÑ÷\WÁU€”m)ÛR¶ÁË^/{½ìi7Òn¤Ý€ÜÔÜÔÜT0?b~ÄüÔZÿiý§ðÀû÷ox»àí‚· /$/$/ø†oøÆÔ£ò÷'0É'ÅXËXËX 2Ã2Ã2ÃÀe„Ë—¦Nõéð=ã{Æ÷ LÙ4eÓ”MðpöÃÙgÆcŽm8šo4ßh¾ùóúwhåÐÊ¡L·™n3ÝTN*'•uFQ#»ì>²;XU³ªfU­è{Íz5ëÕ¬ô•õ•õ•AB£„F  öòÚËk/‡n‡»îv”ÊeŒ4:|ó}ó}óámÒÛ¤·I˜˜…Aanà|0i%É'%§^N½œz0nܸqãÆÁØÃc= å÷—ß_þü°Uü¤øIñ“`IÅ%—T„K ,1FºŒté– – – ¦N)ùXIg`’OJ~©üRù¥À`o°7؃µ¿µ¿õ_péJòËܹ/r_S/M½4õd|Ÿñ}Æ÷°dÚ’iK¦AÖð¬áYÃMRò±’ ˜ä“¢NV'«“Aa«°UØ‚²Ž²Ž²Ž©SI\v»ìvÙ SN98å ˆb„ mÚ,´´NiÒ:™:¥äc#0É'E]L]L] ³³³Ai¦4Sš™:•ä'v‡íÛ† _OøzÂ×`wÎîœÝ9˜;k³ þtüéøÓ¦N)ùXH÷À$Ÿ”<à°'{Oöžì¢ÿ÷,KÁÔé$ÿ—ºP]¨.„Mi›Ò6¥Ax±ðbáÅ`Ü™qgÆÏž=<{˜:¥ÄT¤30É'E­R«Ô*0«bVŬ ˜¹˜¹˜¹˜:•ä×SSSÂðIÃ' Ÿ5ŽÔ8Rã,4_h¾Ð^.y¹äåS§”˜ŠTÀ$Ÿ”Ì´Ì´Ì4°ziõÒê%(&+&+&›:•ä¿QîRîRî‚þíû·ïßš››aщE'€ÝtÐÝÔ)%5©€I>)Yû²öeí›{6÷lî0F#Œ1u*Éo¥pR8)œ {Íî5»×„î†î†îX­_­_­‡Ëõ/׿\ßÔ)%©€I>)ù#óGæ‹Ý»-v›:ä÷’—‘—‘— ‹ ‹ ÜppÃÁ a»ùvóíæpüÜñsÇÏñ€ñ€ñ€©ÓJþ,Ò³à’OŠN¥SéT`;Ìv˜í0S§‘|°K\â4¤! «-V[¬¶ÀÊY+g­œ9êu޾¸ñÅ/n€r½r½r½©CKþ(Ò˜äÓðŒg<íeíeíeP-Q-QI7ÿÿqª‡V­ Ó¦9Ls€ž7¤NH:ðãÍoþxó7w#ù‹IÓè%Ÿ†§<å)ÈŽËŽËŽƒ¢²¢²¢²©CIþ*­=Z{´ö€rËM,7v;Øí`78üåá/ M#šF4CCCÐ6Ð6Ð6€=—÷\ÞsÚµlײ]Kp>ç|ÎùÜïOœ N'€F¡Qh Ñh4 h#´ÚÐöÑöÑöýúõ?‚q±q±q1€XW¬+Ö¹^®—ëA¶A¶A¶äUäUäUÀ,Ñ,Ñ,T¥U¥U¥AÕBÕBÕŠeË*–ŠŠŠ¦>ê>©€I> 餓‚“à$8ì°ì°ì0Ð~ô3u8ÉŸM1_1_1*S™Ê@%c%c%#ô~Ûûmï·pää‘“GNÂÁ7ß|a¶a¶a¶ð üƒòÊÃý~è÷C?h;½íô¶Ó!¾Z|µøjÛ)¶Sl'HYž²¡ö±ÏÔ{û¿“——Gq«:Vu¬ Þxã 4Jm”Ú(µh ÉÌ Ì Ì ?~0ü ‚NÐ :0ûÒìK³/AÛRÛRû kÞ%¿N~üb­b­b­ÀÜÁÜÁÜôãôãôã Ì2CÊ ‹uë,ÖAxÇðŽáÁº½u{ëö »®»®»Î!Î!Î!P©n¥º•ꂪ„ª„ªE³‚"¨¨_mˆ6DáïÂß…¿ƒ„* Uª@Ú¬´Yi³À6ß6ß6jm­µµÖVP¼S¼S¼‹4‹4‹4PQQÑOôýà¸ñ¸ñ¸®¤_I¿’cÛm?¶=”û¾Ü÷徇´6imÒÚ@\n\n\.˜ç›ç›çƒ÷FïÞ!£FFŒ|=ùzòu°Ùe³ËfˆeŲbYp½âzÅõ ¼ñvÄÛàQÆ£ŒG°\n¹ÜrùŸ?žqßÅ}÷Zzhé¡¥ðìÖ³[Ïn_¼_¼_.5]jºÔ„Î5;×ì\ZvoÙ½ew8Ÿw>ï|lé¾¥û–îpµíÕ¶WÛB¿½ýööÛ n­ÜZ¹µúßû“ ˜äÓ0„! ³$³$³$Ð5Ô5Ô5ñˆGE›•°*aU ¬[=¶z õ,ëYÖ³{£½ÑÞ}'ôÐw¤Z¤Z¤Z€ó]ç»Îw¡D¥•JT‚Y³f¢š¢š¢<ÜþpûÃíbL1¦B )üy<[[[ðjãÕÆ« ,(XP°j×­]·v]ÐwÖwÖwK[K[K[0¾4¾4¾šÒ”¦üûÿŒ-vYì²Ø¥Ž—:^ê8¤=N{œöjÕ ª‡{îu¸$=Iz’ôæœ?pþ@8juÔꨜ¨y¢æ‰š0?u~êüT0?n~Üü84Ûdl“±àÝÈ»‘w#‚„ !=^ôxÑcpŽpŽpŽøã‡-½gzÏôžðæ;Íwˆ/_*¾ × × ×AÍàšÁ5ƒAž"O‘K³J?:VÁVÁVÁÐép§ÃCýú!õC`×½]÷v݃éªéªé*¢¢¢ÿ þü/­hÅo(hR“|RÌôfz3=hvjvjvþÂJ”(A ƒÅ` ¥(*µJ­RƒÐDh"4|Ÿ|Ÿ|º Ý…î`6Êl”Ù(0‹3‹3‹0€ü{òŸó9Ÿÿ†€¹ä’ ¢¿è/úýù–O>ùÍŽË"‹,Èè“Ñ'£Äî‰Ý»v–ØYbg Hz˜ô0é!x·ónçÝ„>B¡È6É6É6ÊBe¡²s­¹Ö\[Ô;î¸ÿ 㔨KÔ%ê`iìÒØ¥±àéé ólçÙγ§ÕN«VW¹ÊÕ?!€äÕ….t×.®]\»À˜ycæ™篿vþ¬¾vúÚéÐwtßÑ}GC³‰Í&6›È¿_ƒôk¤&ù¤XNµœj9²ÏdŸÉ>ÃÏŸÓ AÂa°8À€º‚º‚ºˆóÅùâ|°ýÒöKÛ/Aì-ö{3˜ÁŒ_êK,A8*ŽéLçÿð_7„+Âá ÐŒf4£èÌí_÷n„@!PüñÇhG;Ún¸á„J(®®®5owÓî¦ÝM(ýªô«Ò¯ ÷W½¿êý˜77onÞ¼è^á»ã; a0$À¢v “ “ “ åZʵ”kà<Ñy¢óD0‹1‹1‹ùýã“Õ1«cVGXéºÒu¥+xùyùyùÁÀ–[l ªªªÿ¡éLg:ä¹ç¹ç¹ƒ:^¯Ž‡­[¶‚Ä^޽{~lûcÛÛB­eµ–ÕZ{ö8ìÝSwOÝ=.ú_ô¿è±=c{Æö„wï<Þy@¶¶¶?DŠ=ª(ïÛ}o÷½Ý*M¨4¡¼¼öòÚËk¿\ÄAâ qìóÞç½ÏG;Žv Ö X3`Ío(\?µÓXl,6†G=õxÔ£è’nìg±ŸÅ~öá¿?Ù²7do€9/缜óžÄ<‰yéŽéŽéŽ0qöÄÙgÃöÚhÿ^®ãâqñø{ílÉÞ’½å½v¶=ÙödÛ‡çû¿òÆæÍ [\·¸nqëÖ¬;€ìºìºì:¬{°îÁºpúóÓŸŸþ < < <`õ¦Õ›Vo‚Å“O^<Ä’bI±äŸï'uÏÖ=[÷,ôßÒKÿ-ðýÐï‡~?’;$wHîðëß“ÎÀ$Ÿ‡ë×®CNxNxN8–/,_XþßWáxŠúŠúŠúà\Ϲžs=¨ýCíjÿeÖ–Y[f-(½•ÞJo0>`|Èäò½’½’½.s™ËÐce•=V‚nŒnŒn «[¬n±º?ÏõÓ =K÷,ݳ4h¶h¶h¶€Õ«VÀhm´6ZÃRÝRÝRØ$Ú$Ú$‚í6Ûm¶Û`©íRÛ¥¶`×À®]p]ëºÖu-”¶-m[ÚTõTõTõ tÒuJ×ÉC&™<âããAõTõTõ,¶ZlµØ e¬ËX—±†uYë²ÖeÛN·n;‹òº§º§º§ÂÔˆ©S# ôªÒ«J¯®sëÿû¸<ïû¼ïó¾Y7²nd]˜,L& `®0W˜ÿÿJ Í…æBsð¼éyÓófÑtï … ÿ€×æXå[å[åðíöÛ®é®é®é`½Çzõ°¾b}Åú äîÊÝ•» rmrmrmàÔÖS[Om…6Û l3¬­­ßk§½k{×öžïÿÊé•Ó+§„V­Z>ølà3¨Ð£B =Àn¿Ý~»ý`ñÒâ¥ÅK°o3Þf<¸Wp¯à^žÖZÿi} ‚"€ TàO|ýPãìÆÙ³!,),), Žu:ÖéX'¬¬¬A%¨Õ{ã-­Ä!ù”<üâ῀ݛwoÞ½¦,LY˜–^–^–^Ù%²Kdè_п ¬{½îõº×P-¼ZxµpS§ÿúø–—X^by pqrqrq‚/=¿ôüÒó÷7Ow>Ýù4|YòË’_–ewewewpÒ:i´P{zíéµ§C°K°K° Ô¬P³BÍ Pip¥Á•î¨]Q»¢ ÖÕZWk]…ÊÛ*o«¼ öXï±Þc Õ—V_Z})<xF 5dÔ(û¤ì“²OÀ%Ç%Ç%Öõ^×{]o}oô½Ñ÷ vÍÚ5kׄ­O´>Ѫ]¯v½Úu0Œ6Œ6Œ†{Þ÷¼ïyCåU•WU^["¶Dl€ZµjAÀÌ€™3}ÿ Õ…êB5œ<x:&ž¼]q¸GÜæææP«x­âµŠC‹àÁ-‚á”Ý)»Svp/î^ܽ8ˆŒŒŒ…ÇçŸ|œ;9wrîîîîE?wjîÔÜ©9¼ {ö* =züÞó|$“L2(Œ £Â.*•‹ ,'YN²œuÆÕWg”ª\ªr©ÊðÒõ¥ëKWxñ,âY0šÑŒ†«W®^¹zªU ª÷î;܇û6îÛ¸ vì,Øùëû¯ÌPf(3 |¯ò½Ê÷Ç·ŽoßBCC”Xv`ÙaÈ0dàJÄ•ˆ+¿0‹T8$AÁþ‚ýûa•Û*·Un`©·Ô[ê¡Îà:ƒë †ïÒ¾Kû. bvÄìˆÙñáãW¦R™Je*-2üêÇW?¾ú…¿Ò%DÉ'Ŧ†M ›PèTèTèÚÚÚÀf6³j®=ºöh¨MmjLcÓLúŸ+')')' ..\ Î6Î6Î6@ÃÿzþKö@ö@öì½ì½ì½ lfÙ̲™àWʯ”_)xÐñAÇAi§´SÚPB(!”dÈyˆyˆys„9œ¢æÍ˜0?ÂIá¤pò½~šä+ø ¾`ooæçÌÏ™ŸÇQŽ£G2R©ŒóVæ­Ì[ÌUæ*sóóó0;cvÆì 8%9%9%wCï†Þ áhúÑô£é ë§ë§ë‘‰‘‰‘‰éœéœé rw¹»Üªíª¶«Ú.°ibÓĦ ¨TªpT8* Û.Û.ÛÅ*«\¬2g„3™ŸFáœpN8Ùw³ïfß…ßß_ht¸ÑáF‡A—¥ËÒeA²e²e²eÑãe)KÙ>Yœ,N*:T„dÏdÏä_8#—ÎÀ$Ÿkkk¢„(! r|r|r|LêÓ¥l¡l¡ld’I&èªèªèªü ÿ«Gq@i¤½÷ùYÎr„GÂ#á>‚àÂ@a 0ðÜA‘¢çšpÀá7|ï_gr?{n0€€2”¡ „Ž :îXݱºcwóïæß͇Ü5¹kr×€ ô‚Ä—âKñ%ˆñb¼ÿ?ä·Ç{0î0î0î€Â… @êW©_¥~YU³ªfU…¡[†nº¼*zUôªøÇ¾Ÿ.…***þüs©€I>)V§¬NYëëëH(P:¡ôŸØa7ºÑ ž}6öÙX8[îl¹³å@ã¡ñÐü†éÈâñ€xô—ô—ô—À¸Þ¸Þ¸ž_} úïÆÚÝÚÝÚl£m£m£!Ö>Ö>ÖþhØ 'œ@/Žǃ.V«‹…ì©ÙS³§Bxðá= Î :ƒê Õ-Õ-Õ-È)•S*§TQ3ÆóÆóÆó`È5äÞ{Ï0ß0ß0ô…úBý{ã`ØoØoØzµ^­Wƒ ä‚ <*x9Ws®æ\f2“™`6‚AUUô¾z_½/ÊÊÊ€a²a²a2ÆÆÆýœw¼ãôÜ×s_Ï}0Y3Y3YãóÆçÏ·Ý~tû ÅB±PcscscsÐ'êõï=F`¨c¨c¨†á†á†áïý|€a€aèsõ¹ú\°Xm±Úb5x~ëù­ç·PòeÉ—%_B«™­f¶š ]ûwíßµ?8_t¾è|ñÇ/osÞæ¼ÍÚ/µ_j?ðtótótûùvÒ%DÉ'E®+ä p6:P˜P˜ð'‚çMŸ7}Þ¾ïú}×ﻂïvßí¾ÛAãªqÕ¸‚9æ˜ÿ‡ïgfgfgfÃæÂÍ…› ÁìŠÙ³+0f嘕cVò·_*I±F±F±jÝ©u§Ö¸ëw×ï®4ÈhÑ d2Ùo9cù?l‡Úµ -ª´¨Ò¢ \©q¥Æ• ¾߈o ž[=·znвIË&-›€} ûö-à‡ ?LøapdÀ‘`ñÅwß"Y‘¬H†°a'ÂN€b½b½b=$$$BH«V!­À,Û,Û,òOåŸÊ?¶¶¶Pù|åó•ÏÃþ×û_ï MtMtMt ,¥,¥,Y¯²^e½‚n/Ü^¸Ë—-.[ îTÜ©¸S<(yPò p©âRÅ¥ ¤ Mš2ì°Ãîößxßxßx"JG”Ž( λœw9ï‚°+aW®€ýfûÍö›!ÛmÈ6€Y5³jfÕàѨG£‚¼]y»òvÙ³;fw Ç7Ç7ÇF6ÙtdS8[ýlõ³Õ!Î?Î?Îʽ-÷¶Ü[hp¯Á½÷À¢ŽE‹:ÿã ½çy‡çžw(z]×>¯}^¿°ú¿4 QòIÚº#tG(d¶Íl›ÙƼófÌ›?¾ŸÝßîþv÷·ð°ËÃ.»ÀRË¥–K-Áì±Ùc³Ç þ{;ë—®_º~)<Ïxžñ<6´ßÐ~C{ê u…ºÿýû»ÔôÔôÔt˜Ÿ2?e~ ô,Þ³xÏâPÛ¾¶}í8#»Š]Å® OÕ§êSA\".—€òšòšòã…ñÂxà{¾ç{ЫÿVÿ-ˆcűâX† C…¡ ¬Ök@8/œ΃±ž±ž±`ƒ 6 x ž‚'ˆ9bŽ˜X`ÈÈÈ€ÑÒhi´ÃÃÃ[É­äV F‹Ñb4I$‘ÀMnrÅ(FݯŠWÅ« zŠž¢'ÈgÈgÈg€ Ô‚úv<„BÀpÖpÖpÄsâ9ñÿ¾t*w–;ËÁ°Ô°Ô°'œð¢K©be±²X¸Æ5®|¹|¹|9©Bª úáúáúá`Ì6f³Aæ+ó•ù‚"L¦+:žÿ«Üâ¹Ås‹Ã‚С B¡é䦓›N†›[ln±ùçÛKLòI:Wx®ð\!\®u¹ÖåZ°8|qøâpþ}þCåĿĿÄœ°9asÂàåÒ—K_.…™-f¶˜Ùj„ׯ÷»ßï~¿;¤¥¥üŠüŠü Ô¯S¿Ný:àhæhæhV4­ùÙËg/Ÿ½„õŸ­ÿlýg^9¼rxexUðªàU())A½võÚÕkŽë×;®‡wgß}wB‡,Y ô£ýÀ¿‰ÿ&PÜ£¸Gñ?`……uiÙ¥e—–ÁÁ¡‡ “4“4“4PÖ±¬cYGS§“üYt1º] ¬³]g»Î´Z­Œ;=îô¸Ó l­l­lýóïI÷À$Ÿ¤rÊ5*×2–g,ÏXo3Þf¼ýãÚW©T*• ¬°þÁú‡¢çÌíííÁ¨5jZuuu€JL(1®¿vüÚqØÕlW³]Í~Þ®` ‚2fgÌΘ ³sgçÎÎ…B·B·B7Ð^Ô^Ô^„Œ—/3^Bæ ÌA™ƒ`iÆÒŒ¥ qÓ¸iÜ 9%9%9Vd¬ÈX‘êpu¸ú#xέI…&šT€FŸ5ú¬Ñg°´êÒªK«BĸˆqãLNòGËóÅ|Öe®Ë\— ïn¼»ñî|%|%|%üzáú‰TÀ$Ÿ$‡ž=z½x25;5;5ûk_U\U\U\Ÿº>u} ΞΞΞàÙÁ³ƒg0Ûk¶×l/´¹ÒæJ›+PaQ…E뷮ߺ~ QÙQÙQ¿”ç_³ÏŒYÆ,c¤ÊSå©rx5ïÕ¼WóÀï©ßS¿§àõÎë×;ˆ5,j¼Œyó2ª_¨~¡ú(ߢ|‹ò-àíÛ¶¥ÊRe©þ§]üSÈÚÈÚÈÚÀ5¾¨ñE hСA‡`þèù£ç†‹/¼x c c cLVò?û× CZLz^¼„y \:¹tri˜à:Áu‚+8ŒNÆÿÞœTÀ$Ÿ$«#VG¬Ž€Õz«õVë!ù`òÁäƒÞîÏP@ˆ}žb_\Á"ò"ò"ò`]½uõÖÕƒ#»Žì:² B­C­C­ApœçŸ7'æ‰yb8Æ9Æ9ÆÁÜü¹ùsó!cDƈŒ0Ìu˜ë0W8·ýÜösÛA_W_W_2,2,2,àRÐ¥ KAö*ìUØ+Ê Ê ÊË»–w-ïšzTŠÈ×Ê×Ê׺/t_è ÿØþcû…}ÝöuÛ× –——áÝðwÃß ÿðþ$.õõõ8¾âøŠã+`FÞŒ¼yà~Îýœû9˜vfÚ™ig xâuŠÿ“?¤Yˆ’O’êªêªê*”1/c^ÆÂ‡-[ hĺ¸=zà7¸Á¿W£¿5îÖ¸[ãàí´·ÓÞNƒ 4\Ðt[t[t[àYÏg=Ÿõü…vÊSžòÿ"ÿEþ (R,¤X¬<¹òäÊ“0Þu¼ëxW¸ÒûJï+½¡ÿ þƒú÷&îMÜ›@Ë -+´¬ðÞ‹RêT7õ¨üœl³l³lsÑbø>3}fúÌ„}6ûlöÙÀ´ÓJL+›7n†–9-sZæ@‰q%Æ•.9šL¾6_›¯…G£~4Ž;6îØ8Ðêõ0¸õàÖƒ[Cîuº×éòBy¡üwÌ– ˜ä“æ]Ö»¬wY¸vâÚ‰k'À¸Ü¸Ü¸doeoepO,oMÞš¼5ðVÿVÿVé•Ó+§W†×¶¯m_ÛB¥a•†U×+^¯x½"ì‹Úµ/ lllAÜ"n·@ttttt4ÄŸ‹?rÞå¼Ëy¯[¿nýº5|xðáÁp¿ßý~÷ûÍ"kÙ­e·–ÝÀ³¬gYϲÔ)¨SP'ØQnG¹åÀ»wï>àsÒç¤ÏI¨¹»æîš»A¾^¾^¾ÞÔ£òëÜf»Ív› c£ÇF†gKŸ-}¶Žzõ8êSºOé>¥;øôé?š?mþ´ùS(£)£)£³ûf÷Íî›z/þ9DÑGô´´´¸{ðîÁ»á¢ÏEŸ‹> ™­™­™ -¶|Øò!|öåg_~ö%Xu²êdÕ‰~žQš…(ù¤EÄFÄFÄÂ’Ô%©KRaÙüeó—Í»cvÇìŽýþv ~?ƒdÜ˸—q Ï Ï ÏÀö˜í1Ûc j£j£j®®®`,o,o,ò{ò{ò{@úÐ,Ã,Ã,à /)/)/ ŒµŒµŒµÀ¦ŒM›2PQQÚmŽ6Ìv™í2Û'N8œa•°JX… € Ÿ Ÿ þ=]Û¬oXß°¾$’ȼ/ËTôöz{½=„ÉÃäar8ãÆÿŒ?„9„9„9€Ó\§¹Ns¡nnÝܺ¹PcK-5¶@É»%ï–¼ ò‡ò‡ò‡¦Þ‹—øT|*>…lßlßl_xžó<çyÜK¾—|/^¹¿rå÷î9܃f«›­n¶Îœ 8 6OlžØ<ªP…?b¥•‘ ˜ä“¦é¨é¨éc¼Çxñ†~÷úÝëwj_«}­ö¼ßJbZb’˜$&A’U’U’<þúñ׿†{.÷\î¹@¢6Q›¨Ç Ç Ç ð}àûÀ÷øÚûÚûÚƒÛI·“n'ÁÙÅÙÅÙ” ¥Bù¾^%öûˆ} kYÖ²¬eŸŸ‘s#çFÎ…çžWx^Þ|;ðí@(¶àÿµwßqQœûÿ÷_³ôÞDQ,¢bW,ˆ± *öØ5Å5–£X5–Ø»Æ$"{,ØìX±aAE‘.mwç÷Ç9çkîûäää$Ñý<ÿÉ#ËìÌ{fз×ìì53-fBõSÕOU? ,X6°Ï™ž3=g‚iiiÐëÏ-&0;ivÒì$pþÐùCçaÀÁü S∢E¿K¿K¿ žo}¾õùV8çwÎïœ,߸|ãò³3ggÎNðìéÙÓ³'XyXyXy@MM ”™\fr™Éà1ÇcŽÇp­àZÁµX[[ƒ™•™•™˜Í7›o6Œû÷3îÇÿÍ2ÿÚd“M6èêêBÁ¡‚C‡ ¿r~åüÊ×;¯w^ox1ôÅÐCá~Ìý˜û1´;iwÒnHì‘Ø#±¤lMÙš²4m5m5mÁe±Ëb—ÅPåý*ïWyª«6®Ú8¨x³âÍŠ7ÁôŠéÓ+†;Ÿoñ¿)„øãj}^ëóZŸCÔð¨áQá MA›‚6¯foM{M{M{ДӔӔƒ«Ý¯v¿Úܹs?ƒŽ :6踸¹¸¹¸ÁÝUwWÝ]·kÞ®y»&\Ÿv}ÚõipLsLsL¹Õr«åV“G&LÉ“+&WÀ"Û"Û"<<<Àv™í2Ûe`µÇjÕ°xfñÌâ˜Ú›Ú›ÚƒÑ-£[F·À8×8×8”éÊte:hÇjÇjÇ‚î¬î¬î,h«j«j«BÞÇyç} 9Ór¦åLƒì9Ùs²ç@Zí´Úiµ!ëó¬Ï³>‡Âó…ç ÏCapapa0hÒ5éštpXì°Øa1¸>v}ìúü–ø-ñ[^½*zUçkÎל¯mŠmŠm •3*gTˆ$’HCŸÅWd&poÖ½Y÷fÁÔ^S{Mí3ŽÌ82ã¸õwëïÖßÐéÄ_¥nP7¨àbé‹¥/–†{VìY±Ê+;¬ì0üÉàOÎûœ÷9ïûïëËÿ$ÿ“üO ­fZÍ´šq4ãhÆQÈ•5*kd6Êl”ÙRn§ÜN¹ é‡Ò¥‚—Ë^.{¹ ò+åWʯôê èúJúJúJ ›¨›¨›j}µ¾ZŒ50jU£jT0þÑøGãÁ´‚iÓ `¾Ö|­ùZ°u¶u¶u†_”ø¢ÄàØÙ±³cg°™h3Ñf"س9fs rrrÀf„Í› ¬UÖ*k }vþ<)0!mWmWmW˜0l° àÕäV“[M† ãAǃŽ:ø³òÃòÃòÃ`ë½­÷¶ÞƒÝ;wïܽº¸uqëâíN·;Ýî4˜Z›Z›Z¿@:t耮t¥+¨eÔ2j`-kY êPu¨:”ÿ›Ëõ¬g=(Ý•îJw`;ØÊmå¶r›WWyGI ñ+ë:¬ë°®<1}búÄB#C#C‹Ð%ñÇ$ßI¾“|–G.\ φ<òl Ý0tÃÐ àkçkçkô§?2Â.¶d&!~¥^Ÿz}êõ»ï^¼{^´xÑâE‹¿¾^ñšYa…Ä–Š-[ ¾šýÕì¯fƒuOëžÖ=aÚÓiO§=ß‘¾#}G"Åõ–›8„ø•òÊ?(ÿÌʘ•1+W7]ÝtuÓk˜¡Cü-röäìÉÙ›³7goΆCî‡Ü¹CÏÔž©=S!(=(=(Œk×4®iè´âï�!~Åê3«Ï¬>ƒúÞõ½ë{ÃñºÇë¯ ”§<å NüKRǤŽIaºÑt£éFpA½ ^Pabã‰'6†à-Á[‚·Hq½í¤À„ø ë5®×¸ܳ¿gÏytæ‘LAd0ª§ê©z‰'VœX“ &L*×d×d×d˜ÚrjË©-Áûg_Ǥ̢H’â7TØ^a{…íP:¼txép8–v,íXš¡S½{^Ny9ååXo±Þb½¬µrÔÊQÐ=³{f÷LþÓðŸ†ÿö‡íÛ6tZñ¦É]ˆBüŽSާO9†å–oXþjÎDÛa¶Ãlå1¯MÒò¤åIËaIó%Í—4‡œ9'rNÀðà ^ǼŽyãÕ4õâ$#0!~G­¡µ†Ö -6Zl„“gOž=yÖЩÞ>ú÷ôïé߃“'Ož•}*û:¥(îä¢B½ïê}Wï;ðŠðŠðŠ€ˆÃ‡#ƒÚGí£ö1tº7O}¬>VÃ…é¦_˜“Œ&M2›$›$›$˜ÒjJ«)­¤¸ÄßKæBâO0Zh´Ðh!ôZ×k]¯u0I¤NRá|ÓóMÏ7…ºÔ¥®¡C¾…ß~[ø-l·ßn¿Ývü¼ãç?Cµ‹ÚE…vì:ØñtãéÆÓ V¼m¤À„ø <x ðÌ;˜w0‡ï~?ðûP©t¥Ò•JƒÝ[8âxqüÅñÇaÕ‘UGV„s çÎÁ¸ªãªŽ« 5úÕèW£(Їâaè´âm%—…øOž<lVج°Y§#NGœuŸºOýOø-òþù ÆëÑ×£¯GÃWÚ¯´_i!Ï:Ï:Ϧ÷žÞ{zo¨y¸æáš‡¥¸Ä›!&ÄßÀ<Ô<Ô<n¸mà6ˆŠŠ‚Ó1§cNÇ:ÝŸ§-Ôj aϳ=Ïö<ƒ™“gNž9æ6Ìm˜ ŸÇÿy<”œ_r~Éù†N+Þ5r¢¯Á®Ê»*ïª ;ê憎£>L¯5½ÖôZàò©Ë§.Ÿ:Ý—Ó=§{NwXWg]uuàü'ç?9ÿ Þ7xßà}ÐpFà gqÄgè´â]%#0!^ƒ6óÛÌo3¼«zWõ® Ëï.¿»ü.äMÌ›˜7ñÕrú5ú5ú5áááúúú†Ëä’ä’äÓL0mœô!x÷8îqÜÐGUˆÿUñÚÝYpgÁªÚǪU+UíŸÐ?¡‚ª:å9å9婪} } } ª>}4ú¯oïéʧ+Ÿ®TÕôÓ?Lÿðß^¸¶pmáZUÝn¹Ýr»¥ªöÞ{xï᪺­ö¶ÚÛj«jaýÂú…õ }Ô„ø}r½o@FçŒÎáî™»gŠ1c*¾ú¹²FY£¬Ã9‡sç@SšÒôOl'ûdöÉì“0ùÀä“€S§&NM`²ûd÷Éîçœçœç k笳v\¾|ùòåË0¶ÚØjc«Aí2µËÔ.Üâ· }Ô„ø}R`B¼F{nï¹½ç6ŒŽ9:no¼½ñöÆ_N QCÔˆ9s:æ4¼˜ýbö‹Ùàø™ãgŽŸýñím®¾¹úæêðCä‘?D‚i7Ón¦ÝÀµ¿k×þøKâ/‰¿€rJ9¥œ‚©–S-§ZBéÜÒ¹¥ev}QÌÈg`B¼FîMÝ›º7…jÞÕ¼«yƒ¹§¹§¹ç^þâø‹ã/އ;SîL¹3åoç걫ǮƒyÎóœç9CŽš£æ¨Ö=­{Zw˜¸h⢉‹€–´¤%|eú•éW¦PºQéF¥ú( ñçH ñU\ýqõǰ¦ÒšJk*ÁœþsúÏéžnžnžn@_úÒ÷Õò©šTMªN}"ú@d»Èv‘íþ{Ž=µöÔÚS V}³ê›U߀zR=©ž4ôÑâÏ‘/2 a@/.½¸ôâlÈÝ»!¾ûỾû´hÑ[¿ßúýÖï¡Þ¸zãêÂ# ®|så›+ß@¯f½šõj×\kp­P‹ZÔå=å=å=°ïfß;Ôþ´ö§µ?…zaõÂê…Að–à-Á[ ñÃÆ?eŸ²Oy¦¼ï)0!Šýcýcýc8{ûìí³·aòËÉ/'¿­§ÖSë –K-—Z.…Ê%*—¨\sþÎyة۩۩7?7?7?¨Ü³rÏÊ=¡åÔ–S[N???ðjëÕÖ«-”¨S¢N‰:Àsžó.Q Q”I Qí<»óìγнy÷æÝ›C~v~v~ö«Ÿû6÷mîÛBlBlBl qXã°ÆaPŦŠM°t°t°tqÄÑÐ{#Äë!Ÿ QåççƒÖAë uø÷ŸwÛqlDZ02dþÈ|¨[³nͺ5Á²¢eEËŠHq‰w‚˜EPƒ¶ Ú6h ÁæÁæÁæ`mfmfm~Ýýºûu‡N3;Íì4”½Ê^e¯¡Ó ar Qˆ"ìnƒ» î6€/}ñè‹G0lÛ°möA“ºMê6yù,Äï˜E˜ã#ÇGŽ Tb©ÄR‰PrHÉ!%‡:•EƒL%%DQ–DI€=ö؃úP}¨>4t(!Š !„(–¤À„BKR`B!Š%)0!„Å’˜BˆbI L!D±$&„¢X’BQ,I !„(–¤À„BKR`B!Š%)0!„Å’˜â¿ÊéšÓ5§+<ÿàùÏ?}Œ>FcèTâ]'&„øž/}¾ôùRX¹q寕aeÐÊ •ApÿÃûÞÿš49h™J¦’©ÀýZ÷kݯ‘%"KD–€¤ˆ¤ˆ¤Cï…x[I Q”™bŠ)Ѓô¥¢RQ©øæ6Âç„Ï HôJôJô‚~Mú5é×tÓuÓuÓ!:2:2:²·doÉÞæÕÌ«™WƒUv«ìVÙÁÕ«W¯^½ z^§×AŠyŠyŠ9¨)jŠšbèƒ+Š;)0!Š05D QC ¿0¿0¿Ò´iÚ4-¤¹§¹§¹ÃÓµO×>] Ú$m’6éWïë¥öR{Á‹á/†¿É?%ÿ”üdÚeÚeÚ³™ÍìßÙp*Pî6¿ÛünsH»™v3í&Xõ·êoÕÜZºµtk C’‡$I§ Nœ6€Sk§ÖN­ÁâK‹/-¾¬°Â Ž~üóãŸÃâ¤ÅI‹“àE³Í^45CÍP3 /$/$/žø?ñâ©]S»¦výÏúŸõ?CNãœÆ9áùˆç#ž€Œ;w2î@†e†e†¥â»Jh)D¦6P¨ à†Õ «V°Üd¹ÉrèгCÏ=a÷äÝ“wO†N[:mé´Úïn¿»ýn8´ÿÐþCûáôÕÓWO_ç^νœ{ÁÃ~ôð#è–Õ-«[T§:Õc»©_¤~‘ú$¬KX—°¬|°òÁJ8t6èl¸Õt«éV&xtâQø4üÓðOáI\“¸&qÀ,f1 , , ,áè÷G¿?ú=œ™wfÞ™yÐtÓýM÷C¤I5’`ýÎõ;×ï¯ÆWã Ï·>ßú|+´2jeÔÊLÊ›”7)ÓkL¯1½´ù Ím>“q&ãLÆA?m?m?íÿõ¥xGÈLˆ"Ìx€ñã`Z`Z`ZV«¬VY­‚.Í»4ïÒªgTϨž‡ô‡ô‡ôö<íyÚsX³qÍÆ5!`KÀ–€-0øèࣃ‚{÷.î]`m‡µÖvµ–ZK­õïÛuä4Èiøøø€ÏFŸ>!°_`¿À~àíåíåíô§?ý!÷Eî‹Ü@!„a„Ö¥¬KY—‚Š=*z@å#•T>-J·(Ý¢4œÎ={:.ï½¼÷ò^>{øìá³ÁWï«÷ÕÃOüÄO€{¨{¨{(dwËî–Ý üŽùó;ïŸ}ÿìûgÁ,Ü,Ü,ÜÐgK¼i2¢S³Õl5ø†oøèD':½ú¹™ÎLg¦ƒÂ‹… /BNlNlN,< ~ü,œuÎ:gÝ«åË4)Ó¤LØ¿`ÿ‚ý @¦ Ó† &˜üV€B )u·º[Ý ¼ä%/_½Î{¼Ç{€N8ýêõÿ´žêuÇ«—òø“ÇŸÀCŸ‡>} âVÄ­ˆ[p»á톷‚ÑÇF} j¬«Æ‚éÓ¦ À!Ï!Ï!JÞ.y»ämCŸ%a(R`BaŠ»â®¸I$‘<à~µ€-¶ØËXÆ20Yf²Ìd˜©fª™ @[ÚÒ^6yÙäe°ìmÙÛ²7hzhzhzéHÇß`‰%– ,S–)Ë€¡ e( E‹hF3š~øá\á W€ Ÿ|òg<ãP’’”ó9æsÌç€[„[„[´:Ýêt«ÓЦT›RmJ©©© dÏ<žypà 7 4Ò }v„¡I Q„éRu©ºTÈOÏOÏO‡ŒÑ£3FCNPNPN¼(xQð¢ÒÒÒÀ<Ó<Ó<Þûñ½ßûŽ®=ºöèZ(H)H)H3ËÎ,;³ ‚{÷îFüíîÕíÕí…g5žÕxVR·§nOÝÏ[=oõ¼l/Ø^°²:guÎê OZòIÊ')Ÿ€^xú$ ƒ‘¢ÓÓÓç»ÎwïBcMcMc äŽÉ“;êÞ¯{¿î}ðYí³Úg5hFkFkFÃCV Y§W^uz<:òèÈ£#Ð1µcjÇT¨—V/­ÞïŒ`ò®å]Ë»u<ëxÖñ„Jã*«4^†¿ ÚmŒ6B·œ9®k]׺®…¬ÛY·³nCHÆ! ¡Lb™Ä2‰PáE…^€q3ãfÆÍ µnjÝÔºð^ü{ñïÅÃØic§7:Þèx£#$Å'Å'ŃåRË¥–KÁl‹Ù³-0<`xÀð°®i]Óº&K,±@ÐÀÐgK¼iŠúO†"„øwénénénÖ"¬EX j?Ô~¨=x/ò^ä½ÈÐé„0, Q”%“L2¨;ÕêNPªÕ‡†%DÑ ·Ñ !„(–¤À„BKR`B!Š%)0!„Å’˜BˆbI L!D±$&DQV—ºÔe¿²_ÙÊÊʆ%DÑ _d¢ÐÓÓƒ O4<Ñâ#â#â# ÷@îܰËg—Ï.hêÒÔ¥© ¸”r)åR \r\r\r^Í!h1ÅbŠÅCïo†|‘Yˆ"À¨®Q]£ºŸ¿ÿùûŸ¿ÿïËáG~õÿ}ô]Ðw´)hSЦÀÐ{!Ä›%—…(BšÇ7oî×ݯ»_ÿÏËY&X&X&@[ç¶ÎmÁôkÓ¯M¿6tz!Þ,)0!Šj›ªmª¶ ª{V÷¬îùŸ—óÐxh<4à?Íšÿ4C§Â0¤À„(B,ü,ü,ü Y;³vf )¥)¥)õïË 8\¾rùÊå+C§Â0¤À„(‚ü/ú_ô¿eÒˤ—IõºmÛ2¶e Å…Z\“Þ&½Mz:­†!&DäyÊó”ç)ðKóKóûÕs»*UªT©R%¨¬þ±úÇ RÃ’¢²j1Ôb(Õ ªT,nXܰ¸Í{7ïݼ7¸,tYè²ÐÐ)…0,¹^¼Ó –,/XéëÒ×¥¯ÝFÝFÝFP¼oÅÛp¹”ï•ï•ïÁKñR¼°=`{Àöøn÷Ý=}öôÙSÐëŒuüS¬¦«éj:(÷•ûÊ}°5²5²5KKKÃåïù"³x'¥…¥…¥…ÁÊK+/­¼ç9ÏyÀögÛŸm¥¥ÒRiiÀ€-hA ÐÓÓƒ„Œ„Œ„ (ó¨Ì£2À*Û*Û*ÔÚjmµ¶s6£Í {oöÞì½à6Ûm¶Ûlyo佑÷ÀãC=>4`>ñV“ï”ÛŸÞþôö§°8iqÒâ$°³³ƒW{\íqìŽÛ·;ê|u¾:ßp93ÅL1u–:Kº º º  9¡9¡9š2š2š2 ¦ª©jªsöQú(} ¯N^¼:°ÏrŸå>K8ßí|·óÝ`°Å`‹ÁàwÖï¬ßYP•@%ÐpyÅÛE L¼Ý4hÐ@ôýèûÑ÷aõ•ÕWV_€>øú ë3¬Ï00Ÿf>Í\¾Oõ—éoêoêoÂÞU{Wí]áÚpm¸:^ëx­ã5è|¥ó•ÎWÀø‰ñã'†N+Š;)0ñV*èSЧ Dê#õ‘zؽ~÷úÝëa€Í›6мEóÍ[€f¯f¯f¯¡Ó¾…ºÐ….p©Î¥:—êÀ¢v‹Ú-jUêU©W¥ Ú3hÏ =`ÛÒ¶¥­!/ÕŠbM L¼UÒž¦=M{ +ú®è»¢/<°`ÿÀFTQuDU¨V%¬J˜¡S¾{ž”zRêI)Xxáý…÷!GþŽü0"`DÀˆ(çVέœ›¡SŠâFn£o…„ À¤ÜI¹“r!o\Þ¸¼q0µòÔÊS+KqšËS—§.OáËœ/s¾ÌÏ=ž{<÷@Ø‚°a àtÞé¼ÓyÀD&2ÑÐiEq!&ЧÃæ0Dߊ¾} ¦®˜ºbê ¨ñ²ÆË/aB‰ %&”çiÎӜ峭"ê„U «0¸ÞàzƒëA÷øîñÝãaQü¢øEñÙ6²md[Ð6Ñ6Ñ61tZQÔÉ%DQ¬4/h^Ð"Í#Í#Í!Ê(Ê(Êúº÷uïë-Æ´Ób h*i*i*:­ø£â"â"â"`i…¥–Vï Þ¼7À ƒf šv¶v¶v¶†N)Š)0Q,¼¨ó¢Î‹:°Òh¥ÑJ#¸Ÿx?ñ~"ŒL™<2ª(U”*Š¡SŠ¿*ygòÎä°èࢃ‹B~åüÊù•aä‘FmÛ<¶:¥(*¤ÀD‘–™™ :-t»L»L»Lž9^¯‡ScN95VUXUaUèÐ5 +ôrëåÖË ,½-½- 8Õ“x3´_j¿Ô~ QIQIQIþQøGáAç ÎAƒ Cûí;´“M&›L6:­xÓä&Q$„„„BxÙð²áeayàòÀåÐ÷eß—}_€«®¸ú¿—.I—¤K‚Ôå©ËS—CFDFDFH"‰=wþÓü§ùO!£RF¥ŒJ Öëƒ!Ë1Ë1Ëžy6æÙйéÜtn`= .V«‹ÿþã¬õÓúiý`‡ýöw€5ýÖô[Ó²Kd—È.ñ÷mG]«®U×B–]–]–<›þlú³é sÕ¹ê\ÿøzŒgÏ0žÁ“‚'O‚Ϧ~6õ³©°ÏkŸ×>/X¸táÒ…K!#$#$#äï?^¢h“•v'íNÚ˜;eSàÄÞ{Oì…СB@à²ÀeË@3B3B3â_AXAXA,2_d¾Èf}4ë£Yꮺ«î=ÿß3¾g|aÆøãgŒ‡Ì#™G2Àé§œ!—C.‡\†txÐáÕûÔêuÇo¬§ÂŒ 3*@ÎÙœ³9gÿþã}fá™…gÂ~í~í~-¸—t/é^Ô 5CÍøû¶£‹ÐEè" öTì©ØSbbbZ?hý õŸXaE*Rªï¯¾¿ú~˜òdÊ“)O õËÔ/S¿„)e§”ReŠòw†˜0ˆÛ· nÀ”ÊS*O© y»òvåí‚°ZaµÂjAU‡ªUsÌ1ÿóÛ±Xm±Úb5¸Ìq™ã2Òf§ÍN› $@Â_ßß¾;|wÀÇ1Ç|vSí¦ÚMŸ…> }B¶¶¶?è6ë6ë6C\N\N\xxàᇿ±žú×ÿ¸>X¬³Xg±îï?î7~¹ñË_ ? ? ?Zº¶tmé 6¡6¡6¡ßvŒ£Œ£Œ£À'Ã'Ã'²s²s²s °[a·Ân}ýnÉnÉnÉðE—/º|Ñ*Ý­t·Ò]˜ÒpJÃ) áôúÓëO¯õ¤zR=ù÷GQ4È¿UÄ›a‚ &pb艡'†ÂêS«O­>þý7úo„¾sûÎí;ÌO™Ÿ2?õ¶¿’•¬„ij‰gϦ3›Îl:©R;¥v‚Æol¼ K–*,‡\¹r…? øaÀpÿôýÓ÷OÃá9‡çž |0ð$êu‰:8ÒöHÛ#maàûßø>(w•»Ê]P¾R¾R¾‚çêsõ¹ +rWä®È­›ÖMëŽ;;víxíxíx8Þæx›ãm Kr—ä.ɰ7joÔÞ(°l`ÙÀ²X¤X¤X¤@JÓ”¦)M¡Ïç}>ïó98Ïržå<ë?ï~êâÔÅ©‹áüšókίëw¯ß½~öÚ7jß(Hi—Ò.¥<¶lÿØúÙõ³ëg.?¹üäòd/Ê^”½l l l êlÔÙ¨³ããã ­j´ªÑªÄ.Š]»·%nKÜyëòÖå­ƒÜŹ‹sƒ²JY¥¬ÚÒ–¶ý´ZZZÂÇi§}œeû”íS¶, ]º(:ÖìX³cMèìÙÙ³³'ß1¾c|çµü† ˜x­   !bTĨˆQ°|Èò!ˇ@ŸÑ}F÷ çœ?pþk,®™Ë\æB©ÐR¡¥B¡eAË‚–P.¡\B¹˜_k~­ùµ oÞþ¼ý5(jPÔ È Í Í ç›Î7oBÔûQïG½™ïg¾Ÿù>8q:ãtö¬Ý³vÏZH;œv8í0( •†JCÀ_|Á>À>À>,Z[´¶h ^½z„ªÚªÚªZp¼ìxÙñ2ì¾·ûÞî{ ]¢]¢]ñÞñÞñÞðôîÓ»OïBóöÍÛ7oç¬ÏYŸ³†}£÷Þ7ú¿ï¾ÓN§N;¡|lùØò±P6¡lBÙhdÝȺ‘5”¢¥€SõOÕ?U̘50k±Æ±Æ±Æ0¹Ëä.“»€®‰®‰® dµËj—Õì¶ÚmµÛ 'Çž{r,lž²yÊæ)Ðüûæß7ÿ~ ø)à'0Ûg¶Ïl°Œe,ûûO¯¦»¦»¦;ÁøqãÇûîo¸¿!,I^’¼$²\³\³þ‡ÏàDÑ&&^«ï›|ßäû&°î溛ën„À !°o`ßÀ¾ ‰ÑÄhbÞ@<à˜›››››ƒs¸s¸s84}ÖôYÓgcžcžcÇ>ûp,˜¬0Ya²”!ÊeX¶·loÙŒ–-7ZJO¥§Ò,M,M,MÀh¥ÑJ£• Ä*±J,N:é F©Qj˜†˜†˜†€yŽyŽyØÆØÆØÆ€Å.‹]»^=Ò¨·Qo£Þ`²Ñd£ÉF0ûÀì³À²Ÿe?Ë~à’å’å’ŽÕ«;V‡Ô§©OSŸBNÙœ²9e!ºTt©èRpT{T{T qãÇ=ö³Ÿý`Ýź‹u°ê`ÕÁª8$:$:$BÀ?üŽ8€ ¦L/˜BÂÓ„§ O!6?6?6Î|uæ«3_½º£ú¨ê£ª‚“%N–8Y*XT°¨`ž›=7{n†§Kœ.q4-5-5-AMPÔ¿áÒíô ¿ð Ô¸^ãzë0Íxšñ4c8ûÃÙÎþ3šùÓÌŸ ÿhþÑü£oà÷N¼VR`⵪r£Ê*7ÀÙÄÙÄÙΖ;[îl9ÈÊÊzƒAtèÐzS½©Þ^ò’— „)aJEQÀ°àWÏ­ªMmj¿zÿŸ¦¢¢N8áÄ¿„V@ ¦¨)jʯ^·Ã;ÐÔÕÔÕÔ…Ì™ 2@lNlNlÄXÇXÇXõqׯ]÷«÷iÑ¢5FQc@£ÎQç€u„u„uÔÓÔÓÔÓÀ¶1ÛÆlÚÚÚÐâP‹C-Á–1[ÆlÚ®Ú®Ú®àºÞu½ëzÈ;šw4ï(˜~jú©é§oð¼þ§Ó=V7V7.] ºª“ê¤:AÝÎu;×í Æ Æ Æ¯³HÅ!&^«Æ7ßl|ÂÆ„ qš8Mœf˜u`Öxô,èYÐòÏ¿¸uKuKuK¡°baÅŠ78npÜ`°úÜês«Ï¡rïʽ+÷mEmEmEÈ>™}2û$hMµ¦ZSПџџ—ÎK纇º‡º‡ ©© ÚTmª6tñºx]<è'ê'ê'‚ö;íwÚï@IT•DH/H/H/íííÐÒÒý—ú/õ_Ba‰Â…%@×O×O×tÓuÓuÓ_íŽn­n­n-|[ðmÁ·àÚŵ‹kŸ=>{|6„æ…æ…æAŸ}6öÙø«÷UÔUÔUÎGçúžúžúž¯~°0`aÀB¸ÔúRëK­¡TéR¥K•†ví<Úy@t¥èJÑ•À#Î#Î#îÕû¼2¼2¼2àîî»»ïî†ìèìèìh(¬_X¿°>èGëGëGƒ¾·¾·¾÷ë;Íÿº{så‚• V.€ˆÖ­#ZèÐQ¡£BáýÉïO~2……Ém÷Åž˜x#*úWô¯èSÏO=?õü«HN*œT8©®—º^êúkœQ£ÖàZƒk †RcK-5ÖõX×c]ˆ‰‰‰‡¡öCí‡ÚCµÈj‘Õ"¡Ýêv«Û­†½ãöŽÛ;bkÇÖŽ­ åj–«Y®&¤D¥D¥DÁõ×\o.ö.ö.öpc×]7vÁµY×f]›®©®©®©p¯Þ½z÷êA³´fiÍÒà‘ý#ûGö°sèΡ;‡B|ƒøñ Àõ‚ë× pfæ™™gf§8Å)Еԕԕ„‡~ýúÉ“+&W@¯Óëô:ÈÝ•»+w×ÞÿÌ%™K2—@úô;éw@3D3D3nM¸5áÖ„WËyú{ú{úCö~õÚÖk[¯-TY_e}•õðÁóžðªÝ¬v³ÚÍWï뺴ëÒ®K¡â¶ŠÛ*nƒUÝWu_ÕŽO8>áøðèêÑÕ£+¤¾L}™úòï?¿É“&„é3Òg¤CBû„ö íaÊà)ƒ§ †ú§êŸª ÃƼ¾ß3ñfÉL æÌ)˜[6mÙ´eìn¹»åî–п^ÿzýëA‹¹-涘û7~Fv‹[ÜÝÝÝÐ=Ó=Ó=MŠ&E“Æ={÷ZÓšÖ ¶P[¨- pKá–Â-  Õ„jBoù–oA¤ ÒZN-§–ÕNµSí@Y©¬TVÁ ªê£ú€RZ)­”£‹F.Ba•Â*…U€‘Œd$húhúhú€Z^-¯–ö²—½€'žx‚rH9¤åŽrG¹úúú ÌSæ)óÀ¨¶Qm£ÚÀ6¶ñsªOÔ'êЭ֭֭6³™Í ñ×øküA3O3O30à 3P¿S¿S¿ÅIqRœ€¾ô¥/¨…j¡ZJ´­DÍiNóWÛÑoÕoÕomœ6NJ?¥ŸÒ ÅB±Í4Í4Í4Ð,Ò,Ò,âÿîNýŸµ£íàRâ¥ÄK‰°8iqÒâ$ð¹ásÃç|Té£JU› › ›¿ñûm¢h‘†õ¯ÛëŸ|b0¬Z¸j᪅ÐäÇ&?6ùú®ì»²ïJ0?i~Ò\¾ÏóÎÓGê#õ‘°·ÛÞn{»AxXxXxtÒqHÇ!ÐÙ¿³g0¾m|Ûø¶¡ÓŠ×M.! Ã*¤Bð_â¿Ä LÜ?qÿÄýpåÁ•WÀ×_~øê6rñnÊ>”}(û¬X±bÅŠ°%zKô–h3"fD tïß5^Šë]##0Q$¥]H»v–Ç.] ‰y‰y‰y0gè´¢¸‘oµ„ À‚: ê,¨N~N~N~0ìΰ;Ãî€óTç©ÎS òí““š“š“ >Þðñ†áô¡Ó‡N‚¡“†N: üîùÝó»,d! VWR`â——+­´b<ðyàóÀFôÑkD/¨Ò¶JÛ*ÃßuO‚Ÿ? ~õÙVÞò¼åyËa„÷ïÞP®Q¹Få:¥x[H‰wJAï‚Þ½!Ò$Ò$Òö˜í1ÛcõºÕëV¯¸Vq­âZXÃÖ2è?£Â 1ŒÎ7:ú]ú]ú] :ªŽª#`=ö†‹©ÌVf+³!½qzãôÆpªÑ©F§o¢o¢o" ê9¨ç ž`hhhÀã)ÞJR`⤦©ijÄtŠéÓ ]8táÐPü?ÅøœÏùÜpùþõ ͼ¨¼¨¼(8÷à܃s êùªç«ž‡=z€zK½¥Þ2àÌ'Ÿ|е׵׵‡Z k5¬ÕÚÌj3«Í,0ñ7ñ7ñ7`>ñV“¢K7M7M7…Éõ&×›\†F •5•5•eñŽ“?Beÿœì˜«\å*M6Ù†%DÑ &„¢X’BQ,I !„(–¤À„BKR`B!Š%)0!„Å’˜BˆbI L!D±$&„¢X’BQ,I !„(–¤À„BKR`B!Š%)0!„Å’˜BˆbI L!D±$&„¢X’BQ,I QP@ð„'<ùÕë¶Øb „J((” J…_ý<•TRl²É6ôNñf)ê?:ˆï2ÝVÝVÝV8^öxÙãe!^¯‰×@ntntn4üâó‹Ï/>Ð* U@+p‰s‰s‰×P×P×PJ J J‹X‹X‹XCïo†±¡!À¨‹Q£.paÒ…I&ÁøöãÛoŒcã@§ÎSçÁ±Ç:ëj¾š¯æÃ·nÜ ¸spçàÎ†Þ !Þ,¹„(DÒdl“±MÆBi]i]i¨ZU«j‘Œdä«â²L°L°L€ÀÎ;ƒÉb“Å&‹ ^ˆ7K Lˆ"Ä7Ç7Ç7jt®Ñ¹ÆïŒ¨<==Áÿ‘ÿ#ÿG†N-„aH Q„X¸Y¸Y¸Að‰àÁ'@³Z³Z³úß—kÕ©U§VÀe¤ËH—‘†N-„aÈg`BAþþþàþÜý¹ûsH$‘DÀ¦ƒM›Ð,¾Y|³x0ifÒ̤™¡Ó a2¢òœé9Ós&42idÒÈäÕëÞÞÞàwÙï²ßeC§°¤À„(‚,ú[ô·èAÎAÎAÎ`1Öb¬ÅXhQ­EµÕÀe‰Ë—%†N)„aÉ%DñNÈðÈðÈð€}¹ûr÷åBú²ôeéË@©ªTUª:Ý¿S¼/Å x8àá0‰1‰1‰ôGéÒÁêÖ«[¯n úúú†NûÖ°†5`ºÅt‹éhY¿eý–õÁ}“û&÷M†'ÞR`âðhÝ£uÖÁú õAëƒ 0#0#0Lt&:¡Óý;ÅAqPÀ±“c'ÇN®Y®Y®Yç›ç›ç ªNÕ©E1ÿ4eš2 vœÜqrÇI(IIJî¸ãnèpâ­!&Þ êêêàfïfïfÃúë;¬/˜™š™š™:ÝoÈ ƒ  ,e) ùó;çw“)&SL¦€ÆYã¬q6tÈÿîaðÃà‡Á wÓ»éÝ F¼m¤À„(Êþyû¡f˜:‹EŒÜÄ!„¢X’BQ,I !„(–¤À„BKR`B!Š%)0!„Å’ÜF/ÄŸñ2ãeÆK¸·ñÞÆ{¡ÔõR×K]‡’÷JÞ+yž$*ù¨ä#°œ`9Ár´ø¢Å-¾µªZU­ ;vì ÇŽ={@l`l`l ØL¶™l3Ä ú¬ñ2âw<œûpîù°hõ¢Õ‹VC³…Í6[› l2° xŽðá9tn:7”˜TbR‰Iw&ïLÞx´ÿÑþGûáæ“›On>mÍ·5ßÖ: é4¤ÓhݸuãÖÁ<Í<Í< ÎÍ?7ÿÜ|Ï Ï ÏƒnG»ívG Ž›<6ylý9ý9ý9°ýÖö[Ûo¡OÓ>Mû4…®^]½ºzÁÏ7~¾ñó È·Ë·Ë·ƒ¼%yKò–@ÚgiŸ¥}­ÂZ…µ ˜;~îø¹ãÁã¢ÇE‹ðÑ{½÷Ñ{P¿Lý2õË€:K¥Î4häo QTÈLˆß‘˜˜¹Ú\m®¼ïzßõ¾ Ê`e°2ŒÚµ1jêõ‚záÕûŒ‚‚‚'<á ¸}äö‘ÛGàïï“FN9i$tý°ë‡]?O/O/O/¸p-àZØœ°9asÊ\*s©Ì%Pæ)ó”yÐκu;kÐØhl46`ddWï†_ ‡g—ž]zv ²eÊ>:K¥ÎŒsss¡äÇ%?.ù1TWi\¥qü^ò{ÉïÁýÏîvÿ3ðíæÛÍ·Û«ý0Ž0Ž0Ž5YMV“—¼ä¥¡ÏŠÿ &ÄïP•p%xÄ#ý꿃Ì`þï3$¥ŠRE©Üâ·k¬±}w}w}wp=èzÐõ Ìm:·éܦp&òLä™H˜gþùwÀê¸Õq«ã`fmfmf º†º†º† vP;¨@é¦tSº &˜éýÒû¥÷ƒI3'Íœ4‚&Mš¥•ÒJiŒ#ÅH,±ÄH!…`/{Ù Ìcó€þô§?Pžò”µ´ZZ-ý«`„F TSª)Õ€óœç¼¡ÏŠÿ „øe¼Êx•ñ›26elÊ@Ìј£1G!­nZÝ´ºû ÷AîÈ-›[6·,h;h;h;@îšÜ5¹k wOîžÜ=pÝ÷ºïu_8¿àü‚ó À®ÿ\ÿ¹à±ÇcÇÈy–ó,çÔ™Zgj©Û7·on_ˆ™3/f¤ J”22ÇgŽÏ¹³rgå΂¤óIç“΃[†[†[¸•v+íVôQú(}dùfùfùBn\n\ndΜ=XÅ*V]»v Òו¾®ô5œjxªá©†¾(}Qú"Ⱦœ}9û2ä©yjž Ú/µ_j¿4ôYâ¤À„øîUÜ«¸W±¡cCdžÂ;!wBàÀª«¬ŸDŸDŸD(½¡ô†Ò ¡NB„:P©S¥N•:CCC¨ËÕåêrxÒþIû'íaçÕWw^…6ÛZú¨?Ðò-1aÆ„f@·&nMܠ݀vÚ 0t*ñ¶˜BˆbI L!D±$&„¢X’BQ,I !„(–¤À„BKR`B!Š%)0!„Å’˜x7Üæ6·A}ª>UŸ"³ª¿)Ùd“ \æ2— F¼md2_ñN0©lRÙ¤2¤LJ™”2 ¾èðE‡/:€I“>&} î-4Ÿù̇K/U¼T7n ÜdèPâm#&Þ îܹ7‚Ðs¡çBÏAÆ?füJ¶’­d:ÝÛGµV­Ukh×*®UÔ̬™Y3ÓЩÄÛFæBBQ,ɧB!Š¥ÿ;¹uîe+‰ô.zTXtcreate-datexÚ320°Ô50Õ54 14µ2µ´22×60²20B# ðc}.zTXtmodify-datexÚ320°Ô50Õ54 14µ25°26Ñ60²20A¼õä‡IEND®B`‚rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_abortonuncleanconfig.rst0000644000000000000000000000013215055603742030774 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.309699145 30 ctime=1764935920.661537969 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_abortonuncleanconfig.rst0000664000175000017500000000301215055603742030434 0ustar00rgerrger`rsyslog.conf configuration parameter `_ $AbortOnUncleanConfig ---------------------- **Type:** global configuration parameter **Parameter Values:** boolean (on/off, yes/no) **Available since:** 5.3.1+ **Default:** off **Description:** This parameter permits to prevent rsyslog from running when the configuration file is not clean. "Not Clean" means there are errors or some other annoyances that rsyslogd reports on startup. This is a user-requested feature to have a strict startup mode. Note that with the current code base it is not always possible to differentiate between a real error and a warning-like condition. As such, the startup will also prevented if warnings are present. I consider this a good thing in being "strict", but I admit there also currently is no other way of doing it. It is recommended to use the new config style. The equivalent of this parameter in the new style is ``global(abortOnUncleanConfig="")``. **Caveats:** Note that the consequences of a failed rsyslogd startup can be much more serious than a startup with only partial configuration. For example, log data may be lost or systems that depend on the log server in question will not be able to send logs, what in the ultimate result could result in a system hang on those systems. Also, the local system may hang when the local log socket has become full and is not read. There exist many such scenarios. As such, it is strongly recommended not to turn on this parameter. [`rsyslog site `_\ ] rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_debugprinttemplatelist.r0000644000000000000000000000013215055603742031020 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.348699607 30 ctime=1764935920.668538076 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_debugprinttemplatelist.rst0000664000175000017500000000045215055603742031034 0ustar00rgerrger$DebugPrintTemplateList ----------------------- **Type:** global configuration parameter **Default:** on **Description:** Specifies whether or not the template list should be written to the debug log. Possible values: on/off. Default is on. Does not affect operation if debugging is disabled.. rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_modload.rst0000644000000000000000000000013215055603742026213 xustar0030 mtime=1756825570.248068247 30 atime=1764928592.942456044 30 ctime=1764935920.684538321 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_modload.rst0000664000175000017500000000156015055603742025661 0ustar00rgerrger$ModLoad -------- **Type:** global configuration parameter **Default:** **Description:** Dynamically loads a plug-in into rsyslog's address space and activates it. The plug-in must obey the rsyslog module API. Currently, only MariaDB/ MySQL and Postgres output modules are available as a plugins, but users may create their own. A plug-in must be loaded BEFORE any configuration file lines that reference it. Modules must be present in the system default destination for rsyslog modules. You can also set the directory via the `$ModDir `_ parameter. If a full path name is specified, the module is loaded from that path. The default module directory is ignored in that case. **Sample:** .. code-block:: none $ModLoad ommysql # load MariaDB/MySQL functionality $ModLoad /rsyslog/modules/ompgsql.so # load the postgres module via absolute path rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_resetconfigvariables.rst0000644000000000000000000000013215055603742030775 xustar0030 mtime=1756825570.248068247 30 atime=1764928592.954456414 30 ctime=1764935920.686538352 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_resetconfigvariables.rst0000664000175000017500000000066315055603742030446 0ustar00rgerrger$ResetConfigVariables --------------------- **Type:** global configuration parameter **Default:** **Description:** Resets all configuration variables to their default value. Any settings made will not be applied to configuration lines following the $ResetConfigVariables. This is a good method to make sure no side-effects exists from previous parameters. This parameter has no parameters. **Sample:** ``$ResetConfigVariables`` rsyslog-8.2512.0/doc/source/configuration/global/options/PaxHeaders/rsconf1_debugprintmodulelist.rst0000644000000000000000000000013115055603742031040 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.335699453 29 ctime=1764935920.66553803 rsyslog-8.2512.0/doc/source/configuration/global/options/rsconf1_debugprintmodulelist.rst0000664000175000017500000000044315055603742030506 0ustar00rgerrger$DebugPrintModuleList --------------------- **Type:** global configuration parameter **Default:** on **Description:** Specifies whether or not the module list should be written to the debug log. Possible values: on/off. Default is on. Does not affect operation if debugging is disabled. rsyslog-8.2512.0/doc/source/configuration/global/PaxHeaders/index.rst0000644000000000000000000000013215062756615022563 xustar0030 mtime=1758190989.171640695 30 atime=1764928348.289698908 30 ctime=1764935920.659537938 rsyslog-8.2512.0/doc/source/configuration/global/index.rst0000664000175000017500000002150615062756615022233 0ustar00rgerrgerLegacy Global Configuration Statements ====================================== Global configuration statements, as their name implies, usually affect some global features. However, some also affect main queues, which are "global" to a ruleset. True Global Directives ---------------------- .. toctree:: :glob: options/rsconf1_abortonuncleanconfig options/rsconf1_debugprintcfsyslinehandlerlist options/rsconf1_debugprintmodulelist options/rsconf1_debugprinttemplatelist options/rsconf1_failonchownfailure options/rsconf1_generateconfiggraph options/rsconf1_includeconfig options/rsconf1_mainmsgqueuesize options/rsconf1_maxopenfiles options/rsconf1_moddir options/rsconf1_modload options/rsconf1_umask options/rsconf1_resetconfigvariables - **$MaxMessageSize** , default 8k - allows to specify maximum supported message size (both for sending and receiving). The default should be sufficient for almost all cases. Do not set this below 1k, as it would cause interoperability problems with other syslog implementations. **Important:** In order for this directive to work correctly, it **must** be placed right at the top of ``rsyslog.conf`` (before any input is defined). Change the setting to e.g. 32768 if you would like to support large message sizes for IHE (32k is the current maximum needed for IHE). I was initially tempted to set the default to 32k, but there is a some memory footprint with the current implementation in rsyslog. If you intend to receive Windows Event Log data (e.g. via `EventReporter `_), you might want to increase this number to an even higher value, as event log messages can be very lengthy ("$MaxMessageSize 64k" is not a bad idea). Note: testing showed that 4k seems to be the typical maximum for **UDP** based syslog. This is an IP stack restriction. Not always ... but very often. If you go beyond that value, be sure to test that rsyslogd actually does what you think it should do ;) It is highly suggested to use a TCP based transport instead of UDP (plain TCP syslog, RELP). This resolves the UDP stack size restrictions. Note that 2k, is the smallest size that must be supported in order to be compliant to the upcoming new syslog RFC series. - **$LocalHostName** [name] - this directive permits to overwrite the system hostname with the one specified in the directive. If the directive is given multiple times, all but the last one will be ignored. Please note that startup error messages may be issued with the real hostname. This is by design and not a bug (but one may argue if the design should be changed ;)). Available since 4.7.4+, 5.7.3+, 6.1.3+. - **$LogRSyslogStatusMessages** [**on**/off] - If set to on (the default), rsyslog emits message on startup and shutdown as well as when it is HUPed. This information might be needed by some log analyzers. If set to off, no such status messages are logged, what may be useful for other scenarios. [available since 4.7.0 and 5.3.0] - **$DefaultRuleset** [name] - changes the default ruleset for unbound inputs to the provided *name* (the default ruleset is named "RSYSLOG\_DefaultRuleset"). It is advised to also read our paper on :doc:`using multiple rule sets in rsyslog <../../concepts/multi_ruleset>`. - **$DefaultNetstreamDriver** , the default :doc:`network stream driver <../../concepts/netstrm_drvr>` to use. Defaults to ptcp. - **$DefaultNetstreamDriverCAFile** - **$DefaultNetstreamDriverCertFile** - **$DefaultNetstreamDriverKeyFile** - **$NetstreamDriverCaExtraFiles** - This directive allows to configure multiple additional extra CA files. This is intended for SSL certificate chains to work appropriately, as the different CA files in the chain need to be specified. It must be remarked that this directive only works with the OpenSSL driver. - **$RepeatedMsgContainsOriginalMsg** [on/**off**] - "last message repeated n times" messages, if generated, have a different format that contains the message that is being repeated. Note that only the first "n" characters are included, with n to be at least 80 characters, most probably more (this may change from version to version, thus no specific limit is given). The bottom line is that n is large enough to get a good idea which message was repeated but it is not necessarily large enough for the whole message. (Introduced with 4.1.5). Once set, it affects all following actions. - **$OptimizeForUniprocessor** - This directive is no longer supported. While present in versions prior to 8.32.0, the directive had no effect for many years. Attempts to use the directive now results in a warning. - **$PreserveFQDN** [on/**off**) - if set to off (legacy default to remain compatible to sysklogd), the domain part from a name that is within the same domain as the receiving system is stripped. If set to on, full names are always used. Reverse lookup results are cached; see :ref:`reverse_dns_cache` for controlling cache refresh. - **$WorkDirectory** (directory for spool and other work files. Do **not** use trailing slashes) - `$PrivDropToGroup `_ - `$PrivDropToGroupID `_ - `$PrivDropToUser `_ - `$PrivDropToUserID `_ - **$Sleep** - puts the rsyslog main thread to sleep for the specified number of seconds immediately when the directive is encountered. You should have a good reason for using this directive! - **$LocalHostIPIF** - (available since 5.9.6) - if provided, the IP of the specified interface (e.g. "eth0") shall be used as fromhost-ip for local-originating messages. If this directive is not given OR the interface cannot be found (or has no IP address), the default of "127.0.0.1" is used. Note that this directive can be given only once. Trying to reset will result in an error message and the new value will be ignored. Please note that modules must have support for obtaining the local IP address set via this directive. While this is the case for rsyslog-provided modules, it may not always be the case for contributed plugins. **Important:** This directive shall be placed **right at the top of rsyslog.conf**. Otherwise, if error messages are triggered before this directive is processed, rsyslog will fix the local host IP to "127.0.0.1", what than can not be reset. - **$ErrorMessagesToStderr** [**on**\ \|off] - direct rsyslogd error message to stderr (in addition to other targets) - **$SpaceLFOnReceive** [on/**off**] - instructs rsyslogd to replace LF with spaces during message reception (sysklogd compatibility aid). This is applied at the beginning of the parser stage and cannot be overridden (neither at the input nor parser level). Consequently, it affects all inputs and parsers. main queue specific Directives ------------------------------ Note that these directives modify ruleset main message queues. This includes the default ruleset's main message queue, the one that is always present. To do this, specify directives outside of a ruleset definition. To understand queue parameters, read :doc:`queues in rsyslog <../../concepts/queues>`. - **$MainMsgQueueCheckpointInterval** - **$MainMsgQueueDequeueBatchSize** [default 32] - **$MainMsgQueueDequeueSlowdown** [number is timeout in *micro*\ seconds (1000000us is 1sec!), default 0 (no delay). Simple rate-limiting!] - **$MainMsgQueueDiscardMark** [default 98% of queue size] - **$MainMsgQueueDiscardSeverity** [either a textual or numerical severity! default 4 (warning)] - **$MainMsgQueueFileName** - **$MainMsgQueueHighWaterMark** [default 90% of queue size] - **$MainMsgQueueImmediateShutdown** [on/**off**] - **$MainMsgQueueLowWaterMark** [default 70% of queue size] - **$MainMsgQueueMaxFileSize** , default 1m - **$MainMsgQueueTimeoutActionCompletion** [number is timeout in ms (1000ms is 1sec!), default 1000, 0 means immediate!] - **$MainMsgQueueTimeoutEnqueue** [number is timeout in ms (1000ms is 1sec!), default 2000, 0 means discard immediately] - **$MainMsgQueueTimeoutShutdown** [number is timeout in ms (1000ms is 1sec!), default 0 (indefinite)] - **$MainMsgQueueWorkerTimeoutThreadShutdown** [number is timeout in ms (1000ms is 1sec!), default 60000 (1 minute)] - **$MainMsgQueueType** [**FixedArray**/LinkedList/Direct/Disk] - **$MainMsgQueueSaveOnShutdown**  [on/**off**] - **$MainMsgQueueWorkerThreads** , num worker threads, default 2, recommended 1 - **$MainMsgQueueWorkerThreadMinumumMessages** , default queue size/number of workers rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/converting_to_new_format.rst0000644000000000000000000000013215055603742025307 xustar0030 mtime=1756825570.248068247 30 atime=1764928348.142697167 30 ctime=1764935920.643537693 rsyslog-8.2512.0/doc/source/configuration/converting_to_new_format.rst0000664000175000017500000001635015055603742024760 0ustar00rgerrgerConverting older formats to |FmtAdvancedName| ============================================= First of all, converting of older formats is not strictly necessary. All formats can be mixed and matched and play well together. There are still a number of reasons to convert older formats: * existing simple constructs need to be enhanced and become more complex * aid future extensions * ensure no side-effects accidentally occur * unify rsyslog.conf language Do not overdo conversion ~~~~~~~~~~~~~~~~~~~~~~~~ Note: simple facility and severity based filters which trigger writing to files can actually be very well expressed in |FmtBasicName|. So if you have something like:: mail.info /var/log/maillog We suggest you leave it as-is without conversion. Equally, in our opinion it is also fine to add new rules like the above. If you still want to convert, the line may look as follows (completely in new format):: if prifilt("mail.info") then { action(type="omfile" file="/var/log/maillog") } More compact, this can also be written like:: if prifilt("mail.info") then action(type="omfile" file="/var/log/maillog") The older-selector-style filter is well-known, so this may also write it as:: mail.info action(type="omfile" file="/var/log/maillog") There are ample additional possibilities. We suggest to keep things consistent. Converting Module Load ~~~~~~~~~~~~~~~~~~~~~~ This is very straight-forward. In |FmtObsoleteName| format we use:: $ModLoad module-name This is very simply converted to:: module(load="module-name") Sometimes modules provide global settings. In |FmtObsoleteName| format these are given in individual lines **after** the \$ModLoad. In |FmtAdvancedName| format they are given inside the module object. This makes it much clearer which module they belong to and that they actually are global parameters (in contrast to per-action or per-listener parameters). A typical example is `imtcp`:: $ModLoad imtcp $InputTCPMaxSession 500 This is converted to:: module(load="imtcp" maxSessions="500") Note: in |FmtObsoleteName| format it is possible to provide global parameters more than once. In this case it is unclear which one actually applies. For example:: $ModLoad imtcp $InputTCPMaxSession 500 ... *.* /var/log/messages ... $InputTCPMaxSession 200 This is especially problematic if module-global parameters are used multiple times in include files. In |FmtAdvancedName| format this is no longer possible. Module-global parameters can only be applied once when the module is loaded. Any attempt to change them afterwards results in an error message and will be ignored. The error messages will help you find and fix multiple settings. Let us assume "200" is the setting actually intended in above config snippet. So it would be converted to:: module(load="imtcp" maxSessions="200") ... *.* /var/log/messages ... Converting Actions ~~~~~~~~~~~~~~~~~~ In general, you have lines like:: filter action where *filter* is any of the filters and *action* is ... the action to be carried out. As could be seen above, the filter does **not** necessarily need to be changed in order to convert the action. All filters also work with all config formats. It often is best to keep existing filters, at least while working on the conversion (do not change too many things at once). The following table lists traditional action syntax and how it can be converted to new-style ``action()`` objects. The link will bring you to detail documentation. In these detail documentations all parameters are given. It is also specified which |FmtObsoleteName| directives map to |FmtAdvancedName| properties. This table is not conclusive but covers the most commonly used actions. .. csv-table:: :header: "|FmtBasicName|", "|FmtAdvancedName|" :widths: auto :class: parameter-table "file path (`/var/log/...`)", "action(type="":doc:`omfile `"" file=""/var/log.../"" ...)" "UDP forwarding (`@remote`)", "action(type="":doc:`omfwd `"" target=""remote"" protocol=""udp"" ...)" "TCP forwarding (`@@remote`)", "action(type="":doc:`omfwd `"" target=""remote"" protocol=""tcp"" ...)" "user notify (``:omusrmsg:user``)", "action(type="":doc:`omusrmsg `"" users=""user"" ...)" "module name (``:omxxx:..``)", "action(type="":doc:`omxxx `"" ...)" Some concrete examples:: OLD: :hostname, contains, "remote-sender" @@central NEW: :hostname, contains, "remote-sender" action(type="omfwd" target="central" protocol="tcp") OLD: if $msg contains "error" then @central NEW: if $msg contains "error" then action(type="omfwd" target="central" protocol="udp") OLD: *.emerg :omusrmsg:* NEW: *.emerg action(type="omusrmsg" users="*") **NOTE:** Some actions do not have a |FmtBasicName| format configuration line. They may only be called via the ``action()`` syntax. Similarly, some very few actions, mostly contributed, do not support ``action()`` syntax and thus can only be configured via |FmtBasicName| and |FmtObsoleteName|. See module doc for details. Action with Multiple Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In many cases, actions have additional parameters, which also need to be converted. In |FmtObsoleteName| format the action parameters are given before the actual action call. To convert such constructs, you need to map all |FmtObsoleteName| parameters to |FmtAdvancedName| ones. To look these up, you need to turn to three different documentation pages: * the :doc:`action object ` itself * the :doc:`output module ` that is called in the action (e.g. omfwd) * the :doc:`queue documentation <../rainerscript/queue_parameters>` (if an action queue is used) To find the parameter in question, you can other do an on-page search via the browser on these pages. Often it is very convenient to just use the `rsyslog doc search engine `_: Type the |FmtObsoleteName| format statement into the search box. Most often, one of the first search results is the matching object description doc page. Converting Action Chains ~~~~~~~~~~~~~~~~~~~~~~~~ Actions can be chained via the ampersand character ('``&``'). In |FmtAdvancedName| format this has been replaced by blocks. For example:: *.error /var/log/errorlog & @remote becomes:: *.error { action(type="omfile" file="/var/log/errorlog") action(type="omfwd" target="remote" protocol="udp") } The latter is much easier to understand and less error-prone when extended. A common construct is to send messages to a remote host based on some message content and then not further process it. This involves the ``stop`` statement (or it's very old-time equivalent tilde ('``~``'). It may be specified as such:: :msg, contains, "error" @remote & ~ which is equivalent to:: :msg, contains, "error" @remote & stop This format is often found in more modern distro's rsyslog.conf. It again is fully equivalent to:: :msg, contains, "error" { action(type="omfwd" target="remote" protocol="udp") stop } And, just to prove the point, this is also exactly the same like:: if $msg contains "error" then { action(type="omfwd" target="remote" protocol="udp") stop } rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/sysklogd_format.rst0000644000000000000000000000013215055603742023415 xustar0030 mtime=1756825570.255068361 30 atime=1764928604.145799202 30 ctime=1764935920.983542898 rsyslog-8.2512.0/doc/source/configuration/sysklogd_format.rst0000664000175000017500000002755715055603742023101 0ustar00rgerrger *************** sysklogd format *************** This is the format in use since the beginning of syslogging. It still is an excellent choice to do very simple things. For more advanced things, use the |FmtAdvancedName| format. DESCRIPTION =========== The syslog.conf file is the main configuration file for :manpage:`syslogd(8)` which logs system messages on \*nix systems. This file specifies rules for logging. For special features see the sysklogd(8) manpage. Every rule consists of two fields, a selector field and an action field. These two fields are separated by one or more spaces or tabs. The selector field specifies a pattern of facilities and priorities belonging to the specified action. Lines starting with a hash mark ("#") and empty lines are ignored. This variant of syslogd is able to understand a slightly extended syntax compared to the original BSD syslogd. One rule may be divided into several lines if the leading line is terminated with a backslash ("\\"). SELECTORS ========= The selector field consists of two parts, a facility and a priority, separated by a period ("."). Both parts are case insensitive and can also be specified as decimal numbers corresponding to the definitions in ``/usr/include/syslog.h``. It is safer to use symbolic names rather than decimal numbers. Both facilities and priorities are described in :manpage:`syslog(3)`. The names mentioned below correspond to the similar ``LOG_`` values in ``/usr/include/syslog.h``. The facility is one of the following keywords: auth, authpriv, cron, daemon, ftp, kern, lpr, mail, mark, news, security (same as auth), syslog, user, uucp and local0 through local7. The keyword security is deprecated and mark is only for internal use and therefore should not be used in applications. The facility specifies the subsystem that produced the message, e.g. all mail programs log with the mail facility (LOG_MAIL) if they log using syslog. In most cases anyone can log to any facility, so we rely on convention for the correct facility to be chosen. However, generally only the kernel can log to the "kern" facility. This is because the implementation of ``openlog()`` and ``syslog()`` in glibc does not allow logging to the "kern" facility. Klogd circumvents this restriction when logging to syslogd by reimplementing those functions itself. The priority is one of the following keywords, in ascending order: debug, info, notice, warning, warn (same as warning), err, error (same as err), crit, alert, emerg, panic (same as emerg). The keywords warn, error and panic are deprecated and should not be used anymore. The priority defines the severity of the message. The behavior of the original BSD syslogd is that all messages of the specified priority and higher are logged according to the given action. This :manpage:`syslogd(8)` behaves the same, but has some extensions. In addition to the above mentioned names the :manpage:`syslogd(8)` understands the following extensions: An asterisk ("\*") stands for all facilities or all priorities, depending on where it is used (before or after the period). The keyword none stands for no priority of the given facility. Multiple facilities may be specified for a single priority pattern in one statement using the comma (",") operator to separate the facilities. You may specify as many facilities as you want. Please note that only the facility part from such a statement is taken, a priority part would be ignored. Multiple selectors may be specified for a single action using the semicolon (";") separator. Selectors are processed from left to right, with each selector being able to overwrite preceding ones. Using this behavior you are able to exclude some priorities from the pattern. This :manpage:`syslogd(8)` has a syntax extension to the original BSD source, which makes its use more intuitive. You may precede every priority with an equation sign ("=") to specify that syslogd should only refer to this single priority and not this priority and all higher priorities. You may also precede the priority with an exclamation mark ("!") if you want syslogd to ignore this priority and all higher priorities. You may even use both, the exclamation mark and the equation sign if you want syslogd to ignore only this single priority. If you use both extensions then the exclamation mark must occur before the equation sign, just use it intuitively. ACTIONS ======= The action field of a rule describes the abstract term "logfile". A "logfile" need not to be a real file, btw. The :manpage:`syslogd(8)` provides the following actions. Regular File ------------ Typically messages are logged to real files. The filename is specified with an absolute pathname. It may be specified as a file name relative to rsyslog's working directory if the filename starts with "." or "..". However, this is dangerous and should be avoided. Named Pipes ----------- This version of :manpage:`syslogd(8)` has support for logging output to named pipes (fifos). A fifo or named pipe can be used as a destination for log messages by prepending a pipe symbol ("|") to the name of the file. This is handy for debugging. Note that the fifo must be created with the :manpage:`mkfifo(1)` command before :manpage:`syslogd(8)` is started. Terminal and Console -------------------- If the file you specified is a tty, special tty-handling is done, same with ``/dev/console``. Remote Machine -------------- This :manpage:`syslogd(8)` provides full remote logging, i.e. is able to send messages to a remote host running :manpage:`syslogd(8)` and to receive messages from remote hosts. The remote host won't forward the message again, it will just log them locally. To forward messages to another host, prepend the hostname with the at sign ("@"). Using this feature you are able to collect all syslog messages on a central host, if all other machines log remotely to that one. This reduces administration needs. Using a named pipe log method, messages from remote hosts can be sent to a log program. By reading log messages line by line such a program is able to sort log messages by host name or program name on the central log host. This way it is possible to split the log into separate files. List of Users ------------- Usually critical messages are also directed to "root" on that machine. You can specify a list of users that ought to receive the log message on the terminal by writing their usernames. You may specify more than one user by separating the usernames with commas (","). If they're logged in they will receive the log messages. Everyone logged on ------------------ Emergency messages often go to all users currently online to notify them that something strange is happening with the system. To specify this wall(1)-feature use an asterisk ("*"). EXAMPLES ======== Here are some examples, partially taken from a real existing site and configuration. Hopefully they answer all questions about configuring this :manpage:`syslogd(8)`. If not, don't hesitate to contact the mailing list. :: # Store critical stuff in critical # *.=crit;kern.none /var/adm/critical This will store all messages of priority crit in the file ``/var/adm/critical``, with the exception of any kernel messages. :: # Kernel messages are stored in the kernel file, # critical messages and higher ones also go # to another host and to the console # kern.* /var/adm/kernel kern.crit @finlandia kern.crit /dev/console kern.info;kern.!err /var/adm/kernel-info The first rule directs any message that has the kernel facility to the file ``/var/adm/kernel``. (But recall that only the kernel itself can log to this facility.) The second statement directs all kernel messages of priority crit and higher to the remote host finlandia. This is useful, because if the host crashes and the disks get irreparable errors you might not be able to read the stored messages. If they're on a remote host, too, you still can try to find out the reason for the crash. The third rule directs kernel messages of priority crit and higher to the actual console, so the person who works on the machine will get them, too. The fourth line tells the syslogd to save all kernel messages that come with priorities from info up to warning in the file ``/var/adm/kernel-info``. This is an example of the 2nd selector overwriting part of the first one. The first selector selects kernel messages of priority info and higher. The second selector filters out kernel messages of priority error and higher. This leaves just priorities info, notice and warning to get logged. :: # The tcp wrapper logs with mail.info, we display # all the connections on tty12 # mail.=info /dev/tty12 This directs all messages that use ``mail.info`` (in source ``LOG_MAIL | LOG_INFO``) to ``/dev/tty12``, the 12th console. For example the tcpwrapper :manpage:`tcpd(8)` uses this as its default. :: # Write all mail related logs to a file # mail.*;mail.!=info /var/adm/mail This pattern matches all messages that come with the mail facility, except for the info priority. These will be stored in the file ``/var/adm/mail``. :: # Log all mail.info and news.info messages to info # mail,news.=info /var/adm/info This will extract all messages that come either with mail.info or with news.info and store them in the file ``/var/adm/info``. :: # Log info and notice messages to messages file # *.=info;*.=notice;\ mail.none /var/log/messages This lets the syslogd log all messages that come with either the info or the notice priority into the file ``/var/log/messages``, except for all messages that use the mail facility. :: # Log info messages to messages file # *.=info;\ mail,news.none /var/log/messages This statement causes the syslogd to log all messages that come with the info priority to the file ``/var/log/messages``. But any message coming either with the mail or the news facility will not be stored. :: # Emergency messages will be displayed using wall # *.=emerg * This rule tells the syslogd to write all emergency messages to all currently logged in users. This is the wall action. :: # Messages of the priority alert will be directed # to the operator # *.alert root,joey This rule directs all messages of priority alert or higher to the terminals of the operator, i.e. of the users "root" and "joey" if they're logged in. :: *.* @finlandia This rule would redirect all messages to a remote host called finlandia. This is useful especially in a cluster of machines where all syslog messages will be stored on only one machine. CONFIGURATION FILE SYNTAX DIFFERENCES ===================================== Syslogd uses a slightly different syntax for its configuration file than the original BSD sources. Originally all messages of a specific priority and above were forwarded to the log file. The modifiers "=", "!" and "-" were added to make the syslogd more flexible and to use it in a more intuitive manner. The original BSD syslogd doesn't understand spaces as separators between the selector and the action field. BUGS ==== The effects of multiple selectors are sometimes not intuitive. For example "mail.crit,\*.err" will select "mail" facility messages at the level of "err" or higher, not at the level of "crit" or higher. Also, if you specify a selector with an exclamation mark in it which is not preceded by a corresponding selector without an exclamation mark, nothing will be logged. Intuitively, the selector "ftp.!alert" on its own will select all ftp messages with priorities less than alert. In fact it selects nothing. Similarly "ftp.!=alert" might reasonably be expected to select all ftp messages other than those with priority alert, but again it selects nothing. It seems the selectors with exclamation marks in them should only be used as "filters" following selectors without exclamation marks. Finally, using a backslash to divide a line into two doesn't work if the backslash is used immediately after the end of the selector, without intermediate whitespace. rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/property_replacer.rst0000644000000000000000000000013215071746523023752 xustar0030 mtime=1760021843.789420213 30 atime=1764928603.965793723 30 ctime=1764935920.968542669 rsyslog-8.2512.0/doc/source/configuration/property_replacer.rst0000664000175000017500000003626515071746523023432 0ustar00rgerrgerThe Property Replacer ===================== **The property replacer is a core component in rsyslogd's** `string template system `_. A syslog message has a number of well-defined properties. Each of these properties can be accessed **and** manipulated by the property replacer. With it, it is easy to use only part of a property value or manipulate the value, e.g. by converting all characters to lower case. Accessing Properties -------------------- Syslog message properties are used inside templates. They are accessed by putting them between percent signs. Properties can be modified by the property replacer. The full syntax is as follows: :: %property:fromChar:toChar:options% Available Properties ^^^^^^^^^^^^^^^^^^^^ The property replacer can use all :doc:`rsyslog properties `. Character Positions ^^^^^^^^^^^^^^^^^^^^ **FromChar** and **toChar** are used to build substrings. They specify the offset within the string that should be copied. Offset counting starts at 1, so if you need to obtain the first 2 characters of the message text, you can use this syntax: "%msg:1:2%". If you do not wish to specify from and to, but you want to specify options, you still need to include the colons. For example, if you would like to convert the full message text to lower case, use "%msg:::lowercase%". If you would like to extract from a position until the end of the string, you can place a dollar-sign ("$") in toChar (e.g. %msg:10:$%, which will extract from position 10 to the end of the string). There is also support for **regular expressions**. To use them, you need to place a "R" into FromChar. This tells rsyslog that a regular expression instead of position-based extraction is desired. The actual regular expression must then be provided in toChar. The regular expression **must** be followed by the string "--end". It denotes the end of the regular expression and will not become part of it. If you are using regular expressions, the property replacer will return the part of the property text that matches the regular expression. An example for a property replacer sequence with a regular expression is: "%msg:R:.\*Sev:. \\(.\*\\) \\[.\*--end%" It is possible to specify some parameters after the "R". These are comma-separated. They are: R,,,<:doc:`nomatch `\ >, regexp-type is either "BRE" for Posix basic regular expressions or "ERE" for extended ones. The string must be given in upper case. The default is "BRE" to be consistent with earlier versions of rsyslog that did not support ERE. The submatch identifies the submatch to be used with the result. A single digit is supported. Match 0 is the full match, while 1 to 9 are the actual submatches. The match-number identifies which match to use, if the expression occurs more than once inside the string. Please note that the first match is number 0, the second 1 and so on. Up to 10 matches (up to number 9) are supported. Please note that it would be more natural to have the match-number in front of submatch, but this would break backward-compatibility. So the match-number must be specified after "nomatch". :doc:`nomatch ` specifies what should be used in case no match is found. The following is a sample of an ERE expression that takes the first submatch from the message string and replaces the expression with the full field if no match is found: :: %msg:R,ERE,1,FIELD:for (vlan[0-9]\*):--end% and this takes the first submatch of the second match of said expression: :: %msg:R,ERE,1,FIELD,1:for (vlan[0-9]\*):--end% **Please note: there is also a** `rsyslog regular expression checker/generator `_ **online tool available.** With that tool, you can check your regular expressions and also generate a valid property replacer sequence. Usage of this tool is recommended. Depending on the version offered, the tool may not cover all subtleties that can be done with the property replacer. It concentrates on the most often used cases. So it is still useful to hand-craft expressions for demanding environments. **Also, extraction can be done based on so-called "fields"**. To do so, place a "F" into FromChar. A field in its current definition is anything that is delimited by a delimiter character. The delimiter by default is TAB (US-ASCII value 9). However, if can be changed to any other US-ASCII character by specifying a comma and the **decimal** US-ASCII value of the delimiter immediately after the "F". For example, to use comma (",") as a delimiter, use this field specifier: "F,44".  If your syslog data is delimited, this is a quicker way to extract than via regular expressions (actually, a *much* quicker way). Field counting starts at 1. Field zero is accepted, but will always lead to a "field not found" error. The same happens if a field number higher than the number of fields in the property is requested. The field number must be placed in the "ToChar" parameter. An example where the 3rd field (delimited by TAB) from the msg property is extracted is as follows: "%msg:F:3%". The same example with semicolon as delimiter is "%msg:F,59:3%". The use of fields does not permit to select substrings, what is rather unfortunate. To solve this issue, starting with 6.3.9, fromPos and toPos can be specified for strings as well. However, the syntax is quite ugly, but it was the only way to integrate this functionality into the already-existing system. To do so, use ",fromPos" and ",toPos" during field extraction. Let's assume you want to extract the substring from position 5 to 9 in the previous example. Then, the syntax is as follows: "%msg:F,59,5:3,9%". As you can see, "F,59" means field-mode, with semicolon delimiter and ",5" means starting at position 5. Then "3,9" means field 3 and string extraction to position 9. Please note that the special characters "F" and "R" are case-sensitive. Only upper case works, lower case will return an error. There are no white spaces permitted inside the sequence (that will lead to error messages and will NOT provide the intended result). Each occurrence of the field delimiter starts a new field. However, if you add a plus sign ("+") after the field delimiter, multiple delimiters, one immediately after the others, are treated as separate fields. This can be useful in cases where the syslog message contains such sequences. A frequent case may be with code that is written as follows: ```` :: int n, m; ... syslog(LOG_ERR, "%d test %6d", n, m); This will result into things like this in syslog messages: "1 test      2", "1 test     23", "1 test  234567" As you can see, the fields are delimited by space characters, but their exact number is unknown. They can properly be extracted as follows: :: "%msg:F,32:2%" to "%msg:F,32+:2%". This feature was suggested by Zhuang Yuyao and implemented by him. It is modeled after perl compatible regular expressions. Property Options ^^^^^^^^^^^^^^^^ **Property options** are case-insensitive. Currently, the following options are defined: **uppercase** convert property to uppercase only **lowercase** convert property text to lowercase only **fixed-width** changes behaviour of toChar so that it pads the source string with spaces up to the value of toChar if the source string is shorter. *This feature was introduced in rsyslog 8.13.0* **json** encode the value so that it can be used inside a JSON field. This means that several characters (according to the JSON spec) are being escaped, for example US-ASCII LF is replaced by "\\n". The json option cannot be used together with either jsonf or csv options. **jsonf**\[:outname\] (available in 6.3.9+) This signifies that the property should be expressed as a JSON field. That means not only the property is written, but rather a complete JSON field in the format ``"fieldname"="value"`` where "fieldname" is given in the *outname* property (or the property name if none was assigned) and value is the end result of property replacer operation. Note that value supports all property replacer options, like substrings, case conversion and the like. Values are properly JSON-escaped, however field names are (currently) not, so it is expected that proper field names are configured. The jsonf option cannot be used together with either json or csv options. For more information you can read `this article from Rainer's blog `_. **csv** formats the resulting field (after all modifications) in CSV format as specified in `RFC 4180 `_. Rsyslog will always use double quotes. Note that in order to have full CSV-formatted text, you need to define a proper template. An example is this one: $template csvline,"%syslogtag:::csv%,%msg:::csv%" Most importantly, you need to provide the commas between the fields inside the template. *This feature was introduced in rsyslog 4.1.6.* **drop-last-lf** The last LF in the message (if any), is dropped. Especially useful for PIX. **date-utc** convert data to UTC prior to outputting it (available since 8.18.0) **date-mysql** format as MariaDB/MySQL date **date-rfc3164** format as RFC 3164 date **date-rfc3164-buggyday** similar to date-rfc3164, but emulates a common coding error: RFC 3164 demands that a space is written for single-digit days. With this option, a zero is written instead. This format seems to be used by syslog-ng and the date-rfc3164-buggyday option can be used in migration scenarios where otherwise lots of scripts would need to be adjusted. It is recommended *not* to use this option when forwarding to remote hosts - they may treat the date as invalid (especially when parsing strictly according to RFC 3164). *This feature was introduced in rsyslog 4.6.2 and v4 versions above and 5.5.3 and all versions above.* **date-rfc3339** format as RFC 3339 date **date-unixtimestamp** Format as a unix timestamp (seconds since epoch) **date-year** just the year part (4-digit) of a timestamp **date-month** just the month part (2-digit) of a timestamp **date-day** just the day part (2-digit) of a timestamp **date-hour** just the hour part (2-digit, 24-hour clock) of a timestamp **date-minute** just the minute part (2-digit) of a timestamp **date-second** just the second part (2-digit) of a timestamp **date-subseconds** just the subseconds of a timestamp (always 0 for a low precision timestamp) **date-tzoffshour** just the timezone offset hour part (2-digit) of a timestamp **date-tzoffsmin** just the timezone offset minute part (2-digit) of a timestamp. Note that this is usually 0, but there are some time zones that have offsets which are not hourly-granular. If so, this is the minute offset. **date-tzoffsdirection** just the timezone offset direction part of a timestamp. This specifies if the offsets needs to be added ("+") or subtracted ("-") to the timestamp in order to get UTC. **date-ordinal** returns the ordinal for the given day, e.g. it is 2 for January, 2nd **date-iso-week** and **date-iso-week-year** return the ISO week number and week-numbering year, which should be used together. See `ISO week date `_ for more details **date-week** returns the week number **date-wday** just the weekday number of the timestamp. This is a single digit, with 0=Sunday, 1=Monday, ..., 6=Saturday. **date-wdayname** just the abbreviated english name of the weekday (e.g. "Mon", "Sat") of the timestamp. **escape-cc** replace control characters (ASCII value 127 and values less then 32) with an escape sequence. The sequence is "#" where charval is the 3-digit decimal value of the control character. For example, a tabulator would be replaced by "#009". Note: using this option requires that `$EscapeControlCharactersOnReceive `_ is set to off. **space-cc** replace control characters by spaces Note: using this option requires that `$EscapeControlCharactersOnReceive `_ is set to off. **drop-cc** drop control characters - the resulting string will neither contain control characters, escape sequences nor any other replacement character like space. Note: using this option requires that `$EscapeControlCharactersOnReceive `_ is set to off. **compressspace** compresses multiple spaces (US-ASCII SP character) inside the string to a single one. This compression happens at a very late stage in processing. Most importantly, it happens after substring extraction, so the **FromChar** and **ToChar** positions are **NOT** affected by this option. (available since v8.18.0) **sp-if-no-1st-sp** This option looks scary and should probably not be used by a user. For any field given, it returns either a single space character or no character at all. Field content is never returned. A space is returned if (and only if) the first character of the field's content is NOT a space. This option is kind of a hack to solve a problem rooted in RFC 3164: 3164 specifies no delimiter between the syslog tag sequence and the actual message text. Almost all implementation in fact delimit the two by a space. As of RFC 3164, this space is part of the message text itself. This leads to a problem when building the message (e.g. when writing to disk or forwarding). Should a delimiting space be included if the message does not start with one? If not, the tag is immediately followed by another non-space character, which can lead some log parsers to misinterpret what is the tag and what the message. The problem finally surfaced when the klog module was restructured and the tag correctly written. It exists with other message sources, too. The solution was the introduction of this special property replacer option. Now, the default template can contain a conditional space, which exists only if the message does not start with one. While this does not solve all issues, it should work good enough in the far majority of all cases. If you read this text and have no idea of what it is talking about - relax: this is a good indication you will never need this option. Simply forget about it ;) **secpath-drop** Drops slashes inside the field (e.g. "a/b" becomes "ab"). Useful for secure pathname generation (with dynafiles). **secpath-replace** Replace slashes inside the field by an underscore. (e.g. "a/b" becomes "a\_b"). Useful for secure pathname generation (with dynafiles). To use multiple options, simply place them one after each other with a comma delimiting them. For example "escape-cc,sp-if-no-1st-sp". If you use conflicting options together, the last one will override the previous one. For example, using "escape-cc,drop-cc" will use drop-cc and "drop-cc,escape-cc" will use escape-cc mode. Further Links ------------- - Article on ":doc:`Recording the Priority of Syslog Messages <../tutorials/recording_pri>`" (describes use of templates to record severity and facility of a message) - `Configuration file syntax `_, this is where you actually use the property replacer. .. toctree:: :maxdepth: 2 nomatch rsyslog-8.2512.0/doc/source/configuration/PaxHeaders/modules0000644000000000000000000000013015114544360021041 xustar0029 mtime=1764935920.95554247 30 atime=1764935930.366686544 29 ctime=1764935920.95554247 rsyslog-8.2512.0/doc/source/configuration/modules/0000775000175000017500000000000015114544360020564 5ustar00rgerrgerrsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/mmjsontransform.rst0000644000000000000000000000013115103346332025105 xustar0030 mtime=1762512090.625175919 29 atime=1764928598.04961299 30 ctime=1764935920.822540434 rsyslog-8.2512.0/doc/source/configuration/modules/mmjsontransform.rst0000664000175000017500000001250015103346332024550 0ustar00rgerrger.. _ref-mmjsontransform: JSON Dotted Key Transformer (mmjsontransform) ============================================= =========================== ========================================================================== **Module Name:** **mmjsontransform** **Author:** `rsyslog project `_ **Available since:** 8.2410.0 =========================== ========================================================================== .. note:: ``mmjsontransform`` is a **fresh** module. Parameter names and behavior may still change as real-world feedback arrives, so expect possible breaking adjustments in upcoming releases. Purpose ======= ``mmjsontransform`` restructures JSON properties whose names contain dotted segments. The action reads a JSON object from the configured input property and stores the transformed tree under a dedicated output property. By default the module expands dotted keys into nested containers (``unflatten`` mode) so pipelines that consume ``option.jsonfTree`` data can normalize payloads inline. When ``mode="flatten"`` is selected, the action collapses nested objects back into dotted keys. Failure conditions ================== ``mmjsontransform`` aborts the action when any of the following occur: * The input property does not resolve to a JSON object. * The output property already exists on the message. * Rewriting a key would overwrite an existing incompatible value (for example, ``{"a": 1}`` combined with ``{"a.b": 2}``). Notable Features ================ - :ref:`mmjsontransform-modes` — bidirectional conversion between dotted keys and nested containers. - :ref:`mmjsontransform-conflict-handling` — detailed conflict reporting to locate incompatible payloads quickly. Configuration Parameters ======================== .. note:: Parameter names are case-insensitive. For readability, camelCase is recommended. Action Parameters ----------------- .. list-table:: :widths: 30 70 :header-rows: 1 * - Parameter - Summary * - :ref:`param-mmjsontransform-input` - .. include:: ../../reference/parameters/mmjsontransform-input.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-mmjsontransform-output` - .. include:: ../../reference/parameters/mmjsontransform-output.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-mmjsontransform-mode` - .. include:: ../../reference/parameters/mmjsontransform-mode.rst :start-after: .. summary-start :end-before: .. summary-end .. _mmjsontransform-modes: Transformation modes ==================== ``mmjsontransform`` supports two modes controlled by the :ref:`mode ` parameter. Both modes rewrite the entire input object before assigning it to the configured output property. .. _mmjsontransform-mode-unflatten: Unflatten dotted keys --------------------- ``mode="unflatten"`` (the default) expands dotted keys into nested containers. For example ``{"a.b": 1, "a.c": 2}`` becomes ``{"a": {"b": 1, "c": 2}}``. When the module encounters a dotted path that points to an existing non-object value, it stops processing, leaves the output unset, and reports the conflicting path. .. _mmjsontransform-mode-flatten: Flatten nested containers ------------------------- ``mode="flatten"`` performs the reverse operation. Nested objects become dotted key paths (``{"nested": {"value": 1}}`` is rewritten to ``{"nested.value": 1}``), while arrays are preserved with their elements recursively flattened. If flattening would overwrite an existing scalar with a different value, the action fails and reports the mismatch. .. _mmjsontransform-conflict-handling: Conflict handling ================= The module tracks the full dotted path responsible for a hierarchy conflict and logs a user-facing error when a mismatch occurs. Review the reported path to identify which input property must be renamed or preprocessed before retrying the transformation. Examples ======== Normalize and persist dotted JSON --------------------------------- The following snippet receives JSON payloads, normalizes dotted keys into nested objects, and writes both the structured tree and a flattened representation to ``/tmp/out.json``:: module(load="mmjsontransform") module(load="imtcp") input(type="imtcp" port="10514" ruleset="process-json") ruleset(name="process-json") { action(type="mmjsontransform" input="$!raw" output="$!normalized") action(type="mmjsontransform" mode="flatten" input="$!normalized" output="$!normalized_flat") action(type="omfile" file="/tmp/out.json" template="json-template") } template(name="json-template" type="string" string="%$!normalized%\n%$!normalized_flat%\n") Troubleshooting =============== When a hierarchy conflict occurs (for example, ``mode="unflatten"`` sees ``"a": "value"`` and ``"a.b": 1``), ``mmjsontransform`` logs an error that includes the conflicting path. Inspect the reported path to determine which input property needs to be renamed or moved before retrying the transformation. .. toctree:: :hidden: ../../reference/parameters/mmjsontransform-input ../../reference/parameters/mmjsontransform-output ../../reference/parameters/mmjsontransform-mode rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/idx_parser.rst0000644000000000000000000000013115055603742024015 xustar0029 mtime=1756825570.25006828 30 atime=1764928593.250465532 30 ctime=1764935920.736539117 rsyslog-8.2512.0/doc/source/configuration/modules/idx_parser.rst0000664000175000017500000000064215055603742023464 0ustar00rgerrgerParser Modules -------------- Parser modules are used to parse message content, once the message has been received. They can be used to process custom message formats or invalidly formatted messages. For details, please see the :doc:`rsyslog message parser documentation <../../concepts/messageparser>`. The current modules are currently provided as part of rsyslog: .. toctree:: :glob: :maxdepth: 1 pm* rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/omgssapi.rst0000644000000000000000000000013215114522477023501 xustar0030 mtime=1764926783.024631588 30 atime=1764926783.449642023 30 ctime=1764935920.875541245 rsyslog-8.2512.0/doc/source/configuration/modules/omgssapi.rst0000664000175000017500000000666515114522477023162 0ustar00rgerrgerGSSAPI module support in rsyslog v3 =================================== What is it good for. - client-serverauthentication - Log messages encryption Requirements. - Kerberos infrastructure - rsyslog, rsyslog-gssapi Configuration. Let's assume there are 3 machines in Kerberos Realm: - the first is running KDC (Kerberos Authentication Service and Key Distribution Center), - the second is a client sending its logs to the server, - the third is receiver, gathering all logs. 1. KDC: - Kerberos database must be properly set-up on KDC machine first. Use kadmin/kadmin.local to do that. Two principals need to be add in our case: #. sender@REALM.ORG - client must have ticket for principal sender - REALM.ORG is kerberos Realm #. host/receiver.mydomain.com@REALM.ORG - service principal - Use ktadd to export service principal and transfer it to /etc/krb5.keytab on receiver 2. CLIENT: - set-up rsyslog, in /etc/rsyslog.conf - $ModLoad omgssapi - load output gss module - $GSSForwardServiceName otherThanHost - set the name of service principal, "host" is the default one - \*.\* :omgssapi:receiver.mydomain.com - action line, forward logs to receiver - kinit root - get the TGT ticket - service rsyslog start 3. SERVER: - set-up rsyslog, in /etc/rsyslog.conf - $ModLoad `imgssapi `_ - load input gss module - $InputGSSServerServiceName otherThanHost - set the name of service principal, "host" is the default one - $InputGSSServerPermitPlainTCP on - accept GSS and TCP connections (not authenticated senders), off by default - $InputGSSServerRun 514 - run server on port - service rsyslog start The picture demonstrate how things work. .. figure:: gssapi.png :align: center :alt: rsyslog gssapi support rsyslog gssapi support Configuration Parameters ======================== .. note:: Parameter names are case-insensitive; camelCase is recommended for readability. Module Parameters ----------------- .. list-table:: :widths: 30 70 :header-rows: 1 * - Parameter - Summary * - :ref:`param-omgssapi-gssforwardservicename` - .. include:: ../../reference/parameters/omgssapi-gssforwardservicename.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omgssapi-gssmode` - .. include:: ../../reference/parameters/omgssapi-gssmode.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omgssapi-actiongssforwarddefaulttemplate` - .. include:: ../../reference/parameters/omgssapi-actiongssforwarddefaulttemplate.rst :start-after: .. summary-start :end-before: .. summary-end Action Parameters ----------------- The ``omgssapi`` action is configured via module parameters. In modern ``action()`` syntax, it takes a ``target`` parameter and can optionally have a ``template`` assigned. Legacy ``:omgssapi:`` syntax is also supported and includes options for compression and TCP framing. These are specified in parentheses after the selector, for example ``:omgssapi:(z5,o)hostname``. - **z[0-9]**: Enables zlib compression. The optional digit specifies the compression level (0-9). Defaults to 9 if no digit is given. - **o**: Enables octet-counted TCP framing. .. toctree:: :hidden: ../../reference/parameters/omgssapi-gssforwardservicename ../../reference/parameters/omgssapi-gssmode ../../reference/parameters/omgssapi-actiongssforwarddefaulttemplate rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/omsnmp.rst0000644000000000000000000000013215071746523023172 xustar0030 mtime=1760021843.789420213 30 atime=1764928602.467748064 30 ctime=1764935920.919541919 rsyslog-8.2512.0/doc/source/configuration/modules/omsnmp.rst0000664000175000017500000000772515071746523022651 0ustar00rgerrger******************************* omsnmp: SNMP Trap Output Module ******************************* =========================== =========================================================================== **Module Name:**  **omsnmp** **Author:** Andre Lorbach =========================== =========================================================================== Purpose ======= Provides the ability to send syslog messages as an SNMPv1 & v2c traps. By default, SNMPv2c is preferred. The syslog message is wrapped into a OCTED STRING variable. This module uses the `NET-SNMP `_ library. In order to compile this module, you will need to have the `NET-SNMP `_ developer (headers) package installed. Configuration Parameters ======================== .. note:: Parameter names are case-insensitive; camelCase is recommended for readability. Action Parameters ----------------- .. list-table:: :widths: 30 70 :header-rows: 1 * - Parameter - Summary * - :ref:`param-omsnmp-server` - .. include:: ../../reference/parameters/omsnmp-server.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-port` - .. include:: ../../reference/parameters/omsnmp-port.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-transport` - .. include:: ../../reference/parameters/omsnmp-transport.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-version` - .. include:: ../../reference/parameters/omsnmp-version.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-community` - .. include:: ../../reference/parameters/omsnmp-community.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-trapoid` - .. include:: ../../reference/parameters/omsnmp-trapoid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-messageoid` - .. include:: ../../reference/parameters/omsnmp-messageoid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-enterpriseoid` - .. include:: ../../reference/parameters/omsnmp-enterpriseoid.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-specifictype` - .. include:: ../../reference/parameters/omsnmp-specifictype.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-snmpv1dynsource` - .. include:: ../../reference/parameters/omsnmp-snmpv1dynsource.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-omsnmp-traptype` - .. include:: ../../reference/parameters/omsnmp-traptype.rst :start-after: .. summary-start :end-before: .. summary-end .. toctree:: :hidden: ../../reference/parameters/omsnmp-server ../../reference/parameters/omsnmp-port ../../reference/parameters/omsnmp-transport ../../reference/parameters/omsnmp-version ../../reference/parameters/omsnmp-community ../../reference/parameters/omsnmp-trapoid ../../reference/parameters/omsnmp-messageoid ../../reference/parameters/omsnmp-enterpriseoid ../../reference/parameters/omsnmp-specifictype ../../reference/parameters/omsnmp-snmpv1dynsource ../../reference/parameters/omsnmp-traptype Caveats/Known Bugs ================== - In order to decode the custom OIDs, you will need to have the adiscon mibs installed. Examples ======== Sending messages as snmp traps ------------------------------ The following commands send every message as a snmp trap. .. code-block:: none module(load="omsnmp") action(type="omsnmp" server="localhost" port="162" transport="udp" version="1" community="public") rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/ompipe.rst0000644000000000000000000000013215055603742023147 xustar0030 mtime=1756825570.253068328 30 atime=1764928601.989733485 30 ctime=1764935920.905541705 rsyslog-8.2512.0/doc/source/configuration/modules/ompipe.rst0000664000175000017500000000331615055603742022616 0ustar00rgerrgerompipe: Pipe Output Module ========================== **Module Name:    ompipe** **Author:**\ Rainer Gerhards **Description**: The ompipe plug-in provides the core functionality for logging output to named pipes (fifos). It is a built-in module that does not need to be loaded. **Global Configuration Parameters:** Note: parameter names are case-insensitive. - Template: [templateName] sets a new default template for file actions. **Action specific Configuration Parameters:** Note: parameter names are case-insensitive. - Pipe: string a fifo or named pipe can be used as a destination for log messages. - tryResumeReopen: Sometimes we need to reopen a pipe after an ompipe action gets suspended. Sending a HUP signal does the job but requires an interaction with rsyslog. When set to "on" and a resume action fails, the file descriptor is closed, causing a new open in the next resume. Default: "off" to preserve existing behavior before introduction of this option. **Caveats/Known Bugs:** None **Sample:** The following command sends all syslog messages to a pipe named "NameofPipe". ::     Module (path="builtin:ompipe")     *.* action(type="ompipe" Pipe="NameofPipe") **Legacy Configuration Parameters:** rsyslog has support for logging output to named pipes (fifos). A fifo or named pipe can be used as a destination for log messages by prepending a pipe symbol ("|") to the name of the file. This is handy for debugging. Note that the fifo must be created with the mkfifo(1) command before rsyslogd is started. **Legacy Sample:** The following command sends all syslog messages to a pipe named /var/log/pipe. ::     $ModLoad ompipe     *.* |/var/log/pipe rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/impstats.rst0000644000000000000000000000013215114522477023523 xustar0030 mtime=1764926783.023631563 30 atime=1764926784.231661215 30 ctime=1764935920.779539775 rsyslog-8.2512.0/doc/source/configuration/modules/impstats.rst0000664000175000017500000002352515114522477023176 0ustar00rgerrger*********************************************************** impstats: Generate Periodic Statistics of Internal Counters *********************************************************** =========================== =========================================================================== **Module Name:**  **impstats** **Author:** `Rainer Gerhards `_ =========================== =========================================================================== Purpose ======= This module provides periodic output of rsyslog internal counters. The set of available counters will be output as a set of syslog messages. This output is periodic, with the interval being configurable (default is 5 minutes). Be sure that your configuration records the counter messages (default is syslog.=info). Besides logging to the regular syslog stream, the module can also be configured to write statistics data into a (local) file. When logging to the regular syslog stream, impstats records are emitted just like regular log messages. As such, counters increase when processing these messages. This must be taken into consideration when testing and troubleshooting. Note that loading this module has some impact on rsyslog performance. Depending on settings, this impact may be noticeable for high-load environments, but in general the overhead is pretty light. **Note that there is a** `rsyslog statistics online analyzer `_ **available.** It can be given a impstats-generated file and will return problems it detects. Note that the analyzer cannot replace a human in getting things right, but it is expected to be a good aid in starting to understand and gain information from the pstats logs. The rsyslog website has an overview of available `rsyslog statistic counters `_. When browsing this page, please be sure to take note of which rsyslog version is required to provide a specific counter. Counters are continuously being added, and older versions do not support everything. Notable Features ================ - :ref:`impstats-statistic-counter` Configuration Parameters ======================== The configuration parameters for this module are designed for tailoring the method and process for outputting the rsyslog statistics to file. .. note:: Parameter names are case-insensitive; camelCase is recommended for improved readability. .. note:: This module supports module parameters, only. Module Parameters ----------------- .. list-table:: :widths: 30 70 :header-rows: 1 * - Parameter - Summary * - :ref:`param-impstats-interval` - .. include:: ../../reference/parameters/impstats-interval.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-facility` - .. include:: ../../reference/parameters/impstats-facility.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-severity` - .. include:: ../../reference/parameters/impstats-severity.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-resetcounters` - .. include:: ../../reference/parameters/impstats-resetcounters.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-format` - .. include:: ../../reference/parameters/impstats-format.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-log-syslog` - .. include:: ../../reference/parameters/impstats-log-syslog.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-log-file` - .. include:: ../../reference/parameters/impstats-log-file.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-ruleset` - .. include:: ../../reference/parameters/impstats-ruleset.rst :start-after: .. summary-start :end-before: .. summary-end * - :ref:`param-impstats-bracketing` - .. include:: ../../reference/parameters/impstats-bracketing.rst :start-after: .. summary-start :end-before: .. summary-end .. _impstats-statistic-counter: Statistic Counter ================= The impstats plugin gathers some internal :doc:`statistics <../rsyslog_statistic_counter>`. They have different names depending on the actual statistics. Obviously, they do not relate to the plugin itself but rather to a broader object – most notably the rsyslog process itself. The "resource-usage" counter maintains process statistics. They base on the getrusage() system call. The counters are named like getrusage returned data members. So for details, looking them up in "man getrusage" is highly recommended, especially as value may be different depending on the platform. A getrusage() call is done immediately before the counter is emitted. The following individual counters are maintained: - ``utime`` - this is the user time in microseconds (thus the timeval structure combined) - ``stime`` - again, time given in microseconds - ``maxrss`` - ``minflt`` - ``majflt`` - ``inblock`` - ``outblock`` - ``nvcsw`` - ``nivcsw`` - ``openfiles`` - number of file handles used by rsyslog; includes actual files, sockets and others Format ------ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "legacy", "no", "none" .. versionadded:: 8.16.0 Specifies the format of emitted stats messages. The default of "legacy" is compatible with pre v6-rsyslog. The other options provide support for structured formats (note the "cee" is actually "project lumberjack" logging). The json-elasticsearch format supports the broken ElasticSearch JSON implementation. ES 2.0 no longer supports valid JSON and disallows dots inside names. The "json-elasticsearch" format option replaces those dots by the bang ("!") character. So "discarded.full" becomes "discarded!full". The zabbix format supports arrayed-JSON objects with a single JSON object per pstats emission to disk or syslog. This format should be compatible with most JSON parsers from other monitoring products. log.file is highly recommended as log.syslog may encounter message truncation problems if the emission is large. If you must use log.syslog, it's recommended to monitor pstats for truncation and increase $MaxMessageSize at the top of your main rsyslog configuration file. Options: json/json-elasticsearch/cee/legacy/zabbix Caveats/Known Bugs ================== - This module MUST be loaded right at the top of rsyslog.conf, otherwise stats may not get turned on in all places. - When using the format "zabbix", it is not recommended to use logSyslog="on". This can cause message truncation in stats. Examples ======== Load module, send stats data to syslog stream --------------------------------------------- This activates the module and records messages to /var/log/rsyslog-stats in 10 minute intervals: .. code-block:: rsyslog module(load="impstats" interval="600" severity="7") # to actually gather the data: syslog.=debug /var/log/rsyslog-stats Load module, format the output to Zabbix, and output to a local file -------------------------------------------------------------------- .. code-block:: rsyslog module(loadf="impstats" interval="60" severity="7" format="zabbix" logSyslog="off" logFile="/var/log/stats.log") Load module, send stats data to local file ------------------------------------------ Here, the default interval of 5 minutes is used. However, this time, stats data is NOT emitted to the syslog stream but to a local file instead. .. code-block:: rsyslog module(load="impstats" interval="600" severity="7" logSyslog="off" # need to turn log stream logging off! logFile="/path/to/local/stats.log") Load module, send stats data to local file and syslog stream ------------------------------------------------------------ Here we log to both the regular syslog log stream as well as a file. Within the log stream, we forward the data records to another server: .. code-block:: rsyslog module(load="impstats" interval="600" severity="7" logFile="/path/to/local/stats.log") syslog.=debug @central.example.net Explanation of output ===================== Example output for illustration:: Sep 17 11:43:49 localhost rsyslogd-pstats: imuxsock: submitted=16 Sep 17 11:43:49 localhost rsyslogd-pstats: main Q: size=1 enqueued=2403 full=0 maxqsize=2 Explanation: All objects are shown in the results with a separate counter, one object per line. Line 1: shows details for - ``imuxsock``, an object - ``submitted=16``, a counter showing that 16 messages were received by the imuxsock object. Line 2: shows details for the main queue: - ``main Q``, an object - ``size``, messages in the queue - ``enqueued``, all received messages thus far - ``full``, how often was the queue was full - ``maxqsize``, the maximum amount of messages that have passed through the queue since rsyslog was started See Also ======== - `rsyslog statistics counter `_ - `impstats delayed or lost `_ - cause and cure .. toctree:: :hidden: ../../reference/parameters/impstats-interval ../../reference/parameters/impstats-facility ../../reference/parameters/impstats-severity ../../reference/parameters/impstats-resetcounters ../../reference/parameters/impstats-format ../../reference/parameters/impstats-log-syslog ../../reference/parameters/impstats-log-file ../../reference/parameters/impstats-ruleset ../../reference/parameters/impstats-bracketing rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/omhttpfs.rst0000644000000000000000000000013215055603742023522 xustar0030 mtime=1756825570.253068328 30 atime=1764928601.262711287 30 ctime=1764935920.885541398 rsyslog-8.2512.0/doc/source/configuration/modules/omhttpfs.rst0000664000175000017500000000600415055603742023166 0ustar00rgerrger************************************* omhttpfs: Hadoop HTTPFS Output Module ************************************* =========================== =========================================================================== **Module Name:** **omhttpfs** **Available Since:** **8.10.0** **Author:** `sskaje `_ =========================== =========================================================================== Purpose ======= This module is an alternative to omhdfs via `Hadoop HDFS over HTTP `_. Dependencies ============ * libcurl Configuration Parameters ======================== .. note:: Parameter names are case-insensitive. Action Parameters ----------------- Host ^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "127.0.0.1", "no", "none" HttpFS server host. Port ^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "integer", "14000", "no", "none" HttpFS server port. User ^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "hdfs", "no", "none" HttpFS auth user. https ^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "binary", "off", "no", "none" Turn on if your HttpFS runs on HTTPS. File ^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "none", "yes", "none" File to write, or a template name. isDynFile ^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "binary", "off", "no", "none" Turn this on if your **file** is a template name. See examples below. Template ^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "RSYSLOG_FileFormat", "no", "none" Format your message when writing to **file**. Default: *RSYSLOG_FileFormat* Configure ========= .. code-block:: none ./configure --enable-omhttpfs Examples ======== Example 1 --------- .. code-block:: none module(load="omhttpfs") template(name="hdfs_tmp_file" type="string" string="/tmp/%$YEAR%/test.log") template(name="hdfs_tmp_filecontent" type="string" string="%$YEAR%-%$MONTH%-%$DAY% %MSG% ==\n") local4.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on") local5.* action(type="omhttpfs" host="10.1.1.161" port="14000" https="off" file="hdfs_tmp_file" isDynFile="on" template="hdfs_tmp_filecontent") rsyslog-8.2512.0/doc/source/configuration/modules/PaxHeaders/omrelp.rst0000644000000000000000000000013215071746523023157 xustar0030 mtime=1760021843.789420213 30 atime=1764928602.267741964 30 ctime=1764935920.912541812 rsyslog-8.2512.0/doc/source/configuration/modules/omrelp.rst0000664000175000017500000003553515071746523022636 0ustar00rgerrger************************** omrelp: RELP Output Module ************************** =========================== =========================================================================== **Module Name:**  **omrelp** **Author:** `Rainer Gerhards `_ =========================== =========================================================================== Purpose ======= This module supports sending syslog messages over the reliable RELP protocol. For RELP's advantages over plain tcp syslog, please see the documentation for :doc:`imrelp ` (the server counterpart).  Setup Please note that `librelp `__ is required for imrelp (it provides the core relp protocol implementation). Configuration Parameters ======================== .. note:: Parameter names are case-insensitive. Module Parameters ----------------- tls.tlslib ^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "none", "no", "none" .. versionadded:: 8.1903.0 Permits to specify the TLS library used by librelp. All relp protocol operations or actually performed by librelp and not rsyslog itself. This value specified is directly passed down to librelp. Depending on librelp version and build parameters, supported tls libraries differ (or TLS may not be supported at all). In this case rsyslog emits an error message. Usually, the following options should be available: "openssl", "gnutls". Note that "gnutls" is the current default for historic reasons. We actually recommend to use "openssl". It provides better error messages and accepts a wider range of certificate types. If you have problems with the default setting, we recommend to switch to "openssl". Action Parameters ----------------- Target ^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "none", "yes", "none" The target server to connect to. Port ^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "514", "no", "none" Name or numerical value of TCP port to use when connecting to target. Template ^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "RSYSLOG_ForwardFormat", "no", "none" Defines the template to be used for the output. Timeout ^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "int", "90", "no", "none" Timeout for relp sessions. If set too low, valid sessions may be considered dead and tried to recover. Conn.Timeout ^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "int", "10", "no", "none" Timeout for the socket connection. RebindInterval ^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "int", "0", "no", "none" Permits to specify an interval at which the current connection is broken and re-established. This setting is primarily an aid to load balancers. After the configured number of messages has been transmitted, the current connection is terminated and a new one started. This usually is perceived as a \`\`new connection'' by load balancers, which in turn forward messages to another physical target system. KeepAlive ^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "binary", "off", "no", "none" Enable or disable keep-alive packets at the TCP socket layer. By default keep-alive is disabled. KeepAlive.Probes ^^^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "integer", "0", "no", "none" The number of keepalive probes to send before considering the connection dead. The default, 0, uses the operating system defaults. This only has an effect if keep-alive is enabled and may not be available on all platforms. KeepAlive.Interval ^^^^^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "integer", "0", "no", "none" The interval between subsequent keepalive probes. The default, 0, uses the operating system defaults. This only has an effect if keep-alive is enabled and may not be available on all platforms. KeepAlive.Time ^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "integer", "0", "no", "none" The idle time before the first keepalive probe is sent. The default, 0, uses the operating system defaults. This only has an effect if keep-alive is enabled and may not be available on all platforms. WindowSize ^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "int", "0", "no", "none" This is an **expert parameter**. It permits to override the RELP window size being used by the client. Changing the window size has both an effect on performance as well as potential message duplication in failure case. A larger window size means more performance, but also potentially more duplicated messages - and vice versa. The default 0 means that librelp's default window size is being used, which is considered a compromise between goals reached. For your information: at the time of this writing, the librelp default window size is 128 messages, but this may change at any time. Note that there is no equivalent server parameter, as the client proposes and manages the window size in RELP protocol. TLS ^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "binary", "off", "no", "none" If set to "on", the RELP connection will be encrypted by TLS, so that the data is protected against observers. Please note that both the client and the server must have set TLS to either "on" or "off". Other combinations lead to unpredictable results. *Attention when using GnuTLS 2.10.x or older* Versions older than GnuTLS 2.10.x may cause a crash (Segfault) under certain circumstances. Most likely when an imrelp inputs and an omrelp output is configured. The crash may happen when you are receiving/sending messages at the same time. Upgrade to a newer version like GnuTLS 2.12.21 to solve the problem. TLS.Compression ^^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "binary", "off", "no", "none" The controls if the TLS stream should be compressed (zipped). While this increases CPU use, the network bandwidth should be reduced. Note that typical text-based log records usually compress rather well. TLS.PermittedPeer ^^^^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "array", "none", "no", "none" Note: this parameter is mandatory depending on the value of `TLS.AuthMode` but the code does currently not check this. Peer Places access restrictions on this forwarder. Only peers which have been listed in this parameter may be connected to. This guards against rogue servers and man-in-the-middle attacks. The validation bases on the certificate the remote peer presents. This contains either remote system names or fingerprints, depending on the value of parameter `TLS.AuthMode`. One or more values may be entered. When a non-permitted peer is connected to, the refusal is logged together with the given remote peer identify. This is especially useful in *fingerprint* authentication mode: if the administrator knows this was a valid request, he can simply add the fingerprint by copy and paste from the logfile to rsyslog.conf. It must be noted, though, that this situation should usually not happen after initial client setup and administrators should be alert in this case. Note that usually a single remote peer should be all that is ever needed. Support for multiple peers is primarily included in support of load balancing scenarios. If the connection goes to a specific server, only one specific certificate is ever expected (just like when connecting to a specific ssh server). To specify multiple fingerprints, just enclose them in braces like this: .. code-block:: none tls.permittedPeer=["SHA1:...1", "SHA1:....2"] To specify just a single peer, you can either specify the string directly or enclose it in braces. Note that in *name* authentication mode wildcards are supported. This can be done as follows: .. code-block:: none tls.permittedPeer="*.example.com" Of course, there can also be multiple names used, some with and some without wildcards: .. code-block:: none tls.permittedPeer=["*.example.com", "srv1.example.net", "srv2.example.net"] TLS.AuthMode ^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" Sets the mode used for mutual authentication. Supported values are either "*fingerprint*" or "*name*". Fingerprint mode basically is what SSH does. It does not require a full PKI to be present, instead self-signed certs can be used on all peers. Even if a CA certificate is given, the validity of the peer cert is NOT verified against it. Only the certificate fingerprint counts. In "name" mode, certificate validation happens. Here, the matching is done against the certificate's subjectAltName and, as a fallback, the subject common name. If the certificate contains multiple names, a match on any one of these names is considered good and permits the peer to talk to rsyslog. The permitted names or fingerprints are configured via `TLS.PermittedPeer`. About Chained Certificates -------------------------- .. versionadded:: 8.2008.0 With librelp 1.7.0, you can use chained certificates. If using "openssl" as tls.tlslib, we recommend at least OpenSSL Version 1.1 or higher. Chained certificates will also work with OpenSSL Version 1.0.2, but they will be loaded into the main OpenSSL context object making them available to all librelp instances (omrelp/imrelp) within the same process. If this is not desired, you will require to run rsyslog in multiple instances with different omrelp configurations and certificates. TLS.CaCert ^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" The CA certificate that can verify the machine certs. TLS.MyCert ^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" The machine public certificate. TLS.MyPrivKey ^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" The machine private key. TLS.PriorityString ^^^^^^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" This parameter permits to specify the so-called "priority string" to GnuTLS. This string gives complete control over all crypto parameters, including compression setting. For this reason, when the prioritystring is specified, the "tls.compression" parameter has no effect and is ignored. Full information about how to construct a priority string can be found in the GnuTLS manual. At the time of this writing, this information was contained in `section 6.10 of the GnuTLS manual `__. **Note: this is an expert parameter.** Do not use if you do not exactly know what you are doing. tls.tlscfgcmd ^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "string", "none", "no", "none" .. versionadded:: 8.2001.0 The setting can be used if tls.tlslib is set to "openssl" to pass configuration commands to the openssl library. OpenSSL Version 1.0.2 or higher is required for this feature. A list of possible commands and their valid values can be found in the documentation: https://docs.openssl.org/1.0.2/man3/SSL_CONF_cmd/ The setting can be single or multiline, each configuration command is separated by linefeed (\n). Command and value are separated by equal sign (=). Here are a few samples: Example 1 --------- This will allow all protocols except for SSLv2 and SSLv3: .. code-block:: none tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3" Example 2 --------- This will allow all protocols except for SSLv2, SSLv3 and TLSv1. It will also set the minimum protocol to TLSv1.2 .. code-block:: none tls.tlscfgcmd="Protocol=ALL,-SSLv2,-SSLv3,-TLSv1 MinProtocol=TLSv1.2" LocalClientIp ^^^^^^^^^^^^^ .. csv-table:: :header: "type", "default", "mandatory", "|FmtObsoleteName| directive" :widths: auto :class: parameter-table "word", "none", "no", "none" Omrelp uses ip_address as local client address while connecting to remote logserver. Examples ======== Sending msgs with omrelp ------------------------ The following sample sends all messages to the central server "centralserv" at port 2514 (note that the server must run imrelp on port 2514). .. code-block:: none module(load="omrelp") action(type="omrelp" target="centralserv" port="2514") Sending msgs with omrelp via TLS ------------------------------------ This is the same as the previous example but uses TLS (via OpenSSL) for operations. Certificate files must exist at configured locations. Note that authmode "certvalid" is not very strong - you may want to use a different one for actual deployments. For details, see parameter descriptions. .. code-block:: none module(load="omrelp" tls.tlslib="openssl") action(type="omrelp" target="centralserv" port="2514" tls="on" tls.cacert="tls-certs/ca.pem" tls.mycert="tls-certs/cert.pem" tls.myprivkey="tls-certs/key.pem" tls.authmode="certvalid" tls.permittedpeer="rsyslog") |FmtObsoleteName| directives ============================ This module uses old-style action configuration to keep consistent with the forwarding rule. So far, no additional configuration directives can be specified. To send a message via RELP, use .. code-block:: none *.*  :omrelp::;