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