📄 parse.c
字号:
} while ((ch = getc(fp)) != -1); return ENDOFFILE;}/* * Takes a list of the form: * { iso org(3) dod(6) 1 } * and creates several nodes, one for each parent-child pair. * Returns NULL on error. */static intgetoid(fp, SubOid, length) register FILE *fp; register struct subid *SubOid; /* an array of subids */ int length; /* the length of the array */{ register int count; int type; char token[128]; register char *cp; if ((type = get_token(fp, token)) != LEFTBRACKET) { print_error("Expected \"{\"", token, type); return 0; } type = get_token(fp, token); for (count = 0; count < length; count++, SubOid++) { SubOid->label = 0; SubOid->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 */ cp = (char *) xmalloc((unsigned) strlen(token) + 1); strcpy(cp, token); SubOid->label = cp; type = get_token(fp, token); if (type == LEFTPAREN) { type = get_token(fp, token); if (type == NUMBER) { SubOid->subid = atoi(token); if ((type = get_token(fp, token)) != RIGHTPAREN) { print_error("Unexpected a closing parenthesis", token, type); return 0; } } else { print_error("Expected a number", token, type); return 0; } } else { continue; } } else { /* this entry has just an integer sub-identifier */ SubOid->subid = atoi(token); } type = get_token(fp, token); } return count;}static voidfree_node(np) struct node *np;{ struct enum_list *ep, *tep; ep = np->enums; while (ep) { tep = ep; ep = ep->next; xfree((char *) tep); } xfree((char *) np);}/* * Parse an entry of the form: * label OBJECT IDENTIFIER ::= { parent 2 } * The "label OBJECT IDENTIFIER" portion has already been parsed. * Returns 0 on error. */static struct node *parse_objectid(fp, name) FILE *fp; char *name;{ int type; char token[64]; register int count; register struct subid *op, *nop; int length; struct subid SubOid[32]; struct node *np, *root, *oldnp = NULL; type = get_token(fp, token); if (type != EQUALS) { print_error("Bad format", token, type); return 0; } if ((length = getoid(fp, SubOid, 32)) != 0) { np = root = (struct node *) xmalloc(sizeof(struct node)); memset((char *) np, '\0', sizeof(struct node)); /* * For each parent-child subid pair in the subid array, * create a node and link it into the node list. */ for (count = 0, op = SubOid, nop = SubOid + 1; count < (length - 2); count++, op++, nop++) { /* every node must have parent's name and child's name or number */ if (op->label && (nop->label || (nop->subid != -1))) { strcpy(np->parent, op->label); if (nop->label) strcpy(np->label, nop->label); if (nop->subid != -1) np->subid = nop->subid; np->type = 0; np->enums = 0; /* set up next entry */ np->next = (struct node *) xmalloc(sizeof(*np->next)); memset((char *) np->next, '\0', sizeof(struct node)); oldnp = np; np = np->next; } } np->next = (struct node *) NULL; /* * The above loop took care of all but the last pair. This pair is taken * care of here. The name for this node is taken from the label for this * entry. * np still points to an unused entry. */ if (count == (length - 2)) { if (op->label) { strcpy(np->parent, op->label); strcpy(np->label, name); if (nop->subid != -1) np->subid = nop->subid; else print_error("Warning: This entry is pretty silly", np->label, type); } else { free_node(np); if (oldnp) oldnp->next = NULL; else return NULL; } } else { print_error("Missing end of oid", (char *) NULL, type); free_node(np); /* the last node allocated wasn't used */ if (oldnp) oldnp->next = NULL; return NULL; } /* free the oid array */ for (count = 0, op = SubOid; count < length; count++, op++) { if (op->label) xfree(op->label); op->label = 0; } return root; } else { print_error("Bad object identifier", (char *) NULL, type); return 0; }}/* * Parses an asn type. This structure is ignored by this parser. * Returns NULL on error. */static intparse_asntype(fp) FILE *fp;{ int type; char token[64]; type = get_token(fp, token); if (type != SEQUENCE) { print_error("Not a sequence", token, type); /* should we handle this */ return ENDOFFILE; } while ((type = get_token(fp, token)) != ENDOFFILE) { if (type == RIGHTBRACKET) return type; } print_error("Expected \"}\"", token, type); return ENDOFFILE;}/* * Parses an OBJECT TYPE macro. * Returns 0 on error. */static struct node *parse_objecttype(fp, name) register FILE *fp; char *name;{ register int type; char token[64]; int count, length; struct subid SubOid[32]; char syntax[64]; int nexttype; char nexttoken[64]; register struct node *np = NULL; register struct enum_list *ep = NULL; type = get_token(fp, token); if (type != SYNTAX) { print_error("Bad format for OBJECT TYPE", token, type); return 0; } np = (struct node *) xmalloc(sizeof(struct node)); np->next = 0; np->enums = 0; type = get_token(fp, token); nexttype = get_token(fp, nexttoken); np->type = type; switch (type) { case SEQUENCE: strcpy(syntax, token); if (nexttype == OF) { strcat(syntax, " "); strcat(syntax, nexttoken); nexttype = get_token(fp, nexttoken); strcat(syntax, " "); strcat(syntax, nexttoken); nexttype = get_token(fp, nexttoken); } break; case INTEGER: strcpy(syntax, token); if (nexttype == LEFTBRACKET) { /* if there is an enumeration list, parse it */ while ((type = get_token(fp, token)) != ENDOFFILE) { if (type == RIGHTBRACKET) break; if (type == LABEL) { /* this is an enumerated label */ if (np->enums == 0) { ep = np->enums = (struct enum_list *) xmalloc(sizeof(struct enum_list)); } else { ep->next = (struct enum_list *) xmalloc(sizeof(struct enum_list)); ep = ep->next; } ep->next = 0; /* a reasonable approximation for the length */ ep->label = (char *) xmalloc((unsigned) strlen(token) + 1); strcpy(ep->label, token); type = get_token(fp, token); if (type != LEFTPAREN) { print_error("Expected \"(\"", token, type); free_node(np); return 0; } type = get_token(fp, token); if (type != NUMBER) { print_error("Expected integer", token, type); free_node(np); return 0; } ep->value = atoi(token); type = get_token(fp, token); if (type != RIGHTPAREN) { print_error("Expected \")\"", token, type); free_node(np); return 0; } } } if (type == ENDOFFILE) { print_error("Expected \"}\"", token, type); free_node(np); return 0; } nexttype = get_token(fp, nexttoken); } else if (nexttype == LEFTPAREN) { /* ignore the "constrained integer" for now */ nexttype = get_token(fp, nexttoken); nexttype = get_token(fp, nexttoken); nexttype = get_token(fp, nexttoken); } break; case OBJID: case OCTETSTR: case NETADDR: case IPADDR: case COUNTER: case GAUGE: case TIMETICKS: case OPAQUE: case NUL: case LABEL: strcpy(syntax, token); break; default: print_error("Bad syntax", token, type); free_node(np); return 0; } if (nexttype != ACCESS) { print_error("Should be ACCESS", nexttoken, nexttype); free_node(np); return 0; } type = get_token(fp, token); if (type != READONLY && type != READWRITE && type != WRITEONLY && type != NOACCESS) { print_error("Bad access type", nexttoken, nexttype); free_node(np); return 0; } type = get_token(fp, token); if (type != STATUS) { print_error("Should be STATUS", token, nexttype); free_node(np); return 0; } type = get_token(fp, token); if (type != MANDATORY && type != OPTIONAL && type != OBSOLETE && type != RECOMMENDED) { print_error("Bad status", token, type); free_node(np); return 0; } /* Fetch next token. Either: * * -> EQUALS (Old MIB format) * -> DESCRIPTION, INDEX (New MIB format) */ type = get_token(fp, token); if ((type != DESCRIPTION) && (type != INDEX) && (type != EQUALS)) { print_error("Should be DESCRIPTION, INDEX, or EQUALS", token, nexttype); free_node(np); return 0; } if (type == DESCRIPTION) { type = get_token(fp, token); if (type != QUOTE) { print_error("Should be Description open quote", token, nexttype); free_node(np); return 0; } /* Fetch description string */ { int ReadChar; ReadChar = last; /* skip everything until closing quote */ while ((ReadChar != '"') && (ReadChar != -1)) { ReadChar = getc(fp); if (ReadChar == '\n') Line++; } last = ' '; } /* ASSERT: Done with description. */ type = get_token(fp, token); } if ((type != INDEX) && (type != EQUALS)) { print_error("Should be INDEX, or EQUALS", token, nexttype); free_node(np); return 0; } if (type == INDEX) { /* Scarf INDEX */ type = get_token(fp, token); if (type != LEFTBRACKET) { print_error("Should be INDEX left brace", token, type); free_node(np); return 0; } /* Fetch description string */ { int ReadChar; ReadChar = last; /* skip everything until closing quote */ while ((ReadChar != '}') && (ReadChar != -1)) { ReadChar = getc(fp); if (ReadChar == '\n') Line++; } last = ' '; } /* ASSERT: Done with INDEX. */ type = get_token(fp, token); } if (type != EQUALS) { print_error("Bad format", token, type); free_node(np); return 0; } length = getoid(fp, SubOid, 32); if (length > 1 && length <= 32) { /* just take the last pair in the oid list */ if (SubOid[length - 2].label) strncpy(np->parent, SubOid[length - 2].label, 64); strcpy(np->label, name); if (SubOid[length - 1].subid != -1) np->subid = SubOid[length - 1].subid; else print_error("Warning: This entry is pretty silly", np->label, type); } else { print_error("No end to oid", (char *) NULL, type); free_node(np); np = 0; } /* free oid array */ for (count = 0; count < length; count++) { if (SubOid[count].label) xfree(SubOid[count].label); SubOid[count].label = 0; } return np;}/* * Parses a mib file and returns a linked list of nodes found in the file. * Returns NULL on error. */#ifndef TESTstatic#endifstruct node *parse(fp) FILE *fp;{ char token[64]; char name[64]; int type = 1; struct node *np = NULL, *root = NULL; hash_init(); while (type != ENDOFFILE) { type = get_token(fp, token); if (type != LABEL) { if (type == ENDOFFILE) { return root; } print_error(token, "is a reserved word", type); return NULL; } strncpy(name, token, 64); type = get_token(fp, token); if (type == OBJTYPE) { if (root == NULL) { /* first link in chain */ np = root = parse_objecttype(fp, name); if (np == NULL) { print_error("Bad parse of object type", (char *) NULL, type); return NULL; } } else { np->next = parse_objecttype(fp, name); if (np->next == NULL) { print_error("Bad parse of objecttype", (char *) NULL, type); return NULL; } } /* now find end of chain */ while (np->next) np = np->next; } else if (type == OBJID) { if (root == NULL) { /* first link in chain */ np = root = parse_objectid(fp, name); if (np == NULL) { print_error("Bad parse of object id", (char *) NULL, type); return NULL; } } else { np->next = parse_objectid(fp, name); if (np->next == NULL) { print_error("Bad parse of object type", (char *) NULL, type); return NULL; } } /* now find end of chain */ while (np->next) np = np->next; } else if (type == EQUALS) { type = parse_asntype(fp); } else if (type == ENDOFFILE) { break; } else { print_error("Bad operator", (char *) NULL, type); return NULL; } }#ifdef TEST { struct enum_list *ep; for (np = root; np; np = np->next) { printf("%s ::= { %s %d } (%d)\n", np->label, np->parent, np->subid, np->type); if (np->enums) { printf("Enums: \n"); for (ep = np->enums; ep; ep = ep->next) { printf("%s(%d)\n", ep->label, ep->value); } } } }#endif /* TEST */ return root;}struct snmp_mib_tree *read_mib(char *filename){ FILE *fp; struct node *nodes; struct snmp_mib_tree *tree; char mbuf[256]; char *p; fp = fopen(filename, "r"); if (fp == NULL) { snmplib_debug(1, "init_mib: %s: %s\n", filename, xstrerror()); return (NULL); } mbuf[0] = '\0'; while ((p = fgets(mbuf, 256, fp)) && strncmp(mbuf, "DUMMY", strlen("DUMMY"))); if (!p) { snmplib_debug(0, "Bad MIB version or tag missing, install original!\n"); return NULL; } if (!strcmp(mbuf, "DUMMY")) { snmplib_debug(0, "You need to update your MIB!\n"); return NULL; } nodes = parse(fp); if (!nodes) { snmplib_debug(0, "Mib table is bad. Exiting\n"); return NULL; } tree = build_tree(nodes); fclose(fp); return (tree);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -