summaryrefslogtreecommitdiffstats
path: root/template.h
blob: e41823e9a31528365a3d9f95de509c7fdf314655 (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
138
139
140
141
142
143
144
145
146
147
/* 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-2012 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 <libestr.h>
#include "regexp.h"
#include "stringbuf.h"

struct template {
	struct template *pNext;
	char *pszName;
	int iLenName;
	rsRetVal (*pStrgen)(msg_t*, uchar**, size_t *);	/* name of strgen to use (bound if non-NULL!) */
	int tpenElements; /* number of elements in templateEntry list */
	struct templateEntry *pEntryRoot;
	struct templateEntry *pEntryLast;
	char optFormatEscape;	/* in text fields, */
#	define NO_ESCAPE 0	/* 0 - do not escape, */
#	define SQL_ESCAPE 1	/* 1 - escape "the MySQL way"  */
#	define STDSQL_ESCAPE 2  /* 2 - escape quotes by double quotes, */
#	define JSON_ESCAPE 3	/* 3 - escape double quotes for JSON.  */
	/* 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, tplFmtRFC3164BuggyDate = 6, tplFmtUnixDate};
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... */
			unsigned iFieldNr;	/* for field extraction: field to extract */
#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? */

			es_str_t *propName;	/**< property name (currently being used for CEE only) */
			es_str_t *fieldName;	/**< field name to be used for structured output */

			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;	/* be a space if 1st pos if field is no space*/
				unsigned bCSV: 1;		/* format field in CSV (RFC 4180) format */
				unsigned bJSON: 1;		/* format field JSON escaped */
				unsigned bJSONf: 1;		/* format field JSON *field* (n/v pair) */
			} 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(rsconf_t *conf, char* pName, unsigned char** pRestOfConfLine);
struct template *tplFind(rsconf_t *conf, char *pName, int iLenName);
int tplGetEntryCount(struct template *pTpl);
void tplDeleteAll(rsconf_t *conf);
void tplDeleteNew(rsconf_t *conf);
void tplPrintList(rsconf_t *conf);
void tplLastStaticInit(rsconf_t *conf, struct template *tpl);
rsRetVal ExtendBuf(uchar **pBuf, size_t *pLenBuf, size_t iMinSize);
/* 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 doEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode);

rsRetVal templateInit();

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