⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
do_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;
        while (tp)
            if (tp->subid == np->subid) break;
            else tp = tp->next_peer;
        if (tp) {
	    if (!label_compare (tp->label, np->label)) {
		    /* Update list of modules */
                int_p = (int *) malloc((tp->number_modules+1) * sizeof(int));
                if (int_p == NULL) return;
                memcpy(int_p, tp->module_list, tp->number_modules*sizeof(int));
                int_p[tp->number_modules] = np->modid;
                if (tp->number_modules > 1 )
                   free((char*)tp->module_list);
                ++tp->number_modules;
                tp->module_list = int_p;

		if ( ds_get_boolean(DS_LIBRARY_ID, DS_LIB_MIB_REPLACE) ) {
		    /* Replace from node */
		    tree_from_node(tp,np);
		}
		    /* Handle children */
		do_subtree(tp, nodes);
		continue;
            }
            if (!strncmp( np->label, ANON, ANON_LEN) ||
                !strncmp( tp->label, ANON, ANON_LEN)) {
                anon_tp = tp;	/* Need to merge these two trees later */
            }
	    else 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",
			root->label, np->subid, tp->label, np->label, File);
	}

        tp = (struct tree *) calloc(1, sizeof(struct tree));
        if (tp == NULL) return;
        tp->parent = root;
        tp->modid = np->modid;
        tp->number_modules = 1;
        tp->module_list = &(tp->modid);
        tree_from_node(tp, np);
        tp->next_peer = root->child_list;
        root->child_list = tp;
        hash = NBUCKET(name_hash(tp->label));
        tp->next = tbuckets[hash];
        tbuckets[hash] = tp;
/*      if (tp->type == TYPE_OTHER) */
            do_subtree(tp, nodes);      /* recurse on this child if it isn't
                                           an end node */
        if ( anon_tp ) {
            if (!strncmp( tp->label, ANON, ANON_LEN)) {
			/*
			 * The new node is anonymous,
			 *  so merge it with the existing one.
			 */
                merge_anon_children( tp, anon_tp );

		/* unlink and destroy tp */
		unlink_tree(tp);
		free_tree(tp);
            }
            else if (!strncmp( anon_tp->label, ANON, ANON_LEN)) {
		struct tree *ntp;
			/*
			 * The old node was anonymous,
			 *  so merge it with the existing one,
			 *  and fill in the full information.
			 */
                merge_anon_children( anon_tp, tp );

		/* unlink anon_tp from the hash */
		unlink_tbucket(anon_tp);

		/* get rid of old contents of anon_tp */
                free_partial_tree(anon_tp, FALSE);

		/* put in the current information */
                anon_tp->label = tp->label;
                anon_tp->child_list = tp->child_list;
                anon_tp->modid = tp->modid;
                anon_tp->tc_index = tp->tc_index;
                anon_tp->type = tp->type;
                anon_tp->enums = tp->enums;
                anon_tp->indexes = tp->indexes;
                anon_tp->ranges = tp->ranges;
                anon_tp->hint = tp->hint;
                anon_tp->units = tp->units;
                anon_tp->description = tp->description;
		anon_tp->parent = tp->parent;
                set_function(anon_tp);

		/* update parent pointer in moved children */
		ntp = anon_tp->child_list;
		while (ntp) {
		    ntp->parent = anon_tp;
		    ntp = ntp->next_peer;
		}

		/* hash in anon_tp in its new place */
		hash = NBUCKET(name_hash(anon_tp->label));
		anon_tp->next = tbuckets[hash];
		tbuckets[hash] = anon_tp;

		/* unlink and destroy tp */
		unlink_tbucket(tp);
		unlink_tree(tp);
		free(tp);
            }
            else {
                /* Uh?  One of these two should have been anonymous! */
	        if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))
		    snmp_log(LOG_WARNING,
                             "Warning: expected anonymous node (either %s or %s) in %s\n",
                             tp->label, anon_tp->label, File);
            }
            anon_tp = NULL;
        }
    }
    /* free all nodes that were copied into tree */
    oldnp = NULL;
    for(np = child_list; np; np = np->next){
        if (oldnp)
            free_node(oldnp);
        oldnp = np;
    }
    if (oldnp)
        free_node(oldnp);
}

static void do_linkup(struct module *mp,
		      struct node *np)
{
    struct module_import *mip;
    struct node *onp;
    struct tree *tp;
    int i;
	/*
	 * All modules implicitly import
	 *   the roots of the tree
	 */
    if (snmp_get_do_debugging() > 1) dump_module_list();
    DEBUGMSGTL(("parse-mibs", "Processing IMPORTS for module %d %s\n", mp->modid, mp->name));
    if ( mp->no_imports == 0 ) {
	mp->no_imports = NUMBER_OF_ROOT_NODES;
	mp->imports = root_imports;
    }

	/*
	 * Build the tree
	 */
    init_node_hash( np );
    for ( i=0, mip=mp->imports ; i < mp->no_imports ; ++i, ++mip ) {
	char modbuf[256];
	DEBUGMSGTL(("parse-mibs", "  Processing import: %s\n", mip->label));
	if (get_tc_index( mip->label, mip->modid ) != -1)
	    continue;
	tp = find_tree_node( mip->label, mip->modid );
	if (!tp) {
	    if (mip->modid != -1)
		snmp_log(LOG_WARNING, "Did not find '%s' in module %s (%s)\n",
                         mip->label, module_name(mip->modid, modbuf), File);
	    continue;
	}
	do_subtree( tp, &np );
    }

	/*
	 * If any nodes left over,
	 *   check that they're not the result of a "fully qualified"
	 *   name, and then add them to the list of orphans
	 */

    if (!np) return;
    for ( tp = tree_head ; tp ; tp=tp->next_peer )
        do_subtree( tp, &np );
    if (!np) return;
    for ( np = orphan_nodes ; np && np->next ; np = np->next )
	;	/* find the end of the orphan list */
    for (i = 0; i < NHASHSIZE; i++)
	if ( nbuckets[i] ) {
	    if ( orphan_nodes )
		onp = np->next = nbuckets[i];
	    else
		onp = orphan_nodes = nbuckets[i];
	    nbuckets[i] = NULL;
	    while (onp) {
		if (ds_get_int(DS_LIBRARY_ID, DS_LIB_MIB_WARNINGS))
		    snmp_log(LOG_WARNING,
                             "Unlinked OID in %s: %s ::= { %s %ld }\n",
                             (mp->name ? mp->name : "<no module>"),
                             (onp->label ? onp->label : "<no label>"),
                             (onp->parent ? onp->parent : "<no parent>"),
                             onp->subid);
		np = onp;
		onp = onp->next;
	    }
	}

    return;
}


/*
 * Takes a list of the form:
 * { iso org(3) dod(6) 1 }
 * and creates several nodes, one for each parent-child pair.
 * Returns 0 on error.
 */
static int
getoid(FILE *fp,
       struct subid_s *id, /* an array of subids */
       int length)  /* the length of the array */
{
    register int count;
    int type;
    char token[MAXTOKEN];

    if ((type = get_token(fp, token, MAXTOKEN)) != LEFTBRACKET){
        print_error("Expected \"{\"", token, type);
        return 0;
    }
    type = get_token(fp, token, MAXTOKEN);
    for(count = 0; count < length; count++, id++){
        id->label = NULL;
        id->modid = current_module;
        id->subid = -1;
        if (type == RIGHTBRACKET){
            return count;
        } else if (type != LABEL && type != NUMBER){
            print_error("Not valid for object identifier", token, type);
            return 0;
        }
        if (type == LABEL){
            /* this entry has a label */
            id->label = strdup(token);
            type = get_token(fp, token, MAXTOKEN);
            if (type == LEFTPAREN){
                type = get_token(fp, token, MAXTOKEN);
                if (type == NUMBER){
                    id->subid = atoi(token);
                    if ((type = get_token(fp, token, MAXTOKEN)) != RIGHTPAREN){
                        print_error("Expected a closing parenthesis",
                                    token, type);
                        return 0;
                    }
                } else {
                    print_error("Expected a number", token, type);
                    return 0;
                }
            } else {
                continue;
            }
        } else if (type == NUMBER) {
            /* this entry  has just an integer sub-identifier */
            id->subid = atoi(token);
        }
	else {
	    print_error("Expected label or number", token, type);
	    return 0;
	}
        type = get_token(fp, token, MAXTOKEN);
    }
    print_error ("Too long OID", token, type);
    return 0;
}

/*
 * Parse a sequence of object subidentifiers for the given name.
 * The "label OBJECT IDENTIFIER ::=" portion has already been parsed.
 *
 * The majority of cases take this form :
 * label OBJECT IDENTIFIER ::= { parent 2 }
 * where a parent label and a child subidentifier number are specified.
 *
 * Variations on the theme include cases where a number appears with
 * the parent, or intermediate subidentifiers are specified by label,
 * by number, or both.
 *
 * Here are some representative samples :
 * internet        OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 }
 * mgmt            OBJECT IDENTIFIER ::= { internet 2 }
 * rptrInfoHealth  OBJECT IDENTIFIER ::= { snmpDot3RptrMgt 0 4 }
 *
 * Here is a very rare form :
 * iso             OBJECT IDENTIFIER ::= { 1 }
 *
 * Returns NULL on error.  When this happens, memory may be leaked.
 */
static struct node *
parse_objectid(FILE *fp,
	       char *name)
{
    register int count;
    register struct subid_s *op, *nop;
    int length;
    struct subid_s loid[32];
    struct node *np, *root = NULL, *oldnp = NULL;
    struct tree *tp;

    if ((length = getoid(fp, loid, 32)) == 0){
        print_error("Bad object identifier", NULL, CONTINUE);
        return NULL;
    }

    /*
     * Handle numeric-only object identifiers,
     *  by labelling the first sub-identifier
     */
    op = loid;
    if ( !op->label )
      for ( tp = tree_head ; tp ; tp=tp->next_peer )
        if ( (int)tp->subid == op->subid ) {
            op->label = strdup(tp->label);
            break;
        }

    /*
     * Handle  "label OBJECT-IDENTIFIER ::= { subid }"
     */
    if (length == 1) {
        op = loid;
        np = alloc_node(op->modid);
        if (np == NULL) return(NULL);
        np->subid = op->subid;
        np->label = strdup(name);
        if (op->label) free(op->label);
        return np;
    }

    /*
     * For each parent-child subid pair in the subid array,
     * create a node and link it into the node list.
     */
    for(count = 0, op = loid, nop=loid+1; count < (length - 1);
      count++, op++, nop++){
        /* every node must have parent's name and child's name or number */
/* XX the next statement is always true -- does it matter ?? */
        if (op->label && (nop->label || (nop->subid != -1))){
            np = alloc_node(nop->modid);
            if (np == NULL) return(NULL);
            if (root == NULL) root = np;

            np->parent = strdup (op->label);
            if (count == (length - 2)) {
                /* The name for this node is the label for this entry */
                np->label = strdup (name);
            }
            else {
                if (!nop->label) {
                    nop->label = (char *) malloc(20 + ANON_LEN);
                    if (nop->label == NULL) return(NULL);
                    sprintf(nop->label, "%s%d", ANON, anonymous++);
                }
                np->label = strdup (nop->label);
            }
            if (nop->subid != -1)
                np->subid = nop->subid;
            else
                print_error("Warning: This entry is pretty silly",
			    np->label, CONTINUE);

            /* set up next entry */
            if (oldnp) oldnp->next = np;
            oldnp = np;
        } /* end if(op->label... */
    }

    /* free the loid array */
    for(count = 0, op = loid; count < length; count++, op++){
        if (op->label)
            free(op->label);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -