~ubuntu-branches/ubuntu/karmic/rsyslog/karmic-200908151517

« back to all changes in this revision

Viewing changes to template.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2008-04-23 16:46:39 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080423164639-5acmt8a4vpxjgnxw
Tags: 3.14.2-3
* debian/rsyslog-doc.install
  - Fix a typo in the install path of the dia files. Closes: #477489
    Thanks to Justin B Rye for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* This is the template processing code of rsyslog.
2
2
 * Please see syslogd.c for license information.
3
 
 * This code is placed under the GPL.
4
3
 * begun 2004-11-17 rgerhards
 
4
 *
 
5
 * Copyright 2004, 2007 Rainer Gerhards and Adiscon
 
6
 *
 
7
 * This file is part of rsyslog.
 
8
 *
 
9
 * Rsyslog is free software: you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation, either version 3 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * Rsyslog is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with Rsyslog.  If not, see <http://www.gnu.org/licenses/>.
 
21
 *
 
22
 * A copy of the GPL can be found in the file "COPYING" in this distribution.
5
23
 */
6
24
#include "config.h"
7
25
 
8
 
#ifdef __FreeBSD__
9
 
#define BSD
10
 
#endif
11
 
 
12
26
#include "rsyslog.h"
13
27
#include <stdio.h>
14
28
#include <stdlib.h>
20
34
#include "template.h"
21
35
#include "msg.h"
22
36
#include "syslogd.h"
23
 
 
 
37
#include "obj.h"
 
38
#include "errmsg.h"
 
39
 
 
40
/* static data */
 
41
DEFobjCurrIf(obj)
 
42
DEFobjCurrIf(errmsg)
 
43
DEFobjCurrIf(regexp)
 
44
 
 
45
static int bFirstRegexpErrmsg = 1; /**< did we already do a "can't load regexp" error message? */
24
46
static struct template *tplRoot = NULL; /* the root of the template list */
25
47
static struct template *tplLast = NULL; /* points to the last element of the template list */
26
48
static struct template *tplLastStatic = NULL; /* last static element of the template list */
50
72
{
51
73
        DEFiRet;
52
74
        struct templateEntry *pTpe;
53
 
        rsCStrObj *pCStr;
 
75
        cstr_t *pCStr;
54
76
        unsigned short bMustBeFreed;
55
77
        uchar *pVal;
56
78
        size_t iLenVal;
64
86
         * free the obtained value (if requested). We continue this
65
87
         * loop until we got hold of all values.
66
88
         */
67
 
        if((pCStr = rsCStrConstruct()) == NULL) {
68
 
                dbgprintf("memory shortage, tplToString failed\n");
69
 
                ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
70
 
        }
 
89
        CHKiRet(rsCStrConstruct(&pCStr));
71
90
 
72
91
        pTpe = pTpl->pEntryRoot;
73
92
        while(pTpe != NULL) {
78
97
                                                         ) {
79
98
                                dbgprintf("error %d during tplToString()\n", iRet);
80
99
                                /* it does not make sense to continue now */
81
 
                                rsCStrDestruct(pCStr);
 
100
                                rsCStrDestruct(&pCStr);
82
101
                                FINALIZE;
83
102
                        }
84
103
                } else  if(pTpe->eEntryType == FIELD) {
98
117
                        CHKiRet_Hdlr(rsCStrAppendStrWithLen(pCStr, (uchar*) pVal, iLenVal)) {
99
118
                                dbgprintf("error %d during tplToString()\n", iRet);
100
119
                                /* it does not make sense to continue now */
101
 
                                rsCStrDestruct(pCStr);
 
120
                                rsCStrDestruct(&pCStr);
102
121
                                if(bMustBeFreed)
103
122
                                        free(pVal);
104
123
                                FINALIZE;
118
137
finalize_it:
119
138
        *ppSz = (iRet == RS_RET_OK) ? pVal : NULL;
120
139
 
121
 
        return iRet;
 
140
        RETiRet;
122
141
}
123
142
 
124
143
/* Helper to doSQLEscape. This is called if doSQLEscape
173
192
{
174
193
        uchar *p;
175
194
        int iLen;
176
 
        rsCStrObj *pStrB;
 
195
        cstr_t *pStrB;
177
196
        uchar *pszGenerated;
178
197
 
179
198
        assert(pp != NULL);
195
214
 
196
215
        p = *pp;
197
216
        iLen = *pLen;
198
 
        if((pStrB = rsCStrConstruct()) == NULL) {
 
217
        if(rsCStrConstruct(&pStrB) != RS_RET_OK) {
199
218
                /* oops - no mem ... Do emergency... */
200
219
                doSQLEmergencyEscape(p, escapeMode);
201
220
                return;
205
224
                if(*p == '\'') {
206
225
                        if(rsCStrAppendChar(pStrB, (escapeMode == 0) ? '\'' : '\\') != RS_RET_OK) {
207
226
                                doSQLEmergencyEscape(*pp, escapeMode);
208
 
                                rsCStrDestruct(pStrB);
 
227
                                rsCStrDestruct(&pStrB);
209
228
                                return;
210
229
                                }
211
230
                        iLen++; /* reflect the extra character */
212
231
                } else if((escapeMode == 1) && (*p == '\\')) {
213
232
                        if(rsCStrAppendChar(pStrB, '\\') != RS_RET_OK) {
214
233
                                doSQLEmergencyEscape(*pp, escapeMode);
215
 
                                rsCStrDestruct(pStrB);
 
234
                                rsCStrDestruct(&pStrB);
216
235
                                return;
217
236
                                }
218
237
                        iLen++; /* reflect the extra character */
219
238
                }
220
239
                if(rsCStrAppendChar(pStrB, *p) != RS_RET_OK) {
221
240
                        doSQLEmergencyEscape(*pp, escapeMode);
222
 
                        rsCStrDestruct(pStrB);
 
241
                        rsCStrDestruct(&pStrB);
223
242
                        return;
224
243
                }
225
244
                ++p;
299
318
static int do_Constant(unsigned char **pp, struct template *pTpl)
300
319
{
301
320
        register unsigned char *p;
302
 
        rsCStrObj *pStrB;
 
321
        cstr_t *pStrB;
303
322
        struct templateEntry *pTpe;
304
323
        int i;
305
324
 
309
328
 
310
329
        p = *pp;
311
330
 
312
 
        if((pStrB = rsCStrConstruct()) == NULL)
 
331
        if(rsCStrConstruct(&pStrB) != RS_RET_OK)
313
332
                 return 1;
314
333
        rsCStrSetAllocIncrement(pStrB, 32);
315
334
        /* process the message and expand escapes
424
443
                 */
425
444
                 if(!strcmp((char*)Buf, "date-mysql")) {
426
445
                        pTpe->data.field.eDateFormat = tplFmtMySQLDate;
 
446
                 } else if(!strcmp((char*)Buf, "date-pgsql")) {
 
447
                        pTpe->data.field.eDateFormat = tplFmtPgSQLDate;
427
448
                 } else if(!strcmp((char*)Buf, "date-rfc3164")) {
428
449
                        pTpe->data.field.eDateFormat = tplFmtRFC3164Date;
429
450
                 } else if(!strcmp((char*)Buf, "date-rfc3339")) {
460
481
static int do_Parameter(unsigned char **pp, struct template *pTpl)
461
482
{
462
483
        unsigned char *p;
463
 
        rsCStrObj *pStrB;
 
484
        cstr_t *pStrB;
464
485
        struct templateEntry *pTpe;
465
486
        int iNum;       /* to compute numbers */
 
487
        rsRetVal iRetLocal;
466
488
 
467
489
#ifdef FEATURE_REGEXP
468
 
        /* APR: variables for regex */
469
 
        int longitud;
470
 
        unsigned char *regex_char;
 
490
        /* APR: variables for regex */
 
491
        int longitud;
 
492
        unsigned char *regex_char;
471
493
        unsigned char *regex_end;
472
494
#endif
473
495
 
477
499
 
478
500
        p = (unsigned char*) *pp;
479
501
 
480
 
        if((pStrB = rsCStrConstruct()) == NULL)
 
502
        if(rsCStrConstruct(&pStrB) != RS_RET_OK)
481
503
                 return 1;
482
504
 
483
505
        if((pTpe = tpeConstruct(pTpl)) == NULL) {
507
529
                        if (*p != ':') {
508
530
                                /* There is something more than an R , this is invalid ! */
509
531
                                /* Complain on extra characters */
510
 
                                logerrorSz
511
 
                                  ("error: invalid character in frompos after \"R\", property: '%%%s'",
 
532
                                errmsg.LogError(NO_ERRCODE, "error: invalid character in frompos after \"R\", property: '%%%s'",
512
533
                                    (char*) *pp);
513
534
                        } else {
514
535
                                pTpe->data.field.has_regex = 1;
532
553
                                        pTpe->data.field.has_fields = 1;
533
554
                                        if(!isdigit((int)*p)) {
534
555
                                                /* complain and use default */
535
 
                                                logerrorSz
536
 
                                                  ("error: invalid character in frompos after \"F,\", property: '%%%s' - using 9 (HT) as field delimiter",
 
556
                                                errmsg.LogError(NO_ERRCODE, "error: invalid character in frompos after \"F,\", property: '%%%s' - using 9 (HT) as field delimiter",
537
557
                                                    (char*) *pp);
538
558
                                                pTpe->data.field.field_delim = 9;
539
559
                                        } else {
541
561
                                                while(isdigit((int)*p))
542
562
                                                        iNum = iNum * 10 + *p++ - '0';
543
563
                                                if(iNum < 0 || iNum > 255) {
544
 
                                                        logerrorInt
545
 
                                                          ("error: non-USASCII delimiter character value in template - using 9 (HT) as substitute", iNum);
 
564
                                                        errmsg.LogError(NO_ERRCODE, "error: non-USASCII delimiter character value %d in template - using 9 (HT) as substitute", iNum);
546
565
                                                        pTpe->data.field.field_delim = 9;
547
566
                                                  } else {
548
567
                                                        pTpe->data.field.field_delim = iNum;
552
571
                                        /* invalid character after F, so we need to reject
553
572
                                         * this.
554
573
                                         */
555
 
                                        logerrorSz
556
 
                                          ("error: invalid character in frompos after \"F\", property: '%%%s'",
 
574
                                        errmsg.LogError(NO_ERRCODE, "error: invalid character in frompos after \"F\", property: '%%%s'",
557
575
                                            (char*) *pp);
558
576
                                }
559
577
                        } else {
594
612
                                longitud = regex_end - p;
595
613
                                /* Malloc for the regex string */
596
614
                                regex_char = (unsigned char *) malloc(longitud + 1);
597
 
                                if (regex_char == NULL) {
598
 
                                        dbgprintf
599
 
                                            ("Could not allocate memory for template parameter!\n");
 
615
                                if(regex_char == NULL) {
 
616
                                        dbgprintf("Could not allocate memory for template parameter!\n");
600
617
                                        pTpe->data.field.has_regex = 0;
601
618
                                        return 1;
602
619
                                        /* TODO: RGer: check if we can recover better... (probably not) */
610
627
 
611
628
                                /* Now i compile the regex */
612
629
                                /* Remember that the re is an attribute of the Template entry */
613
 
                                if(regcomp(&(pTpe->data.field.re), (char*) regex_char, 0) != 0) {
614
 
                                        dbgprintf("error: can not compile regex: '%s'\n", regex_char);
 
630
                                if((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) {
 
631
dbgprintf("compile data.field.re ptr: %p (pTpe %p)\n", (&(pTpe->data.field.re)), pTpe);
 
632
                                        if(regexp.regcomp(&(pTpe->data.field.re), (char*) regex_char, 0) != 0) {
 
633
                                                dbgprintf("error: can not compile regex: '%s'\n", regex_char);
 
634
                                                pTpe->data.field.has_regex = 2;
 
635
                                        }
 
636
                                } else {
 
637
                                        /* regexp object could not be loaded */
 
638
                                        dbgprintf("error %d trying to load regexp library - this may be desired and thus OK",
 
639
                                                  iRetLocal);
 
640
                                        if(bFirstRegexpErrmsg) { /* prevent flood of messages, maybe even an endless loop! */
 
641
                                                bFirstRegexpErrmsg = 0;
 
642
                                                errmsg.LogError(NO_ERRCODE, "regexp library could not be loaded (error %d), "
 
643
                                                                "regexp ignored", iRetLocal);
 
644
                                        }
615
645
                                        pTpe->data.field.has_regex = 2;
616
646
                                }
617
647
 
649
679
#endif /* #ifdef FEATURE_REGEXP */
650
680
        }
651
681
 
652
 
        /* TODO: add more sanity checks. For now, we do the bare minimum */
653
682
        if((pTpe->data.field.has_fields == 0) && (pTpe->data.field.iToPos < pTpe->data.field.iFromPos)) {
654
683
                iNum = pTpe->data.field.iToPos;
655
684
                pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
820
849
{
821
850
        struct template *pTpl, *pTplDel;
822
851
        struct templateEntry *pTpe, *pTpeDel;
 
852
        rsRetVal iRetLocal;
 
853
        BEGINfunc
823
854
 
824
855
        pTpl = tplRoot;
825
856
        while(pTpl != NULL) {
839
870
                                free(pTpeDel->data.constant.pConstant);
840
871
                                break;
841
872
                        case FIELD:
 
873
                                /* check if we have a regexp and, if so, delete it */
 
874
                                if(pTpeDel->data.field.has_regex != 0) {
 
875
                                        if((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) {
 
876
                                                regexp.regfree(&(pTpeDel->data.field.re));
 
877
                                        }
 
878
                                }
842
879
                                /*dbgprintf("(FIELD), value: '%s'", pTpeDel->data.field.pPropRepl);*/
843
880
                                free(pTpeDel->data.field.pPropRepl);
844
881
                                break;
852
889
                        free(pTplDel->pszName);
853
890
                free(pTplDel);
854
891
        }
 
892
        ENDfunc
855
893
}
856
894
 
 
895
 
857
896
/* Destroy all templates obtained from conf file
858
 
 * preserving hadcoded ones. This is called from init().
 
897
 * preserving hardcoded ones. This is called from init().
859
898
 */
860
899
void tplDeleteNew(void)
861
900
{
862
901
        struct template *pTpl, *pTplDel;
863
902
        struct templateEntry *pTpe, *pTpeDel;
 
903
        rsRetVal iRetLocal;
 
904
 
 
905
        BEGINfunc
864
906
 
865
907
        if(tplRoot == NULL || tplLastStatic == NULL)
866
908
                return;
885
927
                                free(pTpeDel->data.constant.pConstant);
886
928
                                break;
887
929
                        case FIELD:
 
930
                                /* check if we have a regexp and, if so, delete it */
 
931
                                if(pTpeDel->data.field.has_regex != 0) {
 
932
                                        if((iRetLocal = objUse(regexp, LM_REGEXP_FILENAME)) == RS_RET_OK) {
 
933
                                                regexp.regfree(&(pTpeDel->data.field.re));
 
934
                                        }
 
935
                                }
888
936
                                /*dbgprintf("(FIELD), value: '%s'", pTpeDel->data.field.pPropRepl);*/
889
937
                                free(pTpeDel->data.field.pPropRepl);
890
938
                                break;
898
946
                        free(pTplDel->pszName);
899
947
                free(pTplDel);
900
948
        }
 
949
        ENDfunc
901
950
}
902
951
 
903
952
/* Store the pointer to the last hardcoded teplate */
924
973
                dbgprintf("\n");
925
974
                pTpe = pTpl->pEntryRoot;
926
975
                while(pTpe != NULL) {
927
 
                        dbgprintf("\tEntry(%x): type %d, ", (unsigned) pTpe, pTpe->eEntryType);
 
976
                        dbgprintf("\tEntry(%lx): type %d, ", (unsigned long) pTpe, pTpe->eEntryType);
928
977
                        switch(pTpe->eEntryType) {
929
978
                        case UNDEFINED:
930
979
                                dbgprintf("(UNDEFINED)");
941
990
                                case tplFmtMySQLDate:
942
991
                                        dbgprintf("[Format as MySQL-Date] ");
943
992
                                        break;
 
993
                                case tplFmtPgSQLDate:
 
994
                                        dbgprintf("[Format as PgSQL-Date] ");
 
995
                                        break;
944
996
                                case tplFmtRFC3164Date:
945
997
                                        dbgprintf("[Format as RFC3164-Date] ");
946
998
                                        break;
995
1047
        assert(pTpl != NULL);
996
1048
        return(pTpl->tpenElements);
997
1049
}
 
1050
 
 
1051
/* our init function. TODO: remove once converted to a class
 
1052
 */
 
1053
rsRetVal templateInit()
 
1054
{
 
1055
        DEFiRet;
 
1056
        CHKiRet(objGetObjInterface(&obj));
 
1057
        CHKiRet(objUse(errmsg, CORE_COMPONENT));
 
1058
 
 
1059
finalize_it:
 
1060
        RETiRet;
 
1061
}
 
1062
 
998
1063
/*
999
1064
 * vi:set ai:
1000
1065
 */