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, <mp, 1, when);
}
}
}
snprintf(configfile, sizeof(configfile),
"%s/%s.conf", cptr2, ctmp->fileHeader);
configfile[ sizeof(configfile)-1 ] = 0;
! read_config_list(configfile, <mp, 1, when);
snprintf(configfile, sizeof(configfile),
"%s/%s.local.conf", cptr2, ctmp->fileHeader);
configfile[ sizeof(configfile)-1 ] = 0;
! read_config_list(configfile, <mp, 1, when);
cptr2 = ++cptr1;
}
SNMP_FREE(envconfpath);