[augeas-devel] [PATCH] Lens and transform for xinetd.conf

David Lutterkort dlutter at redhat.com
Tue May 6 01:13:09 UTC 2008


# HG changeset patch
# User David Lutterkort <dlutter at redhat.com>
# Date 1210036284 25200
# Node ID 1fc53b95ee8d765f8a12338a94782cf2bfd20060
# Parent  3aac4ca5d0afee4fef06bf5c771359043ca01ce9
Lens and transform for xinetd.conf

diff -r 3aac4ca5d0af -r 1fc53b95ee8d lenses/tests/test_xinetd.aug
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lenses/tests/test_xinetd.aug	Mon May 05 18:11:24 2008 -0700
@@ -0,0 +1,67 @@
+module Test_xinetd =
+
+let eol_ws = "defaults \t \n{\n  enabled = cvs echo  \n}\n\n"
+
+let cvs = "# default: off
+# description: The CVS service can record the history of your source \
+#              files. CVS stores all the versions of a file in a single \
+#              file in a clever way that only stores the differences \
+#              between versions.
+service cvspserver
+{
+        disable                 = yes
+        port                    = 2401
+        socket_type             = stream
+        protocol                = tcp
+        wait                    = no
+        user                    = root
+        passenv                 = PATH
+        server                  = /usr/bin/cvs
+        env                    -= HOME=/var/cvs
+        server_args             = -f --allow-root=/var/cvs pserver
+#       bind                    = 127.0.0.1
+        log_on_failure         += HOST
+}
+"
+
+let lst_add = "service svc_add
+{
+   log_on_failure += HOST
+}
+"
+
+test Xinetd.lns get eol_ws =
+  { "defaults" { "enabled"
+                 { "value" = "cvs" }
+                 { "value" = "echo" } } }
+  {}
+
+test Xinetd.lns put eol_ws after rm "/defaults/enabled/value[last()]" =
+  "defaults \t \n{\n  enabled = cvs  \n}\n\n"
+
+test Xinetd.lns get cvs =
+  {} {} {} {} {}
+  { "cvspserver"
+      { "disable" = "yes" }
+      { "port" = "2401" }
+      { "socket_type" = "stream" }
+      { "protocol" = "tcp" }
+      { "wait" = "no" }
+      { "user" = "root" }
+      { "passenv" { "value" = "PATH" } }
+      { "server" = "/usr/bin/cvs" }
+      { "env" { "del" } { "value" = "HOME=/var/cvs" } }
+      { "server_args"
+          { "value" = "-f" }
+          { "value" = "--allow-root=/var/cvs" }
+          { "value" = "pserver" } }
+      {}
+      { "log_on_failure" { "add" } { "value" = "HOST" } } }
+
+(* Switch the '+=' to a simple '=' *)
+test Xinetd.lns put lst_add after rm "/svc_add/log_on_failure/add" =
+  "service svc_add\n{\n   log_on_failure = HOST\n}\n"
+
+(* Local Variables: *)
+(* mode: caml       *)
+(* End:             *)
diff -r 3aac4ca5d0af -r 1fc53b95ee8d lenses/xinetd.aug
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lenses/xinetd.aug	Mon May 05 18:11:24 2008 -0700
@@ -0,0 +1,98 @@
+(* Process xinetd config files *)
+(* The structure of the lens and allowed attributes are ripped directly   *)
+(* from xinetd's parser in xinetd/parse.c in xinetd's source checkout     *)
+(* The downside of being so precise here is that if attributes are added  *)
+(* they need to be added here, too. Writing a catchall entry, and getting *)
+(* to typecheck correctly would be a huge pain.                           *)
+(* A really enterprising soul could tighten this down even further by     *)
+(* restricting the acceptable values for each attribute.                  *)
+module Xinetd =
+  autoload xfm
+
+  let comment = [ del /(#.*|[ \t]*)\n/ "#\n" ]
+
+  let name = key /[^ \t\n\/+-=]+/
+  let opt_spc = del /[ \t]*/ ""
+  let spc = del /[ \t]+/ " "
+  let eol = del /[ \t]*\n/ "\n"
+
+  let eq = opt_spc . Util.del_str "="
+
+  let op = opt_spc . ([ label "add" . Util.del_str "+=" ]
+                 |[ label "del" . Util.del_str "-=" ]
+                 |Util.del_str "=")
+
+  let value = store /[^ \t\n]+/
+
+  let attr_one (n:regexp) =
+    [ opt_spc . key n . eq . spc . value . eol ]
+
+  let attr_lst (n:regexp) (op_eq: lens) =
+    [ opt_spc . key n . op_eq . [label "value" . spc . value]* . eol ]
+
+  let attr_lst_eq (n:regexp) = attr_lst n eq
+
+  let attr_lst_op (n:regexp) = attr_lst n op
+
+  (* Note: it is much faster to combine, for example, all the attr_one    *)
+  (* attributes into one regexp and pass that to a lens instead of        *)
+  (* using lens union (attr_one "a" | attr_one "b"|..) because the latter *)
+  (* causes the type checker to work _very_ hard.                         *)
+
+  let service_attr =
+    attr_one ("socket_type" | "protocol" | "wait" | "user" | "group"
+             |"server" | "instances"  | "rpc_version" | "rpc_number"
+             | "id" | "port" | "nice" | "banner" | "bind" | "interface"
+             | "per_source" | "groups" | "banner_success" | "banner_fail"
+             | "disable" | "max_load" | "rlimit_as" | "rlimit_cpu"
+             | "rlimit_data" | "rlimit_rss" | "rlimit_stack" | "v6only"
+             | "deny_time" | "umask" | "mdns" | "libwrap")
+   (* redirect and cps aren't really lists, they take exactly two values *)
+   |attr_lst_eq ("server_args" | "log_type" |  "access_times" | "type"
+                | "flags" | "redirect" | "cps")
+   |attr_lst_op ( "log_on_success" | "log_on_failure"| "only_from"
+                | "no_access" | "env" | "passenv")
+
+  let default_attr =
+    attr_one ( "instances" | "banner" | "bind" | "interface" | "per_source"
+             | "groups" | "banner_success" | "banner_fail" | "max_load"
+             | "v6only" | "umask" | "mdns")
+   |attr_lst_eq "cps"       (* really only two values, not a whole list *)
+   |attr_lst_op ( "log_type" | "log_on_success" | "log_on_failure" | "disabled"
+                | "no_access" | "only_from" | "passenv" | "enabled" )
+
+  (* Note: we would really like to say "the body can contain any of a list *)
+  (*       of a list of attributes, each of them at most once"; but that   *)
+  (*       would require that we build a lens that matches the permutation *)
+  (*       of all attributes; with around 40 individual attributes, that's *)
+  (*       not computationally feasible, even if we didn't have to worry   *)
+  (*       about how to write that down. The resulting regular expressions *)
+  (*       would simply be prohibitively large.                            *)
+  let body (attr:lens) = Util.del_str "\n{\n"
+                       . (comment|attr)*
+                       . Util.del_str "}\n"
+
+  (* It would be nice if we could use the directories given in include and *)
+  (* includedir directives to parse additional files instead of hardcoding *)
+  (* all the places where xinetd config files can be found; but that is    *)
+  (* currently not possible, and implementing that has a good amount of    *)
+  (* hairy corner cases to consider.                                       *)
+  let includes = [ key /include|includedir/
+                     . Util.del_ws_spc . store /[^ \t\n]+/ . eol ]
+
+  let service = [ del /service[ \t]+/ "service " . key /[^ \t\n\/]+/
+                 . body service_attr ]
+
+  let defaults = [ key "defaults" . del /[ \t]*/ "" . body default_attr ]
+
+  let lns = ( comment | includes | defaults | service )*
+
+  let filter = incl "/etc/xinetd.d/*"
+             . incl "/etc/xinetd.conf"
+             . Util.stdexcl
+
+  let xfm = transform lns filter
+
+(* Local Variables: *)
+(* mode: caml       *)
+(* End:             *)
diff -r 3aac4ca5d0af -r 1fc53b95ee8d tests/root/etc/xinetd.conf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/root/etc/xinetd.conf	Mon May 05 18:11:24 2008 -0700
@@ -0,0 +1,50 @@
+#
+# This is the master xinetd configuration file. Settings in the
+# default section will be inherited by all service configurations
+# unless explicitly overridden in the service configuration. See
+# xinetd.conf in the man pages for a more detailed explanation of
+# these attributes.
+
+defaults
+{
+# The next two items are intended to be a quick access place to
+# temporarily enable or disable services.
+#
+#	enabled		=
+#	disabled	=
+
+# Define general logging characteristics.
+	log_type	= SYSLOG daemon info 
+	log_on_failure	= HOST
+	log_on_success	= PID HOST DURATION EXIT
+
+# Define access restriction defaults
+#
+#	no_access	=
+#	only_from	=
+#	max_load	= 0
+	cps		= 50 10
+	instances	= 50
+	per_source	= 10
+
+# Address and networking defaults
+#
+#	bind		=
+#	mdns		= yes
+	v6only		= no
+
+# setup environmental attributes
+#
+#	passenv		=
+	groups		= yes
+	umask		= 002
+
+# Generally, banners are not used. This sets up their global defaults
+#
+#	banner		=
+#	banner_fail	=
+#	banner_success	=
+}
+
+includedir /etc/xinetd.d
+ 
diff -r 3aac4ca5d0af -r 1fc53b95ee8d tests/root/etc/xinetd.d/cvs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/root/etc/xinetd.d/cvs	Mon May 05 18:11:24 2008 -0700
@@ -0,0 +1,19 @@
+# default: off
+# description: The CVS service can record the history of your source \
+#              files. CVS stores all the versions of a file in a single \
+#              file in a clever way that only stores the differences \
+#              between versions.
+service cvspserver
+{
+	disable			= yes
+	port			= 2401
+	socket_type		= stream
+	protocol		= tcp
+	wait			= no
+	user			= root
+	passenv			= PATH
+	server			= /usr/bin/cvs
+	env			= HOME=/var/cvs
+	server_args		= -f --allow-root=/var/cvs pserver
+#	bind			= 127.0.0.1
+}
diff -r 3aac4ca5d0af -r 1fc53b95ee8d tests/root/etc/xinetd.d/rsync
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/root/etc/xinetd.d/rsync	Mon May 05 18:11:24 2008 -0700
@@ -0,0 +1,14 @@
+# default: off
+# description: The rsync server is a good addition to an ftp server, as it \
+#	allows crc checksumming etc.
+service rsync
+{
+	disable	= yes
+	flags		= IPv6
+	socket_type     = stream
+	wait            = no
+	user            = root
+	server          = /usr/bin/rsync
+	server_args     = --daemon
+	log_on_failure  += USERID
+}




More information about the augeas-devel mailing list