Corrected typo
[freeradius.git] / src / main / conffile.c
1 /*
2  * conffile.c   Read the radiusd.conf file.
3  *
4  *              Yep I should learn to use lex & yacc, or at least
5  *              write a decent parser. I know how to do that, really :)
6  *              miquels@cistron.nl
7  *
8  * Version:     $Id$
9  *
10  *   This program is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU General Public License as published by
12  *   the Free Software Foundation; either version 2 of the License, or
13  *   (at your option) any later version.
14  *
15  *   This program is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program; if not, write to the Free Software
22  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  *
24  * Copyright 2000,2006  The FreeRADIUS server project
25  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
26  * Copyright 2000  Alan DeKok <aland@ox.org>
27  */
28
29 #include <freeradius-devel/ident.h>
30 RCSID("$Id$")
31
32 #include <freeradius-devel/autoconf.h>
33
34 #include <stdlib.h>
35 #include <string.h>
36
37 #ifdef HAVE_NETINET_IN_H
38 #       include <netinet/in.h>
39 #endif
40
41 #ifdef HAVE_DIRENT_H
42 #include <dirent.h>
43
44 #ifdef HAVE_SYS_STAT_H
45 #include <sys/stat.h>
46 #endif
47 #endif
48
49 #include <ctype.h>
50
51 #include <freeradius-devel/radiusd.h>
52 #include <freeradius-devel/rad_assert.h>
53 #include <freeradius-devel/modules.h>
54
55 typedef enum conf_type {
56         CONF_ITEM_INVALID = 0,
57         CONF_ITEM_PAIR,
58         CONF_ITEM_SECTION,
59         CONF_ITEM_DATA
60 } CONF_ITEM_TYPE;
61
62 struct conf_item {
63         struct conf_item *next;
64         struct conf_part *parent;
65         int lineno;
66         CONF_ITEM_TYPE type;
67 };
68 struct conf_pair {
69         CONF_ITEM item;
70         char *attr;
71         char *value;
72         LRAD_TOKEN operator;
73 };
74 struct conf_part {
75         CONF_ITEM item;
76         const char *name1;
77         const char *name2;
78         struct conf_item *children;
79         struct conf_item *tail; /* for speed */
80         rbtree_t        *pair_tree; /* and a partridge.. */
81         rbtree_t        *section_tree; /* no jokes here */
82         rbtree_t        *name2_tree; /* for sections of the same name2 */
83         rbtree_t        *data_tree;
84         void *base;
85         const CONF_PARSER *variables;
86 };
87
88
89 /*
90  *      Internal data that is associated with a configuration section,
91  *      so that we don't have to track it separately.
92  */
93 struct conf_data {
94         CONF_ITEM  item;
95         const char *name;
96         int        flag;
97         void       *data;       /* user data */
98         void       (*free)(void *); /* free user data function */
99 };
100
101
102 static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
103                                 void *data, void (*data_free)(void *),
104                                 int flag);
105 static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
106                                    int flag);
107
108 /*
109  *      Isolate the scary casts in these tiny provably-safe functions
110  */
111 CONF_PAIR *cf_itemtopair(CONF_ITEM *ci)
112 {
113         if (ci == NULL)
114                 return NULL;
115         rad_assert(ci->type == CONF_ITEM_PAIR);
116         return (CONF_PAIR *)ci;
117 }
118 CONF_SECTION *cf_itemtosection(CONF_ITEM *ci)
119 {
120         if (ci == NULL)
121                 return NULL;
122         rad_assert(ci->type == CONF_ITEM_SECTION);
123         return (CONF_SECTION *)ci;
124 }
125 CONF_ITEM *cf_pairtoitem(CONF_PAIR *cp)
126 {
127         if (cp == NULL)
128                 return NULL;
129         return (CONF_ITEM *)cp;
130 }
131 CONF_ITEM *cf_sectiontoitem(CONF_SECTION *cs)
132 {
133         if (cs == NULL)
134                 return NULL;
135         return (CONF_ITEM *)cs;
136 }
137
138 static CONF_DATA *cf_itemtodata(CONF_ITEM *ci)
139 {
140         if (ci == NULL)
141                 return NULL;
142         rad_assert(ci->type == CONF_ITEM_DATA);
143         return (CONF_DATA *)ci;
144 }
145 static CONF_ITEM *cf_datatoitem(CONF_DATA *cd)
146 {
147         if (cd == NULL)
148                 return NULL;
149         return (CONF_ITEM *)cd;
150 }
151
152 /*
153  *      Create a new CONF_PAIR
154  */
155 static CONF_PAIR *cf_pair_alloc(const char *attr, const char *value,
156                                 LRAD_TOKEN operator, CONF_SECTION *parent)
157 {
158         CONF_PAIR *cp;
159
160         cp = rad_malloc(sizeof(*cp));
161         memset(cp, 0, sizeof(*cp));
162         cp->item.type = CONF_ITEM_PAIR;
163         cp->item.parent = parent;
164         cp->attr = strdup(attr);
165         cp->value = strdup(value);
166         cp->operator = operator;
167
168         return cp;
169 }
170
171 /*
172  *      Free a CONF_PAIR
173  */
174 void cf_pair_free(CONF_PAIR **cp)
175 {
176         if (!cp || !*cp) return;
177
178         if ((*cp)->attr)
179                 free((*cp)->attr);
180         if ((*cp)->value)
181                 free((*cp)->value);
182
183 #ifndef NDEBUG
184         memset(*cp, 0, sizeof(*cp));
185 #endif
186         free(*cp);
187
188         *cp = NULL;
189 }
190
191
192 static void cf_data_free(CONF_DATA **cd)
193 {
194         if (!cd || !*cd) return;
195
196         free((*cd)->name);
197         if (!(*cd)->free) {
198                 free((*cd)->data);
199         } else {
200                 ((*cd)->free)((*cd)->data);
201         }
202 #ifndef NDEBUG
203         memset(*cd, 0, sizeof(*cd));
204 #endif
205         free(*cd);
206         *cd = NULL;
207 }
208
209 /*
210  *      rbtree callback function
211  */
212 static int pair_cmp(const void *a, const void *b)
213 {
214         const CONF_PAIR *one = a;
215         const CONF_PAIR *two = b;
216
217         return strcmp(one->attr, two->attr);
218 }
219
220
221 /*
222  *      rbtree callback function
223  */
224 static int section_cmp(const void *a, const void *b)
225 {
226         const CONF_SECTION *one = a;
227         const CONF_SECTION *two = b;
228
229         return strcmp(one->name1, two->name1);
230 }
231
232
233 /*
234  *      rbtree callback function
235  */
236 static int name2_cmp(const void *a, const void *b)
237 {
238         const CONF_SECTION *one = a;
239         const CONF_SECTION *two = b;
240
241         rad_assert(strcmp(one->name1, two->name1) == 0);
242
243         if (!one->name2 && !two->name2) return 0;
244         if (!one->name2) return -1;
245         if (!two->name2) return +1;
246
247         return strcmp(one->name2, two->name2);
248 }
249
250
251 /*
252  *      rbtree callback function
253  */
254 static int data_cmp(const void *a, const void *b)
255 {
256         int rcode;
257
258         const CONF_DATA *one = a;
259         const CONF_DATA *two = b;
260
261         rcode = one->flag - two->flag;
262         if (rcode != 0) return rcode;
263
264         return strcmp(one->name, two->name);
265 }
266
267
268 /*
269  *      Free strings we've parsed into data structures.
270  */
271 static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
272 {
273         int i;
274
275         /*
276          *      Don't automatically free the strings if we're being
277          *      called from a module.
278          */
279         if (base || !variables) return;
280
281         /*
282          *      Free up dynamically allocated string pointers.
283          */
284         for (i = 0; variables[i].name != NULL; i++) {
285                 char **p;
286
287                 if ((variables[i].type != PW_TYPE_STRING_PTR) &&
288                     (variables[i].type != PW_TYPE_FILENAME)) {
289                         continue;
290                 }
291
292                 /*
293                  *      Prefer the data, if it's there.
294                  *      Else use the base + offset.
295                  */
296                 if (!variables[i].data) {
297                         continue;
298                 }
299
300                 /*
301                  *      FIXME: Add base
302                  */
303                 p = (char **) (variables[i].data);
304
305
306                 free(*p);
307                 *p = NULL;
308         }
309 }
310
311
312 /*
313  *      Free a CONF_SECTION
314  */
315 void cf_section_free(CONF_SECTION **cs)
316 {
317         CONF_ITEM       *ci, *next;
318
319         if (!cs || !*cs) return;
320
321         if ((*cs)->variables) {
322                 cf_section_parse_free((*cs)->base, (*cs)->variables);
323         }
324
325         for (ci = (*cs)->children; ci; ci = next) {
326                 next = ci->next;
327
328                 switch (ci->type) {
329                 case CONF_ITEM_PAIR: {
330                                 CONF_PAIR *pair = cf_itemtopair(ci);
331                                 cf_pair_free(&pair);
332                         }
333                         break;
334
335                 case CONF_ITEM_SECTION: {
336                                 
337                                 CONF_SECTION *section = cf_itemtosection(ci);
338                                 cf_section_free(&section);
339                         }
340                         break;
341
342                 case CONF_ITEM_DATA: {
343                                 CONF_DATA *data = cf_itemtodata(ci);
344                                 cf_data_free(&data);
345                         }
346                         break;
347
348                 default:        /* should really be an error. */
349                         break;
350                 }
351         }
352
353         if ((*cs)->name1)
354                 free((*cs)->name1);
355         if ((*cs)->name2)
356                 free((*cs)->name2);
357         if ((*cs)->pair_tree)
358                 rbtree_free((*cs)->pair_tree);
359         if ((*cs)->section_tree)
360                 rbtree_free((*cs)->section_tree);
361         if ((*cs)->name2_tree)
362                 rbtree_free((*cs)->name2_tree);
363         if ((*cs)->data_tree)
364                 rbtree_free((*cs)->data_tree);
365
366         /*
367          * And free the section
368          */
369 #ifndef NDEBUG
370         memset(*cs, 0, sizeof(*cs));
371 #endif
372         free(*cs);
373
374         *cs = NULL;
375 }
376
377
378 /*
379  *      Allocate a CONF_SECTION
380  */
381 static CONF_SECTION *cf_section_alloc(const char *name1, const char *name2,
382                                       CONF_SECTION *parent)
383 {
384         CONF_SECTION    *cs;
385
386         if (!name1) return NULL;
387
388         cs = rad_malloc(sizeof(*cs));
389         memset(cs, 0, sizeof(*cs));
390         cs->item.type = CONF_ITEM_SECTION;
391         cs->item.parent = parent;
392         cs->name1 = strdup(name1);
393         if (!cs->name1) {
394                 cf_section_free(&cs);
395                 return NULL;
396         }
397         
398         if (name2 && *name2) {
399                 cs->name2 = strdup(name2);
400                 if (!cs->name2) {
401                         cf_section_free(&cs);
402                         return NULL;
403                 }
404         }
405         cs->pair_tree = rbtree_create(pair_cmp, NULL, 0);
406         if (!cs->pair_tree) {
407                 cf_section_free(&cs);
408                 return NULL;
409         }
410
411         /*
412          *      Don't create a data tree, it may not be needed.
413          */
414
415         /*
416          *      Don't create the section tree here, it may not
417          *      be needed.
418          */
419         return cs;
420 }
421
422
423 /*
424  *      Add an item to a configuration section.
425  */
426 static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
427 {
428         if (!cs->children) {
429                 rad_assert(cs->tail == NULL);
430                 cs->children = ci;
431         } else {
432                 rad_assert(cs->tail != NULL);
433                 cs->tail->next = ci;
434         }
435
436         /*
437          *      Update the trees (and tail) for each item added.
438          */
439         for (/* nothing */; ci != NULL; ci = ci->next) {
440                 cs->tail = ci;
441
442                 /*
443                  *      For fast lookups, pair's and sections get
444                  *      added to rbtree's.
445                  */
446                 switch (ci->type) {
447                         case CONF_ITEM_PAIR:
448                                 rbtree_insert(cs->pair_tree, ci);
449                                 break;
450                                 
451                         case CONF_ITEM_SECTION: {
452                                 const CONF_SECTION *cs_new = cf_itemtosection(ci);
453                                 
454                                 if (!cs->section_tree) {
455                                         cs->section_tree = rbtree_create(section_cmp, NULL, 0);
456                                         /* ignore any errors */
457                                 }
458                                 
459                                 if (cs->section_tree) {
460                                         rbtree_insert(cs->section_tree, cs_new);                                }
461                                 
462                                 /*
463                                  *      Two names: find the named instance.
464                                  */
465                                 if (cs_new->name2) {
466                                         CONF_SECTION *old_cs;
467                                         
468                                         /*
469                                          *      Find the FIRST
470                                          *      CONF_SECTION having
471                                          *      the given name1, and
472                                          *      create a new tree
473                                          *      under it.
474                                          */
475                                         old_cs = rbtree_finddata(cs->section_tree, cs_new);
476                                         if (!old_cs) return; /* this is a bad error! */
477                                         
478                                         if (!old_cs->name2_tree) {
479                                                 old_cs->name2_tree = rbtree_create(name2_cmp,
480                                                                                    NULL, 0);
481                                         }
482                                         if (old_cs->name2_tree) {
483                                                 rbtree_insert(old_cs->name2_tree, cs_new);
484                                         }
485                                 } /* had a name2 */
486                                 break;
487                         } /* was a section */
488
489                         case CONF_ITEM_DATA:
490                                 if (!cs->data_tree) {
491                                         cs->data_tree = rbtree_create(data_cmp, NULL, 0);
492                                 }
493                                 if (cs->data_tree) {
494                                         rbtree_insert(cs->data_tree, ci);
495                                 }
496                                 break;
497
498                         default: /* FIXME: assert & error! */
499                                 break;
500
501                 } /* switch over conf types */
502         } /* loop over ci */
503 }
504
505 /*
506  *      Expand the variables in an input string.
507  */
508 static const char *cf_expand_variables(const char *cf, int *lineno,
509                                        const CONF_SECTION *outercs,
510                                        char *output, const char *input)
511 {
512         char *p;
513         const char *end, *ptr;
514         char name[8192];
515         const CONF_SECTION *parentcs;
516
517         /*
518          *      Find the master parent conf section.
519          *      We can't use mainconfig.config, because we're in the
520          *      process of re-building it, and it isn't set up yet...
521          */
522         for (parentcs = outercs;
523              parentcs->item.parent != NULL;
524              parentcs = parentcs->item.parent) {
525                 /* do nothing */
526         }
527
528         p = output;
529         ptr = input;
530         while (*ptr) {
531                 /*
532                  *      Ignore anything other than "${"
533                  */
534                 if ((*ptr == '$') && (ptr[1] == '{')) {
535                         int up;
536                         CONF_PAIR *cp;
537                         const CONF_SECTION *cs;
538
539                         /*
540                          *      FIXME: Add support for ${foo:-bar},
541                          *      like in xlat.c
542                          */
543
544                         /*
545                          *      Look for trailing '}', and log a
546                          *      warning for anything that doesn't match,
547                          *      and exit with a fatal error.
548                          */
549                         end = strchr(ptr, '}');
550                         if (end == NULL) {
551                                 *p = '\0';
552                                 radlog(L_INFO, "%s[%d]: Variable expansion missing }",
553                                        cf, *lineno);
554                                 return NULL;
555                         }
556
557                         ptr += 2;
558
559                         cp = NULL;
560                         up = 0;
561
562                         /*
563                          *      ${.foo} means "foo from the current section"
564                          */
565                         if (*ptr == '.') {
566                                 up = 1;
567                                 cs = outercs;
568                                 ptr++;
569
570                                 /*
571                                  *      ${..foo} means "foo from the section
572                                  *      enclosing this section" (etc.)
573                                  */
574                                 while (*ptr == '.') {
575                                         if (cs->item.parent)
576                                                 cs = cs->item.parent;
577                                         ptr++;
578                                 }
579
580                         } else {
581                                 const char *q;
582                                 /*
583                                  *      ${foo} is local, with
584                                  *      main as lower priority
585                                  */
586                                 cs = outercs;
587
588                                 /*
589                                  *      ${foo.bar.baz} is always rooted
590                                  *      from the top.
591                                  */
592                                 for (q = ptr; *q && q != end; q++) {
593                                         if (*q == '.') {
594                                                 cs = parentcs;
595                                                 up = 1;
596                                                 break;
597                                         }
598                                 }
599                         }
600
601                         while (cp == NULL) {
602                                 char *q;
603                                 /*
604                                  *      Find the next section.
605                                  */
606                                 for (q = name;
607                                      (*ptr != 0) && (*ptr != '.') &&
608                                              (ptr != end);
609                                      q++, ptr++) {
610                                         *q = *ptr;
611                                 }
612                                 *q = '\0';
613
614                                 /*
615                                  *      The character is a '.', find a
616                                  *      section (as the user has given
617                                  *      us a subsection to find)
618                                  */
619                                 if (*ptr == '.') {
620                                         CONF_SECTION *next;
621
622                                         ptr++;  /* skip the period */
623
624                                         /*
625                                          *      Find the sub-section.
626                                          */
627                                         next = cf_section_sub_find(cs, name);
628                                         if (next == NULL) {
629                                                 radlog(L_ERR, "config: No such section %s in variable %s", name, input);
630                                                 return NULL;
631                                         }
632                                         cs = next;
633
634                                 } else { /* no period, must be a conf-part */
635                                         /*
636                                          *      Find in the current referenced
637                                          *      section.
638                                          */
639                                         cp = cf_pair_find(cs, name);
640                                         if (cp == NULL) {
641                                                 /*
642                                                  *      It it was NOT ${..foo}
643                                                  *      then look in the
644                                                  *      top-level config items.
645                                                  */
646                                                 if (!up) cp = cf_pair_find(parentcs, name);
647                                         }
648                                         if (cp == NULL) {
649                                                 radlog(L_ERR, "config: No such configuration item %s in section %s when expanding string \"%s\"", name,
650                                                        cf_section_name1(cs),
651                                                        input);
652                                                 return NULL;
653                                         }
654                                 }
655                         } /* until cp is non-NULL */
656
657                         /*
658                          *  Substitute the value of the variable.
659                          */
660                         strcpy(p, cp->value);
661                         p += strlen(p);
662                         ptr = end + 1;
663
664                 } else if (memcmp(ptr, "$ENV{", 5) == 0) {
665                         char *env;
666
667                         ptr += 5;
668
669                         /*
670                          *      Look for trailing '}', and log a
671                          *      warning for anything that doesn't match,
672                          *      and exit with a fatal error.
673                          */
674                         end = strchr(ptr, '}');
675                         if (end == NULL) {
676                                 *p = '\0';
677                                 radlog(L_INFO, "%s[%d]: Environment variable expansion missing }",
678                                        cf, *lineno);
679                                 return NULL;
680                         }
681
682                         memcpy(name, ptr, end - ptr);
683                         name[end - ptr] = '\0';
684
685                         /*
686                          *      Get the environment variable.
687                          *      If none exists, then make it an empty string.
688                          */
689                         env = getenv(name);
690                         if (env == NULL) {
691                                 *name = '\0';
692                                 env = name;
693                         }
694
695                         strcpy(p, env);
696                         p += strlen(p);
697                         ptr = end + 1;
698
699                 } else {
700                         /*
701                          *      Copy it over verbatim.
702                          */
703                         *(p++) = *(ptr++);
704                 }
705         } /* loop over all of the input string. */
706
707         *p = '\0';
708
709         return output;
710 }
711
712
713 /*
714  *      Parses an item (not a CONF_ITEM) into the specified format,
715  *      with a default value.
716  *
717  *      Returns -1 on error, 0 for correctly parsed, and 1 if the
718  *      default value was used.  Note that the default value will be
719  *      used ONLY if the CONF_PAIR is NULL.
720  */
721 int cf_item_parse(CONF_SECTION *cs, const char *name,
722                   int type, void *data, const char *dflt)
723 {
724         int rcode = 0;
725         char **q;
726         const char *value;
727         lrad_ipaddr_t ipaddr;
728         const CONF_PAIR *cp;
729         char ipbuf[128];
730
731         cp = cf_pair_find(cs, name);
732         if (cp) {
733                 value = cp->value;
734
735         } else if (!dflt) {
736                 return 1;       /* nothing to parse, return default value */
737
738         } else {
739                 rcode = 1;
740                 value = dflt;
741         }
742
743         switch (type) {
744         case PW_TYPE_BOOLEAN:
745                 /*
746                  *      Allow yes/no and on/off
747                  */
748                 if ((strcasecmp(value, "yes") == 0) ||
749                     (strcasecmp(value, "on") == 0)) {
750                         *(int *)data = 1;
751                 } else if ((strcasecmp(value, "no") == 0) ||
752                            (strcasecmp(value, "off") == 0)) {
753                         *(int *)data = 0;
754                 } else {
755                         *(int *)data = 0;
756                         radlog(L_ERR, "Bad value \"%s\" for boolean variable %s", value, name);
757                         return -1;
758                 }
759                 DEBUG2(" %s: %s = %s", cs->name1, name, value);
760                 break;
761                 
762         case PW_TYPE_INTEGER:
763                 *(int *)data = strtol(value, 0, 0);
764                 DEBUG2(" %s: %s = %d",
765                        cs->name1, name,
766                        *(int *)data);
767                 break;
768                 
769         case PW_TYPE_STRING_PTR:
770                 q = (char **) data;
771                 if (*q != NULL) {
772                         free(*q);
773                 }
774                 
775                 /*
776                  *      Expand variables which haven't already been
777                  *      expanded automagically when the configuration
778                  *      file was read.
779                  */
780                 if (value == dflt) {
781                         char buffer[8192];
782
783                         int lineno = cs->item.lineno;
784
785                         /*
786                          *      FIXME: sizeof(buffer)?
787                          */
788                         value = cf_expand_variables("?",
789                                                     &lineno,
790                                                     cs, buffer, value);
791                         if (!value) return -1;
792                 }
793                 
794                 DEBUG2(" %s: %s = \"%s\"",
795                        cs->name1, name,
796                        value ? value : "(null)");
797                 *q = value ? strdup(value) : NULL;
798                 break;
799                 
800                 /*
801                  *      This is the same as PW_TYPE_STRING_PTR,
802                  *      except that we also "stat" the file, and
803                  *      cache the result.
804                  */
805         case PW_TYPE_FILENAME:
806                 q = (char **) data;
807                 if (*q != NULL) {
808                         free(*q);
809                 }
810                 
811                 /*
812                  *      Expand variables which haven't already been
813                  *      expanded automagically when the configuration
814                  *      file was read.
815                  */
816                 if (value == dflt) {
817                         char buffer[8192];
818
819                         int lineno = cs->item.lineno;
820
821                         /*
822                          *      FIXME: sizeof(buffer)?
823                          */
824                         value = cf_expand_variables("?",
825                                                     &lineno,
826                                                     cs, buffer, value);
827                         if (!value) return -1;
828                 }
829                 
830                 DEBUG2(" %s: %s = \"%s\"",
831                        cs->name1, name,
832                        value ? value : "(null)");
833                 *q = value ? strdup(value) : NULL;
834
835                 /*
836                  *      And now we "stat" the file.
837                  */
838                 if (*q) {
839                         struct stat buf;
840
841                         if (stat(*q, &buf) == 0) {
842                                 time_t *mtime;
843
844                                 mtime = rad_malloc(sizeof(*mtime));
845                                 *mtime = buf.st_mtime;
846                                 /* FIXME: error? */
847                                 cf_data_add_internal(cs, *q, mtime, free,
848                                                      PW_TYPE_FILENAME);
849                         }
850                 }
851                 break;
852
853         case PW_TYPE_IPADDR:
854                 /*
855                  *      Allow '*' as any address
856                  */
857                 if (strcmp(value, "*") == 0) {
858                         *(uint32_t *) data = htonl(INADDR_ANY);
859                         DEBUG2(" %s: %s = *", cs->name1, name);
860                         break;
861                 }
862                 if (ip_hton(value, AF_INET, &ipaddr) < 0) {
863                         radlog(L_ERR, "Can't find IP address for host %s", value);
864                         return -1;
865                 }
866                 DEBUG2(" %s: %s = %s IP address [%s]",
867                        cs->name1, name, value,
868                        ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
869                 *(uint32_t *) data = ipaddr.ipaddr.ip4addr.s_addr;
870                 break;
871                 
872         case PW_TYPE_IPV6ADDR:
873                 if (ip_hton(value, AF_INET6, &ipaddr) < 0) {
874                         radlog(L_ERR, "Can't find IPv6 address for host %s", value);
875                         return -1;
876                 }
877                 DEBUG2(" %s: %s = %s IPv6 address [%s]",
878                        cs->name1, name, value,
879                        ip_ntoh(&ipaddr, ipbuf, sizeof(ipbuf)));
880                 memcpy(data, &ipaddr.ipaddr.ip6addr,
881                        sizeof(ipaddr.ipaddr.ip6addr));
882                 break;
883                 
884         default:
885                 radlog(L_ERR, "type %d not supported yet", type);
886                 return -1;
887                 break;
888         } /* switch over variable type */
889         
890         return rcode;
891 }
892
893 /*
894  *      Parse a configuration section into user-supplied variables.
895  */
896 int cf_section_parse(CONF_SECTION *cs, void *base,
897                      const CONF_PARSER *variables)
898 {
899         int i;
900         void *data;
901
902         /*
903          *      Handle the known configuration parameters.
904          */
905         for (i = 0; variables[i].name != NULL; i++) {
906                 /*
907                  *      Handle subsections specially
908                  */
909                 if (variables[i].type == PW_TYPE_SUBSECTION) {
910                         const CONF_SECTION *subcs;
911                         subcs = cf_section_sub_find(cs, variables[i].name);
912                         
913                         /*
914                          *      If the configuration section is NOT there,
915                          *      then ignore it.
916                          *
917                          *      FIXME! This is probably wrong... we should
918                          *      probably set the items to their default values.
919                          */
920                         if (!subcs) continue;
921
922                         if (!variables[i].dflt) {
923                                 DEBUG2("Internal sanity check 1 failed in cf_section_parse");
924                                 cf_section_parse_free(base, variables);
925                                 return -1;
926                         }
927                         
928                         if (cf_section_parse(subcs, base,
929                                              (const CONF_PARSER *) variables[i].dflt) < 0) {
930                                 cf_section_parse_free(base, variables);
931                                 return -1;
932                         }
933                         continue;
934                 } /* else it's a CONF_PAIR */
935                 
936                 if (variables[i].data) {
937                         data = variables[i].data; /* prefer this. */
938                 } else if (base) {
939                         data = ((char *)base) + variables[i].offset;
940                 } else {
941                         DEBUG2("Internal sanity check 2 failed in cf_section_parse");
942                         cf_section_parse_free(base, variables);
943                         return -1;
944                 }
945
946                 /*
947                  *      Parse the pair we found, or a default value.
948                  */
949                 if (cf_item_parse(cs, variables[i].name, variables[i].type,
950                                   data, variables[i].dflt) < 0) {
951                         cf_section_parse_free(base, variables);
952                         return -1;
953                 }
954         } /* for all variables in the configuration section */
955
956         cs->base = base;
957         cs->variables = variables;
958
959         return 0;
960 }
961
962
963 /*
964  *      Read a part of the config file.
965  */
966 static int cf_section_read(const char *file, int *lineno, FILE *fp,
967                            CONF_SECTION *current)
968
969 {
970         CONF_SECTION *this, *css;
971         CONF_PAIR *cpn;
972         char *ptr;
973         const char *value;
974         char buf[8192];
975         char buf1[8192];
976         char buf2[8192];
977         char buf3[8192];
978         int t1, t2, t3;
979         char *cbuf = buf;
980         int len;
981
982         this = current;         /* add items here */
983
984         /*
985          *      Read, checking for line continuations ('\\' at EOL)
986          */
987         for (;;) {
988                 int eof;
989
990                 /*
991                  *      Get data, and remember if we are at EOF.
992                  */
993                 eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
994                 (*lineno)++;
995
996                 len = strlen(cbuf);
997
998                 /*
999                  *      We've filled the buffer, and there isn't
1000                  *      a CR in it.  Die!
1001                  */
1002                 if ((len == (sizeof(buf) - 1)) &&
1003                     (cbuf[len - 1] != '\n')) {
1004                         radlog(L_ERR, "%s[%d]: Line too long",
1005                                file, *lineno);
1006                         return -1;
1007                 }
1008
1009                 /*
1010                  *  Check for continuations.
1011                  */
1012                 if (cbuf[len - 1] == '\n') len--;
1013
1014                 /*
1015                  *      Last character is '\\'.  Over-write it,
1016                  *      and read another line.
1017                  */
1018                 if ((len > 0) && (cbuf[len - 1] == '\\')) {
1019                         cbuf[len - 1] = '\0';
1020                         cbuf += len - 1;
1021                         continue;
1022                 }
1023
1024                 /*
1025                  *  We're at EOF, and haven't read anything.  Stop.
1026                  */
1027                 if (eof && (cbuf == buf)) {
1028                         break;
1029                 }
1030
1031                 ptr = cbuf = buf;
1032                 t1 = gettoken(&ptr, buf1, sizeof(buf1));
1033
1034                if ((*buf1 == '#') || (*buf1 == '\0')) {
1035                        continue;
1036                }
1037
1038                 /*
1039                  *      The caller eats "name1 name2 {", and calls us
1040                  *      for the data inside of the section.  So if we
1041                  *      receive a closing brace, then it must mean the
1042                  *      end of the section.
1043                  */
1044                if (t1 == T_RCBRACE) {
1045                        if (this == current) {
1046                                radlog(L_ERR, "%s[%d]: Too many closing braces",
1047                                       file, *lineno);
1048                                return -1;
1049                                
1050                        }
1051                        this = this->item.parent;
1052                        continue;
1053                 }
1054
1055                 /*
1056                  *      Allow for $INCLUDE files
1057                  *
1058                  *      This *SHOULD* work for any level include.
1059                  *      I really really really hate this file.  -cparker
1060                  */
1061                 if (strcasecmp(buf1, "$INCLUDE") == 0) {
1062                         t2 = getword(&ptr, buf2, sizeof(buf2));
1063
1064                         value = cf_expand_variables(file, lineno, this, buf, buf2);
1065                         if (!value) return -1;
1066
1067 #ifdef HAVE_DIRENT_H
1068                         /*
1069                          *      $INCLUDE foo/
1070                          *
1071                          *      Include ALL non-"dot" files in the directory.
1072                          *      careful!
1073                          */
1074                         if (value[strlen(value) - 1] == '/') {
1075                                 DIR             *dir;
1076                                 struct dirent   *dp;
1077                                 struct stat stat_buf;
1078
1079                                 DEBUG2( "Config:   including files in directory: %s", value );
1080                                 dir = opendir(value);
1081                                 if (!dir) {
1082                                         radlog(L_ERR, "%s[%d]: Error reading directory %s: %s",
1083                                                file, *lineno, value,
1084                                                strerror(errno));
1085                                         return -1;
1086                                 }
1087
1088                                 /*
1089                                  *      Read the directory, ignoring "." files.
1090                                  */
1091                                 while ((dp = readdir(dir)) != NULL) {
1092                                         const char *p;
1093
1094                                         if (dp->d_name[0] == '.') continue;
1095
1096                                         /*
1097                                          *      Check for valid characters
1098                                          */
1099                                         for (p = dp->d_name; *p != '\0'; p++) {
1100                                                 if (isalpha((int)*p) ||
1101                                                     isdigit((int)*p) ||
1102                                                     (*p == '_') ||
1103                                                     (*p == '.')) continue;
1104                                                 break;
1105                                         }
1106                                         if (*p != '\0') continue;
1107
1108                                         snprintf(buf2, sizeof(buf2), "%s%s",
1109                                                  value, dp->d_name);
1110                                         if ((stat(buf2, &stat_buf) != 0) ||
1111                                             S_ISDIR(stat_buf.st_mode)) continue;
1112                                         /*
1113                                          *      Read the file into the current
1114                                          *      configuration sectoin.
1115                                          */
1116                                         if (cf_file_include(buf2, this) < 0) {
1117                                                 closedir(dir);
1118                                                 return -1;
1119                                         }
1120                                 }
1121                                 closedir(dir);
1122                         }  else
1123 #endif
1124                         { /* it was a normal file */
1125                                 if (cf_file_include(value, this) < 0) {
1126                                         return -1;
1127                                 }
1128                         }
1129                         continue;
1130                 } /* we were in an include */
1131
1132                 /*
1133                  *      No '=': must be a section or sub-section.
1134                  */
1135                 if (strchr(ptr, '=') == NULL) {
1136                         t2 = gettoken(&ptr, buf2, sizeof(buf2));
1137                         t3 = gettoken(&ptr, buf3, sizeof(buf3));
1138                 } else {
1139                         t2 = gettoken(&ptr, buf2, sizeof(buf2));
1140                         t3 = getword(&ptr, buf3, sizeof(buf3));
1141                 }
1142
1143                 /*
1144                  * Perhaps a subsection.
1145                  */
1146                 if (t2 == T_LCBRACE || t3 == T_LCBRACE) {
1147                         css = cf_section_alloc(buf1,
1148                                                t2 == T_LCBRACE ? NULL : buf2,
1149                                                this);
1150                         if (!css) {
1151                                 radlog(L_ERR, "%s[%d]: Failed allocating memory for section",
1152                                                 file, *lineno);
1153                         }
1154                         cf_item_add(this, cf_sectiontoitem(css));
1155                         css->item.lineno = *lineno;
1156
1157                         /*
1158                          *      The current section is now the child section.
1159                          */
1160                         this = css;
1161                         continue;
1162                 }
1163
1164                 /*
1165                  *      Ignore semi-colons.
1166                  */
1167                 if (*buf2 == ';')
1168                         *buf2 = '\0';
1169
1170                 /*
1171                  *      Must be a normal attr = value line.
1172                  */
1173                 if (buf1[0] != 0 && buf2[0] == 0 && buf3[0] == 0) {
1174                         t2 = T_OP_EQ;
1175                 } else if (buf1[0] == 0 || buf2[0] == 0 ||
1176                            (t2 < T_EQSTART || t2 > T_EQEND)) {
1177                         radlog(L_ERR, "%s[%d]: Line is not in 'attribute = value' format",
1178                                         file, *lineno);
1179                         return -1;
1180                 }
1181
1182                 /*
1183                  *      Ensure that the user can't add CONF_PAIRs
1184                  *      with 'internal' names;
1185                  */
1186                 if (buf1[0] == '_') {
1187                         radlog(L_ERR, "%s[%d]: Illegal configuration pair name \"%s\"",
1188                                         file, *lineno, buf1);
1189                         return -1;
1190                 }
1191
1192                 /*
1193                  *      Handle variable substitution via ${foo}
1194                  */
1195                 value = cf_expand_variables(file, lineno, this, buf, buf3);
1196                 if (!value) return -1;
1197
1198
1199                 /*
1200                  *      Add this CONF_PAIR to our CONF_SECTION
1201                  */
1202                 cpn = cf_pair_alloc(buf1, value, t2, this);
1203                 cpn->item.lineno = *lineno;
1204                 cf_item_add(this, cf_pairtoitem(cpn));
1205         }
1206
1207         /*
1208          *      See if EOF was unexpected ..
1209          */
1210         if (feof(fp) && (this != current)) {
1211                 radlog(L_ERR, "%s[%d]: EOF reached without closing brace for section %s starting at line %d",
1212                        file, *lineno,
1213                        cf_section_name1(this), cf_section_lineno(this));
1214                 return -1;
1215         }
1216
1217         return 0;
1218 }
1219
1220 /*
1221  *      Include one config file in another.
1222  */
1223 int cf_file_include(const char *file, CONF_SECTION *cs)
1224 {
1225         FILE            *fp;
1226         int             lineno = 0;
1227         struct stat     statbuf;
1228         time_t          *mtime;
1229
1230         DEBUG2( "Config:   including file: %s", file);
1231
1232         if (stat(file, &statbuf) == 0) {
1233                 if ((statbuf.st_mode & S_IWOTH) != 0) {
1234                         radlog(L_ERR|L_CONS, "Configuration file %s is globally writable.  Refusing to start due to insecure configuration.",
1235                                file);
1236                         return -1;
1237                 }
1238
1239                 if (0 && (statbuf.st_mode & S_IROTH) != 0) {
1240                         radlog(L_ERR|L_CONS, "Configuration file %s is globally readable.  Refusing to start due to insecure configuration.",
1241                                file);
1242                         return -1;
1243                 }
1244         }
1245
1246         fp = fopen(file, "r");
1247         if (!fp) {
1248                 radlog(L_ERR|L_CONS, "Unable to open file \"%s\": %s",
1249                        file, strerror(errno));
1250                 return -1;
1251         }
1252
1253         /*
1254          *      Read the section.  It's OK to have EOF without a
1255          *      matching close brace.
1256          */
1257         if (cf_section_read(file, &lineno, fp, cs) < 0) {
1258                 fclose(fp);
1259                 return -1;
1260         }
1261
1262         /*
1263          *      Add the filename to the section
1264          */
1265         mtime = rad_malloc(sizeof(*mtime));
1266         *mtime = statbuf.st_mtime;
1267         /* FIXME: error? */
1268         cf_data_add_internal(cs, file, mtime, free,
1269                              PW_TYPE_FILENAME);
1270
1271         fclose(fp);
1272         return 0;
1273 }
1274
1275 /*
1276  *      Bootstrap a config file.
1277  */
1278 CONF_SECTION *cf_file_read(const char *file)
1279 {
1280         CONF_SECTION *cs;
1281
1282         cs = cf_section_alloc("main", NULL, NULL);
1283         if (!cs) return NULL;
1284
1285         if (cf_file_include(file, cs) < 0) {
1286                 cf_section_free(&cs);
1287                 return NULL;
1288         }
1289
1290         return cs;
1291 }
1292
1293 /*
1294  * Return a CONF_PAIR within a CONF_SECTION.
1295  */
1296 CONF_PAIR *cf_pair_find(const CONF_SECTION *cs, const char *name)
1297 {
1298         CONF_ITEM       *ci;
1299
1300         if (!cs) cs = mainconfig.config;
1301
1302         /*
1303          *      Find the name in the tree, for speed.
1304          */
1305         if (name) {
1306                 CONF_PAIR mycp;
1307
1308                 mycp.attr = name;
1309                 return rbtree_finddata(cs->pair_tree, &mycp);
1310         }
1311
1312         /*
1313          *      Else find the first one
1314          */
1315         for (ci = cs->children; ci; ci = ci->next) {
1316                 if (ci->type == CONF_ITEM_PAIR)
1317                         return cf_itemtopair(ci);
1318         }
1319         
1320         return NULL;
1321 }
1322
1323 /*
1324  * Return the attr of a CONF_PAIR
1325  */
1326
1327 char *cf_pair_attr(CONF_PAIR *pair)
1328 {
1329         return (pair ? pair->attr : NULL);
1330 }
1331
1332 /*
1333  * Return the value of a CONF_PAIR
1334  */
1335
1336 char *cf_pair_value(CONF_PAIR *pair)
1337 {
1338         return (pair ? pair->value : NULL);
1339 }
1340
1341 /*
1342  * Return the first label of a CONF_SECTION
1343  */
1344
1345 const char *cf_section_name1(const CONF_SECTION *cs)
1346 {
1347         return (cs ? cs->name1 : NULL);
1348 }
1349
1350 /*
1351  * Return the second label of a CONF_SECTION
1352  */
1353
1354 const char *cf_section_name2(const CONF_SECTION *cs)
1355 {
1356         return (cs ? cs->name2 : NULL);
1357 }
1358
1359 /*
1360  * Find a value in a CONF_SECTION
1361  */
1362 char *cf_section_value_find(const CONF_SECTION *cs, const char *attr)
1363 {
1364         CONF_PAIR       *cp;
1365
1366         cp = cf_pair_find(cs, attr);
1367
1368         return (cp ? cp->value : NULL);
1369 }
1370
1371 /*
1372  * Return the next pair after a CONF_PAIR
1373  * with a certain name (char *attr) If the requested
1374  * attr is NULL, any attr matches.
1375  */
1376
1377 CONF_PAIR *cf_pair_find_next(const CONF_SECTION *cs,
1378                              const CONF_PAIR *pair, const char *attr)
1379 {
1380         CONF_ITEM       *ci;
1381
1382         /*
1383          * If pair is NULL this must be a first time run
1384          * Find the pair with correct name
1385          */
1386
1387         if (pair == NULL){
1388                 return cf_pair_find(cs, attr);
1389         }
1390
1391         ci = cf_pairtoitem(pair)->next;
1392
1393         for (; ci; ci = ci->next) {
1394                 if (ci->type != CONF_ITEM_PAIR)
1395                         continue;
1396                 if (attr == NULL || strcmp(cf_itemtopair(ci)->attr, attr) == 0)
1397                         break;
1398         }
1399
1400         return cf_itemtopair(ci);
1401 }
1402
1403 /*
1404  * Find a CONF_SECTION, or return the root if name is NULL
1405  */
1406
1407 CONF_SECTION *cf_section_find(const char *name)
1408 {
1409         if (name)
1410                 return cf_section_sub_find(mainconfig.config, name);
1411         else
1412                 return mainconfig.config;
1413 }
1414
1415 /*
1416  * Find a sub-section in a section
1417  */
1418
1419 CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name)
1420 {
1421         CONF_ITEM *ci;
1422
1423         /*
1424          *      Do the fast lookup if possible.
1425          */
1426         if (name && cs->section_tree) {
1427                 CONF_SECTION mycs;
1428
1429                 mycs.name1 = name;
1430                 mycs.name2 = NULL;
1431                 return rbtree_finddata(cs->section_tree, &mycs);
1432         }
1433
1434         for (ci = cs->children; ci; ci = ci->next) {
1435                 if (ci->type != CONF_ITEM_SECTION)
1436                         continue;
1437                 if (strcmp(cf_itemtosection(ci)->name1, name) == 0)
1438                         break;
1439         }
1440
1441         return cf_itemtosection(ci);
1442
1443 }
1444
1445
1446 /*
1447  *      Find a CONF_SECTION with both names.
1448  */
1449 CONF_SECTION *cf_section_sub_find_name2(const CONF_SECTION *cs,
1450                                         const char *name1, const char *name2)
1451 {
1452         CONF_ITEM    *ci;
1453
1454         if (!name2) return cf_section_sub_find(cs, name1);
1455
1456         if (!cs) cs = mainconfig.config;
1457
1458         if (name1 && (cs->section_tree)) {
1459                 CONF_SECTION mycs, *master_cs;
1460                 
1461                 mycs.name1 = name1;
1462                 mycs.name2 = name2;
1463                 
1464                 master_cs = rbtree_finddata(cs->section_tree, &mycs);
1465                 if (master_cs) {
1466                         return rbtree_finddata(master_cs->name2_tree, &mycs);
1467                 }
1468         }
1469
1470         /*
1471          *      Else do it the old-fashioned way.
1472          */
1473         for (ci = cs->children; ci; ci = ci->next) {
1474                 CONF_SECTION *subcs;
1475
1476                 if (ci->type != CONF_ITEM_SECTION)
1477                         continue;
1478
1479                 subcs = cf_itemtosection(ci);
1480                 if (!name1) {
1481                         if (!subcs->name2) {
1482                                 if (strcmp(subcs->name1, name2) == 0) break;
1483                         } else {
1484                                 if (strcmp(subcs->name2, name2) == 0) break;
1485                         }
1486                         continue; /* don't do the string comparisons below */
1487                 }
1488
1489                 if ((strcmp(subcs->name1, name1) == 0) &&
1490                     (subcs->name2 != NULL) &&
1491                     (strcmp(subcs->name2, name2) == 0))
1492                         break;
1493         }
1494
1495         return cf_itemtosection(ci);
1496 }
1497
1498 /*
1499  * Return the next subsection after a CONF_SECTION
1500  * with a certain name1 (char *name1). If the requested
1501  * name1 is NULL, any name1 matches.
1502  */
1503
1504 CONF_SECTION *cf_subsection_find_next(CONF_SECTION *section,
1505                                       CONF_SECTION *subsection,
1506                                       const char *name1)
1507 {
1508         CONF_ITEM       *ci;
1509
1510         /*
1511          * If subsection is NULL this must be a first time run
1512          * Find the subsection with correct name
1513          */
1514
1515         if (subsection == NULL){
1516                 ci = section->children;
1517         } else {
1518                 ci = cf_sectiontoitem(subsection)->next;
1519         }
1520
1521         for (; ci; ci = ci->next) {
1522                 if (ci->type != CONF_ITEM_SECTION)
1523                         continue;
1524                 if ((name1 == NULL) ||
1525                     (strcmp(cf_itemtosection(ci)->name1, name1) == 0))
1526                         break;
1527         }
1528
1529         return cf_itemtosection(ci);
1530 }
1531
1532 /*
1533  * Return the next item after a CONF_ITEM.
1534  */
1535
1536 CONF_ITEM *cf_item_find_next(CONF_SECTION *section, CONF_ITEM *item)
1537 {
1538         /*
1539          * If item is NULL this must be a first time run
1540          * Return the first item
1541          */
1542
1543         if (item == NULL) {
1544                 return section->children;
1545         } else {
1546                 return item->next;
1547         }
1548 }
1549
1550 int cf_section_lineno(CONF_SECTION *section)
1551 {
1552         return cf_sectiontoitem(section)->lineno;
1553 }
1554
1555 int cf_pair_lineno(CONF_PAIR *pair)
1556 {
1557         return cf_pairtoitem(pair)->lineno;
1558 }
1559
1560 int cf_item_is_section(CONF_ITEM *item)
1561 {
1562         return item->type == CONF_ITEM_SECTION;
1563 }
1564 int cf_item_is_pair(CONF_ITEM *item)
1565 {
1566         return item->type == CONF_ITEM_PAIR;
1567 }
1568
1569
1570 static CONF_DATA *cf_data_alloc(CONF_SECTION *parent, const char *name,
1571                                 void *data, void (*data_free)(void *))
1572 {
1573         CONF_DATA *cd;
1574
1575         cd = rad_malloc(sizeof(*cd));
1576         memset(cd, 0, sizeof(*cd));
1577
1578         cd->item.type = CONF_ITEM_DATA;
1579         cd->item.parent = parent;
1580         cd->name = strdup(name);
1581         cd->data = data;
1582         cd->free = data_free;
1583
1584         return cd;
1585 }
1586
1587
1588 static void *cf_data_find_internal(CONF_SECTION *cs, const char *name,
1589                                    int flag)
1590 {
1591         if (!cs || !name) return NULL;
1592         
1593         /*
1594          *      Find the name in the tree, for speed.
1595          */
1596         if (cs->data_tree) {
1597                 CONF_DATA mycd, *cd;
1598
1599                 mycd.name = name;
1600                 mycd.flag = flag;
1601                 cd = rbtree_finddata(cs->data_tree, &mycd);
1602                 if (cd) return cd->data;
1603         }
1604
1605         return NULL;
1606 }
1607
1608 /*
1609  *      Find data from a particular section.
1610  */
1611 void *cf_data_find(CONF_SECTION *cs, const char *name)
1612 {
1613         return cf_data_find_internal(cs, name, 0);
1614 }
1615
1616
1617 /*
1618  *      Add named data to a configuration section.
1619  */
1620 static int cf_data_add_internal(CONF_SECTION *cs, const char *name,
1621                                 void *data, void (*data_free)(void *),
1622                                 int flag)
1623 {
1624         CONF_DATA *cd;
1625
1626         if (!cs || !name) return -1;
1627
1628         /*
1629          *      Already exists.  Can't add it.
1630          */
1631         if (cf_data_find_internal(cs, name, flag) != NULL) return -1;
1632
1633         cd = cf_data_alloc(cs, name, data, data_free);
1634         if (!cd) return -1;
1635         cd->flag = flag;
1636
1637         cf_item_add(cs, cf_datatoitem(cd));
1638
1639         return 0;
1640 }
1641
1642 /*
1643  *      Add named data to a configuration section.
1644  */
1645 int cf_data_add(CONF_SECTION *cs, const char *name,
1646                 void *data, void (*data_free)(void *))
1647 {
1648         return cf_data_add_internal(cs, name, data, data_free, 0);
1649 }
1650
1651
1652 /*
1653  *      Copy CONF_DATA from src to dst
1654  */
1655 static void cf_section_copy_data(CONF_SECTION *s, CONF_SECTION *d)
1656 {
1657         
1658         CONF_ITEM *cd, *next, **last;
1659
1660         /*
1661          *      Don't check if s->data_tree is NULL.  It's child
1662          *      sections may have data, even if this section doesn't.
1663          */
1664
1665         rad_assert(d->data_tree == NULL);
1666         d->data_tree = s->data_tree;
1667         s->data_tree = NULL;
1668         
1669         /*
1670          *      Walk through src, moving CONF_ITEM_DATA
1671          *      to dst, by hand.
1672          */
1673         last = &(s->children);
1674         for (cd = s->children; cd != NULL; cd = next) {
1675                 next = cd->next;
1676                 
1677                 /*
1678                  *      Recursively copy data from child sections.
1679                  */
1680                 if (cd->type == CONF_ITEM_SECTION) {
1681                         CONF_SECTION *s1, *d1;
1682                         
1683                         s1 = cf_itemtosection(cd);
1684                         d1 = cf_section_sub_find_name2(d, s1->name1, s1->name2);
1685                         if (d1) {
1686                                 cf_section_copy_data(s1, d1);
1687                         }
1688                         last = &(cd->next);
1689                         continue;
1690                 }
1691
1692                 /*
1693                  *      Not conf data, remember last ptr.
1694                  */
1695                 if (cd->type != CONF_ITEM_DATA) {
1696                         last = &(cd->next);
1697                         continue;
1698                 }
1699                 
1700                 /*
1701                  *      Remove it from the src list
1702                  */
1703                 *last = cd->next;
1704                 cd->next = NULL;
1705                 
1706                 /*
1707                  *      Add it to the dst list
1708                  */
1709                 if (!d->children) {
1710                         rad_assert(d->tail == NULL);
1711                         d->children = cd;
1712                 } else {
1713                         rad_assert(d->tail != NULL);
1714                         d->tail->next = cd;
1715                 }
1716                 d->tail = cd;
1717         }
1718 }
1719
1720 /*
1721  *      For a CONF_DATA element, stat the filename, if necessary.
1722  */
1723 static int filename_stat(void *context, void *data)
1724 {
1725         struct stat buf;
1726         CONF_DATA *cd = data;
1727
1728         context = context;      /* -Wunused */
1729
1730         if (cd->flag != PW_TYPE_FILENAME) return 0;
1731
1732         if (stat(cd->name, &buf) < 0) return -1;
1733
1734         if (buf.st_mtime != *(time_t *) cd->data) return -1;
1735
1736         return 0;
1737 }
1738
1739
1740 /*
1741  *      Compare two CONF_SECTIONS.  The items MUST be in the same
1742  *      order.
1743  */
1744 static int cf_section_cmp(CONF_SECTION *a, CONF_SECTION *b)
1745 {
1746         CONF_ITEM *ca = a->children;
1747         CONF_ITEM *cb = b->children;
1748
1749         while (1) {
1750                 CONF_PAIR *pa, *pb;
1751
1752                 /*
1753                  *      Done.  Stop.
1754                  */
1755                 if (!ca && !cb) break;
1756
1757                 /*
1758                  *      Skip CONF_DATA.
1759                  */
1760                 if (ca && ca->type == CONF_ITEM_DATA) {
1761                         ca = ca->next;
1762                         continue;
1763                 }
1764                 if (cb && cb->type == CONF_ITEM_DATA) {
1765                         cb = cb->next;
1766                         continue;
1767                 }
1768
1769                 /*
1770                  *      One is smaller than the other.  Exit.
1771                  */
1772                 if (!ca || !cb) return 0;
1773
1774                 if (ca->type != cb->type) return 0;
1775
1776                 /*
1777                  *      Deal with subsections.
1778                  */
1779                 if (ca->type == CONF_ITEM_SECTION) {
1780                         CONF_SECTION *sa = cf_itemtosection(ca);
1781                         CONF_SECTION *sb = cf_itemtosection(cb);
1782
1783                         if (!cf_section_cmp(sa, sb)) return 0;
1784                         goto next;
1785                 }
1786
1787                 rad_assert(ca->type == CONF_ITEM_PAIR);
1788
1789                 pa = cf_itemtopair(ca);
1790                 pb = cf_itemtopair(cb);
1791
1792                 /*
1793                  *      Different attr and/or value, Exit.
1794                  */
1795                 if ((strcmp(pa->attr, pb->attr) != 0) ||
1796                     (strcmp(pa->value, pb->value) != 0)) return 0;
1797                 
1798
1799                 /*
1800                  *      And go to the next element.
1801                  */
1802         next:
1803                 ca = ca->next;
1804                 cb = cb->next;
1805         }
1806
1807         /*
1808          *      Walk over the CONF_DATA, stat'ing PW_TYPE_FILENAME.
1809          */
1810         if (a->data_tree &&
1811             (rbtree_walk(a->data_tree, InOrder, filename_stat, NULL) != 0)) {
1812                 return 0;
1813         }
1814
1815         /*
1816          *      They must be the same, say so.
1817          */
1818         return 1;
1819 }
1820
1821
1822
1823
1824 /*
1825  *      Migrate CONF_DATA from one section to another.
1826  */
1827 int cf_section_migrate(CONF_SECTION *dst, CONF_SECTION *src)
1828 {
1829         CONF_ITEM *ci;
1830         CONF_SECTION *s, *d;
1831
1832         for (ci = src->children; ci != NULL; ci = ci->next) {
1833                 if (ci->type != CONF_ITEM_SECTION)
1834                         continue;
1835
1836                 s = cf_itemtosection(ci);
1837                 d = cf_section_sub_find_name2(dst, s->name1, s->name2);
1838
1839                 if (!d) continue; /* not in new one, don't migrate it */
1840
1841                 /*
1842                  *      A section of the same name is in BOTH src & dst,
1843                  *      compare the CONF_PAIR's.  If they're all the same,
1844                  *      then copy the CONF_DATA from one to the other.
1845                  */
1846                 if (cf_section_cmp(s, d)) {
1847                         cf_section_copy_data(s, d);
1848                 }
1849         }
1850
1851         return 1;               /* rcode means anything? */
1852 }
1853
1854
1855 #if 0
1856 /*
1857  * JMG dump_config tries to dump the config structure in a readable format
1858  *
1859 */
1860
1861 static int dump_config_section(CONF_SECTION *cs, int indent)
1862 {
1863         CONF_SECTION    *scs;
1864         CONF_PAIR       *cp;
1865         CONF_ITEM       *ci;
1866
1867         /* The DEBUG macro doesn't let me
1868          *   for(i=0;i<indent;++i) debugputchar('\t');
1869          * so I had to get creative. --Pac. */
1870
1871         for (ci = cs->children; ci; ci = ci->next) {
1872                 switch (ci->type) {
1873                 case CONF_ITEM_PAIR:
1874                         cp=cf_itemtopair(ci);
1875                         DEBUG("%.*s%s = %s",
1876                                 indent, "\t\t\t\t\t\t\t\t\t\t\t",
1877                                 cp->attr, cp->value);
1878                         break;
1879
1880                 case CONF_ITEM_SECTION:
1881                         scs=cf_itemtosection(ci);
1882                         DEBUG("%.*s%s %s%s{",
1883                                 indent, "\t\t\t\t\t\t\t\t\t\t\t",
1884                                 scs->name1,
1885                                 scs->name2 ? scs->name2 : "",
1886                                 scs->name2 ?  " " : "");
1887                         dump_config_section(scs, indent+1);
1888                         DEBUG("%.*s}",
1889                                 indent, "\t\t\t\t\t\t\t\t\t\t\t");
1890                         break;
1891
1892                 default:        /* FIXME: Do more! */
1893                         break;
1894                 }
1895         }
1896
1897         return 0;
1898 }
1899
1900 int dump_config(void)
1901 {
1902         return dump_config_section(mainconfig.config, 0);
1903 }
1904 #endif