summaryrefslogtreecommitdiffstats
path: root/template.h
blob: 271e82712b8f69ee23cd0d3eb85dfba4cd1ae957 (plain)
1
2
3
4
5
6
7
8
9
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
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
/* This is the header for template processing code of rsyslog.
 * Please see syslogd.c for license information.
 * begun 2004-11-17 rgerhards
 *
 * Copyright (C) 2004 by 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 <http://www.gnu.org/licenses/>.
 *
 * A copy of the GPL can be found in the file "COPYING" in this distribution.
 */

#ifndef	TEMPLATE_H_INCLUDED
#define	TEMPLATE_H_INCLUDED 1

#include "regexp.h"
#include "stringbuf.h"

struct template {
	struct template *pNext;
	char *pszName;
	int iLenName;
	int tpenElements; /* number of elements in templateEntry list */
	struct templateEntry *pEntryRoot;
	struct templateEntry *pEntryLast;
	char optFormatForSQL;	/* in text fields,  0 - do not escape,
	                         * 1 - escape quotes by double quotes,
				 * 2 - escape "the MySQL way" 
				 */
	/* following are options. All are 0/1 defined (either on or off).
	 * we use chars because they are faster than bit fields and smaller
	 * than short...
	 */
};

enum EntryTypes { UNDEFINED = 0, CONSTANT = 1, FIELD = 2 };
enum tplFormatTypes { tplFmtDefault = 0, tplFmtMySQLDate = 1,
                      tplFmtRFC3164Date = 2, tplFmtRFC3339Date = 3, tplFmtPgSQLDate = 4,
		      tplFmtSecFrac = 5};
enum tplFormatCaseConvTypes { tplCaseConvNo = 0, tplCaseConvUpper = 1, tplCaseConvLower = 2 };

#include "msg.h"

/* a specific parse entry */
struct templateEntry {
	struct templateEntry *pNext;
	enum EntryTypes eEntryType;
	union {
		struct {
			uchar *pConstant;	/* pointer to constant value */
			int iLenConstant;	/* its length */
		} constant;
		struct {
			propid_t propid;	/* property to be used */
			unsigned iFromPos;	/* for partial strings only chars from this position ... */
			unsigned iToPos;	/* up to that one... */
#ifdef FEATURE_REGEXP
			regex_t re;	/* APR: this is the regular expression */
			short has_regex;
			short iMatchToUse;/* which match should be obtained (10 max) */
			short iSubMatchToUse;/* which submatch should be obtained (10 max) */
			enum {
				TPL_REGEX_BRE = 0, /* posix BRE */
				TPL_REGEX_ERE = 1  /* posix ERE */
			} typeRegex;
			enum {
				TPL_REGEX_NOMATCH_USE_DFLTSTR = 0, /* use the (old style) default "**NO MATCH**" string */
				TPL_REGEX_NOMATCH_USE_BLANK = 1, /* use a blank string */
				TPL_REGEX_NOMATCH_USE_WHOLE_FIELD = 2, /* use the full field contents that we were searching in*/
				TPL_REGEX_NOMATCH_USE_ZERO = 3 /* use  0 (useful for numerical values) */
			}  nomatchAction;	/**< what to do if we do not have a match? */
			
#endif
			unsigned has_fields; /* support for field-counting: field to extract */
			unsigned char field_delim; /* support for field-counting: field delemiter char */
			int field_expand;	/* use multiple instances of the field delimiter as a single one? */

			enum tplFormatTypes eDateFormat;
			enum tplFormatCaseConvTypes eCaseConv;
			struct { 		/* bit fields! */
				unsigned bDropCC: 1;		/* drop control characters? */
				unsigned bSpaceCC: 1;		/* change control characters to spaceescape? */
				unsigned bEscapeCC: 1;		/* escape control characters? */
				unsigned bDropLastLF: 1;	/* drop last LF char in msg (PIX!) */
				unsigned bSecPathDrop: 1;	/* drop slashes, replace dots, empty string */
				unsigned bSecPathReplace: 1;	/* replace slashes, replace dots, empty string */
				unsigned bSPIffNo1stSP: 1;	/* replace slashes, replace dots, empty string */
				unsigned bCSV: 1;		/* format field in CSV (RFC 4180) format */
			} options;		/* options as bit fields */
		} field;
	} data;
};


/* interfaces */
BEGINinterface(tpl) /* name must also be changed in ENDinterface macro! */
ENDinterface(tpl)
#define tplCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */

/* prototypes */
PROTOTYPEObj(tpl);


struct template* tplConstruct(void);
struct template *tplAddLine(char* pName, unsigned char** pRestOfConfLine);
struct template *tplFind(char *pName, int iLenName);
int tplGetEntryCount(struct template *pTpl);
void tplDeleteAll(void);
void tplDeleteNew(void);
void tplPrintList(void);
void tplLastStaticInit(struct template *tpl);
/* note: if a compiler warning for undefined type tells you to look at this
 * code line below, the actual cause is that you currently MUST include template.h
 * BEFORE msg.h, even if your code file does not actually need it.
 * rgerhards, 2007-08-06
 */
rsRetVal tplToArray(struct template *pTpl, msg_t *pMsg, uchar*** ppArr);
rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar** ppSz, size_t *);
rsRetVal doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode);

rsRetVal templateInit();

#endif /* #ifndef TEMPLATE_H_INCLUDED */
/* vim:set ai:
 */