annotate src/syslogconfig.cpp @ 2:6e88da080f08

initial coding
author carl
date Thu, 24 Nov 2005 10:31:09 -0800
parents 551433a01cab
children 8fe310e5cd44
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
551433a01cab initial coding
carl
parents:
diff changeset
1 /***************************************************************************
551433a01cab initial coding
carl
parents:
diff changeset
2 * Copyright (C) 2005 by 510 Software Group *
551433a01cab initial coding
carl
parents:
diff changeset
3 * *
551433a01cab initial coding
carl
parents:
diff changeset
4 * *
551433a01cab initial coding
carl
parents:
diff changeset
5 * This program is free software; you can redistribute it and/or modify *
551433a01cab initial coding
carl
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by *
551433a01cab initial coding
carl
parents:
diff changeset
7 * the Free Software Foundation; either version 2 of the License, or *
551433a01cab initial coding
carl
parents:
diff changeset
8 * (at your option) any later version. *
551433a01cab initial coding
carl
parents:
diff changeset
9 * *
551433a01cab initial coding
carl
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful, *
551433a01cab initial coding
carl
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
551433a01cab initial coding
carl
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
551433a01cab initial coding
carl
parents:
diff changeset
13 * GNU General Public License for more details. *
551433a01cab initial coding
carl
parents:
diff changeset
14 * *
551433a01cab initial coding
carl
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License *
551433a01cab initial coding
carl
parents:
diff changeset
16 * along with this program; if not, write to the *
551433a01cab initial coding
carl
parents:
diff changeset
17 * Free Software Foundation, Inc., *
551433a01cab initial coding
carl
parents:
diff changeset
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
551433a01cab initial coding
carl
parents:
diff changeset
19 ***************************************************************************/
551433a01cab initial coding
carl
parents:
diff changeset
20
551433a01cab initial coding
carl
parents:
diff changeset
21 #include "includes.h"
2
6e88da080f08 initial coding
carl
parents: 1
diff changeset
22 #include <fcntl.h>
1
551433a01cab initial coding
carl
parents:
diff changeset
23
551433a01cab initial coding
carl
parents:
diff changeset
24 static char* syslogconfig_version="$Id$";
551433a01cab initial coding
carl
parents:
diff changeset
25
551433a01cab initial coding
carl
parents:
diff changeset
26 char *token_cisco;
551433a01cab initial coding
carl
parents:
diff changeset
27 char *token_file;
551433a01cab initial coding
carl
parents:
diff changeset
28 char *token_include;
551433a01cab initial coding
carl
parents:
diff changeset
29 char *token_lbrace;
551433a01cab initial coding
carl
parents:
diff changeset
30 char *token_parser;
551433a01cab initial coding
carl
parents:
diff changeset
31 char *token_rbrace;
551433a01cab initial coding
carl
parents:
diff changeset
32 char *token_semi;
551433a01cab initial coding
carl
parents:
diff changeset
33 char *token_ssh;
551433a01cab initial coding
carl
parents:
diff changeset
34
551433a01cab initial coding
carl
parents:
diff changeset
35 string_set all_strings; // owns all the strings, only modified by the config loader thread
551433a01cab initial coding
carl
parents:
diff changeset
36 const int maxlen = 1000; // used for snprintf buffers
551433a01cab initial coding
carl
parents:
diff changeset
37
551433a01cab initial coding
carl
parents:
diff changeset
38
551433a01cab initial coding
carl
parents:
diff changeset
39 CONFIG::CONFIG() {
551433a01cab initial coding
carl
parents:
diff changeset
40 reference_count = 0;
551433a01cab initial coding
carl
parents:
diff changeset
41 generation = 0;
551433a01cab initial coding
carl
parents:
diff changeset
42 load_time = 0;
551433a01cab initial coding
carl
parents:
diff changeset
43 }
551433a01cab initial coding
carl
parents:
diff changeset
44
551433a01cab initial coding
carl
parents:
diff changeset
45
551433a01cab initial coding
carl
parents:
diff changeset
46 CONFIG::~CONFIG() {
551433a01cab initial coding
carl
parents:
diff changeset
47 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) {
551433a01cab initial coding
carl
parents:
diff changeset
48 SYSLOGCONFIG *c = *i;
551433a01cab initial coding
carl
parents:
diff changeset
49 delete c;
551433a01cab initial coding
carl
parents:
diff changeset
50 }
551433a01cab initial coding
carl
parents:
diff changeset
51 }
551433a01cab initial coding
carl
parents:
diff changeset
52
551433a01cab initial coding
carl
parents:
diff changeset
53
551433a01cab initial coding
carl
parents:
diff changeset
54 void CONFIG::add_syslogconfig(SYSLOGCONFIGP con) {
551433a01cab initial coding
carl
parents:
diff changeset
55 syslogconfigs.push_back(con);
551433a01cab initial coding
carl
parents:
diff changeset
56 }
551433a01cab initial coding
carl
parents:
diff changeset
57
551433a01cab initial coding
carl
parents:
diff changeset
58
551433a01cab initial coding
carl
parents:
diff changeset
59 void CONFIG::dump() {
551433a01cab initial coding
carl
parents:
diff changeset
60 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) {
551433a01cab initial coding
carl
parents:
diff changeset
61 SYSLOGCONFIGP c = *i;
551433a01cab initial coding
carl
parents:
diff changeset
62 c->dump(0);
551433a01cab initial coding
carl
parents:
diff changeset
63 }
551433a01cab initial coding
carl
parents:
diff changeset
64 }
551433a01cab initial coding
carl
parents:
diff changeset
65
551433a01cab initial coding
carl
parents:
diff changeset
66
2
6e88da080f08 initial coding
carl
parents: 1
diff changeset
67 void CONFIG::read() {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
68 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
69 SYSLOGCONFIGP c = *i;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
70 c->read();
6e88da080f08 initial coding
carl
parents: 1
diff changeset
71 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
72 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
73
6e88da080f08 initial coding
carl
parents: 1
diff changeset
74
6e88da080f08 initial coding
carl
parents: 1
diff changeset
75 SYSLOGCONFIG::SYSLOGCONFIG(TOKEN &tok, char *file_name_, parser_style parser_) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
76 file_name = file_name_;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
77 parser = parser_;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
78 fd = open(file_name, O_RDONLY);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
79 len = 0;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
80 if (fd == -1) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
81 char buf[maxlen];
6e88da080f08 initial coding
carl
parents: 1
diff changeset
82 snprintf(buf, sizeof(buf), "syslog file %s not readable", file_name);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
83 tok.token_error(buf);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
84 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
85 else {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
86 lseek(fd, 0, SEEK_END);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
87 }
1
551433a01cab initial coding
carl
parents:
diff changeset
88 }
551433a01cab initial coding
carl
parents:
diff changeset
89
551433a01cab initial coding
carl
parents:
diff changeset
90
551433a01cab initial coding
carl
parents:
diff changeset
91 SYSLOGCONFIG::~SYSLOGCONFIG() {
2
6e88da080f08 initial coding
carl
parents: 1
diff changeset
92 if (fd != -1) close(fd);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
93 fd = -1;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
94 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
95
6e88da080f08 initial coding
carl
parents: 1
diff changeset
96
6e88da080f08 initial coding
carl
parents: 1
diff changeset
97 void SYSLOGCONFIG::read() {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
98 if (failed()) return;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
99 int n = ::read(fd, buf, buflen-len);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
100 if (n > 0) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
101 len += n;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
102 while (true) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
103 char *p = (char*)memchr(buf, '\n', len);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
104 if (!p) break;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
105 n = p-buf;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
106 *p = '\0';
6e88da080f08 initial coding
carl
parents: 1
diff changeset
107 process(); // process null terminated string
6e88da080f08 initial coding
carl
parents: 1
diff changeset
108 len -= n+1;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
109 memmove(buf, p+1, len);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
110 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
111 // no <lf> in a full buffer
6e88da080f08 initial coding
carl
parents: 1
diff changeset
112 if (len == buflen) len = 0;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
113 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
114 }
6e88da080f08 initial coding
carl
parents: 1
diff changeset
115
6e88da080f08 initial coding
carl
parents: 1
diff changeset
116
6e88da080f08 initial coding
carl
parents: 1
diff changeset
117 void SYSLOGCONFIG::process() {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
118 my_syslog(buf);
1
551433a01cab initial coding
carl
parents:
diff changeset
119 }
551433a01cab initial coding
carl
parents:
diff changeset
120
551433a01cab initial coding
carl
parents:
diff changeset
121
551433a01cab initial coding
carl
parents:
diff changeset
122 void SYSLOGCONFIG::dump(int level) {
551433a01cab initial coding
carl
parents:
diff changeset
123 char indent[maxlen];
551433a01cab initial coding
carl
parents:
diff changeset
124 int i = min(maxlen-1, level*4);
551433a01cab initial coding
carl
parents:
diff changeset
125 memset(indent, ' ', i);
551433a01cab initial coding
carl
parents:
diff changeset
126 indent[i] = '\0';
551433a01cab initial coding
carl
parents:
diff changeset
127 char buf[maxlen];
551433a01cab initial coding
carl
parents:
diff changeset
128 printf("%s file \"%s\" {\n", indent, file_name);
551433a01cab initial coding
carl
parents:
diff changeset
129 switch (parser) {
551433a01cab initial coding
carl
parents:
diff changeset
130 case cisco:
551433a01cab initial coding
carl
parents:
diff changeset
131 printf("%s parser cisco; \n", indent);
551433a01cab initial coding
carl
parents:
diff changeset
132 break;
551433a01cab initial coding
carl
parents:
diff changeset
133 case ssh:
551433a01cab initial coding
carl
parents:
diff changeset
134 printf("%s parser ssh; \n", indent);
551433a01cab initial coding
carl
parents:
diff changeset
135 break;
551433a01cab initial coding
carl
parents:
diff changeset
136 }
551433a01cab initial coding
carl
parents:
diff changeset
137 printf("%s }; \n", indent);
551433a01cab initial coding
carl
parents:
diff changeset
138 }
551433a01cab initial coding
carl
parents:
diff changeset
139
551433a01cab initial coding
carl
parents:
diff changeset
140
551433a01cab initial coding
carl
parents:
diff changeset
141 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
142 // helper to discard the strings held by a string_set
551433a01cab initial coding
carl
parents:
diff changeset
143 //
551433a01cab initial coding
carl
parents:
diff changeset
144 void discard(string_set &s) {
551433a01cab initial coding
carl
parents:
diff changeset
145 for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
551433a01cab initial coding
carl
parents:
diff changeset
146 free(*i);
551433a01cab initial coding
carl
parents:
diff changeset
147 }
551433a01cab initial coding
carl
parents:
diff changeset
148 s.clear();
551433a01cab initial coding
carl
parents:
diff changeset
149 }
551433a01cab initial coding
carl
parents:
diff changeset
150
551433a01cab initial coding
carl
parents:
diff changeset
151
551433a01cab initial coding
carl
parents:
diff changeset
152 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
153 // helper to register a string in a string set
551433a01cab initial coding
carl
parents:
diff changeset
154 //
551433a01cab initial coding
carl
parents:
diff changeset
155 char* register_string(string_set &s, char *name) {
551433a01cab initial coding
carl
parents:
diff changeset
156 string_set::iterator i = s.find(name);
551433a01cab initial coding
carl
parents:
diff changeset
157 if (i != s.end()) return *i;
551433a01cab initial coding
carl
parents:
diff changeset
158 char *x = strdup(name);
551433a01cab initial coding
carl
parents:
diff changeset
159 s.insert(x);
551433a01cab initial coding
carl
parents:
diff changeset
160 return x;
551433a01cab initial coding
carl
parents:
diff changeset
161 }
551433a01cab initial coding
carl
parents:
diff changeset
162
551433a01cab initial coding
carl
parents:
diff changeset
163
551433a01cab initial coding
carl
parents:
diff changeset
164 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
165 // register a global string
551433a01cab initial coding
carl
parents:
diff changeset
166 //
551433a01cab initial coding
carl
parents:
diff changeset
167 char* register_string(char *name) {
551433a01cab initial coding
carl
parents:
diff changeset
168 return register_string(all_strings, name);
551433a01cab initial coding
carl
parents:
diff changeset
169 }
551433a01cab initial coding
carl
parents:
diff changeset
170
551433a01cab initial coding
carl
parents:
diff changeset
171
551433a01cab initial coding
carl
parents:
diff changeset
172 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
173 //
551433a01cab initial coding
carl
parents:
diff changeset
174 bool tsa(TOKEN &tok, char *token);
551433a01cab initial coding
carl
parents:
diff changeset
175 bool tsa(TOKEN &tok, char *token) {
551433a01cab initial coding
carl
parents:
diff changeset
176 char *have = tok.next();
551433a01cab initial coding
carl
parents:
diff changeset
177 if (have == token) return true;
551433a01cab initial coding
carl
parents:
diff changeset
178 tok.token_error(token, have);
551433a01cab initial coding
carl
parents:
diff changeset
179 return false;
551433a01cab initial coding
carl
parents:
diff changeset
180 }
551433a01cab initial coding
carl
parents:
diff changeset
181
551433a01cab initial coding
carl
parents:
diff changeset
182
551433a01cab initial coding
carl
parents:
diff changeset
183 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
184 //
551433a01cab initial coding
carl
parents:
diff changeset
185 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc);
551433a01cab initial coding
carl
parents:
diff changeset
186 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc) {
551433a01cab initial coding
carl
parents:
diff changeset
187 char *name = tok.next();
551433a01cab initial coding
carl
parents:
diff changeset
188 parser_style parser;
551433a01cab initial coding
carl
parents:
diff changeset
189 if (!tsa(tok, token_lbrace)) return false;
551433a01cab initial coding
carl
parents:
diff changeset
190 while (true) {
551433a01cab initial coding
carl
parents:
diff changeset
191 char *have = tok.next();
551433a01cab initial coding
carl
parents:
diff changeset
192 if (have == token_parser) {
551433a01cab initial coding
carl
parents:
diff changeset
193 have = tok.next();
551433a01cab initial coding
carl
parents:
diff changeset
194 if (have == token_cisco) parser = cisco;
551433a01cab initial coding
carl
parents:
diff changeset
195 else if (have == token_ssh) parser = ssh;
551433a01cab initial coding
carl
parents:
diff changeset
196 else {
551433a01cab initial coding
carl
parents:
diff changeset
197 tok.token_error("cisco/ssh", have);
551433a01cab initial coding
carl
parents:
diff changeset
198 return false;
551433a01cab initial coding
carl
parents:
diff changeset
199 }
551433a01cab initial coding
carl
parents:
diff changeset
200 if (!tsa(tok, token_semi)) return false;
551433a01cab initial coding
carl
parents:
diff changeset
201 }
551433a01cab initial coding
carl
parents:
diff changeset
202 else if (have == token_rbrace) {
551433a01cab initial coding
carl
parents:
diff changeset
203 break; // done
551433a01cab initial coding
carl
parents:
diff changeset
204 }
551433a01cab initial coding
carl
parents:
diff changeset
205 else {
551433a01cab initial coding
carl
parents:
diff changeset
206 tok.token_error("file keyword", have);
551433a01cab initial coding
carl
parents:
diff changeset
207 return false;
551433a01cab initial coding
carl
parents:
diff changeset
208 }
551433a01cab initial coding
carl
parents:
diff changeset
209 }
551433a01cab initial coding
carl
parents:
diff changeset
210 if (!tsa(tok, token_semi)) return false;
2
6e88da080f08 initial coding
carl
parents: 1
diff changeset
211 SYSLOGCONFIGP con = new SYSLOGCONFIG(tok, name, parser);
6e88da080f08 initial coding
carl
parents: 1
diff changeset
212 if (con->failed()) {
6e88da080f08 initial coding
carl
parents: 1
diff changeset
213 delete con;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
214 return false;
6e88da080f08 initial coding
carl
parents: 1
diff changeset
215 }
1
551433a01cab initial coding
carl
parents:
diff changeset
216 dc.add_syslogconfig(con);
551433a01cab initial coding
carl
parents:
diff changeset
217 return true;
551433a01cab initial coding
carl
parents:
diff changeset
218 }
551433a01cab initial coding
carl
parents:
diff changeset
219
551433a01cab initial coding
carl
parents:
diff changeset
220
551433a01cab initial coding
carl
parents:
diff changeset
221 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
222 // parse a config file
551433a01cab initial coding
carl
parents:
diff changeset
223 //
551433a01cab initial coding
carl
parents:
diff changeset
224 bool load_conf(CONFIG &dc, char *fn) {
551433a01cab initial coding
carl
parents:
diff changeset
225 int count = 0;
551433a01cab initial coding
carl
parents:
diff changeset
226 TOKEN tok(fn, &dc.config_files);
551433a01cab initial coding
carl
parents:
diff changeset
227 while (true) {
551433a01cab initial coding
carl
parents:
diff changeset
228 char *have = tok.next();
551433a01cab initial coding
carl
parents:
diff changeset
229 if (!have) break;
551433a01cab initial coding
carl
parents:
diff changeset
230 if (have == token_file) {
551433a01cab initial coding
carl
parents:
diff changeset
231 if (!parse_syslogconfig(tok, dc)) {
551433a01cab initial coding
carl
parents:
diff changeset
232 tok.token_error("load_conf() failed to parse syslogconfig");
551433a01cab initial coding
carl
parents:
diff changeset
233 return false;
551433a01cab initial coding
carl
parents:
diff changeset
234 }
551433a01cab initial coding
carl
parents:
diff changeset
235 else count++;
551433a01cab initial coding
carl
parents:
diff changeset
236 }
551433a01cab initial coding
carl
parents:
diff changeset
237 else {
551433a01cab initial coding
carl
parents:
diff changeset
238 tok.token_error(token_file, have);
551433a01cab initial coding
carl
parents:
diff changeset
239 return false;
551433a01cab initial coding
carl
parents:
diff changeset
240 }
551433a01cab initial coding
carl
parents:
diff changeset
241 }
551433a01cab initial coding
carl
parents:
diff changeset
242 tok.token_error("load_conf() found %d syslog files in %s", count, fn);
551433a01cab initial coding
carl
parents:
diff changeset
243 return (!dc.syslogconfigs.empty());
551433a01cab initial coding
carl
parents:
diff changeset
244 }
551433a01cab initial coding
carl
parents:
diff changeset
245
551433a01cab initial coding
carl
parents:
diff changeset
246
551433a01cab initial coding
carl
parents:
diff changeset
247 ////////////////////////////////////////////////
551433a01cab initial coding
carl
parents:
diff changeset
248 // init the tokens
551433a01cab initial coding
carl
parents:
diff changeset
249 //
551433a01cab initial coding
carl
parents:
diff changeset
250 void token_init() {
551433a01cab initial coding
carl
parents:
diff changeset
251 token_cisco = register_string("cisco");
551433a01cab initial coding
carl
parents:
diff changeset
252 token_file = register_string("file");
551433a01cab initial coding
carl
parents:
diff changeset
253 token_include = register_string("include");
551433a01cab initial coding
carl
parents:
diff changeset
254 token_lbrace = register_string("{");
551433a01cab initial coding
carl
parents:
diff changeset
255 token_parser = register_string("parser");
551433a01cab initial coding
carl
parents:
diff changeset
256 token_rbrace = register_string("}");
551433a01cab initial coding
carl
parents:
diff changeset
257 token_semi = register_string(";");
551433a01cab initial coding
carl
parents:
diff changeset
258 token_ssh = register_string("ssh");
551433a01cab initial coding
carl
parents:
diff changeset
259 }