parse.c
来自「eCos操作系统源码」· C语言 代码 · 共 2,108 行 · 第 1/5 页
C
2,108 行
struct tree *tree, int count){ struct tree *tp; count++; for(tp = tree->child_list; tp; tp = tp->next_peer){ fprintf(f, "%s OBJECT IDENTIFIER ::= { %s %ld }\n", tp->label, tree->label, tp->subid); } for(tp = tree->child_list; tp; tp = tp->next_peer){ if (tp->child_list) print_ascii_dump_tree(f, tp, count); }}static int translation_table[256];static voidbuild_translation_table(){ int count; for(count = 0; count < 256; count++){ switch(count){ case OBJID: translation_table[count] = TYPE_OBJID; break; case OCTETSTR: translation_table[count] = TYPE_OCTETSTR; break; case INTEGER: translation_table[count] = TYPE_INTEGER; break; case NETADDR: translation_table[count] = TYPE_IPADDR; break; case IPADDR: translation_table[count] = TYPE_IPADDR; break; case COUNTER: translation_table[count] = TYPE_COUNTER; break; case GAUGE: translation_table[count] = TYPE_GAUGE; break; case TIMETICKS: translation_table[count] = TYPE_TIMETICKS; break; case KW_OPAQUE: translation_table[count] = TYPE_OPAQUE; break; case NUL: translation_table[count] = TYPE_NULL; break; case COUNTER64: translation_table[count] = TYPE_COUNTER64; break; case BITSTRING: translation_table[count] = TYPE_BITSTRING; break; case NSAPADDRESS: translation_table[count] = TYPE_NSAPADDRESS; break; case UINTEGER32: translation_table[count] = TYPE_UINTEGER; break; default: translation_table[count] = TYPE_OTHER; break; } }}static voidinit_tree_roots(){ struct tree *tp, *lasttp; int base_modid; int hash; base_modid = which_module("SNMPv2-SMI"); if (base_modid == -1 ) base_modid = which_module("RFC1155-SMI"); if (base_modid == -1 ) base_modid = which_module("RFC1213-MIB"); /* build root node */ tp = (struct tree *) calloc(1, sizeof(struct tree)); if (tp == NULL) return; tp->label = strdup("joint-iso-ccitt"); tp->modid = base_modid; tp->number_modules = 1; tp->module_list = &(tp->modid); tp->subid = 2; tp->tc_index = -1; set_function(tp); /* from mib.c */ hash = NBUCKET(name_hash(tp->label)); tp->next = tbuckets[hash]; tbuckets[hash] = tp; lasttp = tp; root_imports[0].label = strdup( tp->label ); root_imports[0].modid = base_modid; /* build root node */ tp = (struct tree *) calloc(1, sizeof(struct tree)); if (tp == NULL) return; tp->next_peer = lasttp; tp->label = strdup("ccitt"); tp->modid = base_modid; tp->number_modules = 1; tp->module_list = &(tp->modid); tp->subid = 0; tp->tc_index = -1; set_function(tp); /* from mib.c */ hash = NBUCKET(name_hash(tp->label)); tp->next = tbuckets[hash]; tbuckets[hash] = tp; lasttp = tp; root_imports[1].label = strdup( tp->label ); root_imports[1].modid = base_modid; /* build root node */ tp = (struct tree *) calloc(1, sizeof(struct tree)); if (tp == NULL) return; tp->next_peer = lasttp; tp->label = strdup("iso"); tp->modid = base_modid; tp->number_modules = 1; tp->module_list = &(tp->modid); tp->subid = 1; tp->tc_index = -1; set_function(tp); /* from mib.c */ hash = NBUCKET(name_hash(tp->label)); tp->next = tbuckets[hash]; tbuckets[hash] = tp; lasttp = tp; root_imports[2].label = strdup( tp->label ); root_imports[2].modid = base_modid; tree_head = tp;}#ifdef STRICT_MIB_PARSEING#define label_compare strcasecmp#else#define label_compare strcmp#endifstruct tree *find_tree_node(const char *name, int modid){ struct tree *tp, *headtp; int count, *int_p; if (!name || !*name) return(NULL); headtp = tbuckets[NBUCKET(name_hash(name))]; for ( tp = headtp ; tp ; tp=tp->next ) { if ( !label_compare(tp->label, name) ) { if ( modid == -1 ) /* Any module */ return(tp); for (int_p = tp->module_list, count=0 ; count < tp->number_modules ; ++count, ++int_p ) if ( *int_p == modid ) return(tp); } } return(NULL);}/* computes a value which represents how close name1 is to name2. * high scores mean a worse match. * (yes, the algorithm sucks!) */#define MAX_BAD 0xffffffu_intcompute_match(const char *search_base, const char *key) {#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP) int rc; regex_t parsetree; regmatch_t pmatch; rc=regcomp(&parsetree, key, REG_ICASE | REG_EXTENDED); if (rc == 0) rc=regexec(&parsetree, search_base, 1, &pmatch, 0); regfree(&parsetree); if (rc == 0) { /* found */ return pmatch.rm_so; }#else /* use our own wildcard matcher */ /* first find the longest matching substring (ick) */ char *first = NULL, *result = NULL, *entry; const char *position; char *newkey = strdup(key); entry = strtok( newkey, "*" ); position = search_base; while ( entry ) { result = strcasestr(position, entry); if (result == NULL) { free(newkey); return MAX_BAD; } if (first == NULL) first = result; position = result + strlen(entry); entry = strtok( NULL, "*" ); } free(newkey); if (result) return(first-search_base);#endif /* not found */ return MAX_BAD;}/* * Find the tree node that best matches the pattern string. * Use the "reported" flag such that only one match * is attempted for every node. * * Warning! This function may recurse. * * Caller _must_ invoke clear_tree_flags before first call * to this function. This function may be called multiple times * to ensure that the entire tree is traversed. */struct tree *find_best_tree_node(const char *pattrn, struct tree *tree_top, u_int *match){ struct tree *tp, *best_so_far = NULL, *retptr; u_int old_match=MAX_BAD, new_match=MAX_BAD; if (!pattrn || !*pattrn) return(NULL); if (!tree_top) tree_top = get_tree_head(); for ( tp = tree_top ; tp ; tp=tp->next_peer ) { if (!tp->reported) new_match = compute_match(tp->label, pattrn); tp->reported = 1; if (new_match < old_match) { best_so_far = tp; old_match = new_match; } if (new_match == 0) break; /* this is the best result we can get */ if (tp->child_list) { retptr = find_best_tree_node(pattrn, tp->child_list, &new_match); if (new_match < old_match) { best_so_far = retptr; old_match = new_match; } if (new_match == 0) break; /* this is the best result we can get */ } } if (match) *match = old_match; return(best_so_far);}static voidmerge_anon_children(struct tree *tp1, struct tree *tp2) /* NB: tp1 is the 'anonymous' node */{ struct tree *child1, *child2, *previous; for ( child1 = tp1->child_list ; child1 ; ) { for ( child2 = tp2->child_list, previous = NULL ; child2 ; previous = child2, child2 = child2->next_peer ) { if ( child1->subid == child2->subid ) { /* * Found 'matching' children, * so merge them */ if ( !strncmp( child1->label, ANON, ANON_LEN)) { merge_anon_children( child1, child2 ); child1->child_list = NULL; previous = child1; /* Finished with 'child1' */ child1 = child1->next_peer; free_tree( previous ); goto next; } else if ( !strncmp( child2->label, ANON, ANON_LEN)) { merge_anon_children( child2, child1 ); if ( previous ) previous->next_peer = child2->next_peer; else tp2->child_list = child2->next_peer; free_tree(child2); previous = child1; /* Move 'child1' to 'tp2' */ child1 = child1->next_peer; previous->next_peer = tp2->child_list; tp2->child_list = previous; for ( previous = tp2->child_list ; previous ; previous = previous->next_peer ) previous->parent = tp2; goto next; } else if ( !label_compare( child1->label, child2->label) ) { if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS)) snmp_log(LOG_WARNING, "Warning: %s.%ld is both %s and %s (%s)\n", tp2->label, child1->subid, child1->label, child2->label, File); continue; } else { /* * Two copies of the same node. * 'child2' adopts the children of 'child1' */ if ( child2->child_list ) { for ( previous = child2->child_list ; previous->next_peer ; previous = previous->next_peer ) ; /* Find the end of the list */ previous->next_peer = child1->child_list; } else child2->child_list = child1->child_list; for ( previous = child1->child_list ; previous ; previous = previous->next_peer ) previous->parent = child2; child1->child_list = NULL; previous = child1; /* Finished with 'child1' */ child1 = child1->next_peer; free_tree( previous ); goto next; } } } /* * If no match, move 'child1' to 'tp2' child_list */ if ( child1 ) { previous = child1; child1 = child1->next_peer; previous->parent = tp2; previous->next_peer = tp2->child_list; tp2->child_list = previous; } next:; }}/* * Find all the children of root in the list of nodes. Link them into the * tree and out of the nodes list. */static voiddo_subtree(struct tree *root, struct node **nodes){ register struct tree *tp, *anon_tp=NULL; register struct node *np, **headp; struct node *oldnp = NULL, *child_list = NULL, *childp = NULL; int hash; int *int_p; tp = root; headp = &nbuckets[NBUCKET(name_hash(tp->label))]; /* * Search each of the nodes for one whose parent is root, and * move each into a separate list. */ for(np = *headp; np; np = np->next){ if ( !label_compare(tp->label, np->parent)){ /* take this node out of the node list */ if (oldnp == NULL){ *headp = np->next; /* fix root of node list */ } else { oldnp->next = np->next; /* link around this node */ } if (child_list) childp->next = np; else child_list = np; childp = np; } else { oldnp = np; } } if (childp) childp->next = NULL; /* * Take each element in the child list and place it into the tree. */ for(np = child_list; np; np = np->next){ anon_tp = NULL; tp = root->child_list;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?