3 parses /etc/syslog.conf
5 Author: Mathieu Arnold <mat@FreeBSD.org>
8 This lens tries to keep as close as possible to `man 5 resolv.conf` where possible.
9 An online source being :
10 http://www.freebsd.org/cgi/man.cgi?query=syslog.conf&sektion=5
13 This file is licensed under the BSD License.
18 About: Configuration files
19 This lens applies to /etc/syslog.conf. See <filter>.
25 (************************************************************************
26 * Group: USEFUL PRIMITIVES
27 *************************************************************************)
29 (* Group: Comments and empty lines *)
32 let empty = Util.empty
35 (* Variable: sep_tab *)
36 let sep_tab = del /([ \t]+|[ \t]*\\\\\n[ \t]*)/ "\t"
38 (* Variable: sep_tab_opt *)
39 let sep_tab_opt = del /([ \t]*|[ \t]*\\\\\n[ \t]*)/ ""
42 Map comments into "#comment" nodes
43 Can't use Util.comment as #+ and #! have a special meaning.
44 However, '# !' and '# +' have no special meaning so they should be allowed.
47 let comment_gen (space:regexp) (sto:regexp) =
48 [ label "#comment" . del ("#" . space) "# " . store sto . eol ]
51 let comment_withsign = comment_gen Rx.space /([!+-].*[^ \t\n]|[!+-])/
52 in let comment_nosign = comment_gen Rx.opt_space /([^ \t\n+!-].*[^ \t\n]|[^ \t\n+!-])/
53 in comment_withsign | comment_nosign
55 (* Group: single characters macro *)
58 Deletes a comma and default to it
60 let comma = sep_tab_opt . Util.del_str "," . sep_tab_opt
62 Deletes a colon and default to it
64 let colon = sep_tab_opt . Util.del_str ":" . sep_tab_opt
65 (* Variable: semicolon
66 Deletes a semicolon and default to it
68 let semicolon = sep_tab_opt . Util.del_str ";" . sep_tab_opt
70 Deletes a dot and default to it
72 let dot = Util.del_str "."
74 Deletes a pipe and default to it
76 let pipe = Util.del_str "|"
78 Deletes a plus and default to it
80 let plus = Util.del_str "+"
82 Deletes a bang and default to it
84 let bang = Util.del_str "!"
87 deletes an optional # sign
89 let opt_hash = del /#?/ ""
91 deletes an optional + sign
93 let opt_plus = del /\+?/ ""
95 (* Group: various macros *)
98 our version can't start with [_.-] because it would mess up the grammar
100 let word = /[A-Za-z0-9][A-Za-z0-9_.-]*/
102 (* Variable: comparison
103 a comparison is an optional ! with optionaly some of [<=>]
105 let comparison = /(!|[<=>]+|![<=>]+)/
107 (* Variable: protocol
111 let protocol = /@{1,2}/
116 let token = /([A-Za-z0-9]+|\*)/
119 a file begins with a / and get almost anything else after
121 let file_r = /\/[^ \t\n;]+/
123 (* Variable: loghost_r
124 Matches a hostname, that is labels speparated by dots, labels can't
125 start or end with a "-". maybe a bit too complicated for what it's worth *)
126 let loghost_r = /[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*/ |
129 (* Group: Function *)
131 (* View: label_opt_list
132 Uses Build.opt_list to generate a list of labels
135 l:string - the label name
136 r:lens - the lens going after the label
137 s:lens - the separator lens passed to Build.opt_list
139 let label_opt_list (l:string) (r:lens) (s:lens) = Build.opt_list [ label l . r ] s
141 (* View: label_opt_list_or
142 Either label_opt_list matches something or it emits a single label
143 with the "or" string.
146 l:string - the label name
147 r:lens - the lens going after the label
148 s:lens - the separator lens passed to Build.opt_list
149 or:string - the string used if the label_opt_list does not match anything
151 let label_opt_list_or (l:string) (r:lens) (s:lens) (or:string) =
152 ( label_opt_list l r s | [ label l . store or ] )
155 (************************************************************************
156 * Group: LENSE DEFINITION
157 *************************************************************************)
159 (* Group: selector *)
162 a list of facilities, separated by commas
164 let facilities = label_opt_list "facility" (store token) comma
167 a selector is a list of facilities, an optional comparison and a level
169 let selector = facilities . dot .
170 [ label "comparison" . store comparison]? .
171 [ label "level" . store token ]
174 a list of selectors, separated by semicolons
176 let selectors = label_opt_list "selector" selector semicolon
181 a file may start with a "-" meaning it does not gets sync'ed everytime
183 let file = [ Build.xchgs "-" "no_sync" ]? . [ label "file" . store file_r ]
186 a loghost is an @ sign followed by the hostname and a possible port
188 let loghost = [label "protocol" . store protocol] . [ label "hostname" . store loghost_r ] .
189 (colon . [ label "port" . store /[0-9]+/ ] )?
192 a list of users or a "*"
194 let users = label_opt_list_or "user" (store word) comma "*"
197 a log program begins with a pipe
199 let logprogram = pipe . [ label "program" . store /[^ \t\n][^\n]+[^ \t\n]/ ]
202 an action is either a file, a host, users, or a program
204 let action = (file | loghost | users | logprogram)
209 an entry contains selectors and an action
211 let entry = [ label "entry" .
212 selectors . sep_tab .
213 [ label "action" . action ] . eol ]
216 entries are either comments/empty lines or entries
218 let entries = (empty | comment | entry)*
220 (* Group: Program matching *)
225 let programs = label_opt_list_or "program" (store word) comma "*"
228 a program begins with an optional hash, a bang, and an optional + or -
230 let program = [ label "program" . opt_hash . bang .
231 ( opt_plus | [ Build.xchgs "-" "reverse" ] ) .
232 programs . eol . entries ]
234 (* Group: Hostname maching *)
239 let hostnames = label_opt_list_or "hostname" (store Rx.word) comma "*"
242 a program begins with an optional hash, and a + or -
244 let hostname = [ label "hostname" . opt_hash .
245 ( plus | [ Build.xchgs "-" "reverse" ] ) .
246 hostnames . eol . entries ]
248 (* Group: Top of the tree *)
251 generic entries then programs or hostnames matching blocs
253 let lns = entries . ( program | hostname )*
256 all you need is /etc/syslog.conf
258 let filter = incl "/etc/syslog.conf"
260 let xfm = transform lns filter