]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add support for writing out whether CONF_PAIRs were provided
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 15 May 2016 01:02:22 +0000 (21:02 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 15 May 2016 01:02:36 +0000 (21:02 -0400)
src/include/conffile.h
src/main/conffile.c

index 9f4fad507e8803ae4d4ed48f8c5fb317a3750e14..0cd77f2b8b68df4ec81c7e7a3f1c0cf7a39a5327 100644 (file)
@@ -196,20 +196,30 @@ typedef struct timeval _timeval_t;
  *      correctly by the config parser.
  * @{
  */
-#define PW_TYPE_DEPRECATED     (1 << 10) //!< If a matching #CONF_PAIR is found, error out with a deprecated message.
-#define PW_TYPE_REQUIRED       (1 << 11) //!< Error out if no matching #CONF_PAIR is found, and no dflt value is set.
-#define PW_TYPE_ATTRIBUTE      (1 << 12) //!< Value must resolve to attribute in dict (deprecated, use #PW_TYPE_TMPL).
-#define PW_TYPE_SECRET         (1 << 13) //!< Only print value if debug level >= 3.
-
-#define PW_TYPE_FILE_INPUT     ((1 << 14) | PW_TYPE_STRING) //!< File matching value must exist, and must be readable.
-#define PW_TYPE_FILE_OUTPUT    ((1 << 15) | PW_TYPE_STRING) //!< File matching value must exist, and must be writeable.
-
-#define PW_TYPE_XLAT           (1 << 16) //!< string will be dynamically expanded.
-#define PW_TYPE_TMPL           (1 << 17) //!< CONF_PAIR should be parsed as a template.
-
-#define PW_TYPE_MULTI          (1 << 18) //!< CONF_PAIR can have multiple copies.
-#define PW_TYPE_NOT_EMPTY      (1 << 19) //!< CONF_PAIR is required to have a non zero length value.
-#define PW_TYPE_FILE_EXISTS    ((1 << 20) | PW_TYPE_STRING) //!< File matching value must exist
+#define PW_TYPE_DEPRECATED             (1 << 10)                       //!< If a matching #CONF_PAIR is found,
+                                                                       //!< error out with a deprecated message.
+#define PW_TYPE_REQUIRED               (1 << 11)                       //!< Error out if no matching #CONF_PAIR
+                                                                       //!< is found, and no dflt value is set.
+#define PW_TYPE_ATTRIBUTE              (1 << 12)                       //!< Value must resolve to attribute in dict
+                                                                       //!< (deprecated, use #PW_TYPE_TMPL).
+#define PW_TYPE_SECRET                 (1 << 13)                        //!< Only print value if debug level >= 3.
+
+#define PW_TYPE_FILE_INPUT             ((1 << 14) | PW_TYPE_STRING)    //!< File matching value must exist,
+                                                                       //!< and must be readable.
+#define PW_TYPE_FILE_OUTPUT            ((1 << 15) | PW_TYPE_STRING)    //!< File matching value must exist,
+                                                                       //!< and must be writeable.
+
+#define PW_TYPE_XLAT                   (1 << 16)                       //!< string will be dynamically expanded.
+#define PW_TYPE_TMPL                   (1 << 17)                       //!< CONF_PAIR should be parsed as a template.
+
+#define PW_TYPE_MULTI                  (1 << 18)                       //!< CONF_PAIR can have multiple copies.
+#define PW_TYPE_NOT_EMPTY              (1 << 19)                       //!< CONF_PAIR is required to have a non zero
+                                                                       //!< length value.
+#define PW_TYPE_FILE_EXISTS            ((1 << 20) | PW_TYPE_STRING)    //!< File matching value must exist
+
+#define PW_TYPE_IS_SET                 (1 << 21)                       //!< Write whether this config item was
+                                                                       //!< left as the default to is_set_offset
+                                                                       //!< or is_set_ptr.
 /* @} **/
 
 #define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\
@@ -279,6 +289,18 @@ typedef struct CONF_PARSER {
        void            *data;                  //!< Pointer to a static variable to write the parsed value to.
                                                //!< @note Must be used exclusively to #offset.
 
+       /** Where to write status if PW_TYPE_IS_DEFAULT is set
+        *
+        * @note Which field is used, is determined by whether
+        *      data ptr is set.
+        */
+       union {
+               size_t          is_set_offset;  //!< If type contains PW_TYPE_IS_DEFAULT write status to bool.
+                                               //!< at this address.
+               void            *is_set_ptr;    //!< If type contains PW_TYPE_IS_DEFAULT write status to ptr
+                                               //!< at this address.
+       };
+
        union {
                char const      *dflt;          //!< Default as it would appear in radiusd.conf.
 
index deb31852ba321e54711d8c679666c2ad66e603b7..45d33cccb67753826386a7ef5e564f224f45cb2b 100644 (file)
@@ -2020,6 +2020,7 @@ static int cf_pair_default(CONF_PAIR **out, CONF_SECTION *cs, char const *name,
  *     - ``flag`` #PW_TYPE_FILE_INPUT          - @copybrief PW_TYPE_FILE_INPUT
  *     - ``flag`` #PW_TYPE_NOT_EMPTY           - @copybrief PW_TYPE_NOT_EMPTY
  *     - ``flag`` #PW_TYPE_MULTI               - @copybrief PW_TYPE_MULTI
+  *    - ``flag`` #PW_TYPE_IS_SET              - @copybrief PW_TYPE_IS_SET
  * @param data Pointer to a global variable, or pointer to a field in the struct being populated with values.
  * @param dflt value to use, if no #CONF_PAIR is found.
  * @param dflt_quote around the dflt value.
@@ -2292,6 +2293,7 @@ int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
        int ret = 0;
        int i;
        void *data;
+       bool *is_set;
 
        cs->variables = variables; /* this doesn't hurt anything */
 
@@ -2333,24 +2335,35 @@ int cf_section_parse(CONF_SECTION *cs, void *base, CONF_PARSER const *variables)
                if (variables[i].data) {
                        data = variables[i].data; /* prefer this. */
                } else if (base) {
-                       data = ((char *)base) + variables[i].offset;
+                       data = ((uint8_t *)base) + variables[i].offset;
                } else {
                        ERROR("Internal sanity check 2 failed in cf_section_parse");
                        ret = -1;
                        goto finish;
                }
 
+               /*
+                *      Get pointer to where we need to write out
+                *      whether the pointer was set.
+                */
+               if (variables[i].type & PW_TYPE_IS_SET) {
+                       is_set = variables[i].data ? variables[i].is_set_ptr :
+                                                    ((uint8_t *)base) + variables[i].is_set_offset;
+               }
+
                /*
                 *      Parse the pair we found, or a default value.
                 */
                ret = cf_pair_parse(cs, variables[i].name, variables[i].type, data,
                                    variables[i].dflt, variables[i].quote);
                switch (ret) {
-               case 1:         /* Used default */
+               case 1:         /* Used default (or not present) */
+                       if (is_set) *is_set = false;
                        ret = 0;
                        break;
 
                case 0:         /* OK */
+                       if (is_set) *is_set = true;
                        break;
 
                case -1:        /* Parse error */