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