Added more 'const'
[freeradius.git] / src / main / conffile.c
index 8281e9c..b56f5ba 100644 (file)
@@ -517,11 +517,13 @@ static void cf_item_add(CONF_SECTION *cs, CONF_ITEM *ci)
 
                                if (!cs->section_tree) {
                                        cs->section_tree = rbtree_create(section_cmp, NULL, 0);
-                                       /* ignore any errors */
+                                       if (!cs->section_tree) {
+                                               radlog(L_ERR, "Out of memory");
+                                               _exit(1);
+                                       }
                                }
 
-                               if (cs->section_tree) {
-                                       rbtree_insert(cs->section_tree, cs_new);                                }
+                               rbtree_insert(cs->section_tree, cs_new);
 
                                /*
                                 *      Two names: find the named instance.
@@ -906,7 +908,9 @@ int cf_item_parse(CONF_SECTION *cs, const char *name,
                if (value == dflt) {
                        char buffer[8192];
 
-                       int lineno = cs->item.lineno;
+                       int lineno = 0;
+
+                       if (cs) lineno = cs->item.lineno;
 
                        /*
                         *      FIXME: sizeof(buffer)?
@@ -940,7 +944,9 @@ int cf_item_parse(CONF_SECTION *cs, const char *name,
                if (value == dflt) {
                        char buffer[8192];
 
-                       int lineno = cs->item.lineno;
+                       int lineno = 0;
+
+                       if (cs) lineno = cs->item.lineno;
 
                        /*
                         *      FIXME: sizeof(buffer)?
@@ -1237,12 +1243,12 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
         *      Read, checking for line continuations ('\\' at EOL)
         */
        for (;;) {
-               int eof;
+               int at_eof;
 
                /*
                 *      Get data, and remember if we are at EOF.
                 */
-               eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
+               at_eof = (fgets(cbuf, sizeof(buf) - (cbuf - buf), fp) == NULL);
                (*lineno)++;
 
                /*
@@ -1264,14 +1270,14 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
                 *      conditions.
                 */
                if (cbuf == buf) {
-                       if (eof) break;
+                       if (at_eof) break;
                        
                        ptr = buf;
                        while (*ptr && isspace((int) *ptr)) ptr++;
 
                        if (!*ptr || (*ptr == '#')) continue;
 
-               } else if (eof || (len == 0)) {
+               } else if (at_eof || (len == 0)) {
                        radlog(L_ERR, "%s[%d]: Continuation at EOF is illegal",
                               filename, *lineno);
                        return -1;
@@ -1456,12 +1462,19 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
 
               if (strcasecmp(buf1, "$template") == 0) {
                       CONF_ITEM *ci;
-                      CONF_SECTION *parentcs;
+                      CONF_SECTION *parentcs, *templatecs;
                       t2 = getword(&ptr, buf2, sizeof(buf2));
 
                       parentcs = cf_top_section(current);
 
-                      ci = cf_reference_item(parentcs, this, buf2);
+                      templatecs = cf_section_sub_find(parentcs, "templates");
+                      if (!templatecs) {
+                               radlog(L_ERR, "%s[%d]: No \"templates\" section for reference \"%s\"",
+                                      filename, *lineno, buf2);
+                               return -1;
+                      }
+
+                      ci = cf_reference_item(parentcs, templatecs, buf2);
                       if (!ci || (ci->type != CONF_ITEM_SECTION)) {
                                radlog(L_ERR, "%s[%d]: Reference \"%s\" not found",
                                       filename, *lineno, buf2);
@@ -1505,6 +1518,7 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
                case T_OP_SUB:
                case T_OP_LE:
                case T_OP_GE:
+               case T_OP_CMP_FALSE:
                        if (!this || (strcmp(this->name1, "update") != 0)) {
                                radlog(L_ERR, "%s[%d]: Invalid operator in assignment",
                                       filename, *lineno);
@@ -1515,6 +1529,12 @@ static int cf_section_read(const char *filename, int *lineno, FILE *fp,
                case T_OP_SET:
                do_set:
                        t3 = getstring(&ptr, buf3, sizeof(buf3));
+                       if (t3 == T_OP_INVALID) {
+                               radlog(L_ERR, "%s[%d]: Parse error: %s",
+                                      filename, *lineno,
+                                      fr_strerror());
+                               return -1;
+                       }
 
                        /*
                         *      Handle variable substitution via ${foo}
@@ -1686,6 +1706,12 @@ int cf_file_include(const char *filename, CONF_SECTION *cs)
                return -1;
        }
 
+       if (cf_data_find_internal(cs, filename, PW_TYPE_FILENAME)) {
+               radlog(L_ERR, "Cannot include the same file twice: \"%s\"",
+                      filename);
+               return -1;
+       }
+
        /*
         *      Add the filename to the section
         */
@@ -1695,7 +1721,7 @@ int cf_file_include(const char *filename, CONF_SECTION *cs)
        if (cf_data_add_internal(cs, filename, mtime, free,
                                 PW_TYPE_FILENAME) < 0) {
                fclose(fp);
-               radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",
+               radlog(L_ERR|L_CONS, "Internal error opening file \"%s\"",
                       filename);
                return -1;
        }
@@ -1703,7 +1729,7 @@ int cf_file_include(const char *filename, CONF_SECTION *cs)
        cd = cf_data_find_internal(cs, filename, PW_TYPE_FILENAME);
        if (!cd) {
                fclose(fp);
-               radlog(L_ERR|L_CONS, "Internal error open file \"%s\"",
+               radlog(L_ERR|L_CONS, "Internal error opening file \"%s\"",
                       filename);
                return -1;
        }
@@ -1805,10 +1831,6 @@ const char *cf_pair_value(CONF_PAIR *pair)
        return (pair ? pair->value : NULL);
 }
 
-/*
- *     Copied here for error reporting.
- */
-extern void fr_strerror_printf(const char *, ...);
 
 /*
  * Turn a CONF_PAIR into a VALUE_PAIR
@@ -1942,10 +1964,12 @@ CONF_SECTION *cf_section_sub_find(const CONF_SECTION *cs, const char *name)
 {
        CONF_ITEM *ci;
 
+       if (!name) return NULL; /* can't find an un-named section */
+
        /*
         *      Do the fast lookup if possible.
         */
-       if (name && cs->section_tree) {
+       if (cs->section_tree) {
                CONF_SECTION mycs;
 
                mycs.name1 = name;
@@ -2549,42 +2573,53 @@ static const char *cf_pair_print_value(const CONF_PAIR *cp,
 }
 
 
-int cf_pair2xml(FILE *fp, CONF_PAIR *cp)
+int cf_pair2xml(FILE *fp, const CONF_PAIR *cp)
 {
-       fprintf(fp, "<pair name=\"%s\">", cp->attr);
-       switch (cp->value_type) {
-       case T_DOUBLE_QUOTED_STRING:
-               /*
-                *      FIXME: Handle this later!
-                */
+       fprintf(fp, "<%s>", cp->attr);
+       if (cp->value) {
+               char buffer[2048];
 
-       case T_BARE_WORD:
-       default:
-               /*
-                *      FIXME: Escape '<', '>', '&', etc.
+               char *p = buffer;
+               const char *q = cp->value;
 
-                */
-               if (cp->value) fprintf(fp, "%s", cp->value);
-               break;
+               while (*q && (p < (buffer + sizeof(buffer)))) {
+                       if (q[0] == '&') {
+                               memcpy(p, "&amp;", 4);
+                               p += 5;
+
+                       } else if (q[0] == '<') {
+                               memcpy(p, "&lt;", 4);
+                               p += 4;
+
+                       } else if (q[0] == '>') {
+                               memcpy(p, "&gt;", 4);
+                               p += 4;
+
+                       } else {
+                               *(p++) = *q;
+                       }
+                       q++;
+               }
+
+               *p = '\0';
+               fprintf(fp, "%s", buffer);
        }
 
-       fprintf(fp, "</pair>\n");
+       fprintf(fp, "</%s>\n", cp->attr);
 
        return 1;
 }
 
-int cf_section2xml(FILE *fp, CONF_SECTION *cs)
+int cf_section2xml(FILE *fp, const CONF_SECTION *cs)
 {
        CONF_ITEM *ci, *next;
 
        /*
         *      Section header
         */
-       if (!cs->name2) {
-               fprintf(fp, "<section name=\"%s\">\n", cs->name1);
-       } else {
-               fprintf(fp, "<section name=\"%s\" name2=\"%s\">\n",
-                       cs->name1, cs->name2);
+       fprintf(fp, "<%s>\n", cs->name1);
+       if (cs->name2) {
+               fprintf(fp, "<_name2>%s</_name2>\n", cs->name2);
        }
 
        /*
@@ -2608,12 +2643,12 @@ int cf_section2xml(FILE *fp, CONF_SECTION *cs)
                }
        }
 
-       fprintf(fp, "</section>\n");
+       fprintf(fp, "</%s>\n", cs->name1);
 
        return 1;               /* success */
 }
 
-int cf_pair2file(FILE *fp, CONF_PAIR *cp)
+int cf_pair2file(FILE *fp, const CONF_PAIR *cp)
 {
        char buffer[2048];
 
@@ -2623,9 +2658,9 @@ int cf_pair2file(FILE *fp, CONF_PAIR *cp)
        return 1;
 }
 
-int cf_section2file(FILE *fp, CONF_SECTION *cs)
+int cf_section2file(FILE *fp, const CONF_SECTION *cs)
 {
-       CONF_ITEM *ci, *next;
+       const CONF_ITEM *ci, *next;
 
        /*
         *      Section header