1 (* Apache HTTPD lens for Augeas
4 David Lutterkort <lutter@redhat.com>
5 Francis Giraldeau <francis.giraldeau@usherbrooke.ca>
6 Raphael Pinson <raphink@gmail.com>
9 Online Apache configuration manual: http://httpd.apache.org/docs/trunk/
12 This file is licensed under the LGPL v2+.
15 Sample usage of this lens in augtool
17 Apache configuration is represented by two main structures, nested sections
18 and directives. Sections are used as labels, while directives are kept as a
19 value. Sections and directives can have positional arguments inside values
20 of "arg" nodes. Arguments of sections must be the firsts child of the
23 This lens doesn't support automatic string quoting. Hence, the string must
24 be quoted when containing a space.
26 Create a new VirtualHost section with one directive:
27 > clear /files/etc/apache2/sites-available/foo/VirtualHost
28 > set /files/etc/apache2/sites-available/foo/VirtualHost/arg "172.16.0.1:80"
29 > set /files/etc/apache2/sites-available/foo/VirtualHost/directive "ServerAdmin"
30 > set /files/etc/apache2/sites-available/foo/VirtualHost/*[self::directive="ServerAdmin"]/arg "admin@example.com"
32 About: Configuration files
33 This lens applies to files in /etc/httpd and /etc/apache2. See <filter>.
42 (******************************************************************
44 *****************************************************************)
45 let dels (s:string) = del s s
47 (* deal with continuation lines *)
48 let sep_spc = del /([ \t]+|[ \t]*\\\\\r?\n[ \t]*)+/ " "
49 let sep_osp = del /([ \t]*|[ \t]*\\\\\r?\n[ \t]*)*/ ""
50 let sep_eq = del /[ \t]*=[ \t]*/ "="
52 let nmtoken = /[a-zA-Z:_][a-zA-Z0-9:_.-]*/
53 let word = /[a-z][a-z0-9._-]*/i
56 let empty = Util.empty_dos
57 let indent = Util.indent
59 let comment_val_re = /([^ \t\r\n](.|\\\\\r?\n)*[^ \\\t\r\n]|[^ \t\r\n])/
60 let comment = [ label "#comment" . del /[ \t]*#[ \t]*/ "# "
61 . store comment_val_re . eol ]
63 (* borrowed from shellvars.aug *)
64 let char_arg_dir = /([^\\ '"{\t\r\n]|[^ '"{\t\r\n]+[^\\ \t\r\n])|\\\\"|\\\\'|\\\\ /
65 let char_arg_sec = /([^\\ '"\t\r\n>]|[^ '"\t\r\n>]+[^\\ \t\r\n>])|\\\\"|\\\\'|\\\\ /
66 let char_arg_wl = /([^\\ '"},\t\r\n]|[^ '"},\t\r\n]+[^\\ '"},\t\r\n])/
71 let no_dquot = /[^"\\\r\n]/
72 in /"/ . (no_dquot|cdot|cl)* . /"/
74 let no_dquot = /([^ \t"\\\r\n]|[^"\\\r\n]+[^ \t"\\\r\n])/
75 in /"/ . (no_dquot|cdot|cl)*
77 let no_squot = /[^'\\\r\n]/
78 in /'/ . (no_squot|cdot|cl)* . /'/
81 (******************************************************************
83 *****************************************************************)
85 let arg_dir = [ label "arg" . store (char_arg_dir+|dquot|squot) ]
86 (* message argument starts with " but ends at EOL *)
87 let arg_dir_msg = [ label "arg" . store dquot_msg ]
88 let arg_sec = [ label "arg" . store (char_arg_sec+|comp|dquot|squot) ]
89 let arg_wl = [ label "arg" . store (char_arg_wl+|dquot|squot) ]
91 (* comma-separated wordlist as permitted in the SSLRequire directive *)
93 let wl_start = Util.del_str "{" in
94 let wl_end = Util.del_str "}" in
95 let wl_sep = del /[ \t]*,[ \t]*/ ", "
96 in [ label "wordlist" . wl_start . arg_wl . (wl_sep . arg_wl)* . wl_end ]
98 let argv (l:lens) = l . (sep_spc . l)*
101 (* arg_dir_msg may be the last or only argument *)
102 let dir_args = (argv (arg_dir|arg_wordlist) . (sep_spc . arg_dir_msg)?) | arg_dir_msg
103 in [ indent . label "directive" . store word . (sep_spc . dir_args)? . eol ]
105 let section (body:lens) =
106 (* opt_eol includes empty lines *)
107 let opt_eol = del /([ \t]*#?\r?\n)*/ "\n" in
108 let inner = (sep_spc . argv arg_sec)? . sep_osp .
109 dels ">" . opt_eol . ((body|comment) . (body|empty|comment)*)? .
110 indent . dels "</" in
111 let kword = key (word - /perl/i) in
112 let dword = del (word - /perl/i) "a" in
113 [ indent . dels "<" . square kword inner dword . del />[ \t\n\r]*/ ">\n" ]
115 let perl_section = [ indent . label "Perl" . del /<perl>/i "<Perl>"
117 . del /<\/perl>/i "</Perl>" . eol ]
120 let rec content = section (content|directive)
123 let lns = (content|directive|comment|empty)*
125 let filter = (incl "/etc/apache2/apache2.conf") .
126 (incl "/etc/apache2/httpd.conf") .
127 (incl "/etc/apache2/ports.conf") .
128 (incl "/etc/apache2/conf.d/*") .
129 (incl "/etc/apache2/conf-available/*.conf") .
130 (incl "/etc/apache2/mods-available/*") .
131 (incl "/etc/apache2/sites-available/*") .
132 (incl "/etc/apache2/vhosts.d/*.conf") .
133 (incl "/etc/httpd/conf.d/*.conf") .
134 (incl "/etc/httpd/httpd.conf") .
135 (incl "/etc/httpd/conf/httpd.conf") .
138 let xfm = transform lns filter