1 /*
2 * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <ctype.h>
20 #define SYSLOG_NAMES
21 #include "dstruct.h"
22 #include "eval.h"
23 #include "syntax.h"
24 #include "syslog.h"
25 #include "pmapi.h"
26
27 #if defined(IS_SOLARIS) || defined(IS_AIX) || defined(IS_MINGW)
28 #include "logger.h"
29 #endif
30
31 /*
32 * based on source for logger(1)
33 */
34 static int
35 decode(char *name, CODE *codetab)
36 {
37 CODE *c;
38
39 if (isdigit((int)*name))
40 return (atoi(name));
41
42 for (c = codetab; c->c_name; c++)
43 if (!strcasecmp(name, c->c_name))
44 return (c->c_val);
45
46 return (-1);
47 }
48
49 /*
50 * Decode a symbolic name to a numeric value
51 * ... based on source for logger(1)
52 */
53 static int
54 pencode(char *s)
55 {
56 char *save;
57 int fac, lev;
58
59 save = s;
60 while (*s && *s != '.') ++s;
61 if (*s) {
62 *s = '\0';
63 fac = decode(save, facilitynames);
64 if (fac < 0) {
65 synwarn();
66 fprintf(stderr, "Ignoring unknown facility (%s) for -p in syslog action\n", save);
67 fac = 0;
68 }
69 s++;
70 }
71 else {
72 fac = 0;
73 s = save;
74 }
75 lev = decode(s, prioritynames);
76 if (lev < 0) {
77 synwarn();
78 fprintf(stderr, "Ignoring unknown priority (%s) for -p in syslog action\n", s);
79 lev = LOG_NOTICE;
80 }
81 return ((lev & LOG_PRIMASK) | (fac & LOG_FACMASK));
82 }
83
84 /*
85 * handle splitting of -t tag and -p prio across one or two
86 * arguments to the syslog action in the rule
87 */
88 static void
89 nextch(char **p, Expr **x)
90 {
91 static char end = '\0';
92 (*p)++;
93 while (**p == '\0') {
94 if ((*x)->arg1 == NULL) {
95 *p = &end;
96 return;
97 }
98 *x = (*x)->arg1;
99 *p = (*x)->ring;
100 }
101 }
102
103 /*
104 * post-process the expression tree for a syslog action to gather
105 * any -t tag or -p pri options (as for logger(1)) and build the
106 * encoded equivalent as a new expression accessed via arg2 from
107 * the head of the arguments list
108 */
109 void
110 do_syslog_args(Expr *act)
111 {
112 int pri = -1;
113 char *tag = NULL;
114 char *p;
115 char *q;
116 Expr *others;
117 Expr *tmp;
118 Expr *new;
119
120 others = act->arg1;
121 /*
122 * scan for -p pri and -t tag
123 */
|
At conditional (1): "others != NULL": Taking true branch.
|
124 for (others = act->arg1; others != NULL; ) {
|
At conditional (2): "others->ring == NULL": Taking true branch.
|
125 if (others->ring == NULL) break;
126 p = others->ring;
127 if (*p != '-') break;
128 nextch(&p, &others);
129 if (*p == 'p' && pri == -1) {
130 nextch(&p, &others);
131 while (*p && isspace((int)*p)) nextch(&p, &others);
132 if (*p == '\0') {
133 synwarn();
134 fprintf(stderr, "Missing [facility.]priority after -p in syslog action\n");
135 }
136 else {
137 q = p+1;
138 while (*q && !isspace((int)*q)) q++;
139 if (*q) {
140 synwarn();
141 fprintf(stderr, "Ignoring extra text (%s) after -p pri in syslog action\n", q);
142 *q = '\0';
143 }
144 pri = pencode(p);
145 }
146 }
147 else if (*p == 't' && tag == NULL) {
148 nextch(&p, &others);
149 while (*p && isspace((int)*p)) nextch(&p, &others);
150 if (*p == '\0') {
151 synwarn();
152 fprintf(stderr, "Missing tag after -t in syslog action\n");
153 }
154 else {
155 q = p+1;
156 while (*q && !isspace((int)*q)) q++;
157 if (*q) {
158 synwarn();
159 fprintf(stderr, "Ignoring extra text (%s) after -t tag in syslog action\n", q);
160 *q = '\0';
161 }
162 tag = p;
163 }
164 }
165 else
166 break;
167 others = others->arg1;
168 }
169
170 /* defaults if -t and/or -p not seen */
|
At conditional (3): "pri < 0": Taking true branch.
|
171 if (pri < 0) pri = LOG_NOTICE;
|
At conditional (4): "tag == NULL": Taking true branch.
|
172 if (tag == NULL) tag = "pcp-pmie";
173
174 /*
175 * construct new arg2 argument node, with
176 * ring -> pri (int) and tag (char *) concatenated
177 */
178 new = (Expr *) zalloc(sizeof(Expr));
179 new->op = NOP;
180 new->ring = (char *)alloc(sizeof(int)+strlen(tag)+1);
181 *((int *)new->ring) = pri;
|
Event alloc_fn: |
Calling allocation function "sdup". [details] |
|
Event noescape: |
Variable "sdup(tag)" is not freed or pointed-to in function "strcpy". |
|
Event leaked_storage: |
Failing to save storage allocated by "sdup(tag)" leaks it. |
182 strcpy(&((char *)new->ring)[sizeof(int)], sdup(tag));
183 act->arg2 = new;
184 new->parent = act;
185
186 /* free old argument nodes used for -p and/or -t specifications */
187 for (tmp = act->arg1; tmp != others; ) {
188 if (tmp->ring) {
189 free(tmp->ring);
190 }
191 new = tmp->arg1;
192 free(tmp);
193 tmp = new;
194 }
195
196 /* re-link remaining argument nodes */
197 if (others != act->arg1) {
198 act->arg1 = others;
199 if (others != NULL)
200 others->parent = act;
201 }
202
203 }