Update the GPL boilerplate with the new address of the FSF.
[freeradius.git] / src / main / conffile.c
index c28409e..4d9332a 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
  * Copyright 2000  The FreeRADIUS server project
  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
  * Copyright 2000  Alan DeKok <aland@ox.org>
  */
 
-#include "autoconf.h"
+#include <freeradius-devel/autoconf.h>
 
 #include <stdlib.h>
 #include <string.h>
 
 #include <ctype.h>
 
-#include "radiusd.h"
-#include "rad_assert.h"
-#include "conffile.h"
-#include "token.h"
-#include "modules.h"
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/rad_assert.h>
+#include <freeradius-devel/conffile.h>
+#include <freeradius-devel/token.h>
+#include <freeradius-devel/modules.h>
 
 static const char rcsid[] =
 "$Id$";
@@ -869,13 +869,13 @@ int cf_section_parse(const CONF_SECTION *cs, void *base,
                         */
                        if (!subcs) continue;
 
-                       if (!variables[i].data) {
+                       if (!variables[i].dflt) {
                                DEBUG2("Internal sanity check 1 failed in cf_section_parse");
                                return -1;
                        }
                        
                        if (cf_section_parse(subcs, base,
-                                            (CONF_PARSER *) variables[i].data) < 0) {
+                                            (const CONF_PARSER *) variables[i].dflt) < 0) {
                                return -1;
                        }
                        continue;
@@ -918,7 +918,8 @@ void cf_section_parse_free_strings(void *base, const CONF_PARSER *variables)
        for (i = 0; variables[i].name != NULL; i++) {
                char **p;
 
-               if (variables[i].type != PW_TYPE_STRING_PTR) {
+               if ((variables[i].type != PW_TYPE_STRING_PTR) &&
+                   (variables[i].type != PW_TYPE_FILENAME)) {
                        continue;
                }
                
@@ -1131,7 +1132,7 @@ static CONF_SECTION *cf_section_read(const char *cf, int *lineno, FILE *fp,
                                                 value, dp->d_name);
                                        if ((stat(buf2, &stat_buf) != 0) ||
                                            S_ISDIR(stat_buf.st_mode)) continue;
-                                       if ((is = conf_read(cf, *lineno, buf2, parent)) == NULL) {
+                                       if ((is = conf_read(cf, *lineno, buf2, cs)) == NULL) {
                                                closedir(dir);
                                                cf_section_free(&cs);
                                                return NULL;
@@ -1144,7 +1145,7 @@ static CONF_SECTION *cf_section_read(const char *cf, int *lineno, FILE *fp,
 #endif
                        { /* it was a normal file */
                                DEBUG2( "Config:   including file: %s", value );
-                               if ((is = conf_read(cf, *lineno, value, parent)) == NULL) {
+                               if ((is = conf_read(cf, *lineno, value, cs)) == NULL) {
                                        cf_section_free(&cs);
                                        return NULL;
                                }
@@ -1610,12 +1611,12 @@ static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
 {
        CONF_DATA *cd;
 
-       if (!cs || !name || !data) return -1;
+       if (!cs || !name) return -1;
 
        /*
         *      Already exists.  Can't add it.
         */
-       if (cf_data_find(cs, name) != NULL) return -1;
+       if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
 
        cd = cf_data_alloc(cs, name, data, data_free);
        if (!cd) return -1;
@@ -1637,6 +1638,74 @@ int cf_data_add(CONF_SECTION *cs, const char *name,
 
 
 /*
+ *     Copy CONF_DATA from src to dst
+ */
+static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d)
+{
+       
+       CONF_ITEM *cd, *next, **last;
+
+       /*
+        *      Don't check if s->data_tree is NULL.  It's child
+        *      sections may have data, even if this section doesn't.
+        */
+
+       rad_assert(d->data_tree == NULL);
+       d->data_tree = s->data_tree;
+       s->data_tree = NULL;
+       
+       /*
+        *      Walk through src, moving CONF_ITEM_DATA
+        *      to dst, by hand.
+        */
+       last = &(s->children);
+       for (cd = s->children; cd != NULL; cd = next) {
+               next = cd->next;
+               
+               /*
+                *      Recursively copy data from child sections.
+                */
+               if (cd->type == CONF_ITEM_SECTION) {
+                       CONF_SECTION *s1, *d1;
+                       
+                       s1 = cf_itemtosection(cd);
+                       d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);
+                       if (d1) {
+                               cf_section_copy_data(s1, d1);
+                       }
+                       last = &(cd->next);
+                       continue;
+               }
+
+               /*
+                *      Not conf data, remember last ptr.
+                */
+               if (cd->type != CONF_ITEM_DATA) {
+                       last = &(cd->next);
+                       continue;
+               }
+               
+               /*
+                *      Remove it from the src list
+                */
+               *last = cd->next;
+               cd->next = NULL;
+               
+               /*
+                *      Add it to the dst list
+                */
+               if (!d->children) {
+                       rad_assert(d->tail == NULL);
+                       d->children = cd;
+               } else {
+                       rad_assert(d->tail != NULL);
+                       d->tail->next = cd;
+               }
+               d->tail = cd;
+       }
+}
+
+/*
  *     For a CONF_DATA element, stat the filename, if necessary.
  */
 static int filename_stat(void *context, void *data)
@@ -1655,6 +1724,7 @@ static int filename_stat(void *context, void *data)
        return 0;
 }
 
+
 /*
  *     Compare two CONF_SECTIONS.  The items MUST be in the same
  *     order.
@@ -1692,7 +1762,7 @@ static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b)
                if (ca->type != cb->type) return 0;
 
                /*
-                *      FIXME: Deal with this case, too!
+                *      Deal with subsections.
                 */
                if (ca->type == CONF_ITEM_SECTION) {
                        CONF_SECTION *sa = cf_itemtosection(ca);
@@ -1762,43 +1832,7 @@ int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src)
                 *      then copy the CONF_DATA from one to the other.
                 */
                if (cf_section_cmp(s, d)) {
-                       CONF_ITEM *cd, *next, **last;
-
-                       rad_assert(d->data_tree == NULL);
-                       d->data_tree = s->data_tree;
-                       s->data_tree = NULL;
-
-                       /*
-                        *      Walk through src, moving CONF_ITEM_DATA
-                        *      to dst, by hand.
-                        */
-                       last = &(s->children);
-                       for (cd = s->children; cd != NULL; cd = next) {
-                               next = cd->next;
-
-                               if (cd->type != CONF_ITEM_DATA) {
-                                       last = &(cd->next);
-                                       continue;
-                               }
-
-                               /*
-                                *      Remove it from the src list
-                                */
-                               *last = cd->next;
-                               cd->next = NULL;
-
-                               /*
-                                *      Add it to the dst list
-                                */
-                               if (!d->children) {
-                                       rad_assert(d->tail == NULL);
-                                       d->children = cd;
-                               } else {
-                                       rad_assert(d->tail != NULL);
-                                       d->tail->next = cd;
-                               }
-                               d->tail = cd;
-                       }
+                       cf_section_copy_data(s, d);
                }
        }