1 (* Intefraces module for Augeas
2 Author: Free Ekanayaka <free@64studio.com>
4 Reference: man dhclient.conf
5 The only difference with the reference syntax is that this lens assumes
6 that statements end with a new line, while the reference syntax allows
7 new statements to be started right after the trailing ";" of the
8 previous statement. This should not be a problem in real-life
9 configuration files as statements get usually split across several
10 lines, rather than merged in a single one.
18 (************************************************************************
20 *************************************************************************)
23 let comment = Util.comment
24 let comment_or_eol = Util.comment_or_eol
25 let empty = Util.empty
27 (* Define separators *)
28 let sep_spc = del /[ \t\n]+/ " "
29 let sep_scl = del /[ \t]*;/ ";"
30 let sep_obr = del /[ \t\n]*\{\n]*/ " {\n"
31 let sep_cbr = del /[ \t\n]*\}/ " }"
32 let sep_com = del /[ \t\n]*,[ \t\n]*/ ","
33 let sep_slh = del "\/" "/"
34 let sep_col = del ":" ":"
35 let sep_eq = del /[ \t]*=[ \t]*/ "="
37 (* Define basic types *)
38 let word = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
42 (* TODO: there could be a " " in the middle of a value ... *)
43 let sto_to_spc = store /[^\\#,;{}" \t\n]+|"[^\\#"\n]+"/
44 let sto_to_spc_noeval = store /[^=\\#,;{}" \t\n]|[^=\\#,;{}" \t\n][^\\#,;{}" \t\n]*|"[^\\#"\n]+"/
45 let sto_to_scl = store /[^ \t\n][^;\n]+[^ \t]|[^ \t;\n]+/
46 let rfc_code = [ key "code" . sep_spc . store word ]
48 . [ label "value" . sto_to_scl ]
49 let eval = [ label "#eval" . Sep.equal . sep_spc . sto_to_scl ]
50 let sto_number = store /[0-9][0-9]*/
52 (************************************************************************
54 *************************************************************************)
56 let stmt_simple_re = "timeout"
62 | "do-forward-updates"
65 let stmt_simple = [ key stmt_simple_re
72 (************************************************************************
74 *************************************************************************)
76 (* TODO: the array could also be empty, like in the request statement *)
77 let stmt_array_re = "media"
81 let stmt_array = [ key stmt_array_re
83 . counter "stmt_array"
84 . [ seq "stmt_array" . sto_to_spc ]
85 . [ sep_com . seq "stmt_array" . sto_to_spc ]*
86 . sep_scl . comment_or_eol ]
88 (************************************************************************
90 *************************************************************************)
93 let stmt_hash_re = "send"
96 let stmt_args = ( [ key word . sep_spc . sto_to_spc_noeval ]
97 | [ key word . sep_spc . (rfc_code|eval) ] )
101 let stmt_hash = [ key stmt_hash_re
105 let stmt_opt_mod_re = "append"
110 let stmt_opt_mod = [ key stmt_opt_mod_re
114 (************************************************************************
116 *************************************************************************)
118 let stmt_block_re = "interface"
122 let stmt_block_opt_re = "interface"
129 | "vendor option space"
131 (* TODO: some options could take no argument like bootp *)
132 let stmt_block_opt = [ key stmt_block_opt_re
138 let stmt_block_date_re
143 let stmt_block_date = [ key stmt_block_date_re
144 . [ sep_spc . label "weekday" . sto_number ]
145 . [ sep_spc . label "year" . sto_number ]
146 . [ sep_slh . label "month" . sto_number ]
147 . [ sep_slh . label "day" . sto_number ]
148 . [ sep_spc . label "hour" . sto_number ]
149 . [ sep_col . label "minute" . sto_number ]
150 . [ sep_col . label "second" . sto_number ]
154 let stmt_block_arg = sep_spc . sto_to_spc
156 let stmt_block_entry = sep_spc
163 let stmt_block = [ key stmt_block_re
170 (************************************************************************
172 *************************************************************************)
174 let statement = (stmt_simple|stmt_opt_mod|stmt_array|stmt_hash|stmt_block)
180 let filter = incl "/etc/dhcp3/dhclient.conf"
181 . incl "/etc/dhcp/dhclient.conf"
182 . incl "/etc/dhclient.conf"
184 let xfm = transform lns filter