1
/* This is the output channel processing code of rsyslog.
2
* Output channels - in the long term - will define how
3
* messages will be sent to whatever file or other medium.
4
* Currently, they mainly provide a way to store some file-related
5
* information (most importantly the maximum file size allowed).
6
* Please see syslogd.c for license information.
7
* This code is placed under the GPL.
8
* begun 2005-06-21 rgerhards
23
#include "stringbuf.h"
24
#include "outchannel.h"
27
static struct outchannel *ochRoot = NULL; /* the root of the outchannel list */
28
static struct outchannel *ochLast = NULL; /* points to the last element of the outchannel list */
30
/* Constructs a outchannel list object. Returns pointer to it
31
* or NULL (if it fails).
33
struct outchannel* ochConstruct(void)
35
struct outchannel *pOch;
36
if((pOch = calloc(1, sizeof(struct outchannel))) == NULL)
39
/* basic initialisaion is done via calloc() - need to
40
* initialize only values != 0. */
43
{ /* we are the first element! */
44
ochRoot = ochLast = pOch;
48
ochLast->pNext = pOch;
56
/* skips the next comma and any whitespace
57
* in front and after it.
59
static void skip_Comma(char **pp)
67
while(isspace((int)*p))
71
while(isspace((int)*p))
76
/* helper to ochAddLine. Parses a comma-delimited field
77
* The field is delimited by SP or comma. Leading whitespace
78
* is "eaten" and does not become part of the field content.
79
* returns: 0 - ok, 1 - failure
81
static int get_Field(uchar **pp, uchar **pField)
88
assert(pField != NULL);
90
skip_Comma((char**)pp);
93
if((pStrB = rsCStrConstruct()) == NULL)
95
rsCStrSetAllocIncrement(pStrB, 32);
98
while(*p && *p != ' ' && *p != ',') {
99
rsCStrAppendChar(pStrB, *p++);
104
if(rsCStrConvSzStrAndDestruct(pStrB, pField, 0) != RS_RET_OK)
111
/* helper to ochAddLine. Parses a off_t type from the
113
* returns: 0 - ok, 1 - failure
115
static int get_off_t(uchar **pp, off_t *pOff_t)
122
assert(pOff_t != NULL);
124
skip_Comma((char**)pp);
128
while(*p && isdigit((int)*p)) {
129
val = val * 10 + (*p - '0');
140
/* helper to ochAddLine. Parses everything from the
141
* current position to the end of line and returns it
142
* to the caller. Leading white space is removed, but
144
* returns: 0 - ok, 1 - failure
146
static inline int get_restOfLine(uchar **pp, uchar **pBuf)
153
assert(pBuf != NULL);
155
skip_Comma((char**)pp);
158
if((pStrB = rsCStrConstruct()) == NULL)
160
rsCStrSetAllocIncrement(pStrB, 32);
164
rsCStrAppendChar(pStrB, *p++);
169
if(rsCStrConvSzStrAndDestruct(pStrB, pBuf, 0) != RS_RET_OK)
176
/* Add a new outchannel line
177
* returns pointer to new object if it succeeds, NULL otherwise.
178
* An outchannel line is primarily a set of fields delemited by commas.
179
* There might be some whitespace between the field (but not within)
180
* and the commas. This can be removed.
182
struct outchannel *ochAddLine(char* pName, uchar** ppRestOfConfLine)
184
struct outchannel *pOch;
187
assert(pName != NULL);
188
assert(ppRestOfConfLine != NULL);
190
if((pOch = ochConstruct()) == NULL)
193
pOch->iLenName = strlen(pName);
194
pOch->pszName = (char*) malloc(sizeof(char) * (pOch->iLenName + 1));
195
if(pOch->pszName == NULL) {
196
dbgprintf("ochAddLine could not alloc memory for outchannel name!");
199
/* I know - we create a memory leak here - but I deem
200
* it acceptable as it is a) a very small leak b) very
201
* unlikely to happen. rgerhards 2004-11-17
204
memcpy(pOch->pszName, pName, pOch->iLenName + 1);
206
/* now actually parse the line */
207
p = *ppRestOfConfLine;
211
get_Field(&p, &pOch->pszFileTemplate);
212
if(*p) get_off_t(&p, &pOch->uSizeLimit);
213
if(*p) get_restOfLine(&p, &pOch->cmdOnSizeLimit);
215
*ppRestOfConfLine = p;
220
/* Find a outchannel object based on name. Search
221
* currently is case-senstive (should we change?).
222
* returns pointer to outchannel object if found and
224
* rgerhards 2004-11-17
226
struct outchannel *ochFind(char *pName, int iLenName)
228
struct outchannel *pOch;
230
assert(pName != NULL);
233
while(pOch != NULL &&
234
!(pOch->iLenName == iLenName &&
235
!strcmp(pOch->pszName, pName)
243
/* Destroy the outchannel structure. This is for de-initialization
244
* at program end. Everything is deleted.
245
* rgerhards 2005-02-22
247
void ochDeleteAll(void)
249
struct outchannel *pOch, *pOchDel;
252
while(pOch != NULL) {
253
dbgprintf("Delete Outchannel: Name='%s'\n ", pOch->pszName == NULL? "NULL" : pOch->pszName);
256
if(pOchDel->pszName != NULL)
257
free(pOchDel->pszName);
263
/* Print the outchannel structure. This is more or less a
264
* debug or test aid, but anyhow I think it's worth it...
266
void ochPrintList(void)
268
struct outchannel *pOch;
271
while(pOch != NULL) {
272
dbgprintf("Outchannel: Name='%s'\n", pOch->pszName == NULL? "NULL" : pOch->pszName);
273
dbgprintf("\tFile Template: '%s'\n", pOch->pszFileTemplate == NULL ? "NULL" : (char*) pOch->pszFileTemplate);
274
dbgprintf("\tMax Size.....: %lu\n", pOch->uSizeLimit);
275
dbgprintf("\tOnSizeLimtCmd: '%s'\n", pOch->cmdOnSizeLimit == NULL ? "NULL" : (char*) pOch->cmdOnSizeLimit);
276
pOch = pOch->pNext; /* done, go next */