Hello.

This is an adapted version of Roberts patch which makes some more testcases pass
for me.

I have made a few functions that wasn't in the header file static in the process
since I wanted to change their behaviour slightly in order to make error reporting
consistent.

Could this please be applyed to the head branch?

/MF
Index: snmplib/read_config.c
===================================================================
RCS file: /cvsroot/net-snmp/net-snmp/snmplib/read_config.c,v
retrieving revision 5.24
diff -c -r5.24 read_config.c
*** snmplib/read_config.c       17 Aug 2004 09:08:54 -0000      5.24
--- snmplib/read_config.c       24 Aug 2004 06:09:52 -0000
***************
*** 437,454 ****
      return NULL;
  }
  
  void
  read_config_with_type(const char *filename, const char *type)
  {
      struct config_line *ctmp = read_config_get_handlers(type);
      if (ctmp)
!         read_config(filename, ctmp, EITHER_CONFIG);
      else
          DEBUGMSGTL(("read_config",
!                     "read_config: I have no registrations for type:%s,file:%s\n",
                      type, filename));
  }
  
  
  struct config_line *
  read_config_find_handler(struct config_line *line_handlers,
--- 437,510 ----
      return NULL;
  }
  
+ static void
+ read_config_list(const char *filename,
+                struct config_line **line_handler, int line_handlers,
+                int when);
+ 
  void
  read_config_with_type(const char *filename, const char *type)
  {
      struct config_line *ctmp = read_config_get_handlers(type);
      if (ctmp)
!         read_config_list(filename, &ctmp, 1, EITHER_CONFIG);
      else
          DEBUGMSGTL(("read_config",
!                     "read_config: I have no registrations for type:%s, file:%s\n",
                      type, filename));
  }
  
+ static void
+ read_config_with_types(const char *filename, const char *types)
+ {
+     if (NULL != strchr(types, ':')) {
+         const char *delim;
+ 
+       int count = 0;
+       int size = 0;
+       struct config_line** clist = 0;
+ 
+       do {
+           struct config_files* ctmp;
+ 
+             delim = strchr(types, ':');
+             if (NULL == delim)
+                 delim = types + strlen(types);
+ 
+           if(count == size) {
+               struct config_line** list;
+               list = realloc(clist, size * sizeof(struct config_line*));
+               if(list == NULL) {
+                   free(clist);
+                   snmp_log(LOG_ERR,"realloc failed\n");
+                   return;
+               } else {
+                   size += 16;
+                   clist = list;
+               }
+           }
+ 
+           ctmp = config_files;
+           while (ctmp != NULL &&
+                  (strncmp(ctmp->fileHeader, types, delim - types) ||
+                   ctmp->fileHeader[1 + (delim - types)] != '\0'))
+               ctmp = ctmp->next;
+           if (ctmp) {
+               clist[count] = ctmp->start;
+               ++count;
+           } else {
+               DEBUGMSGTL(("read_config",
+                           "read_config: I have no registrations for type:%.*s, 
file:%s\n",
+                           (int)(delim - types), types, filename));
+           }
+           types = delim + 1;
+         } while(*delim != '\0');
+         read_config_list(filename, clist, count, EITHER_CONFIG);
+       free(clist);
+     } else {
+         read_config_with_type(filename, types);
+     }
+ }
  
  struct config_line *
  read_config_find_handler(struct config_line *line_handlers,
***************
*** 467,478 ****
  
  /*
   * searches a config_line linked list for a match 
   */
! int
  run_config_handler(struct config_line *lptr,
                     const char *token, char *cptr, int when)
  {
-     char            tmpbuf[STRINGMAX];
      char           *cp;
      lptr = read_config_find_handler(lptr, token);
      if (lptr != NULL) {
--- 523,534 ----
  
  /*
   * searches a config_line linked list for a match 
+  * returns SNMPERR_SUCCESS if the item was found, SNMP_GENERR otherwise
   */
! static int
  run_config_handler(struct config_line *lptr,
                     const char *token, char *cptr, int when)
  {
      char           *cp;
      lptr = read_config_find_handler(lptr, token);
      if (lptr != NULL) {
***************
*** 489,503 ****
              }
              (*(lptr->parse_line)) (token, cptr);
          }
!     } else if (when != PREMIB_CONFIG && 
!              !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
!                                      NETSNMP_DS_LIB_NO_TOKEN_WARNINGS)) {
!         snprintf(tmpbuf, sizeof(tmpbuf), "Unknown token: %s.", token);
!         tmpbuf[ sizeof(tmpbuf)-1 ] = 0;
!         config_pwarn(tmpbuf);
!         return SNMPERR_GENERR;
      }
!     return SNMPERR_SUCCESS;
  }
  
  /*
--- 545,554 ----
              }
              (*(lptr->parse_line)) (token, cptr);
          }
!       return SNMPERR_SUCCESS;
      }
! 
!     return SNMPERR_GENERR;
  }
  
  /*
***************
*** 568,574 ****
       */
      line = skip_white(line + (cptr - buf) + strlen(cptr) + 1);
  
!     return (run_config_handler(lptr, cptr, line, when));
  }
  
  int
--- 619,634 ----
       */
      line = skip_white(line + (cptr - buf) + strlen(cptr) + 1);
  
!     if(run_config_handler(lptr, cptr, line, when) == SNMPERR_GENERR &&
!        when != PREMIB_CONFIG &&
!        !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
!                              NETSNMP_DS_LIB_NO_TOKEN_WARNINGS)) {
!         snprintf(tmpbuf, sizeof(tmpbuf), "Unknown token: %s.", cptr);
!         tmpbuf[ sizeof(tmpbuf)-1 ] = 0;
!         config_pwarn(tmpbuf);
!         return SNMPERR_GENERR;
!     } else
!       return SNMPERR_SUCCESS;
  }
  
  int
***************
*** 681,694 ****
   */
  void
  read_config(const char *filename,
!             struct config_line *line_handler, int when)
  {
  
      FILE           *ifile;
      char            line[STRINGMAX], token[STRINGMAX], tmpbuf[STRINGMAX];
      char           *cptr;
      int             i;
!     struct config_line *lptr;
  
      linecount = 0;
      curfilename = filename;
--- 741,766 ----
   */
  void
  read_config(const char *filename,
!           struct config_line *line_handler, int when)
! {
!     read_config_list(filename, &line_handler, 1, when);
! }
! 
! static void
! read_config_list(const char *filename,
!                struct config_line **line_handler, int line_handlers,
!                int when)
  {
  
      FILE           *ifile;
      char            line[STRINGMAX], token[STRINGMAX], tmpbuf[STRINGMAX];
      char           *cptr;
      int             i;
!     struct config_line **lptr;
!     int             lcnt;
! 
!     struct config_line *altlptr;
!     struct config_line *tmplptr;
  
      linecount = 0;
      curfilename = filename;
***************
*** 721,726 ****
--- 793,799 ----
  
      while (fgets(line, sizeof(line), ifile) != NULL) {
          lptr = line_handler;
+         lcnt = line_handlers;
          linecount++;
          cptr = line;
          i = strlen(line) - 1;
***************
*** 741,748 ****
                      continue;
                  }
                  token[strlen(token) - 1] = '\0';
!                 lptr = read_config_get_handlers(&token[1]);
!                 if (lptr == NULL) {
                      snprintf(tmpbuf, sizeof(tmpbuf),
                              "No handlers regestered for type %s.",
                              &token[1]);
--- 814,821 ----
                      continue;
                  }
                  token[strlen(token) - 1] = '\0';
!                 tmplptr = read_config_get_handlers(&token[1]);
!                 if (tmplptr == NULL) {
                      snprintf(tmpbuf, sizeof(tmpbuf),
                              "No handlers regestered for type %s.",
                              &token[1]);
***************
*** 758,773 ****
                      /*
                       * change context permanently 
                       */
!                     line_handler = lptr;
                      continue;
                  } else {
                      /*
                       * the rest of this line only applies. 
                       */
                      cptr = copy_nword(cptr, token, sizeof(token));
                  }
-             } else {
-                 lptr = line_handler;
              }
              if (cptr == NULL) {
                  snprintf(tmpbuf, sizeof(tmpbuf),
--- 831,848 ----
                      /*
                       * change context permanently 
                       */
!                     altlptr = tmplptr;
!                     line_handler = &altlptr;
!                     line_handlers = 1;
                      continue;
                  } else {
                      /*
                       * the rest of this line only applies. 
                       */
+                     lptr = &tmplptr;
+                     lcnt = 1;
                      cptr = copy_nword(cptr, token, sizeof(token));
                  }
              }
              if (cptr == NULL) {
                  snprintf(tmpbuf, sizeof(tmpbuf),
***************
*** 777,790 ****
              } else {
                  DEBUGMSGTL(("read_config", "%s:%d examining: %s\n",
                              filename, linecount, line));
!                 run_config_handler(lptr, token, cptr, when);
              }
          }
      }
      fclose(ifile);
      return;
  
! }                               /* end read_config() */
  
  
  
--- 852,881 ----
              } else {
                  DEBUGMSGTL(("read_config", "%s:%d examining: %s\n",
                              filename, linecount, line));
!                 if(lcnt > 0) {
!                     int res;
!                     do {
!                         res = run_config_handler(*lptr, token, cptr, when);
!                         --lcnt;
!                         ++lptr;
!                     } while(res == SNMPERR_GENERR && lcnt > 0);
!                     if(res == SNMPERR_GENERR &&
!                        when != PREMIB_CONFIG && 
!                        !netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, 
!                                                NETSNMP_DS_LIB_NO_TOKEN_WARNINGS)) {
!                         snprintf(tmpbuf, sizeof(tmpbuf), "Unknown token: %s.",
!                                  token);
!                         tmpbuf[ sizeof(tmpbuf)-1 ] = 0;
!                         config_pwarn(tmpbuf);
!                     }
!                 }
              }
          }
      }
      fclose(ifile);
      return;
  
! }                               /* end read_config_list() */
  
  
  
***************
*** 838,844 ****
              DEBUGMSGTL(("read_config",
                          "Reading optional config file: \"%s\"\n",
                          cp));
!             read_config_with_type(cp, type);
          }
          cp = strtok(NULL, ",");
        }
--- 929,935 ----
              DEBUGMSGTL(("read_config",
                          "Reading optional config file: \"%s\"\n",
                          cp));
!             read_config_with_types(cp, type);
          }
          cp = strtok(NULL, ",");
        }
***************
*** 1115,1132 ****
                          DEBUGMSGTL(("read_config_files",
                                      "old config file found: %s, parsing\n",
                                      configfile));
!                         read_config(configfile, ltmp, when);
                      }
                  }
              }
              snprintf(configfile, sizeof(configfile),
                       "%s/%s.conf", cptr2, ctmp->fileHeader);
              configfile[ sizeof(configfile)-1 ] = 0;
!             read_config(configfile, ltmp, when);
              snprintf(configfile, sizeof(configfile),
                       "%s/%s.local.conf", cptr2, ctmp->fileHeader);
              configfile[ sizeof(configfile)-1 ] = 0;
!             read_config(configfile, ltmp, when);
              cptr2 = ++cptr1;
          }
          SNMP_FREE(envconfpath);
--- 1206,1223 ----
                          DEBUGMSGTL(("read_config_files",
                                      "old config file found: %s, parsing\n",
                                      configfile));
!                         read_config_list(configfile, &ltmp, 1, when);
                      }
                  }
              }
              snprintf(configfile, sizeof(configfile),
                       "%s/%s.conf", cptr2, ctmp->fileHeader);
              configfile[ sizeof(configfile)-1 ] = 0;
!             read_config_list(configfile, &ltmp, 1, when);
              snprintf(configfile, sizeof(configfile),
                       "%s/%s.local.conf", cptr2, ctmp->fileHeader);
              configfile[ sizeof(configfile)-1 ] = 0;
!             read_config_list(configfile, &ltmp, 1, when);
              cptr2 = ++cptr1;
          }
          SNMP_FREE(envconfpath);

Reply via email to