Next Previous Contents

6. CONFIG_FILE object

6.1 Alphabetical function listing

Classe CONFIG_FILE, vue publique

6.2 Some specs

#Specification: configuration files / default permissions ([configf.cc,201])

Unless explicitly stated, the owner and permissions of every configuration file produced and maintained by linuxconf are

        rw-r--r--   root    root

#Specification: saving multi-user config file / strategy ([configf.cc,719])

Here is the strategy used to update file like /etc/passwd in linuxconf. This strategy is used because those file may be access any time. The strategy provide an atomic file update. Here is a step by step sequence, shown for /etc/passwd. This strategy is used for few other files in linuxconf.

        -Create /etc/passwd.TMP with the new contain
        -unlink /etc/passwd.OLD
        -link /etc/passwd to /etc/passwd.OLD
        -rename /etc/passwd.TMP -> /etc/passwd
         This last link delete the previous /etc/passwd but the
         file continue to exist as /etc/passwd.OLD
This strategy makes that /etc/passwd is always visible and in a consistant state at any given time. Some provision are made so this works also if /etc/passwd did not exist.

#Specification: CONFIG_FILE / update strategy / .TMP files ([configf.cc,638])

The flag CONFIGF_TMPLOCK was used to produce a temp file which was renamed in place at fclose time. This was ensuring a consistant state for the configuration file at all time (since rename is atomic). So any competing process would either read the old or the new version, both in a "completed" state. This strategy has other advantages. If Linuxconf has a flaw and fails (crashes) while updating the file, the original is left in place. Also, at fclose time, we have the old and new file side by side. This may be used by modules supporting the "updatefile" message so they can inspect the changes. The updatemon module is doing that and allows the user to preview the change and even reject them. Because of those advantage, the CONFIGF_TMPLOCK is now the default behavior.

#Specification: FILE_CFG / principles ([filecfg.cc,1])

Originally, the CONFIG_FILE::fopen() function was returning a FILE pointer and client code all over the place where using stdio functions on it, including fclose(). This was not a problem, except for fclose(). We had control over the "open" process, but could not enhance the process at close time. The FILE_CFG works (from outside) like a FILE object (from stdio.h). All stdio function are overloaded to work with FILE_CFG. Our goal is to overload the fclose stdio function so we know when a CONFIG_FILE is updated. The function CONFIG_FILE::fopen return a FILE_CFG pointer. To overload fclose, we have to overload few things as well: fputs, fprintf , etc ...).

6.3 CONFIG_FILE status bits

#Specbeg: CONFIG_FILE / status bits definition ([configf.h,39])

        #define CONFIGF_NONE        0
        #define CONFIGF_MANAGED     1       // linuxconf do edit this file
        #define CONFIGF_PRIVATE     2       // Only root can see this
        #define CONFIGF_OPTIONAL    4       // Don't complain if the file
                                            // is missing.
        #define CONFIGF_OPTIONNAL   CONFIGF_OPTIONAL    // Old error
        #define CONFIGF_GENERATED   8       // linuxconf do not edit
                                            // the file, but generate it.
        #define CONFIGF_PROBED      16      // This file is checked to
                                            // control a daemon
        #define CONFIGF_ERASED      32      // Erased at boot time
        #define CONFIGF_SIGNPOUND   64      // Write a linuxconf signature
                                            // when opening the file for writing
        #define CONFIGF_NOARCH      128     // This file must not be archived
        #define CONFIGF_VIRTUAL     256     // Logical view of a configuration file
                                            // used for archiving and remote admin
        #define CONFIGF_DIST        512     // The file is not archived directly
                                            // but is distributed in various sub-systems
        #define CONFIGF_TMPLOCK     1024    // The file is saved in a temporary file
                                            // and then renamed atomically in place
        #define CONFIGF_FIXEDBASE   2048    // This file can't be relocated to
                                            // an admin tree (this was really
                                            // created for /var/log/netconf.log)

6.4 CONFIG_FILE main functions

CONFIG_FILE::CONFIG_FILE()

Record the spec of a config file that is maintain (or used) by linuxconf

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status)
        

CONFIG_FILE::CONFIG_FILE()

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status,
                const char *_subsys)
        

CONFIG_FILE::CONFIG_FILE()

Record the spec of a config file that is maintain (or used) by linuxconf

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status,
                const char *_owner,
                const char *_group,
                int _perm)
        

CONFIG_FILE::CONFIG_FILE()

Record the spec of a config file that is maintain (or used) by linuxconf

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status,
                const char *_owner,
                const char *_group,
                int _perm,
                const char *_subsys)
        

CONFIG_FILE::CONFIG_FILE()

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status,
                const char *_owner,
                const char *_group,
                const char *_perm_str)
        

CONFIG_FILE::CONFIG_FILE()

        PUBLIC CONFIG_FILE::CONFIG_FILE(
                const char *_path,
                HELP_FILE&_helpfile,
                int _status,
                const char *_owner,
                const char *_group,
                const char *_perm_str,
                const char *_subsys)
        

CONFIG_FILE::exist()

Check if the configuration file do exist. Return != 0 if yes.

        PUBLIC int CONFIG_FILE::exist(
                void) const
        
        

CONFIG_FILE::fopen()

Open the configuration file with permission checking. It may even ask the user for the root password or a user password if priv != NULL.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen(
                PRIVILEGE *priv,
                const char *mode) const
        
        

CONFIG_FILE::fopen()

Open the configuration file with permission checking. It may even ask the user for the root password.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen(
                const char *mode) const
        
        

CONFIG_FILE::fopen()

Open the temp configuration file with permission checking. It may even ask the user for the root password.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen(
                PRIVILEGE *priv,
                const char *temp,
                const char *mode) const
        
        

CONFIG_FILE::fopen()

Open the temp configuration file with permission checking. It may even ask the user for the root password.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen(
                const char *temp,
                const char *mode) const
        
        

CONFIG_FILE::getdate()

Get the modification time of a configuration file.

        PUBLIC long CONFIG_FILE::getdate(
                void) const
        
        

CONFIG_FILE::getpath()

Return the path of the configuration file

        PUBLIC const char *CONFIG_FILE::getpath(
                void) const
        
        

CONFIG_FILE::getstdpath()

Return the standard path of the configuration file

        PUBLIC const char *CONFIG_FILE::getstdpath(
                void) const
        
        

6.5 Other functions

CONFIG_FILE::editpath()

        PUBLIC int CONFIG_FILE::editpath(
                void)
        

CONFIG_FILE::fixpath()

        PRIVATE void CONFIG_FILE::fixpath(
                void) const
        
        

CONFIG_FILE::fopen_ok()

Open the configuration file without permission checking.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen_ok(
                const char *mode) const
        
        

CONFIG_FILE::fopen_tmp()

Open a temporary file using the configuration and adding .TMP to its name.

        PUBLIC FILE_CFG *CONFIG_FILE::fopen_tmp(
                PRIVILEGE *priv,
                const char *mode) const
        
        

CONFIG_FILE::gethelp()

Return the path of the help for that configuration file

        PUBLIC const char *CONFIG_FILE::gethelp(
                void) const
        
        

CONFIG_FILE::init()

        PRIVATE void CONFIG_FILE::init(
                HELP_FILE&_helpfile,
                const char *_path,
                int _status,
                const char *_owner,
                const char *_group,
                int _perm,
                const char *_subsys)
        

CONFIG_FILE::init()

        PRIVATE void CONFIG_FILE::init(
                HELP_FILE&_helpfile,
                const char *_path,
                int _status,
                const char *_owner,
                const char *_group,
                const char *_perm_str,
                const char *_subsys)
        

CONFIG_FILE::is_erased()

Return != 0 if the configuration file is erased at boot time

        PUBLIC int CONFIG_FILE::is_erased(
                void) const
        
        

CONFIG_FILE::is_generated()

Return != 0 if the configuration file is generated by linuxconf.

        PUBLIC int CONFIG_FILE::is_generated(
                void) const
        
        

CONFIG_FILE::is_managed()

Return != 0 if the configuration file is managed by linuxconf. Some configuration file are only read (expect to be there and probably never edited by the user.

        PUBLIC int CONFIG_FILE::is_managed(
                void) const
        
        

CONFIG_FILE::is_optionnal()

Return != 0 if the configuration file is optionnal.

        PUBLIC int CONFIG_FILE::is_optionnal(
                void) const
        
        

CONFIG_FILE::is_probed()

Return != 0 if the configuration file is probed by linuxconf. probing is simply to check its modification time.

        PUBLIC int CONFIG_FILE::is_probed(
                void) const
        
        

CONFIG_FILE::relink_tmp()

Rename to original to .OLD, rename the tmp to the original (This function assumes that fopen_tmp() has been used to update the configuration file. It is called from filecfg.cc) return -1 if any error.

        PUBLIC int CONFIG_FILE::relink_tmp(
                void) const
        
        

CONFIG_FILE::setperm()

Set the permissions and owner of a file to the same value as the configuration file, if it has such a requirement. Return -1 if any error.

        PUBLIC int CONFIG_FILE::setperm(
                const char *fpath) const
        
        

CONFIG_FILE::sign()

        PRIVATE void CONFIG_FILE::sign(
                FILE_CFG *fout,
                const char *mode) const
        
        

CONFIG_FILE::unlink()

Erase a configuration file

        PUBLIC int CONFIG_FILE::unlink(
                void) const
        
        

6.6 Archiving

#Specification: config file / archiving / strategy ([configf.cc,844])

Linuxconf is calling a command (user changeable) to archive various config file (or sometime parts of). It is opening a pipe to this command and sends the content of the file to it. The command receive the full path of the file as it is accessed on the file system. This allows the archiving mecanism to create an archive tree similar to the normal tree. For example, the supplied archiving mecanism of linuxconf create a sub-tree in /etc/linuxconf/archive where you will find the various RCS files in the etc subdirectory for example. The archiving command does not read directly the original. There are various reasons for that

        The file may not exist at all. In that case, linuxconf
        is archiving that fact by sending a special content.
        When linuxconf is extracting the file, it finds out
        that the file did not exist at that time and can
        reproduce the same state.
        The archiving is fine grain. Some aspect of some
        files may be archived independantly. Linuxconf
        creates "virtual files" which represent limited
        views of a physical file. So the actual name
        used for archiving is "virtual".

#Specification: config files / archiving / exception ([configf.cc,1057])

All config file which do not carry the CONFIGF_NOARCH are candidate for archiving. There are some exceptions. Any file in the following subdirectory are never archived

        /proc
        /usr/lib/linuxconf
        /var/run
        /var/log

#Specification: config versionning / extraction / principle ([configf.cc,1544])

Extracting a configuration is difficult because ultimatly we have no clue what must be extracted. For example, we may archive a lot of .dconf file (PPP/Slip dialout config) but we have no clue which one to extract. The same apply to the DNS configuration. We know how to extract the /etc/named.conf but without its content, we have no clue about the various zone file. Extraction is done by iteration. First we extract the well known config file. As a side effect of the extraction, the various CONFIG_FILE are free to define new CONFIG_FILE object as they learn about them. New CONFIG_FILE are recorded at the beginning of the linked list. So by running the process until all file have been extracted and no new CONFIG_FILE has been added, we end with a working solution.

#Specification: config versionning / extraction / principle part 2 ([configf.cc,1579])

After doing some iteration, we may have extracts all needed sub-systems and files. But we may have missed some. Here is a case. We can to extract /var/named/solucorp.qc.ca. This is a DNS zone file. We only learn about this zone file if we extract /etc/named.conf. Now, if we do not extract the dnsserv sub-system (which own /etc/named.conf) or /etc/named.conf, we will never learn about the zone file. So it won't be extracted. After doing the iteration explain above, where we extract files and sub-systems, checking if new config file appears, we may still have some sub-system and files not extracted. THis time, we trigger the config file listers and we try again to perform the extraction.

CONFIG_FILE::archive()

        PROTECTED VIRTUAL int CONFIG_FILE::archive(
                SSTREAM&ss) const
        
        

CONFIG_FILE::archive()

Archive the config file if configured

        PUBLIC VIRTUAL int CONFIG_FILE::archive(
                void) const
        
        

6.7 misc

#Specification: *.paths files / location ([configf.cc,393])

We check first in /usr/lib/linuxconf/distribution/release then in /usr/lib/linuxconf/distribution/base-release then in /usr/lib/linuxconf/distribution. This allows redefinition for a specific release, a major version or any version. For example, when running on a RedHat 6.2, we look in the following directory

        /usr/lib/linuxconf/redhat/6.2
        /usr/lib/linuxconf/redhat/6
        /usr/lib/linuxconf/redhat
This should offer enough flexibility to adapt to newer releases.
Next Previous Contents