This is CVSMAN. cvsman is a simple tool to manage file collections across hosts. It has some basis in sup(8). Basically I like sup(8), but I had trouble making it work on Linux. Then I decided I liked the idea of managing the files in CVS for version control. CVS fails at some things, but this is not one of them. cvsman is, in essence, simple. Create a module in CVS. How this is done is up to the user. In the module there must be two toplevel directories: "hosts" and "root". The "root" directory is easy, it represents the root of the file tree ("/"). Any file under this directory is eventually mapped to its analog in the actual filesystem. The "hosts" directory contains the file lists for the hosts. Each file contains the directives describing what files to install into the actual filesystem. The host list files have a simple format. Comment lines start with '#'. Blank lines are ignored. All other lines are directives. Three directives are supported. The first two, "include" and "exclude", specify file installation parameters. They have a simple pattern: " ", where "" is an absolute filename relative to the real filesystem (eg, "/etc/hosts"). The patterns support shell wildcards. The third directive, "execute", takes a full command as its argument. All directives must start on the beginning of the line. The "include" directive specifies files to install. If a file is listed, then it is expected to exist under the "root" directory. Eg, "include /etc/hosts" expects to install "root/etc/hosts" in "/etc/hosts". The "exclude" directive specifes to exclude from installation. This is most useful in the presence of wildcards. For example, to install all automount maps except auto.broken, you might use: ---- include /etc/auto.* exclude /etc/auto.broken ---- Order is important. The exclude directive in the above example must appear after the include directive. In essence, the last directive to reference a file wins. The "execute" directive provides a way to run tasks after files have been installed. "execute" directives can appear anywhere in the file, but they will be run after all files have been installed. They will run in order. These commands will be passed to the shell as is, so they may contain any valid shell code. Note that cvsman is not installed setuid, as this code can be untrustworthy. The user must be careful with the permissions on the CVS repository and the resulting collection directory. The last requirement is a file "config" in the collection directory. This file generally should not be maintained in CVS, as it may differ from machine to machine. The format is a simple : format; spaces are kept. The "host" variable specifies which file underneath the "hosts" directory to use. If not set, "host" defaults to the output of /bin/hostname. The "securepath" variable specifies a secure path to run "execute" directives under. This defaults to "/usr/sbin:/usr/bin:/sbin:/bin". The "CVS_RSH" variable specifies a setting for the $CVS_RSH environment variable in the case of cvs repositories using the :ext: protocol. Once the collection directory has been created, cvsman can be run. If no option is specified, cvsman assumes the collection directory is "/var/lib/cvsman". If it is elsewhere, cvsman can be told where with the "-d" option (eg, "cvsman -d /my/collections"). CVS has known issues preserving file permissions. For that reason, a special file named ".cvsperms" can be placed in any collection directory. The file has the format "///". Every file that needs specific owner, group, or permissions can be placed in this file. The uid and gid are integers, and the permissions are in octal (the leading 0 is not required). For example, a setuid program managed out of cvsman could live in /usr/bin. The host list file contains "/usr/bin/safeprog". The permission file "root/usr/bin/.cvsperms" contains "safeprog/0/0/4755". Have fun!