📄 parse.c
字号:
#define HASHSIZE 32
#define BUCKET(x) (x & (HASHSIZE-1))
#define NHASHSIZE 128
#define NBUCKET(x) (x & (NHASHSIZE-1))
static struct tok *buckets[HASHSIZE];
static struct node *nbuckets[NHASHSIZE];
static struct tree *tbuckets[NHASHSIZE];
static struct module *module_head = NULL;
struct node *orphan_nodes = NULL;
struct tree *tree_head = NULL;
#define NUMBER_OF_ROOT_NODES 3
static struct module_import root_imports[NUMBER_OF_ROOT_NODES];
static int current_module = 0;
static int max_module = 0;
static char *last_err_module = 0; /* no repeats on "Cannot find module..." */
static void tree_from_node(struct tree *tp, struct node *np);
static void do_subtree (struct tree *, struct node **);
static void do_linkup (struct module *, struct node *);
static void dump_module_list (void);
static int get_token (FILE *, char *, int);
static int parseQuoteString (FILE *, char *, int);
static int tossObjectIdentifier (FILE *);
static int name_hash (const char *);
static void init_node_hash (struct node *);
static void print_error (const char *, const char *, int);
static void free_tree (struct tree *);
static void free_partial_tree (struct tree *, int);
static void free_node (struct node *);
static void build_translation_table (void);
static void init_tree_roots (void);
static void merge_anon_children (struct tree *, struct tree *);
static void unlink_tbucket(struct tree *);
static void unlink_tree(struct tree *);
static int getoid (FILE *, struct subid_s *, int);
static struct node *parse_objectid (FILE *, char *);
static int get_tc (const char *, int, int *, struct enum_list **, struct range_list **, char **);
static int get_tc_index (const char *, int);
static struct enum_list *parse_enumlist (FILE *, struct enum_list **);
static struct range_list *parse_ranges(FILE *fp, struct range_list **);
static struct node *parse_asntype (FILE *, char *, int *, char *);
static struct node *parse_objecttype (FILE *, char *);
static struct node *parse_objectgroup (FILE *, char *);
static struct node *parse_notificationDefinition (FILE *, char *);
static struct node *parse_trapDefinition (FILE *, char *);
static struct node *parse_compliance (FILE *, char *);
static struct node *parse_capabilities(FILE *, char *);
static struct node *parse_moduleIdentity (FILE *, char *);
static struct node *parse_macro(FILE *, char *);
static void parse_imports (FILE *);
static struct node *parse (FILE *, struct node *);
static int read_module_internal (const char *);
static void read_module_replacements (const char *);
static void read_import_replacements (const char *, struct module_import *);
static void new_module (const char *, const char *);
static struct node *merge_parse_objectid (struct node *, FILE *, char *);
static struct index_list *getIndexes(FILE *fp, struct index_list **);
static void free_indexes(struct index_list **);
static void free_ranges(struct range_list **);
static void free_enums(struct enum_list **);
static struct range_list * copy_ranges(struct range_list *);
static struct enum_list * copy_enums(struct enum_list *);
static struct index_list * copy_indexes(struct index_list *);
/* backwards compatibility wrappers */
void snmp_set_mib_errors(int err)
{
ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_ERRORS, err);
}
void snmp_set_mib_warnings(int warn)
{
ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, warn);
}
void snmp_set_save_descriptions(int save)
{
ds_set_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS, save);
}
void snmp_set_mib_comment_term(int save)
{
/* 0=strict, 1=EOL terminated */
ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM, save);
}
void snmp_set_mib_parse_label(int save)
{
/* 0=strict, 1=underscore OK in label */
ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL, save);
}
/* end wrappers */
void snmp_mib_toggle_options_usage(const char *lead, FILE *outf) {
fprintf(outf, "%sMIBOPTS values:\n", lead);
fprintf(outf, "%s u: %sallow the usage of underlines in mib symbols.\n",
lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL))?"dis":""));
fprintf(outf, "%s c: %sallow the usage of \"--\" to terminate comments.\n",
lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM))?"":"dis"));
fprintf(outf, "%s d: %ssave the descriptions of the mib objects.\n",
lead, ((ds_get_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS))?"don't ":""));
fprintf(outf, "%s e: Disable mib errors of MIB symbols conflicts\n",
lead);
fprintf(outf, "%s w: Enable mib warnings of MIB symbols conflicts\n",
lead);
fprintf(outf, "%s W: Enable detailed warnings of MIB symbols conflicts\n",
lead);
fprintf(outf, "%s R: Replace MIB symbols from latest module\n",
lead);
}
char *snmp_mib_toggle_options(char *options) {
if (options) {
while(*options) {
switch(*options) {
case 'u':
ds_set_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL, !ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_PARSE_LABEL));
break;
case 'c':
ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_COMMENT_TERM);
break;
case 'e':
ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_ERRORS);
break;
case 'w':
ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, 1);
break;
case 'W':
ds_set_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS, 2);
break;
case 'd':
ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_SAVE_MIB_DESCRS);
break;
case 'R':
ds_toggle_boolean(DS_LIBRARY_ID, DS_LIB_MIB_REPLACE);
break;
default:
/* return at the unknown option */
return options;
}
options++;
}
}
return NULL;
}
static int
name_hash(const char* name)
{
int hash = 0;
const char *cp;
if (name) {
for(cp = name; *cp; cp++) {
hash += tolower(*cp);
}
}
return(hash);
}
void
init_mib_internals (void)
{
register struct tok *tp;
register int b, i;
int max_modc;
if (tree_head)
return;
/*
* Set up hash list of pre-defined tokens
*/
memset(buckets, 0, sizeof(buckets));
for (tp = tokens; tp->name; tp++) {
tp->hash = name_hash( tp->name );
b = BUCKET(tp->hash);
if (buckets[b])
tp->next = buckets[b]; /* BUG ??? */
buckets[b] = tp;
}
/*
* Initialise other internal structures
*/
max_modc = sizeof(module_map)/sizeof(module_map[0])-1;
for ( i = 0; i < max_modc; ++i )
module_map[i].next = &(module_map[i+1]);
module_map[max_modc].next = NULL;
module_map_head = module_map;
memset(nbuckets, 0, sizeof(nbuckets));
memset(tbuckets, 0, sizeof(tbuckets));
memset(tclist, 0, MAXTC * sizeof(struct tc));
build_translation_table();
init_tree_roots(); /* Set up initial roots */
/* Relies on 'add_mibdir' having set up the modules */
}
static void
init_node_hash(struct node *nodes)
{
register struct node *np, *nextp;
register int hash;
memset(nbuckets, 0, sizeof(nbuckets));
for(np = nodes; np;){
nextp = np->next;
hash = NBUCKET(name_hash(np->parent));
np->next = nbuckets[hash];
nbuckets[hash] = np;
np = nextp;
}
}
static int erroneousMibs = 0;
int get_mib_parse_error_count(void)
{
return erroneousMibs;
}
static void
print_error(const char *string,
const char *token,
int type)
{
erroneousMibs++;
DEBUGMSGTL(("parse-mibs", "\n"));
if (type == ENDOFFILE)
snmp_log(LOG_ERR, "%s (EOF): At line %d in %s\n", string, Line,
File);
else if (token && *token)
snmp_log(LOG_ERR, "%s (%s): At line %d in %s\n", string, token,
Line, File);
else
snmp_log(LOG_ERR, "%s: At line %d in %s\n", string, Line, File);
}
static void
print_module_not_found(const char *cp)
{
if (!last_err_module || strcmp(cp, last_err_module))
print_error("Cannot find module", cp, CONTINUE);
if (last_err_module) free(last_err_module);
last_err_module = strdup(cp);
}
static struct node *
alloc_node(int modid)
{
struct node *np;
np = (struct node *) calloc(1, sizeof(struct node));
if (np) {
np->tc_index = -1;
np->modid = modid;
}
return np;
}
static void unlink_tbucket(struct tree *tp)
{
int hash = NBUCKET(name_hash(tp->label));
struct tree *otp = NULL, *ntp = tbuckets[hash];
while (ntp && ntp != tp) {
otp = ntp; ntp = ntp->next;
}
if (!ntp) snmp_log(LOG_EMERG, "Can't find %s in tbuckets\n", tp->label);
else if (otp) otp->next = ntp->next;
else tbuckets[hash] = tp->next;
}
static void unlink_tree(struct tree *tp)
{
struct tree *otp = NULL, *ntp = tp->parent->child_list;
while (ntp && ntp != tp) {
otp = ntp; ntp = ntp->next_peer;
}
if (!ntp) snmp_log(LOG_EMERG, "Can't find %s in %s's children\n",
tp->label, tp->parent->label);
else if (otp) otp->next_peer = ntp->next_peer;
else tp->parent->child_list = tp->next_peer;
}
static void
free_partial_tree(struct tree *tp, int keep_label)
{
if ( !tp)
return;
/* remove the data from this tree node */
free_enums(&tp->enums);
free_ranges(&tp->ranges);
free_indexes(&tp->indexes);
if (!keep_label)
SNMP_FREE(tp->label);
SNMP_FREE(tp->hint);
SNMP_FREE(tp->units);
SNMP_FREE(tp->description);
}
/*
* free a tree node. Note: the node must already have been unlinked
* from the tree when calling this routine
*/
static void
free_tree(struct tree *Tree)
{
if (!Tree)
return;
unlink_tbucket(Tree);
free_partial_tree (Tree, FALSE);
if (Tree->number_modules > 1 )
free((char*)Tree->module_list);
free ((char*)Tree);
}
static void
free_node(struct node *np)
{
if ( !np) return;
free_enums(&np->enums);
free_ranges(&np->ranges);
free_indexes(&np->indexes);
if (np->label) free(np->label);
if (np->hint) free(np->hint);
if (np->units) free(np->units);
if (np->description) free(np->description);
if (np->parent) free(np->parent);
free((char*)np);
}
#ifdef TEST
static void
print_nodes(FILE *fp,
struct node *root)
{
extern void xmalloc_stats (FILE *);
struct enum_list *ep;
struct index_list *ip;
struct range_list *rp;
struct node *np;
for(np = root; np; np = np->next){
fprintf(fp, "%s ::= { %s %ld } (%d)\n", np->label, np->parent,
np->subid, np->type);
if (np->tc_index >= 0)
fprintf(fp, " TC = %s\n", tclist[np->tc_index].descriptor);
if (np->enums){
fprintf(fp, " Enums: \n");
for(ep = np->enums; ep; ep = ep->next){
fprintf(fp, " %s(%d)\n", ep->label, ep->value);
}
}
if (np->ranges){
fprintf(fp, " Ranges: \n");
for(rp = np->ranges; rp; rp = rp->next){
fprintf(fp, " %d..%d\n", rp->low, rp->high);
}
}
if (np->indexes){
fprintf(fp, " Indexes: \n");
for(ip = np->indexes; ip; ip = ip->next){
fprintf(fp, " %s\n", ip->ilabel);
}
}
if (np->hint)
fprintf(fp, " Hint: %s\n", np->hint);
if (np->units)
fprintf(fp, " Units: %s\n", np->units);
}
}
#endif
void
print_subtree(FILE *f,
struct tree *tree,
int count)
{
struct tree *tp;
int i;
char modbuf[256];
for(i = 0; i < count; i++)
fprintf(f, " ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -