Imported Upstream version 1.7.0
[platform/upstream/augeas.git] / lenses / syslog.aug
1 (*
2 Module: Syslog
3   parses /etc/syslog.conf
4
5 Author: Mathieu Arnold <mat@FreeBSD.org>
6
7 About: Reference
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
11
12 About: Licence
13   This file is licensed under the BSD License.
14
15 About: Lens Usage
16    To be documented
17
18 About: Configuration files
19   This lens applies to /etc/syslog.conf. See <filter>.
20
21  *)
22 module Syslog =
23   autoload xfm
24
25         (************************************************************************
26          * Group:                 USEFUL PRIMITIVES
27          *************************************************************************)
28
29         (* Group: Comments and empty lines *)
30
31         (* Variable: empty *)
32         let empty      = Util.empty
33         (* Variable: eol *)
34         let eol        = Util.eol
35         (* Variable: sep_tab *)
36         let sep_tab    = del /([ \t]+|[ \t]*\\\\\n[ \t]*)/ "\t"
37
38         (* Variable: sep_tab_opt *)
39         let sep_tab_opt = del /([ \t]*|[ \t]*\\\\\n[ \t]*)/ ""
40
41         (* View: comment
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.
45      *)
46
47         let comment_gen (space:regexp) (sto:regexp) =
48           [ label "#comment" . del ("#" . space) "# " . store sto . eol ]
49
50         let comment =
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
54
55         (* Group: single characters macro *)
56
57         (* Variable: comma
58          Deletes a comma and default to it
59          *)
60         let comma      = sep_tab_opt . Util.del_str "," . sep_tab_opt
61         (* Variable: colon
62          Deletes a colon and default to it
63          *)
64         let colon      = sep_tab_opt . Util.del_str ":" . sep_tab_opt
65         (* Variable: semicolon
66          Deletes a semicolon and default to it
67          *)
68         let semicolon  = sep_tab_opt . Util.del_str ";" . sep_tab_opt
69         (* Variable: dot
70          Deletes a dot and default to it
71          *)
72         let dot        = Util.del_str "."
73         (* Variable: pipe
74          Deletes a pipe and default to it
75          *)
76         let pipe       = Util.del_str "|"
77         (* Variable: plus
78          Deletes a plus and default to it
79          *)
80         let plus       = Util.del_str "+"
81         (* Variable: bang
82          Deletes a bang and default to it
83          *)
84         let bang       = Util.del_str "!"
85
86         (* Variable: opt_hash
87           deletes an optional # sign
88           *)
89         let opt_hash   = del /#?/ ""
90         (* Variable: opt_plus
91           deletes an optional + sign
92           *)
93         let opt_plus   = del /\+?/ ""
94
95         (* Group: various macros *)
96
97         (* Variable: word
98           our version can't start with [_.-] because it would mess up the grammar
99           *)
100         let word      = /[A-Za-z0-9][A-Za-z0-9_.-]*/
101
102         (* Variable: comparison
103           a comparison is an optional ! with optionaly some of [<=>]
104           *)
105         let comparison = /(!|[<=>]+|![<=>]+)/
106
107         (* Variable: protocol
108           @ means UDP
109     @@ means TCP
110           *)
111         let protocol      = /@{1,2}/
112
113         (* Variable: token
114           alphanum or "*"
115           *)
116         let token      = /([A-Za-z0-9]+|\*)/
117
118         (* Variable: file_r
119          a file begins with a / and get almost anything else after
120          *)
121         let file_r     = /\/[^ \t\n;]+/
122
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])?)*/ |
127                     "[" . Rx.ipv6 . "]"
128
129         (* Group: Function *)
130
131         (* View: label_opt_list
132          Uses Build.opt_list to generate a list of labels
133
134          Parameters:
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
138          *)
139         let label_opt_list (l:string) (r:lens) (s:lens) = Build.opt_list [ label l . r ] s
140
141         (* View: label_opt_list_or
142          Either label_opt_list matches something or it emits a single label
143          with the "or" string.
144
145          Parameters:
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
150          *)
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 ] )
153
154
155         (************************************************************************
156          * Group:                 LENSE DEFINITION
157          *************************************************************************)
158
159         (* Group: selector *)
160
161         (* View: facilities
162          a list of facilities, separated by commas
163          *)
164         let facilities = label_opt_list "facility" (store token) comma
165
166         (* View: selector
167          a selector is a list of facilities, an optional comparison and a level
168          *)
169         let selector = facilities . dot .
170                        [ label "comparison" . store comparison]? .
171                        [ label "level" . store token ]
172
173         (* View: selectors
174          a list of selectors, separated by semicolons
175          *)
176         let selectors = label_opt_list "selector" selector semicolon
177
178         (* Group: action *)
179
180         (* View: file
181          a file may start with a "-" meaning it does not gets sync'ed everytime
182          *)
183         let file = [ Build.xchgs "-" "no_sync" ]? . [ label "file" . store file_r ]
184
185         (* View: loghost
186          a loghost is an @  sign followed by the hostname and a possible port
187          *)
188         let loghost = [label "protocol" . store protocol] . [ label "hostname" . store loghost_r ] .
189             (colon . [ label "port" . store /[0-9]+/ ] )?
190
191         (* View: users
192          a list of users or a "*"
193          *)
194         let users = label_opt_list_or "user" (store word) comma "*"
195
196         (* View: logprogram
197          a log program begins with a pipe
198          *)
199         let logprogram = pipe . [ label "program" . store /[^ \t\n][^\n]+[^ \t\n]/ ]
200
201         (* View: discard
202          discards matching messages
203          *)
204         let discard = [ label "discard" . Util.del_str "~" ]
205
206         (* View: action
207          an action is either a file, a host, users, a program, or discard
208          *)
209         let action = (file | loghost | users | logprogram | discard)
210
211         (* Group: Entry *)
212
213         (* View: entry
214          an entry contains selectors and an action
215          *)
216         let entry = [ label "entry" .
217             selectors . sep_tab .
218             [ label "action" . action ] . eol ]
219
220         (* View: entries
221          entries are either comments/empty lines or entries
222          *)
223         let entries = (empty | comment | entry)*
224
225         (* Group: Program matching *)
226
227         (* View: programs
228          a list of programs
229          *)
230         let programs = label_opt_list_or "program" (store word) comma "*"
231
232         (* View: program
233          a program begins with an optional hash, a bang, and an optional + or -
234          *)
235         let program = [ label "program" . opt_hash . bang .
236               ( opt_plus | [ Build.xchgs "-" "reverse" ] ) .
237               programs . eol .  entries ]
238
239         (* Group: Hostname maching *)
240
241         (* View: hostnames
242          a list of hostnames
243          *)
244         let hostnames = label_opt_list_or "hostname" (store Rx.word) comma "*"
245
246         (* View: hostname
247          a program begins with an optional hash, and a + or -
248          *)
249         let hostname = [ label "hostname" . opt_hash .
250               ( plus | [ Build.xchgs "-" "reverse" ] ) .
251               hostnames . eol .  entries ]
252
253         (* Group: Top of the tree *)
254
255         (* View: lns
256          generic entries then programs or hostnames matching blocs
257          *)
258         let lns = entries . ( program | hostname )*
259
260         (* Variable: filter
261          all you need is /etc/syslog.conf
262          *)
263         let filter = incl "/etc/syslog.conf"
264
265         let xfm = transform lns filter
266